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

@ -41,4 +41,10 @@ public interface ICommunityMessageService : IBaseService<CommunityMessage>
/// 设置排序权重
/// </summary>
Task SetSortOrderAsync(long id, int sortOrder);
/// <summary>
/// 批量发布消息IsActive false => true
/// </summary>
/// <param name="ids">消息ID列表</param>
Task BatchPublishAsync(List<long> ids);
}

View File

@ -0,0 +1,45 @@
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Dto.Compensation;
using QYZH.InteractiveMagazine.Models.Entity;
namespace QYZH.InteractiveMagazine.IService;
/// <summary>
/// 补偿任务管理服务接口
/// </summary>
public interface ICompensationManageService : IBaseService<CompensationTask>
{
/// <summary>
/// 分页查询补偿任务
/// </summary>
/// <param name="input">查询参数</param>
/// <returns>分页结果</returns>
Task<PageListModel<CompensationManageOutput>> GetListAsync(CompensationTaskQueryInput input);
/// <summary>
/// 手动重试补偿任务(将状态改为 Pending重置 RetryCount
/// </summary>
/// <param name="taskId">任务Id</param>
/// <param name="operatorId">操作人Id</param>
/// <param name="operatorName">操作人用户名</param>
/// <param name="input">重试参数</param>
/// <param name="ipAddress">IP地址</param>
Task RetryAsync(long taskId, long operatorId, string operatorName, CompensationRetryInput input, string? ipAddress = null);
/// <summary>
/// 标记补偿任务为已解决
/// </summary>
/// <param name="taskId">任务Id</param>
/// <param name="operatorId">操作人Id</param>
/// <param name="operatorName">操作人用户名</param>
/// <param name="input">解决参数</param>
/// <param name="ipAddress">IP地址</param>
Task ResolveAsync(long taskId, long operatorId, string operatorName, CompensationResolveInput input, string? ipAddress = null);
/// <summary>
/// 获取补偿任务详情
/// </summary>
/// <param name="taskId">任务Id</param>
/// <returns>任务详情</returns>
Task<CompensationManageDetailOutput> GetDetailAsync(long taskId);
}

View File

@ -0,0 +1,37 @@
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Entity;
namespace QYZH.InteractiveMagazine.IService;
/// <summary>
/// 操作日志服务接口
/// </summary>
public interface IOperationLogService : IBaseService<OperationLog>
{
/// <summary>
/// 记录操作日志
/// </summary>
/// <param name="operatorId">操作人Id</param>
/// <param name="operatorName">操作人用户名</param>
/// <param name="actionType">操作类型(使用 OperationLogActionType 常量)</param>
/// <param name="targetType">目标类型(使用 OperationLogTargetType 常量)</param>
/// <param name="targetId">目标记录Id</param>
/// <param name="targetName">目标名称</param>
/// <param name="detail">操作详情可选JSON格式</param>
/// <param name="ipAddress">IP地址可选</param>
Task LogAsync(long operatorId, string operatorName, string actionType, string targetType, long targetId, string? targetName = null, string? detail = null, string? ipAddress = null);
/// <summary>
/// 分页查询操作日志
/// </summary>
/// <param name="input">查询参数</param>
/// <returns>分页结果</returns>
Task<PageListModel<OperationLogOutput>> GetListAsync(OperationLogQueryInput input);
/// <summary>
/// 获取操作日志详情
/// </summary>
/// <param name="id">日志Id</param>
/// <returns>日志详情</returns>
Task<OperationLogDetailOutput> GetDetailAsync(long id);
}

View File

@ -44,4 +44,112 @@ public interface IPetService : IBaseService<UserPet>
/// <param name="petId">宠物Id</param>
/// <returns>喂养记录列表</returns>
Task<PageListModel<FeedingRecordOutput>> GetFeedingRecordsAsync(long userId, long petId, PageQueryModel pageQuery);
// ==================== 后台管理:宠物模板 ====================
/// <summary>
/// 创建宠物模板
/// </summary>
Task<PetTemplateOutput> CreateTemplateAsync(PetTemplateInput input);
/// <summary>
/// 更新宠物模板
/// </summary>
Task<PetTemplateOutput> UpdateTemplateAsync(long id, PetTemplateInput input);
/// <summary>
/// 删除宠物模板(软删除)
/// </summary>
Task DeleteTemplateAsync(long id);
/// <summary>
/// 获取单个宠物模板
/// </summary>
Task<PetTemplateOutput> GetTemplateByIdAsync(long id);
/// <summary>
/// 分页查询宠物模板列表
/// </summary>
Task<PageListModel<PetTemplateOutput>> GetTemplatesAsync(PetTemplateQueryInput input);
/// <summary>
/// 更新模板状态(启用/禁用)
/// </summary>
Task UpdateTemplateStatusAsync(long id, string status);
// ==================== 后台管理:进化链 ====================
/// <summary>
/// 创建进化阶段
/// </summary>
Task<PetEvolutionOutput> CreateEvolutionAsync(PetEvolutionInput input);
/// <summary>
/// 更新进化阶段
/// </summary>
Task<PetEvolutionOutput> UpdateEvolutionAsync(long id, PetEvolutionInput input);
/// <summary>
/// 删除进化阶段(软删除)
/// </summary>
Task DeleteEvolutionAsync(long id);
/// <summary>
/// 获取单个进化阶段
/// </summary>
Task<PetEvolutionOutput> GetEvolutionByIdAsync(long id);
/// <summary>
/// 分页查询进化阶段列表
/// </summary>
Task<PageListModel<PetEvolutionOutput>> GetEvolutionsAsync(PetEvolutionQueryInput input);
// ==================== 后台管理:皮肤 ====================
/// <summary>
/// 创建皮肤
/// </summary>
Task<PetSkinOutput> CreateSkinAsync(PetSkinInput input);
/// <summary>
/// 更新皮肤
/// </summary>
Task<PetSkinOutput> UpdateSkinAsync(long id, PetSkinInput input);
/// <summary>
/// 删除皮肤(软删除)
/// </summary>
Task DeleteSkinAsync(long id);
/// <summary>
/// 获取单个皮肤(含图片列表)
/// </summary>
Task<PetSkinOutput> GetSkinByIdAsync(long id);
/// <summary>
/// 分页查询皮肤列表
/// </summary>
Task<PageListModel<PetSkinOutput>> GetSkinsAsync(PetSkinQueryInput input);
// ==================== 后台管理:皮肤图片 ====================
/// <summary>
/// 创建皮肤图片
/// </summary>
Task<PetSkinImageOutput> CreateSkinImageAsync(PetSkinImageInput input);
/// <summary>
/// 更新皮肤图片
/// </summary>
Task<PetSkinImageOutput> UpdateSkinImageAsync(long id, PetSkinImageInput input);
/// <summary>
/// 删除皮肤图片(软删除)
/// </summary>
Task DeleteSkinImageAsync(long id);
/// <summary>
/// 获取指定皮肤的所有图片
/// </summary>
Task<List<PetSkinImageOutput>> GetSkinImagesBySkinIdAsync(long skinId);
}

View File

