682 lines
26 KiB
C#
682 lines
26 KiB
C#
using MiAssessment.Core.Interfaces;
|
||
using MiAssessment.Model.Data;
|
||
using MiAssessment.Model.Models.Assessment;
|
||
using MiAssessment.Model.Models.Common;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using Microsoft.Extensions.Logging;
|
||
|
||
namespace MiAssessment.Core.Services;
|
||
|
||
/// <summary>
|
||
/// 测评服务实现
|
||
/// </summary>
|
||
/// <remarks>
|
||
/// 提供测评模块的核心业务功能,包括:
|
||
/// - 测评介绍获取
|
||
/// - 题目列表查询
|
||
/// - 答案提交处理
|
||
/// - 报告状态查询
|
||
/// - 测评结果获取
|
||
/// - 邀请码验证
|
||
/// - 往期测评记录查询
|
||
/// </remarks>
|
||
public class AssessmentService : IAssessmentService
|
||
{
|
||
private readonly MiAssessmentDbContext _dbContext;
|
||
private readonly ILogger<AssessmentService> _logger;
|
||
private readonly ReportGenerationService _reportGenerationService;
|
||
|
||
/// <summary>
|
||
/// 构造函数
|
||
/// </summary>
|
||
/// <param name="dbContext">数据库上下文</param>
|
||
/// <param name="logger">日志记录器</param>
|
||
/// <param name="reportGenerationService">报告生成服务</param>
|
||
public AssessmentService(
|
||
MiAssessmentDbContext dbContext,
|
||
ILogger<AssessmentService> logger,
|
||
ReportGenerationService reportGenerationService)
|
||
{
|
||
_dbContext = dbContext;
|
||
_logger = logger;
|
||
_reportGenerationService = reportGenerationService;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<AssessmentIntroDto?> GetIntroAsync(long typeId)
|
||
{
|
||
_logger.LogDebug("获取测评介绍,typeId: {TypeId}", typeId);
|
||
|
||
var assessmentType = await _dbContext.AssessmentTypes
|
||
.AsNoTracking()
|
||
.Where(a => a.Id == typeId && !a.IsDeleted)
|
||
.Select(a => new AssessmentIntroDto
|
||
{
|
||
ImageUrl = a.DetailImageUrl,
|
||
Content = a.IntroContent ?? string.Empty,
|
||
ContentType = "html",
|
||
Price = a.Price
|
||
})
|
||
.FirstOrDefaultAsync();
|
||
|
||
if (assessmentType == null)
|
||
{
|
||
_logger.LogWarning("测评类型不存在,typeId: {TypeId}", typeId);
|
||
}
|
||
else
|
||
{
|
||
_logger.LogDebug("获取测评介绍成功,typeId: {TypeId}", typeId);
|
||
}
|
||
|
||
return assessmentType;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<List<QuestionDto>> GetQuestionListAsync(long typeId)
|
||
{
|
||
_logger.LogDebug("获取题目列表,typeId: {TypeId}", typeId);
|
||
|
||
var questions = await _dbContext.Questions
|
||
.AsNoTracking()
|
||
.Where(q => q.AssessmentTypeId == typeId && q.Status == 1 && !q.IsDeleted)
|
||
.OrderBy(q => q.QuestionNo)
|
||
.Select(q => new QuestionDto
|
||
{
|
||
Id = q.Id,
|
||
QuestionNo = q.QuestionNo,
|
||
Content = q.Content
|
||
})
|
||
.ToListAsync();
|
||
|
||
_logger.LogDebug("获取到 {Count} 道题目,typeId: {TypeId}", questions.Count, typeId);
|
||
return questions;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<ResultStatusDto?> GetResultStatusAsync(long userId, long recordId)
|
||
{
|
||
_logger.LogDebug("查询报告状态,userId: {UserId}, recordId: {RecordId}", userId, recordId);
|
||
|
||
var record = await _dbContext.AssessmentRecords
|
||
.AsNoTracking()
|
||
.Where(r => r.Id == recordId && r.UserId == userId && !r.IsDeleted)
|
||
.Select(r => new ResultStatusDto
|
||
{
|
||
Status = r.Status,
|
||
IsCompleted = r.Status == 4
|
||
})
|
||
.FirstOrDefaultAsync();
|
||
|
||
if (record == null)
|
||
{
|
||
_logger.LogWarning("测评记录不存在或不属于当前用户,userId: {UserId}, recordId: {RecordId}", userId, recordId);
|
||
}
|
||
else
|
||
{
|
||
_logger.LogDebug("查询报告状态成功,status: {Status}, isCompleted: {IsCompleted}", record.Status, record.IsCompleted);
|
||
}
|
||
|
||
return record;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<PagedResult<AssessmentHistoryDto>> GetHistoryListAsync(long userId, int page, int pageSize)
|
||
{
|
||
_logger.LogDebug("获取往期测评列表,userId: {UserId}, page: {Page}, pageSize: {PageSize}", userId, page, pageSize);
|
||
|
||
// 确保分页参数有效
|
||
if (page < 1) page = 1;
|
||
if (pageSize < 1) pageSize = 20;
|
||
if (pageSize > 100) pageSize = 100;
|
||
|
||
var query = _dbContext.AssessmentRecords
|
||
.AsNoTracking()
|
||
.Where(r => r.UserId == userId && !r.IsDeleted);
|
||
|
||
// 获取总数
|
||
var total = await query.CountAsync();
|
||
|
||
// 分页查询(使用左连接避免缺少关联数据时丢失记录)
|
||
var records = await query
|
||
.OrderByDescending(r => r.CreateTime)
|
||
.Skip((page - 1) * pageSize)
|
||
.Take(pageSize)
|
||
.GroupJoin(
|
||
_dbContext.Orders.AsNoTracking(),
|
||
r => r.OrderId,
|
||
o => o.Id,
|
||
(r, orders) => new { Record = r, Orders = orders }
|
||
)
|
||
.SelectMany(
|
||
ro => ro.Orders.DefaultIfEmpty(),
|
||
(ro, o) => new { ro.Record, Order = o }
|
||
)
|
||
.GroupJoin(
|
||
_dbContext.AssessmentTypes.AsNoTracking(),
|
||
ro => ro.Record.AssessmentTypeId,
|
||
at => at.Id,
|
||
(ro, types) => new { ro.Record, ro.Order, Types = types }
|
||
)
|
||
.SelectMany(
|
||
rot => rot.Types.DefaultIfEmpty(),
|
||
(rot, at) => new AssessmentHistoryDto
|
||
{
|
||
Id = rot.Record.Id,
|
||
OrderNo = rot.Order != null ? rot.Order.OrderNo : "",
|
||
AssessmentName = at != null ? at.Name : "多元智能测评",
|
||
Name = rot.Record.Name,
|
||
AssessmentTypeId = rot.Record.AssessmentTypeId,
|
||
Status = rot.Record.Status,
|
||
StatusText = GetStatusText(rot.Record.Status),
|
||
TestDate = rot.Record.CreateTime.ToString("yyyy-MM-dd")
|
||
}
|
||
)
|
||
.ToListAsync();
|
||
|
||
_logger.LogDebug("获取到 {Count} 条往期测评记录,总数: {Total}", records.Count, total);
|
||
|
||
return PagedResult<AssessmentHistoryDto>.Create(records, total, page, pageSize);
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<SubmitAnswersResponse> SubmitAnswersAsync(long userId, SubmitAnswersRequest request)
|
||
{
|
||
_logger.LogDebug("提交测评答案,userId: {UserId}, recordId: {RecordId}, answerCount: {AnswerCount}",
|
||
userId, request.RecordId, request.Answers?.Count ?? 0);
|
||
|
||
// 参数验证
|
||
if (request.Answers == null || request.Answers.Count == 0)
|
||
{
|
||
_logger.LogWarning("答案列表为空,userId: {UserId}, recordId: {RecordId}", userId, request.RecordId);
|
||
throw new InvalidOperationException("答案列表不能为空");
|
||
}
|
||
|
||
// 查询测评记录
|
||
var record = await _dbContext.AssessmentRecords
|
||
.Where(r => r.Id == request.RecordId && !r.IsDeleted)
|
||
.FirstOrDefaultAsync();
|
||
|
||
// 验证记录是否存在
|
||
if (record == null)
|
||
{
|
||
_logger.LogWarning("测评记录不存在,recordId: {RecordId}", request.RecordId);
|
||
throw new InvalidOperationException("测评记录不存在");
|
||
}
|
||
|
||
// 验证记录归属当前用户
|
||
if (record.UserId != userId)
|
||
{
|
||
_logger.LogWarning("测评记录不属于当前用户,userId: {UserId}, recordUserId: {RecordUserId}, recordId: {RecordId}",
|
||
userId, record.UserId, request.RecordId);
|
||
throw new UnauthorizedAccessException("无权限访问该测评记录");
|
||
}
|
||
|
||
// 验证记录状态(只有待测评或测评中状态才能提交答案)
|
||
if (record.Status != 1 && record.Status != 2)
|
||
{
|
||
_logger.LogWarning("测评记录状态不允许提交答案,status: {Status}, recordId: {RecordId}",
|
||
record.Status, request.RecordId);
|
||
throw new InvalidOperationException("当前测评状态不允许提交答案");
|
||
}
|
||
|
||
// 获取该测评类型的题目数量
|
||
var questionCount = await _dbContext.Questions
|
||
.Where(q => q.AssessmentTypeId == record.AssessmentTypeId && q.Status == 1 && !q.IsDeleted)
|
||
.CountAsync();
|
||
|
||
// 验证答案数量与题目数量匹配
|
||
if (request.Answers.Count != questionCount)
|
||
{
|
||
_logger.LogWarning("答案数量与题目数量不匹配,answerCount: {AnswerCount}, questionCount: {QuestionCount}, recordId: {RecordId}",
|
||
request.Answers.Count, questionCount, request.RecordId);
|
||
throw new InvalidOperationException($"答案数量({request.Answers.Count})与题目数量({questionCount})不匹配");
|
||
}
|
||
|
||
// 获取所有有效题目ID用于验证
|
||
var validQuestionIds = await _dbContext.Questions
|
||
.Where(q => q.AssessmentTypeId == record.AssessmentTypeId && q.Status == 1 && !q.IsDeleted)
|
||
.Select(q => new { q.Id, q.QuestionNo })
|
||
.ToDictionaryAsync(q => q.Id, q => q.QuestionNo);
|
||
|
||
// 验证所有答案的题目ID是否有效
|
||
foreach (var answer in request.Answers)
|
||
{
|
||
if (!validQuestionIds.ContainsKey(answer.QuestionId))
|
||
{
|
||
_logger.LogWarning("无效的题目ID,questionId: {QuestionId}, recordId: {RecordId}",
|
||
answer.QuestionId, request.RecordId);
|
||
throw new InvalidOperationException($"无效的题目ID: {answer.QuestionId}");
|
||
}
|
||
}
|
||
|
||
// 使用事务保存答案
|
||
using var transaction = await _dbContext.Database.BeginTransactionAsync();
|
||
try
|
||
{
|
||
// 删除已有的答案(如果有的话,支持重新提交)
|
||
var existingAnswers = await _dbContext.AssessmentAnswers
|
||
.Where(a => a.RecordId == request.RecordId)
|
||
.ToListAsync();
|
||
|
||
if (existingAnswers.Any())
|
||
{
|
||
_dbContext.AssessmentAnswers.RemoveRange(existingAnswers);
|
||
_logger.LogDebug("删除已有答案,count: {Count}, recordId: {RecordId}",
|
||
existingAnswers.Count, request.RecordId);
|
||
}
|
||
|
||
// 创建新的答案记录
|
||
var now = DateTime.Now;
|
||
var answers = request.Answers.Select(a => new MiAssessment.Model.Entities.AssessmentAnswer
|
||
{
|
||
RecordId = request.RecordId,
|
||
QuestionId = a.QuestionId,
|
||
QuestionNo = validQuestionIds[a.QuestionId],
|
||
AnswerValue = a.AnswerValue,
|
||
CreateTime = now
|
||
}).ToList();
|
||
|
||
await _dbContext.AssessmentAnswers.AddRangeAsync(answers);
|
||
|
||
// 更新测评记录状态为"生成中"
|
||
record.Status = 3; // 3=生成中
|
||
record.SubmitTime = now;
|
||
record.UpdateTime = now;
|
||
|
||
await _dbContext.SaveChangesAsync();
|
||
await transaction.CommitAsync();
|
||
|
||
_logger.LogInformation("测评答案提交成功,userId: {UserId}, recordId: {RecordId}, answerCount: {AnswerCount}",
|
||
userId, request.RecordId, answers.Count);
|
||
|
||
// 触发报告生成
|
||
try
|
||
{
|
||
await _reportGenerationService.GenerateReportAsync(request.RecordId);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "报告生成失败,recordId: {RecordId}", request.RecordId);
|
||
// 报告生成失败不影响答案提交的返回,状态保持为3(生成中)
|
||
}
|
||
|
||
return new SubmitAnswersResponse
|
||
{
|
||
Success = true,
|
||
EstimatedTime = 30 // 预计30秒生成报告
|
||
};
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
await transaction.RollbackAsync();
|
||
_logger.LogError(ex, "提交测评答案失败,userId: {UserId}, recordId: {RecordId}", userId, request.RecordId);
|
||
throw;
|
||
}
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<AssessmentResultDto?> GetResultAsync(long userId, long recordId)
|
||
{
|
||
_logger.LogDebug("获取测评结果,userId: {UserId}, recordId: {RecordId}", userId, recordId);
|
||
|
||
// 1. 查询测评记录,验证归属和完成状态
|
||
var record = await _dbContext.AssessmentRecords
|
||
.AsNoTracking()
|
||
.Where(r => r.Id == recordId && !r.IsDeleted)
|
||
.FirstOrDefaultAsync();
|
||
|
||
// 记录不存在
|
||
if (record == null)
|
||
{
|
||
_logger.LogWarning("测评记录不存在,recordId: {RecordId}", recordId);
|
||
return null;
|
||
}
|
||
|
||
// 验证记录归属当前用户(Requirements 4.5)
|
||
if (record.UserId != userId)
|
||
{
|
||
_logger.LogWarning("测评记录不属于当前用户,userId: {UserId}, recordUserId: {RecordUserId}, recordId: {RecordId}",
|
||
userId, record.UserId, recordId);
|
||
return null;
|
||
}
|
||
|
||
// 验证记录已完成(Status=4表示已完成)(Requirements 4.3)
|
||
if (record.Status != 4)
|
||
{
|
||
_logger.LogWarning("测评记录未完成,status: {Status}, recordId: {RecordId}", record.Status, recordId);
|
||
return null;
|
||
}
|
||
|
||
// 2. 获取测评类型信息
|
||
var assessmentType = await _dbContext.AssessmentTypes
|
||
.AsNoTracking()
|
||
.Where(at => at.Id == record.AssessmentTypeId && !at.IsDeleted)
|
||
.FirstOrDefaultAsync();
|
||
|
||
if (assessmentType == null)
|
||
{
|
||
_logger.LogWarning("测评类型不存在,assessmentTypeId: {AssessmentTypeId}", record.AssessmentTypeId);
|
||
return null;
|
||
}
|
||
|
||
// 3. 获取所有报告分类
|
||
var categories = await _dbContext.ReportCategories
|
||
.AsNoTracking()
|
||
.Where(c => c.AssessmentTypeId == record.AssessmentTypeId && !c.IsDeleted)
|
||
.OrderBy(c => c.Sort)
|
||
.ToListAsync();
|
||
|
||
// 4. 获取该记录的所有测评结果
|
||
var results = await _dbContext.AssessmentResults
|
||
.AsNoTracking()
|
||
.Where(r => r.RecordId == recordId)
|
||
.ToListAsync();
|
||
|
||
// 5. 组装报告数据
|
||
var resultDto = new AssessmentResultDto
|
||
{
|
||
Id = record.Id,
|
||
TypeId = record.AssessmentTypeId,
|
||
AssessmentName = assessmentType.Name,
|
||
Name = record.Name,
|
||
TestDate = record.CompleteTime?.ToString("yyyy-MM-dd") ?? record.CreateTime.ToString("yyyy-MM-dd"),
|
||
Intelligences = new List<IntelligenceDto>(),
|
||
Traits = new List<TraitDto>(),
|
||
Abilities = new List<AbilityDto>(),
|
||
InnateLearningTypes = new List<CategoryResultDto>(),
|
||
KeyLearningAbilities = new List<CategoryResultDto>(),
|
||
BrainTypes = new List<CategoryResultDto>(),
|
||
PersonalityTypes = new List<CategoryResultDto>(),
|
||
FutureDevelopmentAbilities = new List<CategoryResultDto>(),
|
||
Suggestions = new List<string>()
|
||
};
|
||
|
||
// 6. 按分类类型组装数据
|
||
foreach (var result in results)
|
||
{
|
||
var category = categories.FirstOrDefault(c => c.Id == result.CategoryId);
|
||
if (category == null) continue;
|
||
|
||
switch (category.CategoryType)
|
||
{
|
||
case 1: // 八大智能
|
||
resultDto.Intelligences.Add(new IntelligenceDto
|
||
{
|
||
Name = category.Name,
|
||
Code = category.Code,
|
||
Score = result.Score,
|
||
Percentage = result.Percentage,
|
||
StarLevel = result.StarLevel,
|
||
Level = GetLevelText(result.StarLevel)
|
||
});
|
||
break;
|
||
|
||
case 2: // 个人特质
|
||
resultDto.Traits.Add(new TraitDto
|
||
{
|
||
Name = category.Name,
|
||
Code = category.Code,
|
||
Score = result.Score,
|
||
Percentage = result.Percentage,
|
||
StarLevel = result.StarLevel
|
||
});
|
||
break;
|
||
|
||
case 3: // 细分能力
|
||
resultDto.Abilities.Add(new AbilityDto
|
||
{
|
||
Name = category.Name,
|
||
Code = category.Code,
|
||
Score = result.Score,
|
||
Percentage = result.Percentage,
|
||
StarLevel = result.StarLevel,
|
||
Level = GetLevelText(result.StarLevel)
|
||
});
|
||
break;
|
||
|
||
case 4: // 先天学习类型
|
||
resultDto.InnateLearningTypes.Add(new CategoryResultDto
|
||
{
|
||
Name = category.Name,
|
||
Code = category.Code,
|
||
Score = result.Score,
|
||
Percentage = result.Percentage,
|
||
StarLevel = result.StarLevel,
|
||
Rank = result.Rank
|
||
});
|
||
break;
|
||
|
||
case 5: // 学习关键能力
|
||
resultDto.KeyLearningAbilities.Add(new CategoryResultDto
|
||
{
|
||
Name = category.Name,
|
||
Code = category.Code,
|
||
Score = result.Score,
|
||
Percentage = result.Percentage,
|
||
StarLevel = result.StarLevel,
|
||
Rank = result.Rank
|
||
});
|
||
break;
|
||
|
||
case 6: // 科学大脑类型
|
||
resultDto.BrainTypes.Add(new CategoryResultDto
|
||
{
|
||
Name = category.Name,
|
||
Code = category.Code,
|
||
Score = result.Score,
|
||
Percentage = result.Percentage,
|
||
StarLevel = result.StarLevel,
|
||
Rank = result.Rank
|
||
});
|
||
break;
|
||
|
||
case 7: // 性格类型
|
||
resultDto.PersonalityTypes.Add(new CategoryResultDto
|
||
{
|
||
Name = category.Name,
|
||
Code = category.Code,
|
||
Score = result.Score,
|
||
Percentage = result.Percentage,
|
||
StarLevel = result.StarLevel,
|
||
Rank = result.Rank
|
||
});
|
||
break;
|
||
|
||
case 8: // 未来关键发展能力
|
||
resultDto.FutureDevelopmentAbilities.Add(new CategoryResultDto
|
||
{
|
||
Name = category.Name,
|
||
Code = category.Code,
|
||
Score = result.Score,
|
||
Percentage = result.Percentage,
|
||
StarLevel = result.StarLevel,
|
||
Rank = result.Rank
|
||
});
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 7. 按得分排序各分类结果
|
||
resultDto.Intelligences = resultDto.Intelligences.OrderByDescending(i => i.Score).ToList();
|
||
resultDto.Traits = resultDto.Traits.OrderByDescending(t => t.Score).ToList();
|
||
resultDto.Abilities = resultDto.Abilities.OrderByDescending(a => a.Score).ToList();
|
||
resultDto.InnateLearningTypes = resultDto.InnateLearningTypes.OrderBy(i => i.Rank).ToList();
|
||
resultDto.KeyLearningAbilities = resultDto.KeyLearningAbilities.OrderBy(k => k.Rank).ToList();
|
||
resultDto.BrainTypes = resultDto.BrainTypes.OrderBy(b => b.Rank).ToList();
|
||
resultDto.PersonalityTypes = resultDto.PersonalityTypes.OrderBy(p => p.Rank).ToList();
|
||
resultDto.FutureDevelopmentAbilities = resultDto.FutureDevelopmentAbilities.OrderBy(f => f.Rank).ToList();
|
||
|
||
// 8. 生成综合评价(基于八大智能的最高分和最低分)
|
||
if (resultDto.Intelligences.Count > 0)
|
||
{
|
||
var topIntelligence = resultDto.Intelligences.First();
|
||
var bottomIntelligence = resultDto.Intelligences.Last();
|
||
resultDto.Summary = $"您的{topIntelligence.Name}表现突出,建议在此领域继续发展。同时可以关注{bottomIntelligence.Name}的提升。";
|
||
}
|
||
|
||
_logger.LogDebug("获取测评结果成功,recordId: {RecordId}, intelligenceCount: {IntelligenceCount}, traitCount: {TraitCount}, abilityCount: {AbilityCount}",
|
||
recordId, resultDto.Intelligences.Count, resultDto.Traits.Count, resultDto.Abilities.Count);
|
||
|
||
return resultDto;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据星级获取等级文本
|
||
/// </summary>
|
||
/// <param name="starLevel">星级(1-5)</param>
|
||
/// <returns>等级文本</returns>
|
||
private static string GetLevelText(int starLevel)
|
||
{
|
||
return starLevel switch
|
||
{
|
||
5 => "优秀",
|
||
4 => "良好",
|
||
3 => "中等",
|
||
2 => "一般",
|
||
1 => "较弱",
|
||
_ => "未知"
|
||
};
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<VerifyInviteCodeResponse> VerifyInviteCodeAsync(string code)
|
||
{
|
||
_logger.LogDebug("验证邀请码,code: {Code}", code);
|
||
|
||
// 参数验证
|
||
if (string.IsNullOrWhiteSpace(code))
|
||
{
|
||
_logger.LogWarning("邀请码为空");
|
||
return new VerifyInviteCodeResponse
|
||
{
|
||
IsValid = false,
|
||
ErrorMessage = "邀请码不能为空"
|
||
};
|
||
}
|
||
|
||
// 查询邀请码
|
||
var inviteCode = await _dbContext.InviteCodes
|
||
.AsNoTracking()
|
||
.Where(ic => ic.Code == code.Trim().ToUpper() && !ic.IsDeleted)
|
||
.FirstOrDefaultAsync();
|
||
|
||
// 邀请码不存在
|
||
if (inviteCode == null)
|
||
{
|
||
_logger.LogWarning("邀请码不存在,code: {Code}", code);
|
||
return new VerifyInviteCodeResponse
|
||
{
|
||
IsValid = false,
|
||
ErrorMessage = "邀请码有误,请重新输入"
|
||
};
|
||
}
|
||
|
||
// 邀请码已使用(Status=3表示已使用)
|
||
if (inviteCode.Status == 3)
|
||
{
|
||
_logger.LogWarning("邀请码已被使用,code: {Code}", code);
|
||
return new VerifyInviteCodeResponse
|
||
{
|
||
IsValid = false,
|
||
ErrorMessage = "邀请码已被使用"
|
||
};
|
||
}
|
||
|
||
// 邀请码未分配(Status=1表示未分配,不能使用)
|
||
if (inviteCode.Status == 1)
|
||
{
|
||
_logger.LogWarning("邀请码未分配,code: {Code}", code);
|
||
return new VerifyInviteCodeResponse
|
||
{
|
||
IsValid = false,
|
||
ErrorMessage = "邀请码有误,请重新输入"
|
||
};
|
||
}
|
||
|
||
// 验证通过(Status=2表示已分配,可以使用)
|
||
_logger.LogDebug("邀请码验证通过,code: {Code}, id: {Id}", code, inviteCode.Id);
|
||
return new VerifyInviteCodeResponse
|
||
{
|
||
IsValid = true,
|
||
InviteCodeId = inviteCode.Id
|
||
};
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取状态文本
|
||
/// </summary>
|
||
/// <param name="status">状态值</param>
|
||
/// <returns>状态文本</returns>
|
||
private static string GetStatusText(int status)
|
||
{
|
||
return status switch
|
||
{
|
||
1 => "待测评",
|
||
2 => "测评中",
|
||
3 => "生成中",
|
||
4 => "已完成",
|
||
_ => "未知"
|
||
};
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<List<ScoreOptionDto>> GetScoreOptionsAsync(long typeId)
|
||
{
|
||
_logger.LogDebug("获取评分标准选项,typeId: {TypeId}", typeId);
|
||
|
||
var options = await _dbContext.ScoreOptions
|
||
.AsNoTracking()
|
||
.Where(s => s.AssessmentTypeId == typeId && s.Status == 1 && !s.IsDeleted)
|
||
.OrderBy(s => s.Sort)
|
||
.ThenBy(s => s.Score)
|
||
.Select(s => new ScoreOptionDto
|
||
{
|
||
Score = s.Score,
|
||
Label = s.Label,
|
||
Description = s.Description
|
||
})
|
||
.ToListAsync();
|
||
|
||
return options;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<PendingRecordDto?> GetPendingRecordAsync(long userId, long typeId)
|
||
{
|
||
_logger.LogDebug("查询进行中的测评记录,userId: {UserId}, typeId: {TypeId}", userId, typeId);
|
||
|
||
var record = await _dbContext.AssessmentRecords
|
||
.AsNoTracking()
|
||
.Where(r => r.UserId == userId
|
||
&& r.AssessmentTypeId == typeId
|
||
&& (r.Status == 1 || r.Status == 2)
|
||
&& !r.IsDeleted)
|
||
.OrderByDescending(r => r.CreateTime)
|
||
.Select(r => new PendingRecordDto
|
||
{
|
||
RecordId = r.Id,
|
||
OrderId = r.OrderId,
|
||
AssessmentTypeId = r.AssessmentTypeId,
|
||
Name = r.Name,
|
||
Phone = r.Phone,
|
||
Gender = r.Gender,
|
||
Age = r.Age,
|
||
EducationStage = r.EducationStage,
|
||
Province = r.Province,
|
||
City = r.City,
|
||
District = r.District,
|
||
Status = r.Status,
|
||
CreateTime = r.CreateTime
|
||
})
|
||
.FirstOrDefaultAsync();
|
||
|
||
if (record != null)
|
||
{
|
||
_logger.LogInformation("找到进行中的测评记录,userId: {UserId}, recordId: {RecordId}, status: {Status}",
|
||
userId, record.RecordId, record.Status);
|
||
}
|
||
|
||
return record;
|
||
}
|
||
}
|