using AutoMapper; using Entities.Contracts; using SharedDATA.Api; using System.Linq.Expressions; using System.Linq; using Entities.DTO; namespace TechHelper.Services.Beta { public class QuestionService : IQuestionService { private readonly IUnitOfWork _work; private readonly IMapper _mapper; private readonly IExamService _examService; public QuestionService(IUnitOfWork work, IMapper mapper, IExamService examService) { _work = work; _mapper = mapper; _examService = examService; } #region CRUD Operations /// /// 创建新题目 /// /// 题目DTO /// API响应结果 public async Task AddAsync(QuestionDto model) { try { // 业务逻辑校验:检查题目是否已存在 var existingQuestion = await _work.GetRepository().GetFirstOrDefaultAsync( predicate: q => q.Title == model.Title && !q.IsDeleted ); if (existingQuestion != null) { return ApiResponse.Error($"题目 '{model.Title}' 已存在,请勿重复添加。"); } var newQuestion = _mapper.Map(model); // 插入数据 await _work.GetRepository().InsertAsync(newQuestion); await _work.SaveChangesAsync(); return ApiResponse.Success("题目添加成功。", newQuestion); } catch (Exception ex) { return ApiResponse.Error($"添加题目失败: {ex.Message}"); } } /// /// 根据ID获取题目 /// /// 题目ID /// API响应结果 public async Task GetAsync(Guid id) { try { var question = await _work.GetRepository().GetFirstOrDefaultAsync( predicate: q => q.Id == id && !q.IsDeleted ); if (question == null) { return ApiResponse.Error($"找不到 ID 为 {id} 的题目。"); } return ApiResponse.Success(result: question); } catch (Exception ex) { return ApiResponse.Error($"获取题目时发生错误: {ex.Message}"); } } /// /// 获取所有题目(支持分页和搜索) /// /// 查询参数 /// API响应结果 public async Task GetAllAsync(QueryParameter query) { try { var repository = _work.GetRepository(); if (query.Search != null && !string.IsNullOrWhiteSpace(query.Search)) { var questions = await repository.GetPagedListAsync( predicate: q => q.Title.Contains(query.Search) && !q.IsDeleted, pageSize: query.PageSize, pageIndex: query.PageIndex ); var questionDtosFiltered = _mapper.Map>(questions.Items); return new ApiResponse(true, questionDtosFiltered); } else { var questions = await repository.GetPagedListAsync( predicate: q => !q.IsDeleted, pageSize: query.PageSize, pageIndex: query.PageIndex ); var questionDtos = _mapper.Map>(questions.Items); return new ApiResponse(true, questionDtos); } } catch (Exception ex) { return new ApiResponse($"获取所有题目时发生错误: {ex.Message}"); } } /// /// 更新题目信息 /// /// 题目DTO /// API响应结果 public async Task UpdateAsync(QuestionDto model) { try { // 检查题目是否存在 var existingQuestion = await _work.GetRepository().GetFirstOrDefaultAsync( predicate: q => q.Id == model.Id && !q.IsDeleted ); if (existingQuestion == null) { return ApiResponse.Error($"找不到 ID 为 {model.Id} 的题目,无法更新。"); } // 检查题目文本是否与其他题目重复 var duplicateCheck = await _work.GetRepository().GetFirstOrDefaultAsync( predicate: q => q.Id != model.Id && q.Title == model.Title && !q.IsDeleted ); if (duplicateCheck != null) { return ApiResponse.Error($"题目文本 '{model.Title}' 已被其他题目占用,请修改。"); } // 使用mapper更新实体属性,保留系统字段 _mapper.Map(model, existingQuestion); existingQuestion.UpdatedAt = DateTime.UtcNow; // 更新数据 _work.GetRepository().Update(existingQuestion); await _work.SaveChangesAsync(); return ApiResponse.Success("题目更新成功。", existingQuestion); } catch (Exception ex) { return ApiResponse.Error($"更新题目失败: {ex.Message}"); } } /// /// 删除题目(软删除) /// /// 题目ID /// API响应结果 public async Task DeleteAsync(Guid id) { try { var questionToDelete = await _work.GetRepository().GetFirstOrDefaultAsync( predicate: q => q.Id == id && !q.IsDeleted ); if (questionToDelete == null) { return ApiResponse.Error($"找不到 ID 为 {id} 的题目,或者该题目已被删除。"); } // 软删除 questionToDelete.IsDeleted = true; questionToDelete.UpdatedAt = DateTime.UtcNow; _work.GetRepository().Update(questionToDelete); await _work.SaveChangesAsync(); return ApiResponse.Success($"ID 为 {id} 的题目已成功删除 (软删除)。"); } catch (Exception ex) { return ApiResponse.Error($"删除题目时发生错误: {ex.Message}"); } } #endregion #region Business Logic Methods /// /// 根据标题查找题目 /// /// 题目标题 /// API响应结果 public async Task FindByTitle(string title) { try { var question = await _work.GetRepository().GetFirstOrDefaultAsync( predicate: q => q.Title == title && !q.IsDeleted ); if (question == null) { return ApiResponse.Error($"未找到题目 '{title}'。"); } return ApiResponse.Success(result: question); } catch (Exception ex) { return ApiResponse.Error($"查找题目时出现问题: {ex.Message}"); } } /// /// 批量检查题目标题是否存在 /// /// 题目标题集合 /// API响应结果 public async Task CheckTitlesExistence(IEnumerable titles) { try { if (titles == null || !titles.Any()) { return ApiResponse.Success("未指定查询的题目文本,返回空结果。", new Dictionary()); } var distinctTitles = titles.Distinct(StringComparer.OrdinalIgnoreCase).ToList(); var existingQuestions = await _work.GetRepository().GetAllAsync( predicate: q => distinctTitles.Contains(q.Title) && !q.IsDeleted ); var existingQuestionTexts = new HashSet( existingQuestions.Select(q => q.Title), StringComparer.OrdinalIgnoreCase ); var resultDictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (var title in titles) { resultDictionary[title] = existingQuestionTexts.Contains(title); } return ApiResponse.Success(result: resultDictionary); } catch (Exception ex) { return ApiResponse.Error($"批量查找题目存在性时出现问题: {ex.Message}"); } } #endregion } /// /// 表达式构建器扩展类 /// public static class PredicateBuilder { public static Expression> And( this Expression> first, Expression> second) { var invokedExpr = Expression.Invoke(second, first.Parameters.Cast()); return Expression.Lambda>( Expression.AndAlso(first.Body, invokedExpr), first.Parameters ); } public static Expression> Or( this Expression> first, Expression> second) { var invokedExpr = Expression.Invoke(second, first.Parameters.Cast()); return Expression.Lambda>( Expression.OrElse(first.Body, invokedExpr), first.Parameters ); } public static Expression> True() => f => true; public static Expression> False() => f => false; } }