@ -0,0 +1,66 @@
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Dto.Points;
using QYZH.InteractiveMagazine.Models.Entity;
namespace QYZH.InteractiveMagazine.IService;
/// <summary>
/// 积分服务接口
/// </summary>
public interface IPointsService : IBaseService<PointsRecord>
{
// ==================== 带事务版本(独立调用) ====================
/// <summary>
/// 增加积分(带事务)
/// </summary>
/// <param name="input">增加积分参数</param>
/// <returns>增加结果</returns>
Task<AddPointsOutput> AddPointsAsync(AddPointsInput input);
/// <summary>
/// 扣除积分(带事务,含余额不足校验)
/// </summary>
/// <param name="input">扣除积分参数</param>
/// <returns>扣除结果</returns>
Task<DeductPointsOutput> DeductPointsAsync(DeductPointsInput input);
// ==================== 无事务版本(供外部事务调用) ====================
/// <summary>
/// 增加积分(无事务,需在外部事务中调用)
/// </summary>
/// <param name="input">增加积分参数</param>
/// <returns>增加结果</returns>
Task<AddPointsOutput> AddPointsInTranAsync(AddPointsInput input);
/// <summary>
/// 扣除积分(无事务,需在外部事务中调用,含余额不足校验)
/// </summary>
/// <param name="input">扣除积分参数</param>
/// <returns>扣除结果</returns>
Task<DeductPointsOutput> DeductPointsInTranAsync(DeductPointsInput input);
// ==================== 查询 ====================
/// <summary>
/// 查询用户当前积分余额
/// </summary>
/// <param name="userId">用户Id</param>
/// <returns>当前积分余额</returns>
Task<int> GetUserPointsAsync(long userId);
/// <summary>
/// 获取用户积分概览(当前余额 + 累计收入 + 累计支出)
/// </summary>
/// <param name="userId">用户Id</param>
/// <returns>积分概览</returns>
Task<PointsSummaryOutput> GetPointsSummaryAsync(long userId);
/// <summary>
/// 分页查询积分流水
/// </summary>
/// <param name="input">查询参数</param>
/// <returns>分页流水列表</returns>
Task<PageListModel<PointsRecordOutput>> GetPointsRecordsAsync(PointsRecordQueryInput input);
}

View File

@ -1,5 +1,5 @@
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Dto.Points;
using QYZH.InteractiveMagazine.Models.Entity;
namespace QYZH.InteractiveMagazine.IService;
@ -12,12 +12,22 @@ public interface IUsersService : IBaseService<Users>
Task<BaseResponse<PageListModel<UsersOutput>>> GetListAsync(UsersQueryInput input);
/// <summary>
/// 获取用户详情
/// 获取用户详情(包含积分记录、签到记录、补偿任务、期刊列表)
/// </summary>
Task<BaseResponse<UsersOutput>> GetDetailAsync(long id);
Task<BaseResponse<UserDetailOutput>> GetDetailAsync(long id);
/// <summary>
/// 更新用户状态
/// </summary>
Task<BaseResponse> UpdateStatusAsync(long id, UpdateUserStatusInput input);
/// <summary>
/// 手动增加用户积分
/// </summary>
Task<ManualPointsOutput> ManualAddPointsAsync(long userId, ManualAddPointsInput input, long operatorId, string operatorName, string? ipAddress = null);
/// <summary>
/// 手动扣除用户积分
/// </summary>
Task<ManualPointsOutput> ManualDeductPointsAsync(long userId, ManualDeductPointsInput input, long operatorId, string operatorName, string? ipAddress = null);
}

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位

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -32,7 +33,7 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:Editor
/// Nullable:False
/// </summary>
public string Type {get;set;}
public AdminUserTypeEnum Type {get;set;}
}
}

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -40,13 +41,13 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:Daily
/// Nullable:False
/// </summary>
public string Type {get;set;}
public CheckInConfigTypeEnum Type {get;set;}
/// <summary>
/// Desc:状态: Active, Inactive
/// Default:Active
/// Nullable:False
/// </summary>
public string Status {get;set;}
public CheckInConfigStatusEnum Status {get;set;}
}
}

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -52,13 +53,6 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:Normal
/// Nullable:False
/// </summary>
public string Type {get;set;}
/// <summary>
/// Desc:状态: Success
/// Default:Success
/// Nullable:False
/// </summary>
public string Status {get;set;}
public CheckInRecordTypeEnum Type { get;set;}
}
}

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -79,7 +80,7 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:Article
/// Nullable:False
/// </summary>
public string Type { get; set; }
public MessageTypeEnum Type { get; set; }
/// <summary>
/// Desc:点赞数

View File

@ -1,11 +1,12 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
///<summary>
///模板评论表
///</summary>
[SugarTable("MessageComment")]
[SugarTable("CommunityMessageComment")]
public partial class CommunityMessageComment : SqlSugarBaseEntity
{
public CommunityMessageComment(){
@ -39,13 +40,13 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:TemplateComment
/// Nullable:False
/// </summary>
public string Type {get;set;}
public CommunityMessageCommentTypeEnum Type {get;set;}
/// <summary>
/// Desc:状态: Published, Hidden
/// Default:Published
/// Nullable:False
/// </summary>
public string Status {get;set;}
public CommunityMessageCommentStatusEnum Status {get;set;}
}
}

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -32,7 +33,7 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:Like
/// Nullable:False
/// </summary>
public string Type { get; set; }
public CommunityMessageLikeTypeEnum Type { get; set; }
}
}

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -33,13 +34,13 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:Neutral
/// Nullable:False
/// </summary>
public string Type {get;set;}
public CommunityTemplateSentenceTypeEnum Type {get;set;}
/// <summary>
/// Desc:状态: Active, Inactive
/// Default:Active
/// Nullable:False
/// </summary>
public string Status {get;set;}
public CommunityTemplateSentenceStatusEnum Status {get;set;}
}
}

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -19,7 +20,7 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:
/// Nullable:False
/// </summary>
public string TaskType { get; set; }
public int TaskType { get; set; }
/// <summary>
/// Desc:业务来源(如 CheckIn、Purchase、Activity
@ -82,7 +83,7 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:Pending
/// Nullable:False
/// </summary>
public new string Status { get; set; }
public CompensationTaskStatusEnum Status { get; set; }
/// <summary>
/// Desc:最后处理时间

View File

@ -2,6 +2,7 @@
using System.Linq;
using System.Text;
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -98,7 +99,7 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:Pending
/// Nullable:False
/// </summary>
public string Status {get;set;}
public DotFileStatusEnum Status {get;set;}
/// <summary>
/// Desc:

View File

@ -2,6 +2,7 @@
using System.Linq;
using System.Text;
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -63,7 +64,7 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:Pending
/// Nullable:False
/// </summary>
public string Status {get;set;}
public DotFileDetailStatusEnum Status {get;set;}
/// <summary>
/// Desc:

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -64,6 +65,6 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:Success
/// Nullable:False
/// </summary>
public new string Status { get; set; }
public ExchangeRecordStatusEnum Status { get; set; }
}
}

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -80,13 +81,13 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:Normal
/// Nullable:False
/// </summary>
public string Type {get;set;}
public JournalTypeEnum Type {get;set;}
/// <summary>
/// Desc:状态: Draft, Published, Archived
/// Default:Draft
/// Nullable:False
/// </summary>
public string Status {get;set;}
public JournalStatusEnum Status {get;set;}
}
}

View File

