This commit is contained in:
glz
2026-06-29 16:34:29 +08:00
8 changed files with 706 additions and 344 deletions

View File

@ -34,7 +34,7 @@ public interface IUserAnswerTaskService : IBaseService<JournalPageTaskUserAnswer
/// <summary>
/// 获取用户答题任务列表
/// </summary>
/// <param name="catalogId">二级目录IdJournalCatalogId</param>
/// <param name="catalogId">二级目录IdCatalogId</param>
/// <param name="userId">用户Id</param>
/// <returns>答题任务列表</returns>
Task<UserAnswerTaskListOutput> GetUserAnswerTaskListAsync(long catalogId, long userId);
@ -50,10 +50,10 @@ public interface IUserAnswerTaskService : IBaseService<JournalPageTaskUserAnswer
/// <summary>
/// 领取任务积分
/// </summary>
/// <param name="journalPageTaskGroupId">任务分组IdJournalPageTask.GroupId</param>
/// <param name="groupId">任务分组IdJournalPageTask.GroupId</param>
/// <param name="userId">用户Id</param>
/// <returns>领取结果</returns>
Task<ClaimTaskPointsOutput> ClaimTaskPointsAsync(long journalPageTaskGroupId, long userId);
Task<ClaimTaskPointsOutput> ClaimTaskPointsAsync(long groupId, long userId);
/// <summary>
/// 批量领取任务积分(一键领取)
@ -71,6 +71,14 @@ public interface IUserAnswerTaskService : IBaseService<JournalPageTaskUserAnswer
/// <returns>杂志列表</returns>
Task<List<JournalListOutput>> GetJournalListAsync(long userId, string? queryType);
/// <summary>
/// 添加用户与杂志关联(绑定杂志)
/// </summary>
/// <param name="journalId">杂志ID</param>
/// <param name="userId">用户ID</param>
/// <returns>是否绑定成功已绑定过返回false</returns>
Task<bool> AddUserJournalAsync(long journalId, long userId);
/// <summary>
/// 新增学生
/// </summary>

View File

@ -28,5 +28,5 @@ public class CatalogListOutput
/// <summary>
/// 二级栏目列表
/// </summary>
public List<SecondCatalogOutput> Children { get; set; } = new();
public List<SecondCatalogOutput> Children { get; set; } = [];
}

View File

@ -31,7 +31,7 @@ public class ClaimTaskPointsOutput
public string TaskName { get; set; }
/// <summary>
/// 题目得分(从 JournalPageTaskUserAnswer 表获取,跨页题目为所有相关任务得分之和
/// 题目得分(从 JournalPageTaskUserAnswer 表获取,JournalPageTaskId == GroupId 的 Score
/// </summary>
public float Score { get; set; }
}

View File

@ -23,10 +23,20 @@ public class CrossPageTaskOutput
/// <summary>
/// 图片数组已答题用PageAnswerUrl未答题用TaskUrl
/// </summary>
public List<string> Images { get; set; } = new();
public List<string> Images { get; set; } = [];
/// <summary>
/// 页面作答点读图片地址集合(已答题返回,未答题返回空集合)
/// </summary>
public List<string> PageAnswerDotUrl { get; set; } = [];
/// <summary>
/// 是否跨页题目
/// </summary>
public bool IsCrossPage { get; set; }
/// <summary>
/// 是否可以领取积分(任务已完成且未领取过积分)
/// </summary>
public bool CanClaimPoints { get; set; }
}

View File

@ -26,24 +26,25 @@ public class UserAnswerTaskListOutput
public int EndPage { get; set; }
/// <summary>
/// 任务名称列表
/// 任务列表
/// </summary>
public List<string> TaskNames { get; set; } = new();
public List<UserAnswerTaskItemOutput> Tasks { get; set; } = new();
}
/// <summary>
/// 用户答题任务项输出
/// </summary>
public class UserAnswerTaskItemOutput
{
/// <summary>
/// 任务GroupId
/// </summary>
public long GroupId { get; set; }
/// <summary>
/// 任务状态(进行中、已完成、未开始)
/// 任务名称
/// </summary>
public string Status { get; set; }
/// <summary>
/// 答题时间(分钟)
/// </summary>
public double AnswerMinutes { get; set; }
/// <summary>
/// 徽章个数
/// </summary>
public int MedalCount { get; set; }
public string TaskName { get; set; }
/// <summary>
/// 总成长值
@ -54,4 +55,14 @@ public class UserAnswerTaskListOutput
/// 总积分
/// </summary>
public int TotalPoints { get; set; }
/// <summary>
/// 答题时间(分钟)
/// </summary>
public double AnswerMinutes { get; set; }
/// <summary>
/// 任务状态(进行中、已完成、未开始)
/// </summary>
public string Status { get; set; }
}

