feat(journal task): add crud operations for task answers

重构了任务答案的处理逻辑,将原有的先删后插从任务更新中拆分出来,新增独立的答案增删改查接口:
1. 移除了JournalPageTaskUpdateInput中的TaskAnswer属性
2. 新增JournalTaskAnswerAddInput/UpdateInput DTO
3. 在服务层实现答案的增删改业务逻辑,包含OSS文件处理
4. 在控制器中添加对应的API接口
This commit is contained in:
glz
2026-06-22 17:49:37 +08:00
parent d9933e4537
commit 2d3fceb265
6 changed files with 144 additions and 29 deletions

View File

@ -13,4 +13,8 @@ public interface IJournalPageTaskService : IBaseService<JournalPageTask>
Task<bool> DeleteAsync(long id);
Task<bool> ComplementAsync(JournalPageTaskComplementInput input);
Task<long> AddAnswerAsync(JournalTaskAnswerAddInput input);
Task<bool> UpdateAnswerAsync(JournalTaskAnswerUpdateInput input);
Task<bool> DeleteAnswerAsync(long id);
}

View File

@ -37,11 +37,6 @@ namespace QYZH.InteractiveMagazine.Models.Dto.Journal
/// </summary>
public string Task { get; set; }
/// <summary>
/// 答案
/// </summary>
public List<JournalTaskAnswerInput> TaskAnswer { get; set; }
/// <summary>
/// 积分
/// </summary>

View File

@ -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
{
/// <summary>
/// 题目Id
/// </summary>
public long JournalPageTaskId { get; set; }
/// <summary>
/// 参考答案
/// </summary>
public string Answer { get; set; }
/// <summary>
/// 参考答案图片
/// </summary>
public string AnswerUrl { get; set; }
}
}

View File

@ -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
{
/// <summary>
/// 答案Id
/// </summary>
public long Id { get; set; }
/// <summary>
/// 参考答案
/// </summary>
public string Answer { get; set; }
/// <summary>
/// 参考答案图片
/// </summary>
public string AnswerUrl { get; set; }
}
}

View File

@ -80,30 +80,6 @@ public class JournalPageTaskService(BaseRepository<Journal> 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<Journal> journalRepository, O
return await Updateable(input.Adapt<JournalPageTask>()).Where(w => w.Id == input.Id).ExecuteCommandAsync() > 0;
}
public async Task<long> 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<bool> 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<bool> 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 为空,则直接返回

View File

@ -506,6 +506,39 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
var data = await JournalPageTaskService.ComplementAsync(input);
return BaseResponse<bool>.Success(data);
}
/// <summary>
/// 答案新增
/// </summary>
/// <returns></returns>
[HttpPost, Route("page/task/answer/add")]
public async Task<BaseResponse<long>> AnswerAdd(JournalTaskAnswerAddInput input)
{
var data = await JournalPageTaskService.AddAnswerAsync(input);
return BaseResponse<long>.Success(data);
}
/// <summary>
/// 答案更新
/// </summary>
/// <returns></returns>
[HttpPost, Route("page/task/answer/update")]
public async Task<BaseResponse<bool>> AnswerUpdate(JournalTaskAnswerUpdateInput input)
{
var data = await JournalPageTaskService.UpdateAnswerAsync(input);
return BaseResponse<bool>.Success(data);
}
/// <summary>
/// 答案删除
/// </summary>
/// <returns></returns>
[HttpPost, Route("page/task/answer/delete/{id:long}")]
public async Task<BaseResponse<bool>> AnswerDelete(long id)
{
var data = await JournalPageTaskService.DeleteAnswerAsync(id);
return BaseResponse<bool>.Success(data);
}
#endregion
}
}