refactor(pet): 重构宠物模块实体与接口
1. 将原Pet实体重命名为UserPet,新增PetTemplate模板实体拆分宠物模板与实例数据 2. 调整IPetService泛型参数为IBaseService<UserPet> 3. 补充宠物模板相关字段与查询逻辑,完善创建默认宠物的流程 4. 替换所有Pet实体引用为UserPet,修正相关服务层查询与更新逻辑
This commit is contained in:
@ -8,7 +8,7 @@ namespace QYZH.InteractiveMagazine.IService;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 宠物服务接口
|
/// 宠物服务接口
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IPetService : IBaseService<Pet>
|
public interface IPetService : IBaseService<UserPet>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取用户宠物信息
|
/// 获取用户宠物信息
|
||||||
|
|||||||
@ -15,6 +15,16 @@ public class PetOutput
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public long UserId { get; set; }
|
public long UserId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 宠物模板Id
|
||||||
|
/// </summary>
|
||||||
|
public long TemplateId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 宠物模板名称
|
||||||
|
/// </summary>
|
||||||
|
public string? TemplateName { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 宠物昵称
|
/// 宠物昵称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -10,6 +10,13 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
|||||||
{
|
{
|
||||||
public PetEvolution() { }
|
public PetEvolution() { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Desc:所属宠物模板Id(关联PetTemplate.Id)
|
||||||
|
/// Default:
|
||||||
|
/// Nullable:False
|
||||||
|
/// </summary>
|
||||||
|
public long TemplateId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:阶段名称
|
/// Desc:阶段名称
|
||||||
/// Default:
|
/// Default:
|
||||||
|
|||||||
@ -10,6 +10,13 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
|||||||
{
|
{
|
||||||
public PetSkin() { }
|
public PetSkin() { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Desc:所属宠物模板Id(关联PetTemplate.Id)
|
||||||
|
/// Default:
|
||||||
|
/// Nullable:False
|
||||||
|
/// </summary>
|
||||||
|
public long TemplateId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:皮肤名称
|
/// Desc:皮肤名称
|
||||||
/// Default:
|
/// 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
|
namespace QYZH.InteractiveMagazine.Models.Entity
|
||||||
{
|
{
|
||||||
///<summary>
|
///<summary>
|
||||||
///宠物实例表
|
///用户宠物实例表
|
||||||
///</summary>
|
///</summary>
|
||||||
[SugarTable("Pet")]
|
[SugarTable("UserPet")]
|
||||||
public partial class Pet : SqlSugarBaseEntity
|
public partial class UserPet : SqlSugarBaseEntity
|
||||||
{
|
{
|
||||||
public Pet()
|
public UserPet()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
@ -20,6 +20,13 @@ namespace QYZH.InteractiveMagazine.Models.Entity
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public long UserId { get; set; }
|
public long UserId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Desc:宠物模板Id(关联PetTemplate.Id)
|
||||||
|
/// Default:
|
||||||
|
/// Nullable:False
|
||||||
|
/// </summary>
|
||||||
|
public long TemplateId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Desc:宠物昵称
|
/// Desc:宠物昵称
|
||||||
/// Default:
|
/// Default:
|
||||||
@ -60,7 +60,7 @@ public class CheckInService(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 5. 查询用户宠物(如果有)
|
// 5. 查询用户宠物(如果有)
|
||||||
var pet = await checkInRecordRepository.Context.Queryable<Pet>()
|
var pet = await checkInRecordRepository.Context.Queryable<UserPet>()
|
||||||
.Where(p => p.UserId == userId && !p.IsDeleted)
|
.Where(p => p.UserId == userId && !p.IsDeleted)
|
||||||
.FirstAsync();
|
.FirstAsync();
|
||||||
|
|
||||||
@ -258,7 +258,7 @@ public class CheckInService(
|
|||||||
throw new BusinessException("用户不存在", 404);
|
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)
|
.Where(p => p.UserId == userId && !p.IsDeleted)
|
||||||
.FirstAsync();
|
.FirstAsync();
|
||||||
|
|
||||||
|
|||||||
@ -13,13 +13,14 @@ namespace QYZH.InteractiveMagazine.Service;
|
|||||||
/// 宠物服务实现
|
/// 宠物服务实现
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PetService(
|
public class PetService(
|
||||||
BaseRepository<Pet> petRepository,
|
BaseRepository<UserPet> petRepository,
|
||||||
|
BaseRepository<PetTemplate> petTemplateRepository,
|
||||||
BaseRepository<PetFeedingRecord> feedingRecordRepository,
|
BaseRepository<PetFeedingRecord> feedingRecordRepository,
|
||||||
BaseRepository<PetEvolution> petEvolutionRepository,
|
BaseRepository<PetEvolution> petEvolutionRepository,
|
||||||
BaseRepository<PetSkinImage> petSkinImageRepository,
|
BaseRepository<PetSkinImage> petSkinImageRepository,
|
||||||
BaseRepository<PetSkin> petSkinRepository,
|
BaseRepository<PetSkin> petSkinRepository,
|
||||||
ILogger<PetService> logger)
|
ILogger<PetService> logger)
|
||||||
: BaseRepository<Pet>, IPetService
|
: BaseRepository<UserPet>, IPetService
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取用户宠物信息(含当前形态名称、皮肤图片序列)
|
/// 获取用户宠物信息(含当前形态名称、皮肤图片序列)
|
||||||
@ -39,6 +40,11 @@ public class PetService(
|
|||||||
.Where(e => e.Id == pet.CurrentEvolutionId)
|
.Where(e => e.Id == pet.CurrentEvolutionId)
|
||||||
.FirstAsync();
|
.FirstAsync();
|
||||||
|
|
||||||
|
// 查询宠物模板名称
|
||||||
|
var template = await petTemplateRepository.Queryable()
|
||||||
|
.Where(t => t.Id == pet.TemplateId && !t.IsDeleted)
|
||||||
|
.FirstAsync();
|
||||||
|
|
||||||
// 查询当前皮肤名称
|
// 查询当前皮肤名称
|
||||||
string? skinName = null;
|
string? skinName = null;
|
||||||
if (pet.CurrentSkinId > 0)
|
if (pet.CurrentSkinId > 0)
|
||||||
@ -68,6 +74,8 @@ public class PetService(
|
|||||||
{
|
{
|
||||||
Id = pet.Id,
|
Id = pet.Id,
|
||||||
UserId = pet.UserId,
|
UserId = pet.UserId,
|
||||||
|
TemplateId = pet.TemplateId,
|
||||||
|
TemplateName = template?.Name,
|
||||||
Name = pet.Name,
|
Name = pet.Name,
|
||||||
CurrentEvolutionId = pet.CurrentEvolutionId,
|
CurrentEvolutionId = pet.CurrentEvolutionId,
|
||||||
EvolutionStageName = evolution?.StageName,
|
EvolutionStageName = evolution?.StageName,
|
||||||
@ -90,7 +98,7 @@ public class PetService(
|
|||||||
logger.LogInformation("为用户创建默认宠物,UserId: {UserId}", userId);
|
logger.LogInformation("为用户创建默认宠物,UserId: {UserId}", userId);
|
||||||
|
|
||||||
// 检查用户是否已有宠物
|
// 检查用户是否已有宠物
|
||||||
var exists = petRepository.Context.Queryable<Pet>()
|
var exists = petRepository.Context.Queryable<UserPet>()
|
||||||
.Any(p => p.UserId == userId);
|
.Any(p => p.UserId == userId);
|
||||||
if (exists)
|
if (exists)
|
||||||
{
|
{
|
||||||
@ -98,16 +106,31 @@ public class PetService(
|
|||||||
return;
|
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()
|
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)
|
.OrderBy(e => e.StageLevel)
|
||||||
.FirstAsync();
|
.FirstAsync();
|
||||||
|
|
||||||
var pet = new Pet
|
var pet = new UserPet
|
||||||
{
|
{
|
||||||
UserId = userId,
|
UserId = userId,
|
||||||
Name = "小精灵",
|
TemplateId = defaultTemplate.Id,
|
||||||
|
Name = defaultTemplate.Name,
|
||||||
CurrentEvolutionId = initialEvolution?.Id ?? 0,
|
CurrentEvolutionId = initialEvolution?.Id ?? 0,
|
||||||
GrowthPoints = 0,
|
GrowthPoints = 0,
|
||||||
FeedingCount = 0,
|
FeedingCount = 0,
|
||||||
@ -156,7 +179,7 @@ public class PetService(
|
|||||||
}
|
}
|
||||||
|
|
||||||
var result = await petRepository.UpdateAsync(
|
var result = await petRepository.UpdateAsync(
|
||||||
p => new Pet { Status = "Active" },
|
p => new UserPet { Status = "Active" },
|
||||||
p => p.UserId == userId);
|
p => p.UserId == userId);
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
@ -217,7 +240,7 @@ public class PetService(
|
|||||||
await UseTranAsync(async () =>
|
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.GrowthPoints == growthAfter)
|
||||||
.SetColumns(p => p.FeedingCount == p.FeedingCount + 1)
|
.SetColumns(p => p.FeedingCount == p.FeedingCount + 1)
|
||||||
.SetColumns(p => p.UpdatedAt == DateTime.Now)
|
.SetColumns(p => p.UpdatedAt == DateTime.Now)
|
||||||
@ -241,7 +264,7 @@ public class PetService(
|
|||||||
if (nextEvolution != null)
|
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.CurrentEvolutionId == nextEvolution.Id)
|
||||||
.SetColumns(p => p.UpdatedAt == DateTime.Now)
|
.SetColumns(p => p.UpdatedAt == DateTime.Now)
|
||||||
.SetColumns(p => p.UpdatedBy == userId.ToString())
|
.SetColumns(p => p.UpdatedBy == userId.ToString())
|
||||||
|
|||||||
@ -495,7 +495,7 @@ public class WxMallService(
|
|||||||
logger.LogInformation("宠物换肤,UserId: {UserId}, SkinId: {SkinId}", userId, input.SkinId);
|
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)
|
.Where(p => p.UserId == userId && !p.IsDeleted)
|
||||||
.FirstAsync();
|
.FirstAsync();
|
||||||
|
|
||||||
@ -505,7 +505,7 @@ public class WxMallService(
|
|||||||
if (input.SkinId == 0)
|
if (input.SkinId == 0)
|
||||||
{
|
{
|
||||||
// 恢复默认皮肤
|
// 恢复默认皮肤
|
||||||
await exchangeRecordRepository.Context.Updateable<Pet>()
|
await exchangeRecordRepository.Context.Updateable<UserPet>()
|
||||||
.SetColumns(p => p.CurrentSkinId == 0)
|
.SetColumns(p => p.CurrentSkinId == 0)
|
||||||
.SetColumns(p => p.UpdatedAt == DateTime.Now)
|
.SetColumns(p => p.UpdatedAt == DateTime.Now)
|
||||||
.Where(p => p.Id == pet.Id)
|
.Where(p => p.Id == pet.Id)
|
||||||
@ -535,7 +535,7 @@ public class WxMallService(
|
|||||||
throw new BusinessException("您尚未拥有该皮肤,请先兑换", 400);
|
throw new BusinessException("您尚未拥有该皮肤,请先兑换", 400);
|
||||||
|
|
||||||
// 换肤
|
// 换肤
|
||||||
await exchangeRecordRepository.Context.Updateable<Pet>()
|
await exchangeRecordRepository.Context.Updateable<UserPet>()
|
||||||
.SetColumns(p => p.CurrentSkinId == skin.Id)
|
.SetColumns(p => p.CurrentSkinId == skin.Id)
|
||||||
.SetColumns(p => p.UpdatedAt == DateTime.Now)
|
.SetColumns(p => p.UpdatedAt == DateTime.Now)
|
||||||
.Where(p => p.Id == pet.Id)
|
.Where(p => p.Id == pet.Id)
|
||||||
|
|||||||
Reference in New Issue
Block a user