File diff suppressed because it is too large Load Diff

View File

@ -51,13 +51,14 @@ public class UserAnswerTaskController : WeChatBaseController
}
}
/// <summary>
/// 获取目录列表(按一级目录分组,二级目录含完成状态)
/// </summary>
/// <param name="journalId">期刊Id</param>
/// <returns>按一级目录分组的目录列表</returns>
[HttpGet("catalog-list/{journalId:long}")]
public async Task<BaseResponse<List<CatalogListOutput>>> GetCatalogListAsync([Required] long journalId)
public async Task<BaseResponse<List<CatalogListOutput>>> GetCatalogListAsync([Required(ErrorMessage = "参数错误")] long journalId)
{
try
{
@ -88,7 +89,7 @@ public class UserAnswerTaskController : WeChatBaseController
/// <param name="catalogId">一级目录Id</param>
/// <returns>一级目录概览数据</returns>
[HttpGet("catalog-overview/{catalogId:long}")]
public async Task<BaseResponse<CatalogOverviewOutput>> GetCatalogOverviewAsync([Required] long catalogId)
public async Task<BaseResponse<CatalogOverviewOutput>> GetCatalogOverviewAsync([Required(ErrorMessage = "参数错误")] long catalogId)
{
try
{
@ -124,7 +125,7 @@ public class UserAnswerTaskController : WeChatBaseController
/// <param name="catalogId">二级目录Id</param>
/// <returns>答题任务列表</returns>
[HttpGet("task-list/{catalogId:long}")]
public async Task<BaseResponse<UserAnswerTaskListOutput>> GetTaskListAsync([Required] long catalogId)
public async Task<BaseResponse<UserAnswerTaskListOutput>> GetTaskListAsync([Required(ErrorMessage = "参数错误")] long catalogId)
{
try
{
@ -160,7 +161,7 @@ public class UserAnswerTaskController : WeChatBaseController
/// <param name="journalPageTaskId">任务Id</param>
/// <returns>跨页题目详情</returns>
[HttpGet("cross-page-task/{journalPageTaskId:long}")]
public async Task<BaseResponse<CrossPageTaskOutput>> GetCrossPageTaskAsync([Required] long journalPageTaskId)
public async Task<BaseResponse<CrossPageTaskOutput>> GetCrossPageTaskAsync([Required(ErrorMessage ="参数错误")] long journalPageTaskId)
{
try
{
@ -193,10 +194,10 @@ public class UserAnswerTaskController : WeChatBaseController
/// <summary>
/// 领取任务积分
/// </summary>
/// <param name="journalPageTaskGroupId">任务分组IdJournalPageTask.GroupId</param>
/// <param name="groupId">任务分组IdGroupId</param>
/// <returns>领取结果</returns>
[HttpPost("claim-points/{journalPageTaskGroupId:long}")]
public async Task<BaseResponse<ClaimTaskPointsOutput>> ClaimTaskPointsAsync([Required] long journalPageTaskGroupId)
[HttpPost("claim-points/{groupId:long}")]
public async Task<BaseResponse<ClaimTaskPointsOutput>> ClaimTaskPointsAsync([Required(ErrorMessage = "参数错误")] long groupId)
{
try
{
@ -206,22 +207,22 @@ public class UserAnswerTaskController : WeChatBaseController
return BaseResponse<ClaimTaskPointsOutput>.Fail(ResultCode.DENY, "未获取到用户信息");
}
if (journalPageTaskGroupId <= 0)
if (groupId <= 0)
{
return BaseResponse<ClaimTaskPointsOutput>.Fail(ResultCode.PARAM_ERROR, "任务分组Id不能为空");
}
var result = await _userAnswerTaskService.ClaimTaskPointsAsync(journalPageTaskGroupId, userId);
var result = await _userAnswerTaskService.ClaimTaskPointsAsync(groupId, userId);
return Success(result);
}
catch (BusinessException ex)
{
_logger.LogWarning(ex, "领取任务积分业务异常,JournalPageTaskGroupId: {JournalPageTaskGroupId}, UserId: {UserId}", journalPageTaskGroupId, GetCurrentUserId());
_logger.LogWarning(ex, "领取任务积分业务异常,groupId: {groupId}, UserId: {UserId}", groupId, GetCurrentUserId());
return BaseResponse<ClaimTaskPointsOutput>.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "领取任务积分失败,JournalPageTaskGroupId: {JournalPageTaskGroupId}, UserId: {UserId}", journalPageTaskGroupId, GetCurrentUserId());
_logger.LogError(ex, "领取任务积分失败,groupId: {groupId}, UserId: {UserId}", groupId, GetCurrentUserId());
return BaseResponse<ClaimTaskPointsOutput>.Fail("领取任务积分失败,请稍后重试");
}
}
@ -265,10 +266,10 @@ public class UserAnswerTaskController : WeChatBaseController
/// <summary>
/// 获取杂志列表
/// </summary>
/// <param name="queryType">查询类型:Bound=已绑定,Unbound=未绑定(添加书籍用),默认是:Bound</param>
/// <param name="queryType">查询类型:bound=已绑定,unbound=未绑定(添加杂志用列表),默认是:bound</param>
/// <returns>杂志列表</returns>
[HttpGet("journal-list")]
public async Task<BaseResponse<List<JournalListOutput>>> GetJournalListAsync([FromQuery] string? queryType = "Bound")
public async Task<BaseResponse<List<JournalListOutput>>> GetJournalListAsync(string? queryType = "bound")
{
try
{
@ -293,6 +294,37 @@ public class UserAnswerTaskController : WeChatBaseController
}
}
/// <summary>
/// 绑定杂志(添加用户与杂志关联)
/// </summary>
/// <param name="journalId">杂志ID</param>
/// <returns>是否绑定成功已绑定过返回false</returns>
[HttpPost("add-user-journal/{journalId:long}")]
public async Task<BaseResponse<bool>> AddUserJournalAsync([Required(ErrorMessage = "参数错误")] long journalId)
{
try
{
var userId = GetCurrentUserId();
if (userId == 0)
{
return BaseResponse<bool>.Fail(ResultCode.DENY, "未获取到用户信息");
}
var result = await _userAnswerTaskService.AddUserJournalAsync(journalId, userId);
return Success(result);
}
catch (BusinessException ex)
{
_logger.LogWarning(ex, "绑定杂志业务异常UserId: {UserId}, JournalId: {JournalId}", GetCurrentUserId(), journalId);
return BaseResponse<bool>.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "绑定杂志失败UserId: {UserId}, JournalId: {JournalId}", GetCurrentUserId(), journalId);
return BaseResponse<bool>.Fail("绑定杂志失败,请稍后重试");
}
}
/// <summary>
/// 新增学生
/// </summary>
@ -308,8 +340,11 @@ public class UserAnswerTaskController : WeChatBaseController
{
return BaseResponse<bool>.Fail(ResultCode.DENY, "未获取到用户信息");
}
var result = await _userAnswerTaskService.AddStudentAsync(input, GetCurrentWxUserId().Value);
if (GetCurrentWxUserId() == null)
{
return BaseResponse<bool>.Fail(ResultCode.DENY, "未获取到微信信息");
}
var result = await _userAnswerTaskService.AddStudentAsync(input, GetCurrentWxUserId()!.Value);
return Success(result);
}
catch (BusinessException ex)

View File

@ -22,8 +22,10 @@
"ClientProvidedName": "Custom connection name"
},
"WeChatSettings": {
"AppId": "wx8c08da60bd207e64",
"AppSecret": "76fa314c34762c0347bd613e488c6872"
//"AppId": "wx5d8f281c2fd6594c",
//"AppSecret": "974f45e4a0aaa075278db0477d0bd8b6"
"AppId": "a",
"AppSecret": "a"
},
"Serilog": {
"MinimumLevel": {