feat: 完成宠物模块重构与社区功能开发

本次提交包含多项核心更新:
1.  重构宠物模块数据结构:拆分皮肤图片为独立表,优化Pet、PetEvolution实体,调整字段类型与冗余字段
2.  新增宠物皮肤图片管理表,支持多进化阶段多图片展示
3.  完善宠物DTO,新增当前形态名称、皮肤信息与图片序列返回
4.  新增社区功能模块:
    - 微信端社区Feed流、点赞/取消点赞接口
    - 后台社区消息管理接口与服务实现
5.  优化商城与背包模块,替换皮肤图片获取逻辑为从新表读取预览图
6.  重构勋章服务,新增规则校验逻辑
7.  调整命名规范,修复原有控制器命名问题
This commit is contained in:
glz
2026-06-05 17:15:30 +08:00
parent eab84747a5
commit 8291b82362
19 changed files with 1753 additions and 182 deletions

View File

@ -41,8 +41,12 @@ public class BagSkinBrief
{
public long SkinId { get; set; }
public string SkinName { get; set; } = string.Empty;
public string? SkinImage { get; set; }
public string Rarity { get; set; } = string.Empty;
/// <summary>
/// 皮肤预览图(取第一张图片)
/// </summary>
public string? PreviewImage { get; set; }
}
/// <summary>

View File

