feat: 完成多模块功能迭代与代码重构
本次提交包含多方面更新: 1. 新增消息类型枚举、杂志标题字段与AI提示词状态管理 2. 重构杂志服务,新增创建杂志接口并统一OSS路径命名规范 3. 调整题库任务结构,将答案解析迁移至独立表并优化关联查询 4. 新增AI提示词无分页查询与状态切换接口 5. 精简任务添加输入DTO,移除冗余字段 6. 修复控制器路由命名大小写不一致问题
This commit is contained in:
@ -13,7 +13,7 @@ using Yitter.IdGenerator;
|
||||
|
||||
namespace QYZH.InteractiveMagazine.Service;
|
||||
|
||||
public class JournalPageTaskService(BaseRepository<Journal> journalRepository, OssService ossService) : BaseRepository<JournalPageTask>, IJournalPageTaskService
|
||||
public class JournalPageTaskService(BaseRepository<Journal> journalRepository, OssService ossService, BaseRepository<JournalPageTaskAnswer> answerRepository) : BaseRepository<JournalPageTask>, IJournalPageTaskService
|
||||
{
|
||||
public async Task<long?> InsertAsync(JournalPageTaskAddInput input)
|
||||
{
|
||||
@ -30,12 +30,40 @@ public class JournalPageTaskService(BaseRepository<Journal> journalRepository, O
|
||||
var groupTask = await Queryable().Where(w => w.No == startNo && w.JournalId == input.JournalId).FirstAsync();
|
||||
BusinessException.ThrowIf(groupTask.IsNull(), "未找到关联跨页的第一部分");
|
||||
map.GroupId = groupTask.GroupId;
|
||||
map.Score = groupTask.Score;
|
||||
map.AnswerTime = groupTask.AnswerTime;
|
||||
map.Type = groupTask.Type;
|
||||
}
|
||||
|
||||
var data = await base.InsertAsync(map);
|
||||
|
||||
// 创建默认答案记录
|
||||
var answer = new JournalPageTaskAnswer
|
||||
{
|
||||
JournalPageTaskId = map.Id,
|
||||
CreatedBy = "System",
|
||||
UpdatedBy = "System",
|
||||
CreatedAt = DateTime.Now,
|
||||
UpdatedAt = DateTime.Now,
|
||||
IsDeleted = false
|
||||
};
|
||||
|
||||
// 如果是关联跨页题目,从第一部分的 Answer 复制 Score 和 AnswerTime
|
||||
if (no.Last() >= 2)
|
||||
{
|
||||
var startNo = $"{no[0]}-{no[1]}-{no[2]}-1";
|
||||
var firstTask = await Queryable().Where(w => w.No == startNo && w.JournalId == input.JournalId).FirstAsync();
|
||||
if (firstTask != null)
|
||||
{
|
||||
var firstAnswer = await answerRepository.Queryable().Where(a => a.JournalPageTaskId == firstTask.Id).FirstAsync();
|
||||
if (firstAnswer != null)
|
||||
{
|
||||
answer.Score = firstAnswer.Score;
|
||||
answer.AnswerTime = firstAnswer.AnswerTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await answerRepository.InsertAsync(answer);
|
||||
|
||||
return map?.Id;
|
||||
}
|
||||
|
||||
@ -48,41 +76,18 @@ public class JournalPageTaskService(BaseRepository<Journal> journalRepository, O
|
||||
var task = await base.Queryable().Where(w => w.Id == input.Id).FirstAsync();
|
||||
BusinessException.ThrowIf(task.IsNull(), "未找到关联的题号");
|
||||
|
||||
var sameTask = await base.Queryable().Where(w => w.No == input.No && w.JournalId == input.JournalId).FirstAsync();
|
||||
var sameTask = await base.Queryable().Where(w => w.No == input.No && w.JournalId == input.JournalId && w.Id != input.Id).FirstAsync();
|
||||
BusinessException.ThrowIf(sameTask.IsNotEmpty(), "已经存在相同题号题目");
|
||||
|
||||
|
||||
var key = $"Journal/{task.JournalId}/{task.JournalPageId}/{task.GroupId}";
|
||||
//if (task.AnswerUrl != input.AnswerUrl && input.AnswerUrl.NotNull())
|
||||
//{
|
||||
// ossService.CopyObject(input.AnswerUrl.RemoveDomain(), $"{key}/answer.{input.AnswerUrl.ToExtension()}");
|
||||
// input.AnswerUrl = $"{key}/answer.{input.AnswerUrl.ToExtension()}";
|
||||
//}
|
||||
//if (task.AnalysisUrl != input.AnalysisUrl && input.AnalysisUrl.NotNull())
|
||||
//{
|
||||
// ossService.CopyObject(input.AnalysisUrl.RemoveDomain(), $"{key}/analysis.{input.AnalysisUrl.ToExtension()}");
|
||||
// input.AnalysisUrl = $"{key}/analysis.{input.AnalysisUrl.ToExtension()}";
|
||||
//}
|
||||
//if (task.VideoUrl != input.VideoUrl && input.VideoUrl.NotNull())
|
||||
//{
|
||||
// ossService.CopyObject(input.VideoUrl.RemoveDomain(), $"{key}/video.{input.VideoUrl.ToExtension()}");
|
||||
// input.VideoUrl = $"{key}/video.{input.VideoUrl.ToExtension()}";
|
||||
//}
|
||||
var key = $"journal/{task.JournalId}/{task.JournalPageId}/{task.GroupId}";
|
||||
|
||||
// 题目侧字段处理
|
||||
input.Task = Deal(task.Task, input.Task, key, "task");
|
||||
input.Answer = Deal(task.Answer, input.Answer, key, "answer");
|
||||
input.Analysis = Deal(task.Analysis, input.Analysis, key, "analysis");
|
||||
|
||||
task.Type = input.Type;
|
||||
task.Task = input.Task;
|
||||
task.Options = input.Options;
|
||||
task.Answer = input.Answer;
|
||||
//task.AnswerUrl = input.AnswerUrl;
|
||||
task.Analysis = input.Analysis;
|
||||
//task.AnalysisUrl = input.AnalysisUrl;
|
||||
task.Score = input.Score;
|
||||
task.AnswerTime = input.AnswerTime;
|
||||
// task.VideoUrl = input.VideoUrl;
|
||||
task.No = input.No;
|
||||
var no = input.No.Split('-').Select(int.Parse).ToArray();
|
||||
if (no.Last() >= 2)
|
||||
@ -91,27 +96,92 @@ public class JournalPageTaskService(BaseRepository<Journal> journalRepository, O
|
||||
var groupTask = await Queryable().Where(w => w.No == startNo && w.JournalId == input.JournalId).FirstAsync();
|
||||
BusinessException.ThrowIf(groupTask.IsNull(), "未找到关联跨页的第一部分");
|
||||
task.GroupId = groupTask.GroupId;
|
||||
task.Score = groupTask.Score;
|
||||
task.AnswerTime = groupTask.AnswerTime;
|
||||
task.Type = groupTask.Type;
|
||||
}
|
||||
//task.JournalId = input.JournalId;
|
||||
//task.JournalPageId = input.JournalPageId;
|
||||
// 这里不能直接用Set,因为jsonmap无法赋值 不知道为啥
|
||||
return await base.Updateable(task).ExecuteCommandAsync() > 0;
|
||||
|
||||
var taskResult = await base.Updateable(task).ExecuteCommandAsync() > 0;
|
||||
|
||||
// 答案侧字段处理
|
||||
var answer = await answerRepository.Queryable().Where(a => a.JournalPageTaskId == task.Id).FirstAsync();
|
||||
if (answer == null)
|
||||
{
|
||||
// 兼容旧数据:如果 Answer 记录不存在则创建
|
||||
answer = new JournalPageTaskAnswer
|
||||
{
|
||||
JournalPageTaskId = task.Id,
|
||||
CreatedBy = "System",
|
||||
CreatedAt = DateTime.Now,
|
||||
IsDeleted = false
|
||||
};
|
||||
}
|
||||
|
||||
// 答案/解析内容处理
|
||||
answer.Answer = Deal(answer.Answer, input.Answer, key, "answer");
|
||||
answer.Analysis = Deal(answer.Analysis, input.Analysis, key, "analysis");
|
||||
answer.Score = input.Score;
|
||||
answer.AnswerTime = input.AnswerTime;
|
||||
answer.UpdatedBy = "System";
|
||||
answer.UpdatedAt = DateTime.Now;
|
||||
|
||||
if (no.Last() >= 2)
|
||||
{
|
||||
var startNo = $"{no[0]}-{no[1]}-{no[2]}-1";
|
||||
var firstTask = await Queryable().Where(w => w.No == startNo && w.JournalId == input.JournalId).FirstAsync();
|
||||
if (firstTask != null)
|
||||
{
|
||||
var firstAnswer = await answerRepository.Queryable().Where(a => a.JournalPageTaskId == firstTask.Id).FirstAsync();
|
||||
if (firstAnswer != null)
|
||||
{
|
||||
answer.Score = firstAnswer.Score;
|
||||
answer.AnswerTime = firstAnswer.AnswerTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (answer.Id == 0)
|
||||
{
|
||||
await answerRepository.InsertAsync(answer);
|
||||
}
|
||||
else
|
||||
{
|
||||
await answerRepository.UpdateAsync(answer);
|
||||
}
|
||||
|
||||
return taskResult;
|
||||
}
|
||||
|
||||
public async Task<bool> KeywordAnalysisAsync(JournalPageTaskKeywordAnalysis input)
|
||||
{
|
||||
return await base.Updateable().SetColumns(s => s.KeywordAnalysis, input.KeywordAnalysis).Where(w => w.GroupId == input.Id).ExecuteCommandAsync() > 0;
|
||||
// KeywordAnalysis 已移至 Answer 表,通过 GroupId 关联的 Task 找到对应的 Answer 记录进行更新
|
||||
var taskIds = await Queryable().Where(w => w.GroupId == input.Id).Select(w => w.Id).ToListAsync();
|
||||
if (taskIds.Count == 0) return false;
|
||||
|
||||
return await answerRepository.Updateable()
|
||||
.SetColumns(s => s.KeywordAnalysis, input.KeywordAnalysis)
|
||||
.Where(a => taskIds.Contains(a.JournalPageTaskId))
|
||||
.ExecuteCommandAsync() > 0;
|
||||
}
|
||||
|
||||
public async Task<JournalPageTaskOutput> DetailAsync(long id)
|
||||
{
|
||||
var data = await base.Queryable()
|
||||
.Where(w => w.Id == id)
|
||||
.Select(w => new JournalPageTaskOutput()
|
||||
, true).FirstAsync();
|
||||
.InnerJoin<JournalPageTaskAnswer>((w, a) => a.JournalPageTaskId == w.Id)
|
||||
.Where((w, a) => w.Id == id)
|
||||
.Select((w, a) => new JournalPageTaskOutput()
|
||||
{
|
||||
Id = w.Id,
|
||||
JournalId = w.JournalId,
|
||||
JournalPageId = w.JournalPageId,
|
||||
No = w.No,
|
||||
Type = (TaskBankTypeEnum)w.Type,
|
||||
Task = w.Task,
|
||||
Options = w.Options,
|
||||
Answer = a.Answer,
|
||||
Analysis = a.Analysis,
|
||||
Score = a.Score,
|
||||
AnswerTime = a.AnswerTime,
|
||||
KeywordAnalysis = a.KeywordAnalysis
|
||||
}, true).FirstAsync();
|
||||
return data;
|
||||
|
||||
}
|
||||
@ -121,7 +191,10 @@ public class JournalPageTaskService(BaseRepository<Journal> journalRepository, O
|
||||
var task = await base.Queryable().Where(w => w.Id == id).FirstAsync();
|
||||
BusinessException.ThrowIf(task.IsNull(), "问题不存在");
|
||||
|
||||
var key = $"Journal/{task.JournalId}/{task.JournalPageId}/{id}";
|
||||
var key = $"journal/{task.JournalId}/{task.JournalPageId}/{id}";
|
||||
|
||||
// 同时删除关联的答案记录
|
||||
await answerRepository.DeleteAsync(a => a.JournalPageTaskId == id);
|
||||
|
||||
ossService.DeleteObject(key);
|
||||
|
||||
@ -135,13 +208,13 @@ public class JournalPageTaskService(BaseRepository<Journal> journalRepository, O
|
||||
|
||||
if (input.AudioUrl.NotNull())
|
||||
{
|
||||
var key = $"Journal/{task.JournalId}/{task.JournalPageId}/{task.Id}/audio.{input.AudioUrl.ToExtension()}";
|
||||
var key = $"journal/{task.JournalId}/{task.JournalPageId}/{task.Id}/audio.{input.AudioUrl.ToExtension()}";
|
||||
ossService.CopyObject(input.AudioUrl, key);
|
||||
input.AudioUrl = key;
|
||||
}
|
||||
if (input.PointsUrl.NotNull())
|
||||
{
|
||||
var key = $"Journal/{task.JournalId}/{task.JournalPageId}/{task.Id}/points.json";
|
||||
var key = $"journal/{task.JournalId}/{task.JournalPageId}/{task.Id}/points.json";
|
||||
ossService.CopyObject(input.PointsUrl, key);
|
||||
input.PointsUrl = key;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user