diff --git a/QYZH.InteractiveMagazine.IService/IPetService.cs b/QYZH.InteractiveMagazine.IService/IPetService.cs index 8e1563c..15e801c 100644 --- a/QYZH.InteractiveMagazine.IService/IPetService.cs +++ b/QYZH.InteractiveMagazine.IService/IPetService.cs @@ -8,7 +8,7 @@ namespace QYZH.InteractiveMagazine.IService; /// /// 宠物服务接口 /// -public interface IPetService : IBaseService +public interface IPetService : IBaseService { /// /// 获取用户宠物信息 diff --git a/QYZH.InteractiveMagazine.Models/Dto/Pet/PetDto.cs b/QYZH.InteractiveMagazine.Models/Dto/Pet/PetDto.cs index a935ab0..9f7f6b3 100644 --- a/QYZH.InteractiveMagazine.Models/Dto/Pet/PetDto.cs +++ b/QYZH.InteractiveMagazine.Models/Dto/Pet/PetDto.cs @@ -15,6 +15,16 @@ public class PetOutput /// public long UserId { get; set; } + /// + /// 宠物模板Id + /// + public long TemplateId { get; set; } + + /// + /// 宠物模板名称 + /// + public string? TemplateName { get; set; } + /// /// 宠物昵称 /// diff --git a/QYZH.InteractiveMagazine.Models/Entity/PetEvolution.cs b/QYZH.InteractiveMagazine.Models/Entity/PetEvolution.cs index 3873010..b243f7c 100644 --- a/QYZH.InteractiveMagazine.Models/Entity/PetEvolution.cs +++ b/QYZH.InteractiveMagazine.Models/Entity/PetEvolution.cs @@ -10,6 +10,13 @@ namespace QYZH.InteractiveMagazine.Models.Entity { public PetEvolution() { } + /// + /// Desc:所属宠物模板Id(关联PetTemplate.Id) + /// Default: + /// Nullable:False + /// + public long TemplateId { get; set; } + /// /// Desc:阶段名称 /// Default: diff --git a/QYZH.InteractiveMagazine.Models/Entity/PetSkin.cs b/QYZH.InteractiveMagazine.Models/Entity/PetSkin.cs index bcbea9a..07c8f32 100644 --- a/QYZH.InteractiveMagazine.Models/Entity/PetSkin.cs +++ b/QYZH.InteractiveMagazine.Models/Entity/PetSkin.cs @@ -10,6 +10,13 @@ namespace QYZH.InteractiveMagazine.Models.Entity { public PetSkin() { } + /// + /// Desc:所属宠物模板Id(关联PetTemplate.Id) + /// Default: + /// Nullable:False + /// + public long TemplateId { get; set; } + /// /// Desc:皮肤名称 /// Default: diff --git a/QYZH.InteractiveMagazine.Models/Entity/PetTemplate.cs b/QYZH.InteractiveMagazine.Models/Entity/PetTemplate.cs new file mode 100644 index 0000000..1453f4b --- /dev/null +++ b/QYZH.InteractiveMagazine.Models/Entity/PetTemplate.cs @@ -0,0 +1,62 @@ +using SqlSugar; + +namespace QYZH.InteractiveMagazine.Models.Entity +{ + /// + /// 宠物模板表(定义不同宠物种类,支持后期多宠物扩展) + /// + [SugarTable("PetTemplate")] + public partial class PetTemplate : SqlSugarBaseEntity + { + public PetTemplate() { } + + /// + /// Desc:模板名称 + /// Default: + /// Nullable:False + /// + public string Name { get; set; } + + /// + /// Desc:模板描述 + /// Default: + /// Nullable:True + /// + public string Description { get; set; } + + /// + /// Desc:默认初始进化形态Id(关联PetEvolution.Id) + /// Default: + /// Nullable:False + /// + public long DefaultEvolutionId { get; set; } + + /// + /// Desc:模板图标地址 + /// Default: + /// Nullable:True + /// + public string IconUrl { get; set; } + + /// + /// Desc:排序权重 + /// Default:0 + /// Nullable:False + /// + public int SortOrder { get; set; } + + /// + /// Desc:模板类型: Normal, Special, Limited + /// Default:Normal + /// Nullable:False + /// + public string Type { get; set; } + + /// + /// Desc:状态: Active, Inactive + /// Default:Active + /// Nullable:False + /// + public new string Status { get; set; } + } +} diff --git a/QYZH.InteractiveMagazine.Models/Entity/Pet.cs b/QYZH.InteractiveMagazine.Models/Entity/UserPet.cs similarity index 85% rename from QYZH.InteractiveMagazine.Models/Entity/Pet.cs rename to QYZH.InteractiveMagazine.Models/Entity/UserPet.cs index 8beb35c..4bf4d26 100644 --- a/QYZH.InteractiveMagazine.Models/Entity/Pet.cs +++ b/QYZH.InteractiveMagazine.Models/Entity/UserPet.cs @@ -3,12 +3,12 @@ using SqlSugar; namespace QYZH.InteractiveMagazine.Models.Entity { /// - ///宠物实例表 + ///用户宠物实例表 /// - [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 /// public long UserId { get; set; } + /// + /// Desc:宠物模板Id(关联PetTemplate.Id) + /// Default: + /// Nullable:False + /// + public long TemplateId { get; set; } + /// /// Desc:宠物昵称 /// Default: diff --git a/QYZH.InteractiveMagazine.Service/CheckInService.cs b/QYZH.InteractiveMagazine.Service/CheckInService.cs index df0913c..a084782 100644 --- a/QYZH.InteractiveMagazine.Service/CheckInService.cs +++ b/QYZH.InteractiveMagazine.Service/CheckInService.cs @@ -60,7 +60,7 @@ public class CheckInService( } // 5. 查询用户宠物(如果有) - var pet = await checkInRecordRepository.Context.Queryable() + var pet = await checkInRecordRepository.Context.Queryable() .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() + var pet = await checkInRecordRepository.Context.Queryable() .Where(p => p.UserId == userId && !p.IsDeleted) .FirstAsync(); diff --git a/QYZH.InteractiveMagazine.Service/PetService.cs b/QYZH.InteractiveMagazine.Service/PetService.cs index 0e3d1bc..b45c6d0 100644 --- a/QYZH.InteractiveMagazine.Service/PetService.cs +++ b/QYZH.InteractiveMagazine.Service/PetService.cs @@ -13,13 +13,14 @@ namespace QYZH.InteractiveMagazine.Service; /// 宠物服务实现 /// public class PetService( - BaseRepository petRepository, + BaseRepository petRepository, + BaseRepository petTemplateRepository, BaseRepository feedingRecordRepository, BaseRepository petEvolutionRepository, BaseRepository petSkinImageRepository, BaseRepository petSkinRepository, ILogger logger) - : BaseRepository, IPetService + : BaseRepository, IPetService { /// /// 获取用户宠物信息(含当前形态名称、皮肤图片序列) @@ -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() + var exists = petRepository.Context.Queryable() .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() + var updateResult = await petRepository.Context.Updateable() .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() + var evolveResult = await petRepository.Context.Updateable() .SetColumns(p => p.CurrentEvolutionId == nextEvolution.Id) .SetColumns(p => p.UpdatedAt == DateTime.Now) .SetColumns(p => p.UpdatedBy == userId.ToString()) diff --git a/QYZH.InteractiveMagazine.Service/WxMallService.cs b/QYZH.InteractiveMagazine.Service/WxMallService.cs index e7db82c..bce4cf8 100644 --- a/QYZH.InteractiveMagazine.Service/WxMallService.cs +++ b/QYZH.InteractiveMagazine.Service/WxMallService.cs @@ -495,7 +495,7 @@ public class WxMallService( logger.LogInformation("宠物换肤,UserId: {UserId}, SkinId: {SkinId}", userId, input.SkinId); // 查询用户宠物 - var pet = await exchangeRecordRepository.Context.Queryable() + var pet = await exchangeRecordRepository.Context.Queryable() .Where(p => p.UserId == userId && !p.IsDeleted) .FirstAsync(); @@ -505,7 +505,7 @@ public class WxMallService( if (input.SkinId == 0) { // 恢复默认皮肤 - await exchangeRecordRepository.Context.Updateable() + await exchangeRecordRepository.Context.Updateable() .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() + await exchangeRecordRepository.Context.Updateable() .SetColumns(p => p.CurrentSkinId == skin.Id) .SetColumns(p => p.UpdatedAt == DateTime.Now) .Where(p => p.Id == pet.Id)