@ -0,0 +1,288 @@
namespace QYZH.InteractiveMagazine.Models.Dto;
#region DTO
/// <summary>
/// 社区消息分页查询输入(后台)
/// </summary>
public class AdminMessageQueryInput : PageQueryModel
{
/// <summary>
/// 期刊ID
/// </summary>
public long? JournalId { get; set; }
/// <summary>
/// 消息类型: Article, Quote, Announcement
/// </summary>
public string? Type { get; set; }
/// <summary>
/// 状态: 0=审核中, 1=已通过, 2=已冻结
/// </summary>
public int? Status { get; set; }
/// <summary>
/// 是否精选: 0=否, 1=是
/// </summary>
public int? IsFeatured { get; set; }
/// <summary>
/// 是否启用
/// </summary>
public bool? IsActive { get; set; }
/// <summary>
/// 内容关键词(模糊查询)
/// </summary>
public string? Keyword { get; set; }
/// <summary>
/// 用户ID
/// </summary>
public long? UserId { get; set; }
}
/// <summary>
/// 社区消息详情输出(后台)
/// </summary>
public class AdminMessageDetailOutput
{
/// <summary>
/// 主键ID
/// </summary>
public long Id { get; set; }
/// <summary>
/// 期刊ID
/// </summary>
public long JournalId { get; set; }
/// <summary>
/// 用户ID
/// </summary>
public long UserId { get; set; }
/// <summary>
/// 用户实例期刊ID
/// </summary>
public long UserJournalId { get; set; }
/// <summary>
/// 期刊任务ID
/// </summary>
public long JournalTaskId { get; set; }
/// <summary>
/// 用户期刊任务回答ID
/// </summary>
public long JournalTaskAnswerId { get; set; }
/// <summary>
/// 消息内容
/// </summary>
public string Content { get; set; } = string.Empty;
/// <summary>
/// 配图
/// </summary>
public string? ImageUrl { get; set; }
/// <summary>
/// 排序权重
/// </summary>
public int SortOrder { get; set; }
/// <summary>
/// 是否启用
/// </summary>
public bool IsActive { get; set; }
/// <summary>
/// 消息类型
/// </summary>
public string Type { get; set; } = string.Empty;
/// <summary>
/// 点赞数
/// </summary>
public int LikeCount { get; set; }
/// <summary>
/// 是否精选
/// </summary>
public int IsFeatured { get; set; }
/// <summary>
/// 状态: 0=审核中, 1=已通过, 2=已冻结
/// </summary>
public int Status { get; set; }
/// <summary>
/// 创建人
/// </summary>
public string? CreatedBy { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreatedAt { get; set; }
/// <summary>
/// 更新人
/// </summary>
public string? UpdatedBy { get; set; }
/// <summary>
/// 更新时间
/// </summary>
public DateTime? UpdatedAt { get; set; }
}
/// <summary>
/// 设置精选入参
/// </summary>
public class AdminSetFeaturedInput
{
/// <summary>
/// 是否精选: 0=否, 1=是
/// </summary>
public int IsFeatured { get; set; }
}
/// <summary>
/// 设置排序权重入参
/// </summary>
public class AdminSetSortOrderInput
{
/// <summary>
/// 排序权重
/// </summary>
public int SortOrder { get; set; }
}
/// <summary>
/// 冻结/解冻入参
/// </summary>
public class AdminFreezeInput
{
/// <summary>
/// 状态: 1=解冻(通过), 2=冻结
/// </summary>
public int Status { get; set; }
}
#endregion
#region DTO
/// <summary>
/// 微信端社区Feed消息输出
/// </summary>
public class WxFeedMessageOutput
{
/// <summary>
/// 消息ID
/// </summary>
public long Id { get; set; }
/// <summary>
/// 期刊ID
/// </summary>
public long JournalId { get; set; }
/// <summary>
/// 作者用户ID
/// </summary>
public long UserId { get; set; }
/// <summary>
/// 消息内容
/// </summary>
public string Content { get; set; } = string.Empty;
/// <summary>
/// 配图
/// </summary>
public string? ImageUrl { get; set; }
/// <summary>
/// 消息类型
/// </summary>
public string Type { get; set; } = string.Empty;
/// <summary>
/// 点赞数
/// </summary>
public int LikeCount { get; set; }
/// <summary>
/// 是否精选
/// </summary>
public int IsFeatured { get; set; }
/// <summary>
/// 当前用户是否已点赞
/// </summary>
public bool IsLiked { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreatedAt { get; set; }
}
/// <summary>
/// 微信端社区Feed输出含游标
/// </summary>
public class WxFeedOutput
{
/// <summary>
/// 消息列表
/// </summary>
public List<WxFeedMessageOutput> Messages { get; set; } = new();
/// <summary>
/// 下一页游标为null表示没有更多数据
/// </summary>
public long? NextCursor { get; set; }
/// <summary>
/// 是否还有更多数据
/// </summary>
public bool HasMore { get; set; }
}
/// <summary>
/// 微信端点赞入参
/// </summary>
public class WxLikeInput
{
/// <summary>
/// 消息ID
/// </summary>
public long MessageId { get; set; }
}
/// <summary>
/// 微信端点赞输出
/// </summary>
public class WxLikeOutput
{
/// <summary>
/// 消息ID
/// </summary>
public long MessageId { get; set; }
/// <summary>
/// 当前点赞数
/// </summary>
public int LikeCount { get; set; }
/// <summary>
/// 是否已点赞
/// </summary>
public bool IsLiked { get; set; }
}
#endregion

View File

@ -30,9 +30,13 @@ public class PetSkinBrief
{
public long SkinId { get; set; }
public string SkinName { get; set; } = string.Empty;
public string? SkinImage { get; set; }
public string? Description { get; set; }
public string Rarity { get; set; } = string.Empty;
/// <summary>
/// 皮肤预览图(取当前进化阶段第一张图片)
/// </summary>
public string? PreviewImage { get; set; }
}
/// <summary>

View File

@ -23,7 +23,12 @@ public class PetOutput
/// <summary>
/// 当前进化形态Id
/// </summary>
public int CurrentEvolutionId { get; set; }
public long CurrentEvolutionId { get; set; }
/// <summary>
/// 当前进化阶段名称
/// </summary>
public string? EvolutionStageName { get; set; }
/// <summary>
/// 当前成长值
@ -35,6 +40,21 @@ public class PetOutput
/// </summary>
public int FeedingCount { get; set; }
/// <summary>
/// 当前皮肤Id
/// </summary>
public long CurrentSkinId { get; set; }
/// <summary>
/// 当前皮肤名称
/// </summary>
public string? CurrentSkinName { get; set; }
/// <summary>
/// 当前形态+当前皮肤 的图片列表按SortOrder排序
/// </summary>
public List<SkinImageOutput> CurrentImages { get; set; } = new();
/// <summary>
/// 宠物类型: Normal
/// </summary>
@ -51,6 +71,27 @@ public class PetOutput
public DateTime CreatedAt { get; set; }
}
/// <summary>
/// 皮肤图片输出
/// </summary>
public class SkinImageOutput
{
/// <summary>
/// 图片Id
/// </summary>
public long Id { get; set; }
/// <summary>
/// 图片地址
/// </summary>
public string ImageUrl { get; set; } = string.Empty;
/// <summary>
/// 图片顺序
/// </summary>
public int SortOrder { get; set; }
}
/// <summary>
/// 喂养宠物输入
/// </summary>

View File

@ -8,64 +8,85 @@ namespace QYZH.InteractiveMagazine.Models.Entity
[SugarTable("Pet")]
public partial class Pet : SqlSugarBaseEntity
{
public Pet(){
public Pet()
{
}
}
/// <summary>
/// Desc:用户Id
/// Default:
/// Nullable:False
/// </summary>
public long UserId {get;set;}
public long UserId { get; set; }
/// <summary>
/// Desc:宠物昵称
/// Default:
/// Nullable:True
/// </summary>
public string Name {get;set;}
/// <summary>
/// Desc:宠物昵称
/// Default:
/// Nullable:True
/// </summary>
public string Name { get; set; }
/// <summary>
/// Desc:当前进化形态Id
/// Default:
/// Nullable:False
/// </summary>
public int CurrentEvolutionId {get;set;}
/// <summary>
/// Desc:当前进化形态Id
/// Default:
/// Nullable:False
/// </summary>
public long CurrentEvolutionId { get; set; }
/// <summary>
/// Desc:当前成长值
/// Default:0
/// Nullable:False
/// </summary>
public int GrowthPoints {get;set;}
/// <summary>
/// Desc:当前成长值
/// Default:0
/// Nullable:False
/// </summary>
public int GrowthPoints { get; set; }
/// <summary>
/// Desc:累计喂养次数
/// Default:0
/// Nullable:False
/// </summary>
public int FeedingCount {get;set;}
/// <summary>
/// Desc:累计喂养次数
/// Default:0
/// Nullable:False
/// </summary>
public int FeedingCount { get; set; }
/// <summary>
/// Desc:当前皮肤Id0为默认皮肤
/// Default:0
/// Nullable:False
/// </summary>
public long CurrentSkinId {get;set;}
/// <summary>
/// Desc:当前皮肤Id0为默认皮肤
/// Default:0
/// Nullable:False
/// </summary>
public long CurrentSkinId { get; set; }
/// <summary>
/// Desc:宠物类型
/// Default:Normal
/// Nullable:False
/// </summary>
public string Type {get;set;}
/// <summary>
/// Desc:宠物类型
/// Default:Normal
/// Nullable:False
/// </summary>
public string Type { get; set; }
/// <summary>
/// Desc:状态: Inactive, Active, Sleeping
/// Default:Inactive
/// Nullable:False
/// </summary>
public string Status {get;set;}
/// <summary>
/// Desc:状态: Inactive, Active, Sleeping
/// Default:Inactive
/// Nullable:False
/// </summary>
public new string Status { get; set; }
/// <summary>
/// 理解力
/// </summary>
public int Comprehension { get; set; }
/// <summary>
/// 判断力
/// </summary>
public int Judgment { get; set; }
/// <summary>
/// 表达力
/// </summary>
public int Expression { get; set; }
/// <summary>
/// 说服力
/// </summary>
public int Persuasiveness { get; set; }
}
}