@ -1,7 +1,8 @@
using System;
using QYZH.InteractiveMagazine.Models.Enum;
using SqlSugar;
using System;
using System.Linq;
using System.Text;
using SqlSugar;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -64,7 +65,7 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:0
/// Nullable:False
/// </summary>
public int Type {get;set;}
public JournalCatalogTypeEnum Type {get;set;}
}

View File

@ -1,7 +1,8 @@
using System;
using QYZH.InteractiveMagazine.Models.Enum;
using SqlSugar;
using System;
using System.Linq;
using System.Text;
using SqlSugar;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -42,7 +43,7 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:
/// Nullable:False
/// </summary>
public int Type {get;set;}
public JournalPageTaskTypeEnum Type {get;set;}
/// <summary>
/// Desc:任务

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -47,7 +48,7 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:Pet
/// Nullable:False
/// </summary>
public string Type { get; set; }
public MedalTypeEnum Type { get; set; }
/// <summary>
/// Desc:书id

View File

@ -0,0 +1,68 @@
using SqlSugar;
namespace QYZH.InteractiveMagazine.Models.Entity;
/// <summary>
/// 操作日志表 — 记录后台管理员的所有手动操作
/// </summary>
[SugarTable("OperationLog")]
public partial class OperationLog : SqlSugarBaseEntity
{
public OperationLog() { }
/// <summary>
/// Desc:操作人Id管理员Id
/// Default:
/// Nullable:False
/// </summary>
public long OperatorId { get; set; }
/// <summary>
/// Desc:操作人用户名
/// Default:
/// Nullable:False
/// </summary>
public string OperatorName { get; set; }
/// <summary>
/// Desc:操作类型ManualAddPoints/ManualDeductPoints/CompensationRetry/CompensationResolve
/// Default:
/// Nullable:False
/// </summary>
public string ActionType { get; set; }
/// <summary>
/// Desc:目标类型User/CompensationTask
/// Default:
/// Nullable:False
/// </summary>
public string TargetType { get; set; }
/// <summary>
/// Desc:目标记录Id
/// Default:
/// Nullable:False
/// </summary>
public long TargetId { get; set; }
/// <summary>
/// Desc:目标名称(用户昵称/任务描述等,便于展示)
/// Default:
/// Nullable:True
/// </summary>
public string? TargetName { get; set; }
/// <summary>
/// Desc:操作详情JSON格式记录操作参数和结果
/// Default:
/// Nullable:True
/// </summary>
public string? Detail { get; set; }
/// <summary>
/// Desc:操作IP地址
/// Default:
/// Nullable:True
/// </summary>
public string? IpAddress { get; set; }
}

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -78,13 +79,13 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:Normal
/// Nullable:False
/// </summary>
public string Type { get; set; }
public PetEvolutionTypeEnum Type { get; set; }
/// <summary>
/// Desc:状态: Active, Inactive
/// Default:Active
/// Nullable:False
/// </summary>
public new string Status { get; set; }
public PetEvolutionStatusEnum Status { get; set; }
}
}

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -60,13 +61,13 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:Normal
/// Nullable:False
/// </summary>
public string Type {get;set;}
public PetFeedingRecordTypeEnum Type {get;set;}
/// <summary>
/// Desc:状态
/// Default:Success
/// Nullable:False
/// </summary>
public string Status {get;set;}
public PetFeedingRecordStatusEnum Status {get;set;}
}
}

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -50,6 +51,6 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:Normal
/// Nullable:False
/// </summary>
public string Type { get; set; }
public PetSkinTypeEnum Type { get; set; }
}
}

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -43,6 +44,6 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:Normal
/// Nullable:False
/// </summary>
public string Type { get; set; }
public PetSkinImageTypeEnum Type { get; set; }
}
}

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -50,13 +51,13 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:Normal
/// Nullable:False
/// </summary>
public string Type { get; set; }
public PetTemplateTypeEnum Type { get; set; }
/// <summary>
/// Desc:状态: Active, Inactive
/// Default:Active
/// Nullable:False
/// </summary>
public new string Status { get; set; }
public PetTemplateStatusEnum Status { get; set; }
}
}

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -60,13 +61,13 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:
/// Nullable:True
/// </summary>
public string Type {get;set;}
public PointsFlowTypeEnum Type {get;set;}
/// <summary>
/// Desc:状态: Success, Failed, Pending
/// Default:Success
/// Nullable:False
/// </summary>
public string Status {get;set;}
public PointsRecordStatusEnum Status {get;set;}
}
}

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -46,7 +47,7 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:
/// Nullable:False
/// </summary>
public string Type {get;set;}
public ProductTypeEnum Type {get;set;}
/// <summary>
/// Desc:售卖状态: OnSale, OffSale

View File

@ -14,7 +14,7 @@ namespace QYZH.InteractiveMagazine.Models.Entity
[SugarColumn(IsPrimaryKey = true, ColumnName = "Id")]
public long Id { get; set; } = YitIdHelper.NextId();
/// <summary>
/// Desc:状态 0禁用 1启用
/// Desc:
/// Default:1
/// Nullable:False
/// </summary>

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -52,13 +53,13 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:
/// Nullable:True
/// </summary>
public string Type {get;set;}
public UserBagTypeEnum Type {get;set;}
/// <summary>
/// Desc:状态: Available, Expired
/// Default:Available
/// Nullable:False
/// </summary>
public string Status {get;set;}
public UserBagStatusEnum Status {get;set;}
}
}

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -35,7 +36,7 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Nullable:False
/// </summary>
[SugarColumn(ColumnName = "Type")]
public string Type { get; set; }
public UserJournalTypeEnum Type { get; set; }
/// <summary>
/// Desc:状态: Active(正常), Inactive(失效)
@ -43,6 +44,6 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Nullable:False
/// </summary>
[SugarColumn(ColumnName = "Status")]
public new string Status { get; set; }
public UserJournalStatusEnum Status { get; set; }
}
}

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -38,13 +39,13 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:
/// Nullable:True
/// </summary>
public string Type {get;set;}
public UserMedalTypeEnum Type {get;set;}
/// <summary>
/// Desc:状态: Awarded, Revoked
/// Default:Awarded
/// Nullable:False
/// </summary>
public string Status {get;set;}
public UserMedalStatusEnum Status {get;set;}
}
}

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -67,14 +68,14 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:Normal
/// Nullable:False
/// </summary>
public string Type { get; set; }
public UserPetTypeEnum Type { get; set; }
/// <summary>
/// Desc:状态: Inactive, Active, Sleeping
/// Default:Inactive
/// Nullable:False
/// </summary>
public new string Status { get; set; }
public UserPetStatusEnum Status { get; set; }
/// <summary>
/// 理解力

View File

