Files
QYZH.InteractiveMagazine/QYZH.InteractiveMagazine.WebApi/Controllers/WeChat/UserAnswerTaskController.cs
glz cc2276fe27 refactor(user-journal): 重构用户期刊关联逻辑,移除枚举依赖并新增二维码功能
1.  删除不再使用的UserJournalTypeEnum枚举
2.  将UserJournal实体的Type字段改为int类型并移除枚举依赖
3.  移除BindJournal相关接口的类型参数校验和赋值逻辑
4.  新增二维码生成和上传功能,为用户期刊绑定QrCodeUrl字段
5.  修复UserAnswerTaskController的用户ID获取逻辑
6.  调整UserJournalQrCodeOutput的字段映射,替换QrCodeContent为QrCodeUrl
2026-07-01 17:59:35 +08:00

269 lines
10 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.AspNetCore.Mvc;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Dto.UserAnswerTaskService;
using System.ComponentModel.DataAnnotations;
namespace QYZH.InteractiveMagazine.WebApi.Controllers.WeChat;
/// <summary>
/// 小程序首页控制器
/// </summary>
public class UserAnswerTaskController : WeChatBaseController
{
private readonly IUserAnswerTaskService _userAnswerTaskService;
private readonly ILogger<UserAnswerTaskController> _logger;
/// <summary>
/// 构造函数
/// </summary>
public UserAnswerTaskController(
IUserAnswerTaskService userAnswerTaskService,
ILogger<UserAnswerTaskController> logger)
{
_userAnswerTaskService = userAnswerTaskService;
_logger = logger;
}
private const long ConstUserId = 821752253853766;
/// <summary>
/// 获取当前用户的期刊学习进度列表
/// </summary>
/// <returns>按期刊分组的学习进度数据</returns>
[HttpGet("progress")]
public async Task<BaseResponse<List<JournalProgressOutput>>> GetProgressAsync()
{
try
{
var userId = GetCurrentUserId();
if (userId == 0)
{
return BaseResponse<List<JournalProgressOutput>>.Fail(ResultCode.DENY, "未获取到用户信息");
}
var result = await _userAnswerTaskService.GetJournalProgressAsync(userId);
return Success(result);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取学习进度失败UserId: {UserId}", GetCurrentUserId());
return BaseResponse<List<JournalProgressOutput>>.Fail("获取学习进度失败,请稍后重试");
}
}
/// <summary>
/// 获取目录列表(按一级目录分组,二级目录含完成状态)
/// </summary>
/// <param name="journalId">期刊Id</param>
/// <returns>按一级目录分组的目录列表</returns>
[HttpGet("catalog-list/{journalId:long}")]
public async Task<BaseResponse<List<CatalogListOutput>>> GetCatalogListAsync([Required(ErrorMessage = "参数错误")] long journalId)
{
try
{
var userId = GetCurrentUserId();
if (userId == 0)
{
return BaseResponse<List<CatalogListOutput>>.Fail(ResultCode.DENY, "未获取到用户信息");
}
if (journalId <= 0)
{
return BaseResponse<List<CatalogListOutput>>.Fail(ResultCode.PARAM_ERROR, "期刊Id不能为空");
}
var result = await _userAnswerTaskService.GetCatalogListAsync(journalId, userId);
return Success(result);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取目录列表失败JournalId: {JournalId}, UserId: {UserId}", journalId, GetCurrentUserId());
return BaseResponse<List<CatalogListOutput>>.Fail("获取目录列表失败,请稍后重试");
}
}
/// <summary>
/// 获取一级目录概览(含二级目录详情、页码范围、任务完成状态)
/// </summary>
/// <param name="catalogId">一级目录Id</param>
/// <returns>一级目录概览数据</returns>
[HttpGet("catalog-overview/{catalogId:long}")]
public async Task<BaseResponse<CatalogOverviewOutput>> GetCatalogOverviewAsync([Required(ErrorMessage = "参数错误")] long catalogId)
{
try
{
var userId = GetCurrentUserId();
if (userId == 0)
{
return BaseResponse<CatalogOverviewOutput>.Fail(ResultCode.DENY, "未获取到用户信息");
}
if (catalogId <= 0)
{
return BaseResponse<CatalogOverviewOutput>.Fail(ResultCode.PARAM_ERROR, "目录Id不能为空");
}
var result = await _userAnswerTaskService.GetCatalogOverviewAsync(catalogId, userId);
if (result == null)
{
return BaseResponse<CatalogOverviewOutput>.Fail("未找到该目录");
}
return Success(result);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取目录概览失败CatalogId: {CatalogId}, UserId: {UserId}", catalogId, GetCurrentUserId());
return BaseResponse<CatalogOverviewOutput>.Fail("获取目录概览失败,请稍后重试");
}
}
/// <summary>
/// 获取用户答题任务列表
/// </summary>
/// <param name="catalogId">二级目录Id</param>
/// <returns>答题任务列表</returns>
[HttpGet("task-list/{catalogId:long}")]
public async Task<BaseResponse<UserAnswerTaskListOutput>> GetTaskListAsync([Required(ErrorMessage = "参数错误")] long catalogId)
{
try
{
var userId = GetCurrentUserId();
if (userId == 0)
{
return BaseResponse<UserAnswerTaskListOutput>.Fail(ResultCode.DENY, "未获取到用户信息");
}
if (catalogId <= 0)
{
return BaseResponse<UserAnswerTaskListOutput>.Fail(ResultCode.PARAM_ERROR, "目录Id不能为空");
}
var result = await _userAnswerTaskService.GetUserAnswerTaskListAsync(catalogId, userId);
if (result == null)
{
return BaseResponse<UserAnswerTaskListOutput>.Fail("未找到该目录");
}
return Success(result);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取任务列表失败CatalogId: {CatalogId}, UserId: {UserId}", catalogId, GetCurrentUserId());
return BaseResponse<UserAnswerTaskListOutput>.Fail("获取任务列表失败,请稍后重试");
}
}
/// <summary>
/// 获取跨页题目详情
/// </summary>
/// <param name="groupId">任务分组ID</param>
/// <returns>跨页题目详情</returns>
[HttpGet("cross-page-task/{groupId:long}")]
public async Task<BaseResponse<CrossPageTaskOutput>> GetCrossPageTaskAsync([Required(ErrorMessage ="参数错误")] long groupId)
{
try
{
var userId = GetCurrentUserId();
if (userId == 0)
{
return BaseResponse<CrossPageTaskOutput>.Fail(ResultCode.DENY, "未获取到用户信息");
}
if (groupId <= 0)
{
return BaseResponse<CrossPageTaskOutput>.Fail(ResultCode.PARAM_ERROR, "任务Id不能为空");
}
var result = await _userAnswerTaskService.GetCrossPageTaskAsync(groupId, userId);
if (result == null)
{
return BaseResponse<CrossPageTaskOutput>.Fail("未找到该任务");
}
return Success(result);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取跨页题目失败JournalPageTaskGroupId: {groupId}, UserId: {UserId}", groupId, GetCurrentUserId());
return BaseResponse<CrossPageTaskOutput>.Fail("获取跨页题目失败,请稍后重试");
}
}
/// <summary>
/// 领取任务积分
/// </summary>
/// <param name="groupId">任务分组IdGroupId</param>
/// <returns>领取结果</returns>
[HttpPost("claim-points/{groupId:long}")]
public async Task<BaseResponse<ClaimTaskPointsOutput>> ClaimTaskPointsAsync([Required(ErrorMessage = "参数错误")] long groupId)
{
try
{
var userId = GetCurrentUserId();
if (userId == 0)
{
return BaseResponse<ClaimTaskPointsOutput>.Fail(ResultCode.DENY, "未获取到用户信息");
}
if (groupId <= 0)
{
return BaseResponse<ClaimTaskPointsOutput>.Fail(ResultCode.PARAM_ERROR, "任务分组Id不能为空");
}
var result = await _userAnswerTaskService.ClaimTaskPointsAsync(groupId, userId);
return Success(result);
}
catch (BusinessException ex)
{
_logger.LogWarning(ex, "领取任务积分业务异常groupId: {groupId}, UserId: {UserId}", groupId, GetCurrentUserId());
return BaseResponse<ClaimTaskPointsOutput>.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "领取任务积分失败groupId: {groupId}, UserId: {UserId}", groupId, GetCurrentUserId());
return BaseResponse<ClaimTaskPointsOutput>.Fail("领取任务积分失败,请稍后重试");
}
}
/// <summary>
/// 批量领取任务积分(一键领取)
/// </summary>
/// <param name="input">批量领取参数</param>
/// <returns>批量领取结果</returns>
[HttpPost("batch-claim-points")]
public async Task<BaseResponse<BatchClaimPointsOutput>> BatchClaimPointsAsync([FromBody] BatchClaimPointsInput input)
{
try
{
var userId = GetCurrentUserId();
if (userId == 0)
{
return BaseResponse<BatchClaimPointsOutput>.Fail(ResultCode.DENY, "未获取到用户信息");
}
if (input == null || input.GroupIds == null || input.GroupIds.Count == 0)
{
return BaseResponse<BatchClaimPointsOutput>.Fail(ResultCode.PARAM_ERROR, "任务分组Id列表不能为空");
}
var result = await _userAnswerTaskService.BatchClaimPointsAsync(input, userId);
return Success(result);
}
catch (BusinessException ex)
{
_logger.LogWarning(ex, "批量领取积分业务异常UserId: {UserId}", GetCurrentUserId());
return BaseResponse<BatchClaimPointsOutput>.Fail(ex.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "批量领取积分失败UserId: {UserId}", GetCurrentUserId());
return BaseResponse<BatchClaimPointsOutput>.Fail("批量领取积分失败,请稍后重试");
}
}
}