View File

@ -8,86 +8,76 @@ namespace QYZH.InteractiveMagazine.Models.Entity
[SugarTable("PetEvolution")]
public partial class PetEvolution : SqlSugarBaseEntity
{
public PetEvolution(){
public PetEvolution() { }
/// <summary>
/// Desc:阶段名称
/// Default:
/// Nullable:False
/// </summary>
public string StageName { get; set; }
}
/// <summary>
/// Desc:阶段等级
/// Default:
/// Nullable:False
/// </summary>
public int StageLevel { get; set; }
/// <summary>
/// Desc:阶段名称
/// Default:
/// Nullable:False
/// </summary>
public string StageName {get;set;}
/// <summary>
/// Desc:进化所需成长值
/// Default:
/// Nullable:False
/// </summary>
public int RequiredGrowth { get; set; }
/// <summary>
/// Desc:阶段等级
/// Default:
/// Nullable:False
/// </summary>
public int StageLevel {get;set;}
/// <summary>
/// Desc:前一形态Idnull表示初始形态
/// Default:
/// Nullable:True
/// </summary>
public long? PreviousEvolutionId { get; set; }
/// <summary>
/// Desc:进化所需成长值
/// Default:
/// Nullable:False
/// </summary>
public int RequiredGrowth {get;set;}
/// <summary>
/// Desc:基础力量
/// Default:0
/// Nullable:False
/// </summary>
public int BaseStrength { get; set; }
/// <summary>
/// Desc:形态图片
/// Default:
/// Nullable:True
/// </summary>
public string ImageUrl {get;set;}
/// <summary>
/// Desc:基础敏捷
/// Default:0
/// Nullable:False
/// </summary>
public int BaseAgility { get; set; }
/// <summary>
/// Desc:前一形态Id
/// Default:
/// Nullable:True
/// </summary>
public int? PreviousEvolutionId {get;set;}
/// <summary>
/// Desc:基础智力
/// Default:0
/// Nullable:False
/// </summary>
public int BaseIntelligence { get; set; }
/// <summary>
/// Desc:基础力
/// Default:0
/// Nullable:False
/// </summary>
public int BaseStrength {get;set;}
/// <summary>
/// Desc:基础
/// Default:0
/// Nullable:False
/// </summary>
public int BaseCharm { get; set; }
/// <summary>
/// Desc:基础敏捷
/// Default:0
/// Nullable:False
/// </summary>
public int BaseAgility {get;set;}
/// <summary>
/// Desc:进化类型: Normal, Special
/// Default:Normal
/// Nullable:False
/// </summary>
public string Type { get; set; }
/// <summary>
/// Desc:基础智力
/// Default:0
/// Nullable:False
/// </summary>
public int BaseIntelligence {get;set;}
/// <summary>
/// Desc:基础魅力
/// Default:0
/// Nullable:False
/// </summary>
public int BaseCharm {get;set;}
/// <summary>
/// Desc:进化类型: Normal, Special
/// Default:Normal
/// Nullable:False
/// </summary>
public string Type {get;set;}
/// <summary>
/// Desc:状态: Active, Inactive
/// Default:Active
/// Nullable:False
/// </summary>
public string Status {get;set;}
/// <summary>
/// Desc:状态: Active, Inactive
/// Default:Active
/// Nullable:False
/// </summary>
public new string Status { get; set; }
}
}

