From 2d3fceb2655752cbf591a8a17b56cad8396a8434 Mon Sep 17 00:00:00 2001 From: glz <694770232@qq.com> Date: Mon, 22 Jun 2026 17:49:37 +0800 Subject: [PATCH] feat(journal task): add crud operations for task answers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重构了任务答案的处理逻辑,将原有的先删后插从任务更新中拆分出来,新增独立的答案增删改查接口: 1. 移除了JournalPageTaskUpdateInput中的TaskAnswer属性 2. 新增JournalTaskAnswerAddInput/UpdateInput DTO 3. 在服务层实现答案的增删改业务逻辑,包含OSS文件处理 4. 在控制器中添加对应的API接口 --- .../IJournalPageTaskService.cs | 4 + .../Dto/Journal/JournalPageTaskUpdateInput.cs | 5 -- .../Dto/Journal/JournalTaskAnswerAddInput.cs | 26 ++++++ .../Journal/JournalTaskAnswerUpdateInput.cs | 26 ++++++ .../JournalPageTaskService.cs | 79 +++++++++++++------ .../Controllers/JournalController.cs | 33 ++++++++ 6 files changed, 144 insertions(+), 29 deletions(-) create mode 100644 QYZH.InteractiveMagazine.Models/Dto/Journal/JournalTaskAnswerAddInput.cs create mode 100644 QYZH.InteractiveMagazine.Models/Dto/Journal/JournalTaskAnswerUpdateInput.cs diff --git a/QYZH.InteractiveMagazine.IService/IJournalPageTaskService.cs b/QYZH.InteractiveMagazine.IService/IJournalPageTaskService.cs index 3a64d73..c916fbb 100644 --- a/QYZH.InteractiveMagazine.IService/IJournalPageTaskService.cs +++ b/QYZH.InteractiveMagazine.IService/IJournalPageTaskService.cs @@ -13,4 +13,8 @@ public interface IJournalPageTaskService : IBaseService Task DeleteAsync(long id); Task ComplementAsync(JournalPageTaskComplementInput input); + + Task AddAnswerAsync(JournalTaskAnswerAddInput input); + Task UpdateAnswerAsync(JournalTaskAnswerUpdateInput input); + Task DeleteAnswerAsync(long id); } diff --git a/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalPageTaskUpdateInput.cs b/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalPageTaskUpdateInput.cs index 0f1b907..dc0b78d 100644 --- a/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalPageTaskUpdateInput.cs +++ b/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalPageTaskUpdateInput.cs @@ -37,11 +37,6 @@ namespace QYZH.InteractiveMagazine.Models.Dto.Journal /// public string Task { get; set; } - /// - /// 答案 - /// - public List TaskAnswer { get; set; } - /// /// 积分 /// diff --git a/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalTaskAnswerAddInput.cs b/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalTaskAnswerAddInput.cs new file mode 100644 index 0000000..cf5488f --- /dev/null +++ b/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalTaskAnswerAddInput.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace QYZH.InteractiveMagazine.Models.Dto.Journal +{ + public class JournalTaskAnswerAddInput + { + /// + /// 题目Id + /// + public long JournalPageTaskId { get; set; } + + /// + /// 参考答案 + /// + public string Answer { get; set; } + + /// + /// 参考答案图片 + /// + public string AnswerUrl { get; set; } + } +} diff --git a/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalTaskAnswerUpdateInput.cs b/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalTaskAnswerUpdateInput.cs new file mode 100644 index 0000000..02824c6 --- /dev/null +++ b/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalTaskAnswerUpdateInput.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace QYZH.InteractiveMagazine.Models.Dto.Journal +{ + public class JournalTaskAnswerUpdateInput + { + /// + /// 答案Id + /// + public long Id { get; set; } + + /// + /// 参考答案 + /// + public string Answer { get; set; } + + /// + /// 参考答案图片 + /// + public string AnswerUrl { get; set; } + } +} diff --git a/QYZH.InteractiveMagazine.Service/JournalPageTaskService.cs b/QYZH.InteractiveMagazine.Service/JournalPageTaskService.cs index e0e147c..6eaac9f 100644 --- a/QYZH.InteractiveMagazine.Service/JournalPageTaskService.cs +++ b/QYZH.InteractiveMagazine.Service/JournalPageTaskService.cs @@ -80,30 +80,6 @@ public class JournalPageTaskService(BaseRepository journalRepository, O var taskResult = await base.Updateable(task).ExecuteCommandAsync() > 0; - // 答案处理:先删后插 - await answerRepository.DeleteAsync(a => a.JournalPageTaskId == task.Id); - - if (input.TaskAnswer != null && input.TaskAnswer.Count > 0) - { - foreach (var ansInput in input.TaskAnswer) - { - // 处理答案中的文件OSS拷贝 - ansInput.Answer = Deal(null, ansInput.Answer, key, "answer"); - ansInput.AnswerUrl = Deal(null, ansInput.AnswerUrl, key, "answerUrl"); - - var answerEntity = new JournalPageTaskAnswer - { - JournalPageTaskId = task.Id, - Answer = ansInput.Answer, - AnswerUrL = ansInput.AnswerUrl, - CreatedBy = "System", - CreatedAt = DateTime.Now, - IsDeleted = false - }; - await answerRepository.InsertAsync(answerEntity); - } - } - return taskResult; } @@ -179,6 +155,61 @@ public class JournalPageTaskService(BaseRepository journalRepository, O return await Updateable(input.Adapt()).Where(w => w.Id == input.Id).ExecuteCommandAsync() > 0; } + public async Task AddAnswerAsync(JournalTaskAnswerAddInput input) + { + var task = await base.Queryable().Where(w => w.Id == input.JournalPageTaskId).FirstAsync(); + BusinessException.ThrowIf(task.IsNull(), "问题不存在"); + + var key = $"journal/{task.JournalId}/{task.JournalPageId}/{task.GroupId}"; + input.Answer = Deal(null, input.Answer, key, "answer"); + input.AnswerUrl = Deal(null, input.AnswerUrl, key, "answerUrl"); + + var entity = new JournalPageTaskAnswer + { + JournalPageTaskId = input.JournalPageTaskId, + Answer = input.Answer, + AnswerUrL = input.AnswerUrl, + CreatedBy = "System", + CreatedAt = DateTime.Now, + IsDeleted = false + }; + await answerRepository.InsertAsync(entity); + return entity.Id; + } + + public async Task UpdateAnswerAsync(JournalTaskAnswerUpdateInput input) + { + var answer = await answerRepository.Queryable().Where(a => a.Id == input.Id).FirstAsync(); + BusinessException.ThrowIf(answer.IsNull(), "答案不存在"); + + var task = await base.Queryable().Where(w => w.Id == answer.JournalPageTaskId).FirstAsync(); + var key = $"journal/{task.JournalId}/{task.JournalPageId}/{task.GroupId}"; + + input.Answer = Deal(answer.Answer, input.Answer, key, "answer"); + input.AnswerUrl = Deal(answer.AnswerUrL, input.AnswerUrl, key, "answerUrl"); + + return await answerRepository.Updateable() + .SetColumns(a => a.Answer == input.Answer) + .SetColumns(a => a.AnswerUrL == input.AnswerUrl) + .Where(a => a.Id == input.Id) + .ExecuteCommandAsync() > 0; + } + + public async Task DeleteAnswerAsync(long id) + { + var answer = await answerRepository.Queryable().Where(a => a.Id == id).FirstAsync(); + BusinessException.ThrowIf(answer.IsNull(), "答案不存在"); + + var task = await base.Queryable().Where(w => w.Id == answer.JournalPageTaskId).FirstAsync(); + var key = $"journal/{task.JournalId}/{task.JournalPageId}/{task.GroupId}"; + + // 清理OSS文件 + Deal(answer.Answer, "", key, "answer"); + Deal(answer.AnswerUrL, "", key, "answerUrl"); + + return await answerRepository.DeleteAsync(a => a.Id == id); + } + private string Deal(string oldUrls, string newUrls, string key, string type) { // 如果 newUrls 为空,则直接返回 diff --git a/QYZH.InteractiveMagazine.WebApi/Controllers/JournalController.cs b/QYZH.InteractiveMagazine.WebApi/Controllers/JournalController.cs index 4f32dde..76b03bc 100644 --- a/QYZH.InteractiveMagazine.WebApi/Controllers/JournalController.cs +++ b/QYZH.InteractiveMagazine.WebApi/Controllers/JournalController.cs @@ -506,6 +506,39 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers var data = await JournalPageTaskService.ComplementAsync(input); return BaseResponse.Success(data); } + + /// + /// 答案新增 + /// + /// + [HttpPost, Route("page/task/answer/add")] + public async Task> AnswerAdd(JournalTaskAnswerAddInput input) + { + var data = await JournalPageTaskService.AddAnswerAsync(input); + return BaseResponse.Success(data); + } + + /// + /// 答案更新 + /// + /// + [HttpPost, Route("page/task/answer/update")] + public async Task> AnswerUpdate(JournalTaskAnswerUpdateInput input) + { + var data = await JournalPageTaskService.UpdateAnswerAsync(input); + return BaseResponse.Success(data); + } + + /// + /// 答案删除 + /// + /// + [HttpPost, Route("page/task/answer/delete/{id:long}")] + public async Task> AnswerDelete(long id) + { + var data = await JournalPageTaskService.DeleteAnswerAsync(id); + return BaseResponse.Success(data); + } #endregion } }