Kaynağa Gözat

mutidatasource

xiatian 3 ay önce
ebeveyn
işleme
68d0467ea8

+ 16 - 1
pom.xml

@@ -36,10 +36,25 @@
             <artifactId>core-ai</artifactId>
             <version>${qmth-boot-version}</version>
         </dependency>
-        <dependency>
+<!--        <dependency>
             <groupId>com.qmth.boot</groupId>
             <artifactId>data-mybatis-plus</artifactId>
             <version>${qmth-boot-version}</version>
+        </dependency>-->
+       
+<dependency>
+    <groupId>mysql</groupId>
+    <artifactId>mysql-connector-java</artifactId>
+</dependency>
+      <dependency>
+        <groupId>com.baomidou</groupId>
+        <artifactId>mybatis-plus-boot-starter</artifactId>
+        <version>3.4.2</version>
+      </dependency>
+     <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
+            <version>3.4.1</version>
         </dependency>
         <dependency>
             <groupId>com.qmth.boot</groupId>

+ 1 - 0
src/main/java/cn/com/qmth/am/AmApplication.java

@@ -14,6 +14,7 @@ import com.github.jeffreyning.mybatisplus.conf.EnableMPP;
 @Configuration
 @MapperScan("cn.com.qmth.am.dao")
 public class AmApplication {
+
     public static void main(String[] args) {
         SpringApplication.run(AmApplication.class, args);
     }

+ 10 - 0
src/main/java/cn/com/qmth/am/bean/ds/ChatReq.java

@@ -2,6 +2,8 @@ package cn.com.qmth.am.bean.ds;
 
 public class ChatReq {
 
+    private Boolean stream = false;
+
     private String model;
 
     public ChatReq(String modelType) {
@@ -17,4 +19,12 @@ public class ChatReq {
         this.model = model;
     }
 
+    public Boolean getStream() {
+        return stream;
+    }
+
+    public void setStream(Boolean stream) {
+        this.stream = stream;
+    }
+
 }

+ 40 - 0
src/main/java/cn/com/qmth/am/config/DataSourceConfigLocal.java

@@ -0,0 +1,40 @@
+package cn.com.qmth.am.config;
+
+import javax.sql.DataSource;
+
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+// @Configuration
+// @MapperScan(basePackages = "cn.com.qmth.am.dao.local", sqlSessionFactoryRef =
+// "sqlSessionFactoryLocal")
+public class DataSourceConfigLocal {
+
+    // @Bean(name = "dataSourceLocal")
+    // @ConfigurationProperties(prefix = "spring.data-source-local")
+    // public DataSource dataSource() {
+    // return DataSourceBuilder.create().build();
+    // }
+    //
+    // @Bean(name = "sqlSessionFactoryLocal")
+    // public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSourceLocal")
+    // DataSource dataSource) throws Exception {
+    // SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
+    // factoryBean.setDataSource(dataSource);
+    // return factoryBean.getObject();
+    // }
+    //
+    // @Bean("db1SqlSessionTemplate")
+    // public SqlSessionTemplate db1SqlSessionTemplate(
+    // @Qualifier("sqlSessionFactoryLocal") SqlSessionFactory sqlSessionFactory)
+    // {
+    // return new SqlSessionTemplate(sqlSessionFactory);
+    // }
+}

+ 40 - 0
src/main/java/cn/com/qmth/am/config/DataSourceConfigStmms.java

@@ -0,0 +1,40 @@
+package cn.com.qmth.am.config;
+
+import javax.sql.DataSource;
+
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+// @Configuration
+// @MapperScan(basePackages = "cn.com.qmth.am.dao.stmms", sqlSessionFactoryRef =
+// "sqlSessionFactoryStmms")
+public class DataSourceConfigStmms {
+
+    // @Bean(name = "dataSourceStmms")
+    // @ConfigurationProperties(prefix = "spring.data-source-stmms")
+    // public DataSource dataSource() {
+    // return DataSourceBuilder.create().build();
+    // }
+    //
+    // @Bean(name = "sqlSessionFactoryStmms")
+    // public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSourceStmms")
+    // DataSource dataSource) throws Exception {
+    // SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
+    // factoryBean.setDataSource(dataSource);
+    // return factoryBean.getObject();
+    // }
+    //
+    // @Bean("db2SqlSessionTemplate")
+    // public SqlSessionTemplate db1SqlSessionTemplate(
+    // @Qualifier("sqlSessionFactoryStmms") SqlSessionFactory sqlSessionFactory)
+    // {
+    // return new SqlSessionTemplate(sqlSessionFactory);
+    // }
+}

+ 16 - 3
src/main/java/cn/com/qmth/am/controller/AdminController.java

@@ -5,7 +5,13 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintWriter;
 import java.math.BigDecimal;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import javax.servlet.http.HttpServletResponse;
 
@@ -25,6 +31,7 @@ import com.qmth.boot.core.concurrent.service.ConcurrentService;
 
 import cn.com.qmth.am.bean.DataKey;
 import cn.com.qmth.am.config.SysProperty;
+import cn.com.qmth.am.dao.stmms.StmmsDao;
 import cn.com.qmth.am.entity.QuestionEntity;
 import cn.com.qmth.am.entity.StudentScoreEntity;
 import cn.com.qmth.am.enums.DataStatus;
@@ -56,6 +63,9 @@ public class AdminController {
     @Autowired
     private ConcurrentService concurrentService;
 
+    @Autowired
+    private StmmsDao stmmsDao;
+
     @ApiOperation(value = "分析数据")
     @RequestMapping(value = "fenxi", method = RequestMethod.GET)
     public void fenxi(HttpServletResponse response, @RequestParam Long examId,
@@ -143,9 +153,9 @@ public class AdminController {
             if (k.getIndex() < roundedValue) {
                 st = st + c;
             }
-            sb.append("        " + k.getKey() + "  " + c + "  " + Calculator.percentage(c, total, 2) + " \r\n");
+            sb.append("            " + k.getKey() + "  " + c + "  " + Calculator.percentage(c, total, 2) + " \r\n");
         }
-        sb.append("        " + roundedValue + "分差值:" + st + "  " + Calculator.percentage(st, total, 2) + " \r\n");
+        sb.append("       " + roundedValue + "分差值:" + st + "  " + Calculator.percentage(st, total, 2) + " \r\n");
     }
 
     private void fillMarkingCount(List<StudentScoreEntity> scores, StringBuilder sb) {
@@ -214,6 +224,8 @@ public class AdminController {
             Integer c = ret.get(k);
             sb.append("            " + k.getKey() + "  " + c + "  " + Calculator.percentage(c, total, 2) + " \r\n");
         }
+        sb.append(
+                "---------------------------------------------------------------------------------------------------------------------------------\r\n");
     }
 
     private static DataKey getKey(double s) {
@@ -253,6 +265,7 @@ public class AdminController {
             }
             qsCourse = cset.size();
         }
+        sb.append("stmms:" + stmmsDao.getName() + "\r\n");
         sb.append("ocr任务是否开启:" + (sysProperty.getOcrTaskEnable() ? "是" : "否") + "\r\n");
         sb.append("评分任务是否开启:" + (sysProperty.getMarkingTaskEnable() ? "是" : "否") + "\r\n");
         sb.append("试卷科目总数:" + qsCourse + "\r\n");

+ 1 - 1
src/main/java/cn/com/qmth/am/dao/QuestionDao.java → src/main/java/cn/com/qmth/am/dao/local/QuestionDao.java

@@ -1,4 +1,4 @@
-package cn.com.qmth.am.dao;
+package cn.com.qmth.am.dao.local;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 

+ 1 - 1
src/main/java/cn/com/qmth/am/dao/StudentScoreDao.java → src/main/java/cn/com/qmth/am/dao/local/StudentScoreDao.java

@@ -1,4 +1,4 @@
-package cn.com.qmth.am.dao;
+package cn.com.qmth.am.dao.local;
 
 import java.util.List;
 

+ 9 - 0
src/main/java/cn/com/qmth/am/dao/stmms/StmmsDao.java

@@ -0,0 +1,9 @@
+package cn.com.qmth.am.dao.stmms;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+
+@DS("data-source-stmms")
+public interface StmmsDao {
+
+    String getName();
+}

+ 72 - 5
src/main/java/cn/com/qmth/am/service/impl/DsMarkingServiceImpl.java

@@ -1,11 +1,15 @@
 package cn.com.qmth.am.service.impl;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -19,6 +23,7 @@ import com.qmth.boot.core.retrofit.exception.RetrofitResponseError;
 
 import cn.com.qmth.am.bean.ds.ChatReq;
 import cn.com.qmth.am.bean.ds.ChatResult;
+import cn.com.qmth.am.bean.ds.DsChoice;
 import cn.com.qmth.am.bean.ds.MarkingReq;
 import cn.com.qmth.am.bean.ds.OcrMessage;
 import cn.com.qmth.am.bean.ds.OcrReq;
@@ -69,19 +74,63 @@ public class DsMarkingServiceImpl implements DsMarkingService {
         return text;
     }
 
+    // @Override
+    // public AutoScoreResult autoScore(AutoScoreRequest request) {
+    // String question = FreeMarkerUtil.getDsMarkingReq(request);
+    // MarkingReq dreq = new MarkingReq(sysProperty.getMarkingModel());
+    // dreq.addMsg(ChatRole.user, question);
+    // String res = marking(dreq);
+    // ChatResult result = JSONObject.parseObject(res, ChatResult.class);
+    // String text = result.getChoices().stream().filter(choice ->
+    // choice.getMessage().getRole() == ChatRole.assistant)
+    // .map(choice -> choice.getMessage().getContent()).findFirst().orElse("");
+    // try {
+    // AutoScoreResult scoreResult = new AutoScoreResult();
+    // String scoreStr = fomatStr(text);
+    // scoreResult.setTotalScore(Double.valueOf(scoreStr));
+    // return scoreResult;
+    // } catch (Exception e) {
+    // log.error(e.getMessage() + " | " + res);
+    // return null;
+    // }
+    // }
+
     @Override
     public AutoScoreResult autoScore(AutoScoreRequest request) {
         String question = FreeMarkerUtil.getDsMarkingReq(request);
         MarkingReq dreq = new MarkingReq(sysProperty.getMarkingModel());
         dreq.addMsg(ChatRole.user, question);
         String res = marking(dreq);
-        ChatResult result = JSONObject.parseObject(res, ChatResult.class);
-        String text = result.getChoices().stream().filter(choice -> choice.getMessage().getRole() == ChatRole.assistant)
-                .map(choice -> choice.getMessage().getContent()).findFirst().orElse("");
+        DsChoice result = JSONObject.parseObject(res, DsChoice.class);
         try {
+            String text = result.getMessage().getContent();
             AutoScoreResult scoreResult = new AutoScoreResult();
-            String scoreStr = fomatStr(text);
-            scoreResult.setTotalScore(Double.valueOf(scoreStr));
+            // 依据总分与步骤分计算最大精度
+            int scale = Math.max(getDecimalPlaces(request.getIntervalScore()),
+                    getDecimalPlaces(request.getTotalScore()));
+            int stepCount = request.getStandardAnswer().size();
+            String scoreStr = null;
+            if (stepCount > 1) {
+                scoreStr = fomatStrByRex(text);
+            } else {
+                scoreStr = fomatStr(text);
+            }
+            String[] scores = StringUtils.split(scoreStr, ",");
+            double[] scoreArray = new double[stepCount];
+            for (int i = 0; i < stepCount; i++) {
+                // 根据得分率与步骤总分计算实际得分,按最大精度保留小数位数
+                double score = BigDecimal
+                        .valueOf(Math.min(Integer.parseInt(scores[i].trim()), 100)
+                                * request.getStandardAnswer().get(i).getScore())
+                        .divide(BigDecimal.valueOf(100), scale, RoundingMode.HALF_UP).doubleValue();
+                scoreArray[i] = score;
+            }
+            scoreResult.setStepScore(scoreArray);
+            scoreResult.setTotalScore(Arrays.stream(scoreArray).mapToObj(BigDecimal::new)
+                    .reduce(BigDecimal.ZERO, BigDecimal::add).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue());
+            if ((scoreResult.getTotalScore() + "").length() > 4) {
+                log.error(" | " + res);
+            }
             return scoreResult;
         } catch (Exception e) {
             log.error(e.getMessage() + " | " + res);
@@ -89,6 +138,21 @@ public class DsMarkingServiceImpl implements DsMarkingService {
         }
     }
 
+    private String fomatStrByRex(String scoreStr) {
+        int tag = scoreStr.lastIndexOf("</think>");
+        if (tag != -1) {
+            scoreStr = scoreStr.substring(tag).trim();
+        }
+        String ret = scoreStr.replaceAll(",", ",").replaceAll("。", "").replaceAll("[0-9]\\.", "");
+        Pattern pattern = Pattern.compile("(\\d{1,3}\\s*,\\s*)+\\d{1,3}");
+        Matcher matcher = pattern.matcher(ret);
+        if (matcher.find()) {
+            return matcher.group();
+        } else {
+            throw new RuntimeException("返回格式错误");
+        }
+    }
+
     private String fomatStr(String scoreStr) {
         scoreStr = scoreStr.substring(scoreStr.lastIndexOf("\n") + 1).trim();
         String ret = scoreStr.replaceAll(",", ",").replaceAll("。", "").replaceAll(":", ":");
@@ -111,6 +175,9 @@ public class DsMarkingServiceImpl implements DsMarkingService {
     // throw new RuntimeException("返回格式错误");
     // }
     // }
+    private int getDecimalPlaces(double value) {
+        return Math.max(0, BigDecimal.valueOf(value).stripTrailingZeros().scale());
+    }
 
     public static void main(String[] args) {
         String scoreStr = "</think>。\\n\\n\\n70,70,60\\n\\n评分结果2个3,29,110 \\n\\n考生的回答完全覆盖了所有的关键内容,逻辑清晰,术语使用准确";

+ 1 - 1
src/main/java/cn/com/qmth/am/service/impl/QuestionServiceImpl.java

@@ -36,7 +36,7 @@ import com.qmth.boot.tools.excel.model.DataMap;
 import cn.com.qmth.am.bean.ImageSlice;
 import cn.com.qmth.am.bean.ImportResult;
 import cn.com.qmth.am.config.SysProperty;
-import cn.com.qmth.am.dao.QuestionDao;
+import cn.com.qmth.am.dao.local.QuestionDao;
 import cn.com.qmth.am.entity.QuestionEntity;
 import cn.com.qmth.am.enums.ImportFileName;
 import cn.com.qmth.am.service.QuestionService;

+ 1 - 1
src/main/java/cn/com/qmth/am/service/impl/StudentScoreServiceImpl.java

@@ -54,7 +54,7 @@ import cn.com.qmth.am.bean.StudentScoreDto;
 import cn.com.qmth.am.bean.StudentScoreImageDto;
 import cn.com.qmth.am.bean.StudentScoreInfo;
 import cn.com.qmth.am.config.SysProperty;
-import cn.com.qmth.am.dao.StudentScoreDao;
+import cn.com.qmth.am.dao.local.StudentScoreDao;
 import cn.com.qmth.am.entity.QuestionEntity;
 import cn.com.qmth.am.entity.StudentScoreEntity;
 import cn.com.qmth.am.enums.DataStatus;

+ 1 - 1
src/main/java/cn/com/qmth/am/utils/FreeMarkerUtil.java

@@ -25,7 +25,7 @@ public class FreeMarkerUtil {
         config.setClassForTemplateLoading(FreeMarkerUtil.class, "/templates/");
 
         try {
-            dsMarkingReq = config.getTemplate("ds_marking_translation.ftl", ENCODING);
+            dsMarkingReq = config.getTemplate("ds_marking.ftl", ENCODING);
         } catch (IOException e) {
             throw new RuntimeException(e);
         }

+ 22 - 13
src/main/resources/application.properties

@@ -11,14 +11,23 @@ com.qmth.mybatis.block-attack=false
 #
 # ********** db config **********
 #
-db.host=localhost
-db.port=3306
-db.database=ai_marking_en
-com.qmth.datasource.username=root
-com.qmth.datasource.password=123456
-com.qmth.datasource.url=jdbc:mysql://${db.host}:${db.port}/${db.database}?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2b8&rewriteBatchedStatements=true
-com.qmth.datasource.max-pool-size=200
-com.qmth.datasource.min-idle=10
+#db.host=localhost
+#db.port=3306
+#db.database=ai_marking_en
+#com.qmth.datasource.username=root
+#com.qmth.datasource.password=123456
+#com.qmth.datasource.url=jdbc:mysql://${db.host}:${db.port}/${db.database}?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2b8&rewriteBatchedStatements=true
+#com.qmth.datasource.max-pool-size=200
+#com.qmth.datasource.min-idle=10
+
+spring.datasource.dynamic.datasource.data-source-local.url=jdbc:mysql://localhost:3306/ai_marking_muti?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2b8&rewriteBatchedStatements=true
+spring.datasource.dynamic.datasource.data-source-local.username=root
+spring.datasource.dynamic.datasource.data-source-local.password=123456
+spring.datasource.dynamic.datasource.data-source-stmms.url=jdbc:mysql://localhost:3306/stmms_ft?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2b8&rewriteBatchedStatements=true
+spring.datasource.dynamic.datasource.data-source-stmms.username=root
+spring.datasource.dynamic.datasource.data-source-stmms.password=123456
+spring.datasource.dynamic.primary=data-source-local
+spring.datasource.dynamic.strict=false
 #
 # ********** sys config **********
 #
@@ -38,16 +47,16 @@ com.qmth.ocr.server=https://solar.qmth.com.cn
 com.qmth.solar.access-key=7bbdc11570bc474dbf50e0d4a5dff328
 com.qmth.solar.access-secret=IOodRvbp2LspJTHOScgB7Yx8MRloMpyl
 
-am.marking-thread-count=8
+am.marking-thread-count=1
 am.ocr-task.enable=false
-am.marking-task.enable=false
+am.marking-task.enable=true
 am.data-type=MARKING_CLOUD
 am.image-server=https://file.markingcloud.com
 am.data-dir=./data
 am.marking-ocr-model=!!solar
 am.marking-ocr-server=
 am.marking-ocr-key=
-am.marking-marking-model=deepseek-r1-distill-qwen-32b-awq
-am.marking-marking-server=http://39.174.90.3:31091/spiritx-api/v1/chat/completions
-am.marking-marking-key=sk-loBBngbg1ymvUo6f647bF35d69684f1280E5D544F1F59f20
+am.marking-marking-model=qwen2.5:32b-instruct
+am.marking-marking-server=http://192.168.10.214:11434/api/chat
+am.marking-marking-key=!
 ##################################setting##########################################

+ 1 - 1
src/main/resources/mapper/QuestionMapper.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="cn.com.qmth.am.dao.QuestionDao">
+<mapper namespace="cn.com.qmth.am.dao.local.QuestionDao">
 
 </mapper>

+ 7 - 0
src/main/resources/mapper/StmmsMapper.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.com.qmth.am.dao.stmms.StmmsDao">
+	<select id="getName" resultType="string">
+		select t.name from b_user t where t.id=1
+	</select>
+</mapper>

+ 1 - 1
src/main/resources/mapper/StudentScoreMapper.xml

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="cn.com.qmth.am.dao.StudentScoreDao">
+<mapper namespace="cn.com.qmth.am.dao.local.StudentScoreDao">
 	<select id="getAllList" resultType="cn.com.qmth.am.bean.StudentScoreInfo">
 		select t.question_id,t.student_code from am_student_score t
 	</select>