refactor: 批量新增枚举类型并完成实体、DTO、服务层枚举替换

- 新增30+业务枚举类型覆盖用户、宠物、商城、社区、积分等模块
- 完成实体类、DTO、服务层的字符串枚举替换为强类型枚举
- 修复用户状态枚举名称变更,将Frozen改为Disabled
- 新增批量发布社区消息接口与控制器实现
- 新增操作日志、积分管理、补偿任务相关服务与DTO
This commit is contained in:
glz
2026-06-08 16:57:44 +08:00
parent 698c404b72
commit 78b686f9e5
116 changed files with 4861 additions and 307 deletions

View File

@ -1,4 +1,5 @@
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Dto;
@ -20,7 +21,7 @@ public class AdminUserInput
/// <summary>
/// 管理员类型: SuperAdmin, Editor
/// </summary>
public string Type { get; set; } = "Editor";
public AdminUserTypeEnum Type { get; set; } = AdminUserTypeEnum.Editor;
/// <summary>
/// 状态: Active, Inactive
@ -92,5 +93,5 @@ public class AdminUserQueryInput : PageQueryModel
/// <summary>
/// 状态
/// </summary>
public string? Status { get; set; }
public int? Status { get; set; }
}

View File

@ -32,10 +32,6 @@ public class AdminMessageQueryInput : PageQueryModel
/// </summary>
public bool? IsActive { get; set; }
/// <summary>
/// 内容关键词(模糊查询)
/// </summary>
public string? Keyword { get; set; }
/// <summary>
/// 用户ID
@ -172,6 +168,17 @@ public class AdminFreezeInput
public int Status { get; set; }
}
/// <summary>
/// 批量发布消息入参
/// </summary>
public class AdminBatchPublishInput
{
/// <summary>
/// 消息ID列表
/// </summary>
public List<long> Ids { get; set; } = new();
}
#endregion
#region DTO

View File