@ -1,4 +1,5 @@
using SqlSugar;
using QYZH.InteractiveMagazine.Models.Enum;
namespace QYZH.InteractiveMagazine.Models.Entity
{
@ -39,14 +40,14 @@ namespace QYZH.InteractiveMagazine.Models.Entity
/// Default:Normal
/// Nullable:False
/// </summary>
public string Type { get; set; }
public UsersTypeEnum Type { get; set; }
/// <summary>
/// Desc:状态: Active, Disabled
/// Default:Active
/// Nullable:False
/// </summary>
public string Status { get; set; }
public UserStatusEnum Status { get; set; }
/// <summary>
/// Desc:微信OpenId
/// Default:

View File

@ -0,0 +1,20 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 管理员类型枚举
/// </summary>
public enum AdminUserTypeEnum
{
/// <summary>
/// 编辑员
/// </summary>
Editor = 2,
/// <summary>
/// 超级管理员
/// </summary>
SuperAdmin = 0,
/// <summary>
/// 超级管理员
/// </summary>
Admin = 1
}

View File

@ -0,0 +1,17 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 签到配置状态枚举
/// </summary>
public enum CheckInConfigStatusEnum
{
/// <summary>
/// 未激活
/// </summary>
Inactive = 0,
/// <summary>
/// 激活
/// </summary>
Active = 1
}

View File

@ -0,0 +1,16 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 签到配置类型枚举
/// </summary>
public enum CheckInConfigTypeEnum
{
/// <summary>
/// 每日签到
/// </summary>
Daily = 1,
/// <summary>
/// 连续签到
/// </summary>
Streak = 2
}

View File

@ -0,0 +1,12 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 签到记录状态枚举
/// </summary>
public enum CheckInRecordStatusEnum
{
/// <summary>
/// 成功
/// </summary>
Success = 1
}

View File

@ -0,0 +1,16 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 签到记录类型枚举
/// </summary>
public enum CheckInRecordTypeEnum
{
/// <summary>
/// 正常签到
/// </summary>
Normal = 1,
/// <summary>
/// 补签
/// </summary>
MakeUp = 2
}

View File

@ -0,0 +1,17 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 模板评论状态枚举
/// </summary>
public enum CommunityMessageCommentStatusEnum
{
/// <summary>
/// 已隐藏
/// </summary>
Hidden = 0,
/// <summary>
/// 已发布
/// </summary>
Published = 1
}

View File

@ -0,0 +1,12 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 评论类型枚举
/// </summary>
public enum CommunityMessageCommentTypeEnum
{
/// <summary>
/// 模板评论
/// </summary>
TemplateComment = 1
}

View File

@ -0,0 +1,12 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 点赞类型枚举
/// </summary>
public enum CommunityMessageLikeTypeEnum
{
/// <summary>
/// 点赞
/// </summary>
Like = 1
}

View File

@ -0,0 +1,17 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 固定模板言论状态枚举
/// </summary>
public enum CommunityTemplateSentenceStatusEnum
{
/// <summary>
/// 未激活
/// </summary>
Inactive = 0,
/// <summary>
/// 激活
/// </summary>
Active = 1
}

View File

@ -0,0 +1,20 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 固定模板言论分类枚举
/// </summary>
public enum CommunityTemplateSentenceTypeEnum
{
/// <summary>
/// 正面
/// </summary>
Positive = 1,
/// <summary>
/// 中性
/// </summary>
Neutral = 2,
/// <summary>
/// 负面
/// </summary>
Negative = 3
}

View File

@ -0,0 +1,32 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 补偿任务状态枚举
/// </summary>
public enum CompensationTaskStatusEnum
{
/// <summary>
/// 待处理
/// </summary>
Pending = 0,
/// <summary>
/// 处理中
/// </summary>
Processing = 1,
/// <summary>
/// 成功
/// </summary>
Success = 2,
/// <summary>
/// 失败
/// </summary>
Failed = 3,
/// <summary>
/// 已取消
/// </summary>
Cancelled = 4
}

View File

@ -0,0 +1,24 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 补偿任务类型枚举
/// </summary>
public enum CompensationTaskTypeEnum
{
/// <summary>
/// 宠物喂养补偿
/// </summary>
PetFeeding = 1,
/// <summary>
/// 用户积分补偿
/// </summary>
UserPoints = 2,
/// <summary>
/// 用户成长值补偿
/// </summary>
UserGrowth = 3,
/// <summary>
/// 发送通知补偿
/// </summary>
SendNotification = 4
}

View File

@ -0,0 +1,32 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 点读文件明细状态枚举
/// </summary>
public enum DotFileDetailStatusEnum
{
/// <summary>
/// 待处理
/// </summary>
Pending = 0,
/// <summary>
/// 处理中
/// </summary>
Processing = 1,
/// <summary>
/// 成功
/// </summary>
Success = 2,
/// <summary>
/// 失败
/// </summary>
Failed = 3,
/// <summary>
/// 已取消
/// </summary>
Cancelled = 4
}

View File

@ -0,0 +1,32 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 点读文件状态枚举
/// </summary>
public enum DotFileStatusEnum
{
/// <summary>
/// 待处理
/// </summary>
Pending = 0,
/// <summary>
/// 处理中
/// </summary>
Processing = 1,
/// <summary>
/// 成功
/// </summary>
Success = 2,
/// <summary>
/// 失败
/// </summary>
Failed = 3,
/// <summary>
/// 已取消
/// </summary>
Cancelled = 4
}

View File

@ -0,0 +1,17 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 兑换记录状态枚举
/// </summary>
public enum ExchangeRecordStatusEnum
{
/// <summary>
/// 成功
/// </summary>
Success = 1,
/// <summary>
/// 已退还
/// </summary>
Refunded = 2
}

View File

@ -0,0 +1,16 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 期刊目录类别枚举
/// </summary>
public enum JournalCatalogTypeEnum
{
/// <summary>
/// 单元
/// </summary>
Unit = 0,
/// <summary>
/// 页面
/// </summary>
Page = 1
}

View File

@ -0,0 +1,22 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 期刊页面状态枚举
/// </summary>
public enum JournalPageStatusEnum
{
/// <summary>
/// 验证失败
/// </summary>
Failed = -1,
/// <summary>
/// 未验证
/// </summary>
NotVerified = 0,
/// <summary>
/// 验证成功
/// </summary>
Success = 1
}

View File

@ -0,0 +1,24 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 杂志任务题型枚举
/// </summary>
public enum JournalPageTaskTypeEnum
{
/// <summary>
/// 单选题
/// </summary>
SingleChoice = 1,
/// <summary>
/// 多选题
/// </summary>
MultipleChoice = 2,
/// <summary>
/// 填空题
/// </summary>
FillInBlank = 3,
/// <summary>
/// 问答题
/// </summary>
QuestionAnswer = 4
}

View File

@ -0,0 +1,22 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 期刊状态枚举
/// </summary>
public enum JournalStatusEnum
{
/// <summary>
/// 草稿
/// </summary>
Draft = 0,
/// <summary>
/// 已发布
/// </summary>
Published = 1,
/// <summary>
/// 已归档
/// </summary>
Archived = 2
}

View File

@ -0,0 +1,16 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 期刊类型枚举
/// </summary>
public enum JournalTypeEnum
{
/// <summary>
/// 普通
/// </summary>
Normal = 1,
/// <summary>
/// 特刊
/// </summary>
Special = 2
}

View File

@ -0,0 +1,16 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 勋章类型枚举
/// </summary>
public enum MedalTypeEnum
{
/// <summary>
/// 宠物勋章
/// </summary>
Pet = 1,
/// <summary>
/// 社区勋章
/// </summary>
Community = 2
}

View File

@ -0,0 +1,22 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 社区消息状态枚举
/// </summary>
public enum MessageStatusEnum
{
/// <summary>
/// 审核中
/// </summary>
PendingReview = 0,
/// <summary>
/// 已通过
/// </summary>
Approved = 1,
/// <summary>
/// 已冻结
/// </summary>
Frozen = 2
}

View File

@ -0,0 +1,22 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 消息类型
/// </summary>
public enum MessageTypeEnum
{
/// <summary>
/// 文章
/// </summary>
Article = 1,
/// <summary>
/// 引用
/// </summary>
Quote = 2,
/// <summary>
/// 公告
/// </summary>
Announcement = 3
}

View File

@ -0,0 +1,17 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 宠物进化状态枚举
/// </summary>
public enum PetEvolutionStatusEnum
{
/// <summary>
/// 未激活
/// </summary>
Inactive = 0,
/// <summary>
/// 激活
/// </summary>
Active = 1
}

View File

@ -0,0 +1,16 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 宠物进化类型枚举
/// </summary>
public enum PetEvolutionTypeEnum
{
/// <summary>
/// 普通进化
/// </summary>
Normal = 1,
/// <summary>
/// 特殊进化
/// </summary>
Special = 2
}

View File

@ -0,0 +1,12 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 宠物喂养记录状态枚举
/// </summary>
public enum PetFeedingRecordStatusEnum
{
/// <summary>
/// 成功
/// </summary>
Success = 1
}

View File

@ -0,0 +1,16 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 宠物喂养记录类型枚举
/// </summary>
public enum PetFeedingRecordTypeEnum
{
/// <summary>
/// 普通喂养
/// </summary>
Normal = 1,
/// <summary>
/// 特殊喂养
/// </summary>
Special = 2
}

View File

@ -0,0 +1,16 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 宠物皮肤图片类型枚举
/// </summary>
public enum PetSkinImageTypeEnum
{
/// <summary>
/// 普通图片
/// </summary>
Normal = 1,
/// <summary>
/// 特殊图片
/// </summary>
Special = 2
}

View File

@ -0,0 +1,20 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 宠物皮肤类型枚举
/// </summary>
public enum PetSkinTypeEnum
{
/// <summary>
/// 普通皮肤
/// </summary>
Normal = 1,
/// <summary>
/// 限定皮肤
/// </summary>
Limited = 2,
/// <summary>
/// 活动皮肤
/// </summary>
Event = 3
}

View File

@ -0,0 +1,17 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 宠物模板状态枚举
/// </summary>
public enum PetTemplateStatusEnum
{
/// <summary>
/// 未激活
/// </summary>
Inactive = 0,
/// <summary>
/// 激活
/// </summary>
Active = 1
}

View File

@ -0,0 +1,20 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 宠物模板类型枚举
/// </summary>
public enum PetTemplateTypeEnum
{
/// <summary>
/// 普通
/// </summary>
Normal = 1,
/// <summary>
/// 特殊
/// </summary>
Special = 2,
/// <summary>
/// 限定
/// </summary>
Limited = 3
}

View File

@ -0,0 +1,52 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 积分变动类型
/// </summary>
public enum PointsChangeTypeEnum
{
/// <summary>
/// 签到奖励
/// </summary>
SignIn,
/// <summary>
/// 补签奖励
/// </summary>
MakeUpSign,
/// <summary>
/// 商城兑换扣除
/// </summary>
Exchange,
/// <summary>
/// 宠物喂养消耗
/// </summary>
FeedPet,
/// <summary>
/// 任务奖励(杂志任务等)
/// </summary>
TaskReward,
/// <summary>
/// 注册奖励
/// </summary>
RegisterBonus,
/// <summary>
/// 勋章奖励
/// </summary>
MedalBonus,
/// <summary>
/// 系统补偿
/// </summary>
SystemCompensation,
/// <summary>
/// 后台手动调整
/// </summary>
ManualAdjust
}

View File

@ -0,0 +1,17 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 积分流水分类
/// </summary>
public enum PointsFlowTypeEnum
{
/// <summary>
/// 收入
/// </summary>
Income,
/// <summary>
/// 支出
/// </summary>
Expense
}

View File

@ -0,0 +1,22 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 积分流水记录状态枚举
/// </summary>
public enum PointsRecordStatusEnum
{
/// <summary>
/// 待处理
/// </summary>
Pending = 0,
/// <summary>
/// 成功
/// </summary>
Success = 1,
/// <summary>
/// 失败
/// </summary>
Failed = 2
}

View File

@ -0,0 +1,16 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 商品类型枚举
/// </summary>
public enum ProductTypeEnum
{
/// <summary>
/// 补签卡
/// </summary>
MakeUpCard = 1,
/// <summary>
/// 宠物背景
/// </summary>
PetBg = 2
}

View File

@ -0,0 +1,17 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 用户背包状态枚举
/// </summary>
public enum UserBagStatusEnum
{
/// <summary>
/// 已过期
/// </summary>
Expired = 0,
/// <summary>
/// 可用
/// </summary>
Available = 1
}

View File

@ -0,0 +1,16 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 用户背包物品分类枚举
/// </summary>
public enum UserBagTypeEnum
{
/// <summary>
/// 补签卡
/// </summary>
MakeUpCard = 1,
/// <summary>
/// 宠物背景
/// </summary>
PetBg = 2
}

View File

@ -0,0 +1,17 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 用户期刊关联状态枚举
/// </summary>
public enum UserJournalStatusEnum
{
/// <summary>
/// 失效
/// </summary>
Inactive = 0,
/// <summary>
/// 正常
/// </summary>
Active = 1
}

View File

@ -0,0 +1,20 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 用户期刊关联类型枚举
/// </summary>
public enum UserJournalTypeEnum
{
/// <summary>
/// 已读
/// </summary>
Read = 1,
/// <summary>
/// 收藏
/// </summary>
Favorite = 2,
/// <summary>
/// 订阅
/// </summary>
Subscribe = 3
}

View File

@ -0,0 +1,17 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 用户勋章状态枚举
/// </summary>
public enum UserMedalStatusEnum
{
/// <summary>
/// 已撤销
/// </summary>
Revoked = 0,
/// <summary>
/// 已授予
/// </summary>
Awarded = 1
}

View File

@ -0,0 +1,16 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 用户勋章记录类型枚举
/// </summary>
public enum UserMedalTypeEnum
{
/// <summary>
/// 系统授予
/// </summary>
System = 1,
/// <summary>
/// 活动奖励
/// </summary>
Activity = 2
}

View File

@ -0,0 +1,22 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 用户宠物状态枚举
/// </summary>
public enum UserPetStatusEnum
{
/// <summary>
/// 未激活
/// </summary>
Inactive = 0,
/// <summary>
/// 激活
/// </summary>
Active = 1,
/// <summary>
/// 休眠中
/// </summary>
Sleeping = 2
}

View File

@ -0,0 +1,12 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 用户宠物类型枚举
/// </summary>
public enum UserPetTypeEnum
{
/// <summary>
/// 普通
/// </summary>
Normal = 1
}

View File

@ -11,7 +11,7 @@ public enum UserStatusEnum
Active = 1,
/// <summary>
/// 冻结
/// 禁用
/// </summary>
Frozen = 2
Disabled = 2
}

