package com.linghu.service.impl; import com.alibaba.excel.EasyExcel; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.linghu.config.FinalStatus; import com.linghu.listener.QuestionExcelListener; import com.linghu.mapper.KeywordMapper; import com.linghu.mapper.ReferenceMapper; import com.linghu.model.common.ResponseResult; import com.linghu.model.dto.KeywordDto; import com.linghu.model.entity.Keyword; import com.linghu.model.entity.Question; import com.linghu.model.entity.Reference; import com.linghu.model.excel.QuestionExcel; import com.linghu.service.KeywordService; import com.linghu.service.QuestionService; import com.linghu.mapper.QuestionMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.web.multipart.MultipartFile; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; /** * @author xy * @description 针对表【question】的数据库操作Service实现 * @createDate 2025-07-04 20:17:33 */ @Service public class QuestionServiceImpl extends ServiceImpl implements QuestionService{ @Autowired private KeywordService keywordService; @Autowired private KeywordMapper keywordMapper; @Autowired private ReferenceMapper referenceMapper; @Override public ResponseResult> addQuestion(KeywordDto keywordDto) { List questionList = Arrays.stream(keywordDto.getQuestions().split("\\n")) .filter(q -> !q.trim().isEmpty()) .map(q -> { Question question = new Question(); question.setKeyword_id(keywordDto.getKeyword_id()); question.setQuestion(q.trim()); question.setStatus(FinalStatus.PENDING.getValue()); return question; }).collect(Collectors.toList()); boolean success = this.saveBatch(questionList); if (success) { return ResponseResult.success(questionList); } return ResponseResult.error("添加提问词失败"); } @Override public ResponseResult updateKeyWord(Question questions) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(Question::getQuestion_id, questions.getQuestion_id()); Question keyword = this.getOne(queryWrapper); if (FinalStatus.SUBMITTED.getValue().equals(keyword.getStatus()) ) { return ResponseResult.error("该关键词在采集中"); } boolean success = this.updateById(questions); if (success) { return ResponseResult.success(); } return ResponseResult.error("更新提问词失败"); } @Override public ResponseResult batchDeleteQuestion(List questionIds) { // 新增判断:如果集合为空,直接返回错误 if (CollectionUtils.isEmpty(questionIds)) { return ResponseResult.error("删除失败,至少选择一个提问词"); } // 2. 批量查询所有提问词 List questions = this.listByIds(questionIds); // 3. 校验所有提问词关联的关键词是否处于采集中 for (Question question : questions) { Keyword keyword = keywordService.getById(question.getKeyword_id()); // 关键词不存在也需处理(可选) if (keyword == null) { return ResponseResult.error("提问词关联的关键词不存在,ID:" + question.getKeyword_id()); } // 核心校验:若有任何关键词在采集中,禁止删除 if (FinalStatus.PENDING.getValue().equals(keyword.getStatus())) { return ResponseResult.error("该关键词在采集中,无法删除"); } } this.removeByIds(questionIds); return ResponseResult.success(); } @Override public ResponseResult> notNullQuestionList(Integer keyword_id) { Keyword keyword = keywordMapper.selectById(keyword_id); List references = referenceMapper.selectList(new LambdaQueryWrapper() .eq(Reference::getKeyword_id, keyword_id) .eq(Reference::getNum, keyword.getNum())); List questionIds = references.stream().map(Reference::getQuestion_id).distinct().collect(Collectors.toList()); // 查询success状态的 当前轮数的 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(Question::getKeyword_id, keyword_id); List list = this.list(queryWrapper); return ResponseResult.success(list); } @Override public ResponseResult> getQuestionListByKeywordId(Integer keyword_id) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(Question::getKeyword_id, keyword_id); List list = this.list(queryWrapper); return ResponseResult.success(list); } @Override public ResponseResult importQuestionsExcel(MultipartFile file) { try { if (file.isEmpty()) { return ResponseResult.error("上传文件不能为空"); } // 创建数据监听器 QuestionExcelListener listener = new QuestionExcelListener(); EasyExcel.read(file.getInputStream(), QuestionExcel.class, listener) .sheet() .doRead(); // 获取并合并关键词 String mergedKeywords = String.join("\n", listener.getMergedKeywords()); return ResponseResult.success(mergedKeywords); } catch (IOException e) { return ResponseResult.error("文件读取失败:" + e.getMessage()); } catch (Exception e) { return ResponseResult.error("导入失败:" + e.getMessage()); } } @Override public ResponseResult> updateQuestion(KeywordDto keywordDto) { if (FinalStatus.SUBMITTED.getValue().equals(keywordDto.getStatus()) ) { return ResponseResult.error("该关键词在采集中"); } this.updateBatchById(keywordDto.getQuestionList()); return ResponseResult.success(); } @Override public ResponseEntity downloadQuestion() { ByteArrayOutputStream out = new ByteArrayOutputStream(); EasyExcel.write(out, QuestionExcel.class).sheet("提问词模板").doWrite(new ArrayList<>()); return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=提问词条导入模板.xlsx") .contentType(MediaType.APPLICATION_OCTET_STREAM) .body(out.toByteArray()); } }