Compare commits
2 Commits
5eb856ed73
...
866549873a
| Author | SHA1 | Date | |
|---|---|---|---|
| 866549873a | |||
| 73e4f8e001 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -365,3 +365,4 @@ FodyWeavers.xsd
|
||||
# Trae IDE related files
|
||||
.trae/
|
||||
PROJECT_STRUCTURE.md
|
||||
/SqlMigrations
|
||||
|
||||
@ -8,7 +8,7 @@ namespace QYZH.InteractiveMagazine.IService;
|
||||
/// <summary>
|
||||
/// 宠物服务接口
|
||||
/// </summary>
|
||||
public interface IPetService : IBaseService<Pet>
|
||||
public interface IPetService : IBaseService<UserPet>
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取用户宠物信息
|
||||
|
||||
@ -15,6 +15,16 @@ public class PetOutput
|
||||
/// </summary>
|
||||
public long UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 宠物模板Id
|
||||
/// </summary>
|
||||
public long TemplateId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 宠物模板名称
|
||||
/// </summary>
|
||||
public string? TemplateName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 宠物昵称
|
||||
/// </summary>
|
||||
|
||||
@ -10,6 +10,13 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
||||
{
|
||||
public PetEvolution() { }
|
||||
|
||||
/// <summary>
|
||||
/// Desc:所属宠物模板Id(关联PetTemplate.Id)
|
||||
/// Default:
|
||||
/// Nullable:False
|
||||
/// </summary>
|
||||
public long TemplateId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Desc:阶段名称
|
||||
/// Default:
|
||||
|
||||
@ -10,6 +10,13 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
||||
{
|
||||
public PetSkin() { }
|
||||
|
||||
/// <summary>
|
||||
/// Desc:所属宠物模板Id(关联PetTemplate.Id)
|
||||
/// Default:
|
||||
/// Nullable:False
|
||||
/// </summary>
|
||||
public long TemplateId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Desc:皮肤名称
|
||||
/// Default:
|
||||
|
||||
62
QYZH.InteractiveMagazine.Models/Entity/PetTemplate.cs
Normal file
62
QYZH.InteractiveMagazine.Models/Entity/PetTemplate.cs
Normal file
@ -0,0 +1,62 @@
|
||||
using SqlSugar;
|
||||
|
||||
namespace QYZH.InteractiveMagazine.Models.Entity
|
||||
{
|
||||
/// <summary>
|
||||
/// 宠物模板表(定义不同宠物种类,支持后期多宠物扩展)
|
||||
/// </summary>
|
||||
[SugarTable("PetTemplate")]
|
||||
public partial class PetTemplate : SqlSugarBaseEntity
|
||||
{
|
||||
public PetTemplate() { }
|
||||
|
||||
/// <summary>
|
||||
/// Desc:模板名称
|
||||
/// Default:
|
||||
/// Nullable:False
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Desc:模板描述
|
||||
/// Default:
|
||||
/// Nullable:True
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Desc:默认初始进化形态Id(关联PetEvolution.Id)
|
||||
/// Default:
|
||||
/// Nullable:False
|
||||
/// </summary>
|
||||
public long DefaultEvolutionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Desc:模板图标地址
|
||||
/// Default:
|
||||
/// Nullable:True
|
||||
/// </summary>
|
||||
public string IconUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Desc:排序权重
|
||||
/// Default:0
|
||||
/// Nullable:False
|
||||
/// </summary>
|
||||
public int SortOrder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Desc:模板类型: Normal, Special, Limited
|
||||
/// Default:Normal
|
||||
/// Nullable:False
|
||||
/// </summary>
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Desc:状态: Active, Inactive
|
||||
/// Default:Active
|
||||
/// Nullable:False
|
||||
/// </summary>
|
||||
public new string Status { get; set; }
|
||||
}
|
||||
}
|
||||
@ -3,12 +3,12 @@ using SqlSugar;
|
||||
namespace QYZH.InteractiveMagazine.Models.Entity
|
||||
{
|
||||
///<summary>
|
||||
///宠物实例表
|
||||
///用户宠物实例表
|
||||
///</summary>
|
||||
[SugarTable("Pet")]
|
||||
public partial class Pet : SqlSugarBaseEntity
|
||||
[SugarTable("UserPet")]
|
||||
public partial class UserPet : SqlSugarBaseEntity
|
||||
{
|
||||
public Pet()
|
||||
public UserPet()
|
||||
{
|
||||
|
||||
|
||||
@ -20,6 +20,13 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
||||
/// </summary>
|
||||
public long UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Desc:宠物模板Id(关联PetTemplate.Id)
|
||||
/// Default:
|
||||
/// Nullable:False
|
||||
/// </summary>
|
||||
public long TemplateId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Desc:宠物昵称
|
||||
/// Default:
|
||||
@ -60,7 +60,7 @@ public class CheckInService(
|
||||
}
|
||||
|
||||
// 5. 查询用户宠物(如果有)
|
||||
var pet = await checkInRecordRepository.Context.Queryable<Pet>()
|
||||
var pet = await checkInRecordRepository.Context.Queryable<UserPet>()
|
||||
.Where(p => p.UserId == userId && !p.IsDeleted)
|
||||
.FirstAsync();
|
||||
|
||||
@ -258,7 +258,7 @@ public class CheckInService(
|
||||
throw new BusinessException("用户不存在", 404);
|
||||
|
||||
// 查询宠物
|
||||
var pet = await checkInRecordRepository.Context.Queryable<Pet>()
|
||||
var pet = await checkInRecordRepository.Context.Queryable<UserPet>()
|
||||
.Where(p => p.UserId == userId && !p.IsDeleted)
|
||||
.FirstAsync();
|
||||
|
||||
|
||||
@ -13,13 +13,14 @@ namespace QYZH.InteractiveMagazine.Service;
|
||||
/// 宠物服务实现
|
||||
/// </summary>
|
||||
public class PetService(
|
||||
BaseRepository<Pet> petRepository,
|
||||
BaseRepository<UserPet> petRepository,
|
||||
BaseRepository<PetTemplate> petTemplateRepository,
|
||||
BaseRepository<PetFeedingRecord> feedingRecordRepository,
|
||||
BaseRepository<PetEvolution> petEvolutionRepository,
|
||||
BaseRepository<PetSkinImage> petSkinImageRepository,
|
||||
BaseRepository<PetSkin> petSkinRepository,
|
||||
ILogger<PetService> logger)
|
||||
: BaseRepository<Pet>, IPetService
|
||||
: BaseRepository<UserPet>, IPetService
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取用户宠物信息(含当前形态名称、皮肤图片序列)
|
||||
@ -39,6 +40,11 @@ public class PetService(
|
||||
.Where(e => e.Id == pet.CurrentEvolutionId)
|
||||
.FirstAsync();
|
||||
|
||||
// 查询宠物模板名称
|
||||
var template = await petTemplateRepository.Queryable()
|
||||
.Where(t => t.Id == pet.TemplateId && !t.IsDeleted)
|
||||
.FirstAsync();
|
||||
|
||||
// 查询当前皮肤名称
|
||||
string? skinName = null;
|
||||
if (pet.CurrentSkinId > 0)
|
||||
@ -68,6 +74,8 @@ public class PetService(
|
||||
{
|
||||
Id = pet.Id,
|
||||
UserId = pet.UserId,
|
||||
TemplateId = pet.TemplateId,
|
||||
TemplateName = template?.Name,
|
||||
Name = pet.Name,
|
||||
CurrentEvolutionId = pet.CurrentEvolutionId,
|
||||
EvolutionStageName = evolution?.StageName,
|
||||
@ -90,7 +98,7 @@ public class PetService(
|
||||
logger.LogInformation("为用户创建默认宠物,UserId: {UserId}", userId);
|
||||
|
||||
// 检查用户是否已有宠物
|
||||
var exists = petRepository.Context.Queryable<Pet>()
|
||||
var exists = petRepository.Context.Queryable<UserPet>()
|
||||
.Any(p => p.UserId == userId);
|
||||
if (exists)
|
||||
{
|
||||
@ -98,16 +106,31 @@ public class PetService(
|
||||
return;
|
||||
}
|
||||
|
||||
// 查询初始进化形态(PreviousEvolutionId 为 null 的即为初始形态)
|
||||
// 查询默认宠物模板(取排序权重最低且状态为Active的模板)
|
||||
var defaultTemplate = await petTemplateRepository.Queryable()
|
||||
.Where(t => t.Status == "Active" && !t.IsDeleted)
|
||||
.OrderBy(t => t.SortOrder)
|
||||
.FirstAsync();
|
||||
|
||||
if (defaultTemplate == null)
|
||||
{
|
||||
logger.LogError("未找到可用的宠物模板");
|
||||
throw new Exception("宠物模板配置缺失");
|
||||
}
|
||||
|
||||
// 查询模板对应的初始进化形态
|
||||
var initialEvolution = await petEvolutionRepository.Queryable()
|
||||
.Where(e => e.PreviousEvolutionId == null && e.Status == "Active")
|
||||
.Where(e => e.TemplateId == defaultTemplate.Id
|
||||
&& e.PreviousEvolutionId == null
|
||||
&& e.Status == "Active")
|
||||
.OrderBy(e => e.StageLevel)
|
||||
.FirstAsync();
|
||||
|
||||
var pet = new Pet
|
||||
var pet = new UserPet
|
||||
{
|
||||
UserId = userId,
|
||||
Name = "小精灵",
|
||||
TemplateId = defaultTemplate.Id,
|
||||
Name = defaultTemplate.Name,
|
||||
CurrentEvolutionId = initialEvolution?.Id ?? 0,
|
||||
GrowthPoints = 0,
|
||||
FeedingCount = 0,
|
||||
@ -156,7 +179,7 @@ public class PetService(
|
||||
}
|
||||
|
||||
var result = await petRepository.UpdateAsync(
|
||||
p => new Pet { Status = "Active" },
|
||||
p => new UserPet { Status = "Active" },
|
||||
p => p.UserId == userId);
|
||||
|
||||
if (!result)
|
||||
@ -217,7 +240,7 @@ public class PetService(
|
||||
await UseTranAsync(async () =>
|
||||
{
|
||||
// 累加成长值和喂养次数
|
||||
var updateResult = await petRepository.Context.Updateable<Pet>()
|
||||
var updateResult = await petRepository.Context.Updateable<UserPet>()
|
||||
.SetColumns(p => p.GrowthPoints == growthAfter)
|
||||
.SetColumns(p => p.FeedingCount == p.FeedingCount + 1)
|
||||
.SetColumns(p => p.UpdatedAt == DateTime.Now)
|
||||
@ -241,7 +264,7 @@ public class PetService(
|
||||
if (nextEvolution != null)
|
||||
{
|
||||
// 触发进化
|
||||
var evolveResult = await petRepository.Context.Updateable<Pet>()
|
||||
var evolveResult = await petRepository.Context.Updateable<UserPet>()
|
||||
.SetColumns(p => p.CurrentEvolutionId == nextEvolution.Id)
|
||||
.SetColumns(p => p.UpdatedAt == DateTime.Now)
|
||||
.SetColumns(p => p.UpdatedBy == userId.ToString())
|
||||
|
||||
@ -495,7 +495,7 @@ public class WxMallService(
|
||||
logger.LogInformation("宠物换肤,UserId: {UserId}, SkinId: {SkinId}", userId, input.SkinId);
|
||||
|
||||
// 查询用户宠物
|
||||
var pet = await exchangeRecordRepository.Context.Queryable<Pet>()
|
||||
var pet = await exchangeRecordRepository.Context.Queryable<UserPet>()
|
||||
.Where(p => p.UserId == userId && !p.IsDeleted)
|
||||
.FirstAsync();
|
||||
|
||||
@ -505,7 +505,7 @@ public class WxMallService(
|
||||
if (input.SkinId == 0)
|
||||
{
|
||||
// 恢复默认皮肤
|
||||
await exchangeRecordRepository.Context.Updateable<Pet>()
|
||||
await exchangeRecordRepository.Context.Updateable<UserPet>()
|
||||
.SetColumns(p => p.CurrentSkinId == 0)
|
||||
.SetColumns(p => p.UpdatedAt == DateTime.Now)
|
||||
.Where(p => p.Id == pet.Id)
|
||||
@ -535,7 +535,7 @@ public class WxMallService(
|
||||
throw new BusinessException("您尚未拥有该皮肤,请先兑换", 400);
|
||||
|
||||
// 换肤
|
||||
await exchangeRecordRepository.Context.Updateable<Pet>()
|
||||
await exchangeRecordRepository.Context.Updateable<UserPet>()
|
||||
.SetColumns(p => p.CurrentSkinId == skin.Id)
|
||||
.SetColumns(p => p.UpdatedAt == DateTime.Now)
|
||||
.Where(p => p.Id == pet.Id)
|
||||
|
||||
Reference in New Issue
Block a user