@ -0,0 +1,241 @@
using System.ComponentModel.DataAnnotations;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Dto.Compensation;
/// <summary>
/// 补偿任务分页查询输入
/// </summary>
public class CompensationTaskQueryInput : PageQueryModel
{
/// <summary>
/// 按用户Id筛选
/// </summary>
public long? UserId { get; set; }
/// <summary>
/// 按任务类型筛选PetFeeding/UserPoints/UserGrowth/SendNotification
/// </summary>
public CompensationTaskTypeEnum? TaskType { get; set; }
/// <summary>
/// 按状态筛选Pending/Processing/Success/Failed/Cancelled
/// </summary>
public CompensationTaskStatusEnum? Status { get; set; }
/// <summary>
/// 按业务来源筛选CheckIn/Purchase/Activity等
/// </summary>
public string? BusinessSource { get; set; }
}
/// <summary>
/// 手动重试补偿任务输入
/// </summary>
public class CompensationRetryInput
{
/// <summary>
/// 重试原因
/// </summary>
[Required(ErrorMessage = "重试原因不能为空")]
public string Reason { get; set; } = string.Empty;
}
/// <summary>
/// 标记补偿任务已解决输入
/// </summary>
public class CompensationResolveInput
{
/// <summary>
/// 处理说明
/// </summary>
[Required(ErrorMessage = "处理说明不能为空")]
public string ResolveNote { get; set; } = string.Empty;
}
/// <summary>
/// 补偿任务管理输出(含用户昵称)
/// </summary>
public class CompensationManageOutput
{
/// <summary>
/// 任务Id
/// </summary>
public long Id { get; set; }
/// <summary>
/// 任务类型
/// </summary>
public CompensationTaskTypeEnum TaskType { get; set; }
/// <summary>
/// 业务来源
/// </summary>
public string BusinessSource { get; set; } = string.Empty;
/// <summary>
/// 关联业务Id
/// </summary>
public string? BusinessId { get; set; }
/// <summary>
/// 用户Id
/// </summary>
public long UserId { get; set; }
/// <summary>
/// 用户昵称
/// </summary>
public string? UserName { get; set; }
/// <summary>
/// 处理参数JSON
/// </summary>
public string Payload { get; set; } = string.Empty;
/// <summary>
/// 异常消息
/// </summary>
public string ErrorMessage { get; set; } = string.Empty;
/// <summary>
/// 异常来源
/// </summary>
public string ErrorSource { get; set; } = string.Empty;
/// <summary>
/// 已重试次数
/// </summary>
public int RetryCount { get; set; }
/// <summary>
/// 最大重试次数
/// </summary>
public int MaxRetries { get; set; }
/// <summary>
/// 状态
/// </summary>
public CompensationTaskStatusEnum Status { get; set; }
/// <summary>
/// 最后处理时间
/// </summary>
public DateTime? ProcessedAt { get; set; }
/// <summary>
/// 计划执行时间
/// </summary>
public DateTime? ScheduledAt { get; set; }
/// <summary>
/// 处理结果
/// </summary>
public string? ResultMessage { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreatedAt { get; set; }
}
/// <summary>
/// 补偿任务详情输出(含审计字段)
/// </summary>
public class CompensationManageDetailOutput
{
/// <summary>
/// 任务Id
/// </summary>
public long Id { get; set; }
/// <summary>
/// 任务类型
/// </summary>
public CompensationTaskTypeEnum TaskType { get; set; }
/// <summary>
/// 业务来源
/// </summary>
public string BusinessSource { get; set; } = string.Empty;
/// <summary>
/// 关联业务Id
/// </summary>
public string? BusinessId { get; set; }
/// <summary>
/// 用户Id
/// </summary>
public long UserId { get; set; }
/// <summary>
/// 用户昵称
/// </summary>
public string? UserName { get; set; }
/// <summary>
/// 处理参数JSON
/// </summary>
public string Payload { get; set; } = string.Empty;
/// <summary>
/// 异常消息
/// </summary>
public string ErrorMessage { get; set; } = string.Empty;
/// <summary>
/// 异常来源
/// </summary>
public string ErrorSource { get; set; } = string.Empty;
/// <summary>
/// 已重试次数
/// </summary>
public int RetryCount { get; set; }
/// <summary>
/// 最大重试次数
/// </summary>
public int MaxRetries { get; set; }
/// <summary>
/// 状态
/// </summary>
public CompensationTaskStatusEnum Status { get; set; }
/// <summary>
/// 最后处理时间
/// </summary>
public DateTime? ProcessedAt { get; set; }
/// <summary>
/// 计划执行时间
/// </summary>
public DateTime? ScheduledAt { get; set; }
/// <summary>
/// 处理结果
/// </summary>
public string? ResultMessage { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreatedAt { get; set; }
/// <summary>
/// 创建人
/// </summary>
public string? CreatedBy { get; set; }
/// <summary>
/// 修改人
/// </summary>
public string? UpdatedBy { get; set; }
/// <summary>
/// 修改时间
/// </summary>
public DateTime? UpdatedAt { get; set; }
}

View File

@ -1,56 +1,16 @@
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Dto.Compensation;
/// <summary>
/// 补偿任务类型常量
/// </summary>
public static class CompensationTaskType
{
/// <summary>
/// 宠物喂养补偿
/// Payload: { "PetId": long, "GrowthPoints": int }
/// </summary>
public const string PetFeeding = "PetFeeding";
/// <summary>
/// 用户积分补偿
/// Payload: { "Points": int, "ChangeType": string, "Description": string }
/// </summary>
public const string UserPoints = "UserPoints";
/// <summary>
/// 用户成长值补偿
/// Payload: { "GrowthPoints": int }
/// </summary>
public const string UserGrowth = "UserGrowth";
/// <summary>
/// 发送通知补偿
/// Payload: { "TemplateId": string, "Data": object }
/// </summary>
public const string SendNotification = "SendNotification";
}
/// <summary>
/// 补偿任务状态常量
/// </summary>
public static class CompensationTaskStatus
{
public const string Pending = "Pending";
public const string Processing = "Processing";
public const string Success = "Success";
public const string Failed = "Failed";
public const string Cancelled = "Cancelled";
}
/// <summary>
/// 创建补偿任务输入
/// </summary>
public class CreateCompensationTaskInput
{
/// <summary>
/// 任务类型(使用 CompensationTaskType 常量
/// 任务类型(使用 CompensationTaskTypeEnum 枚举
/// </summary>
public string TaskType { get; set; } = string.Empty;
public CompensationTaskTypeEnum TaskType { get; set; }
/// <summary>
/// 业务来源(如 CheckIn、Purchase
@ -94,7 +54,7 @@ public class CreateCompensationTaskInput
public class CompensationTaskOutput
{
public long Id { get; set; }
public string TaskType { get; set; } = string.Empty;
public CompensationTaskTypeEnum TaskType { get; set; }
public string BusinessSource { get; set; } = string.Empty;
public string? BusinessId { get; set; }
public long UserId { get; set; }
@ -103,7 +63,7 @@ public class CompensationTaskOutput
public string ErrorSource { get; set; } = string.Empty;
public int RetryCount { get; set; }
public int MaxRetries { get; set; }
public string Status { get; set; } = string.Empty;
public CompensationTaskStatusEnum Status { get; set; }
public DateTime? ProcessedAt { get; set; }
public DateTime? ScheduledAt { get; set; }
public string? ResultMessage { get; set; }
@ -118,12 +78,12 @@ public class GetCompensationTasksInput
/// <summary>
/// 按状态筛选
/// </summary>
public string? Status { get; set; }
public CompensationTaskStatusEnum? Status { get; set; }
/// <summary>
/// 按任务类型筛选
/// </summary>
public string? TaskType { get; set; }
public CompensationTaskTypeEnum? TaskType { get; set; }
/// <summary>
/// 按业务来源筛选
@ -142,9 +102,9 @@ public class GetCompensationTasksInput
public class UpdateCompensationStatusInput
{
/// <summary>
/// 目标状态(使用 CompensationTaskStatus 常量
/// 目标状态(使用 CompensationTaskStatusEnum 枚举
/// </summary>
public string Status { get; set; } = string.Empty;
public CompensationTaskStatusEnum Status { get; set; }
/// <summary>
/// 处理结果描述

View File

@ -1,3 +1,5 @@
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Dto;
/// <summary>
@ -18,7 +20,7 @@ public class BindJournalInput
/// <summary>
/// 关联类型: Read(已读), Favorite(收藏), Subscribe(订阅),默认 Subscribe
/// </summary>
public string Type { get; set; } = "Subscribe";
public string Type { get; set; } = UserJournalTypeEnum.Subscribe.ToString();
}
/// <summary>

View File

@ -1,4 +1,5 @@
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Dto;

View File

@ -1,3 +1,5 @@
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Dto;
/// <summary>
@ -28,7 +30,7 @@ public class MedalInput
/// <summary>
/// 勋章的类型: Pet, Community
/// </summary>
public string Type { get; set; } = "Pet";
public string Type { get; set; } = MedalTypeEnum.Pet.ToString();
/// <summary>
/// 书id

View File

@ -0,0 +1,201 @@
namespace QYZH.InteractiveMagazine.Models.Dto;
/// <summary>
/// 操作类型常量
/// </summary>
public static class OperationLogActionType
{
/// <summary>
/// 手动增加积分
/// </summary>
public const string ManualAddPoints = "ManualAddPoints";
/// <summary>
/// 手动扣除积分
/// </summary>
public const string ManualDeductPoints = "ManualDeductPoints";
/// <summary>
/// 补偿任务手动重试
/// </summary>
public const string CompensationRetry = "CompensationRetry";
/// <summary>
/// 补偿任务标记已解决
/// </summary>
public const string CompensationResolve = "CompensationResolve";
}
/// <summary>
/// 目标类型常量
/// </summary>
public static class OperationLogTargetType
{
/// <summary>
/// 用户
/// </summary>
public const string User = "User";
/// <summary>
/// 补偿任务
/// </summary>
public const string CompensationTask = "CompensationTask";
}
/// <summary>
/// 操作日志分页查询输入
/// </summary>
public class OperationLogQueryInput : PageQueryModel
{
/// <summary>
/// 按操作人用户名筛选(模糊查询)
/// </summary>
public string? OperatorName { get; set; }
/// <summary>
/// 按操作类型筛选
/// </summary>
public string? ActionType { get; set; }
/// <summary>
/// 按目标类型筛选
/// </summary>
public string? TargetType { get; set; }
/// <summary>
/// 按目标记录Id筛选
/// </summary>
public long? TargetId { get; set; }
}
/// <summary>
/// 操作日志输出
/// </summary>
public class OperationLogOutput
{
/// <summary>
/// 记录Id
/// </summary>
public long Id { get; set; }
/// <summary>
/// 操作人Id
/// </summary>
public long OperatorId { get; set; }
/// <summary>
/// 操作人用户名
/// </summary>
public string OperatorName { get; set; } = string.Empty;
/// <summary>
/// 操作类型
/// </summary>
public string ActionType { get; set; } = string.Empty;
/// <summary>
/// 目标类型
/// </summary>
public string TargetType { get; set; } = string.Empty;
/// <summary>
/// 目标记录Id
/// </summary>
public long TargetId { get; set; }
/// <summary>
/// 目标名称
/// </summary>
public string? TargetName { get; set; }
/// <summary>
/// 操作详情
/// </summary>
public string? Detail { get; set; }
/// <summary>
/// IP地址
/// </summary>
public string? IpAddress { get; set; }
/// <summary>
/// 操作时间
/// </summary>
public DateTime CreatedAt { get; set; }
}
/// <summary>
/// 操作日志详情输出
/// </summary>
public class OperationLogDetailOutput
{
/// <summary>
/// 记录Id
/// </summary>
public long Id { get; set; }
/// <summary>
/// 操作类型
/// </summary>
public string ActionType { get; set; } = string.Empty;
/// <summary>
/// 目标类型
/// </summary>
public string TargetType { get; set; } = string.Empty;
/// <summary>
/// 目标记录Id
/// </summary>
public long TargetId { get; set; }
/// <summary>
/// 目标名称
/// </summary>
public string? TargetName { get; set; }
/// <summary>
/// 操作详情
/// </summary>
public string? Detail { get; set; }
/// <summary>
/// IP地址
/// </summary>
public string? IpAddress { get; set; }
/// <summary>
/// 操作时间
/// </summary>
public DateTime CreatedAt { get; set; }
/// <summary>
/// 操作人用户名
/// </summary>
public string OperatorName { get; set; } = string.Empty;
/// <summary>
/// 操作人手机号(管理员表无此字段时可为空)
/// </summary>
public string? OperatorPhone { get; set; }
/// <summary>
/// 操作人角色/类型
/// </summary>
public string? OperatorRole { get; set; }
/// <summary>
/// 被操作人用户名(当 TargetType 为 User 时)
/// </summary>
public string? TargetUserName { get; set; }
/// <summary>
/// 被操作人手机号(当 TargetType 为 User 时)
/// </summary>
public string? TargetUserPhone { get; set; }
/// <summary>
/// 被操作人头像(当 TargetType 为 User 时)
/// </summary>
public string? TargetUserAvatar { get; set; }
}

View File

@ -0,0 +1,98 @@
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Dto.Pet;
/// <summary>
/// 进化阶段创建/更新输入
/// </summary>
public class PetEvolutionInput
{
/// <summary>
/// 所属宠物模板Id
/// </summary>
public long TemplateId { get; set; }
/// <summary>
/// 阶段名称
/// </summary>
public string StageName { get; set; } = string.Empty;
/// <summary>
/// 阶段等级
/// </summary>
public int StageLevel { get; set; }
/// <summary>
/// 进化所需成长值
/// </summary>
public int RequiredGrowth { get; set; }
/// <summary>
/// 前一形态Idnull表示初始形态
/// </summary>
public long? PreviousEvolutionId { get; set; }
/// <summary>
/// 基础力量
/// </summary>
public int BaseStrength { get; set; }
/// <summary>
/// 基础敏捷
/// </summary>
public int BaseAgility { get; set; }
/// <summary>
/// 基础智力
/// </summary>
public int BaseIntelligence { get; set; }
/// <summary>
/// 基础魅力
/// </summary>
public int BaseCharm { get; set; }
/// <summary>
/// 进化类型: Normal, Special
/// </summary>
public string Type { get; set; } = PetEvolutionTypeEnum.Normal.ToString();
}
/// <summary>
/// 进化阶段输出
/// </summary>
public class PetEvolutionOutput
{
public long Id { get; set; }
public long TemplateId { get; set; }
public string StageName { get; set; } = string.Empty;
public int StageLevel { get; set; }
public int RequiredGrowth { get; set; }
public long? PreviousEvolutionId { get; set; }
public int BaseStrength { get; set; }
public int BaseAgility { get; set; }
public int BaseIntelligence { get; set; }
public int BaseCharm { get; set; }
public string Type { get; set; } = string.Empty;
public string Status { get; set; } = string.Empty;
public string? CreatedBy { get; set; }
public DateTime CreatedAt { get; set; }
public string? UpdatedBy { get; set; }
public DateTime? UpdatedAt { get; set; }
}
/// <summary>
/// 进化阶段分页查询输入
/// </summary>
public class PetEvolutionQueryInput : PageQueryModel
{
/// <summary>
/// 所属宠物模板Id必填
/// </summary>
public long TemplateId { get; set; }
/// <summary>
/// 阶段名称(模糊搜索)
/// </summary>
public string? StageName { get; set; }
}

View File

@ -0,0 +1,131 @@
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Dto.Pet;
/// <summary>
/// 皮肤创建/更新输入
/// </summary>
public class PetSkinInput
{
/// <summary>
/// 所属宠物模板Id
/// </summary>
public long TemplateId { get; set; }
/// <summary>
/// 皮肤名称
/// </summary>
public string Name { get; set; } = string.Empty;
/// <summary>
/// 描述/特效说明
/// </summary>
public string? Description { get; set; }
/// <summary>
/// 稀有度: Normal, Rare, Epic, Legendary
/// </summary>
public string Rarity { get; set; } = "Normal";
/// <summary>
/// 排序权重
/// </summary>
public int SortOrder { get; set; }
/// <summary>
/// 皮肤类型: Normal, Limited, Event
/// </summary>
public string Type { get; set; } = PetSkinTypeEnum.Normal.ToString();
}
/// <summary>
/// 皮肤输出
/// </summary>
public class PetSkinOutput
{
public long Id { get; set; }
public long TemplateId { get; set; }
public string Name { get; set; } = string.Empty;
public string? Description { get; set; }
public string Rarity { get; set; } = string.Empty;
public int SortOrder { get; set; }
public string Type { get; set; } = string.Empty;
public string? CreatedBy { get; set; }
public DateTime CreatedAt { get; set; }
public string? UpdatedBy { get; set; }
public DateTime? UpdatedAt { get; set; }
/// <summary>
/// 关联的皮肤图片列表
/// </summary>
public List<PetSkinImageOutput>? Images { get; set; }
}
/// <summary>
/// 皮肤分页查询输入
/// </summary>
public class PetSkinQueryInput : PageQueryModel
{
/// <summary>
/// 所属宠物模板Id必填
/// </summary>
public long TemplateId { get; set; }
/// <summary>
/// 皮肤名称(模糊搜索)
/// </summary>
public string? Name { get; set; }
/// <summary>
/// 稀有度: Normal, Rare, Epic, Legendary
/// </summary>
public string? Rarity { get; set; }
}
/// <summary>
/// 皮肤图片创建/更新输入
/// </summary>
public class PetSkinImageInput
{
/// <summary>
/// 皮肤Id
/// </summary>
public long SkinId { get; set; }
/// <summary>
/// 进化阶段Id
/// </summary>
public long EvolutionStageId { get; set; }
/// <summary>
/// 图片地址
/// </summary>
public string ImageUrl { get; set; } = string.Empty;
/// <summary>
/// 图片顺序(动画帧序号)
/// </summary>
public int SortOrder { get; set; }
/// <summary>
/// 图片类型: Normal, Special
/// </summary>
public string Type { get; set; } = PetSkinImageTypeEnum.Normal.ToString();
}
/// <summary>
/// 皮肤图片输出
/// </summary>
public class PetSkinImageOutput
{
public long Id { get; set; }
public long SkinId { get; set; }
public long EvolutionStageId { get; set; }
public string ImageUrl { get; set; } = string.Empty;
public int SortOrder { get; set; }
public string Type { get; set; } = string.Empty;
public string? CreatedBy { get; set; }
public DateTime CreatedAt { get; set; }
public string? UpdatedBy { get; set; }
public DateTime? UpdatedAt { get; set; }
}

View File

@ -0,0 +1,79 @@
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Dto.Pet;
/// <summary>
/// 宠物模板创建/更新输入
/// </summary>
public class PetTemplateInput
{
/// <summary>
/// 模板名称
/// </summary>
public string Name { get; set; } = string.Empty;
/// <summary>
/// 模板描述
/// </summary>
public string? Description { get; set; }
/// <summary>
/// 默认初始进化形态Id
/// </summary>
public long DefaultEvolutionId { get; set; }
/// <summary>
/// 模板图标地址
/// </summary>
public string? IconUrl { get; set; }
/// <summary>
/// 排序权重
/// </summary>
public int SortOrder { get; set; }
/// <summary>
/// 模板类型: Normal, Special, Limited
/// </summary>
public string Type { get; set; } = PetTemplateTypeEnum.Normal.ToString();
}
/// <summary>
/// 宠物模板输出
/// </summary>
public class PetTemplateOutput
{
public long Id { get; set; }
public string Name { get; set; } = string.Empty;
public string? Description { get; set; }
public long DefaultEvolutionId { get; set; }
public string? IconUrl { get; set; }
public int SortOrder { get; set; }
public string Type { get; set; } = string.Empty;
public string Status { get; set; } = string.Empty;
public string? CreatedBy { get; set; }
public DateTime CreatedAt { get; set; }
public string? UpdatedBy { get; set; }
public DateTime? UpdatedAt { get; set; }
}
/// <summary>
/// 宠物模板分页查询输入
/// </summary>
public class PetTemplateQueryInput : PageQueryModel
{
/// <summary>
/// 模板名称(模糊搜索)
/// </summary>
public string? Name { get; set; }
/// <summary>
/// 模板类型: Normal, Special, Limited
/// </summary>
public string? Type { get; set; }
/// <summary>
/// 状态: Active, Inactive
/// </summary>
public string? Status { get; set; }
}

View File

@ -0,0 +1,219 @@
namespace QYZH.InteractiveMagazine.Models.Dto.Points;
using QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 积分流水查询输入
/// </summary>
public class PointsRecordQueryInput : PageQueryModel
{
/// <summary>
/// 用户Id
/// </summary>
public long UserId { get; set; }
/// <summary>
/// 变动类型筛选
/// </summary>
public PointsChangeTypeEnum? ChangeType { get; set; }
/// <summary>
/// 流水分类筛选Income/Expense
/// </summary>
public PointsFlowTypeEnum? Type { get; set; }
/// <summary>
/// 状态筛选Success/Failed 等)
/// </summary>
public string? Status { get; set; }
}
/// <summary>
/// 积分流水输出
/// </summary>
public class PointsRecordOutput
{
/// <summary>
/// 记录Id
/// </summary>
public long Id { get; set; }
/// <summary>
/// 变动数值(正数为收入,负数为支出)
/// </summary>
public int ChangeAmount { get; set; }
/// <summary>
/// 变动后余额
/// </summary>
public int BalanceAfter { get; set; }
/// <summary>
/// 变动类型(如 SignIn、Exchange、TaskReward 等)
/// </summary>
public string ChangeType { get; set; } = string.Empty;
/// <summary>
/// 备注描述
/// </summary>
public string? Description { get; set; }
/// <summary>
/// 流水分类Income/Expense
/// </summary>
public string Type { get; set; } = string.Empty;
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreatedAt { get; set; }
}
/// <summary>
/// 增加积分输入
/// </summary>
public class AddPointsInput
{
/// <summary>
/// 用户Id
/// </summary>
public long UserId { get; set; }
/// <summary>
/// 增加数量
/// </summary>
public int Amount { get; set; }
/// <summary>
/// 变动类型
/// </summary>
public PointsChangeTypeEnum ChangeType { get; set; }
/// <summary>
/// 关联业务Id
/// </summary>
public long? RelatedId { get; set; }
/// <summary>
/// 备注描述
/// </summary>
public string? Description { get; set; }
/// <summary>
/// 操作人名称(为空时默认使用用户昵称)
/// </summary>
public string? OperatorName { get; set; }
}
/// <summary>
/// 扣除积分输入
/// </summary>
public class DeductPointsInput
{
/// <summary>
/// 用户Id
/// </summary>
public long UserId { get; set; }
/// <summary>
/// 扣除数量
/// </summary>
public int Amount { get; set; }
/// <summary>
/// 变动类型
/// </summary>
public PointsChangeTypeEnum ChangeType { get; set; }
/// <summary>
/// 关联业务Id
/// </summary>
public long? RelatedId { get; set; }
/// <summary>
/// 备注描述
/// </summary>
public string? Description { get; set; }
/// <summary>
/// 操作人名称(为空时默认使用用户昵称)
/// </summary>
public string? OperatorName { get; set; }
}
/// <summary>
/// 增加积分输出
/// </summary>
public class AddPointsOutput
{
/// <summary>
/// 积分流水记录Id
/// </summary>
public long RecordId { get; set; }
/// <summary>
/// 操作前积分余额
/// </summary>
public int PreviousBalance { get; set; }
/// <summary>
/// 操作后积分余额
/// </summary>
public int NewBalance { get; set; }
/// <summary>
/// 实际增加数量
/// </summary>
public int AddedAmount { get; set; }
}
/// <summary>
/// 扣除积分输出
/// </summary>
public class DeductPointsOutput
{
/// <summary>
/// 积分流水记录Id
/// </summary>
public long RecordId { get; set; }
/// <summary>
/// 操作前积分余额
/// </summary>
public int PreviousBalance { get; set; }
/// <summary>
/// 操作后积分余额
/// </summary>
public int NewBalance { get; set; }
/// <summary>
/// 实际扣除数量
/// </summary>
public int DeductedAmount { get; set; }
}
/// <summary>
/// 用户积分概览
/// </summary>
public class PointsSummaryOutput
{
/// <summary>
/// 用户Id
/// </summary>
public long UserId { get; set; }
/// <summary>
/// 当前积分余额
/// </summary>
public int CurrentBalance { get; set; }
/// <summary>
/// 累计获得积分
/// </summary>
public int TotalIncome { get; set; }
/// <summary>
/// 累计消耗积分
/// </summary>
public int TotalExpense { get; set; }
}

View File

@ -0,0 +1,75 @@
using System.ComponentModel.DataAnnotations;
namespace QYZH.InteractiveMagazine.Models.Dto.Points;
/// <summary>
/// 手动增加积分输入
/// </summary>
public class ManualAddPointsInput
{
/// <summary>
/// 增加数量必须大于0
/// </summary>
[Range(1, int.MaxValue, ErrorMessage = "增加积分数量必须大于0")]
public int Amount { get; set; }
/// <summary>
/// 操作原因(必填)
/// </summary>
[Required(ErrorMessage = "操作原因不能为空")]
public string Reason { get; set; } = string.Empty;
}
/// <summary>
/// 手动扣除积分输入
/// </summary>
public class ManualDeductPointsInput
{
/// <summary>
/// 扣除数量必须大于0
/// </summary>
[Range(1, int.MaxValue, ErrorMessage = "扣除积分数量必须大于0")]
public int Amount { get; set; }
/// <summary>
/// 操作原因(必填)
/// </summary>
[Required(ErrorMessage = "操作原因不能为空")]
public string Reason { get; set; } = string.Empty;
}
/// <summary>
/// 手动积分操作输出
/// </summary>
public class ManualPointsOutput
{
/// <summary>
/// 积分流水记录Id
/// </summary>
public long RecordId { get; set; }
/// <summary>
/// 操作前积分余额
/// </summary>
public int PreviousBalance { get; set; }
/// <summary>
/// 操作后积分余额
/// </summary>
public int NewBalance { get; set; }
/// <summary>
/// 变动数量(正数为增加,负数为扣除)
/// </summary>
public int ChangeAmount { get; set; }
/// <summary>
/// 操作人
/// </summary>
public string OperatorName { get; set; } = string.Empty;
/// <summary>
/// 操作时间
/// </summary>
public DateTime OperatedAt { get; set; }
}

View File

@ -1,4 +1,6 @@
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Dto.CheckIn;
using QYZH.InteractiveMagazine.Models.Dto.Compensation;
using QYZH.InteractiveMagazine.Models.Dto.Points;
namespace QYZH.InteractiveMagazine.Models.Dto;
@ -59,6 +61,78 @@ public class UsersOutput
public int GrowthPoints { get; set; }
}
/// <summary>
/// 用户详情输出DTO包含基本信息、积分记录、签到记录、补偿任务、期刊列表
/// </summary>
public class UserDetailOutput
{
/// <summary>
/// 用户基本信息
/// </summary>
public UsersOutput BasicInfo { get; set; } = new();
/// <summary>
/// 积分使用记录最近20条
/// </summary>
public List<PointsRecordOutput> PointsRecords { get; set; } = [];
/// <summary>
/// 签到记录最近30条
/// </summary>
public List<CheckInRecordOutput> CheckInRecords { get; set; } = [];
/// <summary>
/// 失败的补偿任务(需要手动处理)
/// </summary>
public List<CompensationTaskOutput> FailedCompensationTasks { get; set; } = [];
/// <summary>
/// 用户拥有的期刊列表
/// </summary>
public List<UserJournalItemOutput> Journals { get; set; } = [];
}
/// <summary>
/// 用户期刊项输出DTO
/// </summary>
public class UserJournalItemOutput
{
/// <summary>
/// 绑定记录Id
/// </summary>
public long BindId { get; set; }
/// <summary>
/// 期刊Id
/// </summary>
public long JournalId { get; set; }
/// <summary>
/// 期刊标题
/// </summary>
public string JournalTitle { get; set; } = string.Empty;
/// <summary>
/// 期刊封面
/// </summary>
public string? CoverImageUrl { get; set; }
/// <summary>
/// 绑定类型: Read, Favorite, Subscribe
/// </summary>
public string Type { get; set; } = string.Empty;
/// <summary>
/// 绑定状态
/// </summary>
public string Status { get; set; } = string.Empty;
/// <summary>
/// 绑定时间
/// </summary>
public DateTime CreatedAt { get; set; }
}
/// <summary>
/// 更新用户状态输入DTO
/// </summary>

View File

@ -1,4 +1,5 @@
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Enum;
using Newtonsoft.Json;
namespace QYZH.InteractiveMagazine.Models.WeChat;
@ -89,12 +90,12 @@ public class WxUserInput
/// <summary>
/// 用户类型: Normal, VIP
/// </summary>
public string Type { get; set; } = "Normal";
public string Type { get; set; } = UsersTypeEnum.Normal.ToString();
/// <summary>
/// 状态: Active, Disabled
/// </summary>
public string Status { get; set; } = "Active";
public string Status { get; set; } = UserStatusEnum.Active.ToString();
/// <summary>
/// 密码默认手机后4位