View File

@ -17,13 +17,6 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// </summary>
public string Name { get; set; }
/// <summary>
/// Desc:皮肤图片
/// Default:
/// Nullable:True
/// </summary>
public string ImageUrl { get; set; }
/// <summary>
/// Desc:描述/特效说明
/// Default:
@ -31,13 +24,6 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// </summary>
public string Description { get; set; }
/// <summary>
/// Desc:关联商品Id用于兑换
/// Default:
/// Nullable:False
/// </summary>
public long ProductId { get; set; }
/// <summary>
/// Desc:稀有度: Normal, Rare, Epic, Legendary
/// Default:Normal
@ -51,5 +37,12 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Nullable:False
/// </summary>
public int SortOrder { get; set; }
/// <summary>
/// Desc:皮肤类型: Normal, Limited, Event
/// Default:Normal
/// Nullable:False
/// </summary>
public string Type { get; set; }
}
}

View File

@ -0,0 +1,48 @@
using SqlSugar;
namespace QYZH.InteractiveMagazine.Models.Entity
{
/// <summary>
/// 宠物皮肤图片表(每个皮肤在每个进化阶段下有一组有序图片,用于动态表示)
/// </summary>
[SugarTable("PetSkinImage")]
public partial class PetSkinImage : SqlSugarBaseEntity
{
public PetSkinImage() { }
/// <summary>
/// Desc:皮肤Id关联PetSkin.Id0表示默认皮肤的图片
/// Default:
/// Nullable:False
/// </summary>
public long SkinId { get; set; }
/// <summary>
/// Desc:进化阶段Id关联PetEvolution.Id
/// Default:
/// Nullable:False
/// </summary>
public long EvolutionStageId { get; set; }
/// <summary>
/// Desc:图片地址
/// Default:
/// Nullable:False
/// </summary>
public string ImageUrl { get; set; }
/// <summary>
/// Desc:图片顺序(动画帧序号)
/// Default:0
/// Nullable:False
/// </summary>
public int SortOrder { get; set; }
/// <summary>
/// Desc:图片类型: Normal, Special
/// Default:Normal
/// Nullable:False
/// </summary>
public string Type { get; set; }
}
}