From 3555c25f02e5f4f13f3336eb9ee1fe770e609785 Mon Sep 17 00:00:00 2001 From: liu Date: Fri, 23 Feb 2024 13:16:38 +0800 Subject: [PATCH 01/13] =?UTF-8?q?=E6=8F=90=E4=BA=A4nacos=E9=83=A8=E7=BD=B2?= =?UTF-8?q?=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/nacos/Dockerfile | 16 ++++++++++++++++ docker/生产环境服务部署文档.md | 23 +++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 docker/nacos/Dockerfile diff --git a/docker/nacos/Dockerfile b/docker/nacos/Dockerfile new file mode 100644 index 00000000..93777d43 --- /dev/null +++ b/docker/nacos/Dockerfile @@ -0,0 +1,16 @@ +# 设置基础镜像 +FROM nacos/nacos-server:v1.4.5 + +# 设置环境变量 +ENV MODE standalone +ENV NACOS_AUTH_IDENTITY_KEY nacos +ENV NACOS_AUTH_IDENTITY_VALUE nacos + +# 设置工作目录 +WORKDIR /home/nacos + +# 对外暴露端口 +EXPOSE 8848 + +# 启动命令 +CMD ["sh", "-c", "/home/nacos/start.sh"] \ No newline at end of file diff --git a/docker/生产环境服务部署文档.md b/docker/生产环境服务部署文档.md index 391a1e6f..071a7285 100644 --- a/docker/生产环境服务部署文档.md +++ b/docker/生产环境服务部署文档.md @@ -23,6 +23,29 @@ docker network create virtual-patient-network ``` +## nacos服务部署 + +- 端口号:8848 +- 首次部署使用dockerfile的形式,后期更新直接docker restart就可以了 + +### 首次部署 + +~~~shell + # 进入virtual-patient-nacos文件夹,依次执行命令 + # 构建镜像 + docker build -t virtual-patient-nacos:1.0.0 . + # 验证镜像是否存在 + docker images | grep virtual-patient-nacos + # 运行容器 + docker run --name virtual-patient-nacos -p 8848:8848 -d virtual-patient-nacos:1.0.0 + # **启用网络环境服务,生产环境请使用** + docker run --name virtual-patient-nacos --restart=always -p 8848:8848 -v /data/nacos/:/home/nacos/data --network virtual-patient-network -d virtual-patient-nacos:1.0.0 + # 验证容器运行 + docker ps | grep virtual-patient-nacos + # 查看日志是否正常 + docker logs -f virtual-patient-nacos +~~~ + ## mysql数据库 - 启动mysql From e3727de97d1e829e6d09eaf45d6d69ed7d9bf8e5 Mon Sep 17 00:00:00 2001 From: liu Date: Fri, 23 Feb 2024 15:43:00 +0800 Subject: [PATCH 02/13] =?UTF-8?q?=E6=8F=90=E4=BA=A4nacos=E9=83=A8=E7=BD=B2?= =?UTF-8?q?=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/nacos/Dockerfile | 16 ---------------- docker/生产环境服务部署文档.md | 22 +++++++++++----------- 2 files changed, 11 insertions(+), 27 deletions(-) delete mode 100644 docker/nacos/Dockerfile diff --git a/docker/nacos/Dockerfile b/docker/nacos/Dockerfile deleted file mode 100644 index 93777d43..00000000 --- a/docker/nacos/Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -# 设置基础镜像 -FROM nacos/nacos-server:v1.4.5 - -# 设置环境变量 -ENV MODE standalone -ENV NACOS_AUTH_IDENTITY_KEY nacos -ENV NACOS_AUTH_IDENTITY_VALUE nacos - -# 设置工作目录 -WORKDIR /home/nacos - -# 对外暴露端口 -EXPOSE 8848 - -# 启动命令 -CMD ["sh", "-c", "/home/nacos/start.sh"] \ No newline at end of file diff --git a/docker/生产环境服务部署文档.md b/docker/生产环境服务部署文档.md index 071a7285..f3087684 100644 --- a/docker/生产环境服务部署文档.md +++ b/docker/生产环境服务部署文档.md @@ -31,19 +31,18 @@ docker network create virtual-patient-network ### 首次部署 ~~~shell - # 进入virtual-patient-nacos文件夹,依次执行命令 - # 构建镜像 - docker build -t virtual-patient-nacos:1.0.0 . - # 验证镜像是否存在 - docker images | grep virtual-patient-nacos + # 拉取镜像 + docker pull nacos/nacos-server:v1.4.5 # 运行容器 - docker run --name virtual-patient-nacos -p 8848:8848 -d virtual-patient-nacos:1.0.0 + docker run -d -p 8848:8848 -e MODE=standalone -e NACOS_AUTH_IDENTITY_KEY=nacos -e NACOS_AUTH_IDENTITY_VALUE=nacos -v /data/nacos/:/home/nacos/data --name nacos --restart=always nacos/nacos-server:v1.4.5 # **启用网络环境服务,生产环境请使用** - docker run --name virtual-patient-nacos --restart=always -p 8848:8848 -v /data/nacos/:/home/nacos/data --network virtual-patient-network -d virtual-patient-nacos:1.0.0 + # 生产环境端口号为18498 + # 很奇怪,这里配置密码不生效,用nacos进去之后再手动改 + docker run -d -p 18498:8848 -e MODE=standalone -e NACOS_AUTH_IDENTITY_KEY=nacos -e NACOS_AUTH_IDENTITY_VALUE='#Yaxin0504' -v /data/nacos/:/home/nacos/data --name nacos --network virtual-patient-network --restart=always nacos/nacos-server:v1.4.5 # 验证容器运行 - docker ps | grep virtual-patient-nacos + docker ps | grep nacos # 查看日志是否正常 - docker logs -f virtual-patient-nacos + docker logs -f nacos ~~~ ## mysql数据库 @@ -56,10 +55,11 @@ docker network create virtual-patient-network # 拉取镜像 docker pull mysql:5.7 # 启动服务 - docker run -d -p 3306:3306 -v /var/lib/mysql:/var/lib/mysql --name vp-mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7 + docker run -d -p 3306:3306 -v /var/lib/mysql:/var/lib/mysql --name vp-mysql -e MYSQL_ROOT_PASSWORD='#Yaxin0504' mysql:5.7 # **启用网络环境服务,生产环境请使用** - docker run -d -p 3306:3306 -v /var/lib/mysql:/var/lib/mysql --name virtual-patient-mysql -e MYSQL_ROOT_PASSWORD=123456 --network virtual-patient-network mysql:5.7 + # 生产环境端口号为37088 + docker run -d -p 37088:3306 -v /var/lib/mysql:/var/lib/mysql --name virtual-patient-mysql -e MYSQL_ROOT_PASSWORD='#Yaxin0504' --network virtual-patient-network mysql:5.7 ~~~ From c0b17d814523d6b703b732686994fadf65fbb835 Mon Sep 17 00:00:00 2001 From: liu Date: Fri, 23 Feb 2024 15:49:08 +0800 Subject: [PATCH 03/13] =?UTF-8?q?=E6=8F=90=E4=BA=A4nacos=E9=83=A8=E7=BD=B2?= =?UTF-8?q?=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/生产环境服务部署文档.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/生产环境服务部署文档.md b/docker/生产环境服务部署文档.md index f3087684..c15f3ef9 100644 --- a/docker/生产环境服务部署文档.md +++ b/docker/生产环境服务部署文档.md @@ -26,6 +26,7 @@ docker network create virtual-patient-network ## nacos服务部署 - 端口号:8848 +- 生产环境端口:18498 - 首次部署使用dockerfile的形式,后期更新直接docker restart就可以了 ### 首次部署 From e850b61f4c0b85f609d2e10b4b70ab02d31145cf Mon Sep 17 00:00:00 2001 From: liu Date: Mon, 26 Feb 2024 09:12:28 +0800 Subject: [PATCH 04/13] =?UTF-8?q?=E7=94=9F=E4=BA=A7=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E7=AB=AF=E5=8F=A3=E4=BF=AE=E6=94=B9=E5=8F=8A=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/生产环境服务部署文档.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docker/生产环境服务部署文档.md b/docker/生产环境服务部署文档.md index c15f3ef9..285607b9 100644 --- a/docker/生产环境服务部署文档.md +++ b/docker/生产环境服务部署文档.md @@ -113,10 +113,12 @@ docker run -it --name minio -p 9002:9000 -p 9001:9001 -d \ virtual-patient-minio:1.0.0 server /data --console-address ":9001" # **启用网络环境服务,生产环境请使用** -docker run -it --name virtual-patient-minio -p 9002:9000 -p 9001:9001 -d \ +# 生产环境密码#Yaxin0504 +# 生产环境端口修改 11900为s3 11901为web +docker run -it --name virtual-patient-minio -p 11900:9000 -p 11901:9001 -d \ -v /data/minio:/data \ -e 'MINIO_ROOT_USER=admin' \ - -e 'MINIO_ROOT_PASSWORD=12345678' \ + -e 'MINIO_ROOT_PASSWORD=#Yaxin0504' \ --network virtual-patient-network \ virtual-patient-minio:1.0.0 server /data --console-address ":9001" @@ -138,7 +140,9 @@ mv virtual-patient-bucket-prod /data/vp/minio/data docker run --name virtual-patient-redis -p 6379:6379 -v /data/vp/redis/data:/data -d virtual-patient-redis:1.0.0 # **启用网络环境服务,生产环境请使用** - docker run --name virtual-patient-redis -p 6379:6379 -v /data/vp/redis/data:/data --network virtual-patient-network -d virtual-patient-redis:1.0.0 + # 生产环境的Redis端口修改为11379 + # 密码:#Yaxin0504 + docker run --name virtual-patient-redis -p 11379:6379 -v /data/vp/redis/data:/data -v /data/redis:/usr/local/redis --network virtual-patient-network -d virtual-patient-redis:1.0.0 # 查看容器运行 docker ps | grep virtual-patient-redis From 37f6268d80c346b31decfeb419966668662314ae Mon Sep 17 00:00:00 2001 From: liu Date: Mon, 26 Feb 2024 10:03:01 +0800 Subject: [PATCH 05/13] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/supervision/pojo/vo/ChartNodeVO.java | 8 ++++++++ .../java/com/supervision/pojo/vo/RadarChartResVO.java | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/virtual-patient-web/src/main/java/com/supervision/pojo/vo/ChartNodeVO.java b/virtual-patient-web/src/main/java/com/supervision/pojo/vo/ChartNodeVO.java index 20961858..dc77eb26 100644 --- a/virtual-patient-web/src/main/java/com/supervision/pojo/vo/ChartNodeVO.java +++ b/virtual-patient-web/src/main/java/com/supervision/pojo/vo/ChartNodeVO.java @@ -1,34 +1,42 @@ package com.supervision.pojo.vo; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; @Data +@ApiModel public class ChartNodeVO { /** * 属性占比 */ + @ApiModelProperty("属性占比") private BigDecimal nodePer; /** * 总数=其他三项之和 */ + @ApiModelProperty("总数") private Integer total; /** * 用户命中的数量 */ + @ApiModelProperty("用户命中的数量") private Integer correct; /** * 不正确,用户未命中的数量=病例库中的总数-用户命中的数量 */ + @ApiModelProperty("不正确") private Integer unCorrect; /** * 标准,病例库中配置的数量 */ + @ApiModelProperty("标准,病例库中配置的数量") private Integer standard; } diff --git a/virtual-patient-web/src/main/java/com/supervision/pojo/vo/RadarChartResVO.java b/virtual-patient-web/src/main/java/com/supervision/pojo/vo/RadarChartResVO.java index 16a2c59d..5911d657 100644 --- a/virtual-patient-web/src/main/java/com/supervision/pojo/vo/RadarChartResVO.java +++ b/virtual-patient-web/src/main/java/com/supervision/pojo/vo/RadarChartResVO.java @@ -1,18 +1,26 @@ package com.supervision.pojo.vo; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data +@ApiModel public class RadarChartResVO { // 生成问诊雷达图 + @ApiModelProperty("生成问诊雷达图") private ChartNodeVO askChart; // 生成体格检查雷达图 + @ApiModelProperty("生成体格检查雷达图") private ChartNodeVO physicalChart; // 生成辅助检查雷达图 + @ApiModelProperty("生成辅助检查雷达图") private ChartNodeVO ancillaryChart; // 生成处置计划雷达图 + @ApiModelProperty("生成处置计划雷达图") private ChartNodeVO treatmentPlanChart; // 临床思维=前面几项和或平均值 + @ApiModelProperty("临床思维") private ChartNodeVO clinicalThinking; } From e7f6d694546d2ec91a23e0f09dbe00f863899118 Mon Sep 17 00:00:00 2001 From: liu Date: Mon, 26 Feb 2024 10:44:20 +0800 Subject: [PATCH 06/13] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=8F=AF=E8=83=BD?= =?UTF-8?q?=E4=B8=BA0=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/AskDiagnosisResultServiceImpl.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/virtual-patient-web/src/main/java/com/supervision/service/impl/AskDiagnosisResultServiceImpl.java b/virtual-patient-web/src/main/java/com/supervision/service/impl/AskDiagnosisResultServiceImpl.java index 4e4a1e54..48ec52d8 100644 --- a/virtual-patient-web/src/main/java/com/supervision/service/impl/AskDiagnosisResultServiceImpl.java +++ b/virtual-patient-web/src/main/java/com/supervision/service/impl/AskDiagnosisResultServiceImpl.java @@ -362,12 +362,12 @@ public class AskDiagnosisResultServiceImpl implements AskDiagnosisResultService // 过程数据3:问诊vs问诊正确率 BigDecimal num3 = BigDecimal.ZERO; if (userTreatmentPlanCount > 0) { - num3 = BigDecimal.valueOf(hitPlanCount).divide(BigDecimal.valueOf(userTreatmentPlanCount), 1, RoundingMode.HALF_UP); + num3 = BigDecimal.valueOf(hitPlanCount).divide(BigDecimal.valueOf(userTreatmentPlanCount), 2, RoundingMode.HALF_UP); } // 过程数据2:问诊vs标准正确率 BigDecimal num2 = BigDecimal.ZERO; if (medicalCount > 0) { - num2 = BigDecimal.valueOf(hitPlanCount).divide(BigDecimal.valueOf(medicalCount), 1, RoundingMode.HALF_UP); + num2 = BigDecimal.valueOf(hitPlanCount).divide(BigDecimal.valueOf(medicalCount), 2, RoundingMode.HALF_UP); } ChartNodeVO chartNodeVO = new ChartNodeVO(); chartNodeVO.setNodePer(num2.multiply(num3)); @@ -393,12 +393,12 @@ public class AskDiagnosisResultServiceImpl implements AskDiagnosisResultService // 过程数据3:问诊vs问诊正确率 BigDecimal num3 = BigDecimal.ZERO; if (userCount > 0) { - num3 = BigDecimal.valueOf(userHitCount).divide(BigDecimal.valueOf(userCount), 1, RoundingMode.HALF_UP); + num3 = BigDecimal.valueOf(userHitCount).divide(BigDecimal.valueOf(userCount), 2, RoundingMode.HALF_UP); } // 过程数据2:问诊vs标准正确率 BigDecimal num2 = BigDecimal.ZERO; if (medicalCount > 0) { - num2 = BigDecimal.valueOf(userHitCount).divide(BigDecimal.valueOf(medicalCount), 1, RoundingMode.HALF_UP); + num2 = BigDecimal.valueOf(userHitCount).divide(BigDecimal.valueOf(medicalCount), 2, RoundingMode.HALF_UP); } ChartNodeVO chartNodeVO = new ChartNodeVO(); @@ -427,12 +427,12 @@ public class AskDiagnosisResultServiceImpl implements AskDiagnosisResultService // 过程数据3:问诊vs问诊正确率 BigDecimal num3 = BigDecimal.ZERO; if (userCount > 0) { - num3 = BigDecimal.valueOf(userHitCount).divide(BigDecimal.valueOf(userCount), 1, RoundingMode.HALF_UP); + num3 = BigDecimal.valueOf(userHitCount).divide(BigDecimal.valueOf(userCount), 2, RoundingMode.HALF_UP); } // 过程数据2:问诊vs标准正确率 BigDecimal num2 = BigDecimal.ZERO; if (medicalCount > 0) { - num2 = BigDecimal.valueOf(userHitCount).divide(BigDecimal.valueOf(medicalCount), 1, RoundingMode.HALF_UP); + num2 = BigDecimal.valueOf(userHitCount).divide(BigDecimal.valueOf(medicalCount), 2, RoundingMode.HALF_UP); } ChartNodeVO chartNodeVO = new ChartNodeVO(); chartNodeVO.setNodePer(num2.multiply(num3)); @@ -474,12 +474,12 @@ public class AskDiagnosisResultServiceImpl implements AskDiagnosisResultService // 过程数据3:问诊vs问诊正确率 BigDecimal num3 = BigDecimal.ZERO; if (userQuestionCount > 0) { - num3 = BigDecimal.valueOf(userHitQuestionCount).divide(BigDecimal.valueOf(userQuestionCount), 1, RoundingMode.HALF_UP); + num3 = BigDecimal.valueOf(userHitQuestionCount).divide(BigDecimal.valueOf(userQuestionCount), 2, RoundingMode.HALF_UP); } // 过程数据2:问诊vs标准正确率 BigDecimal num2 = BigDecimal.ZERO; if (medicalQuestionCount > 0) { - num2 = BigDecimal.valueOf(userHitQuestionCount).divide(BigDecimal.valueOf(medicalQuestionCount), 1, RoundingMode.HALF_UP); + num2 = BigDecimal.valueOf(userHitQuestionCount).divide(BigDecimal.valueOf(medicalQuestionCount), 2, RoundingMode.HALF_UP); } ChartNodeVO chartNodeVO = new ChartNodeVO(); chartNodeVO.setNodePer(num2.multiply(num3)); From 14588a639acb62a7fdde1ac095d4dbe1a6f6e2e5 Mon Sep 17 00:00:00 2001 From: liu Date: Mon, 26 Feb 2024 11:19:59 +0800 Subject: [PATCH 07/13] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E9=98=88=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/templates/config.ftl | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/virtual-patient-rasa/src/main/resources/templates/config.ftl b/virtual-patient-rasa/src/main/resources/templates/config.ftl index d87a0641..d398b7c4 100644 --- a/virtual-patient-rasa/src/main/resources/templates/config.ftl +++ b/virtual-patient-rasa/src/main/resources/templates/config.ftl @@ -5,24 +5,24 @@ pipeline: - name: JiebaTokenizer - name: LanguageModelFeaturizer model_name: bert - model_weights: bert-base-chinese - - name: RegexFeaturizer - - name: DIETClassifier - epochs: 100 - learning_rate: 0.001 - tensorboard_log_directory: ./log - - name: ResponseSelector - epochs: 100 - learning_rate: 0.001 - - name: FallbackClassifier - threshold: 0.87 - ambiguity_threshold: 0.1 - - name: EntitySynonymMapper +model_weights: bert-base-chinese +- name: RegexFeaturizer +- name: DIETClassifier +epochs: 100 +learning_rate: 0.001 +tensorboard_log_directory: ./log +- name: ResponseSelector +epochs: 100 +learning_rate: 0.001 +- name: FallbackClassifier +threshold: 0.4 +ambiguity_threshold: 0.1 +- name: EntitySynonymMapper policies: - - name: MemoizationPolicy - - name: TEDPolicy - - name: RulePolicy - core_fallback_threshold: 0.87 - core_fallback_action_name: "action_default_fallback" - enable_fallback_prediction: True +- name: MemoizationPolicy +- name: TEDPolicy +- name: RulePolicy +core_fallback_threshold: 0.4 +core_fallback_action_name: "action_default_fallback" +enable_fallback_prediction: True From 8cf513afd71a8033efd473989261398ed6b8bb91 Mon Sep 17 00:00:00 2001 From: liu Date: Mon, 26 Feb 2024 11:42:20 +0800 Subject: [PATCH 08/13] =?UTF-8?q?=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../supervision/service/impl/AskDiagnosisResultServiceImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/virtual-patient-web/src/main/java/com/supervision/service/impl/AskDiagnosisResultServiceImpl.java b/virtual-patient-web/src/main/java/com/supervision/service/impl/AskDiagnosisResultServiceImpl.java index 48ec52d8..f67197a5 100644 --- a/virtual-patient-web/src/main/java/com/supervision/service/impl/AskDiagnosisResultServiceImpl.java +++ b/virtual-patient-web/src/main/java/com/supervision/service/impl/AskDiagnosisResultServiceImpl.java @@ -103,6 +103,7 @@ public class AskDiagnosisResultServiceImpl implements AskDiagnosisResultService ArrayList otherTreatmentPlanResults = new ArrayList<>(); for (TreatmentPlanRecord treatmentPlanRecord : treatmentPlanRecordList) { TreatmentPlanRecordVo bean = BeanUtil.toBean(treatmentPlanRecord, TreatmentPlanRecordVo.class); + // 是否正确 boolean flag = StrUtil.isNotEmpty(bean.getDrugId()) ? drugIds.contains(bean.getDrugId()) : planIds.contains(bean.getTreatmentPlanId()); bean.setFlag(flag ? 1 : 0); if (StrUtil.isNotEmpty(bean.getDrugId())) { From 6b4085339739171f7152c112a28a81ef77c334ff Mon Sep 17 00:00:00 2001 From: liu Date: Mon, 26 Feb 2024 13:38:21 +0800 Subject: [PATCH 09/13] =?UTF-8?q?=E7=9F=A5=E8=AF=86=E5=9B=BE=E8=B0=B1?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E9=83=A8=E7=BD=B2=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/virtual-patient-graph/Dockerfile | 8 ++++++ docker/生产环境服务部署文档.md | 33 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 docker/virtual-patient-graph/Dockerfile diff --git a/docker/virtual-patient-graph/Dockerfile b/docker/virtual-patient-graph/Dockerfile new file mode 100644 index 00000000..f18bcf13 --- /dev/null +++ b/docker/virtual-patient-graph/Dockerfile @@ -0,0 +1,8 @@ +# 设置基础镜像 +FROM registry.cn-beijing.aliyuncs.com/longbei/jdk:latest + +# 暴漏服务端口 +EXPOSE 8892 + +# 设置启动命令 +ENTRYPOINT ["java","-Xms256m","-Xmx1g","-Dspring.profiles.active=prod","-Dfile.encoding=utf-8","-Duser.timezone=Asia/Shanghai","-jar","/data/vp/virtual-patient-graph-1.0-SNAPSHOT.jar"] \ No newline at end of file diff --git a/docker/生产环境服务部署文档.md b/docker/生产环境服务部署文档.md index 285607b9..2f423d81 100644 --- a/docker/生产环境服务部署文档.md +++ b/docker/生产环境服务部署文档.md @@ -245,6 +245,39 @@ mv virtual-patient-bucket-prod /data/vp/minio/data docker restart virtual-patient-manage ~~~ +## Graph知识图谱系统部署 + +- 端口号:8892 +- 首次部署使用dockerfile的形式,后期更新直接docker restart就可以了 +- 将代码包virtual-patient-graph-1.0-SNAPSHOT.jar拷贝到路径/data/vp下 + +### 首次部署 + +~~~shell + # 进入virtual-patient-manage文件夹,依次执行命令 + # 构建镜像 + docker build -t virtual-patient-graph:1.0.0 . + # 验证镜像是否存在 + docker images | grep virtual-patient-graph + # 运行容器 + docker run --name virtual-patient-graph -p 8892:8892 -d virtual-patient-graph:1.0.0 + # **启用网络环境服务,生产环境请使用** + docker run --name virtual-patient-graph -p 8892:8892 -v /data/vp:/data/vp --network virtual-patient-network -d virtual-patient-manage:1.0.0 --spring.profiles.active=prod + # 验证容器运行 + docker ps | grep virtual-patient-graph + # 查看日志是否正常 + docker logs -f virtual-patient-graph +~~~ + +### 服务更新 + +- 将代码包virtual-patient-graph-1.0-SNAPSHOT.jar拷贝到路径/data/vp下 +- 重启容器 + +~~~shell + docker restart virtual-patient-graph +~~~ + ## Nginx前端服务 ~~~shell From 6d2af869c7974756a5c6b1431616aa1da70489a9 Mon Sep 17 00:00:00 2001 From: liu Date: Mon, 26 Feb 2024 14:07:54 +0800 Subject: [PATCH 10/13] =?UTF-8?q?=E5=9B=BE=E8=B0=B1=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E9=9B=86=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/生产环境服务部署文档.md | 10 +- virtual-patient-graph/pom.xml | 47 ++++++++ .../VirtualPatientGraphApplication.java | 2 + .../service/impl/GraphNebulaServiceImpl.java | 5 + .../src/main/resources/application-dev.yml | 105 ------------------ .../src/main/resources/application.yml | 49 +++++++- .../src/main/resources/bootstrap-dev.yml | 10 ++ .../src/main/resources/bootstrap-test.yml | 10 ++ .../src/main/resources/bootstrap.yml | 5 + .../src/main/resources/logback-spring.xml | 37 ++++++ .../main/resources/知识图谱test-1.xlsx | Bin 53735 -> 0 bytes 11 files changed, 168 insertions(+), 112 deletions(-) delete mode 100644 virtual-patient-graph/src/main/resources/application-dev.yml create mode 100644 virtual-patient-graph/src/main/resources/bootstrap-dev.yml create mode 100644 virtual-patient-graph/src/main/resources/bootstrap-test.yml create mode 100644 virtual-patient-graph/src/main/resources/bootstrap.yml create mode 100644 virtual-patient-graph/src/main/resources/logback-spring.xml delete mode 100644 virtual-patient-graph/src/main/resources/知识图谱test-1.xlsx diff --git a/docker/生产环境服务部署文档.md b/docker/生产环境服务部署文档.md index 2f423d81..d655b261 100644 --- a/docker/生产环境服务部署文档.md +++ b/docker/生产环境服务部署文档.md @@ -161,7 +161,7 @@ mv virtual-patient-bucket-prod /data/vp/minio/data # 验证镜像是否存在 docker images | grep virtual-patient-rasa-manager # 运行容器 - docker run --name virtual-patient-rasa-manager -p 8990:8890 -d virtual-patient-rasa-manager:1.0.0 + docker run --name virtual-patient-rasa-manager -p 8990:8890 -v /data/vp:/data/vp -d virtual-patient-rasa-manager:1.0.0 # **启用网络环境服务,生产环境请使用** docker run --name virtual-patient-rasa-manager -p 8990:8890 -v /data/vp:/data/vp --network virtual-patient-network -d virtual-patient-rasa-manager:1.0.0 --spring.profiles.active=prod # 验证容器运行 @@ -194,7 +194,7 @@ mv virtual-patient-bucket-prod /data/vp/minio/data # 验证镜像是否存在 docker images | grep virtual-patient-web # 运行容器 - docker run --name virtual-patient-web -p 8899:8899 -d virtual-patient-web + docker run --name virtual-patient-web -p 8899:8899 -v /data/vp:/data/vp -d virtual-patient-web # **启用网络环境服务,生产环境请使用** docker run --name virtual-patient-web -p 8899:8899 -v /data/vp:/data/vp --network virtual-patient-network -d virtual-patient-web:1.0.0 --spring.profiles.active=prod # 验证容器运行 @@ -227,7 +227,7 @@ mv virtual-patient-bucket-prod /data/vp/minio/data # 验证镜像是否存在 docker images | grep virtual-patient-manage # 运行容器 - docker run --name virtual-patient-manage -p 8891:8891 -d virtual-patient-manage:1.0.0 + docker run --name virtual-patient-manage -p 8891:8891 -v /data/vp:/data/vp -d virtual-patient-manage:1.0.0 # **启用网络环境服务,生产环境请使用** docker run --name virtual-patient-manage -p 8891:8891 -v /data/vp:/data/vp --network virtual-patient-network -d virtual-patient-manage:1.0.0 --spring.profiles.active=prod # 验证容器运行 @@ -260,7 +260,7 @@ mv virtual-patient-bucket-prod /data/vp/minio/data # 验证镜像是否存在 docker images | grep virtual-patient-graph # 运行容器 - docker run --name virtual-patient-graph -p 8892:8892 -d virtual-patient-graph:1.0.0 + docker run --name virtual-patient-graph -p 8892:8892 -v /data/vp:/data/vp -d virtual-patient-graph:1.0.0 # **启用网络环境服务,生产环境请使用** docker run --name virtual-patient-graph -p 8892:8892 -v /data/vp:/data/vp --network virtual-patient-network -d virtual-patient-manage:1.0.0 --spring.profiles.active=prod # 验证容器运行 @@ -288,7 +288,7 @@ mv virtual-patient-bucket-prod /data/vp/minio/data # 验证镜像是否存在 docker images | grep virtual-patient-nginx # 运行容器 - docker run --name virtual-patient-nginx -p 443:443 -d -e UPSTREAM_WEB_SERVERS={ip}:{port} -e UPSTREAM_MANAGE_SERVERS={ip}:{port} virtual-patient-nginx:1.0.0 + docker run --name virtual-patient-nginx -p 443:443 -v /data/vp/dist:/usr/share/nginx/html/dist -d -e UPSTREAM_WEB_SERVERS={ip}:{port} -e UPSTREAM_MANAGE_SERVERS={ip}:{port} virtual-patient-nginx:1.0.0 # UPSTREAM_WEB_SERVERS:虚拟病人问诊系统服务的ip:port # UPSTREAM_MANAGE_SERVERS:虚拟病人后端管理系统服务的ip:port diff --git a/virtual-patient-graph/pom.xml b/virtual-patient-graph/pom.xml index 11c19597..847186f2 100644 --- a/virtual-patient-graph/pom.xml +++ b/virtual-patient-graph/pom.xml @@ -20,6 +20,36 @@ + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + com.alibaba + fastjson + + + com.alibaba.nacos + nacos-common + + + + + + com.alibaba.nacos + nacos-common + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + org.nebula-contrib ngbatis @@ -83,4 +113,21 @@ + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + \ No newline at end of file diff --git a/virtual-patient-graph/src/main/java/com/supervision/VirtualPatientGraphApplication.java b/virtual-patient-graph/src/main/java/com/supervision/VirtualPatientGraphApplication.java index 35c473c3..10965b97 100644 --- a/virtual-patient-graph/src/main/java/com/supervision/VirtualPatientGraphApplication.java +++ b/virtual-patient-graph/src/main/java/com/supervision/VirtualPatientGraphApplication.java @@ -3,11 +3,13 @@ package com.supervision; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.scheduling.annotation.EnableScheduling; @EnableScheduling @SpringBootApplication(scanBasePackages = {"com.supervision", "org.nebula"}) @MapperScan(basePackages = {"com.supervision.**.mapper"}) +@EnableDiscoveryClient public class VirtualPatientGraphApplication { public static void main(String[] args) { diff --git a/virtual-patient-graph/src/main/java/com/supervision/service/impl/GraphNebulaServiceImpl.java b/virtual-patient-graph/src/main/java/com/supervision/service/impl/GraphNebulaServiceImpl.java index bafce50c..b9fe54c7 100644 --- a/virtual-patient-graph/src/main/java/com/supervision/service/impl/GraphNebulaServiceImpl.java +++ b/virtual-patient-graph/src/main/java/com/supervision/service/impl/GraphNebulaServiceImpl.java @@ -247,6 +247,11 @@ public class GraphNebulaServiceImpl implements GraphNebulaService { @Override public GraphVO queryGraph(String processId) { Process process = Optional.ofNullable(processService.getById(processId)).orElseThrow(() -> new BusinessException("未找到对应的问诊流程")); + // 如果图谱ID为空,则创建图谱 + if (StrUtil.isEmpty(process.getGraphId())) { + creatGraphByNebula(processId); + process = Optional.ofNullable(processService.getById(processId)).orElseThrow(() -> new BusinessException("未找到对应的问诊流程")); + } List> subgraphList = medicalRecDao.selectSubgraph(process.getGraphId()); List nodeList = new ArrayList<>(); diff --git a/virtual-patient-graph/src/main/resources/application-dev.yml b/virtual-patient-graph/src/main/resources/application-dev.yml deleted file mode 100644 index b3cc9b2f..00000000 --- a/virtual-patient-graph/src/main/resources/application-dev.yml +++ /dev/null @@ -1,105 +0,0 @@ -#服务器端口 -server: - port: 8897 - servlet: - context-path: /virtual-patient-graph - undertow: - # HTTP post内容的最大大小。当值为-1时,默认值为大小是无限的 - max-http-post-size: -1 - # 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理 - # 每块buffer的空间大小,越小的空间被利用越充分 - buffer-size: 512 - # 是否分配的直接内存 - direct-buffers: true - -spring: - application: - name: virtual-patient-graph - servlet: - multipart: - max-file-size: 100MB - max-request-size: 100MB - ##数据源配置 - datasource: - type: com.alibaba.druid.pool.DruidDataSource - druid: - driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://192.168.10.137:3306/virtual_patient?useUnicode=true&characterEncoding=utf-8&useSSL=true&nullCatalogMeansCurrent=true&serverTimezone=GMT%2B8 - username: root - password: '123456' - initial-size: 5 # 初始化大小 - min-idle: 10 # 最小连接数 - max-active: 20 # 最大连接数 - max-wait: 60000 # 获取连接时的最大等待时间 - min-evictable-idle-time-millis: 300000 # 一个连接在池中最小生存的时间,单位是毫秒 - time-between-eviction-runs-millis: 60000 # 多久才进行一次检测需要关闭的空闲连接,单位是毫秒 - filters: stat,wall # 配置扩展插件:stat-监控统计,log4j-日志,wall-防火墙(防止SQL注入),去掉后,监控界面的sql无法统计 - validation-query: SELECT 1 # 检测连接是否有效的 SQL语句,为空时以下三个配置均无效 - test-on-borrow: true # 申请连接时执行validationQuery检测连接是否有效,默认true,开启后会降低性能 - test-on-return: true # 归还连接时执行validationQuery检测连接是否有效,默认false,开启后会降低性能 - test-while-idle: true # 申请连接时如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效,默认false,建议开启,不影响性能 - stat-view-servlet: - enabled: false # 是否开启 StatViewServlet - filter: - stat: - enabled: true # 是否开启 FilterStat,默认true - log-slow-sql: true # 是否开启 慢SQL 记录,默认false - slow-sql-millis: 5000 # 慢 SQL 的标准,默认 3000,单位:毫秒 - merge-sql: false # 合并多个连接池的监控数据,默认false - redis: - host: 192.168.10.138 - port: 6379 - password: 123456 - -nebula: - ngbatis: - use-session-pool: true - # 127.0.0.1:9669, ip:port, .... - hosts: 192.168.10.137:9669 - username: root - password: 123456 - # 注意,新建使用的时候,必须有一个库 - space: virtual_patient - # http客户端使用 - minConnSize: 5 - maxConnSize: 10 - timeout: 300000 - idleTime: 180000 - # ngbatis使用连接池配置 - pool-config: - # 连接池中最小空闲连接数 - min-conns-size: 0 - # 连接池中最大空闲连接数 - max-conns-size: 10 - # 客户端同服务端建立连接的超时时间设置,单位为 ms;超过设定时间未建立起连接,则报错 - timeout: 0 - # 连接空闲时间,为 0 表示连接永不删除,单位为 ms - idle-time: 0 - # 连接池检测空闲连接的时间间隔,为 -1 表示不进行检测 - interval-idle: -1 - # 连接等候时间,超过则不再等候连接 - wait-time: 0 - # 集群允许最小的服务可用率,1.0 表示为所有机器 graphd 可用,0.25 表示集群中 1/4 机器可用即可 - min-cluster-health-rate: 1.0 - # 是否允许 SSL 连接,目前暂不支持 - enable-ssl: false -cql: - parser: - # 更换开发者自定义的 xml 所在位置 - mapper-locations: nebulaMapper/**/*.xml # 默认为 mapper/**/*.xml -# nebula上传文件使用 -path: - uploadFilePath: /opt/project/java/graphFile - importerPath: /data1/opt - -mybatis-plus: - mapper-locations: classpath*:mapper/**/*.xml - configuration: - log-impl: org.apache.ibatis.logging.stdout.StdOutImpl - -logging: - level: - org.nebula.contrib: DEBUG - - - diff --git a/virtual-patient-graph/src/main/resources/application.yml b/virtual-patient-graph/src/main/resources/application.yml index caf4dfcd..e77fd98f 100644 --- a/virtual-patient-graph/src/main/resources/application.yml +++ b/virtual-patient-graph/src/main/resources/application.yml @@ -1,3 +1,48 @@ +#服务器端口 +server: + port: 8892 + servlet: + context-path: /virtual-patient-graph + undertow: + # HTTP post内容的最大大小。当值为-1时,默认值为大小是无限的 + max-http-post-size: -1 + # 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理 + # 每块buffer的空间大小,越小的空间被利用越充分 + buffer-size: 512 + # 是否分配的直接内存 + direct-buffers: true + spring: - profiles: - active: dev \ No newline at end of file + servlet: + multipart: + max-file-size: 100MB + max-request-size: 100MB + ##数据源配置 + datasource: + type: com.alibaba.druid.pool.DruidDataSource + druid: + initial-size: 5 # 初始化大小 + min-idle: 10 # 最小连接数 + max-active: 20 # 最大连接数 + max-wait: 60000 # 获取连接时的最大等待时间 + min-evictable-idle-time-millis: 300000 # 一个连接在池中最小生存的时间,单位是毫秒 + time-between-eviction-runs-millis: 60000 # 多久才进行一次检测需要关闭的空闲连接,单位是毫秒 + filters: stat,wall # 配置扩展插件:stat-监控统计,log4j-日志,wall-防火墙(防止SQL注入),去掉后,监控界面的sql无法统计 + validation-query: SELECT 1 # 检测连接是否有效的 SQL语句,为空时以下三个配置均无效 + test-on-borrow: true # 申请连接时执行validationQuery检测连接是否有效,默认true,开启后会降低性能 + test-on-return: true # 归还连接时执行validationQuery检测连接是否有效,默认false,开启后会降低性能 + test-while-idle: true # 申请连接时如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效,默认false,建议开启,不影响性能 + stat-view-servlet: + enabled: false # 是否开启 StatViewServlet + filter: + stat: + enabled: true # 是否开启 FilterStat,默认true + log-slow-sql: true # 是否开启 慢SQL 记录,默认false + slow-sql-millis: 5000 # 慢 SQL 的标准,默认 3000,单位:毫秒 + merge-sql: false # 合并多个连接池的监控数据,默认false + + +mybatis-plus: + mapper-locations: classpath*:mapper/**/*.xml + configuration: + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl \ No newline at end of file diff --git a/virtual-patient-graph/src/main/resources/bootstrap-dev.yml b/virtual-patient-graph/src/main/resources/bootstrap-dev.yml new file mode 100644 index 00000000..b43e8800 --- /dev/null +++ b/virtual-patient-graph/src/main/resources/bootstrap-dev.yml @@ -0,0 +1,10 @@ +spring: + cloud: + nacos: + config: + server-addr: 192.168.10.137:8848 + file-extension: yml + namespace: b9eea377-79ec-4ba5-9cc2-354f7bd5181e + discovery: + server-addr: 192.168.10.137:8848 + namespace: b9eea377-79ec-4ba5-9cc2-354f7bd5181e diff --git a/virtual-patient-graph/src/main/resources/bootstrap-test.yml b/virtual-patient-graph/src/main/resources/bootstrap-test.yml new file mode 100644 index 00000000..71468fab --- /dev/null +++ b/virtual-patient-graph/src/main/resources/bootstrap-test.yml @@ -0,0 +1,10 @@ +spring: + cloud: + nacos: + config: + server-addr: 192.168.10.137:8848 + file-extension: yml + namespace: 88e1f674-1fbc-4021-9ff1-60b94ee13ef0 + discovery: + server-addr: 192.168.10.137:8848 + namespace: 88e1f674-1fbc-4021-9ff1-60b94ee13ef0 \ No newline at end of file diff --git a/virtual-patient-graph/src/main/resources/bootstrap.yml b/virtual-patient-graph/src/main/resources/bootstrap.yml new file mode 100644 index 00000000..524e3266 --- /dev/null +++ b/virtual-patient-graph/src/main/resources/bootstrap.yml @@ -0,0 +1,5 @@ +spring: + profiles: + active: dev + application: + name: virtual-patient-graph \ No newline at end of file diff --git a/virtual-patient-graph/src/main/resources/logback-spring.xml b/virtual-patient-graph/src/main/resources/logback-spring.xml new file mode 100644 index 00000000..88cefa73 --- /dev/null +++ b/virtual-patient-graph/src/main/resources/logback-spring.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + /data/vp/log/virtual-patient-graph.log + + + /data/vp/log/history/virtual-patient-graph-%d{yyyy-MM-dd}.log + + + %date [%thread] %-5level %logger{35} - %msg%n + + + + + + + \ No newline at end of file diff --git a/virtual-patient-graph/src/main/resources/知识图谱test-1.xlsx b/virtual-patient-graph/src/main/resources/知识图谱test-1.xlsx deleted file mode 100644 index e81adf8383aeda73610b7888a71cd817a4f2d6d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53735 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 Date: Mon, 26 Feb 2024 14:15:18 +0800 Subject: [PATCH 11/13] =?UTF-8?q?=E5=9B=BE=E8=B0=B1=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E9=9B=86=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/supervision/vo/EdgeVO.java | 5 +++++ .../src/main/java/com/supervision/vo/GraphVO.java | 5 +++++ .../src/main/java/com/supervision/vo/NodeVO.java | 15 ++++++++++----- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/virtual-patient-graph/src/main/java/com/supervision/vo/EdgeVO.java b/virtual-patient-graph/src/main/java/com/supervision/vo/EdgeVO.java index 9411fbe8..453522b1 100644 --- a/virtual-patient-graph/src/main/java/com/supervision/vo/EdgeVO.java +++ b/virtual-patient-graph/src/main/java/com/supervision/vo/EdgeVO.java @@ -1,5 +1,6 @@ package com.supervision.vo; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.Map; @@ -7,11 +8,15 @@ import java.util.Map; @Data public class EdgeVO { + @ApiModelProperty("来源节点ID") private String source; + @ApiModelProperty("目标节点ID") private String target; + @ApiModelProperty("连线展示的名称,可能为空") private String name; + @ApiModelProperty("连线所拥有的属性") private Map params; } diff --git a/virtual-patient-graph/src/main/java/com/supervision/vo/GraphVO.java b/virtual-patient-graph/src/main/java/com/supervision/vo/GraphVO.java index 0139923d..fa0ca2cb 100644 --- a/virtual-patient-graph/src/main/java/com/supervision/vo/GraphVO.java +++ b/virtual-patient-graph/src/main/java/com/supervision/vo/GraphVO.java @@ -1,5 +1,7 @@ package com.supervision.vo; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -9,9 +11,12 @@ import java.util.List; @Data @NoArgsConstructor @AllArgsConstructor +@ApiModel public class GraphVO { + @ApiModelProperty("节点") private List nodes; + @ApiModelProperty("关系") private List edges; } diff --git a/virtual-patient-graph/src/main/java/com/supervision/vo/NodeVO.java b/virtual-patient-graph/src/main/java/com/supervision/vo/NodeVO.java index dad5f842..917842b8 100644 --- a/virtual-patient-graph/src/main/java/com/supervision/vo/NodeVO.java +++ b/virtual-patient-graph/src/main/java/com/supervision/vo/NodeVO.java @@ -1,24 +1,29 @@ package com.supervision.vo; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.LinkedHashMap; import java.util.Map; @Data +@ApiModel public class NodeVO { + @ApiModelProperty("节点ID") private String id; - + @ApiModelProperty("节点值(页面展示)") private String nodeValue; - + @ApiModelProperty("节点颜色") private String nodeColour; - + @ApiModelProperty("节点级别 1 2 3 4级") private Integer nodeLevel; - + @ApiModelProperty("节点类型") private String nodeType; - + @ApiModelProperty("节点描述") private String nodeDesc; + @ApiModelProperty("节点拥有的属性列表") private Map params = new LinkedHashMap<>(); } From 37f59030b5a6613cbab0a8b6acd9747aedce7e85 Mon Sep 17 00:00:00 2001 From: liu Date: Mon, 26 Feb 2024 14:16:35 +0800 Subject: [PATCH 12/13] =?UTF-8?q?=E5=9B=BE=E8=B0=B1=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E9=9B=86=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/supervision/vo/TreeNodeVO.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/virtual-patient-graph/src/main/java/com/supervision/vo/TreeNodeVO.java b/virtual-patient-graph/src/main/java/com/supervision/vo/TreeNodeVO.java index e81127a1..39384497 100644 --- a/virtual-patient-graph/src/main/java/com/supervision/vo/TreeNodeVO.java +++ b/virtual-patient-graph/src/main/java/com/supervision/vo/TreeNodeVO.java @@ -1,5 +1,7 @@ package com.supervision.vo; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.LinkedHashMap; @@ -7,24 +9,27 @@ import java.util.List; import java.util.Map; @Data +@ApiModel public class TreeNodeVO { + @ApiModelProperty("ID") private String id; - + @ApiModelProperty("节点值") private String nodeValue; - + @ApiModelProperty("节点颜色") private String nodeColour; - + @ApiModelProperty("节点级别") private Integer nodeLevel; - + @ApiModelProperty("节点类型") private String nodeType; - + @ApiModelProperty("节点描述") private String nodeDesc; - + @ApiModelProperty("节点的属性列表") private Map params = new LinkedHashMap<>(); /** * 子节点 */ + @ApiModelProperty("子节点") private List childNodeList; } From 92a8c2baf8f81ad2b4180298ecd70cdaadea61d7 Mon Sep 17 00:00:00 2001 From: liu Date: Tue, 27 Feb 2024 13:55:22 +0800 Subject: [PATCH 13/13] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/supervision/AskTemplateIdTest.java | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/virtual-patient-web/src/test/java/com/supervision/AskTemplateIdTest.java b/virtual-patient-web/src/test/java/com/supervision/AskTemplateIdTest.java index f98cdb2d..4abd7794 100644 --- a/virtual-patient-web/src/test/java/com/supervision/AskTemplateIdTest.java +++ b/virtual-patient-web/src/test/java/com/supervision/AskTemplateIdTest.java @@ -1,7 +1,6 @@ package com.supervision; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ReUtil; import cn.hutool.http.HttpUtil; @@ -30,6 +29,8 @@ import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; @Slf4j @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @@ -87,6 +88,7 @@ public class AskTemplateIdTest { } } + @Test public void generateQuestion() { // 使用文心一言,这里是付费的,不要随便用哦,注意数量 @@ -94,31 +96,36 @@ public class AskTemplateIdTest { System.out.println(post); JSONObject parse = JSONUtil.parseObj(post); String accessToken = parse.getStr("access_token"); - + List aqtList = commonDicService.lambdaQuery().eq(CommonDic::getGroupCode, "AQT").isNotNull(CommonDic::getParentId).ne(CommonDic::getParentId, 179).list(); + Map dictMap = aqtList.stream().collect(Collectors.toMap(CommonDic::getId, Function.identity())); List list = askTemplateQuestionLibraryService.list(); for (AskTemplateQuestionLibrary ask : list) { try { - String description = ask.getDescription(); - Map map = new HashMap<>(); - map.put("role", "user"); - map.put("content", "请把下面这句话以20种不同的方式提问,以JSONARRAY的形式输出:" + description); - HashMap param = new HashMap<>(); - param.put("messages", CollUtil.newArrayList(map)); - String askAnswer = HttpUtil.post("https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro?access_token=" + accessToken, JSONUtil.toJsonStr(param)); - JSONObject answerJSON = JSONUtil.parseObj(askAnswer); - String result = answerJSON.getStr("result"); - String s = ReUtil.get("\\[(.*?)\\]", result, 0); - List question = JSONUtil.toList(s, String.class); - question.add(0, description); - askTemplateQuestionLibraryService.lambdaUpdate().set(AskTemplateQuestionLibrary::getQuestion, JSONUtil.toJsonStr(question)).eq(AskTemplateQuestionLibrary::getId, ask.getId()).update(); + CommonDic dic = dictMap.get(ask.getDictId()); + if (ObjectUtil.isNotEmpty(dic)) { + String description = ask.getDescription(); + Map map = new HashMap<>(); + map.put("role", "user"); + map.put("content", "假设你是一个精通RASA NLU调优的工程师,我现在有一个意图,有一个问题示例,请你根据这个意图,针对这个问题示例,提出30条与这个问题示例类似的问题,注意,问题不要超出这个意图的范围,回答请使用json array的格式,示例:[\"相似问题1\",\"相似问题2\"]\n" + + "### 下面是意图和问题示例\n" + dic.getNameZhPath() + ":" + ask.getQuestion()); + HashMap param = new HashMap<>(); + param.put("messages", CollUtil.newArrayList(map)); + String askAnswer = HttpUtil.post("https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro?access_token=" + accessToken, JSONUtil.toJsonStr(param)); + JSONObject answerJSON = JSONUtil.parseObj(askAnswer); + String result = answerJSON.getStr("result"); + String s = ReUtil.get("\\[(.*?)\\]", result, 0); + List question = JSONUtil.toList(s, String.class); + question.add(0, description); + askTemplateQuestionLibraryService.lambdaUpdate().set(AskTemplateQuestionLibrary::getQuestion, JSONUtil.toJsonStr(question)).eq(AskTemplateQuestionLibrary::getId, ask.getId()).update(); + } + } catch (Exception e) { log.error("{}生成错误", ask.getDescription(), e); } - } - } + @Autowired private AskService askService;