|
@@ -15,15 +15,14 @@ import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
|
|
+import com.fasterxml.jackson.databind.JsonNode;
|
|
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
import com.github.pagehelper.Page;
|
|
import com.github.pagehelper.Page;
|
|
|
import com.github.pagehelper.PageInfo;
|
|
import com.github.pagehelper.PageInfo;
|
|
|
import com.zhongzheng.common.core.page.TableDataInfo;
|
|
import com.zhongzheng.common.core.page.TableDataInfo;
|
|
|
import com.zhongzheng.common.core.redis.RedisCache;
|
|
import com.zhongzheng.common.core.redis.RedisCache;
|
|
|
import com.zhongzheng.common.exception.CustomException;
|
|
import com.zhongzheng.common.exception.CustomException;
|
|
|
-import com.zhongzheng.common.utils.DateUtils;
|
|
|
|
|
-import com.zhongzheng.common.utils.SecurityUtils;
|
|
|
|
|
-import com.zhongzheng.common.utils.ServletUtils;
|
|
|
|
|
-import com.zhongzheng.common.utils.ToolsUtils;
|
|
|
|
|
|
|
+import com.zhongzheng.common.utils.*;
|
|
|
import com.zhongzheng.common.utils.http.HttpUtils;
|
|
import com.zhongzheng.common.utils.http.HttpUtils;
|
|
|
import com.zhongzheng.modules.alioss.service.OssService;
|
|
import com.zhongzheng.modules.alioss.service.OssService;
|
|
|
import com.zhongzheng.modules.bank.bo.*;
|
|
import com.zhongzheng.modules.bank.bo.*;
|
|
@@ -77,6 +76,8 @@ import java.io.*;
|
|
|
import java.math.BigDecimal;
|
|
import java.math.BigDecimal;
|
|
|
import java.net.HttpURLConnection;
|
|
import java.net.HttpURLConnection;
|
|
|
import java.net.URL;
|
|
import java.net.URL;
|
|
|
|
|
+import java.nio.file.Files;
|
|
|
|
|
+import java.nio.file.Paths;
|
|
|
import java.text.NumberFormat;
|
|
import java.text.NumberFormat;
|
|
|
import java.util.*;
|
|
import java.util.*;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.concurrent.TimeUnit;
|
|
@@ -4603,6 +4604,543 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> i
|
|
|
return Collections.emptyMap();
|
|
return Collections.emptyMap();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ public void getImageWordTwo(MultipartFile file, String major,String exam) {
|
|
|
|
|
+ OCRClient client = new OCRClient("de165480ad1fe94abd16f29a8897b7dd", "6904aae4f8e468d376a3a56f91398e78");
|
|
|
|
|
+
|
|
|
|
|
+ HashMap<String, Object> options = new HashMap<>();
|
|
|
|
|
+ options.put("apply_document_tree", 1);
|
|
|
|
|
+ options.put("apply_image_analysis", 0);
|
|
|
|
|
+ options.put("apply_merge", 1);
|
|
|
|
|
+ options.put("catalog_details", 1);
|
|
|
|
|
+ options.put("dpi", 144);
|
|
|
|
|
+ options.put("formula_level", 1);
|
|
|
|
|
+ options.put("get_excel", 1);
|
|
|
|
|
+ options.put("get_image", "both");
|
|
|
|
|
+ options.put("markdown_details", 1);
|
|
|
|
|
+ options.put("page_count", 1000);
|
|
|
|
|
+ options.put("page_details", 1);
|
|
|
|
|
+ options.put("page_start", 1);
|
|
|
|
|
+ options.put("paratext_mode", "annotation");
|
|
|
|
|
+ options.put("parse_mode", "scan");
|
|
|
|
|
+ options.put("raw_ocr", 0);
|
|
|
|
|
+ options.put("table_flavor", "html");
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ // Read image file
|
|
|
|
|
+ // 方式一:读取本地文件
|
|
|
|
|
+ byte[] fileContent = file.getBytes();
|
|
|
|
|
+// byte[] fileContent = Files.readAllBytes(Paths.get("example.png"));
|
|
|
|
|
+
|
|
|
|
|
+ // 方式二:使用URL方式(需要将headers中的Content-Type改为'text/plain')
|
|
|
|
|
+ // byte[] fileContent = "https://example.com/path/to/your.pdf".getBytes(StandardCharsets.UTF_8);
|
|
|
|
|
+
|
|
|
|
|
+ String response = client.recognize(fileContent, options);
|
|
|
|
|
+ // 保存完整的JSON响应到result.json文件
|
|
|
|
|
+ Files.write(Paths.get("result.json"), response.getBytes());
|
|
|
|
|
+
|
|
|
|
|
+ // 解析JSON响应以提取markdown内容
|
|
|
|
|
+ ObjectMapper mapper = new ObjectMapper();
|
|
|
|
|
+ JsonNode jsonNode = mapper.readTree(response);
|
|
|
|
|
+ if (jsonNode.has("result") && jsonNode.get("result").has("markdown")) {
|
|
|
|
|
+ String markdown = jsonNode.get("result").get("markdown").asText();
|
|
|
|
|
+ List<String> strings = extractPureText(markdown);
|
|
|
|
|
+ questionReset(strings,major,exam);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Files.delete(Paths.get("result.json"));
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ private void questionReset(List<String> questions,String majorName,String exam){
|
|
|
|
|
+
|
|
|
|
|
+ //题库业务层次
|
|
|
|
|
+ CourseEducationType educationType = iCourseEducationTypeService
|
|
|
|
|
+ .getOne(new LambdaQueryWrapper<CourseEducationType>().eq(CourseEducationType::getEducationName, "考前培训").eq(CourseEducationType::getStatus, 1).last("limit 1"));
|
|
|
|
|
+ Long eduId = educationType.getId();
|
|
|
|
|
+ CourseProjectType projectType = iCourseProjectTypeService
|
|
|
|
|
+ .getOne(new LambdaQueryWrapper<CourseProjectType>().eq(CourseProjectType::getProjectName, "施工现场专业人员").eq(CourseProjectType::getEducationId, eduId).eq(CourseProjectType::getStatus, 1).last("limit 1"));
|
|
|
|
|
+ Long proId = projectType.getId();
|
|
|
|
|
+ CourseBusiness business = iCourseBusinessService
|
|
|
|
|
+ .getOne(new LambdaQueryWrapper<CourseBusiness>().eq(CourseBusiness::getBusinessName, "七大员").eq(CourseBusiness::getProjectId, proId).eq(CourseBusiness::getStatus, 1).last("limit 1"));
|
|
|
|
|
+ Long businessId = business.getId();
|
|
|
|
|
+ List<CourseSubjectProject> list = iCourseSubjectProjectService.list(new LambdaQueryWrapper<CourseSubjectProject>().eq(CourseSubjectProject::getProjectId, proId));
|
|
|
|
|
+ List<Long> subIds = list.stream().map(CourseSubjectProject::getSubjectId).collect(Collectors.toList());
|
|
|
|
|
+ CourseSubject courseSubject = iCourseSubjectService.getOne(new LambdaQueryWrapper<CourseSubject>().in(CourseSubject::getId, subIds).eq(CourseSubject::getSubjectName, majorName).last("limit 1"));
|
|
|
|
|
+ Long subId = courseSubject.getId();
|
|
|
|
|
+
|
|
|
|
|
+ //添加试卷
|
|
|
|
|
+ Long examId = 0L;
|
|
|
|
|
+ QuestionWaiBuBo bo1 = new QuestionWaiBuBo();
|
|
|
|
|
+ bo1.setEduId(eduId);
|
|
|
|
|
+ bo1.setProId(proId);
|
|
|
|
|
+ bo1.setBusinessId(businessId);
|
|
|
|
|
+ bo1.setSubId(subId);
|
|
|
|
|
+ bo1.setContent(exam);
|
|
|
|
|
+ Exam examEntity = baseMapper.getExamByWaiBu(bo1);
|
|
|
|
|
+ if (ObjectUtils.isNull(examEntity)){
|
|
|
|
|
+ //新增
|
|
|
|
|
+ Exam exam2 = new Exam();
|
|
|
|
|
+ exam2.setExamName(exam);
|
|
|
|
|
+ exam2.setCode(ServletUtils.getEncoded("SJ"));
|
|
|
|
|
+ exam2.setCreateTime(DateUtils.getNowTime());
|
|
|
|
|
+ exam2.setUpdateTime(DateUtils.getNowTime());
|
|
|
|
|
+ exam2.setPrefixName(String.format("外部系统拉取试卷(%s)",DateUtils.getDate()));
|
|
|
|
|
+ exam2.setPublishStatus(1L);
|
|
|
|
|
+ exam2.setYear(2026L);
|
|
|
|
|
+ exam2.setStatus(1);
|
|
|
|
|
+ exam2.setDoType(1);
|
|
|
|
|
+ //试卷类型ID
|
|
|
|
|
+ ExamPaper paper = iExamPaperService.getOne(new LambdaUpdateWrapper<ExamPaper>().eq(ExamPaper::getStatus, 1).eq(ExamPaper::getPaperName, "普通练习").last("limit 1"));
|
|
|
|
|
+ exam2.setExamPaperId(paper.getPaperId());
|
|
|
|
|
+ iExamService.save(exam2);
|
|
|
|
|
+ //业务乘次
|
|
|
|
|
+ QuestionBusiness questionBusiness = new QuestionBusiness();
|
|
|
|
|
+ questionBusiness.setEducationTypeId(eduId);
|
|
|
|
|
+ questionBusiness.setProjectId(proId);
|
|
|
|
|
+ questionBusiness.setBusinessId(businessId);
|
|
|
|
|
+ questionBusiness.setSubjectId(subId);
|
|
|
|
|
+ questionBusiness.setType(2);
|
|
|
|
|
+ questionBusiness.setMajorId(exam2.getExamId());
|
|
|
|
|
+ iQuestionBusinessService.save(questionBusiness);
|
|
|
|
|
+ examId = exam2.getExamId();
|
|
|
|
|
+ }else {
|
|
|
|
|
+ examId = examEntity.getExamId();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //题库ID
|
|
|
|
|
+ Long questionId = 0L;
|
|
|
|
|
+ //处理题库
|
|
|
|
|
+ Integer start = 0;
|
|
|
|
|
+ Integer end = 0;
|
|
|
|
|
+ for (int i = 0; i < questions.size(); i++) {
|
|
|
|
|
+ String s = questions.get(i);
|
|
|
|
|
+ if (s.contains("/100题")){
|
|
|
|
|
+ start = i;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (s.contains("考生答案")){
|
|
|
|
|
+ end = i;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ List<String> content = questions.subList(start + 1, end);
|
|
|
|
|
+ //获取第一个判断题型
|
|
|
|
|
+ String bt = content.get(0);
|
|
|
|
|
+ if (bt.contains("理解题")){
|
|
|
|
|
+ if (StringUtils.isBlank(exam)){
|
|
|
|
|
+ throw new CustomException("案例题需要补充试卷名称");
|
|
|
|
|
+ }
|
|
|
|
|
+ //就是案例题,分解获取案例题文本
|
|
|
|
|
+ Integer start1 = 0;
|
|
|
|
|
+ Integer end1 = 0;
|
|
|
|
|
+ for (int i = 0; i < content.size(); i++) {
|
|
|
|
|
+ String s = content.get(i);
|
|
|
|
|
+ List<String> list1 = Arrays.asList("多选题", "单选题", "判断题");
|
|
|
|
|
+ if (list1.stream().anyMatch(x -> s.contains(x))){
|
|
|
|
|
+ end1 = i;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ //案例题文案
|
|
|
|
|
+ List<String> anLi = content.subList(start1, end1);
|
|
|
|
|
+ //提取文本
|
|
|
|
|
+ String anLiStr = "";
|
|
|
|
|
+ for (String text : anLi) {
|
|
|
|
|
+ // 排除条件(这些不是问题描述)
|
|
|
|
|
+ if (text.matches("^[0-9]{1,3}\\..*题$") || // 题号类型
|
|
|
|
|
+ text.matches(".*[0-9]分$") || // 简单分数
|
|
|
|
|
+ text.matches("^[A-E][|、::]?.*") || // 选项
|
|
|
|
|
+ text.length() < 10) { // 太短的文本
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ anLiStr = text;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (StringUtils.isBlank(anLiStr)) {
|
|
|
|
|
+ throw new CustomException("案例题文案获取失败");
|
|
|
|
|
+ }
|
|
|
|
|
+ //案例题序号
|
|
|
|
|
+ String anLiXu = bt.replaceAll("^([0-9]+)、.*", "$1");
|
|
|
|
|
+ //检查是否已经存在
|
|
|
|
|
+ QuestionWaiBuBo bo = new QuestionWaiBuBo();
|
|
|
|
|
+ bo.setEduId(eduId);
|
|
|
|
|
+ bo.setProId(proId);
|
|
|
|
|
+ bo.setBusinessId(businessId);
|
|
|
|
|
+ bo.setSubId(subId);
|
|
|
|
|
+ String keyWord = String.format("[%s]案例题序号:%s",exam,anLiXu);
|
|
|
|
|
+ bo.setContent(keyWord);
|
|
|
|
|
+ Question entity = baseMapper.getQuestionByWaiBu(bo);
|
|
|
|
|
+ if (ObjectUtils.isNotNull(entity)){
|
|
|
|
|
+ //修改
|
|
|
|
|
+ entity.setContent(anLiStr);
|
|
|
|
|
+ updateById(entity);
|
|
|
|
|
+ }else {
|
|
|
|
|
+ //新增
|
|
|
|
|
+ Question question = new Question();
|
|
|
|
|
+ question.setContent(anLiStr);
|
|
|
|
|
+ question.setType(4);
|
|
|
|
|
+ question.setStatus(1);
|
|
|
|
|
+ question.setCreateTime(DateUtils.getNowTime());
|
|
|
|
|
+ question.setUpdateTime(DateUtils.getNowTime());
|
|
|
|
|
+ question.setCode(ServletUtils.getEncoded("TM"));
|
|
|
|
|
+ question.setPrefixName(String.format("外部系统拉取(%s)[%s]案例题序号:%s",DateUtils.getDate(),exam,anLiXu));
|
|
|
|
|
+ question.setPublishStatus(1);
|
|
|
|
|
+ question.setFromPlat(1);
|
|
|
|
|
+ save(question);
|
|
|
|
|
+ QuestionBusiness questionBusiness = new QuestionBusiness();
|
|
|
|
|
+ questionBusiness.setEducationTypeId(eduId);
|
|
|
|
|
+ questionBusiness.setProjectId(proId);
|
|
|
|
|
+ questionBusiness.setBusinessId(businessId);
|
|
|
|
|
+ questionBusiness.setSubjectId(subId);
|
|
|
|
|
+ questionBusiness.setType(1);
|
|
|
|
|
+ questionBusiness.setMajorId(question.getQuestionId());
|
|
|
|
|
+ iQuestionBusinessService.save(questionBusiness);
|
|
|
|
|
+ saveExamQuestion(question.getQuestionId(),examId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //案例题小题
|
|
|
|
|
+ content = content.subList(end1,content.size());
|
|
|
|
|
+ bt = content.get(0);
|
|
|
|
|
+ }
|
|
|
|
|
+ // 匹配带小数的数字
|
|
|
|
|
+ Pattern pattern = Pattern.compile("\\d+(\\.\\d+)");
|
|
|
|
|
+ Matcher matcher = pattern.matcher(bt);
|
|
|
|
|
+ if (matcher.find()){
|
|
|
|
|
+ if (StringUtils.isBlank(exam)){
|
|
|
|
|
+ throw new CustomException("案例题需要补充试卷名称");
|
|
|
|
|
+ }
|
|
|
|
|
+ //带有小数点是案例题
|
|
|
|
|
+ String group = matcher.group(0);
|
|
|
|
|
+ List<String> list1 = Arrays.asList(group.split("\\."));
|
|
|
|
|
+ //案例序号
|
|
|
|
|
+ String xuh = list1.get(0);
|
|
|
|
|
+ //案例小题序号
|
|
|
|
|
+ String xuxh = list1.get(1);
|
|
|
|
|
+ String content2 = String.format("[%s]案例题序号:%s",exam, xuh);
|
|
|
|
|
+
|
|
|
|
|
+ //解析题库
|
|
|
|
|
+ List<QuestionInfoVo> infoVoList = new ArrayList<>();
|
|
|
|
|
+ if (bt.contains("单选题")){
|
|
|
|
|
+ List<String> questionList = filterContent(content);
|
|
|
|
|
+ //第一个是标题
|
|
|
|
|
+ String s = questionList.get(0);
|
|
|
|
|
+ QuestionInfoVo infoVo = new QuestionInfoVo();
|
|
|
|
|
+ infoVo.setContent(s);
|
|
|
|
|
+ infoVo.setType(1);
|
|
|
|
|
+ infoVo.setWaiBuSort(Integer.valueOf(xuxh));
|
|
|
|
|
+ List<QuestionDetailVo> detailVoList = new ArrayList<>();
|
|
|
|
|
+ for (int i = 1; i < questionList.size(); i++) {
|
|
|
|
|
+ String s1 = questionList.get(i);
|
|
|
|
|
+ QuestionDetailVo detailVo = new QuestionDetailVo();
|
|
|
|
|
+ detailVo.setContent(s1);
|
|
|
|
|
+ detailVo.setOptionsId(i);
|
|
|
|
|
+ detailVoList.add(detailVo);
|
|
|
|
|
+ }
|
|
|
|
|
+ infoVo.setOptionsList(detailVoList);
|
|
|
|
|
+ //分解答案
|
|
|
|
|
+ String answer = getAnswer(questions);
|
|
|
|
|
+ infoVo.setAnswerQuestion(simpleConvert(answer));
|
|
|
|
|
+ infoVoList.add(infoVo);
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (bt.contains("多选题")){
|
|
|
|
|
+ List<String> questionList = filterContent(content);
|
|
|
|
|
+ //第一个是标题
|
|
|
|
|
+ String s = questionList.get(0);
|
|
|
|
|
+ QuestionInfoVo infoVo = new QuestionInfoVo();
|
|
|
|
|
+ infoVo.setContent(s);
|
|
|
|
|
+ infoVo.setType(2);
|
|
|
|
|
+ infoVo.setWaiBuSort(Integer.valueOf(xuxh));
|
|
|
|
|
+ List<QuestionDetailVo> detailVoList = new ArrayList<>();
|
|
|
|
|
+ for (int i = 1; i < questionList.size(); i++) {
|
|
|
|
|
+ String s1 = questionList.get(i);
|
|
|
|
|
+ QuestionDetailVo detailVo = new QuestionDetailVo();
|
|
|
|
|
+ detailVo.setContent(s1);
|
|
|
|
|
+ detailVo.setOptionsId(i);
|
|
|
|
|
+ detailVoList.add(detailVo);
|
|
|
|
|
+ }
|
|
|
|
|
+ infoVo.setOptionsList(detailVoList);
|
|
|
|
|
+ //分解答案
|
|
|
|
|
+ String answer = getAnswer(questions);
|
|
|
|
|
+ infoVo.setAnswerQuestion(simpleConvert(answer));
|
|
|
|
|
+ infoVoList.add(infoVo);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (bt.contains("判断题")){
|
|
|
|
|
+ List<String> questionList = filterContent(content);
|
|
|
|
|
+ //第一个是标题
|
|
|
|
|
+ String s = questionList.get(0);
|
|
|
|
|
+ QuestionInfoVo infoVo = new QuestionInfoVo();
|
|
|
|
|
+ infoVo.setContent(s);
|
|
|
|
|
+ infoVo.setType(3);
|
|
|
|
|
+ infoVo.setWaiBuSort(Integer.valueOf(xuxh));
|
|
|
|
|
+ //分解答案
|
|
|
|
|
+ String answer = getAnswer(questions);
|
|
|
|
|
+ infoVo.setAnswerQuestion(answer.contains("错") ? "0":"1");
|
|
|
|
|
+ infoVoList.add(infoVo);
|
|
|
|
|
+ }
|
|
|
|
|
+ //判断是否已经在
|
|
|
|
|
+ QuestionWaiBuBo bo = new QuestionWaiBuBo();
|
|
|
|
|
+ bo.setEduId(eduId);
|
|
|
|
|
+ bo.setProId(proId);
|
|
|
|
|
+ bo.setBusinessId(businessId);
|
|
|
|
|
+ bo.setSubId(subId);
|
|
|
|
|
+ bo.setContent(content2);
|
|
|
|
|
+ Question entity = baseMapper.getQuestionByWaiBu(bo);
|
|
|
|
|
+ if (ObjectUtils.isNotNull(entity)){
|
|
|
|
|
+ //已存在,添加案例小题
|
|
|
|
|
+ String jsonStr = entity.getJsonStr();
|
|
|
|
|
+ if (StringUtils.isNotBlank(jsonStr)){
|
|
|
|
|
+ List<QuestionInfoVo> infoVoList1 = JSONArray.parseArray(jsonStr, QuestionInfoVo.class);
|
|
|
|
|
+ infoVoList1.addAll(infoVoList);
|
|
|
|
|
+ List<QuestionInfoVo> collect = infoVoList1.stream().sorted(Comparator.comparingInt(QuestionInfoVo::getWaiBuSort)).collect(Collectors.toList());
|
|
|
|
|
+ entity.setJsonStr(JSONArray.toJSONString(collect));
|
|
|
|
|
+ }else {
|
|
|
|
|
+ entity.setJsonStr(JSONArray.toJSONString(infoVoList));
|
|
|
|
|
+ }
|
|
|
|
|
+ updateById(entity);
|
|
|
|
|
+ questionId = entity.getQuestionId();
|
|
|
|
|
+ }else {
|
|
|
|
|
+ //新增
|
|
|
|
|
+ Question question = new Question();
|
|
|
|
|
+ question.setContent(content2);
|
|
|
|
|
+ question.setType(4);
|
|
|
|
|
+ question.setStatus(1);
|
|
|
|
|
+ question.setCreateTime(DateUtils.getNowTime());
|
|
|
|
|
+ question.setUpdateTime(DateUtils.getNowTime());
|
|
|
|
|
+ question.setCode(ServletUtils.getEncoded("TM"));
|
|
|
|
|
+ question.setPrefixName(String.format("外部系统拉取(%s)[%s]案例题序号:%s",DateUtils.getDate(),exam,xuh));
|
|
|
|
|
+ question.setPublishStatus(1);
|
|
|
|
|
+ question.setFromPlat(1);
|
|
|
|
|
+ question.setJsonStr(JSONArray.toJSONString(infoVoList));
|
|
|
|
|
+ save(question);
|
|
|
|
|
+ questionId = question.getQuestionId();
|
|
|
|
|
+ saveExamQuestion(questionId,examId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }else {
|
|
|
|
|
+ //判断题,多选题,单选题
|
|
|
|
|
+ if (bt.contains("单选题")){
|
|
|
|
|
+ List<String> questionList = filterContent(content);
|
|
|
|
|
+ //第一个是标题
|
|
|
|
|
+ String s = questionList.get(0);
|
|
|
|
|
+ Question question = new Question();
|
|
|
|
|
+ question.setContent(s);
|
|
|
|
|
+ question.setType(1);
|
|
|
|
|
+ question.setStatus(1);
|
|
|
|
|
+ question.setCreateTime(DateUtils.getNowTime());
|
|
|
|
|
+ question.setUpdateTime(DateUtils.getNowTime());
|
|
|
|
|
+ question.setCode(ServletUtils.getEncoded("TM"));
|
|
|
|
|
+ question.setPrefixName(String.format("外部系统拉取(%s)",DateUtils.getDate()));
|
|
|
|
|
+ question.setPublishStatus(1);
|
|
|
|
|
+ question.setFromPlat(1);
|
|
|
|
|
+ List<QuestionOptionVo> optionVos = new ArrayList<>();
|
|
|
|
|
+ for (int i = 1; i < questionList.size(); i++) {
|
|
|
|
|
+ String s1 = questionList.get(i);
|
|
|
|
|
+ QuestionOptionVo questionOptionVo = new QuestionOptionVo();
|
|
|
|
|
+ questionOptionVo.setContent(s1);
|
|
|
|
|
+ questionOptionVo.setOptionsId(i);
|
|
|
|
|
+ optionVos.add(questionOptionVo);
|
|
|
|
|
+ }
|
|
|
|
|
+ question.setJsonStr(JSONArray.toJSONString(optionVos));
|
|
|
|
|
+ //分解答案
|
|
|
|
|
+ String answer = getAnswer(questions);
|
|
|
|
|
+ question.setAnswerQuestion(simpleConvert(answer));
|
|
|
|
|
+ save(question);
|
|
|
|
|
+ questionId = question.getQuestionId();
|
|
|
|
|
+ saveExamQuestion(questionId,examId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (bt.contains("多选题")){
|
|
|
|
|
+ List<String> questionList = filterContent(content);
|
|
|
|
|
+ //第一个是标题
|
|
|
|
|
+ String s = questionList.get(0);
|
|
|
|
|
+ Question question = new Question();
|
|
|
|
|
+ question.setContent(s);
|
|
|
|
|
+ question.setType(2);
|
|
|
|
|
+ question.setStatus(1);
|
|
|
|
|
+ question.setCreateTime(DateUtils.getNowTime());
|
|
|
|
|
+ question.setUpdateTime(DateUtils.getNowTime());
|
|
|
|
|
+ question.setCode(ServletUtils.getEncoded("TM"));
|
|
|
|
|
+ question.setPrefixName(String.format("外部系统拉取(%s)",DateUtils.getDate()));
|
|
|
|
|
+ question.setPublishStatus(1);
|
|
|
|
|
+ question.setFromPlat(1);
|
|
|
|
|
+ List<QuestionOptionVo> optionVos = new ArrayList<>();
|
|
|
|
|
+ for (int i = 1; i < questionList.size(); i++) {
|
|
|
|
|
+ String s1 = questionList.get(i);
|
|
|
|
|
+ QuestionOptionVo questionOptionVo = new QuestionOptionVo();
|
|
|
|
|
+ questionOptionVo.setContent(s1);
|
|
|
|
|
+ questionOptionVo.setOptionsId(i);
|
|
|
|
|
+ optionVos.add(questionOptionVo);
|
|
|
|
|
+ }
|
|
|
|
|
+ question.setJsonStr(JSONArray.toJSONString(optionVos));
|
|
|
|
|
+ //分解答案
|
|
|
|
|
+ String answer = getAnswer(questions);
|
|
|
|
|
+ question.setAnswerQuestion(simpleConvert(answer));
|
|
|
|
|
+ save(question);
|
|
|
|
|
+ questionId = question.getQuestionId();
|
|
|
|
|
+ saveExamQuestion(questionId,examId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (bt.contains("判断题")){
|
|
|
|
|
+ List<String> questionList = filterContent(content);
|
|
|
|
|
+ //第一个是标题
|
|
|
|
|
+ String s = questionList.get(0);
|
|
|
|
|
+ Question question = new Question();
|
|
|
|
|
+ question.setContent(s);
|
|
|
|
|
+ question.setType(3);
|
|
|
|
|
+ question.setStatus(1);
|
|
|
|
|
+ question.setCreateTime(DateUtils.getNowTime());
|
|
|
|
|
+ question.setUpdateTime(DateUtils.getNowTime());
|
|
|
|
|
+ question.setCode(ServletUtils.getEncoded("TM"));
|
|
|
|
|
+ question.setPrefixName(String.format("外部系统拉取(%s)",DateUtils.getDate()));
|
|
|
|
|
+ question.setPublishStatus(1);
|
|
|
|
|
+ question.setFromPlat(1);
|
|
|
|
|
+ //分解答案
|
|
|
|
|
+ String answer = getAnswer(questions);
|
|
|
|
|
+ question.setAnswerQuestion(answer.contains("错") ? "0":"1");
|
|
|
|
|
+ save(question);
|
|
|
|
|
+ questionId = question.getQuestionId();
|
|
|
|
|
+ saveExamQuestion(questionId,examId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ if (questionId <= 0){
|
|
|
|
|
+ throw new CustomException("题库解析失败");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ QuestionBusiness questionBusiness = new QuestionBusiness();
|
|
|
|
|
+ questionBusiness.setEducationTypeId(eduId);
|
|
|
|
|
+ questionBusiness.setProjectId(proId);
|
|
|
|
|
+ questionBusiness.setBusinessId(businessId);
|
|
|
|
|
+ questionBusiness.setSubjectId(subId);
|
|
|
|
|
+ questionBusiness.setType(1);
|
|
|
|
|
+ questionBusiness.setMajorId(questionId);
|
|
|
|
|
+ iQuestionBusinessService.save(questionBusiness);
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void saveExamQuestion(Long questionId,Long examId){
|
|
|
|
|
+ ExamQuestion examQuestion = new ExamQuestion();
|
|
|
|
|
+ examQuestion.setExamId(examId);
|
|
|
|
|
+ examQuestion.setQuestionId(questionId);
|
|
|
|
|
+ //获取最新排序
|
|
|
|
|
+ Integer sort = 0;
|
|
|
|
|
+ ExamQuestion one = iExamQuestionService.getOne(new LambdaUpdateWrapper<ExamQuestion>().eq(ExamQuestion::getExamId, examId).orderByDesc(ExamQuestion::getSort));
|
|
|
|
|
+ if (ObjectUtils.isNotNull(one)){
|
|
|
|
|
+ sort = one.getSort() +1;
|
|
|
|
|
+ }
|
|
|
|
|
+ examQuestion.setSort(sort);
|
|
|
|
|
+ iExamQuestionService.save(examQuestion);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static String simpleConvert(String letters) {
|
|
|
|
|
+ String result = letters.toUpperCase()
|
|
|
|
|
+ .replaceAll("[^A-E]", "") // 只保留A-E
|
|
|
|
|
+ .replace("A", "1")
|
|
|
|
|
+ .replace("B", "2")
|
|
|
|
|
+ .replace("C", "3")
|
|
|
|
|
+ .replace("D", "4")
|
|
|
|
|
+ .replace("E", "5");
|
|
|
|
|
+
|
|
|
|
|
+ // 添加逗号分隔
|
|
|
|
|
+ return String.join(",", result.split(""));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private String getAnswer(List<String> question){
|
|
|
|
|
+ //找正确答案
|
|
|
|
|
+ Integer index =0;
|
|
|
|
|
+ for (int i = 0; i < question.size(); i++) {
|
|
|
|
|
+ String s = question.get(i);
|
|
|
|
|
+ if (s.equals("正确答案")){
|
|
|
|
|
+ index = i;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return question.get(index+3);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private List<String> filterContent(List<String> lines) {
|
|
|
|
|
+ List<String> result = new ArrayList<>();
|
|
|
|
|
+
|
|
|
|
|
+ for (String line : lines) {
|
|
|
|
|
+ String trimmed = line.trim();
|
|
|
|
|
+
|
|
|
|
|
+ // 跳过:题目编号、分值、单独选项字母
|
|
|
|
|
+ if (trimmed.matches("\\d+、.*") ||
|
|
|
|
|
+ trimmed.matches("\\d+分") ||
|
|
|
|
|
+ trimmed.matches("[A-E]$")) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 处理选项内容行(如 "D 高处作业...")
|
|
|
|
|
+ if (trimmed.matches("[A-E]\\s+.*")) {
|
|
|
|
|
+ // 去除开头的选项字母
|
|
|
|
|
+ trimmed = trimmed.substring(1).trim();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 如果以 "|" 开头,去除它
|
|
|
|
|
+ if (trimmed.startsWith("|")) {
|
|
|
|
|
+ trimmed = trimmed.substring(1).trim();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //去除首字母或者| 这种符号
|
|
|
|
|
+ trimmed = trimmed.replaceAll("^[A-E][\\||]?", "");
|
|
|
|
|
+ // 去除结尾的括号
|
|
|
|
|
+// trimmed = trimmed.replaceAll("[()()]+$", "");
|
|
|
|
|
+
|
|
|
|
|
+ if (!trimmed.isEmpty()) {
|
|
|
|
|
+ result.add(trimmed);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 提取纯文本信息,过滤掉所有链接、HTML标签和Markdown符号
|
|
|
|
|
+ */
|
|
|
|
|
+ public static List<String> extractPureText(String input) {
|
|
|
|
|
+ List<String> result = new ArrayList<>();
|
|
|
|
|
+
|
|
|
|
|
+ // 按行分割
|
|
|
|
|
+ String[] lines = input.split("\\n");
|
|
|
|
|
+
|
|
|
|
|
+ for (String line : lines) {
|
|
|
|
|
+ // 移除HTML注释 <!-- ... -->
|
|
|
|
|
+ line = line.replaceAll("<!--.*?-->", "");
|
|
|
|
|
+
|
|
|
|
|
+ // 移除Markdown图片链接 
|
|
|
|
|
+ line = line.replaceAll("!\\[.*?\\]\\(.*?\\)", "");
|
|
|
|
|
+
|
|
|
|
|
+ // 移除普通链接
|
|
|
|
|
+ line = line.replaceAll("https?://\\S+", "");
|
|
|
|
|
+
|
|
|
|
|
+ // 移除HTML标签
|
|
|
|
|
+ line = line.replaceAll("<[^>]+>", "");
|
|
|
|
|
+
|
|
|
|
|
+ // 移除Markdown格式标记 ** **
|
|
|
|
|
+ line = line.replaceAll("\\*\\*", "");
|
|
|
|
|
+
|
|
|
|
|
+ // 移除其他常见Markdown标记
|
|
|
|
|
+ line = line.replaceAll("#{1,6}\\s*", "") // 标题
|
|
|
|
|
+ .replaceAll("`{1,3}", "") // 代码标记
|
|
|
|
|
+ .replaceAll("\\[.*?\\]\\(.*?\\)", "") // 普通链接
|
|
|
|
|
+ .replaceAll("\\*|_", ""); // 斜体和粗体标记
|
|
|
|
|
+
|
|
|
|
|
+ // 修剪空白字符
|
|
|
|
|
+ line = line.trim();
|
|
|
|
|
+
|
|
|
|
|
+ // 只添加非空行
|
|
|
|
|
+ if (!line.isEmpty()) {
|
|
|
|
|
+ result.add(line);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
|
|
|
private void handlePhoto(List<ExternalQuestionDetailVo> questionDetailVos) {
|
|
private void handlePhoto(List<ExternalQuestionDetailVo> questionDetailVos) {
|
|
|
String prefix = "\\Uploads\\qdytopic\\";
|
|
String prefix = "\\Uploads\\qdytopic\\";
|