From a6db06c6cba8dd58a79330d0d0c7746ebb972813 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=BE=B7=E6=AD=A6=20=E9=BB=84?= <865114447@qq.com>
Date: Mon, 29 Jun 2026 17:16:38 +0800
Subject: [PATCH 1/2] =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E6=96=B0=E5=A2=9E?=
=?UTF-8?q?=E4=BB=BB=E5=8A=A1=E5=8F=82=E6=95=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../BatchClaimPointsOutput.cs | 5 +++
.../ClaimTaskPointsOutput.cs | 5 +++
.../UserAnswerTaskService.cs | 34 +++++++++++++++++++
3 files changed, 44 insertions(+)
diff --git a/QYZH.InteractiveMagazine.Models/Dto/UserAnswerTaskService/BatchClaimPointsOutput.cs b/QYZH.InteractiveMagazine.Models/Dto/UserAnswerTaskService/BatchClaimPointsOutput.cs
index 4054b17..f325be9 100644
--- a/QYZH.InteractiveMagazine.Models/Dto/UserAnswerTaskService/BatchClaimPointsOutput.cs
+++ b/QYZH.InteractiveMagazine.Models/Dto/UserAnswerTaskService/BatchClaimPointsOutput.cs
@@ -67,6 +67,11 @@ public class BatchClaimSuccessItem
///
public string TaskName { get; set; }
+ ///
+ /// 任务编号(从 JournalPageTask.No 字段按 - 分割取索引2)
+ ///
+ public string TaskNo { get; set; }
+
///
/// 积分值
///
diff --git a/QYZH.InteractiveMagazine.Models/Dto/UserAnswerTaskService/ClaimTaskPointsOutput.cs b/QYZH.InteractiveMagazine.Models/Dto/UserAnswerTaskService/ClaimTaskPointsOutput.cs
index 41f3d12..1b8c131 100644
--- a/QYZH.InteractiveMagazine.Models/Dto/UserAnswerTaskService/ClaimTaskPointsOutput.cs
+++ b/QYZH.InteractiveMagazine.Models/Dto/UserAnswerTaskService/ClaimTaskPointsOutput.cs
@@ -30,6 +30,11 @@ public class ClaimTaskPointsOutput
///
public string TaskName { get; set; }
+ ///
+ /// 任务编号(从 JournalPageTask.No 字段按 - 分割取索引2)
+ ///
+ public string TaskNo { get; set; }
+
///
/// 题目得分(从 JournalPageTaskUserAnswer 表获取,JournalPageTaskId == GroupId 的 Score)
///
diff --git a/QYZH.InteractiveMagazine.Service/UserAnswerTaskService.cs b/QYZH.InteractiveMagazine.Service/UserAnswerTaskService.cs
index d1093cb..7ce542d 100644
--- a/QYZH.InteractiveMagazine.Service/UserAnswerTaskService.cs
+++ b/QYZH.InteractiveMagazine.Service/UserAnswerTaskService.cs
@@ -1257,6 +1257,22 @@ public class UserAnswerTaskService(
OperatorName = "系统"
});
+ // ============================================
+ // 【任务编号计算】
+ // 从 JournalPageTask.No 字段按 - 分割,取索引为 2 的部分
+ // No 最多出现索引为 3(即最多4段,0-3)
+ // 例如:"A-B-C-D" → 分割后 ["A","B","C","D"] → 取索引2 = "C"
+ // ============================================
+ string taskNo = string.Empty;
+ if (!string.IsNullOrEmpty(mainTask.No))
+ {
+ var parts = mainTask.No.Split('-');
+ if (parts.Length >= 3)
+ {
+ taskNo = parts[2];
+ }
+ }
+
return new ClaimTaskPointsOutput
{
RecordId = addPointsResult.RecordId,
@@ -1264,6 +1280,7 @@ public class UserAnswerTaskService(
NewBalance = addPointsResult.NewBalance,
AddedAmount = addPointsResult.AddedAmount,
TaskName = mainTask.Task ?? string.Empty,
+ TaskNo = !string.IsNullOrWhiteSpace(taskNo) ? "任务:"+ taskNo : string.Empty,
Score = totalScore
};
#endregion
@@ -1483,6 +1500,22 @@ public class UserAnswerTaskService(
// 获取任务名称
var taskName = mainTask.Task ?? string.Empty;
+
+ // ============================================
+ // 【任务编号计算】
+ // 从 JournalPageTask.No 字段按 - 分割,取索引为 2 的部分
+ // No 最多出现索引为 3(即最多4段,0-3)
+ // 例如:"A-B-C-D" → 分割后 ["A","B","C","D"] → 取索引2 = "C"
+ // ============================================
+ string taskNo = string.Empty;
+ if (!string.IsNullOrEmpty(mainTask.No))
+ {
+ var parts = mainTask.No.Split('-');
+ if (parts.Length >= 3)
+ {
+ taskNo = parts[2];
+ }
+ }
#endregion
#region 3.7 调用积分服务并记录结果
@@ -1508,6 +1541,7 @@ public class UserAnswerTaskService(
{
GroupId = groupId,
TaskName = taskName,
+ TaskNo = !string.IsNullOrWhiteSpace(taskNo) ? "任务:" + taskNo : string.Empty,
Points = points,
GrowthPoints = growthPoints,
Score = score
From 5481c091f219cb61f68644b4b88632b15bed4d5c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=BE=B7=E6=AD=A6=20=E9=BB=84?= <865114447@qq.com>
Date: Mon, 29 Jun 2026 17:49:39 +0800
Subject: [PATCH 2/2] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=B9=E6=B3=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../IUserAnswerTaskService.cs | 24 ---
.../UserAnswerTaskService/AddStudentInput.cs | 18 --
.../UserAnswerTaskService/AddStudentOutput.cs | 43 -----
.../JournalListOutput.cs | 32 ----
.../UserAnswerTaskService.cs | 159 ------------------
.../WeChat/UserAnswerTaskController.cs | 96 -----------
6 files changed, 372 deletions(-)
delete mode 100644 QYZH.InteractiveMagazine.Models/Dto/UserAnswerTaskService/AddStudentInput.cs
delete mode 100644 QYZH.InteractiveMagazine.Models/Dto/UserAnswerTaskService/AddStudentOutput.cs
delete mode 100644 QYZH.InteractiveMagazine.Models/Dto/UserAnswerTaskService/JournalListOutput.cs
diff --git a/QYZH.InteractiveMagazine.IService/IUserAnswerTaskService.cs b/QYZH.InteractiveMagazine.IService/IUserAnswerTaskService.cs
index 5ad013c..4621c1a 100644
--- a/QYZH.InteractiveMagazine.IService/IUserAnswerTaskService.cs
+++ b/QYZH.InteractiveMagazine.IService/IUserAnswerTaskService.cs
@@ -62,28 +62,4 @@ public interface IUserAnswerTaskService : IBaseService用户Id
/// 批量领取结果
Task BatchClaimPointsAsync(BatchClaimPointsInput input, long userId);
-
- ///
- /// 获取杂志列表
- ///
- /// 用户Id
- /// 查询类型:Bound=已绑定,Unbound=未绑定(添加书籍用),默认是:Bound
- /// 杂志列表
- Task> GetJournalListAsync(long userId, string? queryType);
-
- ///
- /// 添加用户与杂志关联(绑定杂志)
- ///
- /// 杂志ID
- /// 用户ID
- /// 是否绑定成功(已绑定过返回false)
- Task AddUserJournalAsync(long journalId, long userId);
-
- ///
- /// 新增学生
- ///
- /// 新增学生参数
- /// 当前登录用户微信UserId(WxUserId)
- /// 新增学生结果
- Task AddStudentAsync(AddStudentInput input, long wxUserId);
}
diff --git a/QYZH.InteractiveMagazine.Models/Dto/UserAnswerTaskService/AddStudentInput.cs b/QYZH.InteractiveMagazine.Models/Dto/UserAnswerTaskService/AddStudentInput.cs
deleted file mode 100644
index 32acfac..0000000
--- a/QYZH.InteractiveMagazine.Models/Dto/UserAnswerTaskService/AddStudentInput.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace QYZH.InteractiveMagazine.Models.Dto.UserAnswerTaskService
-{
- ///
- /// 新增学生输入
- ///
- public class AddStudentInput
- {
- ///
- /// 昵称
- ///
- public string? Name { get; set; }
-
- ///
- /// 头像地址
- ///
- public string? AvatarUrl { get; set; }
- }
-}
\ No newline at end of file
diff --git a/QYZH.InteractiveMagazine.Models/Dto/UserAnswerTaskService/AddStudentOutput.cs b/QYZH.InteractiveMagazine.Models/Dto/UserAnswerTaskService/AddStudentOutput.cs
deleted file mode 100644
index 8a073bf..0000000
--- a/QYZH.InteractiveMagazine.Models/Dto/UserAnswerTaskService/AddStudentOutput.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-namespace QYZH.InteractiveMagazine.Models.Dto.UserAnswerTaskService
-{
- ///
- /// 新增学生输出
- ///
- public class AddStudentOutput
- {
- ///
- /// 学生Id
- ///
- public long Id { get; set; }
-
- ///
- /// 关联微信用户Id
- ///
- public long WxUserId { get; set; }
-
- ///
- /// 昵称
- ///
- public string? Name { get; set; }
-
- ///
- /// 头像地址
- ///
- public string? AvatarUrl { get; set; }
-
- ///
- /// 用户类型
- ///
- public string Type { get; set; } = "Normal";
-
- ///
- /// 当前成长值
- ///
- public int GrowthPoints { get; set; }
-
- ///
- /// 积分余额
- ///
- public int Points { get; set; }
- }
-}
\ No newline at end of file
diff --git a/QYZH.InteractiveMagazine.Models/Dto/UserAnswerTaskService/JournalListOutput.cs b/QYZH.InteractiveMagazine.Models/Dto/UserAnswerTaskService/JournalListOutput.cs
deleted file mode 100644
index ece7bd6..0000000
--- a/QYZH.InteractiveMagazine.Models/Dto/UserAnswerTaskService/JournalListOutput.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-namespace QYZH.InteractiveMagazine.Models.Dto.UserAnswerTaskService;
-
-///
-/// 杂志列表输出
-///
-public class JournalListOutput
-{
- ///
- /// 杂志Id
- ///
- public long Id { get; set; }
-
- ///
- /// 杂志名称
- ///
- public string Name { get; set; }
-
- ///
- /// 杂志标题
- ///
- public string Title { get; set; }
-
- ///
- /// 封面
- ///
- public string Cover { get; set; }
-
- ///
- /// 是否已绑定
- ///
- public bool IsBound { get; set; }
-}
diff --git a/QYZH.InteractiveMagazine.Service/UserAnswerTaskService.cs b/QYZH.InteractiveMagazine.Service/UserAnswerTaskService.cs
index 0391516..0fdd4c0 100644
--- a/QYZH.InteractiveMagazine.Service/UserAnswerTaskService.cs
+++ b/QYZH.InteractiveMagazine.Service/UserAnswerTaskService.cs
@@ -1570,163 +1570,4 @@ public class UserAnswerTaskService(
return result;
#endregion
}
-
- ///
- /// ============================================
- /// 方法思路:获取杂志列表
- /// 1. 查询所有已归档的杂志(Status=Archive)
- /// 2. 查询用户已绑定的杂志ID列表
- /// 3. 根据queryType过滤(大小写不敏感):
- /// - "Bound":只返回已绑定的杂志
- /// - "Unbound":只返回未绑定的杂志
- /// - 其他:返回空集合
- /// 4. 返回每个杂志的ID、名称、标题、封面、是否已绑定
- /// ============================================
- ///
- /// 用户ID
- /// 查询类型:bound/unbound(大小写不敏感),其他返回空
- /// 杂志列表
- public async Task> GetJournalListAsync(long userId, string? queryType = "Bound")
- {
- #region 1. 查询所有已归档杂志
- // 查询所有已归档且未删除的杂志
- var allJournals = await journalRepository.Queryable()
- .Where(j => !j.IsDeleted && j.Status == (int)JournalStatusEnum.Archive)
- .OrderByDescending(j => j.CreatedAt)
- .ToListAsync();
- #endregion
-
- #region 2. 查询用户已绑定杂志
- // 查询用户已绑定的杂志ID列表
- var userJournals = await userJournalRepository.Context.Queryable()
- .Where(uj => uj.UserId == userId && !uj.IsDeleted)
- .Select(uj => uj.JournalId)
- .ToListAsync();
-
- var boundJournalIds = userJournals.ToHashSet();
- #endregion
-
- #region 3. 根据queryType过滤
- // ============================================
- // 【大小写兼容处理 + 合法值校验】
- // queryType 只接受两种值(大小写不敏感):
- // - "Bound" / "bound" / "BOUND" → 返回已绑定杂志
- // - "Unbound" / "unbound" / "UNBOUND" → 返回未绑定杂志
- // - 空 / 其他值 → 返回空集合
- // ============================================
- var normalizedQueryType = queryType?.ToLowerInvariant() ?? string.Empty;
-
- IEnumerable filteredJournals;
- if (normalizedQueryType == "bound")
- {
- filteredJournals = allJournals.Where(j => boundJournalIds.Contains(j.Id));
- }
- else if (normalizedQueryType == "unbound")
- {
- filteredJournals = allJournals.Where(j => !boundJournalIds.Contains(j.Id));
- }
- else
- {
- // 非 Bound/Unbound 类型,返回空集合
- filteredJournals = Enumerable.Empty();
- }
- #endregion
-
- #region 4. 返回结果映射
- var result = filteredJournals.Select(j => new JournalListOutput
- {
- Id = j.Id,
- Name = j.Name ?? string.Empty,
- Title = j.Title ?? string.Empty,
- Cover = j.Cover ?? string.Empty,
- IsBound = boundJournalIds.Contains(j.Id)
- }).ToList();
-
- return result;
- #endregion
- }
-
- ///
- /// ============================================
- /// 方法思路:添加用户与杂志关联(绑定杂志)
- /// 1. 验证杂志是否存在
- /// 2. 检查用户是否已绑定过该杂志
- /// - 查询 UserJournal 表,条件:UserId + JournalId
- /// 3. 已绑定过:返回 false
- /// 4. 未绑定:插入 UserJournal 记录,返回 true
- /// ============================================
- ///
- /// 杂志ID
- /// 用户ID
- /// 是否绑定成功(已绑定过返回false)
- public async Task AddUserJournalAsync(long journalId, long userId)
- {
- #region 1. 验证杂志是否存在
- var journal = await journalRepository.Queryable()
- .Where(j => j.Id == journalId && !j.IsDeleted)
- .FirstAsync();
-
- if (journal == null)
- {
- throw new BusinessException("杂志不存在", 404);
- }
- #endregion
-
- #region 2. 检查用户是否已绑定过该杂志
- var exist = await userJournalRepository.Context.Queryable()
- .Where(uj => uj.UserId == userId && uj.JournalId == journalId && !uj.IsDeleted)
- .AnyAsync();
-
- if (exist)
- {
- // 已绑定过,返回 false
- return false;
- }
- #endregion
-
- #region 3. 插入 UserJournal 记录
- var userJournal = new UserJournal
- {
- UserId = userId,
- JournalId = journalId,
- Type = UserJournalTypeEnum.Subscribe
- };
-
- var result = await userJournalRepository.InsertAsync(userJournal);
- return result;
- #endregion
- }
-
- ///
- /// ============================================
- /// 方法思路:新增学生
- /// 1. 创建新的Users记录
- /// 2. WxUserId设置为当前登录人ID(wxUserId参数传入)
- /// 3. 初始化积分和成长值为0
- /// 4. 用户类型设置为普通用户(Normal)
- /// 5. 插入数据库并返回结果
- /// ============================================
- ///
- /// 新增学生输入(姓名、头像URL)
- /// 当前登录人ID(微信用户ID)
- /// 是否插入成功
- public async Task AddStudentAsync(AddStudentInput input, long wxUserId)
- {
- #region 1. 创建学生记录
- var student = new Users
- {
- WxUserId = wxUserId,
- Name = input.Name,
- AvatarUrl = input.AvatarUrl,
- GrowthPoints = 0,
- Points = 0,
- Type = UsersTypeEnum.Normal,
- IsLastOnline = false
- };
- #endregion
-
- #region 2. 插入数据库
- return await usersRepository.InsertAsync(student);
- #endregion
- }
}
diff --git a/QYZH.InteractiveMagazine.WebApi/Controllers/WeChat/UserAnswerTaskController.cs b/QYZH.InteractiveMagazine.WebApi/Controllers/WeChat/UserAnswerTaskController.cs
index e2d5201..a558df6 100644
--- a/QYZH.InteractiveMagazine.WebApi/Controllers/WeChat/UserAnswerTaskController.cs
+++ b/QYZH.InteractiveMagazine.WebApi/Controllers/WeChat/UserAnswerTaskController.cs
@@ -262,100 +262,4 @@ public class UserAnswerTaskController : WeChatBaseController
return BaseResponse.Fail("批量领取积分失败,请稍后重试");
}
}
-
- ///
- /// 获取杂志列表
- ///
- /// 查询类型:bound=已绑定,unbound=未绑定(添加杂志用列表),默认是:bound
- /// 杂志列表
- [HttpGet("journal-list")]
- public async Task>> GetJournalListAsync(string? queryType = "bound")
- {
- try
- {
- var userId = GetCurrentUserId();
- if (userId == 0)
- {
- return BaseResponse>.Fail(ResultCode.DENY, "未获取到用户信息");
- }
-
- var result = await _userAnswerTaskService.GetJournalListAsync(userId, queryType);
- return Success(result);
- }
- catch (BusinessException ex)
- {
- _logger.LogWarning(ex, "查询杂志列表业务异常,UserId: {UserId}", GetCurrentUserId());
- return BaseResponse>.Fail(ex.Message);
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "查询杂志列表失败,UserId: {UserId}", GetCurrentUserId());
- return BaseResponse>.Fail("查询杂志列表失败,请稍后重试");
- }
- }
-
- ///
- /// 绑定杂志(添加用户与杂志关联)
- ///
- /// 杂志ID
- /// 是否绑定成功(已绑定过返回false)
- [HttpPost("add-user-journal/{journalId:long}")]
- public async Task> AddUserJournalAsync([Required(ErrorMessage = "参数错误")] long journalId)
- {
- try
- {
- var userId = GetCurrentUserId();
- if (userId == 0)
- {
- return BaseResponse.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.Fail(ex.Message);
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "绑定杂志失败,UserId: {UserId}, JournalId: {JournalId}", GetCurrentUserId(), journalId);
- return BaseResponse.Fail("绑定杂志失败,请稍后重试");
- }
- }
-
- ///
- /// 新增学生
- ///
- /// 新增学生参数
- /// 新增学生结果
- [HttpPost("add-student")]
- public async Task> AddStudentAsync([FromBody] AddStudentInput input)
- {
- try
- {
- var userId = GetCurrentUserId();
- if (userId == 0)
- {
- return BaseResponse.Fail(ResultCode.DENY, "未获取到用户信息");
- }
- if (GetCurrentWxUserId() == null)
- {
- return BaseResponse.Fail(ResultCode.DENY, "未获取到微信信息");
- }
- var result = await _userAnswerTaskService.AddStudentAsync(input, GetCurrentWxUserId()!.Value);
- return Success(result);
- }
- catch (BusinessException ex)
- {
- _logger.LogWarning(ex, "新增学生业务异常,UserId: {UserId}", GetCurrentUserId());
- return BaseResponse.Fail(ex.Message);
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "新增学生失败,UserId: {UserId}", GetCurrentUserId());
- return BaseResponse.Fail("新增学生失败,请稍后重试");
- }
- }
}