View File

@ -0,0 +1,16 @@
namespace QYZH.InteractiveMagazine.Models.Enum;
/// <summary>
/// 用户类型枚举
/// </summary>
public enum UsersTypeEnum
{
/// <summary>
/// 普通用户
/// </summary>
Normal = 1,
/// <summary>
/// VIP用户
/// </summary>
VIP = 2
}

View File

@ -66,7 +66,7 @@ public class AdminAuthService(BaseRepository<AdminUser> adminUserRepository, ICo
Token = token,
UserId = (long)adminUser.Id,
UserName = adminUser.UserName,
Type = adminUser.Type
Type = adminUser.Type.ToString(),
};
}
@ -94,7 +94,7 @@ public class AdminAuthService(BaseRepository<AdminUser> adminUserRepository, ICo
{
UserId = adminUser.Id,
UserName = adminUser.UserName,
Type = adminUser.Type,
Type = adminUser.Type.ToString(),
Status = adminUser.Status
};
}

View File

@ -6,6 +6,7 @@ using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Entity;
using QYZH.InteractiveMagazine.Models.Enum;
using QYZH.InteractiveMagazine.Repository;
using SqlSugar;
@ -64,7 +65,7 @@ public class AdminUserService(BaseRepository<AdminUser> adminUserRepository, ILo
logger.LogInformation("管理员创建成功,用户名: {UserName}, ID: {Id}", input.UserName, adminUser.Id);
return new AdminUserOutput { Id = adminUser.Id, UserName = adminUser.UserName, Type = adminUser.Type, Status = adminUser.Status, CreatedBy = adminUser.CreatedBy, CreatedAt = adminUser.CreatedAt, UpdatedBy = adminUser.UpdatedBy, UpdatedAt = adminUser.UpdatedAt };
return new AdminUserOutput { Id = adminUser.Id, UserName = adminUser.UserName, Type = adminUser.Type.ToString(), Status = adminUser.Status, CreatedBy = adminUser.CreatedBy, CreatedAt = adminUser.CreatedAt, UpdatedBy = adminUser.UpdatedBy, UpdatedAt = adminUser.UpdatedAt };
}
/// <summary>
@ -100,10 +101,7 @@ public class AdminUserService(BaseRepository<AdminUser> adminUserRepository, ILo
adminUser.PasswordHash = BCrypt.Net.BCrypt.HashPassword(input.Password);
}
if (!string.IsNullOrWhiteSpace(input.Type))
{
adminUser.Type = input.Type;
}
adminUser.UpdatedBy = "System";
@ -118,7 +116,7 @@ public class AdminUserService(BaseRepository<AdminUser> adminUserRepository, ILo
logger.LogInformation("管理员更新成功ID: {Id}", id);
return new AdminUserOutput { Id = adminUser.Id, UserName = adminUser.UserName, Type = adminUser.Type, Status = adminUser.Status, CreatedBy = adminUser.CreatedBy, CreatedAt = adminUser.CreatedAt, UpdatedBy = adminUser.UpdatedBy, UpdatedAt = adminUser.UpdatedAt };
return new AdminUserOutput { Id = adminUser.Id, UserName = adminUser.UserName, Type = adminUser.Type.ToString(), Status = adminUser.Status, CreatedBy = adminUser.CreatedBy, CreatedAt = adminUser.CreatedAt, UpdatedBy = adminUser.UpdatedBy, UpdatedAt = adminUser.UpdatedAt };
}
/// <summary>
@ -162,7 +160,7 @@ public class AdminUserService(BaseRepository<AdminUser> adminUserRepository, ILo
{
Id = adminUser.Id,
UserName = adminUser.UserName,
Type = adminUser.Type,
Type = adminUser.Type.ToString(),
Status = adminUser.Status,
CreatedBy = adminUser.CreatedBy,
CreatedAt = adminUser.CreatedAt,
@ -195,7 +193,7 @@ public class AdminUserService(BaseRepository<AdminUser> adminUserRepository, ILo
{
Id = a.Id,
UserName = a.UserName,
Type = a.Type,
Type = a.Type.ToString(),
Status = a.Status,
CreatedBy = a.CreatedBy,
CreatedAt = a.CreatedAt,

View File

@ -1,10 +1,13 @@
using Microsoft.Extensions.Logging;
using QYZH.InteractiveMagazine.Common.Extensions;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto.CheckIn;
using QYZH.InteractiveMagazine.Models.Dto.Compensation;
using QYZH.InteractiveMagazine.Models.Dto.Pet;
using QYZH.InteractiveMagazine.Models.Dto.Points;
using QYZH.InteractiveMagazine.Models.Entity;
using QYZH.InteractiveMagazine.Models.Enum;
using QYZH.InteractiveMagazine.Repository;
namespace QYZH.InteractiveMagazine.Service;
@ -16,6 +19,7 @@ public class CheckInService(
BaseRepository<CheckInRecord> checkInRecordRepository,
IPetService petService,
ICompensationTaskService compensationTaskService,
IPointsService pointsService,
ILogger<CheckInService> logger)
: BaseRepository<CheckInRecord>, ICheckInService
{
@ -77,35 +81,29 @@ public class CheckInService(
PointsAwarded = pointsReward,
GrowthPointsAwarded = growthReward,
ConsecutiveDays = consecutiveDays,
Type = "Normal",
Status = "Success"
Type = CheckInRecordTypeEnum.Normal,
Status = (int)CheckInRecordStatusEnum.Success
};
var recordId = await checkInRecordRepository.Insertable(checkInRecord).ExecuteReturnIdentityAsync();
checkInRecord.Id = recordId;
// 6b. 更新用户积分余额
var newPointsBalance = user.Points + pointsReward;
// 6b. 更新用户成长值
var newGrowthBalance = user.GrowthPoints + growthReward;
await checkInRecordRepository.Context.Updateable<Users>()
.SetColumns(u => u.Points == newPointsBalance)
.SetColumns(u => u.GrowthPoints == newGrowthBalance)
.Where(u => u.Id == userId && !u.IsDeleted)
.ExecuteCommandAsync();
// 6c. 创建积分变动记录
var pointsRecord = new PointsRecord
// 6c. 通过积分服务增加积分
var pointsResult = await pointsService.AddPointsInTranAsync(new AddPointsInput
{
UserId = userId,
ChangeAmount = pointsReward,
BalanceAfter = newPointsBalance,
ChangeType = "SignIn",
Amount = pointsReward,
ChangeType = PointsChangeTypeEnum.SignIn,
RelatedId = recordId,
Description = $"签到奖励(连续{consecutiveDays}天)",
Type = "Income",
Status = "Success"
};
await checkInRecordRepository.Context.Insertable(pointsRecord).ExecuteCommandAsync();
Description = $"签到奖励(连续{consecutiveDays}天)"
});
// 构建返回结果
result.RecordId = (long)recordId;
@ -113,13 +111,13 @@ public class CheckInService(
result.ConsecutiveDays = consecutiveDays;
result.PointsAwarded = pointsReward;
result.GrowthPointsAwarded = growthReward;
result.PointsBalance = newPointsBalance;
result.PointsBalance = pointsResult.NewBalance;
result.GrowthPointsBalance = newGrowthBalance;
result.HasPet = pet != null;
});
// 7. 如果用户有活跃宠物,调用 PetService 喂养(含进化检查),独立事务
if (pet != null && pet.Status == "Active" && growthReward > 0)
if (pet != null && pet.Status == UserPetStatusEnum.Active && growthReward > 0)
{
try
{
@ -141,7 +139,7 @@ public class CheckInService(
await compensationTaskService.CreateTaskAsync(new CreateCompensationTaskInput
{
TaskType = CompensationTaskType.PetFeeding,
TaskType = CompensationTaskTypeEnum.PetFeeding,
BusinessSource = "CheckIn",
BusinessId = result.RecordId.ToString(),
UserId = userId,
@ -212,8 +210,8 @@ public class CheckInService(
ConsecutiveDays = r.ConsecutiveDays,
PointsAwarded = r.PointsAwarded,
GrowthPointsAwarded = r.GrowthPointsAwarded,
Type = r.Type,
Status = r.Status
Type = r.Type.ToString(),
Status = r.Status.ToString()
})
.ToListAsync();
@ -277,8 +275,8 @@ public class CheckInService(
PointsAwarded = pointsReward,
GrowthPointsAwarded = growthReward,
ConsecutiveDays = 0, // 补签不纳入连续天数
Type = "MakeUp",
Status = "Success",
Type = CheckInRecordTypeEnum.MakeUp,
Status = (int)CheckInRecordStatusEnum.Success,
IsDeleted = false,
CreatedBy = userId.ToString(),
CreatedAt = DateTime.Now,
@ -288,47 +286,36 @@ public class CheckInService(
var recordId = await checkInRecordRepository.Insertable(checkInRecord).ExecuteReturnIdentityAsync();
checkInRecord.Id = recordId;
// 更新用户积分和成长值
var newPointsBalance = user.Points + pointsReward;
// 更新用户成长值
var newGrowthBalance = user.GrowthPoints + growthReward;
await checkInRecordRepository.Context.Updateable<Users>()
.SetColumns(u => u.Points == newPointsBalance)
.SetColumns(u => u.GrowthPoints == newGrowthBalance)
.Where(u => u.Id == userId && !u.IsDeleted)
.ExecuteCommandAsync();
// 创建积分变动记录
var pointsRecord = new PointsRecord
// 通过积分服务增加积分
var pointsResult = await pointsService.AddPointsInTranAsync(new AddPointsInput
{
UserId = userId,
ChangeAmount = pointsReward,
BalanceAfter = newPointsBalance,
ChangeType = "MakeUpSign",
Amount = pointsReward,
ChangeType = PointsChangeTypeEnum.MakeUpSign,
RelatedId = recordId,
Description = $"补签奖励({targetDate:yyyy-MM-dd}",
Type = "Income",
Status = "Success",
IsDeleted = false,
CreatedBy = userId.ToString(),
CreatedAt = DateTime.Now,
UpdatedBy = userId.ToString(),
UpdatedAt = DateTime.Now
};
await checkInRecordRepository.Context.Insertable(pointsRecord).ExecuteCommandAsync();
Description = $"补签奖励({targetDate:yyyy-MM-dd}"
});
result.RecordId = (long)recordId;
result.CheckInDate = targetDate;
result.ConsecutiveDays = 0;
result.PointsAwarded = pointsReward;
result.GrowthPointsAwarded = growthReward;
result.PointsBalance = newPointsBalance;
result.PointsBalance = pointsResult.NewBalance;
result.GrowthPointsBalance = newGrowthBalance;
result.HasPet = pet != null;
});
// 如果有活跃宠物,喂养成长值
if (pet != null && pet.Status == "Active" && growthReward > 0)
if (pet != null && pet.Status == UserPetStatusEnum.Active && growthReward > 0)
{
try
{
@ -404,7 +391,7 @@ public class CheckInService(
{
// 查询签到配置(按 DayNumber 升序)
var configs = await checkInRecordRepository.Context.Queryable<CheckInConfig>()
.Where(c => c.Status == "Active" && !c.IsDeleted)
.Where(c => c.Status == CheckInConfigStatusEnum.Active && !c.IsDeleted)
.OrderBy(c => c.DayNumber)
.ToListAsync();

View File

@ -1,8 +1,10 @@
using Microsoft.Extensions.Logging;
using QYZH.InteractiveMagazine.Common.Extensions;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Entity;
using QYZH.InteractiveMagazine.Models.Enum;
using QYZH.InteractiveMagazine.Repository;
using SqlSugar;
@ -28,11 +30,11 @@ public class CommunityMessageService(BaseRepository<CommunityMessage> messageRep
RefAsync<int> totalNumber = 0;
var pageResult = await messageRepository.Queryable()
.WhereIF(input.JournalId.HasValue, m => m.JournalId == input.JournalId.Value)
.WhereIF(!string.IsNullOrWhiteSpace(input.Type), m => m.Type == input.Type)
.WhereIF(!string.IsNullOrWhiteSpace(input.Type), m => m.Type.ToString() == input.Type)
.WhereIF(input.Status.HasValue, m => m.Status == input.Status.Value)
.WhereIF(input.IsFeatured.HasValue, m => m.IsFeatured == input.IsFeatured.Value)
.WhereIF(input.IsActive.HasValue, m => m.IsActive == input.IsActive.Value)
.WhereIF(!string.IsNullOrWhiteSpace(input.Keyword), m => m.Content.Contains(input.Keyword))
.WhereIF(!string.IsNullOrWhiteSpace(input.KeyWord), m => m.Content.Contains(input.KeyWord))
.WhereIF(input.UserId.HasValue, m => m.UserId == input.UserId.Value)
.OrderByDescending(m => m.IsFeatured)
.OrderByDescending(m => m.CreatedAt)
@ -48,7 +50,7 @@ public class CommunityMessageService(BaseRepository<CommunityMessage> messageRep
ImageUrl = m.ImageUrl,
SortOrder = m.SortOrder,
IsActive = m.IsActive,
Type = m.Type,
Type = m.Type.ToString(),
LikeCount = m.LikeCount,
IsFeatured = m.IsFeatured,
Status = m.Status,
@ -88,7 +90,7 @@ public class CommunityMessageService(BaseRepository<CommunityMessage> messageRep
ImageUrl = message.ImageUrl,
SortOrder = message.SortOrder,
IsActive = message.IsActive,
Type = message.Type,
Type = message.Type.ToString(),
LikeCount = message.LikeCount,
IsFeatured = message.IsFeatured,
Status = message.Status,
@ -216,4 +218,24 @@ public class CommunityMessageService(BaseRepository<CommunityMessage> messageRep
logger.LogInformation("社区消息排序权重设置成功ID: {Id}, SortOrder: {SortOrder}", id, sortOrder);
}
/// <summary>
/// 批量发布消息
/// </summary>
public async Task BatchPublishAsync(List<long> ids)
{
logger.LogInformation("正在批量发布社区消息,数量: {Count}", ids.Count);
if (ids == null || ids.Count == 0)
{
throw new BusinessException("消息ID列表不能为空", 400);
}
var result = await Context.Updateable<CommunityMessage>()
.SetColumns(m => m.IsActive == true)
.Where(m => ids.Contains(m.Id))
.ExecuteCommandAsync();
logger.LogInformation("批量发布社区消息完成,影响行数: {Result}", result);
}
}

View File

@ -0,0 +1,191 @@
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Dto.Compensation;
using QYZH.InteractiveMagazine.Models.Entity;
using QYZH.InteractiveMagazine.Models.Enum;
using QYZH.InteractiveMagazine.Repository;
using SqlSugar;
namespace QYZH.InteractiveMagazine.Service;
/// <summary>
/// 补偿任务管理服务实现
/// </summary>
public class CompensationManageService(
BaseRepository<CompensationTask> compensationTaskRepository,
IOperationLogService operationLogService,
ILogger<CompensationManageService> logger)
: BaseRepository<CompensationTask>, ICompensationManageService
{
/// <summary>
/// 分页查询补偿任务(含用户昵称)
/// </summary>
public async Task<PageListModel<CompensationManageOutput>> GetListAsync(CompensationTaskQueryInput input)
{
if (input.PageIndex <= 0)
input.PageIndex = 1;
if (input.PageSize <= 0 || input.PageSize > 100)
input.PageSize = 10;
RefAsync<int> totalNumber = 0;
var pageResult = await compensationTaskRepository.Queryable()
.LeftJoin<Users>((t, u) => t.UserId == u.Id)
.WhereIF(input.UserId.HasValue, (t, u) => t.UserId == input.UserId.Value)
.WhereIF(input.TaskType.HasValue, (t, u) => t.TaskType == (int)input.TaskType.Value)
.WhereIF(input.Status.HasValue, (t, u) => t.Status == input.Status.Value)
.WhereIF(!string.IsNullOrWhiteSpace(input.BusinessSource), (t, u) => t.BusinessSource == input.BusinessSource)
.OrderByDescending((t, u) => t.CreatedAt)
.Select((t, u) => new CompensationManageOutput
{
Id = t.Id,
TaskType = (CompensationTaskTypeEnum)t.TaskType,
BusinessSource = t.BusinessSource,
BusinessId = t.BusinessId,
UserId = t.UserId,
UserName = u.Name,
Payload = t.Payload,
ErrorMessage = t.ErrorMessage,
ErrorSource = t.ErrorSource,
RetryCount = t.RetryCount,
MaxRetries = t.MaxRetries,
Status = t.Status,
ProcessedAt = t.ProcessedAt,
ScheduledAt = t.ScheduledAt,
ResultMessage = t.ResultMessage,
CreatedAt = t.CreatedAt
})
.ToPageListAsync(input.PageIndex, input.PageSize, totalNumber);
return new PageListModel<CompensationManageOutput>(pageResult, input.PageIndex, input.PageSize, totalNumber);
}
/// <summary>
/// 手动重试补偿任务
/// </summary>
public async Task RetryAsync(long taskId, long operatorId, string operatorName, CompensationRetryInput input, string? ipAddress = null)
{
logger.LogInformation("手动重试补偿任务TaskId: {TaskId}, Operator: {Operator}", taskId, operatorName);
var task = await compensationTaskRepository.GetByIdAsync(taskId);
if (task == null)
throw new BusinessException("补偿任务不存在", 404);
if (task.Status != CompensationTaskStatusEnum.Failed && task.Status != CompensationTaskStatusEnum.Cancelled)
throw new BusinessException($"只有失败或已取消的任务才能重试,当前状态: {task.Status}", 400);
// 重置任务状态为 Pending清零重试次数设置立即执行
await compensationTaskRepository.Context.Updateable<CompensationTask>()
.SetColumns(t => t.Status == CompensationTaskStatusEnum.Pending)
.SetColumns(t => t.RetryCount == 0)
.SetColumns(t => t.ScheduledAt == DateTime.Now)
.SetColumns(t => t.ResultMessage == $"管理员手动重试: {input.Reason}")
.SetColumns(t => t.UpdatedBy == operatorName)
.SetColumns(t => t.UpdatedAt == DateTime.Now)
.Where(t => t.Id == taskId && !t.IsDeleted)
.ExecuteCommandAsync();
// 记录操作日志
var detail = JsonConvert.SerializeObject(new
{
OriginalStatus = task.Status,
Reason = input.Reason,
TaskType = task.TaskType,
UserId = task.UserId
});
await operationLogService.LogAsync(
operatorId, operatorName,
OperationLogActionType.CompensationRetry,
OperationLogTargetType.CompensationTask,
taskId, null, detail, ipAddress);
logger.LogInformation("补偿任务手动重试成功TaskId: {TaskId}", taskId);
}
/// <summary>
/// 标记补偿任务为已解决
/// </summary>
public async Task ResolveAsync(long taskId, long operatorId, string operatorName, CompensationResolveInput input, string? ipAddress = null)
{
logger.LogInformation("标记补偿任务已解决TaskId: {TaskId}, Operator: {Operator}", taskId, operatorName);
var task = await compensationTaskRepository.GetByIdAsync(taskId);
if (task == null)
throw new BusinessException("补偿任务不存在", 404);
if (task.Status == CompensationTaskStatusEnum.Success)
throw new BusinessException("该任务已经是成功状态,无需标记", 400);
// 标记为 Success
await compensationTaskRepository.Context.Updateable<CompensationTask>()
.SetColumns(t => t.Status == CompensationTaskStatusEnum.Success)
.SetColumns(t => t.ResultMessage == $"管理员手动标记已解决: {input.ResolveNote}")
.SetColumns(t => t.ProcessedAt == DateTime.Now)
.SetColumns(t => t.UpdatedBy == operatorName)
.SetColumns(t => t.UpdatedAt == DateTime.Now)
.Where(t => t.Id == taskId && !t.IsDeleted)
.ExecuteCommandAsync();
// 记录操作日志
var detail = JsonConvert.SerializeObject(new
{
OriginalStatus = task.Status,
ResolveNote = input.ResolveNote,
TaskType = task.TaskType,
UserId = task.UserId
});
await operationLogService.LogAsync(
operatorId, operatorName,
OperationLogActionType.CompensationResolve,
OperationLogTargetType.CompensationTask,
taskId, null, detail, ipAddress);
logger.LogInformation("补偿任务标记已解决成功TaskId: {TaskId}", taskId);
}
/// <summary>
/// 获取补偿任务详情
/// </summary>
public async Task<CompensationManageDetailOutput> GetDetailAsync(long taskId)
{
logger.LogInformation("获取补偿任务详情TaskId: {TaskId}", taskId);
var result = await compensationTaskRepository.Queryable()
.LeftJoin<Users>((t, u) => t.UserId == u.Id)
.Where((t, u) => t.Id == taskId && !t.IsDeleted)
.Select((t, u) => new CompensationManageDetailOutput
{
Id = t.Id,
TaskType = (CompensationTaskTypeEnum)t.TaskType,
BusinessSource = t.BusinessSource,
BusinessId = t.BusinessId,
UserId = t.UserId,
UserName = u.Name,
Payload = t.Payload,
ErrorMessage = t.ErrorMessage,
ErrorSource = t.ErrorSource,
RetryCount = t.RetryCount,
MaxRetries = t.MaxRetries,
Status = t.Status,
ProcessedAt = t.ProcessedAt,
ScheduledAt = t.ScheduledAt,
ResultMessage = t.ResultMessage,
CreatedAt = t.CreatedAt,
CreatedBy = t.CreatedBy,
UpdatedBy = t.UpdatedBy,
UpdatedAt = t.UpdatedAt
})
.FirstAsync();
if (result == null)
throw new BusinessException("补偿任务不存在", 404);
return result;
}
}

Some files were not shown because too many files have changed in this diff Show More