|
|
@@ -15,15 +15,14 @@ import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
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.PageInfo;
|
|
|
import com.zhongzheng.common.core.page.TableDataInfo;
|
|
|
import com.zhongzheng.common.core.redis.RedisCache;
|
|
|
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.modules.alioss.service.OssService;
|
|
|
import com.zhongzheng.modules.bank.bo.*;
|
|
|
@@ -77,6 +76,8 @@ import java.io.*;
|
|
|
import java.math.BigDecimal;
|
|
|
import java.net.HttpURLConnection;
|
|
|
import java.net.URL;
|
|
|
+import java.nio.file.Files;
|
|
|
+import java.nio.file.Paths;
|
|
|
import java.text.NumberFormat;
|
|
|
import java.util.*;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
@@ -4603,6 +4604,300 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> i
|
|
|
return Collections.emptyMap();
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public void getImageWordTwo(MultipartFile file, String major) {
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void questionReset(List<String> questions,String majorName){
|
|
|
+ //题库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);
|
|
|
+ // 匹配带小数的数字
|
|
|
+ Pattern pattern = Pattern.compile("\\d+(\\.\\d+)");
|
|
|
+ Matcher matcher = pattern.matcher(bt);
|
|
|
+ if (matcher.find()){
|
|
|
+ //带有小数点是案例题
|
|
|
+ String group = matcher.group(0);
|
|
|
+ List<String> list = Arrays.asList(group.split("\\."));
|
|
|
+ //案例序号
|
|
|
+ String xuh = list.get(0);
|
|
|
+ //案例小题序号
|
|
|
+ String xuxh = list.get(1);
|
|
|
+
|
|
|
+ }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();
|
|
|
+ }
|
|
|
+
|
|
|
+ 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();
|
|
|
+ }
|
|
|
+
|
|
|
+ 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();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ if (questionId <= 0){
|
|
|
+ throw new CustomException("题库解析失败");
|
|
|
+ }
|
|
|
+
|
|
|
+ //题库业务层次
|
|
|
+ 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();
|
|
|
+ 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);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ 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.contains("X") || s.contains("x")){
|
|
|
+ index = i;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return question.get(index+1);
|
|
|
+ }
|
|
|
+
|
|
|
+ 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("[()()]+$", "");
|
|
|
+
|
|
|
+ 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) {
|
|
|
String prefix = "\\Uploads\\qdytopic\\";
|