Compare commits

..
198 Commits
Author SHA1 Message Date
admin d599892899 作者同步问题2 2025-08-29 17:48:53 +08:00
admin 1d0b90881b 作者同步问题1 2025-08-29 17:45:40 +08:00
admin 8195f66ed1 作者同步问题 2025-08-29 17:35:36 +08:00
admin 3e3a0df1ca 标签现实问题, 2025-08-29 17:00:22 +08:00
admin 067254f9db 修改统计的问题 2025-08-29 16:29:02 +08:00
admin 5c081f79d9 修改排序1 2025-08-29 16:06:08 +08:00
admin 69d881cf5a 修改排序 2025-08-29 15:56:39 +08:00
admin eb9cf9964a 1 2025-08-29 15:36:40 +08:00
admin 320bf70024 修改了外链证书的问题1 2025-08-29 13:18:55 +08:00
admin 6a2742d539 修改了外链证书的问题 2025-08-29 13:12:06 +08:00
admin d8e89ca0d7 修改首页推荐展示数量 2025-08-29 09:04:57 +08:00
admin 126b878f3d 666661111 2025-08-28 17:36:00 +08:00
admin a96ae48920 66666 2025-08-21 09:15:17 +08:00
admin 523299f91a 44444 2025-08-20 09:10:15 +08:00
admin 075fb78d3a 111113333 2025-08-20 08:40:24 +08:00
admin f6d0dbba00 11111 2025-08-19 17:30:51 +08:00
admin dc7f5fe174 777743434343333 2025-08-19 17:20:12 +08:00
admin dc7f7d15a8 77774343434 2025-08-19 16:56:24 +08:00
admin d4c1a2a562 7777 2025-08-19 08:52:17 +08:00
admin 4681545595 6666622222 2025-08-19 08:48:22 +08:00
admin 5ac098dbbf 66666 2025-08-18 14:58:29 +08:00
admin 759f1f5dd9 4444443455 2025-08-18 14:20:30 +08:00
admin c43f7ef739 44444 2025-08-18 13:32:59 +08:00
admin f28e8b25b8 3333 2025-08-18 13:13:16 +08:00
admin dc35a7df70 1111 2025-08-18 11:43:32 +08:00
admin 8652bd1d7f 修正了删除状态 2025-08-18 09:26:42 +08:00
admin 7143789256 修改了docker相关11122333 2025-08-15 15:11:02 +08:00
admin 9ab82b718c 修改了docker相关1 2025-08-14 15:02:17 +08:00
admin 32c3be920e 修改了docker相关 2025-08-14 14:52:43 +08:00
admin eaaeb8c28b 评论状态 2025-08-14 08:41:41 +08:00
admin 3eb7107361 4444 2025-08-13 17:59:06 +08:00
admin 1f72007754 修改了首页推荐,新增了医院 2025-08-13 16:30:14 +08:00
admin 24e597966c 55555 2025-08-12 16:39:29 +08:00
admin 6bd9ab31b6 23444 2025-08-12 13:44:55 +08:00
admin fd9ae57649 1123344 2025-08-12 11:40:31 +08:00
admin d8f1eb8d16 评论接口更改返回状态44 2025-08-05 11:27:17 +08:00
admin 5ba59aecf9 评论接口更改返回状态3 2025-08-05 11:22:45 +08:00
admin aa76f5e07f 评论接口更改返回状态2 2025-08-05 11:14:28 +08:00
admin e997998b40 评论接口更改返回状态1 2025-08-05 11:11:09 +08:00
admin 66920c976c 评论接口更改返回状态 2025-08-05 11:01:35 +08:00
admin c0f182de55 4444 2025-08-05 10:16:22 +08:00
admin 5f7e7a0c5f 111 2025-08-05 10:00:21 +08:00
admin 2098589016 修改打上积分4 2025-08-04 17:28:00 +08:00
admin 01ef215163 修改打上积分2 2025-08-04 17:27:02 +08:00
admin f88c3521fd 修改打上积分 2025-08-04 17:26:35 +08:00
admin e1f49cf813 修改登录2 2025-08-04 17:18:52 +08:00
admin e667e312ab 修改登录1 2025-08-04 16:55:13 +08:00
admin c41d50c54f 修改登录 2025-08-04 16:47:24 +08:00
admin 54c250a7a6 修改了病例交流的统计数据和登陆状态1 2025-08-04 16:09:40 +08:00
admin 20ff8778b8 修改了病例交流的统计数据和登陆状态 2025-08-04 15:58:02 +08:00
admin 36a796853b 修改了评论没有域名 2025-08-04 11:01:56 +08:00
admin 85ee55c9f7 修改了资源路径-作者4 2025-08-01 14:58:40 +08:00
admin ac19f19c47 修改了资源路径-作者2 2025-08-01 14:35:37 +08:00
admin 14856318d8 修改了资源路径-作者1 2025-08-01 14:15:46 +08:00
admin b9c47f8aca 修改了资源路径-作者 2025-08-01 13:56:59 +08:00
admin 131d417834 修改了资源路径9 2025-08-01 13:32:21 +08:00
admin 6f1715e857 修改了资源路径8 2025-08-01 13:17:17 +08:00
admin 8962369be6 修改了资源路径7 2025-08-01 11:37:58 +08:00
admin 492eef5bc0 修改了资源路径6 2025-08-01 11:32:54 +08:00
admin 7a060c442e 修改了资源路径5 2025-08-01 11:25:44 +08:00
admin 68e4c8d592 修改了资源路径4 2025-08-01 11:13:07 +08:00
admin edb21d1a99 修改了资源路径3 2025-08-01 11:10:17 +08:00
admin fcf5a0e4eb 修改了资源路径2 2025-08-01 11:07:07 +08:00
admin a8c9f2126c 修改了资源路径1 2025-08-01 11:02:30 +08:00
admin 5c6718b905 修改了资源路径 2025-08-01 10:57:50 +08:00
admin b19c16e540 修改了医生的验证逻辑3344 2025-08-01 10:49:36 +08:00
admin eacc43c2d8 修改了医生的验证逻辑 2025-08-01 10:34:24 +08:00
admin 462318b5ec 修改了图片 2025-08-01 09:32:47 +08:00
admin 329d7c91ff 修改文章查询证书问题 2025-08-01 08:54:00 +08:00
admin 4930e7245f 修改了同步视频2 2025-08-01 08:42:18 +08:00
admin f2ede0d149 修改了同步视频1 2025-07-31 18:41:32 +08:00
admin 0a2457f3b2 修改了同步视频 2025-07-31 18:28:16 +08:00
admin f2581d421c 修改发放积分 2025-07-31 17:42:25 +08:00
admin 8b96dd8325 44444 2025-07-31 17:20:52 +08:00
admin f47161fcc8 11111 2025-07-31 16:51:37 +08:00
admin c2502c487d 修改列表查询12 2025-07-31 16:26:42 +08:00
admin ce9ef01888 修改列表查询1 2025-07-31 16:19:50 +08:00
admin b39a5c8e6e 修改列表查询 2025-07-31 16:18:20 +08:00
admin 206e7db697 修改评论的时区 2025-07-31 08:56:11 +08:00
admin fedd8a0465 修改浏览记录134 2025-07-31 08:51:41 +08:00
admin 1db0b3605b 修改浏览记录13 2025-07-31 08:49:57 +08:00
admin 6b380411c6 修改浏览记录1 2025-07-31 08:47:16 +08:00
admin bc44e11fd9 修改浏览记录 2025-07-31 08:44:42 +08:00
admin 2f0d44ae76 修改发放积分1 2025-07-30 19:20:31 +08:00
admin 8bd0cc1d28 修改发放积分 2025-07-30 19:19:15 +08:00
admin d30982b4d5 8797898989 2025-07-30 19:12:15 +08:00
admin 89dfc5575b 8888 2025-07-30 19:04:24 +08:00
admin a16995d845 56666 2025-07-30 18:48:21 +08:00
admin a344ece9fd 4555 2025-07-30 18:29:09 +08:00
admin a515bb3085 3333 2025-07-30 18:25:33 +08:00
admin 827f8ddc92 1111 2025-07-30 18:23:42 +08:00
admin 9964dccf68 删除评论 2025-07-30 18:22:11 +08:00
admin 0b8413ef79 44444 2025-07-30 17:35:42 +08:00
admin 23fd06cf99 222 2025-07-30 17:25:21 +08:00
admin 34aab6a66c 1 2025-07-30 17:23:34 +08:00
admin 7754370892 评论修改1111 2025-07-30 17:07:05 +08:00
admin 2e5a06f825 评论修改 2025-07-30 17:00:28 +08:00
admin 511ae5c374 5555 2025-07-30 16:53:02 +08:00
admin b165524210 4444 2025-07-30 16:50:16 +08:00
admin a14c951cac 1111 2025-07-30 16:48:44 +08:00
admin 046d7d9c74 登陆增加二次匹配 2025-07-30 16:26:46 +08:00
admin 0c18896fa2 4445 2025-07-30 15:58:06 +08:00
admin c46a83500a 111 2025-07-30 15:46:14 +08:00
admin 4a48ba3757 头像 2025-07-30 15:44:01 +08:00
admin e1f51949ed 445555 2025-07-30 15:29:25 +08:00
admin 2cdb0daf3d 456661233 2025-07-30 15:24:13 +08:00
admin cd5a008a36 45666 2025-07-30 15:22:46 +08:00
admin c1bfcc3840 67777 2025-07-30 15:12:54 +08:00
admin 2bf75f99a5 6666 2025-07-30 14:40:04 +08:00
admin f365725ddc 5555 2025-07-30 14:33:51 +08:00
admin d37e46e2a7 修改评论积分2 2025-07-30 14:30:45 +08:00
admin 4db0e612ab 修改评论积分1 2025-07-30 14:29:52 +08:00
admin dd04813211 修改评论积分 2025-07-30 14:23:46 +08:00
admin 9187b467ce 修正头像11445557777 2025-07-30 14:16:34 +08:00
admin dfab1ec324 修正头像1144555 2025-07-30 14:08:05 +08:00
admin 7997d0abe9 修正头像11111 2025-07-30 13:54:45 +08:00
admin 290e457977 修正头像1111 2025-07-30 13:52:49 +08:00
admin 5ef855aa2d 修正头像 2025-07-30 13:49:38 +08:00
admin 7f6dcd5061 修正头像 2025-07-30 13:00:25 +08:00
admin 667ffdb9ea 55556666 2025-07-30 11:53:00 +08:00
admin 2f92f54cb6 5555 2025-07-30 11:11:49 +08:00
admin 39e57c6fcc nihao1 2025-07-30 11:06:31 +08:00
admin b9be135a56 nihao 2025-07-30 10:58:37 +08:00
admin dd4db760f0 66664666678888 2025-07-30 10:55:17 +08:00
admin 00338d96e5 6666466667 2025-07-30 10:50:59 +08:00
admin 983ec56b9c 666646666 2025-07-30 10:48:11 +08:00
admin 1401671c28 66664 2025-07-30 10:34:42 +08:00
admin 6e076f2a37 6666 2025-07-30 10:30:44 +08:00
admin 3e4642d937 5555 2025-07-30 10:16:39 +08:00
admin 1bc315902f 新增了积分发放 2025-07-30 09:54:42 +08:00
admin cc7c07aa4a 修改了首页临床病例库的推荐 2025-07-29 15:58:07 +08:00
admin 7a752c3cc5 6666 2025-07-29 15:36:32 +08:00
admin 3fe8e3f807 5555 2025-07-29 15:34:31 +08:00
admin 07088b6919 3333 2025-07-29 15:31:34 +08:00
admin ca409dcac6 1111 2025-07-29 15:28:33 +08:00
admin dfce0a6b31 修改排序 2025-07-29 11:29:58 +08:00
admin 45682cac23 445555 2025-07-28 17:09:11 +08:00
admin 3f94685c77 334444 2025-07-28 16:56:40 +08:00
admin 72cc412f50 44444 2025-07-28 15:33:42 +08:00
admin 98449feef3 111 2025-07-28 15:24:12 +08:00
admin 2a68315cc8 修改限制数量1 2025-07-28 14:55:57 +08:00
admin 897b1c3cbe 修改限制数量 2025-07-28 14:46:51 +08:00
admin ec78f1167d 1234 2025-07-28 14:33:31 +08:00
admin 8d659750f7 修改时间排序 2025-07-28 14:17:04 +08:00
admin 98e7715481 111 2025-07-28 11:04:05 +08:00
admin cb10052615 1111 2025-07-28 11:01:20 +08:00
admin 209e52ff4c 新增了同步app视频,1 2025-07-28 09:22:33 +08:00
admin 6372a75c1c 新增了同步app视频, 2025-07-28 09:13:34 +08:00
admin 7b09f59b51 1111 2025-07-25 17:16:30 +08:00
admin 59de0d8ea1 数量为0的判断 2025-07-25 16:54:42 +08:00
admin cbe48f9780 详情页增加了删除状态的判断1 2025-07-25 16:11:47 +08:00
admin a88cdbe43f 详情页增加了删除状态的判断 2025-07-25 16:10:53 +08:00
admin 7d206deaac 病例交流修改的问题 2025-07-25 16:00:46 +08:00
admin d829af6ba0 病例交流列表去掉删除状态 2025-07-25 15:45:59 +08:00
admin d2cb421fa7 app接口。新增了两个接口1 2025-07-25 15:18:19 +08:00
admin 262e576192 app接口。新增了两个接口 2025-07-25 14:34:57 +08:00
admin cb6717e3fa 1 2025-07-24 10:13:54 +08:00
admin 862df3035c 病例交流列表 新增了评论排序 2025-07-22 15:55:45 +08:00
admin c5bc0920d3 病例交流列表2 2025-07-22 15:30:33 +08:00
admin 79ff5e6d10 病例交流列表1 2025-07-22 15:12:51 +08:00
admin 901af4db84 病例交流列表 2025-07-22 15:10:13 +08:00
admin 55f9b8f634 77777 2025-07-18 17:59:53 +08:00
admin 88ee5ad694 22222 2025-07-18 17:32:09 +08:00
admin 579c81e553 1111 2025-07-18 13:28:55 +08:00
admin f53e5b5d65 445555 2025-07-18 10:57:30 +08:00
admin 476dfb53e8 4444 2025-07-17 16:44:53 +08:00
admin 05b3f93703 1113333 2025-07-17 16:42:00 +08:00
admin 9f50e3eb5c 111 2025-07-17 16:04:00 +08:00
admin d99ecce3a4 时间排序 2025-07-17 15:25:53 +08:00
admin 69071077bd 登陆职称修改 2025-07-17 11:26:45 +08:00
admin 2753484bbb 修改了病例交流 2025-07-17 11:03:31 +08:00
admin 20571f6e9e 修改了疾病标签的搜索444 2025-07-16 17:21:48 +08:00
admin e3d7345221 修改了疾病标签的搜索3 2025-07-16 17:15:10 +08:00
admin d134ffd200 修改了疾病标签的搜索2 2025-07-16 17:09:00 +08:00
admin ac161b5bd4 修改了疾病标签的搜索1 2025-07-16 16:39:03 +08:00
admin 0675a7ea21 修改了疾病标签的搜索 2025-07-16 16:28:52 +08:00
admin b1fda37e38 增加了外联地址1 2025-07-16 16:08:31 +08:00
admin a4cd9317f0 增加了外联地址 2025-07-16 16:05:55 +08:00
admin 1064bc0b84 修改了评论1 2025-07-16 15:08:11 +08:00
admin 872598cffe 修改了评论 2025-07-16 13:37:36 +08:00
admin 6553531416 封装了统计字段 2025-06-18 11:54:39 +08:00
admin 61cef2f2a4 修正了登录 2025-06-18 10:56:40 +08:00
admin d4c2385179 修正数据库和互动病例保持一致 2025-06-17 17:17:45 +08:00
admin b449de8732 334444444 2025-06-17 16:12:28 +08:00
admin 3b8fd1e956 33444 2025-06-17 13:05:10 +08:00
admin 3243e23601 333 2025-06-17 11:58:37 +08:00
admin 5517e2c2f8 1 2025-06-17 11:56:27 +08:00
admin bedb39fc58 修改aliyunsdk版本 2025-06-17 11:49:14 +08:00
admin 588e896aff 白名单 2025-06-17 11:35:26 +08:00
admin d86125909a 处理了微信登录1 2025-06-17 11:27:34 +08:00
admin 6eab966eab 处理了微信登录 2025-06-17 11:26:54 +08:00
admin b516ddf5df 修改redis配置 2025-06-16 16:34:42 +08:00
admin db2e0d810a 11111 2025-06-16 16:11:20 +08:00
admin f618d8e733 oss签名修改 2025-06-16 16:05:36 +08:00
admin f70a495bb7 测试跨域 2025-06-16 10:12:29 +08:00
admin 75d13febeb 新增了hcp登录2 2025-06-16 09:42:48 +08:00
admin 72ebcefef7 新增了hcp登录1 2025-06-16 09:30:05 +08:00
admin 92d2483425 新增了hcp登录 2025-06-16 09:20:59 +08:00
114 changed files with 5778 additions and 462 deletions
+1 -1
View File
@@ -38,4 +38,4 @@ COPY --from=builder /app/target/caseData-1.0.0.jar app.jar
EXPOSE 5477
# 启动应用
ENTRYPOINT ["java", "-jar", "app.jar"]
ENTRYPOINT ["java", "-jar", "app.jar", "--spring.profiles.active=dev"]
+41
View File
@@ -0,0 +1,41 @@
# 第一阶段:构建 JAR 包
FROM maven:3.9.2-eclipse-temurin-17-alpine AS builder
WORKDIR /app
# 添加国内 Maven 镜像源
RUN mkdir -p /root/.m2 && \
echo '<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" \
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" \
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 \
https://maven.apache.org/xsd/settings-1.0.0.xsd"> \
<mirrors> \
<mirror> \
<id>aliyun</id> \
<mirrorOf>*</mirrorOf> \
<name>aliyun maven</name> \
<url>https://maven.aliyun.com/repository/public</url> \
</mirror> \
</mirrors> \
</settings>' > /root/.m2/settings.xml
# 将 pom.xml 和 src 目录复制到容器
COPY pom.xml .
COPY src ./src
# 执行 Maven 打包
RUN mvn clean package -DskipTests
# 第二阶段:运行镜像
FROM eclipse-temurin:17-jdk-alpine
WORKDIR /app
# 将构建好的 JAR 包从构建阶段复制到运行阶段
COPY --from=builder /app/target/caseData-1.0.0.jar app.jar
# 暴露端口
EXPOSE 5477
# 启动应用
ENTRYPOINT ["java", "-jar", "app.jar", "--spring.profiles.active=prod"]
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

+27
View File
@@ -98,6 +98,27 @@
<version>3.17.4</version>
</dependency>
<!-- 阿里云短信服务 SDK -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dysmsapi20170525</artifactId>
<version>2.0.23</version>
</dependency>
<!-- 阿里云 OpenAPI 基础依赖 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>tea-openapi</artifactId>
<version>0.2.6</version>
</dependency>
<!-- 阿里云 Tea 工具库 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>tea-util</artifactId>
<version>0.2.13</version>
</dependency>
<!-- JWT 解析库 -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
@@ -158,6 +179,12 @@
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
@@ -1,15 +1,20 @@
package com.example.caseData;
import jakarta.annotation.PostConstruct;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.TimeZone;
@SpringBootApplication
@MapperScan("com.example.caseData.dao")
public class CaseDataApplication {
public static void main(String[] args) {
// 设置 JVM 全局默认时区(建议与数据库一致,比如 "Asia/Shanghai")
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
SpringApplication.run(CaseDataApplication.class, args);
}
}
@@ -21,4 +21,7 @@ public class AppConfig {
@Value("${app.platformPointAccount}")
private String platformPointAccount;
@Value("${app.access-token}")
private String accessToken;
}
@@ -0,0 +1,16 @@
package com.example.caseData.config;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
@Getter
public class DySmsConfig {
@Value("${dysms.access-key}")
private String accessKey;
@Value("${dysms.access-secret}")
private String accessSecret;
}
@@ -0,0 +1,33 @@
package com.example.caseData.config;
import lombok.Getter;
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Value;
@Component
@Getter
public class RedisConfig {
@Value("${spring.redis.dev.host}")
private String devHost;
@Value("${spring.redis.dev.port}")
private int devPort;
@Value("${spring.redis.dev.password}")
private String devPassword;
@Value("${spring.redis.dev.database}")
private String devDatabase;
@Value("${spring.redis.prod.host}")
private String prodHost;
@Value("${spring.redis.prod.port}")
private int prodPort;
@Value("${spring.redis.prod.password}")
private String prodPassword;
@Value("${spring.redis.prod.database}")
private String prodDatabase;
}
@@ -59,6 +59,12 @@ public class CaseClinicalArticleController {
@Resource
private UserDao userDao;
@Resource
private StatsCaseClinicalDao statsCaseClinicalDao;
@Resource
private StatsCaseClinicalHospitalDao statsCaseClinicalHospitalDao;
/**
* 临床病例库-文章-详情
*/
@@ -73,6 +79,12 @@ public class CaseClinicalArticleController {
return Response.error("非法文章");
}
// 检测作品状态
boolean result = caseClinicalArticleService.checkClinicalArticleStatus(article);
if (!result){
return Response.error(201,null,"该作品已被删除");
}
// 查找作者
LambdaQueryWrapper<CaseClinicalArticleAuthorModel> authorQueryWrapper = new LambdaQueryWrapper<>();
authorQueryWrapper.eq(CaseClinicalArticleAuthorModel::getArticleId, article.getArticleId());
@@ -153,7 +165,7 @@ public class CaseClinicalArticleController {
* 临床病例库-文章-新增评论
*/
@PostMapping("/clinical/article/comment/{article_id}")
public Response<T> AddClinicalArticleComment(
public Response<Map<String, Object>> AddClinicalArticleComment(
@PathVariable("article_id") String articleId,
@Validated()
@RequestBody addClinicalArticleComment request
@@ -165,16 +177,16 @@ public class CaseClinicalArticleController {
return Response.error("操作失败");
}
Map<String, Object> resultData = new HashMap<>();
resultData.put("status", 1);
resultData.put("message", "成功");
try {
boolean res = caseClinicalArticleService.AddClinicalArticleComment(articleId,userId,request);
if (!res){
return Response.error("操作失败");
}
resultData = caseClinicalArticleService.AddClinicalArticleComment(articleId,userId,request);
return Response.success(200,resultData,"");
} catch (BusinessException e) {
return Response.error(e.getMessage());
}
return Response.success();
}
/**
@@ -188,13 +200,13 @@ public class CaseClinicalArticleController {
String userId = (String) httpServletRequest.getAttribute("userId");
if (userId == null) {
return Response.error("操作失败");
return Response.error("操作失败1");
}
try {
boolean res = caseClinicalArticleService.DeleteClinicalArticleComment(commentId,userId);
if (!res){
return Response.error("操作失败");
return Response.error("操作失败2");
}
} catch (BusinessException e) {
return Response.error(e.getMessage());
@@ -294,6 +306,9 @@ public class CaseClinicalArticleController {
return Response.error();
}
// 是否作者
int isAuthor = 0;
// 获取文章作者数据
LambdaQueryWrapper<CaseClinicalArticleAuthorModel> authorQueryWrapper = new LambdaQueryWrapper<>();
authorQueryWrapper.eq(CaseClinicalArticleAuthorModel::getArticleId, request.getArticleId());
@@ -306,18 +321,26 @@ public class CaseClinicalArticleController {
}
// 处理是否本人评论
for (UserCommentClinicalArticleDto dto : resultPage.getRecords()) {
if (Objects.equals(dto.getUserIden(), caseClinicalDoctor.getDoctorIden())){
dto.setIsAuthor(1);
}
if (Objects.equals(user.getUserIden(), caseClinicalDoctor.getDoctorIden())){
isAuthor = 1;
}
}
// 处理返回值
for (UserCommentClinicalArticleDto dto : resultPage.getRecords()) {
// 查询医生
LambdaQueryWrapper<CaseClinicalDoctorModel> doctorQueryWrapper = new LambdaQueryWrapper<>();
doctorQueryWrapper.eq(CaseClinicalDoctorModel::getDoctorIden, dto.getUserIden());
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectOne(doctorQueryWrapper);
if (caseClinicalDoctor != null) {
dto.setDoctorId(String.valueOf(caseClinicalDoctor.getDoctorId()));
}
// 去除用户唯一标识
dto.setUserIden(null);
dto.setAvatar(Replace.addOssDomain(dto.getAvatar()));
// 图片
dto.setCommentImage(Replace.addOssDomain(dto.getCommentImage()));
@@ -330,15 +353,35 @@ public class CaseClinicalArticleController {
5
);
for (UserCommentClinicalArticleDto subComment : subComments) {
// 查询医生
doctorQueryWrapper = new LambdaQueryWrapper<>();
doctorQueryWrapper.eq(CaseClinicalDoctorModel::getDoctorIden, subComment.getUserIden());
caseClinicalDoctor = caseClinicalDoctorDao.selectOne(doctorQueryWrapper);
if (caseClinicalDoctor != null) {
subComment.setDoctorId(String.valueOf(caseClinicalDoctor.getDoctorId()));
}
subComment.setAvatar(Replace.addOssDomain(subComment.getAvatar()));
subComment.setCommentImage(Replace.addOssDomain(subComment.getCommentImage()));
}
dto.setSubComment(subComments);
}
}
}
// 获取全部评论数
LambdaQueryWrapper<UserCommentClinicalArticleModel> aQueryWrapper = new LambdaQueryWrapper<>();
aQueryWrapper.eq(UserCommentClinicalArticleModel::getArticleId, request.getArticleId());
aQueryWrapper.eq(UserCommentClinicalArticleModel::getDeleteStatus, 0);
Long total = userCommentClinicalArticleDao.selectCount(aQueryWrapper);
resultMap.put("page", resultPage.getCurrent());
resultMap.put("pageSize", resultPage.getSize());
resultMap.put("total", resultPage.getTotal());
resultMap.put("total", total);
resultMap.put("data", resultPage.getRecords());
resultMap.put("is_author", isAuthor);
return Response.success(resultMap);
}
@@ -397,4 +440,5 @@ public class CaseClinicalArticleController {
return Response.success(resultMap);
}
}
@@ -14,6 +14,7 @@ import com.example.caseData.dto.userCommentClinicalVideo.UserCommentClinicalVide
import com.example.caseData.exception.BusinessException;
import com.example.caseData.model.*;
import com.example.caseData.request.CaseClinicalArticleRequest.getUserClinicalArticleCommentPage;
import com.example.caseData.request.CaseClinicalVideoRequest.addClinicalVideoApp;
import com.example.caseData.request.CaseClinicalVideoRequest.addClinicalVideoComment;
import com.example.caseData.request.CaseClinicalVideoRequest.getClinicalVideoCommentPage;
import com.example.caseData.service.CaseClinicalVideoService;
@@ -69,6 +70,12 @@ public class CaseClinicalVideoController {
return Response.error("非法视频");
}
// 检测作品状态
boolean result = caseClinicalVideoService.checkClinicalVideoStatus(video);
if (!result){
return Response.error(201,null,"该作品已被删除");
}
// 查找作者
LambdaQueryWrapper<CaseClinicalVideoAuthorModel> authorQueryWrapper = new LambdaQueryWrapper<>();
authorQueryWrapper.eq(CaseClinicalVideoAuthorModel::getVideoId, video.getVideoId());
@@ -149,7 +156,7 @@ public class CaseClinicalVideoController {
* 临床病例库-视频-新增评论
*/
@PostMapping("/clinical/video/comment/{video_id}")
public Response<T> AddClinicalVideoComment(
public Response<Map<String, Object>> AddClinicalVideoComment(
@PathVariable("video_id") String videoId,
@Validated()
@RequestBody addClinicalVideoComment request
@@ -161,16 +168,16 @@ public class CaseClinicalVideoController {
return Response.error("操作失败");
}
Map<String, Object> resultData = new HashMap<>();
resultData.put("status", 1);
resultData.put("message", "成功");
try {
boolean res = caseClinicalVideoService.AddClinicalVideoComment(videoId,userId,request);
if (!res){
return Response.error("操作失败");
}
resultData = caseClinicalVideoService.AddClinicalVideoComment(videoId,userId,request);
return Response.success(200,resultData,"");
} catch (BusinessException e) {
return Response.error(e.getMessage());
}
return Response.success();
}
/**
@@ -311,9 +318,19 @@ public class CaseClinicalVideoController {
// 处理返回值
for (UserCommentClinicalVideoDto dto : resultPage.getRecords()) {
// 查询医生
LambdaQueryWrapper<CaseClinicalDoctorModel> doctorQueryWrapper = new LambdaQueryWrapper<>();
doctorQueryWrapper.eq(CaseClinicalDoctorModel::getDoctorIden, dto.getUserIden());
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectOne(doctorQueryWrapper);
if (caseClinicalDoctor != null) {
dto.setDoctorId(String.valueOf(caseClinicalDoctor.getDoctorId()));
}
// 去除用户唯一标识
dto.setUserIden(null);
dto.setAvatar(Replace.addOssDomain(dto.getAvatar()));
// 图片
dto.setCommentImage(Replace.addOssDomain(dto.getCommentImage()));
@@ -326,14 +343,33 @@ public class CaseClinicalVideoController {
5
);
for (UserCommentClinicalVideoDto subComment : subComments) {
// 查询医生
doctorQueryWrapper = new LambdaQueryWrapper<>();
doctorQueryWrapper.eq(CaseClinicalDoctorModel::getDoctorIden, subComment.getUserIden());
caseClinicalDoctor = caseClinicalDoctorDao.selectOne(doctorQueryWrapper);
if (caseClinicalDoctor != null) {
subComment.setDoctorId(String.valueOf(caseClinicalDoctor.getDoctorId()));
}
subComment.setAvatar(Replace.addOssDomain(subComment.getAvatar()));
subComment.setCommentImage(Replace.addOssDomain(subComment.getCommentImage()));
}
dto.setSubComment(subComments);
}
}
}
// 获取全部评论数
LambdaQueryWrapper<UserCommentClinicalVideoModel> aQueryWrapper = new LambdaQueryWrapper<>();
aQueryWrapper.eq(UserCommentClinicalVideoModel::getVideoId, request.getVideoId());
aQueryWrapper.eq(UserCommentClinicalVideoModel::getDeleteStatus, 0);
Long total = userCommentClinicalVideoDao.selectCount(aQueryWrapper);
resultMap.put("page", resultPage.getCurrent());
resultMap.put("pageSize", resultPage.getSize());
resultMap.put("total", resultPage.getTotal());
resultMap.put("total", total);
resultMap.put("data", resultPage.getRecords());
return Response.success(resultMap);
}
@@ -392,4 +428,23 @@ public class CaseClinicalVideoController {
resultMap.put("data", resultPage.getRecords());
return Response.success(resultMap);
}
/**
* 临床病例库-视频-同步app视频
*/
@PostMapping("/app/clinical/video")
public Response<T> AddClinicalVideoApp(
HttpServletRequest request
) {
try {
boolean res = caseClinicalVideoService.AddClinicalVideoApp(request);
if (!res){
return Response.error("操作失败");
}
} catch (BusinessException e) {
return Response.error(e.getMessage());
}
return Response.success();
}
}
@@ -12,6 +12,7 @@ import com.example.caseData.dto.caseExchangeVote.CaseExchangeVoteDto;
import com.example.caseData.dto.caseExchangeVoteOption.CaseExchangeVoteOptionDto;
import com.example.caseData.dto.userCommentCaseExchange.GetUserCaseExchangeCommentPageDto;
import com.example.caseData.dto.userCommentCaseExchange.UserCommentCaseExchangeDto;
import com.example.caseData.dto.userCommentClinicalVideo.UserCommentClinicalVideoDto;
import com.example.caseData.exception.BusinessException;
import com.example.caseData.model.*;
import com.example.caseData.request.caseExchangeRequest.*;
@@ -62,6 +63,9 @@ public class CaseExchangeController {
@Resource
private UserCommentExchangeDao userCommentExchangeDao;
@Resource
private CaseClinicalDoctorDao caseClinicalDoctorDao;
/**
* 临床病例库-病例交流-搜索
*/
@@ -75,18 +79,6 @@ public class CaseExchangeController {
// 此步骤是为了在我的病例交流列表页面少查询
String userId = (String) httpServletRequest.getAttribute("userId");
if (userId != null) {
user = userDao.selectById(Long.valueOf(userId));
if (user == null) {
return Response.error();
}
// 获取当前用户所属医院
basicHospital = basicHospitalDao.selectById(user.getHospitalId());
if (basicHospital == null) {
return Response.error();
}
}
request.validateForPage();
@@ -94,20 +86,17 @@ public class CaseExchangeController {
Page<CaseExchangeDto> page = new Page<>(request.getPage(), request.getPageSize());
// 获取文章数据
// 获取数据
IPage<CaseExchangeDto> resultPage = caseExchangeDao.getCaseExchangeSearchPage(
page,
request.getKeyword(),
request.getUserId(),
request.getIsSelected(),
request.getLabelIden(),
request.handleOrder()
);
for (CaseExchangeDto dto : resultPage.getRecords()) {
// 内容
dto.setExchangeContent("");
dto.setExchangeSummary("");
// 处理预览视频
dto.setExchangeContentVideoString(dto.getExchangeContentVideoString());
@@ -119,9 +108,6 @@ public class CaseExchangeController {
dto.setExchangeContentImageString("");
dto.setExchangeContentVideoString("");
// 查找用户所属医院
if (userId != null){
if (!userId.equals(dto.getUserId())){
user = userDao.selectById(dto.getUserId());
if (user == null) {
return Response.error();
@@ -132,32 +118,16 @@ public class CaseExchangeController {
if (basicHospital == null) {
return Response.error();
}
}
}else{
user = userDao.selectById(dto.getUserId());
if (user == null) {
return Response.error();
}
// 获取当前用户所属医院
basicHospital = basicHospitalDao.selectById(user.getHospitalId());
if (basicHospital == null) {
return Response.error();
}
}
dto.setAvatar(Replace.addOssDomain(user.getAvatar()));
dto.setUserName(user.getUserName());
dto.setHospitalName(basicHospital.getHospitalName());
// 获取用户收藏状态
if (userId != null) {
// 检测用户是否已收藏过
UserCollectExchangeModel userCollectExchangeModel = caseExchangeService.getUserCollectExchangeStatus(dto.getExchangeId(),userId);
if (userCollectExchangeModel != null) {
dto.setCollect(true);
}
}
// 查找标签
LambdaQueryWrapper<CaseExchangeLabelModel> labelQueryWrapper = new LambdaQueryWrapper<>();
@@ -185,12 +155,18 @@ public class CaseExchangeController {
) {
String userId = (String) httpServletRequest.getAttribute("userId");
// 获取文章数据
// 获取数据
CaseExchangeModel caseExchange = caseExchangeDao.selectById(exchangeId);
if (caseExchange == null) {
return Response.error();
}
// 检测作品状态
boolean result = caseExchangeService.checkCaseExchangeStatus(caseExchange);
if (!result){
return Response.error(201,null,"该作品已被删除");
}
// 查找用户
UserModel user = userDao.selectById(caseExchange.getUserId());
if (user == null) {
@@ -282,7 +258,6 @@ public class CaseExchangeController {
}
}
return Response.success(g);
}
@@ -297,9 +272,10 @@ public class CaseExchangeController {
request.validateForLimit();
// 获取数据
List<CaseExchangeDto> caseExchanges = caseExchangeDao.getCaseExchangeSearchList(
List<CaseExchangeDto> caseExchanges = caseExchangeDao.getCaseExchangeSearchLimitList(
request.getLimit(),
request.getKeyword(),
null,
request.getIsSelected(),
request.handleOrder()
);
@@ -401,6 +377,60 @@ public class CaseExchangeController {
return Response.success();
}
/**
* 病例交流-修改
*/
@PutMapping("/exchange/{exchange_id}")
public Response<T> UpdateCaseExchange(
@Validated()
@RequestBody updateCaseExchange request,
@PathVariable("exchange_id") String exchangeId
) {
String userId = (String) httpServletRequest.getAttribute("userId");
if (userId == null) {
return Response.error("操作失败");
}
try {
boolean res = caseExchangeService.UpdateCaseExchange(userId,exchangeId,request);
if (!res){
return Response.error("操作失败");
}
} catch (BusinessException e) {
return Response.error(e.getMessage());
}
return Response.success();
}
/**
* 病例交流-删除
*/
@DeleteMapping("/exchange/{exchange_id}")
public Response<T> DeleteCaseExchange(
@PathVariable("exchange_id") String exchangeId
) {
String userId = (String) httpServletRequest.getAttribute("userId");
if (userId == null) {
return Response.error("操作失败");
}
try {
boolean res = caseExchangeService.DeleteCaseExchange(exchangeId,userId);
if (!res){
return Response.error("操作失败");
}
} catch (BusinessException e) {
return Response.error(e.getMessage());
}
return Response.success();
}
/**
* 病例交流-收藏
*/
@@ -449,7 +479,7 @@ public class CaseExchangeController {
* 病例交流-新增评论
*/
@PostMapping("/exchange/comment/{exchange_id}")
public Response<T> AddCaseExchangeComment(
public Response<Map<String, Object>> AddCaseExchangeComment(
@PathVariable("exchange_id") String exchangeId,
@Validated()
@RequestBody addCaseExchangeComment request
@@ -461,16 +491,16 @@ public class CaseExchangeController {
return Response.error("操作失败");
}
Map<String, Object> resultData = new HashMap<>();
resultData.put("status", 1);
resultData.put("message", "成功");
try {
boolean res = caseExchangeService.AddCaseExchangeComment(exchangeId,userId,request);
if (!res){
return Response.error("操作失败");
}
resultData = caseExchangeService.AddCaseExchangeComment(exchangeId,userId,request);
return Response.success(200,resultData,"");
} catch (BusinessException e) {
return Response.error(e.getMessage());
}
return Response.success();
}
/**
@@ -589,6 +619,17 @@ public class CaseExchangeController {
// 处理返回值
for (UserCommentCaseExchangeDto dto : resultPage.getRecords()) {
// 查询医生
LambdaQueryWrapper<CaseClinicalDoctorModel> doctorQueryWrapper = new LambdaQueryWrapper<>();
doctorQueryWrapper.eq(CaseClinicalDoctorModel::getDoctorIden, dto.getUserIden());
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectOne(doctorQueryWrapper);
if (caseClinicalDoctor != null) {
dto.setDoctorId(String.valueOf(caseClinicalDoctor.getDoctorId()));
}
dto.setAvatar(Replace.addOssDomain(dto.getAvatar()));
// 去除用户唯一标识
dto.setUserIden(null);
@@ -604,14 +645,33 @@ public class CaseExchangeController {
5
);
for (UserCommentCaseExchangeDto subComment : subComments) {
// 查询医生
doctorQueryWrapper = new LambdaQueryWrapper<>();
doctorQueryWrapper.eq(CaseClinicalDoctorModel::getDoctorIden, subComment.getUserIden());
caseClinicalDoctor = caseClinicalDoctorDao.selectOne(doctorQueryWrapper);
if (caseClinicalDoctor != null) {
subComment.setDoctorId(String.valueOf(caseClinicalDoctor.getDoctorId()));
}
subComment.setAvatar(Replace.addOssDomain(subComment.getAvatar()));
subComment.setCommentImage(Replace.addOssDomain(subComment.getCommentImage()));
}
dto.setSubComment(subComments);
}
}
}
// 获取全部评论数
LambdaQueryWrapper<UserCommentExchangeModel> aQueryWrapper = new LambdaQueryWrapper<>();
aQueryWrapper.eq(UserCommentExchangeModel::getExchangeId, request.getExchangeId());
aQueryWrapper.eq(UserCommentExchangeModel::getDeleteStatus, 0);
Long total = userCommentExchangeDao.selectCount(aQueryWrapper);
resultMap.put("page", resultPage.getCurrent());
resultMap.put("pageSize", resultPage.getSize());
resultMap.put("total", resultPage.getTotal());
resultMap.put("total", total);
resultMap.put("data", resultPage.getRecords());
return Response.success(resultMap);
}
@@ -46,6 +46,5 @@ public class CaseLabelController {
}
return Response.success(labelDtoList);
}
}
@@ -27,6 +27,7 @@ import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@RestController
@RequestMapping("/api")
@@ -70,7 +71,11 @@ public class ClinicalController extends BaseController {
@Resource
private StatsCaseClinicalLabelDao statsCaseClinicalLabelDao;
@Resource
private UserDao userDao;
@Resource
private CaseClinicalDoctorCertDao caseClinicalDoctorCertDao;
/**
* 临床病例库-搜索-文章
@@ -82,6 +87,12 @@ public class ClinicalController extends BaseController {
) {
String userId = (String) httpServletRequest.getAttribute("userId");
// 获取用户数据
UserModel user = userDao.selectById(userId);
if (user == null) {
return Response.error("错误");
}
request.validateForPage();
Map<String, Object> resultMap = new HashMap<>();
@@ -94,6 +105,8 @@ public class ClinicalController extends BaseController {
request.getKeyword(),
request.getHospitalId(),
request.getDoctorId(),
request.getLabelIden(),
request.getIsNeedLink(),
request.handleOrder()
);
@@ -106,6 +119,18 @@ public class ClinicalController extends BaseController {
// 查询医生
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectById(author.getDoctorId());
author.setCaseClinicalDoctor(caseClinicalDoctor);
if (Objects.equals(user.getUserIden(), caseClinicalDoctor.getDoctorIden())){
// 获取医生证书
LambdaQueryWrapper<CaseClinicalDoctorCertModel> certWrapper = new LambdaQueryWrapper<>();
certWrapper.eq(CaseClinicalDoctorCertModel::getDoctorId, caseClinicalDoctor.getDoctorId());
certWrapper.eq(CaseClinicalDoctorCertModel::getId, dto.getArticleId());
certWrapper.eq(CaseClinicalDoctorCertModel::getType, 1);
CaseClinicalDoctorCertModel caseClinicalDoctorCert = caseClinicalDoctorCertDao.selectOne(certWrapper);
if (caseClinicalDoctorCert != null){
dto.setCertImage(Replace.addOssDomain(caseClinicalDoctorCert.getCertImage()));
}
}
}
List<CaseClinicalArticleAuthorDto> caseClinicalArticleAuthorListDto = CaseClinicalArticleAuthorDto.GetListDto(caseClinicalArticleAuthors);
@@ -119,9 +144,6 @@ public class ClinicalController extends BaseController {
dto.setCollect(true);
}
}
// 证书图片
dto.setCertImage(Replace.addOssDomain(dto.getCertImage()));
}
if (request.getIsNeedNum() == 1){
@@ -129,7 +151,8 @@ public class ClinicalController extends BaseController {
Long searchVideoNum = caseClinicalVideoDao.getCaseClinicalVideoSearchCount(
request.getKeyword(),
request.getHospitalId(),
request.getDoctorId()
request.getDoctorId(),
request.getLabelIden()
);
resultMap.put("search_article_num", resultPage.getTotal());
@@ -154,6 +177,12 @@ public class ClinicalController extends BaseController {
) {
String userId = (String) httpServletRequest.getAttribute("userId");
// 获取用户数据
UserModel user = userDao.selectById(userId);
if (user == null) {
return Response.error("错误");
}
request.validateForPage();
Map<String, Object> resultMap = new HashMap<>();
@@ -166,6 +195,8 @@ public class ClinicalController extends BaseController {
request.getKeyword(),
request.getHospitalId(),
request.getDoctorId(),
request.getLabelIden(),
request.getIsNeedLink(),
request.handleOrder()
);
@@ -178,6 +209,18 @@ public class ClinicalController extends BaseController {
// 查询医生
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectById(author.getDoctorId());
author.setCaseClinicalDoctor(caseClinicalDoctor);
if (Objects.equals(user.getUserIden(), caseClinicalDoctor.getDoctorIden())){
// 获取医生证书
LambdaQueryWrapper<CaseClinicalDoctorCertModel> certWrapper = new LambdaQueryWrapper<>();
certWrapper.eq(CaseClinicalDoctorCertModel::getDoctorId, caseClinicalDoctor.getDoctorId());
certWrapper.eq(CaseClinicalDoctorCertModel::getId, dto.getVideoId());
certWrapper.eq(CaseClinicalDoctorCertModel::getType, 2);
CaseClinicalDoctorCertModel caseClinicalDoctorCert = caseClinicalDoctorCertDao.selectOne(certWrapper);
if (caseClinicalDoctorCert != null){
dto.setCertImage(Replace.addOssDomain(caseClinicalDoctorCert.getCertImage()));
}
}
}
List<CaseClinicalVideoAuthorDto> caseClinicalVideoAuthorListDto = CaseClinicalVideoAuthorDto.GetListDto(caseClinicalVideoAuthors);
@@ -191,9 +234,6 @@ public class ClinicalController extends BaseController {
dto.setCollect(true);
}
}
// 证书图片
dto.setCertImage(Replace.addOssDomain(dto.getCertImage()));
}
if (request.getIsNeedNum() == 1){
@@ -201,7 +241,8 @@ public class ClinicalController extends BaseController {
Long searchArticleNum = caseClinicalArticleDao.getCaseClinicalArticleSearchCount(
request.getKeyword(),
request.getHospitalId(),
request.getDoctorId()
request.getDoctorId(),
request.getLabelIden()
);
resultMap.put("search_article_num", searchArticleNum);
@@ -315,6 +356,4 @@ public class ClinicalController extends BaseController {
resultMap.put("data", resultPage.getRecords());
return Response.success(resultMap);
}
}
@@ -1,24 +1,38 @@
package com.example.caseData.controller;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import com.example.caseData.common.Response;
import com.example.caseData.config.EnvConfig;
import com.example.caseData.dto.T;
import com.example.caseData.dto.publicDto.GetOssSignDto;
import com.example.caseData.dto.publicDto.LoginDto;
import com.example.caseData.dto.user.UserDto;
import com.example.caseData.exception.BusinessException;
import com.example.caseData.extend.aliyun.DySms;
import com.example.caseData.extend.aliyun.Oss;
import com.example.caseData.request.publicRequest.GetOssSignRequest;
import com.example.caseData.request.publicRequest.LoginRequest;
import com.example.caseData.extend.weChat.WxMaServiceUtils;
import com.example.caseData.request.publicRequest.*;
import com.example.caseData.request.UserRequest.UserRequest;
import com.example.caseData.service.UserService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.time.Duration;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
@RequiredArgsConstructor
@RestController
@RequestMapping("/api")
@Slf4j
public class PublicController {
@Resource
private UserService userService;
@@ -29,20 +43,91 @@ public class PublicController {
@Resource
private EnvConfig envConfig;
private final WxMaServiceUtils wxMaServiceUtils;
@Resource
private RedisTemplate<String, String> redisTemplate;
@Resource
private DySms dySms;
// 登陆
@PostMapping("/login/wechat/mobile")
public Response<LoginDto> login(@Validated({LoginRequest.Login.class}) @ModelAttribute LoginRequest request) {
public Response<LoginDto> loginWechatMobile(@Validated({LoginRequest.Login.class}) @ModelAttribute LoginRequest request) {
// 微信手机号授权登录
try {
// 获取手机号
// 获取用户openid
WxMaPhoneNumberInfo phoneInfo = wxMaServiceUtils.getPhoneNumber(request.getPhone_code());
if (phoneInfo == null) {
return Response.error("微信授权失败");
}
// 临时测试使用
String phone = "18221234167";
if (phoneInfo.getPurePhoneNumber() == null) {
return Response.error("微信授权失败");
}
// 获取用户openid
WxMaJscode2SessionResult wxInfoData = wxMaServiceUtils.getSessionInfo(request.getWx_code());
if (wxInfoData == null) {
return Response.error("微信授权失败");
}
if (wxInfoData.getOpenid() == null) {
return Response.error("微信授权失败");
}
if (wxInfoData.getSessionKey() == null) {
return Response.error("微信授权失败");
}
Map resultMap = userService.getAppUser(phoneInfo.getPurePhoneNumber());
log.info(resultMap.toString());
// 取出code
Integer code = (Integer) resultMap.get("code");
if (code != 200){
String msg = (String) resultMap.get("msg");
if (msg != null && !msg.isEmpty()){
return Response.error(code,null,msg);
}
return Response.error(code,null,"登陆失败");
}
// 用户登陆
LoginDto g = userService.UserLogin(phone);
LoginDto g = userService.UserLoginWithMobile(phoneInfo.getPurePhoneNumber());
return Response.success(g);
} catch (Exception e) {
if (Objects.equals(e.getMessage(), "请耐心等待审核")){
return Response.error(10005,null,e.getMessage());
}
if (Objects.equals(e.getMessage(), "待补充资料")){
return Response.error(10007,null,e.getMessage());
}
return Response.error(e.getMessage());
}
}
// 登陆
@PostMapping("/login/hcp")
public Response<LoginDto> loginHcp(@Validated() @ModelAttribute LoginHcpRequest request) {
try {
// 用户登陆
LoginDto g = userService.UserLoginWithApp(request.getToken());
return Response.success(g);
} catch (Exception e) {
if (Objects.equals(e.getMessage(), "请耐心等待审核")){
return Response.error(10005,null,e.getMessage());
}
if (Objects.equals(e.getMessage(), "待补充资料")){
return Response.error(10007,null,e.getMessage());
}
// if (Objects.equals(e.getMessage(), "没有HCP权限")){
// return Response.error(405,null,e.getMessage());
// }
return Response.error(e.getMessage());
}
}
// 获取签名
@@ -58,10 +143,126 @@ public class PublicController {
ossPath = "prod/";
}
if (request.getScene() == 1){
ossPath = ossPath + "static/images/exchange/";
}else if (request.getScene() == 2){
ossPath = ossPath + "static/video/exchange/";
}else{
return Response.error();
}
// 生成签名
GetOssSignDto g = Oss.getOssSign(ossPath);
return Response.success(g);
}
// 获取验证码
@PostMapping("/code/phone")
public Response<T> GetPhoneCode(@Validated() @ModelAttribute GetPhoneCodeRequest request) {
String templateCode = "";
String scene = "注册验证码";
// 手机号登录
if (request.getScene() == 1){
templateCode = "SMS_215344868";
scene = "注册验证码";
}
// 限流 key
String limitKey = "sms:limit:" + request.getPhone();
// 验证码缓存 key
String codeKey = "sms:code:" + request.getPhone();
// 获取当前请求次数
String countStr = redisTemplate.opsForValue().get(limitKey);
int count = countStr != null ? Integer.parseInt(countStr) : 0;
if (count > 3) {
return Response.error("验证码请求过于频繁,请稍后再试");
}
// 生成 4 位数字验证码
String code = String.format("%04d", new Random().nextInt(10000));
try {
dySms.sendSms(
request.getPhone(),
templateCode,
scene,
Map.of("code", code)
);
} catch (Exception e) {
return Response.error(e.getMessage());
}
// 缓存验证码(有效期 5 分钟)
redisTemplate.opsForValue().set(codeKey, code, Duration.ofMinutes(5));
// 缓存请求次数
if (count == 0) {
// 初次请求,设置有效期为 5 分钟
redisTemplate.opsForValue().set(limitKey, "1", Duration.ofMinutes(5));
} else {
redisTemplate.opsForValue().increment(limitKey);
}
return Response.success();
}
// 登陆
@PostMapping("/login/mobile")
public Response<LoginDto> loginPhone(@Validated() @ModelAttribute LoginPhoneRequest request) {
// 验证码缓存 key
if (!Objects.equals(envConfig.getActive(), "dev")){
String codeKey = "sms:code:" + request.getPhone();
String code = redisTemplate.opsForValue().get(codeKey);
if (!Objects.equals(request.getCode(), code)){
return Response.error("验证码错误");
}
}
try {
// 获取用户openid
WxMaJscode2SessionResult wxInfoData = wxMaServiceUtils.getSessionInfo(request.getWx_code());
if (wxInfoData == null) {
return Response.error("微信授权失败");
}
if (wxInfoData.getOpenid() == null) {
return Response.error("微信授权失败");
}
if (wxInfoData.getSessionKey() == null) {
return Response.error("微信授权失败");
}
Map resultMap = userService.getAppUser(request.getPhone());
// 取出code
Integer code = (Integer) resultMap.get("code");
if (code != 200){
String msg = (String) resultMap.get("msg");
if (msg != null && !msg.isEmpty()){
return Response.error(code,null,msg);
}
return Response.error(code,null,"登陆失败");
}
// 用户登陆
LoginDto g = userService.UserLoginWithMobile(request.getPhone());
return Response.success(g);
} catch (Exception e) {
if (Objects.equals(e.getMessage(), "请耐心等待审核")){
return Response.error(10005,null,e.getMessage());
}
if (Objects.equals(e.getMessage(), "待补充资料")){
return Response.error(10007,null,e.getMessage());
}
return Response.error(e.getMessage());
}
}
}
@@ -2,10 +2,10 @@ package com.example.caseData.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.caseData.common.Response;
import com.example.caseData.dao.StatsCaseClinicalDao;
import com.example.caseData.dao.StatsCaseClinicalDoctorDao;
import com.example.caseData.dao.StatsCaseClinicalHospitalDao;
import com.example.caseData.dao.StatsCaseClinicalLabelDao;
import com.example.caseData.dao.*;
import com.example.caseData.dto.caseClinicalArticle.CaseClinicalArticleDto;
import com.example.caseData.dto.caseClinicalVideo.CaseClinicalVideoDto;
import com.example.caseData.dto.caseExchange.CaseExchangeDto;
import com.example.caseData.dto.statsCaseClinical.StatsCaseClinicalDto;
import com.example.caseData.dto.statsCaseClinicalDoctor.StatsCaseClinicalDoctorDto;
import com.example.caseData.dto.statsCaseClinicalHospital.StatsCaseClinicalHospitalDto;
@@ -17,6 +17,8 @@ import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api")
public class StatsCaseClinicalController extends BaseController {
@@ -32,6 +34,12 @@ public class StatsCaseClinicalController extends BaseController {
@Resource
private StatsCaseClinicalLabelDao statsCaseClinicalLabelDao;
@Resource
private CaseClinicalArticleDao caseClinicalArticleDao;
@Resource
private CaseClinicalVideoDao caseClinicalVideoDao;
/**
* 临床病例库-统计
*/
@@ -47,6 +55,19 @@ public class StatsCaseClinicalController extends BaseController {
return Response.success(new StatsCaseClinicalDto());
}
Long articleReadNum = caseClinicalArticleDao.getTotalReadNum();
if (articleReadNum == null){
articleReadNum = 0L;
}
Long videoReadNum = caseClinicalVideoDao.getTotalReadNum();
if (videoReadNum == null){
videoReadNum = 0L;
}
g.setArticleReadNum(Math.toIntExact(articleReadNum));
g.setVideoReadNum(Math.toIntExact(videoReadNum));
return Response.success(g);
}
@@ -58,17 +79,41 @@ public class StatsCaseClinicalController extends BaseController {
@PathVariable("hospital_id") String hospitalId
){
// 统计表-病例库-临床
LambdaQueryWrapper<StatsCaseClinicalHospitalModel> statsCaseClinicalHospitalQueryWrapper = new LambdaQueryWrapper<>();
statsCaseClinicalHospitalQueryWrapper.eq(StatsCaseClinicalHospitalModel::getHospitalId, hospitalId);
StatsCaseClinicalHospitalModel statsCaseClinicalHospital = statsCaseClinicalHospitalDao.selectOne(statsCaseClinicalHospitalQueryWrapper);
Integer articleReadNum = 0;
Integer videoReadNum = 0;
StatsCaseClinicalHospitalDto g = StatsCaseClinicalHospitalDto.GetDto(statsCaseClinicalHospital);
if (g == null){
return Response.success(new StatsCaseClinicalHospitalDto());
// 获取该标签下文章数据
List<CaseClinicalArticleDto> caseClinicalArticles = caseClinicalArticleDao.getCaseClinicalArticleSearchList(
"",
hospitalId,
"",
"",
null
);
for (CaseClinicalArticleDto article : caseClinicalArticles){
articleReadNum += article.getReadNum();
}
// 获取该标签下视频数据
List<CaseClinicalVideoDto> caseClinicalVideos = caseClinicalVideoDao.getCaseClinicalVideoSearchList(
"",
hospitalId,
"",
"",
null
);
for (CaseClinicalVideoDto video : caseClinicalVideos){
videoReadNum += video.getReadNum();
}
StatsCaseClinicalHospitalDto g = new StatsCaseClinicalHospitalDto();
g.setStatsId("1");
g.setArticleNum(caseClinicalArticles.size());
g.setArticleReadNum(articleReadNum);
g.setVideoNum(caseClinicalVideos.size());
g.setVideoReadNum(videoReadNum);
return Response.success(g);
}
@@ -79,17 +124,41 @@ public class StatsCaseClinicalController extends BaseController {
public Response<StatsCaseClinicalDoctorDto> getClinicalStatsDoctor(
@PathVariable("doctor_id") String doctorId
){
// 统计表-病例库-临床
LambdaQueryWrapper<StatsCaseClinicalDoctorModel> statsCaseClinicalDoctorQueryWrapper = new LambdaQueryWrapper<>();
statsCaseClinicalDoctorQueryWrapper.eq(StatsCaseClinicalDoctorModel::getDoctorId, doctorId);
StatsCaseClinicalDoctorModel statsCaseClinicalDoctor = statsCaseClinicalDoctorDao.selectOne(statsCaseClinicalDoctorQueryWrapper);
Integer articleReadNum = 0;
Integer videoReadNum = 0;
StatsCaseClinicalDoctorDto g = StatsCaseClinicalDoctorDto.GetDto(statsCaseClinicalDoctor);
if (g == null){
return Response.success(new StatsCaseClinicalDoctorDto());
// 获取该标签下文章数据
List<CaseClinicalArticleDto> caseClinicalArticles = caseClinicalArticleDao.getCaseClinicalArticleSearchList(
"",
"",
doctorId,
"",
null
);
for (CaseClinicalArticleDto article : caseClinicalArticles){
articleReadNum += article.getReadNum();
}
// 获取该标签下视频数据
List<CaseClinicalVideoDto> caseClinicalVideos = caseClinicalVideoDao.getCaseClinicalVideoSearchList(
"",
"",
doctorId,
"",
null
);
for (CaseClinicalVideoDto video : caseClinicalVideos){
videoReadNum += video.getReadNum();
}
StatsCaseClinicalDoctorDto g = new StatsCaseClinicalDoctorDto();
g.setStatsId("1");
g.setArticleNum(caseClinicalArticles.size());
g.setArticleReadNum(articleReadNum);
g.setVideoNum(caseClinicalVideos.size());
g.setVideoReadNum(videoReadNum);
return Response.success(g);
}
@@ -100,17 +169,41 @@ public class StatsCaseClinicalController extends BaseController {
public Response<StatsCaseClinicalLabelDto> getClinicalStatsLabel(
@Validated() @ModelAttribute getClinicalStatsLabel request
){
// 统计表-病例库-临床
LambdaQueryWrapper<StatsCaseClinicalLabelModel> statsCaseClinicalLabelQueryWrapper = new LambdaQueryWrapper<>();
statsCaseClinicalLabelQueryWrapper.eq(StatsCaseClinicalLabelModel::getLabelIden, request.getLabel_iden());
StatsCaseClinicalLabelModel statsCaseClinicalLabel = statsCaseClinicalLabelDao.selectOne(statsCaseClinicalLabelQueryWrapper);
Integer articleReadNum = 0;
Integer videoReadNum = 0;
StatsCaseClinicalLabelDto g = StatsCaseClinicalLabelDto.GetDto(statsCaseClinicalLabel);
if (g == null){
return Response.success(new StatsCaseClinicalLabelDto());
// 获取该标签下文章数据
List<CaseClinicalArticleDto> caseClinicalArticles = caseClinicalArticleDao.getCaseClinicalArticleSearchList(
"",
"",
"",
request.getLabel_iden(),
null
);
for (CaseClinicalArticleDto article : caseClinicalArticles){
articleReadNum += article.getReadNum();
}
// 获取该标签下视频数据
List<CaseClinicalVideoDto> caseClinicalVideos = caseClinicalVideoDao.getCaseClinicalVideoSearchList(
"",
"",
"",
request.getLabel_iden(),
null
);
for (CaseClinicalVideoDto video : caseClinicalVideos){
videoReadNum += video.getReadNum();
}
StatsCaseClinicalLabelDto g = new StatsCaseClinicalLabelDto();
g.setStatsId("1");
g.setArticleNum(caseClinicalArticles.size());
g.setArticleReadNum(articleReadNum);
g.setVideoNum(caseClinicalVideos.size());
g.setVideoReadNum(videoReadNum);
return Response.success(g);
}
}
@@ -2,9 +2,12 @@ package com.example.caseData.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.caseData.common.Response;
import com.example.caseData.dao.CaseExchangeDao;
import com.example.caseData.dao.StatsCaseExchangeDao;
import com.example.caseData.dao.StatsCaseExchangeUserDao;
import com.example.caseData.dao.StatsCaseExchangeUserDao;
import com.example.caseData.dto.caseClinicalArticle.CaseClinicalArticleDto;
import com.example.caseData.dto.caseExchange.CaseExchangeDto;
import com.example.caseData.dto.statsCaseClinical.StatsCaseClinicalDto;
import com.example.caseData.dto.statsCaseExchange.StatsCaseExchangeDto;
import com.example.caseData.dto.statsCaseExchange.StatsCaseExchangeDto;
@@ -18,12 +21,17 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/api")
public class StatsCaseExchangeController extends BaseController {
@Resource
private StatsCaseExchangeDao statsCaseExchangeDao;
@Resource
private CaseExchangeDao caseExchangeDao;
@Resource
private StatsCaseExchangeUserDao statsCaseExchangeUserDao;
@@ -43,6 +51,14 @@ public class StatsCaseExchangeController extends BaseController {
if (g == null){
return Response.success(new StatsCaseExchangeDto());
}
Long totalCommentNum = caseExchangeDao.getTotalCommentNum();
if (totalCommentNum == null){
totalCommentNum = 0L;
}
g.setExchangeCommentNum(Math.toIntExact(totalCommentNum));
return Response.success(g);
}
@@ -52,7 +68,7 @@ public class StatsCaseExchangeController extends BaseController {
@GetMapping("/exchange/stats/user")
public Response<StatsCaseExchangeUserDto> getClinicalStatsUser(){
String userId = (String) httpServletRequest.getAttribute("userId");
if (userId != null) {
if (userId == null) {
return Response.error();
}
@@ -65,6 +81,21 @@ public class StatsCaseExchangeController extends BaseController {
return Response.success(new StatsCaseExchangeUserDto());
}
Integer readNum = 0;
// 获取该标签下文章数据
List<CaseExchangeDto> caseExchanges = caseExchangeDao.getCaseExchangeSearchList(
"",
userId,
null,
null
);
for (CaseExchangeDto caseExchange : caseExchanges){
readNum += caseExchange.getReadNum();
}
g.setExchangeReadNum(readNum);
return Response.success(g);
}
}
@@ -114,32 +114,30 @@ public class UserCaseReadController extends BaseController {
resultMap.put("data", resultPage.getRecords());
}else if (request.getType() == 2){
// 视频
Page<UserCollectClinicalVideoDto> page = new Page<>(request.getPage(), request.getPageSize());
Page<UserCaseReadDto> page = new Page<>(request.getPage(), request.getPageSize());
// 获取文章数据
IPage<UserCollectClinicalVideoDto> resultPage = userCollectClinicalVideoDao.getUserCollectClinicalVideoSearchPage(
IPage<UserCaseReadDto> resultPage = userCaseReadDao.getUserCaseReadVideoSearchPage(
page,
request.getKeyword(),
request.getHospitalId(),
request.getDoctorId(),
userId
);
for (UserCollectClinicalVideoDto dto : resultPage.getRecords()) {
UserCollectClinicalVideoDto.DataDto data = dto.getData();
List<UserCollectClinicalVideoDto.DataAuthorDto> dataAuthors = new ArrayList<>();
for (UserCaseReadDto dto : resultPage.getRecords()) {
UserCaseReadDto.DataDto data = dto.getData();
List<UserCaseReadDto.DataAuthorDto> dataAuthors = new ArrayList<>();
// 查找作者
LambdaQueryWrapper<CaseClinicalVideoAuthorModel> authorQueryWrapper = new LambdaQueryWrapper<>();
authorQueryWrapper.eq(CaseClinicalVideoAuthorModel::getVideoId, dto.getId());
List<CaseClinicalVideoAuthorModel> caseClinicalVideoAuthors = caseClinicalVideoAuthorDao.selectList(authorQueryWrapper);
for (CaseClinicalVideoAuthorModel author : caseClinicalVideoAuthors) {
UserCollectClinicalVideoDto.DataAuthorDto dataAuthor = new UserCollectClinicalVideoDto.DataAuthorDto();
UserCaseReadDto.DataAuthorDto dataAuthor = new UserCaseReadDto.DataAuthorDto();
// 查询医生
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectById(author.getDoctorId());
dataAuthor.setDoctorName(caseClinicalDoctor.getDoctorName());
dataAuthors.add(dataAuthor);
}
@@ -152,20 +150,18 @@ public class UserCaseReadController extends BaseController {
resultMap.put("data", resultPage.getRecords());
} else if (request.getType() == 3) {
// 病例交流
Page<UserCollectExchangeDto> page = new Page<>(request.getPage(), request.getPageSize());
Page<UserCaseReadDto> page = new Page<>(request.getPage(), request.getPageSize());
// 获取文章数据
IPage<UserCollectExchangeDto> resultPage = userCollectExchangeDao.getUserCollectExchangeSearchPage(
IPage<UserCaseReadDto> resultPage = userCaseReadDao.getUserCaseReadExchangeSearchPage(
page,
request.getKeyword(),
request.getHospitalId(),
request.getDoctorId(),
userId
);
for (UserCollectExchangeDto dto : resultPage.getRecords()) {
UserCollectExchangeDto.DataDto data = dto.getData();
List<UserCollectExchangeDto.DataAuthorDto> dataAuthors = new ArrayList<>();
for (UserCaseReadDto dto : resultPage.getRecords()) {
UserCaseReadDto.DataDto data = dto.getData();
List<UserCaseReadDto.DataAuthorDto> dataAuthors = new ArrayList<>();
UserModel user = userDao.selectById(Long.valueOf(userId));
if (user == null) {
@@ -178,7 +174,7 @@ public class UserCaseReadController extends BaseController {
return Response.error();
}
UserCollectExchangeDto.DataAuthorDto dataAuthor = new UserCollectExchangeDto.DataAuthorDto();
UserCaseReadDto.DataAuthorDto dataAuthor = new UserCaseReadDto.DataAuthorDto();
dataAuthor.setDoctorName(user.getUserName());
dataAuthor.setHospitalName(basicHospital.getHospitalName());
dataAuthors.add(dataAuthor);
@@ -207,14 +203,13 @@ public class UserCaseReadController extends BaseController {
@RequestBody addUserCaseRead request
) {
String userId = (String) httpServletRequest.getAttribute("userId");
if (userId == null) {
String loginUserId = (String) httpServletRequest.getAttribute("userId");
if (loginUserId == null) {
return Response.error("操作失败");
}
try {
boolean res = userCaseReadService.AddUserCaseRead(request,userId);
boolean res = userCaseReadService.AddUserCaseRead(request,loginUserId);
if (!res){
return Response.error("操作失败");
}
@@ -9,13 +9,19 @@ import com.example.caseData.exception.BusinessException;
import com.example.caseData.extend.app.UserPoint.UserPoint;
import com.example.caseData.extend.app.UserPoint.UserPointResponse;
import com.example.caseData.model.*;
import com.example.caseData.request.CaseClinicalArticleRequest.addClinicalArticleComment;
import com.example.caseData.request.UserRequest.ReportUserScoreRequest;
import com.example.caseData.request.UserRequest.UserRequest;
import com.example.caseData.service.CertService;
import com.example.caseData.service.RewardPointService;
import com.example.caseData.service.UserService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.time.Year;
@RestController
@RequestMapping("/api")
public class UserController extends BaseController {
@@ -55,6 +61,12 @@ public class UserController extends BaseController {
@Resource
private UserPoint userPoint;
@Resource
private UserService userService;
@Resource
private CertService certService;
// // 查询所有用户
// @GetMapping("/users")
// public Response<Map<String, Object>> getUserPage(@Validated({UserRequest.Page.class}) @ModelAttribute UserRequest request) {
@@ -149,4 +161,30 @@ public class UserController extends BaseController {
return Response.success(point);
}
@GetMapping("/user/test")
public Response<T> getUser() {
try {
// 生成证书
/* byte[] qrCodeByte = new byte[0];
// 生成证书
String avt = "src/main/resources/static/cert/avt.png";
String sealPath = "src/main/resources/static/cert/seal.png";
String certificateNo = "GDXZALK" + String.valueOf(Year.now().getValue()) + "123456";
String name = "吴从兴";
String content = "您的案例《儿童肾上腺危象一例》经评议,被肝胆相照临床病例库收录,特发此";
certService.createCertTest(sealPath,certificateNo,name,content);
// 生成用户分享二维码-文章/视频
// userService.CreateUserCaseClinicalContentUnlimitedQrcode(String.valueOf(1),1);*/
// 重新计算标签数量
} catch (Exception e) {
return Response.error(e.getMessage());
}
return Response.success();
}
}
@@ -3,26 +3,44 @@ package com.example.caseData.core;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.NonNull;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.Arrays;
@Configuration
public class CorsConfig {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(@NonNull CorsRegistry registry) {
registry.addMapping("/**") // 允许所有路径
.allowedOriginPatterns("*") // 允许所有来源(Spring 2.4+ 用 `allowedOriginPatterns`)
.allowedMethods("POST", "GET", "OPTIONS", "PUT", "DELETE", "UPDATE") // 允许的 HTTP 方法
.allowedHeaders("Origin", "X-Requested-With", "Content-Type", "Accept", "Authorization") // 允许的请求头
.exposedHeaders("Content-Length", "Access-Control-Allow-Origin",
"Access-Control-Allow-Headers", "Cache-Control",
"Content-Language", "Content-Type") // 允许前端访问的响应头
.allowCredentials(false); // 是否允许携带 Cookie
}
};
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
// 允许所有来源(与 Gin 中的动态 Origin 等价)
config.addAllowedOriginPattern("*");
// 允许的请求方法
config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS", "UPDATE"));
// 允许的请求头
config.setAllowedHeaders(Arrays.asList(
"Origin", "X-Requested-With", "Content-Type", "Accept", "Authorization"
));
// 暴露哪些响应头给前端
config.setExposedHeaders(Arrays.asList(
"Content-Length", "Access-Control-Allow-Origin", "Access-Control-Allow-Headers",
"Cache-Control", "Content-Language", "Content-Type"
));
// 是否允许携带 Cookie 等认证信息(Gin 里是 false)
config.setAllowCredentials(false);
// 注册跨域配置
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
@@ -5,14 +5,17 @@ import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.ZoneId;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
private static final ZoneId BEIJING_ZONE = ZoneId.of("Asia/Shanghai");
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createdAt", LocalDateTime.class, LocalDateTime.now());
this.strictInsertFill(metaObject, "updatedAt", LocalDateTime.class, LocalDateTime.now());
this.strictInsertFill(metaObject, "createdAt", LocalDateTime.class, LocalDateTime.now(BEIJING_ZONE));
this.strictInsertFill(metaObject, "updatedAt", LocalDateTime.class, LocalDateTime.now(BEIJING_ZONE));
}
@Override
@@ -1,26 +0,0 @@
package com.example.caseData.core;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
// 使用String序列化方式
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
template.setValueSerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setHashValueSerializer(stringRedisSerializer);
return template;
}
}
@@ -0,0 +1,63 @@
package com.example.caseData.core;
import com.example.caseData.config.RedisConfig;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@RequiredArgsConstructor
public class RedisConfiguration {
private final RedisConfig redisConfig; // 自动注入你的配置类
@Bean
@Qualifier("redisTemplate")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
// 使用String序列化方式
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
template.setValueSerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setHashValueSerializer(stringRedisSerializer);
return template;
}
@Bean
@Qualifier("prodRedisTemplate")
public RedisTemplate<String, Object> prodRedisTemplate(RedisConnectionFactory connectionFactory) {
RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
configuration.setHostName(redisConfig.getProdHost());
configuration.setPort(redisConfig.getProdPort());
configuration.setDatabase(Integer.parseInt(redisConfig.getProdDatabase()));
if (redisConfig.getProdPassword() != null && !redisConfig.getProdPassword().isEmpty()) {
configuration.setPassword(RedisPassword.of(redisConfig.getProdPassword()));
}
LettuceConnectionFactory factory = new LettuceConnectionFactory(configuration);
factory.afterPropertiesSet();
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 使用String序列化方式
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
template.setValueSerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setHashValueSerializer(stringRedisSerializer);
return template;
}
}
@@ -9,6 +9,8 @@ import com.example.caseData.model.CaseClinicalArticleModel;
import org.apache.ibatis.annotations.*;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@Mapper
@@ -24,9 +26,25 @@ public interface CaseClinicalArticleDao extends BaseMapper<CaseClinicalArticleMo
@Param("keyword") String keyword,
@Param("hospitalId") String hospitalId,
@Param("doctorId") String doctorId,
@Param("labelIden") String labelIden,
@Param("isNeedLink") Integer isNeedLink,
@Param("order") Map<String, String> order
);
/**
* 临床病例库-搜索
* @param keyword 搜索关键词-标题/医生名称/标签名称
* @param order 排序
*/
List<CaseClinicalArticleDto> getCaseClinicalArticleSearchList(
@Param("keyword") String keyword,
@Param("hospitalId") String hospitalId,
@Param("doctorId") String doctorId,
@Param("labelIden") String labelIden,
@Param("order") Map<String, String> order
);
/**
* 临床病例库-搜索-数量
* @param keyword 搜索关键词-标题/医生名称/标签名称
@@ -34,9 +52,18 @@ public interface CaseClinicalArticleDao extends BaseMapper<CaseClinicalArticleMo
Long getCaseClinicalArticleSearchCount(
@Param("keyword") String keyword,
@Param("hospitalId") String hospitalId,
@Param("doctorId") String doctorId
@Param("doctorId") String doctorId,
@Param("labelIden") String labelIden
);
/**
* 查询所有未删除文章的阅读量总和
*
* @return 阅读量总和
*/
@Select("SELECT SUM(read_num) FROM case_clinical_article WHERE delete_status = 0 and article_status = 1")
Long getTotalReadNum();
/**
* Inc 自增
* @param articleId 文章 ID
@@ -59,4 +86,25 @@ public interface CaseClinicalArticleDao extends BaseMapper<CaseClinicalArticleMo
"SET ${field} = CASE WHEN ${field} >= #{numeral} THEN ${field} - #{numeral} ELSE 0 END " +
"WHERE article_id = #{articleId}")
int dec(@Param("articleId") Long articleId, @Param("field") String field, @Param("numeral") int numeral);
/**
* 根据医院ID查询该医院最后一篇文章的发表时间
* @param hospitalId 医院ID
* @return 最新发表时间,无数据时返回 null
*/
LocalDateTime selectLastArticlePushDateByHospitalId(@Param("hospitalId") Long hospitalId);
/**
* 根据医生ID查询该医生最后一篇文章的发表时间
* @param doctorId 医院ID
* @return 最新发表时间,无数据时返回 null
*/
LocalDateTime selectLastArticlePushDateByDoctorId(@Param("doctorId") Long doctorId);
/**
* 根据医院ID查询该医院最后一篇文章的发表时间
* @param labelIden 标签唯一标识
* @return 最新发表时间,无数据时返回 null
*/
LocalDateTime selectLastArticlePushDateByLabelId(@Param("labelIden") String labelIden);
}
@@ -0,0 +1,9 @@
package com.example.caseData.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.caseData.model.CaseClinicalDoctorCertModel;
import com.example.caseData.model.CaseClinicalDoctorModel;
public interface CaseClinicalDoctorCertDao extends BaseMapper<CaseClinicalDoctorCertModel> {
}
@@ -0,0 +1,11 @@
package com.example.caseData.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.caseData.model.CaseClinicalRecordScoreModel;
import com.example.caseData.model.StatsCaseClinicalModel;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
public interface CaseClinicalRecordScoreDao extends BaseMapper<CaseClinicalRecordScoreModel> {
}
@@ -8,8 +8,11 @@ import com.example.caseData.dto.caseClinicalVideo.CaseClinicalVideoDto;
import com.example.caseData.model.CaseClinicalVideoModel;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@Mapper
@@ -25,6 +28,21 @@ public interface CaseClinicalVideoDao extends BaseMapper<CaseClinicalVideoModel>
@Param("keyword") String keyword,
@Param("hospitalId") String hospitalId,
@Param("doctorId") String doctorId,
@Param("labelIden") String labelIden,
@Param("isNeedLink") Integer isNeedLink,
@Param("order") Map<String, String> order
);
/**
* 临床病例库-搜索
* @param keyword 搜索关键词-标题/医生名称/标签名称
* @param order 排序
*/
List<CaseClinicalVideoDto> getCaseClinicalVideoSearchList(
@Param("keyword") String keyword,
@Param("hospitalId") String hospitalId,
@Param("doctorId") String doctorId,
@Param("labelIden") String labelIden,
@Param("order") Map<String, String> order
);
@@ -35,7 +53,8 @@ public interface CaseClinicalVideoDao extends BaseMapper<CaseClinicalVideoModel>
Long getCaseClinicalVideoSearchCount(
@Param("keyword") String keyword,
@Param("hospitalId") String hospitalId,
@Param("doctorId") String doctorId
@Param("doctorId") String doctorId,
@Param("labelIden") String labelIden
);
/**
@@ -48,6 +67,7 @@ public interface CaseClinicalVideoDao extends BaseMapper<CaseClinicalVideoModel>
@Update("UPDATE case_clinical_video SET ${field} = ${field} + #{numeral} WHERE video_id = #{videoId}")
int inc(@Param("videoId") Long articleId, @Param("field") String field, @Param("numeral") int numeral);
/**
* Dec 自减
*
@@ -56,6 +76,37 @@ public interface CaseClinicalVideoDao extends BaseMapper<CaseClinicalVideoModel>
* @param numeral 减少的数值
* @return 更新的行数
*/
@Update("UPDATE case_clinical_video SET ${field} = ${field} - #{numeral} WHERE video_id = #{videoId}")
@Update("UPDATE case_clinical_video " +
"SET ${field} = CASE WHEN ${field} >= #{numeral} THEN ${field} - #{numeral} ELSE 0 END " +
"WHERE video_id = #{videoId}")
int dec(@Param("videoId") Long articleId, @Param("field") String field, @Param("numeral") int numeral);
/**
* 根据医院ID查询该医院最后一篇文章的发表时间
* @param hospitalId 医院ID
* @return 最新发表时间,无数据时返回 null
*/
LocalDateTime selectLastVideoPushDateByHospitalId(@Param("hospitalId") Long hospitalId);
/**
* 根据医生ID查询该医生最后一篇文章的发表时间
* @param doctorId 医院ID
* @return 最新发表时间,无数据时返回 null
*/
LocalDateTime selectLastVideoPushDateByDoctorId(@Param("doctorId") Long doctorId);
/**
* 根据医院ID查询该医院最后一篇文章的发表时间
* @param labelIden 标签唯一标识
* @return 最新发表时间,无数据时返回 null
*/
LocalDateTime selectLastVideoPushDateByLabelId(@Param("labelIden") String labelIden);
/**
* 查询所有未删除文章的阅读量总和
*
* @return 阅读量总和
*/
@Select("SELECT SUM(read_num) FROM case_clinical_video WHERE delete_status = 0 and video_status = 1")
Long getTotalReadNum();
}
@@ -9,6 +9,7 @@ import com.example.caseData.model.CaseClinicalArticleModel;
import com.example.caseData.model.CaseExchangeModel;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
@@ -28,6 +29,20 @@ public interface CaseExchangeDao extends BaseMapper<CaseExchangeModel> {
@Param("keyword") String keyword,
@Param("userId") String userId,
@Param("isSelected") Integer isSelected,
@Param("labelIden") String labelIden,
@Param("order") Map<String, String> order
);
/**
* 临床病例库-搜索
* @param keyword 搜索关键词-标题/医生名称/标签名称
* @param order 排序
*/
List<CaseExchangeDto> getCaseExchangeSearchLimitList(
@Param("limit") Integer limit,
@Param("keyword") String keyword,
@Param("userId") String userId,
@Param("isSelected") Integer isSelected,
@Param("order") Map<String, String> order
);
@@ -37,8 +52,8 @@ public interface CaseExchangeDao extends BaseMapper<CaseExchangeModel> {
* @param order 排序
*/
List<CaseExchangeDto> getCaseExchangeSearchList(
@Param("limit") Integer limit,
@Param("keyword") String keyword,
@Param("userId") String userId,
@Param("isSelected") Integer isSelected,
@Param("order") Map<String, String> order
);
@@ -63,4 +78,20 @@ public interface CaseExchangeDao extends BaseMapper<CaseExchangeModel> {
*/
@Update("UPDATE case_exchange SET ${field} = ${field} - #{numeral} WHERE exchange_id = #{exchangeId}")
int dec(@Param("exchangeId") Long exchangeId, @Param("field") String field, @Param("numeral") int numeral);
/**
* 查询所有未删除文章的阅读量总和
*
* @return 阅读量总和
*/
@Select("SELECT SUM(comment_num) FROM case_exchange WHERE delete_status = 0 and exchange_status = 1")
Long getTotalCommentNum();
/**
* 查询所有未删除文章的阅读量总和
*
* @return 阅读量总和
*/
@Select("SELECT SUM(comment_num) FROM case_exchange WHERE delete_status = 0 and exchange_status = 1")
Long getTotalRedNum();
}
@@ -37,7 +37,7 @@ public interface StatsCaseClinicalHospitalDao extends BaseMapper<StatsCaseClinic
/**
* Dec 自减
*
* @param articleId 文章 ID
* @param hospitalId 文章 ID
* @param field 字段名称
* @param numeral 减少的数值
* @return 更新的行数
@@ -45,5 +45,5 @@ public interface StatsCaseClinicalHospitalDao extends BaseMapper<StatsCaseClinic
@Update("UPDATE stats_case_clinical_hospital " +
"SET ${field} = CASE WHEN ${field} >= #{numeral} THEN ${field} - #{numeral} ELSE 0 END " +
"WHERE hospital_id = #{hospitalId}")
int dec(@Param("hospitalId") Long articleId, @Param("field") String field, @Param("numeral") int numeral);
int dec(@Param("hospitalId") Long hospitalId, @Param("field") String field, @Param("numeral") int numeral);
}
@@ -34,8 +34,8 @@ public interface StatsCaseClinicalLabelDao extends BaseMapper<StatsCaseClinicalL
* @param numeral 增加的数值
* @return 更新的行数
*/
@Update("UPDATE stats_case_exchange_label SET ${field} = ${field} + #{numeral} WHERE label_iden = #{labelIden}")
int inc(@Param("labelIden") Long labelIden, @Param("field") String field, @Param("numeral") int numeral);
@Update("UPDATE stats_case_clinical_label SET ${field} = ${field} + #{numeral} WHERE label_iden = #{labelIden}")
int inc(@Param("labelIden") String labelIden, @Param("field") String field, @Param("numeral") int numeral);
/**
* Dec 自减
@@ -44,6 +44,8 @@ public interface StatsCaseClinicalLabelDao extends BaseMapper<StatsCaseClinicalL
* @param numeral 减少的数值
* @return 更新的行数
*/
@Update("UPDATE stats_case_exchange_label SET ${field} = ${field} - #{numeral} WHERE label_iden = #{labelIdenuserId}")
int dec(@Param("labelIden") Long labelIden, @Param("field") String field, @Param("numeral") int numeral);
@Update("UPDATE stats_case_clinical_label " +
"SET ${field} = CASE WHEN ${field} >= #{numeral} THEN ${field} - #{numeral} ELSE 0 END " +
"WHERE label_iden = #{labelIden}")
int dec(@Param("labelIden") String labelIden, @Param("field") String field, @Param("numeral") int numeral);
}
@@ -25,6 +25,8 @@ public interface StatsCaseExchangeDao extends BaseMapper<StatsCaseExchangeModel>
* @param numeral 减少的数值
* @return 更新的行数
*/
@Update("UPDATE stats_case_exchange SET ${field} = ${field} - #{numeral} WHERE stats_id = #{statsId}")
@Update("UPDATE stats_case_exchange " +
"SET ${field} = CASE WHEN ${field} >= #{numeral} THEN ${field} - #{numeral} ELSE 0 END " +
"WHERE stats_id = #{statsId}")
int dec(@Param("statsId") Long statsId, @Param("field") String field, @Param("numeral") int numeral);
}
@@ -32,6 +32,8 @@ public interface StatsCaseExchangeUserDao extends BaseMapper<StatsCaseExchangeUs
* @param numeral 减少的数值
* @return 更新的行数
*/
@Update("UPDATE stats_case_exchange_user SET ${field} = ${field} - #{numeral} WHERE user_id = #{userId}")
@Update("UPDATE stats_case_exchange_user " +
"SET ${field} = CASE WHEN ${field} >= #{numeral} THEN ${field} - #{numeral} ELSE 0 END " +
"WHERE user_id = #{userId}")
int dec(@Param("userId") Long userId, @Param("field") String field, @Param("numeral") int numeral);
}
@@ -34,6 +34,12 @@ public class CaseClinicalArticleDto {
@JsonProperty("article_status")
private Integer articleStatus;
/**
* 删除状态(0:否 1:是)
*/
@JsonProperty("delete_status")
private Integer deleteStatus;
/**
* 阅读量
*/
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.example.caseData.dto.caseClinicalDoctor.CaseClinicalDoctorDto;
import com.example.caseData.model.CaseClinicalArticleAuthorModel;
import com.example.caseData.utils.Replace;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@@ -39,6 +40,12 @@ public class CaseClinicalArticleAuthorDto {
@JsonProperty("doctor_name")
private String doctorName;
/**
* 医生头像
*/
@JsonProperty("avatar")
private String avatar;
/**
* 医院名称
*/
@@ -80,6 +87,7 @@ public class CaseClinicalArticleAuthorDto {
CaseClinicalDoctorDto caseClinicalDoctorDto = CaseClinicalDoctorDto.GetDto(model.getCaseClinicalDoctor());
dto.setDoctorName(caseClinicalDoctorDto.getDoctorName());
dto.setHospitalName(caseClinicalDoctorDto.getHospitalName());
dto.setAvatar(Replace.addOssDomain(caseClinicalDoctorDto.getAvatar()));
}
return dto;
@@ -34,6 +34,12 @@ public class CaseClinicalVideoDto {
@JsonProperty("video_status")
private Integer videoStatus;
/**
* 删除状态(0:否 1:是)
*/
@JsonProperty("delete_status")
private Integer deleteStatus;
/**
* 阅读量
*/
@@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil;
import com.example.caseData.dto.caseClinicalVideoAuthor.CaseClinicalVideoAuthorDto;
import com.example.caseData.dto.caseClinicalDoctor.CaseClinicalDoctorDto;
import com.example.caseData.model.CaseClinicalVideoAuthorModel;
import com.example.caseData.utils.Replace;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.time.LocalDateTime;
@@ -43,6 +44,12 @@ public class CaseClinicalVideoAuthorDto {
@JsonProperty("hospital_name")
private String hospitalName;
/**
* 医生头像
*/
@JsonProperty("avatar")
private String avatar;
/**
* 创建时间
*/
@@ -75,6 +82,8 @@ public class CaseClinicalVideoAuthorDto {
if (model.getCaseClinicalDoctor() != null) {
CaseClinicalDoctorDto caseClinicalDoctorDto = CaseClinicalDoctorDto.GetDto(model.getCaseClinicalDoctor());
dto.setDoctorName(caseClinicalDoctorDto.getDoctorName());
dto.setHospitalName(caseClinicalDoctorDto.getHospitalName());
dto.setAvatar(Replace.addOssDomain(caseClinicalDoctorDto.getAvatar()));
}
return dto;
@@ -43,6 +43,12 @@ public class CaseExchangeDto {
@JsonProperty("exchange_status")
private Integer exchangeStatus;
/**
* 删除状态(0:否 1:是)
*/
@JsonProperty("delete_status")
private Integer deleteStatus;
/**
* 阅读量
*/
@@ -142,13 +148,13 @@ public class CaseExchangeDto {
/**
* 投票数据
*/
@JsonProperty("case_exchange_vote")
@JsonProperty("exchange_vote")
private CaseExchangeVoteDto caseExchangeVote;
/**
* 标签数据
*/
@JsonProperty("label")
@JsonProperty("exchange_label")
private List<CaseExchangeLabelDto> label;
/**
@@ -114,8 +114,8 @@ public class CaseExchangeDraftDto {
/**
* 选项
*/
@JsonProperty("option")
private List<OptionDto> option;
@JsonProperty("case_exchange_vote_option")
private List<OptionDto> caseExchangeVoteOption;
}
/**
@@ -50,7 +50,7 @@ public class CaseExchangeVoteDto {
* 是否已投票(0: 否 1:是)
*/
@JsonProperty("is_have_voted")
private Integer isHaveVoted;
private Integer isHaveVoted = 0;
/**
* 创建时间
@@ -1,6 +1,7 @@
package com.example.caseData.dto.statsCaseExchange;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.example.caseData.model.StatsCaseExchangeModel;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@@ -36,6 +37,12 @@ public class StatsCaseExchangeDto {
@JsonProperty("exchange_collect_num")
private Integer exchangeCollectNum = 0;
/**
* 总评论量-病例交流
*/
@JsonProperty("exchange_comment_num")
private Integer exchangeCommentNum = 0;
/**
* 创建时间
*/
@@ -29,6 +29,12 @@ public class UserCommentCaseExchangeDto {
@JsonProperty("exchange_id")
private String exchangeId;
/**
* 医生id
*/
@JsonProperty("doctor_id")
private String doctorId;
/**
* 父级id,一级评论为null
*/
@@ -103,6 +109,12 @@ public class UserCommentCaseExchangeDto {
@JsonProperty("user_name")
private String userName;
/**
* 用户头像
*/
@JsonProperty("avatar")
private String avatar;
/**
* 用户唯一标识
*/
@@ -21,6 +21,12 @@ public class UserCommentClinicalArticleDto {
@JsonProperty("user_id")
private String userId;
/**
* 医生id
*/
@JsonProperty("doctor_id")
private String doctorId;
/**
* 临床文章id
*/
@@ -107,6 +113,12 @@ public class UserCommentClinicalArticleDto {
@JsonProperty("user_iden")
private String userIden;
/**
* 用户头像
*/
@JsonProperty("avatar")
private String avatar;
/**
* 是否作者(0:否 1:是)
*/
@@ -22,6 +22,12 @@ public class UserCommentClinicalVideoDto {
@JsonProperty("user_id")
private String userId;
/**
* 医生id
*/
@JsonProperty("doctor_id")
private String doctorId;
/**
* 临床视频id
*/
@@ -102,6 +108,12 @@ public class UserCommentClinicalVideoDto {
@JsonProperty("user_name")
private String userName;
/**
* 用户头像
*/
@JsonProperty("avatar")
private String avatar;
/**
* 用户唯一标识
*/
@@ -0,0 +1,77 @@
package com.example.caseData.extend.aliyun;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.example.caseData.config.DySmsConfig;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Map;
@Slf4j
@Component
public class DySms {
@Resource
private DySmsConfig dySmsConfig;
private static final String endpoint = "dysmsapi.aliyuncs.com";
private static final String signName = "肝胆相照";
/**
* 创建短信客户端
*/
private Client createClient() throws Exception {
Config config = new Config()
.setAccessKeyId(dySmsConfig.getAccessKey())
.setAccessKeySecret(dySmsConfig.getAccessSecret())
.setEndpoint(endpoint);
return new Client(config);
}
/**
* 发送短信
*
* @param phoneNumber 手机号
* @param templateCode 模板CODE
* @param sceneDesc 场景说明,用于日志或调试
* @param templateParam 模板参数
*/
public void sendSms(String phoneNumber, String templateCode, String sceneDesc, Map<String, Object> templateParam) {
try {
Client client = createClient();
ObjectMapper objectMapper = new ObjectMapper();
String paramJson = objectMapper.writeValueAsString(templateParam);
SendSmsRequest request = new SendSmsRequest()
.setPhoneNumbers(phoneNumber)
.setSignName(signName)
.setTemplateCode(templateCode)
.setTemplateParam(paramJson);
// 只用标准的RuntimeOptions,不加任何自定义字段
RuntimeOptions runtime = new RuntimeOptions();
SendSmsResponse response = client.sendSmsWithOptions(request, runtime);
if (response.getBody() == null || !"OK".equals(response.getBody().getCode())) {
log.error("短信发送失败,手机号:{},场景:{},返回信息:{}", phoneNumber, sceneDesc, response.getBody() != null ? response.getBody().getMessage() : "无返回体");
throw new RuntimeException("短信发送失败: " + (response.getBody() != null ? response.getBody().getMessage() : "无返回体"));
} else {
log.info("短信发送成功,手机号:{},场景:{},返回信息:{}", phoneNumber, sceneDesc, response.getBody().getMessage());
}
} catch (TeaException e) {
log.error("阿里云短信发送异常,手机号:{},场景:{},错误信息:{}", phoneNumber, sceneDesc, e.getMessage(), e);
throw new RuntimeException("阿里云短信发送异常", e);
} catch (Exception e) {
log.error("短信发送异常,手机号:{},场景:{},错误信息:{}", phoneNumber, sceneDesc, e.getMessage(), e);
throw new RuntimeException("短信发送异常", e);
}
}
}
@@ -15,6 +15,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
@@ -39,18 +40,75 @@ public class Oss {
}
public static boolean putObject(String fileName, byte[] content) {
if (content == null || content.length == 0) {
logger.warn("Failed to upload object to OSS: content is null or empty, fileName={}", fileName);
return false;
}
if (fileName == null || fileName.trim().isEmpty()) {
logger.warn("Failed to upload object to OSS: fileName is null or empty");
return false;
}
OSS client = createClient();
try (InputStream input = new ByteArrayInputStream(content)) {
client.putObject(ossConfig.getBucket(), fileName, input);
ByteArrayInputStream inputStream = new ByteArrayInputStream(content);
try {
// 推断 Content-Type
String contentType = determineContentType(fileName);
// 创建对象元数据
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(content.length);
metadata.setContentType(contentType);
// 执行上传
PutObjectRequest request = new PutObjectRequest(ossConfig.getBucket(), fileName, inputStream, metadata);
client.putObject(request);
logger.info("Successfully uploaded object to OSS: bucket={}, fileName={}, size={} bytes",
ossConfig.getBucket(), fileName, content.length);
return true;
} catch (Exception e) {
logger.info(e.getMessage());
logger.error("Failed to upload object to OSS. fileName={}, error={}", fileName, e.getMessage(), e);
return false;
} finally {
try {
inputStream.close(); // 可以不关(ByteArrayInputStream 空操作),但建议写上
} catch (IOException ignored) { }
client.shutdown();
}
}
private static String determineContentType(String fileName) {
if (fileName == null) return "application/octet-stream";
int lastDotIndex = fileName.lastIndexOf('.');
if (lastDotIndex < 0) {
return "application/octet-stream";
}
String ext = fileName.substring(lastDotIndex + 1).toLowerCase();
return switch (ext) {
case "jpg", "jpeg" -> "image/jpeg";
case "png" -> "image/png";
case "gif" -> "image/gif";
case "bmp" -> "image/bmp";
case "webp" -> "image/webp";
case "pdf" -> "application/pdf";
case "txt" -> "text/plain";
case "html", "htm" -> "text/html";
case "xml" -> "application/xml";
case "json" -> "application/json";
case "mp4" -> "video/mp4";
case "avi" -> "video/x-msvideo";
case "mp3" -> "audio/mpeg";
default -> "application/octet-stream";
};
}
public static String getObjectToString(String fileName) {
OSS client = createClient();
try {
@@ -112,4 +170,18 @@ public class Oss {
client.shutdown();
}
}
// 下载文件为 byte[]
public static byte[] getObjectToByte(String fileName) {
OSS client = createClient();
try (OSSObject ossObject = client.getObject(ossConfig.getBucket(), fileName);
InputStream content = ossObject.getObjectContent()) {
return content.readAllBytes();
} catch (Exception e) {
log.error("OSS 下载失败: fileName={}, error={}", fileName, e.getMessage(), e);
return null;
} finally {
client.shutdown();
}
}
}
@@ -2,15 +2,22 @@ package com.example.caseData.extend.app;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.example.caseData.exception.BusinessException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
public class Base {
@@ -119,4 +126,42 @@ public class Base {
return response.body();
}
}
/**
* 校验签名(使用已反序列化的 dto 对象)
* @param request HttpServletRequest(用于获取 appId 和 sign)
* @param secretKey 签名用的密钥
* @param dto 请求对象(如 addClinicalVideoApp)
* @param mapper ObjectMapper 实例(用于序列化 dto)
*/
public void checkSign(HttpServletRequest request, String secretKey, Object dto, ObjectMapper mapper) {
try {
String appId = request.getHeader("appId");
String sign = request.getHeader("sign");
if (appId == null || appId.isEmpty()) {
throw new BusinessException("-1", "请求未授权(缺少 appId)");
}
if (sign == null || sign.isEmpty()) {
throw new BusinessException("-1", "缺少签名");
}
// 转换 dto 为 Map<String, Object> 用于签名生成
@SuppressWarnings("unchecked")
Map<String, Object> params = mapper.convertValue(dto, Map.class);
// 生成签名
String serverSign = genSignature(params, secretKey);
System.out.println("客户端签名: " + sign);
System.out.println("服务端签名: " + serverSign);
if (!sign.equals(serverSign)) {
throw new BusinessException("-1", "签名错误");
}
} catch (BusinessException e) {
throw e;
} catch (Exception e) {
throw new BusinessException("-1", "签名校验失败:" + e.getMessage());
}
}
}
@@ -1,6 +1,5 @@
package com.example.caseData.extend.app.Hospital;
import com.example.caseData.extend.app.UserInfo.GetUserInfoByMobileResponse;
import lombok.Data;
@Data
@@ -23,7 +22,7 @@ public class GetHospitalByUuidResponse
/**
* 根据手机号获取医生信息 - 详细数据
* - 详细数据
*/
@Data
public static class GetHospitalByUuidData {
@@ -40,6 +39,12 @@ public class GetHospitalByUuidResponse
/** 省份 */
private String prov_name;
/** 城市 */
private String city_name;
/** 区县 */
private String county_name;
/** 医生数量 */
private Integer expert_num;
}
@@ -0,0 +1,22 @@
package com.example.caseData.extend.app.Score;
import lombok.Data;
@Data
public class ReportUserScoreResponse
{
/** 接口调用状态。200:正常;其它值:调用出错 */
private int code;
/** 结果说明。如果接口调用出错,那么返回错误描述。成功则返回 ok */
private String msg;
/** 接口是否调用成功 */
private boolean success;
/** 错误信息或提示信息 */
private String message;
/** 接口返回的数据 */
private Integer data;
}
@@ -0,0 +1,67 @@
package com.example.caseData.extend.app.Score;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import com.example.caseData.config.AppConfig;
import com.example.caseData.exception.BusinessException;
import com.example.caseData.extend.app.Base;
import com.example.caseData.extend.app.UserPoint.UserPointResponse;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@Slf4j
@Component
public class Score extends Base {
@Resource
private AppConfig appConfig;
// 上报用户积分
public ReportUserScoreResponse ReportUserScore(String uuid,Integer bonuspoints,String bonuspointsNote) throws BusinessException {
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
// 处理参数
Map<String, Object> requestData = new HashMap<>();
requestData.put("bonuspoints_note", bonuspointsNote);
requestData.put("bonuspoints", bonuspoints);
requestData.put("user_uuid", uuid);
requestData.put("platform", appConfig.getPlatform());
requestData.put("timestamp", timestamp);
// 生成签名
String sign = genSignature(requestData,appConfig.getSecretKey());
String url = appConfig.getApiUrl() + "/expert-api/addBonusPoints";
String jsonBody = JSONUtil.toJsonStr(requestData);
log.info("获取app数据参数:{}",jsonBody);
try(HttpResponse response = HttpRequest.post(url)
.header("Content-Type", "application/json")
.header("sign", sign)
.body(jsonBody)
.execute()){
if (response.getStatus() != 200) {
throw new BusinessException("失败");
}
// 反序列化 JSON
ReportUserScoreResponse result = JSONUtil.toBean(response.body(), ReportUserScoreResponse.class);
log.info("获取app数据返回:{}",result);
if (result.getCode() != 200){
if (!Objects.equals(result.getMsg(), "")){
throw new BusinessException(result.getMsg());
}else{
throw new BusinessException("失败");
}
}
return result;
}
}
}
@@ -3,7 +3,7 @@ package com.example.caseData.extend.app.UserInfo;
import lombok.Data;
@Data
public class GetUserInfoByMobileResponse {
public class GetUserInfoResponse {
/** 接口调用状态。200:正常;其它值:调用出错 */
private int code;
@@ -11,7 +11,7 @@ public class GetUserInfoByMobileResponse {
private String msg;
/** 接口返回的用户信息数据 */
private GetUserInfoByMobileData data;
private ResponsData data;
/** 接口是否调用成功 */
private boolean success;
@@ -20,11 +20,8 @@ public class GetUserInfoByMobileResponse {
private String message;
/**
* 根据手机号获取医生信息 - 详细数据
*/
@Data
public static class GetUserInfoByMobileData {
public static class ResponsData {
/** app唯一标识 */
private String uuid;
@@ -41,6 +38,9 @@ public class GetUserInfoByMobileResponse {
/** 手机号 */
private String mobile;
/** 头像地址 */
private String img_host;
/** 头像地址 */
private String photo;
@@ -21,7 +21,7 @@ public class UserInfo extends Base {
private AppConfig appConfig;
// 根据手机号获取信息V3
public GetUserInfoByMobileResponse getUserInfoByMobile(String mobile) throws BusinessException {
public GetUserInfoResponse getUserInfoByMobile(String mobile) throws BusinessException {
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
// 处理参数
@@ -48,7 +48,99 @@ public class UserInfo extends Base {
}
// 反序列化 JSON
GetUserInfoByMobileResponse result = JSONUtil.toBean(response.body(), GetUserInfoByMobileResponse.class);
GetUserInfoResponse result = JSONUtil.toBean(response.body(), GetUserInfoResponse.class);
log.info("获取app数据返回:{}",result);
if (result.getCode() != 200){
if (!Objects.equals(result.getMsg(), "")){
throw new BusinessException(result.getMsg());
}else{
throw new BusinessException("失败");
}
}
if (result.getData() == null){
throw new BusinessException("失败");
}
return result;
}
}
// 根据token获取信息V3
public GetUserInfoResponse getUserInfoByToken(String appToken) throws BusinessException {
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
// 处理参数
Map<String, Object> requestData = new HashMap<>();
requestData.put("token", appToken);
requestData.put("platform", appConfig.getPlatform());
requestData.put("timestamp", timestamp);
// 生成签名
String sign = genSignature(requestData,appConfig.getSecretKey());
String url = appConfig.getApiUrl() + "/expert-api/getInfoByToken";
String jsonBody = JSONUtil.toJsonStr(requestData);
log.info("获取app数据参数:{}",jsonBody);
try(HttpResponse response = HttpRequest.post(url)
.header("Content-Type", "application/json")
.header("sign", sign)
.body(jsonBody)
.execute()){
if (response.getStatus() != 200) {
throw new BusinessException("失败");
}
// 反序列化 JSON
GetUserInfoResponse result = JSONUtil.toBean(response.body(), GetUserInfoResponse.class);
log.info("获取app数据返回:{}",result);
if (result.getCode() != 200){
if (!Objects.equals(result.getMsg(), "")){
throw new BusinessException(result.getMsg());
}else{
throw new BusinessException("失败");
}
}
if (result.getData() == null){
throw new BusinessException("失败");
}
return result;
}
}
// 根据唯一标识获取信息V3
public GetUserInfoResponse getUserInfoByUuid(String uuid) throws BusinessException {
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
// 处理参数
Map<String, Object> requestData = new HashMap<>();
requestData.put("user_uuid", uuid);
requestData.put("platform", appConfig.getPlatform());
requestData.put("timestamp", timestamp);
// 生成签名
String sign = genSignature(requestData,appConfig.getSecretKey());
String url = appConfig.getApiUrl() + "/expert-api/getInfoByUuid";
String jsonBody = JSONUtil.toJsonStr(requestData);
log.info("获取app数据参数:{}",jsonBody);
try(HttpResponse response = HttpRequest.post(url)
.header("Content-Type", "application/json")
.header("sign", sign)
.body(jsonBody)
.execute()){
if (response.getStatus() != 200) {
throw new BusinessException("失败");
}
// 反序列化 JSON
GetUserInfoResponse result = JSONUtil.toBean(response.body(), GetUserInfoResponse.class);
log.info("获取app数据返回:{}",result);
if (result.getCode() != 200){
if (!Objects.equals(result.getMsg(), "")){
@@ -0,0 +1,19 @@
package com.example.caseData.extend.app.Video;
import com.example.caseData.exception.BusinessException;
import com.example.caseData.extend.app.Base;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets;
import java.util.Map;
@Slf4j
@Component
public class Video extends Base {
}
@@ -2,35 +2,50 @@ package com.example.caseData.extend.weChat;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.concurrent.TimeUnit;
@Slf4j
public class WxMaRedisConfig extends WxMaDefaultConfigImpl {
private final StringRedisTemplate redisTemplate;
private final RedisTemplate<String, Object> redisTemplate;
private final RedisTemplate<String, Object> prodRedisTemplate;
public WxMaRedisConfig(StringRedisTemplate redisTemplate) {
public WxMaRedisConfig(RedisTemplate<String, Object> redisTemplate, RedisTemplate<String, Object> prodRedisTemplate) {
this.redisTemplate = redisTemplate;
this.prodRedisTemplate = prodRedisTemplate;
}
@Override
public String getAccessToken() {
String redisKey = "wx:ma:access_token:" + this.getAppid();
String token = redisTemplate.opsForValue().get(redisKey);
String token = (String) redisTemplate.opsForValue().get(redisKey);
if (token != null) {
return token;
}
// 2. 再尝试从 prodRedis 获取
token = (String) prodRedisTemplate.opsForValue().get(redisKey);
if (token != null) {
return token;
}
synchronized (this) {
token = redisTemplate.opsForValue().get(redisKey);
token = (String) redisTemplate.opsForValue().get(redisKey);
if (token != null) return token;
token = (String) prodRedisTemplate.opsForValue().get(redisKey);
if (token != null) return token;
try {
String newToken = super.getAccessToken(); // 强制刷新
redisTemplate.opsForValue().set(redisKey, newToken, this.getExpiresTime() - 200L, TimeUnit.SECONDS);
long expireSeconds = this.getExpiresTime() - 200L;
redisTemplate.opsForValue().set(redisKey, newToken, expireSeconds, TimeUnit.SECONDS);
prodRedisTemplate.opsForValue().set(redisKey, newToken, expireSeconds, TimeUnit.SECONDS);
return newToken;
} catch (Exception e) {
log.error("获取access_token失败", e);
@@ -42,6 +57,9 @@ public class WxMaRedisConfig extends WxMaDefaultConfigImpl {
@Override
public void updateAccessToken(String accessToken, int expiresInSeconds) {
String redisKey = "wx:ma:access_token:" + this.getAppid();
redisTemplate.opsForValue().set(redisKey, accessToken, expiresInSeconds - 200L, TimeUnit.SECONDS);
long expireSeconds = Math.max(expiresInSeconds - 200L, 1L);
redisTemplate.opsForValue().set(redisKey, accessToken, expireSeconds, TimeUnit.SECONDS);
prodRedisTemplate.opsForValue().set(redisKey, accessToken, expireSeconds, TimeUnit.SECONDS);
}
}
@@ -3,20 +3,42 @@ package com.example.caseData.extend.weChat;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import com.example.caseData.config.WxMaConfig;
import com.example.caseData.service.RewardPointService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.RedisTemplate;
@Configuration
public class WxMaServiceConfig {
private final RedisTemplate<String, Object> devRedis;
private final RedisTemplate<String, Object> prodRedis;
@Resource
private WxMaConfig wxMaConfig;
public WxMaServiceConfig(
@Qualifier("redisTemplate") RedisTemplate<String, Object> devRedis,
@Qualifier("prodRedisTemplate") RedisTemplate<String, Object> prodRedis
) {
this.devRedis = devRedis;
this.prodRedis = prodRedis;
}
@Bean
public WxMaService wxMaService(WxMaConfig config, StringRedisTemplate redisTemplate) {
WxMaRedisConfig redisConfig = new WxMaRedisConfig(redisTemplate);
redisConfig.setAppid(config.getAppid());
redisConfig.setSecret(config.getSecret());
public WxMaService wxMaService() {
WxMaRedisConfig redisConfig = new WxMaRedisConfig(devRedis, prodRedis);
redisConfig.setAppid(wxMaConfig.getAppid());
redisConfig.setSecret(wxMaConfig.getSecret());
WxMaServiceImpl service = new WxMaServiceImpl();
service.setWxMaConfig(redisConfig);
return service;
}
}
@@ -1,20 +1,29 @@
package com.example.caseData.extend.weChat;
import cn.binarywang.wx.miniapp.api.WxMaQrcodeService;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import com.example.caseData.config.EnvConfig;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.stereotype.Component;
import java.util.Objects;
@Slf4j
@Component
@RequiredArgsConstructor
public class WxMaServiceUtils {
private final WxMaService wxMaService;
@Resource
private EnvConfig envConfig;
/**
* 通过 code 换取 session 信息(openid/unionid)
*/
@@ -50,4 +59,30 @@ public class WxMaServiceUtils {
throw new RuntimeException("获取 access_token 失败", e);
}
}
/**
* 获取永久小程序码(base64 或保存成文件都可以)
* @param scene 场景值(最长32个可见字符,只能是数字、英文、下划线、减号)
* @param page 跳转页面路径(如 pages/index/index)
* @return 二进制图片数据(image/jpeg)
*/
public byte[] getUnlimitedQrcode(String scene, String page) {
boolean checkPath = false; // 不校验 page 是否存在
String envVersion = "release"; // 可选:trial、develop、release
if (Objects.equals(envConfig.getActive(), "dev")){
envVersion = "trial";
}
int width = 430;
boolean autoColor = true;
WxMaCodeLineColor lineColor = new WxMaCodeLineColor();
boolean isHyaline = true;
try {
WxMaQrcodeService qrcodeService = wxMaService.getQrcodeService();
return qrcodeService.createWxaCodeUnlimitBytes(scene,page,checkPath,envVersion,width,autoColor,lineColor,isHyaline);
} catch (Exception e) {
throw new RuntimeException("获取小程序码失败", e);
}
}
}
@@ -3,10 +3,21 @@ package com.example.caseData.middlewares;
import com.example.caseData.dao.UserDao;
import com.example.caseData.exception.BusinessException;
import com.example.caseData.model.UserModel;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.codec.digest.HmacUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
@Component
public class AuthInterceptor extends BaseInterceptor {
@@ -20,7 +31,6 @@ public class AuthInterceptor extends BaseInterceptor {
public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) throws Exception {
// 放行白名单路径
if (isWhiteListed(request)) {
// 在白名单
return true;
}
@@ -46,4 +56,6 @@ public class AuthInterceptor extends BaseInterceptor {
return true; // 如果权限验证通过,则继续处理请求
}
}
@@ -13,7 +13,12 @@ public abstract class BaseInterceptor implements HandlerInterceptor {
// "POST:/api/public/.*", // POST 请求,匹配 /api/public/xx
// "GET:/api/users" , // GET 请求,匹配具体路径
"POST:/api/login/wechat/mobile", // 登陆
"GET:/api/index/clinical" // 首页-临床病例库
// "GET:/api/index/clinical", // 首页-临床病例库
"POST:/api/login/mobile", // 登陆
"POST:/api/code/phone", // 获取验证码
"POST:/api/login/hcp", // 登陆-hcp
"POST:/api/app/clinical/video" // 视频同步
// "GET:/api/clinical/stats" // 统计
);
/**
@@ -25,6 +25,12 @@ public class CaseClinicalArticleModel {
@TableField("article_status")
private Integer articleStatus;
/**
* 删除状态(0:否 1:是)
*/
@TableField("delete_status")
private Integer deleteStatus;
/**
* 阅读量
*/
@@ -67,6 +73,12 @@ public class CaseClinicalArticleModel {
@TableField("is_link_url")
private String isLinkUrl;
/**
* 分享二维码地址
*/
@TableField("share_qrcode")
private String shareQrcode;
/**
* 内容
*/
@@ -0,0 +1,58 @@
package com.example.caseData.model;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 医生证书信息实体类
*/
@Data
@TableName("`case_clinical_doctor_cert`")
public class CaseClinicalDoctorCertModel {
/**
* 主键id
*/
@TableId(type = IdType.ASSIGN_ID)
private Long certId;
/**
* 医生id
*/
@TableField("doctor_id")
private Long doctorId;
/**
* 关联的视频/文章id
*/
@TableField("id")
private Long id;
/**
* 类型(1:文章 2:视频)
*/
@TableField("type")
private Integer type;
/**
* 证书图片(存储路径或URL)
*/
@TableField("cert_image")
private String certImage;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
@JsonProperty("created_at")
private LocalDateTime createdAt;
/**
* 修改时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
@JsonProperty("updated_at")
private LocalDateTime updatedAt;
}
@@ -0,0 +1,76 @@
package com.example.caseData.model;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 积分发放记录实体类
*/
@TableName("`case_clinical_record_score`")
@Data
public class CaseClinicalRecordScoreModel {
/**
* 主键id
*/
@TableId(value = "score_id", type = IdType.NONE)
private Long scoreId;
/**
* id(根据type不同,对应不同类型)
*/
@TableField("id")
private Long id;
/**
* 类型(1:文章 2:视频 3:病例交流)
*/
@TableField("type")
private Integer type;
/**
* 用户id
*/
@TableField("user_id")
private Long userId;
/**
* 用户名称
*/
@TableField("user_name")
private String userName;
/**
* 积分类型(1:完成阅读 2:阅读时间满足 3:优质留言 4:再次优质留言 5:病例互动-病例库)
*/
@TableField("score_type")
private Integer scoreType;
/**
* 获取积分节点名称(如:阅读时间足够)
*/
@TableField("node_name")
private String nodeName;
/**
* 积分
*/
@TableField("score")
private Integer score;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
@JsonProperty("created_at")
private LocalDateTime createdAt;
/**
* 修改时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
@JsonProperty("updated_at")
private LocalDateTime updatedAt;
}
@@ -28,6 +28,12 @@ public class CaseClinicalVideoModel {
@TableField("video_status")
private Integer videoStatus;
/**
* 删除状态(0:否 1:是)
*/
@TableField("delete_status")
private Integer deleteStatus;
/**
* 阅读量
*/
@@ -76,6 +82,12 @@ public class CaseClinicalVideoModel {
@TableField("is_link_url")
private String isLinkUrl;
/**
* 分享二维码地址
*/
@TableField("share_qrcode")
private String shareQrcode;
/**
* 创建时间
*/
@@ -37,12 +37,23 @@ public class CaseExchangeModel {
@TableField("exchange_status")
private Integer exchangeStatus;
/**
* 删除状态(0:否 1:是)
*/
@TableField("delete_status")
private Integer deleteStatus;
/**
* 是否被精选(0:否 1:是)
*/
@TableField("is_selected")
private Integer isSelected;
/**
* 审核状态(0:否 1:是)
*/
private Integer auditStatus;
/**
* 阅读量
*/
@@ -48,6 +48,12 @@ public class StatsCaseClinicalDoctorModel {
@TableField("article_comment_num")
private Integer articleCommentNum;
/**
* 最后一篇文章发表时间
*/
@TableField("last_push_date")
private LocalDateTime lastPushDate;
/**
* 数量-视频
*/
@@ -30,6 +30,12 @@ public class StatsCaseClinicalLabelModel {
@TableField("label_name")
private String labelName;
/**
* 状态(1:正常 2:不展示)
*/
@TableField("status")
private Integer status;
/**
* 数量-文章
*/
@@ -45,6 +45,11 @@ public class UserCommentClinicalArticleModel {
@TableField("status")
private Integer status;
/**
* 删除状态(0:否 1:是)
*/
private Integer deleteStatus;
/**
* 是否存在敏感词(0:否 1:是)
*/
@@ -51,6 +51,11 @@ public class UserCommentClinicalVideoModel {
@TableField("is_sensitive")
private Integer isSensitive;
/**
* 删除状态(0:否 1:是)
*/
private Integer deleteStatus;
/**
* 是否置顶(0:否 1:是)
*/
@@ -71,6 +71,11 @@ public class UserCommentExchangeModel {
@TableField("is_author")
private Integer isAuthor;
/**
* 删除状态(0:否 1:是)
*/
private Integer deleteStatus;
/**
* 评论内容
*/
@@ -0,0 +1,85 @@
package com.example.caseData.request.CaseClinicalVideoRequest;
import com.example.caseData.request.clinicalRequest.getClinicalArticleSearchPage;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.annotation.Nulls;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Data
public class addClinicalVideoApp {
// 动作(add:新增 update:修改 delete:删除)
@JsonProperty("action")
private String action;
// 视频编号(保利)
@JsonProperty("videoNo")
private String videoNo;
// 是否外部链接(0:否 1:是)
@JsonProperty("isLink")
@JsonInclude(JsonInclude.Include.NON_NULL)
private Integer isLink;
// 外部链接地址
@JsonProperty("isLinkUrl")
@JsonInclude(JsonInclude.Include.NON_NULL)
private String isLinkUrl;
// 标题
@JsonProperty("videoTitle")
@JsonInclude(JsonInclude.Include.NON_NULL)
private String videoTitle;
// 发布时间
@JsonProperty("pushDate")
@JsonInclude(JsonInclude.Include.NON_NULL)
private String pushDate;
// 作者
@JsonProperty("author")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonSetter(nulls = Nulls.SKIP)
private List<Author> author;
// 标签
@JsonProperty("label")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonSetter(nulls = Nulls.SKIP)
private List<Label> label;
/**
* 作者
*/
@Data
public static class Author {
@JsonProperty("doctorIden")
private String doctorIden; // 医生app唯一标识
@JsonProperty("doctorName")
private String doctorName; // 医生app名称
@JsonProperty("hospitalIden")
private String hospitalIden; // 医院app唯一标识
}
/**
* 标签
*/
@Data
public static class Label {
@JsonProperty("appIden")
private String appIden; // app唯一标识
@JsonProperty("labelName")
private String labelName; // 标签名称
}
}
@@ -0,0 +1,17 @@
package com.example.caseData.request.CaseClinicalVideoRequest;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
@Data
public class deleteClinicalVideoApp {
// 动作(add:新增 update:修改 delete:删除)
@JsonProperty("action")
private String action;
// 视频编号(保利)
@JsonProperty("videoNo")
private String videoNo;
}
@@ -0,0 +1,22 @@
package com.example.caseData.request.UserRequest;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.*;
import lombok.Data;
@Data
public class ReportUserScoreRequest {
/**
* 主键id(根据type不同对应不同数据表)
*/
@JsonProperty("id")
@NotEmpty(message = "参数错误")
private String id;
/**
* 类型(1:文章 2:视频 3:病例交流)
*/
@JsonProperty("type")
@NotNull(message = "参数错误")
private Integer type;
}
@@ -12,14 +12,12 @@ public class addCaseExchangeDraft {
/**
* 标题
*/
@NotEmpty(message = "请输入标题")
@JsonProperty("exchange_title")
private String exchangeTitle;
/**
* 内容
*/
@NotEmpty(message = "请输入内容")
@JsonProperty("exchange_content")
private String exchangeContent;
@@ -54,7 +52,7 @@ public class addCaseExchangeDraft {
@Size(min = 1, max = 20, message = "有效期在1-20天内")
private Integer validDay; // 投票有效期天数
@JsonProperty("option")
@JsonProperty("case_exchange_vote_option")
private List<CaseExchangeVoteOptionRequest> option;
}
@@ -1,6 +1,7 @@
package com.example.caseData.request.caseExchangeRequest;
import com.example.caseData.request.clinicalRequest.getClinicalArticleSearchPage;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Size;
@@ -11,6 +12,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public class addCaseExchange {
/**
@@ -48,6 +50,7 @@ public class addCaseExchange {
/**
* 投票
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public static class CaseExchangeVoteRequest {
@JsonProperty("vote_title")
@@ -65,6 +68,7 @@ public class addCaseExchange {
/**
* 投票选项
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public static class CaseExchangeVoteOptionRequest {
@JsonProperty("option_value")
@@ -74,6 +78,7 @@ public class addCaseExchange {
/**
* 标签
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public static class CaseExchangeLabelRequest {
@JsonProperty("app_iden")
@@ -31,6 +31,10 @@ public class getCaseExchangeSearchPage {
@JsonProperty("is_selected")
private Integer isSelected;
// 疾病标签唯一标识
@JsonProperty("label_iden")
private String labelIden;
// 排序字段
private OrderRequest order;
@@ -45,9 +49,15 @@ public class getCaseExchangeSearchPage {
@JsonProperty("read_num")
private String readNum; // 阅读量
@JsonProperty("comment_num")
private String commentNum; // 评论数
@JsonProperty("push_date")
private String pushDate; // 发表时间
@JsonProperty("last_comment_time")
private String lastCommentTime; // 最后评论时间
public Map<String, String> toMap() {
Map<String, String> map = new HashMap<>();
if (StringUtils.hasText(createdAt)) {
@@ -58,10 +68,18 @@ public class getCaseExchangeSearchPage {
map.put("a.read_num", readNum);
}
if (StringUtils.hasText(commentNum)) {
map.put("a.comment_num", commentNum);
}
if (StringUtils.hasText(pushDate)) {
map.put("a.push_date", pushDate);
}
if (StringUtils.hasText(lastCommentTime)) {
map.put("commentCreatedAt", lastCommentTime);
}
// 默认排序(如果用户未传递任何排序字段)
if (map.isEmpty()) {
map.put("a.updated_at", "desc");
@@ -0,0 +1,86 @@
package com.example.caseData.request.caseExchangeRequest;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Size;
import lombok.Data;
import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public class updateCaseExchange {
/**
* 标题
*/
@NotEmpty(message = "请输入标题")
@JsonProperty("exchange_title")
private String exchangeTitle;
/**
* 内容
*/
@NotEmpty(message = "请输入内容")
@JsonProperty("exchange_content")
private String exchangeContent;
/**
* 总结
*/
@JsonProperty("exchange_summary")
private String exchangeSummary;
/**
* 投票
*/
@JsonProperty("case_exchange_vote")
private CaseExchangeVoteRequest caseExchangeVote;
/**
* 标签
*/
@JsonProperty("case_exchange_label")
private List<CaseExchangeLabelRequest> caseExchangeLabel;
/**
* 投票
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public static class CaseExchangeVoteRequest {
@JsonProperty("vote_title")
@NotEmpty(message = "请输入投票标题")
private String voteTitle; // 选项标题
@JsonProperty("valid_day")
@Size(min = 1, max = 20, message = "有效期在1-20天内")
private Integer validDay; // 投票有效期天数
@JsonProperty("case_exchange_vote_option")
private List<CaseExchangeVoteOptionRequest> caseExchangeVoteOption;
}
/**
* 投票选项
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public static class CaseExchangeVoteOptionRequest {
@JsonProperty("option_value")
private String optionValue; // 选项
}
/**
* 标签
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public static class CaseExchangeLabelRequest {
@JsonProperty("app_iden")
private String appIden; // app唯一标识
@JsonProperty("label_name")
private String labelName; // 标签名称
}
}
@@ -1,5 +1,6 @@
package com.example.caseData.request.caseLabelRequest;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
@@ -41,6 +41,9 @@ public class getClinicalArticleSearchPage {
@JsonProperty("is_need_num")
private Integer isNeedNum = 0;
// 是否需要外部链接(0:否 1:是)
@JsonProperty("is_need_link")
private Integer isNeedLink = 1;
// 排序字段
private OrderRequest order;
@@ -39,6 +39,8 @@ public class getClinicalDoctorSearchPage {
@JsonProperty("article_num")
private String articleNum; // 数量-文章
@JsonProperty("push_date")
private String pushDate; // 发布时间
public Map<String, String> toMap() {
Map<String, String> map = new HashMap<>();
@@ -47,16 +49,17 @@ public class getClinicalDoctorSearchPage {
}
if (StringUtils.hasText(doctorName)) {
map.put("b.doctor_name", doctorName);
map.put("CONVERT(b.doctor_name USING gbk)", doctorName);
}
if (StringUtils.hasText(articleNum)) {
map.put("a.article_num", articleNum);
map.put("a.article_num + a.video_num", articleNum);
}
// 默认排序(如果用户未传递任何排序字段)
if (map.isEmpty()) {
map.put("a.updated_at", "desc");
if (StringUtils.hasText(pushDate)) {
map.put("a.last_push_date", pushDate);
}else{
map.put("a.last_push_date", "desc");
}
return map;
@@ -40,6 +40,8 @@ public class getClinicalHospitalSearchPage {
@JsonProperty("article_num")
private String articleNum; // 数量-文章
@JsonProperty("push_date")
private String pushDate; // 发布时间
public Map<String, String> toMap() {
Map<String, String> map = new HashMap<>();
@@ -48,16 +50,17 @@ public class getClinicalHospitalSearchPage {
}
if (StringUtils.hasText(hospitalName)) {
map.put("b.hospital_name", hospitalName);
map.put("CONVERT(b.hospital_name USING gbk)", hospitalName);
}
if (StringUtils.hasText(articleNum)) {
map.put("a.article_num", articleNum);
map.put("a.article_num + a.video_num", articleNum);
}
// 默认排序(如果用户未传递任何排序字段)
if (map.isEmpty()) {
map.put("a.updated_at", "desc");
if (StringUtils.hasText(pushDate)) {
map.put("a.last_push_date", pushDate);
}else{
map.put("a.last_push_date", "desc");
}
return map;
@@ -39,6 +39,8 @@ public class getClinicalLabelSearchPage {
@JsonProperty("article_num")
private String articleNum; // 数量-文章
@JsonProperty("push_date")
private String pushDate; // 发布时间
public Map<String, String> toMap() {
Map<String, String> map = new HashMap<>();
@@ -47,18 +49,25 @@ public class getClinicalLabelSearchPage {
}
if (StringUtils.hasText(labelName)) {
map.put("b.label_name", labelName);
map.put("CONVERT(a.label_name USING gbk)", labelName);
}
if (StringUtils.hasText(articleNum)) {
map.put("a.article_num", articleNum);
map.put("a.article_num + a.video_num", articleNum);
}
// 默认排序(如果用户未传递任何排序字段)
if (map.isEmpty()) {
map.put("a.updated_at", "desc");
if (StringUtils.hasText(pushDate)) {
map.put("a.last_push_date", pushDate);
}else{
map.put("a.last_push_date", "desc");
}
// // 默认排序(如果用户未传递任何排序字段)
// if (map.isEmpty()) {
// map.put("a.updated_at", "desc");
// }
return map;
}
}
@@ -41,6 +41,10 @@ public class getClinicalVideoSearchPage {
@JsonProperty("is_need_num")
private Integer isNeedNum = 0;
// 是否需要外部链接(0:否 1:是)
@JsonProperty("is_need_link")
private Integer isNeedLink = 1;
// 排序字段
private OrderRequest order;
@@ -10,6 +10,6 @@ import lombok.Data;
public class GetOssSignRequest {
@NotNull(message = "错误请求")
@Min(value = 1, message = "错误请求")
@Max(value = 1, message = "错误请求")
private String scene;
@Max(value = 2, message = "错误请求")
private int scene;
}
@@ -0,0 +1,19 @@
package com.example.caseData.request.publicRequest;
import jakarta.validation.constraints.*;
import lombok.Data;
@Data
public class GetPhoneCodeRequest {
@NotNull(message = "错误请求")
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
private String phone;
/**
* 场景值:1登录
*/
@NotNull(message = "错误请求")
@Min(value = 1, message = "错误请求")
@Max(value = 1, message = "错误请求")
private Integer scene;
}
@@ -0,0 +1,10 @@
package com.example.caseData.request.publicRequest;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
@Data
public class LoginHcpRequest {
@NotEmpty(message = "错误请求")
private String token;
}
@@ -0,0 +1,16 @@
package com.example.caseData.request.publicRequest;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
@Data
public class LoginPhoneRequest {
@NotEmpty(message = "错误请求")
private String phone;
@NotEmpty(message = "错误请求")
private String code;
@NotEmpty(message = "错误请求")
private String wx_code;
}
@@ -1,6 +1,7 @@
package com.example.caseData.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.caseData.common.Response;
import com.example.caseData.dao.*;
import com.example.caseData.exception.BusinessException;
import com.example.caseData.model.*;
@@ -12,7 +13,9 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
//import static com.baomidou.mybatisplus.extension.toolkit.Db.removeById;
@@ -50,6 +53,15 @@ public class CaseClinicalArticleService {
@Resource
private UserDao userDao;
@Resource
private UserService userService;
@Resource
private CaseClinicalArticleLabelDao caseClinicalArticleLabelDao;
@Resource
private StatsCaseClinicalLabelDao statsCaseClinicalLabelDao;
/**
* 新增收藏-临床病例库-文章
* @param articleId 文章id
@@ -79,25 +91,11 @@ public class CaseClinicalArticleService {
return false;
}
// 增加文章收藏数
caseClinicalArticleDao.inc(Long.valueOf(articleId),"collect_num",1);
// 增加文章总收藏数
statsCaseClinicalDao.inc(1L,"article_collect_num",1);
// 获取文章作者
LambdaQueryWrapper<CaseClinicalArticleAuthorModel> authorQueryWrapper = new LambdaQueryWrapper<>();
authorQueryWrapper.eq(CaseClinicalArticleAuthorModel::getArticleId, articleId);
List<CaseClinicalArticleAuthorModel> caseClinicalArticleAuthors = caseClinicalArticleAuthorDao.selectList(authorQueryWrapper);
for (CaseClinicalArticleAuthorModel author : caseClinicalArticleAuthors) {
// 查询医生
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectById(author.getDoctorId());
// 增加医院文章收藏数
statsCaseClinicalHospitalDao.inc(caseClinicalDoctor.getHospitalId(),"article_collect_num",1);
// 增加医生文章收藏数
statsCaseClinicalDoctorDao.inc(caseClinicalDoctor.getDoctorId(),"article_collect_num",1);
// 新增统计字段
boolean r = IncClinicalArticleStats(articleId,2,1);
if (!r){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
return true;
@@ -124,25 +122,11 @@ public class CaseClinicalArticleService {
return false;
}
// 减少文章收藏数
caseClinicalArticleDao.dec(Long.valueOf(articleId),"collect_num",1);
// 减少文章总收藏数
statsCaseClinicalDao.dec(1L,"article_collect_num",1);
// 获取文章作者
LambdaQueryWrapper<CaseClinicalArticleAuthorModel> authorQueryWrapper = new LambdaQueryWrapper<>();
authorQueryWrapper.eq(CaseClinicalArticleAuthorModel::getArticleId, articleId);
List<CaseClinicalArticleAuthorModel> caseClinicalArticleAuthors = caseClinicalArticleAuthorDao.selectList(authorQueryWrapper);
for (CaseClinicalArticleAuthorModel author : caseClinicalArticleAuthors) {
// 查询医生
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectById(author.getDoctorId());
// 减少医院文章收藏数
statsCaseClinicalHospitalDao.dec(caseClinicalDoctor.getHospitalId(),"article_collect_num",1);
// 减少医生文章收藏数
statsCaseClinicalDoctorDao.dec(caseClinicalDoctor.getDoctorId(),"article_collect_num",1);
// 减少文章的统计字段
boolean r = DecClinicalArticleStats(articleId,2,1);
if (!r){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
return true;
@@ -155,7 +139,11 @@ public class CaseClinicalArticleService {
* @return bool
*/
@Transactional
public boolean AddClinicalArticleComment(String articleId, String userId, addClinicalArticleComment request){
public Map<String, Object> AddClinicalArticleComment(String articleId, String userId, addClinicalArticleComment request){
Map<String, Object> resultData = new HashMap<>();
resultData.put("status", 1);
resultData.put("message", "成功");
// 获取文章数据
CaseClinicalArticleModel article = caseClinicalArticleDao.selectById(articleId);
if (article == null) {
@@ -192,7 +180,26 @@ public class CaseClinicalArticleService {
}
int res = userCommentClinicalArticleDao.insert(userCommentClinicalArticleData);
return res > 0;
if (res <= 0){
throw new BusinessException("操作失败");
}
// 新增文章的统计字段
boolean r = IncClinicalArticleStats(articleId,3,1);
if (!r){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
throw new BusinessException("操作失败");
}
// 获取发放积分次数
Integer num = userService.GetReportUserScore(userId);
if (num < 3){
// 发放积分
resultData.put("status", 2);
userService.ReportUserScore(articleId,1,userId,5);
}
return resultData;
}
/**
@@ -212,22 +219,57 @@ public class CaseClinicalArticleService {
// 获取文章数据
CaseClinicalArticleModel article = caseClinicalArticleDao.selectById(comment.getArticleId());
if (article == null) {
System.out.println(111);
return false;
}
if (article.getArticleStatus() != 1){
System.out.println(222);
return false;
}
// 检测是否本人的评论
if (!Objects.equals(comment.getUserId(), Long.valueOf(userId))){
// 检测用户是否文章作者
boolean isAuthor = checkUserIsArticleAuthor(String.valueOf(article.getArticleId()),userId);
if (!isAuthor) {
System.out.println(333);
return false;
}
}
// 获取下级评论
LambdaQueryWrapper<UserCommentClinicalArticleModel> articleQueryWrapper = new LambdaQueryWrapper<>();
articleQueryWrapper.eq(UserCommentClinicalArticleModel::getRootId, comment.getCommentId());
List<UserCommentClinicalArticleModel> userCommentClinicalArticles = userCommentClinicalArticleDao.selectList(articleQueryWrapper);
for (UserCommentClinicalArticleModel m : userCommentClinicalArticles){
// 删除评论
int res = userCommentClinicalArticleDao.deleteById(m.getCommentId());
if (res <= 0){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
// 减少文章的统计字段
boolean r = DecClinicalArticleStats(String.valueOf(comment.getArticleId()),2,1);
if (!r){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
}
// 删除评论
int res = userCommentClinicalArticleDao.deleteById(comment.getCommentId());
if (res <= 0){
System.out.println(444);
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
// 减少文章的统计字段
boolean r = DecClinicalArticleStats(String.valueOf(comment.getArticleId()),2,1);
if (!r){
System.out.println(555);
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
@@ -362,9 +404,176 @@ public class CaseClinicalArticleService {
if (Objects.equals(caseClinicalDoctor.getDoctorIden(), user.getUserIden())){
isAuthor = true;
break;
}
}
return isAuthor;
}
/**
* 新增文章的统计字段
* @param articleId 文章id
* @param type 类型:1:阅读量 2:收藏量 3:评论数 4:文章数
*/
@Transactional
public boolean IncClinicalArticleStats(String articleId,Integer type,Integer num){
try {
String caseClinicalArticleField = ""; // 具体文章
String statsCaseClinicalField = ""; // 全部文章
// 阅读
if (type == 1){
caseClinicalArticleField = "read_num"; // 具体文章
statsCaseClinicalField = "article_read_num"; // 全部文章
}
// 收藏
if (type == 2){
caseClinicalArticleField = "collect_num"; // 具体文章
statsCaseClinicalField = "article_collect_num"; // 全部文章
}
// 评论
if (type == 3){
caseClinicalArticleField = "comment_num"; // 具体文章
statsCaseClinicalField = "article_comment_num"; // 全部文章
}
// 文章数
if (type == 4){
statsCaseClinicalField = "article_num"; // 全部文章
}
if (!caseClinicalArticleField.isEmpty()){
caseClinicalArticleDao.inc(Long.valueOf(articleId),caseClinicalArticleField,num);
}
statsCaseClinicalDao.inc(1L,statsCaseClinicalField,num);
return true;
} catch (Exception e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
}
/**
* 减少文章的统计字段
* @param articleId 文章id
* @param type 类型:1:阅读量 2:收藏量 3:评论数 4:文章数
*/
@Transactional
public boolean DecClinicalArticleStats(String articleId,Integer type,Integer num){
try {
String caseClinicalArticleField = ""; // 具体文章
String statsCaseClinicalField = ""; // 全部文章
// 阅读
if (type == 1){
caseClinicalArticleField = "read_num"; // 具体文章
statsCaseClinicalField = "article_read_num"; // 全部文章
}
// 收藏
if (type == 2){
caseClinicalArticleField = "collect_num"; // 具体文章
statsCaseClinicalField = "article_collect_num"; // 全部文章
}
// 评论
if (type == 3){
caseClinicalArticleField = "comment_num"; // 具体文章
statsCaseClinicalField = "article_comment_num"; // 全部文章
}
// 文章数
if (type == 4){
statsCaseClinicalField = "article_num"; // 全部文章
}
if (!caseClinicalArticleField.isEmpty()){
caseClinicalArticleDao.dec(Long.valueOf(articleId),caseClinicalArticleField,num);
}
statsCaseClinicalDao.dec(1L,statsCaseClinicalField,num);
return true;
} catch (Exception e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
}
// /**
// * 处理文章所属医院的数量统计
// */
// @Transactional
// public boolean handleHospitalStat(String doctorId,Long oldHospitalId,String newHospitalId){
// try {
// // 获取统计表医生数据
// LambdaQueryWrapper<StatsCaseClinicalDoctorModel> doctorQueryWrapper = new LambdaQueryWrapper<>();
// doctorQueryWrapper.eq(StatsCaseClinicalDoctorModel::getDoctorId, doctorId);
// StatsCaseClinicalDoctorModel statsCaseClinicalDoctor = statsCaseClinicalDoctorDao.selectOne(doctorQueryWrapper);
// if (statsCaseClinicalDoctor == null){
// return true;
// }
//
// // 获取旧医院数据
// StatsCaseClinicalHospitalModel statsCaseClinicalHospital = statsCaseClinicalHospitalDao.selectById(oldHospitalId);
// if (statsCaseClinicalHospital == null){
// throw new BusinessException("操作失败");
// }
//
// // 减少数-文章
// statsCaseClinicalHospitalDao.dec(oldHospitalId,"article_num",statsCaseClinicalDoctor.getArticleNum());
//
// // 减少阅读数-文章
// statsCaseClinicalHospitalDao.dec(oldHospitalId,"article_read_num",statsCaseClinicalDoctor.getArticleReadNum());
//
// // 减少收藏数-文章
// statsCaseClinicalHospitalDao.dec(oldHospitalId,"article_collect_num",statsCaseClinicalDoctor.getArticleCollectNum());
//
// // 减少评论数-文章
// statsCaseClinicalHospitalDao.dec(oldHospitalId,"article_comment_num",statsCaseClinicalDoctor.getArticleCommentNum());
//
// // 减少数-视频
// statsCaseClinicalHospitalDao.dec(oldHospitalId,"video_num",statsCaseClinicalDoctor.getVideoNum());
//
// // 减少阅读数-视频
// statsCaseClinicalHospitalDao.dec(oldHospitalId,"video_read_num",statsCaseClinicalDoctor.getVideoReadNum());
//
// // 减少收藏数-视频
// statsCaseClinicalHospitalDao.dec(oldHospitalId,"video_collect_num",statsCaseClinicalDoctor.getVideoCollectNum());
//
// // 减少评论数-视频
// statsCaseClinicalHospitalDao.dec(oldHospitalId,"video_comment_num",statsCaseClinicalDoctor.getVideoCommentNum());
//
// // 最后一篇文章发表时间
//
// } catch (Exception e) {
// TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
// return false;
// }
//
// return true;
//
// }
/**
* 检测作品状态
*/
public boolean checkClinicalArticleStatus(CaseClinicalArticleModel caseClinicalArticle){
// 删除状态
if (caseClinicalArticle.getDeleteStatus() == 1){
return false;
}
// 状态(1:正常 2:禁用)
if (caseClinicalArticle.getArticleStatus() == 2){
return false;
}
return true;
}
}
@@ -0,0 +1,22 @@
package com.example.caseData.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.caseData.dao.StatsCaseClinicalLabelDao;
import com.example.caseData.exception.BusinessException;
import com.example.caseData.model.CaseClinicalArticleAuthorModel;
import com.example.caseData.model.CaseClinicalDoctorModel;
import com.example.caseData.model.CaseClinicalVideoModel;
import com.example.caseData.model.StatsCaseClinicalLabelModel;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.util.List;
@Service
public class CaseClinicalLabelService {
}
@@ -0,0 +1,443 @@
package com.example.caseData.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.caseData.dao.*;
import com.example.caseData.exception.BusinessException;
import com.example.caseData.model.CaseClinicalArticleModel;
import com.example.caseData.model.StatsCaseClinicalDoctorModel;
import com.example.caseData.model.StatsCaseClinicalHospitalModel;
import com.example.caseData.model.StatsCaseClinicalLabelModel;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.time.LocalDateTime;
@Service
public class CaseClinicalService {
@Resource
private StatsCaseClinicalLabelDao statsCaseClinicalLabelDao;
@Resource
private StatsCaseClinicalDoctorDao statsCaseClinicalDoctorDao;
@Resource
private StatsCaseClinicalHospitalDao statsCaseClinicalHospitalDao;
@Resource
private CaseClinicalArticleDao caseClinicalArticleDao;
@Resource
private CaseClinicalVideoDao caseClinicalVideoDao;
/**
* 新增标签统计
* @param labelIden
* @param labelName
* @param type 类型 1:文章 2:视频
* @param lastPushDate
* @return
*/
@Transactional
public StatsCaseClinicalLabelModel IncStatsCaseClinicalLabel(String labelIden,String labelName,Integer type,LocalDateTime lastPushDate){
LambdaQueryWrapper<StatsCaseClinicalLabelModel> mapQueryWrapper = new LambdaQueryWrapper<>();
mapQueryWrapper.eq(StatsCaseClinicalLabelModel::getLabelIden, labelIden);
StatsCaseClinicalLabelModel statsCaseClinicalLabel = statsCaseClinicalLabelDao.selectOne(mapQueryWrapper);
if (statsCaseClinicalLabel == null) {
statsCaseClinicalLabel = new StatsCaseClinicalLabelModel();
statsCaseClinicalLabel.setLabelIden(labelIden);
statsCaseClinicalLabel.setLabelName(labelName);
if (type == 1){
statsCaseClinicalLabel.setArticleNum(1);
}else if(type == 2){
statsCaseClinicalLabel.setVideoNum(1);
}
if (lastPushDate!=null){
statsCaseClinicalLabel.setLastPushDate(lastPushDate);
}
statsCaseClinicalLabelDao.insert(statsCaseClinicalLabel);
}else{
if (type == 1){
statsCaseClinicalLabelDao.inc(statsCaseClinicalLabel.getLabelIden(),"article_num",1);
}else{
statsCaseClinicalLabelDao.inc(statsCaseClinicalLabel.getLabelIden(),"video_num",1);
}
}
return statsCaseClinicalLabel;
}
/**
* 减少标签统计
* @param labelIden
* @param type 类型 1:文章 2:视频
* @return
*/
@Transactional
public StatsCaseClinicalLabelModel DecStatsCaseClinicalLabel(String labelIden,Integer type){
LambdaQueryWrapper<StatsCaseClinicalLabelModel> mapQueryWrapper = new LambdaQueryWrapper<>();
mapQueryWrapper.eq(StatsCaseClinicalLabelModel::getLabelIden, labelIden);
StatsCaseClinicalLabelModel statsCaseClinicalLabel = statsCaseClinicalLabelDao.selectOne(mapQueryWrapper);
if (statsCaseClinicalLabel == null) {
return null;
}else{
if (type == 1){
// 最后一篇文章发表时间
LocalDateTime lastPushDate = caseClinicalArticleDao.selectLastArticlePushDateByLabelId(labelIden);
if (lastPushDate != null){
statsCaseClinicalLabel.setLastPushDate(lastPushDate);
statsCaseClinicalLabelDao.updateById(statsCaseClinicalLabel);
}
statsCaseClinicalLabelDao.dec(statsCaseClinicalLabel.getLabelIden(),"article_num",1);
}else{
// 最后一篇文章发表时间
LocalDateTime lastPushDate = caseClinicalVideoDao.selectLastVideoPushDateByLabelId(labelIden);
if (lastPushDate != null){
statsCaseClinicalLabel.setLastPushDate(lastPushDate);
statsCaseClinicalLabelDao.updateById(statsCaseClinicalLabel);
}
statsCaseClinicalLabelDao.dec(statsCaseClinicalLabel.getLabelIden(),"video_num",1);
}
}
return statsCaseClinicalLabel;
}
// 新增医生统计
@Transactional
public StatsCaseClinicalDoctorModel IncStatsCaseClinicalDoctor(String doctorId,Integer type,LocalDateTime lastPushDate){
LambdaQueryWrapper<StatsCaseClinicalDoctorModel> mapQueryWrapper = new LambdaQueryWrapper<>();
mapQueryWrapper.eq(StatsCaseClinicalDoctorModel::getDoctorId, doctorId);
StatsCaseClinicalDoctorModel statsCaseClinicalDoctor = statsCaseClinicalDoctorDao.selectOne(mapQueryWrapper);
if (statsCaseClinicalDoctor == null) {
statsCaseClinicalDoctor = new StatsCaseClinicalDoctorModel();
statsCaseClinicalDoctor.setDoctorId(Long.valueOf(doctorId));
if (type == 1){
statsCaseClinicalDoctor.setArticleNum(1);
}else if(type == 2){
statsCaseClinicalDoctor.setVideoNum(1);
}
if (lastPushDate!=null){
statsCaseClinicalDoctor.setLastPushDate(lastPushDate);
}
statsCaseClinicalDoctorDao.insert(statsCaseClinicalDoctor);
}else{
if (type == 1){
statsCaseClinicalDoctorDao.inc(statsCaseClinicalDoctor.getDoctorId(),"article_num",1);
}else{
statsCaseClinicalDoctorDao.inc(statsCaseClinicalDoctor.getDoctorId(),"video_num",1);
}
}
return statsCaseClinicalDoctor;
}
/**
* 减少医生统计
* @param doctorId
* @param type 类型 1:文章 2:视频
* @return
*/
@Transactional
public StatsCaseClinicalDoctorModel DecStatsCaseClinicalDoctor(String doctorId,Integer type){
LambdaQueryWrapper<StatsCaseClinicalDoctorModel> mapQueryWrapper = new LambdaQueryWrapper<>();
mapQueryWrapper.eq(StatsCaseClinicalDoctorModel::getDoctorId, doctorId);
StatsCaseClinicalDoctorModel statsCaseClinicalDoctor = statsCaseClinicalDoctorDao.selectOne(mapQueryWrapper);
if (statsCaseClinicalDoctor == null) {
return null;
}else{
if (type == 1){
// 最后一篇文章发表时间
LocalDateTime lastPushDate = caseClinicalArticleDao.selectLastArticlePushDateByDoctorId(Long.valueOf(doctorId));
if (lastPushDate != null){
statsCaseClinicalDoctor.setLastPushDate(lastPushDate);
statsCaseClinicalDoctorDao.updateById(statsCaseClinicalDoctor);
}
statsCaseClinicalDoctorDao.dec(statsCaseClinicalDoctor.getDoctorId(),"article_num",1);
}else{
// 最后一篇文章发表时间
LocalDateTime lastPushDate = caseClinicalVideoDao.selectLastVideoPushDateByDoctorId(Long.valueOf(doctorId));
if (lastPushDate != null){
statsCaseClinicalDoctor.setLastPushDate(lastPushDate);
statsCaseClinicalDoctorDao.updateById(statsCaseClinicalDoctor);
}
statsCaseClinicalDoctorDao.dec(statsCaseClinicalDoctor.getDoctorId(),"video_num",1);
}
}
return statsCaseClinicalDoctor;
}
// 新增医院统计
@Transactional
public StatsCaseClinicalHospitalModel IncStatsCaseClinicalHospital(String hospitalId,Integer type,LocalDateTime lastPushDate,Integer num){
LambdaQueryWrapper<StatsCaseClinicalHospitalModel> mapQueryWrapper = new LambdaQueryWrapper<>();
mapQueryWrapper.eq(StatsCaseClinicalHospitalModel::getHospitalId, hospitalId);
StatsCaseClinicalHospitalModel statsCaseClinicalHospital = statsCaseClinicalHospitalDao.selectOne(mapQueryWrapper);
if (statsCaseClinicalHospital == null) {
statsCaseClinicalHospital = new StatsCaseClinicalHospitalModel();
statsCaseClinicalHospital.setHospitalId(Long.valueOf(hospitalId));
if (type == 1){
statsCaseClinicalHospital.setArticleNum(num);
}else if(type == 2){
statsCaseClinicalHospital.setVideoNum(num);
}
if (lastPushDate!=null){
statsCaseClinicalHospital.setLastPushDate(lastPushDate);
}
statsCaseClinicalHospitalDao.insert(statsCaseClinicalHospital);
}else{
if (type == 1){
if (lastPushDate!=null){
statsCaseClinicalHospital.setLastPushDate(lastPushDate);
statsCaseClinicalHospitalDao.updateById(statsCaseClinicalHospital);
}
statsCaseClinicalHospitalDao.inc(statsCaseClinicalHospital.getHospitalId(),"article_num",num);
}else{
statsCaseClinicalHospitalDao.inc(statsCaseClinicalHospital.getHospitalId(),"video_num",num);
}
}
return statsCaseClinicalHospital;
}
/**
* 减少医院统计
* @param hospitalId
* @param type 类型 1:文章 2:视频
* @return
*/
@Transactional
public StatsCaseClinicalHospitalModel DecStatsCaseClinicalHospital(String hospitalId,Integer type,Integer num){
LambdaQueryWrapper<StatsCaseClinicalHospitalModel> mapQueryWrapper = new LambdaQueryWrapper<>();
mapQueryWrapper.eq(StatsCaseClinicalHospitalModel::getHospitalId, hospitalId);
StatsCaseClinicalHospitalModel statsCaseClinicalHospital = statsCaseClinicalHospitalDao.selectOne(mapQueryWrapper);
if (statsCaseClinicalHospital == null) {
return null;
}else{
if (type == 1){
// 最后一篇文章发表时间
LocalDateTime lastPushDate = caseClinicalArticleDao.selectLastArticlePushDateByHospitalId(Long.valueOf(hospitalId));
if (lastPushDate != null){
statsCaseClinicalHospital.setLastPushDate(lastPushDate);
statsCaseClinicalHospitalDao.updateById(statsCaseClinicalHospital);
}
statsCaseClinicalHospitalDao.dec(statsCaseClinicalHospital.getHospitalId(),"article_num",num);
}else{
// 最后一篇文章发表时间
LocalDateTime lastPushDate = caseClinicalVideoDao.selectLastVideoPushDateByHospitalId(Long.valueOf(hospitalId));
if (lastPushDate != null){
statsCaseClinicalHospital.setLastPushDate(lastPushDate);
statsCaseClinicalHospitalDao.updateById(statsCaseClinicalHospital);
}
statsCaseClinicalHospitalDao.dec(statsCaseClinicalHospital.getHospitalId(),"video_num",num);
}
}
return statsCaseClinicalHospital;
}
// /**
// * 处理文章所属医院的数量统计
// */
// @Transactional
// public boolean handleHospitalStat(Long doctorId,Long oldHospitalId,Long newHospitalId){
// try {
// // 获取统计表医生数据
// LambdaQueryWrapper<StatsCaseClinicalDoctorModel> doctorQueryWrapper = new LambdaQueryWrapper<>();
// doctorQueryWrapper.eq(StatsCaseClinicalDoctorModel::getDoctorId, doctorId);
// StatsCaseClinicalDoctorModel statsCaseClinicalDoctor = statsCaseClinicalDoctorDao.selectOne(doctorQueryWrapper);
// if (statsCaseClinicalDoctor == null){
// return true;
// }
//
// // 获取旧医院数据
// LambdaQueryWrapper<StatsCaseClinicalHospitalModel> hospitalQueryWrapper = new LambdaQueryWrapper<>();
// hospitalQueryWrapper.eq(StatsCaseClinicalHospitalModel::getHospitalId, oldHospitalId);
// StatsCaseClinicalHospitalModel statsCaseClinicalHospital = statsCaseClinicalHospitalDao.selectOne(hospitalQueryWrapper);
// if (statsCaseClinicalHospital == null){
// throw new BusinessException("操作失败");
// }
//
// // 减少数-文章
// statsCaseClinicalHospitalDao.dec(oldHospitalId,"article_num",statsCaseClinicalDoctor.getArticleNum());
//
// // 减少阅读数-文章
// statsCaseClinicalHospitalDao.dec(oldHospitalId,"article_read_num",statsCaseClinicalDoctor.getArticleReadNum());
//
// // 减少收藏数-文章
// statsCaseClinicalHospitalDao.dec(oldHospitalId,"article_collect_num",statsCaseClinicalDoctor.getArticleCollectNum());
//
// // 减少评论数-文章
// statsCaseClinicalHospitalDao.dec(oldHospitalId,"article_comment_num",statsCaseClinicalDoctor.getArticleCommentNum());
//
// // 减少数-视频
// statsCaseClinicalHospitalDao.dec(oldHospitalId,"video_num",statsCaseClinicalDoctor.getVideoNum());
//
// // 减少阅读数-视频
// statsCaseClinicalHospitalDao.dec(oldHospitalId,"video_read_num",statsCaseClinicalDoctor.getVideoReadNum());
//
// // 减少收藏数-视频
// statsCaseClinicalHospitalDao.dec(oldHospitalId,"video_collect_num",statsCaseClinicalDoctor.getVideoCollectNum());
//
// // 减少评论数-视频
// statsCaseClinicalHospitalDao.dec(oldHospitalId,"video_comment_num",statsCaseClinicalDoctor.getVideoCommentNum());
//
// // 最后一篇文章发表时间
// LocalDateTime lastPushDate = caseClinicalArticleDao.selectLastArticlePushDateByHospitalId(oldHospitalId);
// if (lastPushDate != null){
// statsCaseClinicalHospital.setLastPushDate(lastPushDate);
// statsCaseClinicalHospitalDao.updateById(statsCaseClinicalHospital);
// }
//
// // 获取新医院数据
// hospitalQueryWrapper = new LambdaQueryWrapper<>();
// hospitalQueryWrapper.eq(StatsCaseClinicalHospitalModel::getHospitalId, newHospitalId);
// statsCaseClinicalHospital = statsCaseClinicalHospitalDao.selectOne(hospitalQueryWrapper);
// if (statsCaseClinicalHospital == null){
// // 新增新医院
// statsCaseClinicalHospital = AddStatsCaseClinicalHospital(String.valueOf(newHospitalId));
// }
//
// // 增加数-文章
// statsCaseClinicalHospitalDao.inc(newHospitalId,"article_num",statsCaseClinicalDoctor.getArticleNum());
//
// // 增加阅读数-文章
// statsCaseClinicalHospitalDao.inc(newHospitalId,"article_read_num",statsCaseClinicalDoctor.getArticleReadNum());
//
// // 增加收藏数-文章
// statsCaseClinicalHospitalDao.inc(newHospitalId,"article_collect_num",statsCaseClinicalDoctor.getArticleCollectNum());
//
// // 增加评论数-文章
// statsCaseClinicalHospitalDao.inc(newHospitalId,"article_comment_num",statsCaseClinicalDoctor.getArticleCommentNum());
//
// // 增加数-视频
// statsCaseClinicalHospitalDao.inc(newHospitalId,"video_num",statsCaseClinicalDoctor.getVideoNum());
//
// // 增加阅读数-视频
// statsCaseClinicalHospitalDao.inc(newHospitalId,"video_read_num",statsCaseClinicalDoctor.getVideoReadNum());
//
// // 增加收藏数-视频
// statsCaseClinicalHospitalDao.inc(newHospitalId,"video_collect_num",statsCaseClinicalDoctor.getVideoCollectNum());
//
// // 增加评论数-视频
// statsCaseClinicalHospitalDao.inc(newHospitalId,"video_comment_num",statsCaseClinicalDoctor.getVideoCommentNum());
//
// // 最后一篇文章发表时间
// lastPushDate = caseClinicalArticleDao.selectLastArticlePushDateByHospitalId(newHospitalId);
// if (lastPushDate != null){
// statsCaseClinicalHospital.setLastPushDate(lastPushDate);
// statsCaseClinicalHospitalDao.updateById(statsCaseClinicalHospital);
// }
// } catch (Exception e) {
// TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
// return false;
// }
//
// return true;
//
// }
//
// /**
// * 处理文章所属医生的数量统计
// */
// @Transactional
// public boolean handleDoctorStat(Long oldDoctorId,Long newDoctorId){
// try {
// // 获取统计表医生数据-旧
// LambdaQueryWrapper<StatsCaseClinicalDoctorModel> doctorQueryWrapper = new LambdaQueryWrapper<>();
// doctorQueryWrapper.eq(StatsCaseClinicalDoctorModel::getDoctorId, oldDoctorId);
// StatsCaseClinicalDoctorModel statsCaseClinicalDoctor = statsCaseClinicalDoctorDao.selectOne(doctorQueryWrapper);
// if (statsCaseClinicalDoctor == null){
// return true;
// }
//
// // 减少数-文章
// statsCaseClinicalDoctorDao.dec(oldDoctorId,"article_num",statsCaseClinicalDoctor.getArticleNum());
//
// // 减少阅读数-文章
// statsCaseClinicalDoctorDao.dec(oldDoctorId,"article_read_num",statsCaseClinicalDoctor.getArticleReadNum());
//
// // 减少收藏数-文章
// statsCaseClinicalDoctorDao.dec(oldDoctorId,"article_collect_num",statsCaseClinicalDoctor.getArticleCollectNum());
//
// // 减少评论数-文章
// statsCaseClinicalDoctorDao.dec(oldDoctorId,"article_comment_num",statsCaseClinicalDoctor.getArticleCommentNum());
//
// // 减少数-视频
// statsCaseClinicalDoctorDao.dec(oldDoctorId,"video_num",statsCaseClinicalDoctor.getVideoNum());
//
// // 减少阅读数-视频
// statsCaseClinicalDoctorDao.dec(oldDoctorId,"video_read_num",statsCaseClinicalDoctor.getVideoReadNum());
//
// // 减少收藏数-视频
// statsCaseClinicalDoctorDao.dec(oldDoctorId,"video_collect_num",statsCaseClinicalDoctor.getVideoCollectNum());
//
// // 减少评论数-视频
// statsCaseClinicalDoctorDao.dec(oldDoctorId,"video_comment_num",statsCaseClinicalDoctor.getVideoCommentNum());
//
// // 最后一篇文章发表时间
// LocalDateTime lastPushDate = caseClinicalArticleDao.selectLastArticlePushDateByDoctorId(oldDoctorId);
// if (lastPushDate != null){
// statsCaseClinicalDoctor.setLastPushDate(lastPushDate);
// statsCaseClinicalDoctorDao.updateById(statsCaseClinicalDoctor);
// }
//
// // 获取统计表医生数据-新
// doctorQueryWrapper = new LambdaQueryWrapper<>();
// doctorQueryWrapper.eq(StatsCaseClinicalDoctorModel::getDoctorId, newDoctorId);
// statsCaseClinicalDoctor = statsCaseClinicalDoctorDao.selectOne(doctorQueryWrapper);
// if (statsCaseClinicalDoctor == null){
// // 新增新医生
// statsCaseClinicalDoctor = AddStatsCaseClinicalDoctor(String.valueOf(newDoctorId));
// }
//
// // 增加数-文章
// statsCaseClinicalDoctorDao.inc(newDoctorId,"article_num",statsCaseClinicalDoctor.getArticleNum());
//
// // 增加阅读数-文章
// statsCaseClinicalDoctorDao.inc(newDoctorId,"article_read_num",statsCaseClinicalDoctor.getArticleReadNum());
//
// // 增加收藏数-文章
// statsCaseClinicalDoctorDao.inc(newDoctorId,"article_collect_num",statsCaseClinicalDoctor.getArticleCollectNum());
//
// // 增加评论数-文章
// statsCaseClinicalDoctorDao.inc(newDoctorId,"article_comment_num",statsCaseClinicalDoctor.getArticleCommentNum());
//
// // 增加数-视频
// statsCaseClinicalDoctorDao.inc(newDoctorId,"video_num",statsCaseClinicalDoctor.getVideoNum());
//
// // 增加阅读数-视频
// statsCaseClinicalDoctorDao.inc(newDoctorId,"video_read_num",statsCaseClinicalDoctor.getVideoReadNum());
//
// // 增加收藏数-视频
// statsCaseClinicalDoctorDao.inc(newDoctorId,"video_collect_num",statsCaseClinicalDoctor.getVideoCollectNum());
//
// // 增加评论数-视频
// statsCaseClinicalDoctorDao.inc(newDoctorId,"video_comment_num",statsCaseClinicalDoctor.getVideoCommentNum());
//
// // 最后一篇文章发表时间
// lastPushDate = caseClinicalArticleDao.selectLastArticlePushDateByDoctorId(newDoctorId);
// if (lastPushDate != null){
// statsCaseClinicalDoctor.setLastPushDate(lastPushDate);
// statsCaseClinicalDoctorDao.updateById(statsCaseClinicalDoctor);
// }
// } catch (Exception e) {
// TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
// return false;
// }
//
// return true;
// }
}
@@ -1,23 +1,46 @@
package com.example.caseData.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.caseData.config.AppConfig;
import com.example.caseData.config.EnvConfig;
import com.example.caseData.dao.*;
import com.example.caseData.exception.BusinessException;
import com.example.caseData.extend.aliyun.Oss;
import com.example.caseData.extend.app.Base;
import com.example.caseData.extend.app.UserInfo.GetUserInfoResponse;
import com.example.caseData.extend.app.UserInfo.UserInfo;
import com.example.caseData.extend.app.UserPoint.UserPoint;
import com.example.caseData.extend.app.Video.Video;
import com.example.caseData.extend.app.label.Label;
import com.example.caseData.model.*;
import com.example.caseData.model.UserCollectClinicalVideoModel;
import com.example.caseData.request.CaseClinicalVideoRequest.addClinicalVideoApp;
import com.example.caseData.request.CaseClinicalVideoRequest.addClinicalVideoComment;
import com.example.caseData.utils.ImageUtil;
import com.example.caseData.utils.Replace;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.util.List;
import java.util.Objects;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
//import static com.baomidou.mybatisplus.extension.toolkit.Db.removeById;
//import static com.baomidou.mybatisplus.extension.toolkit.Db.save;
@Slf4j
@Service
public class CaseClinicalVideoService {
@Resource
@@ -26,12 +49,21 @@ public class CaseClinicalVideoService {
@Resource
private CaseClinicalVideoDao caseClinicalVideoDao;
@Resource
private CaseClinicalVideoLabelDao caseClinicalVideoLabelDao;
@Resource
private StatsCaseClinicalDao statsCaseClinicalDao;
@Resource
private UserDao userDao;
@Resource
private EnvConfig envConfig;
@Resource
private BasicHospitalDao basicHospitalDao;
@Resource
private StatsCaseClinicalHospitalDao statsCaseClinicalHospitalDao;
@@ -50,6 +82,32 @@ public class CaseClinicalVideoService {
@Resource
private UserCommentClinicalVideoDao userCommentClinicalVideoDao;
@Resource
private CaseClinicalLabelService caseClinicalLabelService;
@Resource
private StatsCaseClinicalLabelDao statsCaseClinicalLabelDao;
@Resource
private Video Video;
@Resource
private UserInfo userInfo;
@Resource
private UserService userService;
@Resource
private CaseClinicalService caseClinicalService;
@Resource
private CertService certService;
@Resource
private CaseClinicalDoctorCertDao caseClinicalDoctorCertDao;
@Autowired
private AppConfig appConfig;
/**
* 新增收藏-临床病例库-视频
* @param videoId 视频id
@@ -73,25 +131,11 @@ public class CaseClinicalVideoService {
return false;
}
// 增加视频收藏数
caseClinicalVideoDao.inc(Long.valueOf(videoId),"collect_num",1);
// 增加视频总收藏数
statsCaseClinicalDao.inc(1L,"video_collect_num",1);
// 获取视频作者
LambdaQueryWrapper<CaseClinicalVideoAuthorModel> authorQueryWrapper = new LambdaQueryWrapper<>();
authorQueryWrapper.eq(CaseClinicalVideoAuthorModel::getVideoId, videoId);
List<CaseClinicalVideoAuthorModel> caseClinicalVideoAuthors = caseClinicalVideoAuthorDao.selectList(authorQueryWrapper);
for (CaseClinicalVideoAuthorModel author : caseClinicalVideoAuthors) {
// 查询医生
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectById(author.getDoctorId());
// 增加医院视频收藏数
statsCaseClinicalHospitalDao.inc(caseClinicalDoctor.getHospitalId(),"video_collect_num",1);
// 增加医生视频收藏数
statsCaseClinicalDoctorDao.inc(caseClinicalDoctor.getDoctorId(),"video_collect_num",1);
// 新增统计字段
boolean r = IncClinicalVideoStats(videoId,2,1);
if (!r){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
return true;
@@ -118,25 +162,11 @@ public class CaseClinicalVideoService {
return false;
}
// 减少视频收藏数
caseClinicalVideoDao.dec(Long.valueOf(videoId),"collect_num",1);
// 减少视频总收藏数
statsCaseClinicalDao.dec(1L,"video_collect_num",1);
// 获取视频作者
LambdaQueryWrapper<CaseClinicalVideoAuthorModel> authorQueryWrapper = new LambdaQueryWrapper<>();
authorQueryWrapper.eq(CaseClinicalVideoAuthorModel::getVideoId, videoId);
List<CaseClinicalVideoAuthorModel> caseClinicalVideoAuthors = caseClinicalVideoAuthorDao.selectList(authorQueryWrapper);
for (CaseClinicalVideoAuthorModel author : caseClinicalVideoAuthors) {
// 查询医生
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectById(author.getDoctorId());
// 减少医院视频收藏数
statsCaseClinicalHospitalDao.dec(caseClinicalDoctor.getHospitalId(),"video_collect_num",1);
// 减少医生视频收藏数
statsCaseClinicalDoctorDao.dec(caseClinicalDoctor.getDoctorId(),"video_collect_num",1);
// 减少视频的统计字段
boolean r = DecClinicalVideoStats(videoId,2,1);
if (!r){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
return true;
@@ -149,7 +179,11 @@ public class CaseClinicalVideoService {
* @return bool
*/
@Transactional
public boolean AddClinicalVideoComment(String videoId, String userId, addClinicalVideoComment request){
public Map<String, Object> AddClinicalVideoComment(String videoId, String userId, addClinicalVideoComment request){
Map<String, Object> resultData = new HashMap<>();
resultData.put("status", 1);
resultData.put("message", "成功");
// 获取视频数据
CaseClinicalVideoModel video = caseClinicalVideoDao.selectById(videoId);
if (video == null) {
@@ -186,7 +220,26 @@ public class CaseClinicalVideoService {
}
int res = userCommentClinicalVideoDao.insert(userCommentClinicalVideoData);
return res > 0;
if (res <= 0){
throw new BusinessException("操作失败");
}
// 新增文章的统计字段
boolean r = IncClinicalVideoStats(videoId,3,1);
if (!r){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
throw new BusinessException("操作失败");
}
// 获取发放积分次数
Integer num = userService.GetReportUserScore(userId);
if (num < 3){
// 发放积分
resultData.put("status", 2);
userService.ReportUserScore(videoId,2,userId,5);
}
return resultData;
}
/**
@@ -214,10 +267,34 @@ public class CaseClinicalVideoService {
}
// 检测用户是否视频作者
if (!Objects.equals(comment.getUserId(), Long.valueOf(userId))){
// 检测用户是否文章作者
boolean isAuthor = checkUserIsVideoAuthor(String.valueOf(video.getVideoId()),userId);
if (!isAuthor) {
System.out.println(333);
return false;
}
}
// 获取下级评论
LambdaQueryWrapper<UserCommentClinicalVideoModel> videoQueryWrapper = new LambdaQueryWrapper<>();
videoQueryWrapper.eq(UserCommentClinicalVideoModel::getRootId, comment.getCommentId());
List<UserCommentClinicalVideoModel> userCommentClinicalVideos = userCommentClinicalVideoDao.selectList(videoQueryWrapper);
for (UserCommentClinicalVideoModel m : userCommentClinicalVideos){
// 删除评论
int res = userCommentClinicalVideoDao.deleteById(m.getCommentId());
if (res <= 0){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
// 减少文章的统计字段
boolean r = DecClinicalVideoStats(String.valueOf(comment.getVideoId()),2,1);
if (!r){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
}
// 删除评论
int res = userCommentClinicalVideoDao.deleteById(comment.getCommentId());
@@ -226,6 +303,13 @@ public class CaseClinicalVideoService {
return false;
}
// 减少文章的统计字段
boolean r = DecClinicalVideoStats(String.valueOf(comment.getVideoId()),2,1);
if (!r){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
return true;
}
@@ -361,4 +445,730 @@ public class CaseClinicalVideoService {
return userCollectClinicalVideoDao.selectOne(mapQueryWrapper);
}
/**
* 新增视频的统计字段
* @param videoId 视频id
* @param type 类型:1:阅读量 2:收藏量 3:评论数 4:文章数
*/
@Transactional
public boolean IncClinicalVideoStats(String videoId,Integer type,Integer num){
try {
String caseClinicalVideoField = ""; // 具体文章
String statsCaseClinicalField = ""; // 全部文章
// 阅读
if (type == 1){
caseClinicalVideoField = "read_num"; // 具体文章
statsCaseClinicalField = "video_read_num"; // 全部文章
}
// 收藏
if (type == 2){
caseClinicalVideoField = "collect_num"; // 具体文章
statsCaseClinicalField = "video_collect_num"; // 全部文章
}
// 评论
if (type == 3){
caseClinicalVideoField = "comment_num"; // 具体文章
statsCaseClinicalField = "video_comment_num"; // 全部文章
}
// 文章数
if (type == 4){
statsCaseClinicalField = "video_num"; // 全部文章
}
if (!caseClinicalVideoField.isEmpty()){
caseClinicalVideoDao.inc(Long.valueOf(videoId),caseClinicalVideoField,num);
}
statsCaseClinicalDao.inc(1L,statsCaseClinicalField,num);
return true;
} catch (Exception e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
}
/**
* 减少视频的统计字段
* @param videoId 文章id
* @param type 类型:1:阅读量 2:收藏量 3:评论数 4:文章数
*/
@Transactional
public boolean DecClinicalVideoStats(String videoId,Integer type,Integer num){
try {
String caseClinicalVideoField = ""; // 具体文章
String statsCaseClinicalField = ""; // 全部文章
// 阅读
if (type == 1){
caseClinicalVideoField = "read_num"; // 具体文章
statsCaseClinicalField = "video_read_num"; // 全部文章
}
// 收藏
if (type == 2){
caseClinicalVideoField = "collect_num"; // 具体文章
statsCaseClinicalField = "video_collect_num"; // 全部文章
}
// 评论
if (type == 3){
caseClinicalVideoField = "comment_num"; // 具体文章
statsCaseClinicalField = "video_comment_num"; // 全部文章
}
// 文章数
if (type == 4){
statsCaseClinicalField = "video_num"; // 全部文章
}
if (!caseClinicalVideoField.isEmpty()){
caseClinicalVideoDao.dec(Long.valueOf(videoId),caseClinicalVideoField,num);
}
statsCaseClinicalDao.dec(1L,statsCaseClinicalField,num);
return true;
} catch (Exception e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
}
/**
* 检测作品状态
*/
public boolean checkClinicalVideoStatus(CaseClinicalVideoModel caseClinicalVideo){
// 删除状态
if (caseClinicalVideo.getDeleteStatus() == 1){
return false;
}
// 状态(1:正常 2:禁用)
if (caseClinicalVideo.getVideoStatus() == 2){
return false;
}
return true;
}
/**
* 临床病例库-视频-同步app视频
* @return bool
*/
@Transactional
public boolean AddClinicalVideoApp(HttpServletRequest request){
try {
// 1. 手动读取请求体并转为 addClinicalVideoApp 对象
ObjectMapper objectMapper = new ObjectMapper();
addClinicalVideoApp r = objectMapper.readValue(request.getInputStream(), addClinicalVideoApp.class);
System.out.println(r);
log.info(r.toString());
// 2. 自动校验(@Validated)
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<addClinicalVideoApp>> violations = validator.validate(r);
if (!violations.isEmpty()) {
String errorMessage = violations.iterator().next().getMessage();
throw new BusinessException("-1", errorMessage);
}
String secretKey = "26e8675f44565b1ed4eaaa0fcf3531d7";
if (Objects.equals(envConfig.getActive(), "prod")){
secretKey = "a1e5d9ca1d3fbae69532f134bf6cdee9";
}
// 检测签名
Video.checkSign(request,secretKey,r,objectMapper);
if (r.getIsLink() == null){
r.setIsLink(0);
}
// 获取视频数据
LambdaQueryWrapper<CaseClinicalVideoModel> videoQueryWrapper = new LambdaQueryWrapper<>();
videoQueryWrapper.eq(CaseClinicalVideoModel::getVideoNo, r.getVideoNo());
CaseClinicalVideoModel caseClinicalVideo = caseClinicalVideoDao.selectOne(videoQueryWrapper);
// 修改
if (Objects.equals(r.getAction(), "update")){
if (caseClinicalVideo == null){
r.setAction("add");
}
}
// 二维码-文章/视频
byte[] qrCodeByte = new byte[0];
// 新增
if (Objects.equals(r.getAction(), "add")){
// 是否需要处理作者
boolean isNeedHandleAuthor = false;
if (caseClinicalVideo != null){
if (caseClinicalVideo.getDeleteStatus() == 1){
caseClinicalVideo.setVideoTitle(r.getVideoTitle());
caseClinicalVideo.setVideoNo(r.getVideoNo());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime pushDate = LocalDateTime.parse(r.getPushDate(), formatter);
caseClinicalVideo.setPushDate(pushDate);
caseClinicalVideoDao.updateById(caseClinicalVideo);
// 此处视频被删除过,也需要处理一下作者
isNeedHandleAuthor = true;
}
}else{
// 新增视频
caseClinicalVideo = new CaseClinicalVideoModel();
caseClinicalVideo.setVideoTitle(r.getVideoTitle());
caseClinicalVideo.setVideoNo(r.getVideoNo());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime pushDate = LocalDateTime.parse(r.getPushDate(), formatter);
caseClinicalVideo.setPushDate(pushDate);
caseClinicalVideo.setIsLink(r.getIsLink());
caseClinicalVideo.setIsLinkUrl(r.getIsLinkUrl());
caseClinicalVideo.setDeleteStatus(0);
int res = caseClinicalVideoDao.insert(caseClinicalVideo);
if (res <= 0){
throw new BusinessException("-1", "内部错误,添加视频失败");
}
try {
// 生成用户分享二维码-文章/视频
qrCodeByte = userService.CreateUserCaseClinicalUnlimitedQrcode(String.valueOf(caseClinicalVideo.getVideoId()),2);
} catch (Exception e) {
// 不处理
throw new BusinessException("-1", e.getMessage());
}
}
// 新增统计
IncClinicalVideoStats(String.valueOf(caseClinicalVideo.getVideoId()),4,1);
// 作者处理
if (r.getAuthor() != null) {
AddClinicalVideoAppAuthor(caseClinicalVideo,r,qrCodeByte);
}
// 作者处理-该视频被删除过
if (isNeedHandleAuthor){
// 获取全部作者
LambdaQueryWrapper<CaseClinicalVideoAuthorModel> authorQueryWrapper = new LambdaQueryWrapper<>();
authorQueryWrapper.eq(CaseClinicalVideoAuthorModel::getVideoId, caseClinicalVideo.getVideoId());
List<CaseClinicalVideoAuthorModel> caseClinicalVideoAuthors = caseClinicalVideoAuthorDao.selectList(authorQueryWrapper);
for (CaseClinicalVideoAuthorModel b : caseClinicalVideoAuthors){
// 获取医生数据
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectById(b.getDoctorId());
if (caseClinicalDoctor == null){
throw new BusinessException("-1", "医生数据错误");
}
LocalDateTime lastPushDate = caseClinicalVideoDao.selectLastVideoPushDateByDoctorId(caseClinicalDoctor.getDoctorId());
// 新增作者统计
caseClinicalService.IncStatsCaseClinicalDoctor(String.valueOf(caseClinicalDoctor.getDoctorId()),2,lastPushDate);
// 新增医院统计
caseClinicalService.IncStatsCaseClinicalHospital(String.valueOf(caseClinicalDoctor.getHospitalId()),2,lastPushDate,1);
}
}
// 标签处理
if (r.getLabel() != null) {
AddClinicalVideoAppLabel(caseClinicalVideo,r);
}
// 最后处理删除状态。可能存在删除过的,此处标签和作者就不需要再次扣减统计值
caseClinicalVideo.setDeleteStatus(0);
caseClinicalVideoDao.updateById(caseClinicalVideo);
}
// 修改
if (Objects.equals(r.getAction(), "update")){
if (caseClinicalVideo == null){
throw new BusinessException("-1", "无法完成此操作");
}
if (!Objects.equals(caseClinicalVideo.getIsLink(), r.getIsLink())){
caseClinicalVideo.setIsLink(r.getIsLink());
if (!Objects.equals(caseClinicalVideo.getIsLinkUrl(), r.getIsLinkUrl())){
caseClinicalVideo.setIsLinkUrl(r.getIsLinkUrl());
}
}
caseClinicalVideoDao.updateById(caseClinicalVideo);
// 作者处理
if (r.getAuthor() != null) {
AddClinicalVideoAppAuthor(caseClinicalVideo,r,qrCodeByte);
}
// 标签处理
if (r.getLabel() != null) {
AddClinicalVideoAppLabel(caseClinicalVideo,r);
}
}
// 删除
if (Objects.equals(r.getAction(), "delete")){
if (caseClinicalVideo == null){
return true;
}
deleteClinicalVideo(caseClinicalVideo);
}
} catch (Exception e) {
throw new BusinessException("-1", e.getMessage());
}
return true;
}
/**
* 临床病例库-视频-同步app视频-作者处理
* @param caseClinicalVideo
* @param r
*/
@Transactional
public void AddClinicalVideoAppAuthor(CaseClinicalVideoModel caseClinicalVideo,addClinicalVideoApp r,byte[] qrCodeByte){
// 需新增的
List<addClinicalVideoApp.Author> addList = new ArrayList<>();
// 需删除的
List<CaseClinicalVideoAuthorModel> deleteList = new ArrayList<>();
// 已存在的
List<CaseClinicalVideoAuthorModel> existsList = new ArrayList<>();
// 获取全部作者
LambdaQueryWrapper<CaseClinicalVideoAuthorModel> authorQueryWrapper = new LambdaQueryWrapper<>();
authorQueryWrapper.eq(CaseClinicalVideoAuthorModel::getVideoId, caseClinicalVideo.getVideoId());
List<CaseClinicalVideoAuthorModel> caseClinicalVideoAuthors = caseClinicalVideoAuthorDao.selectList(authorQueryWrapper);
for (CaseClinicalVideoAuthorModel b : caseClinicalVideoAuthors){
// 获取医生数据
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectById(b.getDoctorId());
if (caseClinicalDoctor == null){
throw new BusinessException("-1", "医生数据错误");
}
// 获取医生医院数据
BasicHospitalModel basicHospital = basicHospitalDao.selectById(caseClinicalDoctor.getHospitalId());
if (basicHospital == null) {
throw new BusinessException("-1", "医生医院数据错误");
}
caseClinicalDoctor.setBasicHospital(basicHospital);
b.setCaseClinicalDoctor(caseClinicalDoctor);
}
// 处理新增的情况
for (addClinicalVideoApp.Author a : r.getAuthor()){
// 默认本条为新增
boolean exists = true;
for (CaseClinicalVideoAuthorModel b : caseClinicalVideoAuthors){
// 检测医生唯一标识
if (!Objects.equals(b.getCaseClinicalDoctor().getDoctorIden(), "") && b.getCaseClinicalDoctor().getDoctorIden() != null){
if (Objects.equals(a.getDoctorIden(), b.getCaseClinicalDoctor().getDoctorIden())){
exists = false;
break; // 已存在,跳出内层循环
}
}
// 检测医生姓名+医院唯一标识
String akey = a.getDoctorName() + a.getHospitalIden();
String bkey = b.getCaseClinicalDoctor().getDoctorName() + b.getCaseClinicalDoctor().getBasicHospital().getHospitalIden();
if (akey.equals(bkey)){
exists = false;
break; // 已存在,跳出内层循环
}
}
if (exists) {
addList.add(a); // 不存在于旧数据中,加入新增列表
}
}
// 处理删除的情况
for (CaseClinicalVideoAuthorModel b : caseClinicalVideoAuthors){
// 默认本条为删除
boolean exists = true;
for (addClinicalVideoApp.Author a : r.getAuthor()){
if (!Objects.equals(b.getCaseClinicalDoctor().getDoctorIden(), "") && b.getCaseClinicalDoctor().getDoctorIden() != null){
if (Objects.equals(a.getDoctorIden(), b.getCaseClinicalDoctor().getDoctorIden())){
exists = false;
break; // 已存在,跳出内层循环
}
}
// 检测医生姓名+医院唯一标识
String akey = a.getDoctorName() + a.getHospitalIden();
String bkey = b.getCaseClinicalDoctor().getDoctorName() + b.getCaseClinicalDoctor().getBasicHospital().getHospitalIden();
if (akey.equals(bkey)){
exists = false;
break; // 已存在,跳出内层循环
}
}
if (exists) {
deleteList.add(b); // 加入删除列表
}
}
// 处理已存在的情况
for (CaseClinicalVideoAuthorModel b : caseClinicalVideoAuthors){
// 默认本条不添加
boolean exists = false;
for (addClinicalVideoApp.Author a : r.getAuthor()){
if (!Objects.equals(b.getCaseClinicalDoctor().getDoctorIden(), "") && b.getCaseClinicalDoctor().getDoctorIden() != null){
if (Objects.equals(a.getDoctorIden(), b.getCaseClinicalDoctor().getDoctorIden())){
exists = true;
break; // 已存在,跳出内层循环
}
}
// 检测医生姓名+医院唯一标识
String akey = a.getDoctorName() + a.getHospitalIden();
String bkey = b.getCaseClinicalDoctor().getDoctorName() + b.getCaseClinicalDoctor().getBasicHospital().getHospitalIden();
if (akey.equals(bkey)){
exists = true;
break; // 已存在,跳出内层循环
}
}
if (exists) {
existsList.add(b); // 加入已存在列表
}
}
// 删除
Set<String> deleteHospitalSet = new LinkedHashSet<>();
for (CaseClinicalVideoAuthorModel author : deleteList){
// 获取医生数据
LambdaQueryWrapper<CaseClinicalDoctorModel> doctorQueryWrapper = new LambdaQueryWrapper<>();
doctorQueryWrapper.eq(CaseClinicalDoctorModel::getDoctorId, author.getDoctorId());
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectOne(doctorQueryWrapper);
if (caseClinicalDoctor == null) {
throw new BusinessException("-1", "无法完成此操作");
}
// 获取医院数据
BasicHospitalModel basicHospital = basicHospitalDao.selectById(caseClinicalDoctor.getHospitalId());
if (basicHospital == null) {
throw new BusinessException("-1", "无法完成此操作");
}
// 减少作者统计
caseClinicalService.DecStatsCaseClinicalDoctor(String.valueOf(caseClinicalDoctor.getDoctorId()),2);
// 增加需要减少的医院数据
deleteHospitalSet.add(String.valueOf(caseClinicalDoctor.getHospitalId()));
// 删除该作者
caseClinicalVideoAuthorDao.deleteById(author.getAuthorId());
// 删除该作者证书
LambdaQueryWrapper<CaseClinicalDoctorCertModel> certWrapper = new LambdaQueryWrapper<>();
certWrapper.eq(CaseClinicalDoctorCertModel::getDoctorId, caseClinicalDoctor.getDoctorId());
certWrapper.eq(CaseClinicalDoctorCertModel::getId, caseClinicalVideo.getVideoId());
certWrapper.eq(CaseClinicalDoctorCertModel::getType, 2);
caseClinicalDoctorCertDao.delete(certWrapper);
}
if (!deleteHospitalSet.isEmpty()){
// 减少医院统计
for (String hospitalId : deleteHospitalSet ){
caseClinicalService.DecStatsCaseClinicalHospital(hospitalId,2,1);
}
}
// 新增新的作者
Set<String> addHospitalSet = new LinkedHashSet<>();
for (addClinicalVideoApp.Author author : addList){
GetUserInfoResponse result = new GetUserInfoResponse();
if (author.getDoctorIden() == null || Objects.equals(author.getDoctorIden(), "")){
GetUserInfoResponse.ResponsData resultData = new GetUserInfoResponse.ResponsData();
resultData.setOfficeName(author.getDoctorName());
resultData.setRealname(author.getDoctorName());
resultData.setHospitalUuid(author.getHospitalIden());
result.setData(resultData);
}else{
// 获取医生数据
result = userInfo.getUserInfoByUuid(author.getDoctorIden());
}
CaseClinicalDoctorModel caseClinicalDoctor = userService.GetAppCaseClinicalDoctor(result);
CaseClinicalVideoAuthorModel caseClinicalVideoAuthor = new CaseClinicalVideoAuthorModel();
caseClinicalVideoAuthor.setVideoId(caseClinicalVideo.getVideoId());
caseClinicalVideoAuthor.setDoctorId(String.valueOf(caseClinicalDoctor.getDoctorId()));
caseClinicalVideoAuthorDao.insert(caseClinicalVideoAuthor);
LocalDateTime lastPushDate = caseClinicalVideoDao.selectLastVideoPushDateByDoctorId(caseClinicalDoctor.getDoctorId());
// 新增作者统计
caseClinicalService.IncStatsCaseClinicalDoctor(String.valueOf(caseClinicalDoctor.getDoctorId()),2,lastPushDate);
// 增加需要增加的医院数据
addHospitalSet.add(String.valueOf(caseClinicalDoctor.getHospitalId()));
if (caseClinicalVideo.getIsLink() != 1){
// 生成用户证书-文章/视频
if (qrCodeByte == null || qrCodeByte.length == 0) {
// 生成二维码图片
if (caseClinicalVideo.getShareQrcode() == null){
try {
// 生成用户分享二维码-文章/视频
qrCodeByte = userService.CreateUserCaseClinicalUnlimitedQrcode(String.valueOf(caseClinicalVideo.getVideoId()),2);
} catch (Exception e) {
// 不处理
throw new BusinessException("-1", "无法完成此操作1");
}
}else{
// 下载二维码图片
qrCodeByte = Oss.getObjectToByte(caseClinicalVideo.getShareQrcode().replaceFirst("^/+", ""));
if (qrCodeByte == null) {
throw new BusinessException("-1", "无法完成此操作2");
}
}
}
// 下载头像
byte[] avatarByte = new byte[0];
if (caseClinicalDoctor.getAvatar() != null && !caseClinicalDoctor.getAvatar().isEmpty()) {
avatarByte = Oss.getObjectToByte(caseClinicalDoctor.getAvatar().replaceFirst("^/+", ""));
}else{
try {
avatarByte = ImageUtil.readImageToBytes("static/cert/avatar.png");
} catch (Exception e) {
throw new BusinessException("-1", e.getMessage());
}
}
if (avatarByte == null) {
throw new BusinessException("-1", "无法完成此操作");
}
userService.CreateUserCert(
String.valueOf(caseClinicalVideo.getVideoId()),
2,
String.valueOf(caseClinicalDoctor.getDoctorId()),
qrCodeByte,
avatarByte
);
}
}
if (!addHospitalSet.isEmpty()){
// 增加医院统计
for (String hospitalId : addHospitalSet ){
LocalDateTime lastPushDate = caseClinicalVideoDao.selectLastVideoPushDateByHospitalId(Long.valueOf(hospitalId));
// 新增医院统计
caseClinicalService.IncStatsCaseClinicalHospital(hospitalId,2,
lastPushDate,1);
}
}
// 已存在的
for (CaseClinicalVideoAuthorModel b : existsList){
// 如果现有作者的唯一标识为空
CaseClinicalDoctorModel caseClinicalDoctor = b.getCaseClinicalDoctor();
if (b.getCaseClinicalDoctor().getDoctorIden() == null || caseClinicalDoctor.getDoctorIden().isEmpty()) {
for (addClinicalVideoApp.Author a : r.getAuthor()){
// 检测医生姓名+医院唯一标识
String akey = a.getDoctorName() + a.getHospitalIden();
String bkey = b.getCaseClinicalDoctor().getDoctorName() + caseClinicalDoctor.getBasicHospital().getHospitalIden();
if (akey.equals(bkey)){
// 相等
b.getCaseClinicalDoctor().setDoctorIden(a.getDoctorIden());
caseClinicalDoctorDao.updateById(b.getCaseClinicalDoctor());
}
}
}
}
}
// /**
// * 临床病例库-视频-同步app视频-作者处理
// * @param caseClinicalVideo
// * @param r
// */
// @Transactional
// public void AddClinicalVideoAppAuthor(CaseClinicalVideoModel caseClinicalVideo,addClinicalVideoApp r,byte[] qrCodeByte){
// // 获取全部作者
// LambdaQueryWrapper<CaseClinicalVideoAuthorModel> authorQueryWrapper = new LambdaQueryWrapper<>();
// authorQueryWrapper.eq(CaseClinicalVideoAuthorModel::getVideoId, caseClinicalVideo.getVideoId());
// List<CaseClinicalVideoAuthorModel> caseClinicalVideoAuthors = caseClinicalVideoAuthorDao.selectList(authorQueryWrapper);
// for (CaseClinicalVideoAuthorModel author : caseClinicalVideoAuthors){
// // 获取医生数据
// LambdaQueryWrapper<CaseClinicalDoctorModel> doctorQueryWrapper = new LambdaQueryWrapper<>();
// doctorQueryWrapper.eq(CaseClinicalDoctorModel::getDoctorId, author.getDoctorId());
// CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectOne(doctorQueryWrapper);
// if (caseClinicalDoctor == null) {
// throw new BusinessException("-1", "无法完成此操作");
// }
//
// // 获取医院数据
// BasicHospitalModel basicHospital = basicHospitalDao.selectById(caseClinicalDoctor.getHospitalId());
// if (basicHospital == null) {
// throw new BusinessException("-1", "无法完成此操作");
// }
//
// // 减少作者统计
// caseClinicalService.DecStatsCaseClinicalDoctor(String.valueOf(caseClinicalDoctor.getDoctorId()),2);
//
// // 减少医院统计
// caseClinicalService.DecStatsCaseClinicalHospital(String.valueOf(caseClinicalDoctor.getHospitalId()),2);
//
// // 删除该作者
// caseClinicalVideoAuthorDao.deleteById(author.getAuthorId());
//
// // 删除该作者证书
// LambdaQueryWrapper<CaseClinicalDoctorCertModel> certWrapper = new LambdaQueryWrapper<>();
// certWrapper.eq(CaseClinicalDoctorCertModel::getDoctorId, caseClinicalDoctor.getDoctorId());
// certWrapper.eq(CaseClinicalDoctorCertModel::getId, caseClinicalVideo.getVideoId());
// certWrapper.eq(CaseClinicalDoctorCertModel::getType, 2);
// caseClinicalDoctorCertDao.delete(certWrapper);
// }
//
// // 新增新的作者
// for (addClinicalVideoApp.Author author : r.getAuthor()){
// CaseClinicalDoctorModel caseClinicalDoctor = new CaseClinicalDoctorModel();
//
// if (author.getDoctorIden() != null && !author.getDoctorIden().isEmpty()) {
// GetUserInfoResponse result = userInfo.getUserInfoByUuid(author.getDoctorIden());
// caseClinicalDoctor = userService.GetCaseClinicalDoctor(result);
// }else{
// GetUserInfoResponse result = new GetUserInfoResponse();
// GetUserInfoResponse.ResponsData resultData = new GetUserInfoResponse.ResponsData();
// resultData.setOfficeName(author.getDoctorName());
// resultData.setRealname(author.getDoctorName());
// resultData.setHospitalUuid(author.getHospitalIden());
// result.setData(resultData);
// caseClinicalDoctor = userService.GetCaseClinicalDoctor(result);
// }
//
// CaseClinicalVideoAuthorModel caseClinicalVideoAuthor = new CaseClinicalVideoAuthorModel();
// caseClinicalVideoAuthor.setVideoId(caseClinicalVideo.getVideoId());
// caseClinicalVideoAuthor.setDoctorId(String.valueOf(caseClinicalDoctor.getDoctorId()));
// caseClinicalVideoAuthorDao.insert(caseClinicalVideoAuthor);
//
// LocalDateTime lastPushDate = caseClinicalVideoDao.selectLastVideoPushDateByDoctorId(caseClinicalDoctor.getDoctorId());
//
// // 新增作者统计
// caseClinicalService.IncStatsCaseClinicalDoctor(String.valueOf(caseClinicalDoctor.getDoctorId()),2,lastPushDate);
//
// // 新增医院统计
// caseClinicalService.IncStatsCaseClinicalHospital(String.valueOf(caseClinicalDoctor.getHospitalId()),2,lastPushDate);
//
// // 生成用户证书-文章/视频
// if(qrCodeByte == null){
// // 下载二维码图片
// if (Objects.equals(caseClinicalVideo.getShareQrcode(), "")){
// throw new BusinessException("-1", "无法完成此操作");
// }
//
// qrCodeByte = Oss.getObjectToByte(fileName);
// if (qrCodeByte == null) {
// throw new BusinessException("-1", "无法完成此操作");
// }
// }
//
// userService.CreateUserCert(
// String.valueOf(caseClinicalVideo.getVideoId()),
// 2,
// String.valueOf(caseClinicalDoctor.getDoctorId()),
// qrCodeByte
// );
// }
// }
/**
* 临床病例库-视频-同步app视频-标签处理
* @param caseClinicalVideo
* @param r
*/
@Transactional
public void AddClinicalVideoAppLabel(CaseClinicalVideoModel caseClinicalVideo,addClinicalVideoApp r){
// 获取全部b标签
LambdaQueryWrapper<CaseClinicalVideoLabelModel> labelQueryWrapper = new LambdaQueryWrapper<>();
labelQueryWrapper.eq(CaseClinicalVideoLabelModel::getVideoId, caseClinicalVideo.getVideoId());
List<CaseClinicalVideoLabelModel> caseClinicalVideoLabels = caseClinicalVideoLabelDao.selectList(labelQueryWrapper);
for (CaseClinicalVideoLabelModel label : caseClinicalVideoLabels){
if (caseClinicalVideo.getDeleteStatus() == 0) {
// 减少标签统计
caseClinicalService.DecStatsCaseClinicalLabel(label.getAppIden(),2);
}
// 删除视频标签
caseClinicalVideoLabelDao.deleteById(label.getVideoLabelId());
}
for (addClinicalVideoApp.Label label : r.getLabel()){
CaseClinicalVideoLabelModel caseClinicalVideoLabel = new CaseClinicalVideoLabelModel();
caseClinicalVideoLabel.setVideoId(caseClinicalVideo.getVideoId());
caseClinicalVideoLabel.setAppIden(label.getAppIden());
caseClinicalVideoLabel.setLabelName(label.getLabelName());
caseClinicalVideoLabelDao.insert(caseClinicalVideoLabel);
LocalDateTime lastPushDate = caseClinicalVideoDao.selectLastVideoPushDateByLabelId(label.getAppIden());
// 新增标签统计
if (caseClinicalVideo.getDeleteStatus() == 0) {
caseClinicalService.IncStatsCaseClinicalLabel(label.getAppIden(),caseClinicalVideoLabel.getLabelName(),2,lastPushDate);
}
}
}
// 删除视频数据
@Transactional
public void deleteClinicalVideo(CaseClinicalVideoModel caseClinicalVideo){
// 修改视频为删除
caseClinicalVideo.setDeleteStatus(1);
caseClinicalVideoDao.updateById(caseClinicalVideo);
// 修改视频统计数量
DecClinicalVideoStats(String.valueOf(caseClinicalVideo.getVideoId()),4,1);
// 获取视频标签数据
LambdaQueryWrapper<CaseClinicalVideoLabelModel> labelQueryWrapper = new LambdaQueryWrapper<>();
labelQueryWrapper.eq(CaseClinicalVideoLabelModel::getVideoId, caseClinicalVideo.getVideoId());
List<CaseClinicalVideoLabelModel> caseClinicalVideoLabels = caseClinicalVideoLabelDao.selectList(labelQueryWrapper);
for (CaseClinicalVideoLabelModel label : caseClinicalVideoLabels){
// 减少标签统计
caseClinicalService.DecStatsCaseClinicalLabel(label.getAppIden(),2);
}
// 获取视频作者数据
LambdaQueryWrapper<CaseClinicalVideoAuthorModel> authorQueryWrapper = new LambdaQueryWrapper<>();
authorQueryWrapper.eq(CaseClinicalVideoAuthorModel::getVideoId, caseClinicalVideo.getVideoId());
List<CaseClinicalVideoAuthorModel> caseClinicalVideoAuthors = caseClinicalVideoAuthorDao.selectList(authorQueryWrapper);
for (CaseClinicalVideoAuthorModel author : caseClinicalVideoAuthors){
// 获取医生数据
LambdaQueryWrapper<CaseClinicalDoctorModel> doctorQueryWrapper = new LambdaQueryWrapper<>();
doctorQueryWrapper.eq(CaseClinicalDoctorModel::getDoctorId,author.getDoctorId());
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectOne(doctorQueryWrapper);
if (caseClinicalDoctor == null) {
throw new BusinessException("-1", "无法完成此操作");
}
// 减少医生统计
caseClinicalService.DecStatsCaseClinicalDoctor(author.getDoctorId(),2);
// 减少医院统计
caseClinicalService.DecStatsCaseClinicalHospital(String.valueOf(caseClinicalDoctor.getHospitalId()),2,1);
}
}
}
@@ -1,11 +1,13 @@
package com.example.caseData.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.caseData.common.Response;
import com.example.caseData.dao.*;
import com.example.caseData.exception.BusinessException;
import com.example.caseData.model.*;
import com.example.caseData.request.caseExchangeRequest.addCaseExchange;
import com.example.caseData.request.caseExchangeRequest.addCaseExchangeComment;
import com.example.caseData.request.caseExchangeRequest.updateCaseExchange;
import com.example.caseData.utils.JwtUtil;
import com.example.caseData.utils.RegularUtil;
import com.example.caseData.utils.Replace;
@@ -15,9 +17,8 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.time.ZoneId;
import java.util.*;
@Service
public class CaseExchangeService {
@@ -52,12 +53,18 @@ public class CaseExchangeService {
@Resource
private UserDao userDao;
@Resource
private UserService userService;
@Resource
private RegularUtil regularUtil;
@Resource
private UserVoteExchangeDao userVoteExchangeDao;
@Resource
private StatsCaseClinicalLabelDao statsCaseClinicalLabelDao;
/**
* 新增-病例交流
* @param userId 用户id
@@ -133,7 +140,7 @@ public class CaseExchangeService {
caseExchangeData.setUserId(Long.valueOf(userId));
caseExchangeData.setExchangeTitle(r.getExchangeTitle());
caseExchangeData.setExchangeStatus(1);
caseExchangeData.setPushDate(LocalDateTime.now());
caseExchangeData.setPushDate(LocalDateTime.now(ZoneId.of("Asia/Shanghai")));
caseExchangeData.setExchangeContent(r.getExchangeContent());
caseExchangeData.setExchangeSummary(r.getExchangeSummary());
caseExchangeData.setExchangeContentVideo(exchangeContentVideo);
@@ -186,15 +193,168 @@ public class CaseExchangeService {
}
}
// 新增病例交流统计
if (!handleStatsCaseExchange()){
// // 病例交流统计
// if (!handleStatsCaseExchange()){
// throw new BusinessException("操作失败");
// }
//
// // 新增病例交流统计-用户
// if (!handleStatsCaseExchangeUser(userId,"exchange_num")){
// throw new BusinessException("操作失败");
// }
// 发放积分
// userService.ReportUserScore(String.valueOf(caseExchangeData.getExchangeId()),3,userId,50);
return true;
}
/**
* 修改-病例交流
* @param userId 用户id
* @param exchangeId 病例交流id
* @return bool
*/
@Transactional
public boolean UpdateCaseExchange(String userId,String exchangeId, updateCaseExchange r){
// 获取病例交流数据
CaseExchangeModel caseExchange = caseExchangeDao.selectById(exchangeId);
if (caseExchange == null){
throw new BusinessException("非法操作");
}
if (!Objects.equals(caseExchange.getUserId(), Long.valueOf(userId))){
throw new BusinessException("非法操作");
}
// 检测作品状态
if (!checkCaseExchangeStatus(caseExchange)){
throw new BusinessException("非法操作");
}
// 标签
if (r.getCaseExchangeLabel() != null && !r.getCaseExchangeLabel().isEmpty()){
for (updateCaseExchange.CaseExchangeLabelRequest caseExchangeLabelRequest : r.getCaseExchangeLabel()){
if (caseExchangeLabelRequest.getAppIden() == null){
throw new BusinessException("操作失败");
}
// 新增病例交流统计-用户
if (!handleStatsCaseExchangeUser(userId)){
if (caseExchangeLabelRequest.getLabelName() == null){
throw new BusinessException("操作失败");
}
}
}
// 处理违法内容
BasicSensitiveWordService.FilterResult result = basicSensitiveWordService.filter(r.getExchangeContent());
if (result.hasSensitive == 1){
throw new BusinessException("内容中存在敏感词,请修改后提交");
}
if (r.getExchangeSummary() != null){
result = basicSensitiveWordService.filter(r.getExchangeSummary());
if (result.hasSensitive == 1){
throw new BusinessException("总结中存在敏感词,请修改后提交");
}
}
// 匹配预览视频
List<String> videoUrls = regularUtil.extractOssVideosUrls(r.getExchangeContent());
videoUrls.replaceAll(Replace::removeOssDomain);
String exchangeContentVideo = String.join(",", videoUrls);
String exchangeContentImage = "";
if (exchangeContentVideo.isEmpty()){
// 匹配预览图片
List<String> imageUrls = regularUtil.extractOssImageUrls(r.getExchangeContent());
imageUrls.replaceAll(Replace::removeOssDomain);
exchangeContentImage = String.join(",", imageUrls);
}else{
exchangeContentImage = "";
}
// 修改病例交流
caseExchange.setExchangeTitle(r.getExchangeTitle());
caseExchange.setExchangeContent(r.getExchangeContent());
caseExchange.setExchangeSummary(r.getExchangeSummary());
caseExchange.setExchangeContentVideo(exchangeContentVideo);
caseExchange.setExchangeContentImage(exchangeContentImage);
caseExchangeDao.updateById(caseExchange);
// 删除标签
LambdaQueryWrapper<CaseExchangeLabelModel> labelQueryWrapper = new LambdaQueryWrapper<>();
labelQueryWrapper.eq(CaseExchangeLabelModel::getExchangeId, exchangeId);
caseExchangeLabelDao.delete(labelQueryWrapper);
// 新增标签
if (r.getCaseExchangeLabel() != null && !r.getCaseExchangeLabel().isEmpty()){
// 验证标签数据-暂时无法验证,病例库不存标签库
List<updateCaseExchange.CaseExchangeLabelRequest> caseExchangeLabel = r.getCaseExchangeLabel();
for (updateCaseExchange.CaseExchangeLabelRequest label : caseExchangeLabel ){
CaseExchangeLabelModel caseExchangeLabelData = new CaseExchangeLabelModel();
caseExchangeLabelData.setExchangeId(caseExchange.getExchangeId());
caseExchangeLabelData.setAppIden(label.getAppIden());
caseExchangeLabelData.setLabelName(label.getLabelName());
int res = caseExchangeLabelDao.insert(caseExchangeLabelData);
if (res <= 0){
throw new BusinessException("操作失败");
}
}
}
return true;
}
/**
* 删除-病例交流
* @param exchangeId 病例交流id
* @param userId 用户id
* @return bool
*/
@Transactional
public boolean DeleteCaseExchange(String exchangeId, String userId){
// 获取病例交流数据
CaseExchangeModel caseExchange = caseExchangeDao.selectById(exchangeId);
if (caseExchange == null) {
return false;
}
if (!Objects.equals(caseExchange.getUserId(), Long.valueOf(userId))){
throw new BusinessException("非法操作");
}
if (caseExchange.getDeleteStatus() == 1){
return true;
}
// 修改病例交流删除状态
caseExchange.setDeleteStatus(1);
caseExchangeDao.updateById(caseExchange);
// 处理统计数据
boolean r = DecCaseExchangeStats(exchangeId,4,1);
if (!r){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
r = DecCaseExchangeStats(exchangeId,1,caseExchange.getReadNum());
if (!r){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
r = DecCaseExchangeStats(exchangeId,2,caseExchange.getCollectNum());
if (!r){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
r = DecCaseExchangeStats(exchangeId,3,caseExchange.getCommentNum());
if (!r){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
return true;
}
@@ -228,14 +388,12 @@ public class CaseExchangeService {
return false;
}
// 增加病例交流收藏数
caseExchangeDao.inc(Long.valueOf(exchangeId),"collect_num",1);
// 增加病例交流总收藏数
statsCaseExchangeDao.inc(1L,"exchange_collect_num",1);
// 增加用户交流收藏数
statsCaseExchangeUserDao.inc(Long.valueOf(userId),"exchange_collect_num",1);
// 新增统计字段
boolean r = IncCaseExchangeStats(exchangeId,2);
if (!r){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
return true;
}
@@ -261,14 +419,12 @@ public class CaseExchangeService {
return false;
}
// 减少病例交流收藏数
caseExchangeDao.dec(Long.valueOf(exchangeId),"collect_num",1);
// 减少病例交流总收藏数
statsCaseExchangeDao.dec(1L,"exchange_collect_num",1);
// 减少用户交流收藏数
statsCaseExchangeUserDao.dec(Long.valueOf(userId),"exchange_collect_num",1);
// 减少文章的统计字段
boolean r = DecCaseExchangeStats(exchangeId,2,1);
if (!r){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
return true;
}
@@ -280,7 +436,11 @@ public class CaseExchangeService {
* @return bool
*/
@Transactional
public boolean AddCaseExchangeComment(String exchangeId, String userId, addCaseExchangeComment request){
public Map<String, Object> AddCaseExchangeComment(String exchangeId, String userId, addCaseExchangeComment request){
Map<String, Object> resultData = new HashMap<>();
resultData.put("status", 1);
resultData.put("message", "成功");
// 获取病例交流数据
CaseExchangeModel article = caseExchangeDao.selectById(exchangeId);
if (article == null) {
@@ -317,7 +477,26 @@ public class CaseExchangeService {
}
int res = userCommentExchangeDao.insert(userCommentExchangeData);
return res > 0;
if (res <= 0){
throw new BusinessException("操作失败");
}
// 新增统计字段
boolean r = IncCaseExchangeStats(exchangeId,3);
if (!r){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
throw new BusinessException("操作失败");
}
// 获取发放积分次数
Integer num = userService.GetReportUserScore(userId);
if (num < 3){
// 发放积分
resultData.put("status", 2);
userService.ReportUserScore(exchangeId,3,userId,5);
}
return resultData;
}
/**
@@ -349,6 +528,26 @@ public class CaseExchangeService {
return false;
}
// 获取下级评论
LambdaQueryWrapper<UserCommentExchangeModel> exchangeQueryWrapper = new LambdaQueryWrapper<>();
exchangeQueryWrapper.eq(UserCommentExchangeModel::getRootId, comment.getCommentId());
List<UserCommentExchangeModel> userCommentExchanges = userCommentExchangeDao.selectList(exchangeQueryWrapper);
for (UserCommentExchangeModel m : userCommentExchanges){
// 删除评论
int res = userCommentExchangeDao.deleteById(m.getCommentId());
if (res <= 0){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
// 减少文章的统计字段
boolean r = DecCaseExchangeStats(String.valueOf(comment.getCommentId()),2,1);
if (!r){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
}
// 删除评论
int res = userCommentExchangeDao.deleteById(comment.getCommentId());
if (res <= 0){
@@ -356,6 +555,13 @@ public class CaseExchangeService {
return false;
}
// 减少统计字段
boolean r = DecCaseExchangeStats(String.valueOf(comment.getExchangeId()),3,1);
if (!r){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
return true;
}
@@ -480,7 +686,7 @@ public class CaseExchangeService {
* 新增病例交流统计-用户
* @return bool
*/
public boolean handleStatsCaseExchangeUser(String userId){
public boolean handleStatsCaseExchangeUser(String userId,String field){
LambdaQueryWrapper<StatsCaseExchangeUserModel> mapQueryWrapper = new LambdaQueryWrapper<>();
mapQueryWrapper.eq(StatsCaseExchangeUserModel::getUserId, userId);
StatsCaseExchangeUserModel statsCaseExchangeUser = statsCaseExchangeUserDao.selectOne(mapQueryWrapper);
@@ -493,12 +699,148 @@ public class CaseExchangeService {
return res > 0;
}else{
// 增加数量
statsCaseExchangeUserDao.inc(statsCaseExchangeUser.getStatsId(),"exchange_num",1);
statsCaseExchangeUserDao.inc(statsCaseExchangeUser.getStatsId(),field,1);
}
return true;
}
/**
* 新增病例交流统计字段
* @param exchangeId 病例id
* @param type 类型:1:阅读量 2:收藏量 3:评论数
*/
@Transactional
public boolean IncCaseExchangeStats(String exchangeId,Integer type){
try {
// 获取病例数据
CaseExchangeModel caseExchange = caseExchangeDao.selectById(exchangeId);
if (caseExchange == null){
throw new BusinessException("操作失败");
}
LambdaQueryWrapper<StatsCaseExchangeUserModel> mapQueryWrapper = new LambdaQueryWrapper<>();
mapQueryWrapper.eq(StatsCaseExchangeUserModel::getUserId, caseExchange.getUserId());
StatsCaseExchangeUserModel statsCaseExchangeUser = statsCaseExchangeUserDao.selectOne(mapQueryWrapper);
if (statsCaseExchangeUser == null){
throw new BusinessException("操作失败");
}
// 阅读量
if (type == 1){
// 总
statsCaseExchangeDao.inc(1L,"exchange_read_num",1);
// 单
caseExchangeDao.inc(Long.valueOf(exchangeId),"read_num",1);
// 用户-此处无需担心stats_case_exchange_user无数据,发布病例时会新增
statsCaseExchangeUserDao.inc(statsCaseExchangeUser.getUserId(),"exchange_read_num",1);
}
// 收藏量
if (type == 2){
// 总
statsCaseExchangeDao.inc(1L,"exchange_collect_num",1);
// 单
caseExchangeDao.inc(Long.valueOf(exchangeId),"collect_num",1);
// 用户-此处无需担心stats_case_exchange_user无数据,发布病例时会新增
statsCaseExchangeUserDao.inc(statsCaseExchangeUser.getUserId(),"exchange_collect_num",1);
}
// 评论数
if (type == 3){
// 总
statsCaseExchangeDao.inc(1L,"exchange_comment_num",1);
// 单
caseExchangeDao.inc(Long.valueOf(exchangeId),"comment_num",1);
// 用户-此处无需担心stats_case_exchange_user无数据,发布病例时会新增
statsCaseExchangeUserDao.inc(statsCaseExchangeUser.getUserId(),"exchange_comment_num",1);
}
return true;
} catch (Exception e) {
return false;
}
}
/**
* 减少病例交流统计字段
* @param exchangeId 病例id
* @param type 类型:1:阅读量 2:收藏量 3:评论数 4:数量
*/
@Transactional
public boolean DecCaseExchangeStats(String exchangeId,Integer type,Integer num){
try {
// 获取病例数据
CaseExchangeModel caseExchange = caseExchangeDao.selectById(exchangeId);
if (caseExchange == null){
throw new BusinessException("操作失败");
}
LambdaQueryWrapper<StatsCaseExchangeUserModel> mapQueryWrapper = new LambdaQueryWrapper<>();
mapQueryWrapper.eq(StatsCaseExchangeUserModel::getUserId, caseExchange.getUserId());
StatsCaseExchangeUserModel statsCaseExchangeUser = statsCaseExchangeUserDao.selectOne(mapQueryWrapper);
if (statsCaseExchangeUser == null){
throw new BusinessException("操作失败");
}
// 阅读量
if (type == 1){
// 总
statsCaseExchangeDao.dec(1L,"exchange_read_num",num);
// 单
caseExchangeDao.dec(Long.valueOf(exchangeId),"read_num",num);
// 用户
statsCaseExchangeUserDao.dec(statsCaseExchangeUser.getUserId(),"exchange_read_num",num);
}
// 收藏量
if (type == 2){
// 总
statsCaseExchangeDao.dec(1L,"exchange_collect_num",num);
// 单
caseExchangeDao.dec(Long.valueOf(exchangeId),"collect_num",num);
// 用户
statsCaseExchangeUserDao.dec(statsCaseExchangeUser.getUserId(),"exchange_collect_num",num);
}
// 评论数
if (type == 3){
// 总
statsCaseExchangeDao.dec(1L,"exchange_comment_num",num);
// 单
caseExchangeDao.dec(Long.valueOf(exchangeId),"comment_num",num);
// 用户
statsCaseExchangeUserDao.dec(statsCaseExchangeUser.getUserId(),"exchange_comment_num",num);
}
// 数量
if (type == 4){
// 总
statsCaseExchangeDao.dec(1L,"exchange_num",num);
// 用户
statsCaseExchangeUserDao.dec(statsCaseExchangeUser.getUserId(),"exchange_num",num);
}
return true;
} catch (Exception e) {
return false;
}
}
/**
* 新增投票-病例交流
* @param exchangeId 病例交流id
@@ -555,6 +897,115 @@ public class CaseExchangeService {
// 处理投票数
caseExchangeVoteOptionDao.inc(Long.valueOf(optionId),"vote_num",1);
return true;
}
//
// /**
// * 新增病例交流的统计字段
// * @param exchangeId id
// * @param type 类型:1:阅读量 2:收藏量 3:评论数
// */
// @Transactional
// public boolean IncCaseExchangeStats(String exchangeId,String userId,Integer type){
// try {
// // 阅读量
// if (type == 1){
// // 单
// caseExchangeDao.inc(Long.valueOf(exchangeId),"read_num",1);
//
// // 总
// statsCaseExchangeDao.inc(1L,"exchange_read_num",1);
//
// // 此处无需担心stats_case_exchange_user无数据,发布病例时会新增
// statsCaseExchangeUserDao.inc(Long.valueOf(userId),"exchange_read_num",1);
// }
//
// // 收藏量
// if (type == 2){
// // 单
// caseExchangeDao.inc(Long.valueOf(exchangeId),"collect_num",1);
//
// // 总
// statsCaseExchangeDao.inc(1L,"exchange_collect_num",1);
//
// // 此处无需担心stats_case_exchange_user无数据,发布病例时会新增
// statsCaseExchangeUserDao.inc(Long.valueOf(userId),"exchange_collect_num",1);
// }
//
// // 评论数
// if (type == 3){
// // 单
// caseExchangeDao.inc(Long.valueOf(exchangeId),"comment_num",1);
//
// // 总
// statsCaseExchangeDao.inc(1L,"exchange_comment_num",1);
//
// // 此处无需担心stats_case_exchange_user无数据,发布病例时会新增
// statsCaseExchangeUserDao.inc(Long.valueOf(userId),"exchange_comment_num",1);
// }
//
// return true;
// } catch (Exception e) {
// return false;
// }
// }
//
// /**
// * 减少文章的统计字段
// * @param exchangeId id
// * @param type 类型:1:阅读量 2:收藏量 3:评论数
// */
// @Transactional
// public boolean DecCaseExchangeStats(String exchangeId,String userId,Integer type){
// try {
// // 阅读量
// if (type == 1){
// caseExchangeDao.dec(Long.valueOf(exchangeId),"read_num",1);
// statsCaseExchangeDao.dec(1L,"exchange_read_num",1);
//
// // 此处无需担心stats_case_exchange_user无数据,发布病例时会新增
// statsCaseExchangeUserDao.dec(Long.valueOf(userId),"exchange_read_num",1);
// }
//
// // 收藏量
// if (type == 2){
// caseExchangeDao.inc(Long.valueOf(exchangeId),"collect_num",1);
// statsCaseExchangeDao.dec(1L,"exchange_collect_num",1);
//
// // 此处无需担心stats_case_exchange_user无数据,发布病例时会新增
// statsCaseExchangeUserDao.dec(Long.valueOf(userId),"exchange_collect_num",1);
// }
//
// // 评论数
// if (type == 3){
// caseExchangeDao.inc(Long.valueOf(exchangeId),"comment_num",1);
// statsCaseExchangeDao.dec(1L,"exchange_comment_num",1);
//
// // 此处无需担心stats_case_exchange_user无数据,发布病例时会新增
// statsCaseExchangeUserDao.dec(Long.valueOf(userId),"exchange_comment_num",1);
// }
//
// return true;
// } catch (Exception e) {
// TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
// return false;
// }
// }
/**
* 检测作品状态
*/
public boolean checkCaseExchangeStatus(CaseExchangeModel caseExchange){
// 删除状态
if (caseExchange.getDeleteStatus() == 1){
return false;
}
// 状态(1:正常 2:禁用)
if (caseExchange.getExchangeStatus() == 2){
return false;
}
return true;
}
}
@@ -0,0 +1,280 @@
package com.example.caseData.service;
import com.example.caseData.config.AppConfig;
import com.example.caseData.config.EnvConfig;
import com.example.caseData.exception.BusinessException;
import com.example.caseData.extend.aliyun.Oss;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
import org.springframework.core.io.ClassPathResource;
@Service
public class CertService {
@Resource
private EnvConfig envConfig;
// 生成证书
public String createCert( byte[] avatarPath,
String sealPath,
String certificateNo,
String name,
String content,
byte[] qrCodeByte,
String doctorId
){
try {
// 加载背景模板图片
BufferedImage background = ImageIO.read(new ClassPathResource("static/cert/template.png").getInputStream());
Graphics2D g2d = (Graphics2D) background.getGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
// 1. 添加证书编号
Font font = loadFont("static/cert/msyh.ttf", 40f);
// Font font = new Font("Microsoft YaHei", Font.PLAIN, 40); // 可根据模板调整大小
g2d.setFont(font);
Color customColor = Color.decode("#008983");
g2d.setColor(customColor);
g2d.drawString(certificateNo, 260, 570);
// 2. 处理并添加头像
BufferedImage avatar = ImageIO.read(new ByteArrayInputStream(avatarPath));
int size = 116; // 目标大小
BufferedImage circleAvatar = createCircularImage(avatar, size);
g2d.drawImage(circleAvatar, 465, 620, null);
// 3. 添加姓名
font = loadFont("static/cert/msyh.ttf", 40f);
// font = new Font("Microsoft YaHei", Font.PLAIN, 40); // 可根据模板调整大小
g2d.setFont(font);
customColor = Color.decode("#111827");
g2d.setColor(customColor);
g2d.drawString(name, 465, 790);
// 4. 添加证书内容
// font = new Font("Microsoft YaHei", Font.PLAIN, 48); // 可根据模板调整大小
font = loadFont("static/cert/msyh.ttf", 48f);
g2d.setFont(font);
customColor = Color.decode("#111827");
g2d.setColor(customColor);
drawStringWithLineBreak(g2d, content, 185, 880, 700, font); // 自动换行绘制文本
// 5. 添加日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
String currentDate = sdf.format(new Date());
// font = new Font("Microsoft YaHei", Font.PLAIN, 34); // 可根据模板调整大小
font = loadFont("static/cert/msyh.ttf", 34f);
g2d.setFont(font);
customColor = Color.decode("#111827");
g2d.setColor(customColor);
g2d.drawString(currentDate, 700, 1277);
// 6. 添加印章
BufferedImage seal = ImageIO.read(new ClassPathResource(sealPath).getInputStream());
seal = resize(seal, 264, 264); // 调整印章大小
g2d.drawImage(seal, 645, 1150, null);
// 6. 添加小程序二维码
BufferedImage wechatMa = ImageIO.read(new ByteArrayInputStream(qrCodeByte));
wechatMa = resize(wechatMa, 205, 205); // 调整印章大小
g2d.drawImage(wechatMa, 80, 1450, null);
// 释放资源
g2d.dispose();
// === 将图片转为 byte[] ===
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(background, "png", os);
byte[] imageBytes = os.toByteArray();
String fileName = "";
if (Objects.equals(envConfig.getActive(), "dev")){
fileName = "dev/static/images/" + certificateNo + doctorId + ".png";
}else{
fileName = "prod/static/images/" + certificateNo + doctorId + ".png";
}
boolean uploaded = Oss.putObject(fileName, imageBytes);
if (uploaded) {
// 返回可访问的 URL(假设你有自定义域名)
// 格式:http://你的域名/文件名
return "/" + fileName;
}
// // 保存最终的证书图片
// ImageIO.write(background, "png", new File("cert.png"));
// System.out.println("Certificate generated successfully!");
} catch (IOException e) {
throw new BusinessException(e.getMessage());
}
return null;
}
// 生成证书
public String createCertTest(
String sealPath,
String certificateNo,
String name,
String content
){
try {
// 加载背景模板图片
BufferedImage background = ImageIO.read(new File("src/main/resources/static/cert/template.png"));
Graphics2D g2d = (Graphics2D) background.getGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
// 1. 添加证书编号
Font font = new Font("Microsoft YaHei", Font.PLAIN, 40); // 可根据模板调整大小
g2d.setFont(font);
Color customColor = Color.decode("#008983");
g2d.setColor(customColor);
g2d.drawString(certificateNo, 285, 570);
// 2. 处理并添加头像
BufferedImage avatar = ImageIO.read(new File("src/main/resources/static/cert/avt.png"));
int size = 116; // 目标大小
BufferedImage circleAvatar = createCircularImage(avatar, size);
g2d.drawImage(circleAvatar, 465, 620, null);
// 3. 添加姓名
font = new Font("Microsoft YaHei", Font.PLAIN, 40); // 可根据模板调整大小
g2d.setFont(font);
customColor = Color.decode("#111827");
g2d.setColor(customColor);
g2d.drawString(name, 465, 790);
// 4. 添加证书内容
font = new Font("Microsoft YaHei", Font.PLAIN, 48); // 可根据模板调整大小
g2d.setFont(font);
customColor = Color.decode("#111827");
g2d.setColor(customColor);
drawStringWithLineBreak(g2d, content, 185, 880, 700, font); // 自动换行绘制文本
// 5. 添加日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
String currentDate = sdf.format(new Date());
font = new Font("Microsoft YaHei", Font.PLAIN, 34); // 可根据模板调整大小
g2d.setFont(font);
customColor = Color.decode("#111827");
g2d.setColor(customColor);
g2d.drawString(currentDate, 700, 1277);
// 6. 添加印章
BufferedImage seal = ImageIO.read(new File(sealPath));
seal = resize(seal, 264, 264); // 调整印章大小
g2d.drawImage(seal, 645, 1150, null);
// 6. 添加小程序二维码
BufferedImage wechatMa = ImageIO.read(new File("src/main/resources/static/cert/weChatMa.png"));
wechatMa = resize(wechatMa, 205, 205); // 调整印章大小
g2d.drawImage(wechatMa, 80, 1450, null);
// 释放资源
g2d.dispose();
// === 将图片转为 byte[] ===
// ByteArrayOutputStream os = new ByteArrayOutputStream();
// ImageIO.write(background, "png", os);
// byte[] imageBytes = os.toByteArray();
//
// String fileName = "";
// if (Objects.equals(envConfig.getActive(), "dev")){
// fileName = "dev/static/images/" + certificateNo + ".png";
// }else{
// fileName = "prod/static/images/" + certificateNo + ".png";
// }
//
// boolean uploaded = Oss.putObject(fileName, imageBytes);
// if (uploaded) {
// // 返回可访问的 URL(假设你有自定义域名)
// // 格式:http://你的域名/文件名
// return "/" + fileName;
// }
// // 保存最终的证书图片
ImageIO.write(background, "png", new File("cert.png"));
System.out.println("Certificate generated successfully!");
} catch (IOException e) {
throw new BusinessException(e.getMessage());
}
return null;
}
private static BufferedImage createCircularImage(BufferedImage originalImg, int size) {
BufferedImage outputImage = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = outputImage.createGraphics();
g2.setComposite(AlphaComposite.Src);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.WHITE);
g2.fill(new Ellipse2D.Float(0, 0, size, size));
g2.setComposite(AlphaComposite.SrcAtop);
g2.drawImage(originalImg.getScaledInstance(size, size, Image.SCALE_SMOOTH), 0, 0, null);
g2.dispose();
return outputImage;
}
private static BufferedImage resize(BufferedImage img, int newW, int newH) {
Image tmp = img.getScaledInstance(newW, newH, Image.SCALE_SMOOTH);
BufferedImage dimg = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = dimg.createGraphics();
g2d.drawImage(tmp, 0, 0, null);
g2d.dispose();
return dimg;
}
// 绘制带自动换行的字符串
private static void drawStringWithLineBreak(Graphics2D g2d, String text, int x, int y, int maxWidth, Font font) {
FontMetrics fm = g2d.getFontMetrics(font);
StringBuilder line = new StringBuilder();
String[] words = text.split("");
for (String word : words) {
int lineWidth = fm.stringWidth(line + word);
if (lineWidth < maxWidth) {
line.append(word);
} else {
g2d.drawString(line.toString(), x, y);
y += fm.getHeight();
line = new StringBuilder(word);
}
}
if (!line.isEmpty()) {
g2d.drawString(line.toString(), x, y);
}
}
public static Font loadFont(String path, float size) {
try {
ClassPathResource resource = new ClassPathResource(path);
try (InputStream inputStream = resource.getInputStream()) {
return Font.createFont(Font.TRUETYPE_FONT, inputStream).deriveFont(size);
}
} catch (Exception e) {
throw new RuntimeException("字体加载失败: " + path, e);
}
}
}
@@ -1,6 +1,7 @@
package com.example.caseData.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.caseData.dao.*;
import com.example.caseData.dto.caseClinicalArticle.CaseClinicalArticleDto;
import com.example.caseData.dto.index.GetIndexClinicalDto;
@@ -52,8 +53,9 @@ public class IndexService {
// 最新上线-2条
LambdaQueryWrapper<CaseClinicalArticleModel> caseClinicalArticleQueryWrapper = new LambdaQueryWrapper<>();
caseClinicalArticleQueryWrapper.eq(CaseClinicalArticleModel::getArticleStatus, 1) // 上线状态
.orderByDesc(CaseClinicalArticleModel::getCreatedAt) // 按发布时间倒序
.last("LIMIT 2"); // 只取2条记录
.eq(CaseClinicalArticleModel::getDeleteStatus, 0) // 删除状态状态
.orderByDesc(CaseClinicalArticleModel::getPushDate) // 按发布时间倒序
.last("LIMIT 3"); // 只取2条记录
List<CaseClinicalArticleModel> latestArticles = caseClinicalArticleDao.selectList(caseClinicalArticleQueryWrapper);
for (CaseClinicalArticleModel article : latestArticles) {
// 查找作者
@@ -84,8 +86,9 @@ public class IndexService {
// 最多阅读-2条
caseClinicalArticleQueryWrapper = new LambdaQueryWrapper<>();
caseClinicalArticleQueryWrapper.eq(CaseClinicalArticleModel::getArticleStatus, 1) // 上线状态
.eq(CaseClinicalArticleModel::getDeleteStatus, 0) // 删除状态状态
.orderByDesc(CaseClinicalArticleModel::getReadNum) // 按阅读量倒序
.last("LIMIT 2"); // 只取2条记录
.last("LIMIT 3"); // 只取2条记录
List<CaseClinicalArticleModel> mostReadArticles = caseClinicalArticleDao.selectList(caseClinicalArticleQueryWrapper);
for (CaseClinicalArticleModel article : mostReadArticles) {
// 根据文章ID查找作者
@@ -116,10 +119,13 @@ public class IndexService {
}
// 医院病例库推荐-2条
LambdaQueryWrapper<StatsCaseClinicalHospitalModel> statsCaseClinicalHospitalModelQueryWrapper = new LambdaQueryWrapper<>();
statsCaseClinicalHospitalModelQueryWrapper.orderByDesc(StatsCaseClinicalHospitalModel::getArticleNum) // 按文章数量倒序
.last("LIMIT 2"); // 只取2条记录
List<StatsCaseClinicalHospitalModel> statsCaseClinicalHospitals = statsCaseClinicalHospitalDao.selectList(statsCaseClinicalHospitalModelQueryWrapper);
QueryWrapper<StatsCaseClinicalHospitalModel> statsCaseClinicalHospitalQueryWrapper = new QueryWrapper<>();
statsCaseClinicalHospitalQueryWrapper
.apply("article_num + video_num >= {0}", 10) // 添加条件
.orderByDesc("article_num + video_num") // 按文章数量倒序
.orderByDesc("last_push_date")
.last("LIMIT 3"); // 只取2条记录
List<StatsCaseClinicalHospitalModel> statsCaseClinicalHospitals = statsCaseClinicalHospitalDao.selectList(statsCaseClinicalHospitalQueryWrapper);
for (StatsCaseClinicalHospitalModel hospital : statsCaseClinicalHospitals) {
// 查询医院基础数据
BasicHospitalModel basicHospital = basicHospitalDao.selectById(hospital.getHospitalId());
@@ -127,10 +133,13 @@ public class IndexService {
}
// 医生病例库推荐-2条
LambdaQueryWrapper<StatsCaseClinicalDoctorModel> statsCaseClinicalDoctorModelQueryWrapper = new LambdaQueryWrapper<>();
statsCaseClinicalDoctorModelQueryWrapper.orderByDesc(StatsCaseClinicalDoctorModel::getArticleNum) // 按文章数量倒序
.last("LIMIT 2"); // 只取2条记录
List<StatsCaseClinicalDoctorModel> statsCaseClinicalDoctors = statsCaseClinicalDoctorDao.selectList(statsCaseClinicalDoctorModelQueryWrapper);
QueryWrapper<StatsCaseClinicalDoctorModel> statsCaseClinicalDoctorQueryWrapper = new QueryWrapper<>();
statsCaseClinicalDoctorQueryWrapper
.apply("article_num + video_num >= {0}", 5) // 添加条件
.orderByDesc("article_num + video_num") // 按文章数量倒序
.orderByDesc("last_push_date")
.last("LIMIT 3"); // 只取2条记录
List<StatsCaseClinicalDoctorModel> statsCaseClinicalDoctors = statsCaseClinicalDoctorDao.selectList(statsCaseClinicalDoctorQueryWrapper);
for (StatsCaseClinicalDoctorModel doctor : statsCaseClinicalDoctors) {
// 查询医生数据
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectById(doctor.getDoctorId());
@@ -16,6 +16,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Slf4j
@Service
@@ -72,11 +73,15 @@ public class RewardPointService {
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectById(author.getDoctorId());
if (caseClinicalDoctor == null) {
authorList.add(appConfig.getPlatformPointAccount());
}else{
if (caseClinicalDoctor.getDoctorIden() == null || caseClinicalDoctor.getDoctorIden().isEmpty()){
authorList.add(appConfig.getPlatformPointAccount());
}else{
authorList.add(caseClinicalDoctor.getDoctorIden());
}
}
}
}
// 视频
if (r.getType() == 2){
@@ -90,10 +95,14 @@ public class RewardPointService {
if (caseClinicalDoctor == null) {
authorList.add(appConfig.getPlatformPointAccount());
}else {
if (caseClinicalDoctor.getDoctorIden() == null || caseClinicalDoctor.getDoctorIden().isEmpty()){
authorList.add(appConfig.getPlatformPointAccount());
}else{
authorList.add(caseClinicalDoctor.getDoctorIden());
}
}
}
}
// 病例交流
if (r.getType() == 3){
@@ -121,7 +130,7 @@ public class RewardPointService {
}
String authors = String.join(",", authorList);
System.out.println(authors);
reward.RewardPoint(user.getUserIden(),r.getPoint(),authors);
// 添加打赏记录
@@ -138,4 +147,6 @@ public class RewardPointService {
return true;
}
}
@@ -14,6 +14,7 @@ import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.util.List;
@@ -32,43 +33,62 @@ public class UserCaseReadService {
@Resource
private CaseExchangeDao caseExchangeDao;
@Resource
private StatsCaseClinicalDao statsCaseClinicalDao;
@Resource
private CaseClinicalArticleService caseClinicalArticleService;
@Resource
private CaseClinicalVideoService caseClinicalVideoService;
@Resource
private CaseExchangeService caseExchangeService;
/**
* 浏览记录-新增
* @return bool
*/
@Transactional
public boolean AddUserCaseRead(addUserCaseRead request, String userId){
public boolean AddUserCaseRead(addUserCaseRead request, String loginUserId){
// 检测是否已存在
LambdaQueryWrapper<UserCaseReadModel> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(UserCaseReadModel::getUserId, userId);
queryWrapper.eq(UserCaseReadModel::getId, request.getId());
queryWrapper.eq(UserCaseReadModel::getType, request.getType());
UserCaseReadModel userCaseRead = userCaseReadDao.selectOne(queryWrapper);
if (userCaseRead == null){
UserCaseReadModel data = new UserCaseReadModel();
data.setUserId(Long.valueOf(userId));
data.setUserId(Long.valueOf(loginUserId));
data.setId(Long.valueOf( request.getId()));
data.setType(request.getType());
data.setReadNum(1);
int res = userCaseReadDao.insert(data);
return res > 0;
}else{
userCaseReadDao.inc(userCaseRead.getReadId(),"read_num",1);
if (res <= 0){
throw new BusinessException("操作失败");
}
// 文章
if (request.getType() == 1){
caseClinicalArticleDao.inc(Long.valueOf(request.getId()),"read_num",1);
// 新增统计字段
boolean r = caseClinicalArticleService.IncClinicalArticleStats(request.getId(),1,1);
if (!r){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
}
// 视频
if (request.getType() == 2){
caseClinicalVideoDao.inc(Long.valueOf(request.getId()),"read_num",1);
// 新增统计字段
boolean r = caseClinicalVideoService.IncClinicalVideoStats(request.getId(),1,1);
if (!r){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
}
// 病例交流
if (request.getType() == 3){
caseExchangeDao.inc(Long.valueOf(request.getId()),"read_num",1);
boolean r = caseExchangeService.IncCaseExchangeStats(request.getId(),1);
if (!r){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
}
return true;
@@ -1,30 +1,46 @@
package com.example.caseData.service;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.caseData.dao.BasicHospitalDao;
import com.example.caseData.dao.CaseClinicalDoctorDao;
import com.example.caseData.dao.UserDao;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.caseData.config.AppConfig;
import com.example.caseData.config.EnvConfig;
import com.example.caseData.dao.*;
import com.example.caseData.dto.publicDto.LoginDto;
import com.example.caseData.exception.BusinessException;
import com.example.caseData.extend.aliyun.Oss;
import com.example.caseData.extend.app.Hospital.GetHospitalByUuidResponse;
import com.example.caseData.extend.app.Hospital.Hospital;
import com.example.caseData.extend.app.UserInfo.GetUserInfoByMobileResponse;
import com.example.caseData.extend.app.Score.Score;
import com.example.caseData.extend.app.UserInfo.GetUserInfoResponse;
import com.example.caseData.extend.app.UserInfo.UserInfo;
import com.example.caseData.model.BasicHospitalModel;
import com.example.caseData.model.CaseClinicalDoctorModel;
import com.example.caseData.model.UserModel;
import com.example.caseData.extend.weChat.WxMaServiceUtils;
import com.example.caseData.model.*;
import com.example.caseData.utils.JwtUtil;
import com.example.caseData.utils.Replace;
import com.example.caseData.utils.Sha256Util;
import com.example.caseData.utils.StringToInt;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.time.LocalDateTime;
import java.time.Year;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.Objects;
import java.time.LocalDate;
import java.util.Random;
import static com.baomidou.mybatisplus.extension.toolkit.Db.save;
@Slf4j
@Service
public class UserService {
@Resource
@@ -39,20 +55,83 @@ public class UserService {
@Resource
private CaseClinicalDoctorDao caseClinicalDoctorDao;
@Resource
private CaseClinicalDoctorCertDao caseClinicalDoctorCertDao;
@Resource
private CaseClinicalArticleDao caseClinicalArticleDao;
@Resource
private CaseClinicalVideoDao caseClinicalVideoDao;
@Resource
private CaseClinicalRecordScoreDao caseClinicalRecordScoreDao;
@Resource
private Hospital hospital;
@Resource
private JwtUtil jwtUtil;
@Resource
private Score score;
@Resource
private EnvConfig envConfig;
@Resource
private WxMaServiceUtils wxMaServiceUtils;
@Resource
private CertService certService;
@Resource
private StatsCaseClinicalDao statsCaseClinicalDao;
@Resource
private AppConfig appConfig;
/**
* 用户登陆
* 用户登陆-手机号
* @return UserModel
*/
@Transactional
public LoginDto UserLogin(String phone) throws BusinessException {
public LoginDto UserLoginWithMobile(String phone) throws BusinessException {
// 获取app用户数据
UserModel user = GetAppUserInfoByPhone(phone);
GetUserInfoResponse result = userInfo.getUserInfoByMobile(phone);
UserModel user = GetAppUserInfo(result);
// 生成jwt
String token = jwtUtil.createToken(String.valueOf(user.getUserId()));
// 获取对应医生数据
LambdaQueryWrapper<CaseClinicalDoctorModel> caseClinicalDoctorWrapper = new LambdaQueryWrapper<>();
caseClinicalDoctorWrapper.eq(CaseClinicalDoctorModel::getDoctorIden, user.getUserIden());
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectOne(caseClinicalDoctorWrapper);
// 处理返回值
LoginDto g = new LoginDto();
g.setUserId(String.valueOf(user.getUserId()));
g.setUserName(user.getUserName());
g.setAvatar(Replace.addOssDomain(user.getAvatar()));
g.setToken(token);
if (caseClinicalDoctor != null) {
g.setDoctorId(String.valueOf(caseClinicalDoctor.getDoctorId()));
}
return g;
}
/**
* 用户登陆-app
* @param appToken 1
*/
@Transactional
public LoginDto UserLoginWithApp(String appToken) throws BusinessException {
GetUserInfoResponse result = userInfo.getUserInfoByToken(appToken);
UserModel user = GetAppUserInfo(result);
// 生成jwt
String token = jwtUtil.createToken(String.valueOf(user.getUserId()));
@@ -77,17 +156,14 @@ public class UserService {
/**
* 获取app用户数据
* @param phone 手机号
* @return UserModel
*/
public UserModel GetAppUserInfoByPhone(String phone) throws BusinessException {
// 请求接口获取数据
GetUserInfoByMobileResponse result = userInfo.getUserInfoByMobile(phone);
GetUserInfoByMobileResponse.GetUserInfoByMobileData data = result.getData();
public UserModel GetAppUserInfo(GetUserInfoResponse r) throws BusinessException {
GetUserInfoResponse.ResponsData data = r.getData();
// 查询数据库用户信息
LambdaQueryWrapper<UserModel> userModelWrapper = new LambdaQueryWrapper<>();
userModelWrapper.eq(UserModel::getUserIden, result.getData().getUuid());
userModelWrapper.eq(UserModel::getUserIden, r.getData().getUuid());
UserModel user = userDao.selectOne(userModelWrapper);
if (user == null){
// 构造 UserModel 对象
@@ -101,11 +177,20 @@ public class UserService {
user.setOpenId("");
user.setUnionId("");
user.setSex(0);
user.setAvatar(data.getPhoto());
if (data.getPhoto() != null) {
String ossPath = handleUserImage(data.getImg_host() + data.getPhoto());
user.setAvatar(ossPath);
}else{
user.setAvatar("");
}
user.setDepartmentName(data.getOfficeName());
user.setTitle(StringToInt.DoctorTitleToInt(data.getPositionName()));
user.setAddress(data.getProvName());
save(user);
int res = userDao.insert(user);
if (res <= 0){
throw new BusinessException("操作失败");
}
}else{
if (!Objects.equals(user.getUserName(), data.getRealname())){
user.setUserName(data.getRealname());
@@ -116,8 +201,8 @@ public class UserService {
user.setMobileEncryption(SecureUtil.md5(data.getMobile()));
}
if (!Objects.equals(user.getTitle(), StringToInt.DoctorTitleToInt(data.getOfficeName()))){
user.setTitle(StringToInt.DoctorTitleToInt(data.getOfficeName()));
if (!Objects.equals(user.getTitle(), StringToInt.DoctorTitleToInt(data.getPositionName()))){
user.setTitle(StringToInt.DoctorTitleToInt(data.getPositionName()));
}
if (!Objects.equals(user.getDepartmentName(), data.getOfficeName())){
@@ -128,6 +213,15 @@ public class UserService {
user.setAddress(data.getProvName());
}
if (data.getPhoto() != null) {
try {
String ossPath = handleUserImage(data.getImg_host() + data.getPhoto());
user.setAvatar(ossPath);
}catch (Exception e){
// 不处理
}
}
userDao.updateById(user);
}
@@ -136,10 +230,50 @@ public class UserService {
// 修改用户所属医院
if (!Objects.equals(user.getHospitalId(), basicHospital.getHospitalId())){
UserModel updateUser = new UserModel();
updateUser.setUserId(user.getUserId());
updateUser.setHospitalId(basicHospital.getHospitalId());
userDao.updateById(updateUser);
user.setHospitalId(basicHospital.getHospitalId());
userDao.updateById(user);
}
// 获取对应医生数据
LambdaQueryWrapper<CaseClinicalDoctorModel> caseClinicalDoctorWrapper = new LambdaQueryWrapper<>();
caseClinicalDoctorWrapper.eq(CaseClinicalDoctorModel::getDoctorIden, user.getUserIden());
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectOne(caseClinicalDoctorWrapper);
if (caseClinicalDoctor == null){
// 二次匹配:通过姓名-医院获取医生信息
caseClinicalDoctorWrapper = new LambdaQueryWrapper<>();
caseClinicalDoctorWrapper.eq(CaseClinicalDoctorModel::getDoctorName, user.getUserName());
caseClinicalDoctorWrapper.eq(CaseClinicalDoctorModel::getHospitalId, basicHospital.getHospitalId());
caseClinicalDoctor = caseClinicalDoctorDao.selectOne(caseClinicalDoctorWrapper);
}
if (caseClinicalDoctor == null){
CaseClinicalDoctorModel c = new CaseClinicalDoctorModel();
c.setDoctorName(user.getUserName());
c.setDoctorIden(user.getUserIden());
c.setHospitalId(user.getHospitalId());
c.setAvatar(user.getAvatar());
int res = caseClinicalDoctorDao.insert(c);
if (res <= 0){
throw new BusinessException("操作失败");
}
}else{
if (!Objects.equals(caseClinicalDoctor.getDoctorName(), data.getRealname())){
caseClinicalDoctor.setDoctorName(data.getRealname());
}
if (!Objects.equals(basicHospital.getHospitalId(), caseClinicalDoctor.getHospitalId())){
caseClinicalDoctor.setHospitalId(basicHospital.getHospitalId());
}
if (!Objects.equals(user.getAvatar(), caseClinicalDoctor.getAvatar())){
caseClinicalDoctor.setAvatar(user.getAvatar());
}
if (!Objects.equals(user.getUserIden(), caseClinicalDoctor.getDoctorIden())){
caseClinicalDoctor.setDoctorIden(user.getUserIden());
}
caseClinicalDoctorDao.updateById(caseClinicalDoctor);
}
return user;
@@ -168,9 +302,380 @@ public class UserService {
basicHospital.setHospitalLevel(data.getLevel());
basicHospital.setDoctorNumber(data.getExpert_num());
basicHospital.setProvince(data.getProv_name());
basicHospital.setCity(data.getCity_name());
basicHospital.setCounty(data.getCounty_name());
save(basicHospital);
}
return basicHospital;
}
/**
* 获取app医生数据
* @return UserModel
*/
public CaseClinicalDoctorModel GetAppCaseClinicalDoctor(GetUserInfoResponse r) throws BusinessException {
GetUserInfoResponse.ResponsData data = r.getData();
// 获取app医院数据
BasicHospitalModel basicHospital = GetAppHospital(data.getHospitalUuid());
// 获取对应医生数据
LambdaQueryWrapper<CaseClinicalDoctorModel> caseClinicalDoctorWrapper = new LambdaQueryWrapper<>();
caseClinicalDoctorWrapper.eq(CaseClinicalDoctorModel::getDoctorIden, data.getUuid());
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectOne(caseClinicalDoctorWrapper);
if (caseClinicalDoctor == null){
// 二次匹配:通过姓名-医院获取医生信息
caseClinicalDoctorWrapper = new LambdaQueryWrapper<>();
caseClinicalDoctorWrapper.eq(CaseClinicalDoctorModel::getDoctorName, data.getRealname());
caseClinicalDoctorWrapper.eq(CaseClinicalDoctorModel::getHospitalId, basicHospital.getHospitalId());
caseClinicalDoctor = caseClinicalDoctorDao.selectOne(caseClinicalDoctorWrapper);
}
if (caseClinicalDoctor == null){
caseClinicalDoctor = new CaseClinicalDoctorModel();
caseClinicalDoctor.setDoctorName(data.getRealname());
caseClinicalDoctor.setDoctorIden(data.getUuid());
caseClinicalDoctor.setHospitalId(basicHospital.getHospitalId());
if (data.getPhoto() != null) {
String ossPath = handleUserImage(data.getImg_host() + data.getPhoto());
caseClinicalDoctor.setAvatar(ossPath);
}else{
caseClinicalDoctor.setAvatar("");
}
int res = caseClinicalDoctorDao.insert(caseClinicalDoctor);
if (res <= 0){
throw new BusinessException("操作失败");
}
}else{
if (!Objects.equals(caseClinicalDoctor.getDoctorName(), data.getRealname())){
caseClinicalDoctor.setDoctorName(data.getRealname());
}
if (!Objects.equals(basicHospital.getHospitalId(), caseClinicalDoctor.getHospitalId())){
caseClinicalDoctor.setHospitalId(basicHospital.getHospitalId());
}
if (!Objects.equals(data.getUuid(), caseClinicalDoctor.getDoctorIden())){
caseClinicalDoctor.setDoctorIden(data.getUuid());
}
if (data.getPhoto() != null) {
try {
String ossPath = handleUserImage(data.getImg_host() + data.getPhoto());
caseClinicalDoctor.setAvatar(ossPath);
}catch (Exception e){
// 不处理
}
}
caseClinicalDoctorDao.updateById(caseClinicalDoctor);
}
return caseClinicalDoctor;
}
public Map getAppUser(String mobile) {
try {
HashMap<String, Object> params = new HashMap<>();
params.put("mobile", mobile);
params.put("platform", appConfig.getPlatform());
params.put("timestamp", System.currentTimeMillis() / 1000);
String signature = Sha256Util.getSign(params, appConfig.getSecretKey());
params.put("signature", signature);
String result = HttpUtil.post(appConfig.getApiUrl() + "/hcp/mobileLogin", params);
log.info(result);
// 解析JSON
ObjectMapper objectMapper = new ObjectMapper();
Map resultMap = objectMapper.readValue(result, Map.class);
return resultMap;
} catch (Exception e) {
throw new BusinessException(e.getMessage());
}
}
/**
* 发放积分
* @param type 类型(1:文章 2:视频 3:病例交流)
* @throws BusinessException
*/
public boolean ReportUserScore(String id,Integer type,String userId,Integer point) throws BusinessException{
// 获取积分发放记录
// 获取今天的日期,并设置时间为 00:00:00
LocalDateTime startOfToday = LocalDate.now().atStartOfDay(); // 例如:2025-07-30 00:00:00
QueryWrapper<CaseClinicalRecordScoreModel> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("user_id", userId)
.ge("created_at", startOfToday) // created_at >= 今天 00:00:00
.ge("score_type", 5)
.orderByDesc("created_at"); // 最新的在前
List<CaseClinicalRecordScoreModel> caseClinicalRecordScores = caseClinicalRecordScoreDao.selectList(queryWrapper);
if (caseClinicalRecordScores.size() >= 3){
return true;
}
// 获取用户数据
UserModel user = userDao.selectById(userId);
if (user == null){
throw new BusinessException("操作失败");
}
// 发放积分
score.ReportUserScore(user.getUserIden(),5,"病例库-病例互动");
// 添加打赏记录
CaseClinicalRecordScoreModel data = new CaseClinicalRecordScoreModel();
data.setUserId(Long.valueOf(userId));
data.setScore(point);
data.setId(Long.valueOf(id));
data.setUserName(user.getUserName());
data.setNodeName("病例库-病例互动");
data.setType(type);
data.setScoreType(5);
caseClinicalRecordScoreDao.insert(data);
return true;
}
// 获取发放积分次数
public Integer GetReportUserScore(String userId) throws BusinessException{
// 获取积分发放记录
// 获取今天的日期,并设置时间为 00:00:00
LocalDateTime startOfToday = LocalDate.now().atStartOfDay(); // 例如:2025-07-30 00:00:00
QueryWrapper<CaseClinicalRecordScoreModel> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("user_id", userId)
.ge("created_at", startOfToday) // created_at >= 今天 00:00:00
.orderByDesc("created_at"); // 最新的在前
List<CaseClinicalRecordScoreModel> caseClinicalRecordScores = caseClinicalRecordScoreDao.selectList(queryWrapper);
return caseClinicalRecordScores.size();
}
/**
* 处理用户头像:下载远程头像并上传至 OSS
*
* @param wxAvatarUrl 微信头像地址
* @return OSS 路径(以 / 开头),如 /user/avatar/202507301530123456.png
*/
public String handleUserImage(String wxAvatarUrl) {
if (wxAvatarUrl == null || wxAvatarUrl.isEmpty()) {
return null;
}
HttpURLConnection conn = null;
try {
// 1. 下载远程图片
URL url = new URL(wxAvatarUrl);
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setReadTimeout(10000);
conn.setRequestMethod("GET");
if (conn.getResponseCode() != 200) {
throw new BusinessException("图片处理失败");
}
try (InputStream input = conn.getInputStream();
ByteArrayOutputStream output = new ByteArrayOutputStream()) {
byte[] buffer = new byte[4096];
int len;
while ((len = input.read(buffer)) != -1) {
output.write(buffer, 0, len);
}
byte[] imageBytes = output.toByteArray();
if (imageBytes.length == 0) {
throw new BusinessException("图片处理失败");
}
// 2. 生成 OSS 路径
String dateTimeStr = LocalDateTime.now()
.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
int randomSuffix = new Random().nextInt(9000) + 1000;
String ossPath = "";
if (Objects.equals(envConfig.getActive(), "dev")){
ossPath = "dev/static/images/" + dateTimeStr + randomSuffix + ".png";
}else{
ossPath = "prod/static/images/" + dateTimeStr + randomSuffix + ".png";
}
// 3. 上传 OSS
boolean success = Oss.putObject(ossPath, imageBytes);
if (!success) {
throw new BusinessException("图片处理失败");
}
return "/" + ossPath;
}
} catch (Exception e) {
// 头像处理失败
System.out.println(e.getMessage());
return "";
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
/**
* 生成用户分享二维码-文章/视频
* @param id 文章/视频id
* @param type 类型 1:文章 2:视频
*/
@Transactional
public byte[] CreateUserCaseClinicalUnlimitedQrcode(String id,Integer type) throws BusinessException{
String scene = "";
String page = "pages/detail/detail";
if (type == 1){
scene = "?id=" + id + "&type=1";
}else if (type == 2){
scene = "?id=" + id + "&type=2";
}else{
throw new BusinessException("生成二维码类型错误");
}
try {
// 生成二维码
byte[] fileByte = wxMaServiceUtils.getUnlimitedQrcode(scene,page);
// 上传oss
String fileName = "";
String no = "";
if (type == 1){
no = "a" + id;
}else {
no = "v" + id;
}
if (Objects.equals(envConfig.getActive(), "dev")){
fileName = "dev/static/images/" + no + ".png";
}else{
fileName = "prod/static/images/" + no + ".png";
}
boolean res = Oss.putObject(fileName, fileByte);
if (!res) {
throw new BusinessException("生成失败");
}
if (type == 1){
// 修改文章证书
CaseClinicalArticleModel caseClinicalArticle = caseClinicalArticleDao.selectById(Long.valueOf(id));
if (caseClinicalArticle == null){
throw new BusinessException("生成失败");
}
caseClinicalArticle.setShareQrcode("/" + fileName);
caseClinicalArticleDao.updateById(caseClinicalArticle);
}else{
// 修改视频证书
CaseClinicalVideoModel caseClinicalVideo = caseClinicalVideoDao.selectById(Long.valueOf(id));
if (caseClinicalVideo == null){
throw new BusinessException("生成失败");
}
caseClinicalVideo.setShareQrcode("/" + fileName);
caseClinicalVideoDao.updateById(caseClinicalVideo);
}
return fileByte;
} catch (Exception e) {
throw new BusinessException(e.getMessage());
}
}
/**
* 生成用户证书-文章/视频
* @param id 文章/视频id
* @param type 类型 1:文章 2:视频
*/
@Transactional
public boolean CreateUserCert(String id,Integer type,String doctorId, byte[] qrCodeByte, byte[] avatarByte) throws BusinessException{
try {
String title = ""; // 标题
if (type == 1){
// 获取文章数据
CaseClinicalArticleModel caseClinicalArticle = caseClinicalArticleDao.selectById(Long.valueOf(id));
if (caseClinicalArticle == null){
throw new BusinessException("生成证书错误");
}
title = caseClinicalArticle.getArticleTitle();
}else if (type == 2){
CaseClinicalVideoModel caseClinicalVideo = caseClinicalVideoDao.selectById(Long.valueOf(id));
if (caseClinicalVideo == null){
throw new BusinessException("生成证书错误");
}
title = caseClinicalVideo.getVideoTitle();
}else{
throw new BusinessException("生成证书错误");
}
// 获取医生数据
CaseClinicalDoctorModel caseClinicalDoctor = caseClinicalDoctorDao.selectById(doctorId);
if (caseClinicalDoctor == null){
throw new BusinessException("生成证书错误");
}
// 获取证书文件
LambdaQueryWrapper<CaseClinicalDoctorCertModel> certWrapper = new LambdaQueryWrapper<>();
certWrapper.eq(CaseClinicalDoctorCertModel::getDoctorId, doctorId);
certWrapper.eq(CaseClinicalDoctorCertModel::getId, id);
certWrapper.eq(CaseClinicalDoctorCertModel::getType, type);
CaseClinicalDoctorCertModel caseClinicalDoctorCert = caseClinicalDoctorCertDao.selectOne(certWrapper);
if (caseClinicalDoctorCert != null){
return true;
}
// 获取统计数据
StatsCaseClinicalModel statsCaseClinical = statsCaseClinicalDao.selectById(1);
if (statsCaseClinical == null){
throw new BusinessException("生成证书错误");
}
// 生成证书
String certificateNo = "证书编号:GDXZALK"
+ String.valueOf(Year.now().getValue())
+ String.format("%06d", (statsCaseClinical.getArticleNum() + statsCaseClinical.getVideoNum()));
String ossPath = certService.createCert(
avatarByte,
"static/cert/seal.png",
certificateNo,
caseClinicalDoctor.getDoctorName(),
"您的案例《" + title + "》经评议,被肝胆相照临床病例库收录,特发此证。",
qrCodeByte,
doctorId
);
// 新增证书文件
caseClinicalDoctorCert = new CaseClinicalDoctorCertModel();
caseClinicalDoctorCert.setDoctorId(Long.valueOf(doctorId));
caseClinicalDoctorCert.setId(Long.valueOf(id));
caseClinicalDoctorCert.setType(type);
caseClinicalDoctorCert.setCertImage(ossPath);
caseClinicalDoctorCertDao.insert(caseClinicalDoctorCert);
return true;
} catch (Exception e) {
throw new BusinessException(e.getMessage());
}
}
}
@@ -0,0 +1,79 @@
/**
* Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.caseData.utils;
import java.security.MessageDigest;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class EncryptionKit {
public static String md5Encrypt(String srcStr) {
return encrypt("MD5", srcStr);
}
public static String sha1Encrypt(String srcStr) {
return encrypt("SHA-1", srcStr);
}
public static String sha256Encrypt(String srcStr) {
return encrypt("SHA-256", srcStr);
}
public static String sha384Encrypt(String srcStr) {
return encrypt("SHA-384", srcStr);
}
public static String sha512Encrypt(String srcStr) {
return encrypt("SHA-512", srcStr);
}
public static String encrypt(String algorithm, String srcStr) {
try {
StringBuilder result = new StringBuilder();
MessageDigest md = MessageDigest.getInstance(algorithm);
byte[] bytes = md.digest(srcStr.getBytes("utf-8"));
for (byte b : bytes) {
String hex = Integer.toHexString(b & 0xFF);
if (hex.length() == 1)
result.append("0");
result.append(hex);
}
return result.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static String HMACSHA256(String data, String key) {
try {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
sha256_HMAC.init(secret_key);
byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte item : array) {
sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString().toLowerCase();
} catch (Exception e) {
return "";
}
}
}
@@ -0,0 +1,22 @@
package com.example.caseData.utils;
import org.springframework.core.io.ClassPathResource;
import java.io.*;
public class ImageUtil {
public static byte[] readImageToBytes(String imagePath) throws IOException {
ClassPathResource resource = new ClassPathResource(imagePath);
try (InputStream inputStream = resource.getInputStream();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
return outputStream.toByteArray();
}
}
}
@@ -0,0 +1,46 @@
package com.example.caseData.utils;
import cn.hutool.core.util.StrUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* 加密
*/
public class Sha256Util {
/**
* 加密
* @param params
* @param accessToken
* @return
*/
public static String getSign(Map<String, Object> params, String accessToken) {
List<String> keys = new ArrayList<>(params.keySet());
List<String> tmp = new ArrayList<>();
Collections.sort(keys);
for (String key : keys) {
if (!StrUtil.isEmptyIfStr(params.get(key))) {
tmp.add(key + "=" + params.get(key));
}
}
String join = String.join("&", tmp);
return EncryptionKit.HMACSHA256(join, accessToken);
}
public static String getSignString(Map<String, String> params, String accessToken) {
List<String> keys = new ArrayList<>(params.keySet());
List<String> tmp = new ArrayList<>();
Collections.sort(keys);
for (String key : keys) {
if (!StrUtil.isEmptyIfStr(params.get(key))) {
tmp.add(key + "=" + params.get(key));
}
}
String join = String.join("&", tmp);
return EncryptionKit.HMACSHA256(join, accessToken);
}
}
+84
View File
@@ -0,0 +1,84 @@
server:
port: 5477
# DataSource Config
spring:
application:
name: caseData
datasource:
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
url: jdbc:p6spy:mysql://42.193.16.243:30001/case?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
username: root
password: gdxz123456^%$d
data:
redis:
host: '139.155.127.177'
port: 30002
password: gdxz2022&dj.
database: 9
timeout: 3000
jackson:
time-zone: Asia/Shanghai
default-property-inclusion: always
redis:
dev:
host: '139.155.127.177'
port: 30002
password: gdxz2022&dj.
database: 9
prod:
host: '139.155.127.177'
port: 30002
password: gdxz2022&dj.
database: 10
# MyBatis-Plus 配置
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开启 SQL 日志
map-underscore-to-camel-case: true
mapper-locations: "classpath:mapper/*.xml"
# oss配置
oss:
access-key: LTAI5tKmFrVCghcxX7yHyGhm
access-key-secret: q1aiIZCJJuf92YbKk2cSXnPES4zx26
bucket: caseplatform
endpoint: oss-cn-beijing.aliyuncs.com
custom-domain-name: https://caseplatform.oss-cn-beijing.aliyuncs.com
# [阿里大鱼短信]
dysms:
access-key: LTAI4GGygjsKhyBwvvC3CghV
access-secret: rcx7lO9kQxG10m8NqNPEfEtT9IS8EI
# jwt配置
jwt:
sign-key: 123456899 # 私钥
ttl: 720 # 过期时间 小时
algo: HS256 # 加密方式
# 日志
logging:
level:
root: info # 全局日志级别
file:
name: logs/app.log # 自定义日志文件路径
pattern:
file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
# 微信
wechat:
miniapp:
appid: wx152ad667d5075f27
secret: 0b86e725d8f372fa05dad95a91d41c72
# [app]
app:
apiUrl: https://dev-wx.igandan.com
secretKey: nmBCF@hEK6eN&h03dYUin@AU3%bMf%$O
imagePrefix: https://dev-doc.igandan.com/app
platform: case-storge
platformPointAccount: GDXZadmin01
access-token: XUUHml5iQ9mlFsa8QqOwyBrLI2nGGGxJ
+84
View File
@@ -0,0 +1,84 @@
server:
port: 5477
# DataSource Config
spring:
application:
name: caseData
datasource:
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
url: jdbc:p6spy:mysql://172.27.16.10:3306/case?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
username: root
password: sKptsVOiTf6m3lt_
data:
redis:
host: '139.155.127.177'
port: 30002
password: gdxz2022&dj.
database: 9
timeout: 3000
jackson:
time-zone: Asia/Shanghai
default-property-inclusion: always
redis:
dev:
host: '139.155.127.177'
port: 30002
password: gdxz2022&dj.
database: 9
prod:
host: '139.155.127.177'
port: 30002
password: gdxz2022&dj.
database: 10
# MyBatis-Plus 配置
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开启 SQL 日志
map-underscore-to-camel-case: true
mapper-locations: "classpath:mapper/*.xml"
# oss配置
oss:
access-key: LTAI5tKmFrVCghcxX7yHyGhm
access-key-secret: q1aiIZCJJuf92YbKk2cSXnPES4zx26
bucket: caseplatform
endpoint: oss-cn-beijing.aliyuncs.com
custom-domain-name: https://caseplatform.oss-cn-beijing.aliyuncs.com
# [阿里大鱼短信]
dysms:
access-key: LTAI4GGygjsKhyBwvvC3CghV
access-secret: rcx7lO9kQxG10m8NqNPEfEtT9IS8EI
# jwt配置
jwt:
sign-key: 123456899 # 私钥
ttl: 720 # 过期时间 小时
algo: HS256 # 加密方式
# 日志
logging:
level:
root: info # 全局日志级别
file:
name: logs/app.log # 自定义日志文件路径
pattern:
file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
# 微信
wechat:
miniapp:
appid: wx152ad667d5075f27
secret: 0b86e725d8f372fa05dad95a91d41c72
# [app]
app:
apiUrl: https://wx.igandan.com
secretKey: nI!0ijOoElQI9^z1HtgJ4gsc$s^TJvm2
imagePrefix: https://doc.igandan.com/app
platform: case-storge
platformPointAccount: GDXZadmin01
access-token: zd8V2LYD4achjFZrbHgD2PuzKuthDCVx
+19 -1
View File
@@ -9,7 +9,7 @@ spring:
active: dev
datasource:
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
url: jdbc:p6spy:mysql://42.193.16.243:30001/case_data?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
url: jdbc:p6spy:mysql://42.193.16.243:30001/case?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
username: root
password: gdxz123456^%$d
data:
@@ -22,6 +22,18 @@ spring:
jackson:
time-zone: Asia/Shanghai
default-property-inclusion: always
redis:
dev:
host: '139.155.127.177'
port: 30002
password: gdxz2022&dj.
database: 9
prod:
host: '139.155.127.177'
port: 30002
password: gdxz2022&dj.
database: 10
# MyBatis-Plus 配置
mybatis-plus:
@@ -38,6 +50,11 @@ oss:
endpoint: oss-cn-beijing.aliyuncs.com
custom-domain-name: https://caseplatform.oss-cn-beijing.aliyuncs.com
# [阿里大鱼短信]
dysms:
access-key: LTAI4GGygjsKhyBwvvC3CghV
access-secret: rcx7lO9kQxG10m8NqNPEfEtT9IS8EI
# jwt配置
jwt:
sign-key: 123456899 # 私钥
@@ -66,3 +83,4 @@ app:
imagePrefix: https://dev-doc.igandan.com/app
platform: case-storge
platformPointAccount: GDXZadmin01
access-token: XUUHml5iQ9mlFsa8QqOwyBrLI2nGGGxJ
@@ -7,6 +7,8 @@
<result column="read_num" property="readNum"/>
<result column="collect_num" property="collectNum"/>
<result column="push_date" property="pushDate"/>
<result column="is_link" property="isLink"/>
<result column="is_link_url" property="isLinkUrl"/>
</resultMap>
<select id="getCaseClinicalArticleSearchPage" resultType="com.example.caseData.dto.caseClinicalArticle.CaseClinicalArticleDto">
@@ -48,7 +50,9 @@
a.read_num,
a.collect_num,
a.push_date,
a.cert_image
a.cert_image,
a.is_link,
a.is_link_url
FROM (
SELECT DISTINCT a.article_id
FROM case_clinical_article a
@@ -56,6 +60,7 @@
LEFT JOIN case_clinical_doctor d ON caa.doctor_id = d.doctor_id
LEFT JOIN case_clinical_article_label l ON a.article_id = l.article_id
WHERE a.article_status = 1
AND a.delete_status = 0
<if test="keyword != null and keyword != ''">
AND (
a.article_title LIKE CONCAT('%', #{keyword}, '%')
@@ -64,10 +69,60 @@
)
</if>
<if test="hospitalId != null and hospitalId != ''">
AND d.hospital_id = ${hospitalId}
AND d.hospital_id = #{hospitalId}
</if>
<if test="doctorId != null and doctorId != ''">
AND d.doctor_id = ${doctorId}
AND d.doctor_id = #{doctorId}
</if>
<if test="labelIden != null and labelIden != ''">
AND l.app_iden = #{labelIden}
</if>
<if test="isNeedLink == 0">
AND a.is_link = 0
</if>
) AS result
JOIN case_clinical_article a ON a.article_id = result.article_id
<if test="order != null and !order.isEmpty()">
ORDER BY
<foreach item="entry" index="key" collection="order" separator=",">
${key} ${entry}
</foreach>
</if>
</select>
<select id="getCaseClinicalArticleSearchList" resultType="com.example.caseData.dto.caseClinicalArticle.CaseClinicalArticleDto">
SELECT
a.article_id,
a.article_title,
a.read_num,
a.collect_num,
a.push_date,
a.cert_image,
a.is_link,
a.is_link_url
FROM (
SELECT DISTINCT a.article_id
FROM case_clinical_article a
LEFT JOIN case_clinical_article_author caa ON a.article_id = caa.article_id
LEFT JOIN case_clinical_doctor d ON caa.doctor_id = d.doctor_id
LEFT JOIN case_clinical_article_label l ON a.article_id = l.article_id
WHERE a.article_status = 1
AND a.delete_status = 0
<if test="keyword != null and keyword != ''">
AND (
a.article_title LIKE CONCAT('%', #{keyword}, '%')
OR d.doctor_name LIKE CONCAT('%', #{keyword}, '%')
OR l.label_name LIKE CONCAT('%', #{keyword}, '%')
)
</if>
<if test="hospitalId != null and hospitalId != ''">
AND d.hospital_id = #{hospitalId}
</if>
<if test="doctorId != null and doctorId != ''">
AND d.doctor_id = #{doctorId}
</if>
<if test="labelIden != null and labelIden != ''">
AND l.app_iden = #{labelIden}
</if>
) AS result
JOIN case_clinical_article a ON a.article_id = result.article_id
@@ -94,10 +149,41 @@
)
</if>
<if test="hospitalId != null and hospitalId != ''">
AND d.hospital_id = ${hospitalId}
AND d.hospital_id = #{hospitalId}
</if>
<if test="doctorId != null and doctorId != ''">
AND d.doctor_id = ${doctorId}
AND d.doctor_id = #{doctorId}
</if>
<if test="labelIden != null and labelIden != ''">
AND l.app_iden = #{labelIden}
</if>
</select>
<select id="selectLastArticlePushDateByHospitalId" resultType="java.time.LocalDateTime">
SELECT MAX(ca.push_date) AS last_push_date
FROM case_clinical_article ca
INNER JOIN case_clinical_article_author caa ON ca.article_id = caa.article_id
INNER JOIN case_clinical_doctor cd ON caa.doctor_id = cd.doctor_id
WHERE cd.hospital_id = #{hospitalId}
AND ca.article_status = 1
AND ca.delete_status = 0
</select>
<select id="selectLastArticlePushDateByDoctorId" resultType="java.time.LocalDateTime">
SELECT MAX(ca.push_date) AS last_push_date
FROM case_clinical_article ca
INNER JOIN case_clinical_article_author caa ON ca.article_id = caa.article_id
WHERE caa.doctor_id = #{doctorId}
AND ca.article_status = 1
AND ca.delete_status = 0
</select>
<select id="selectLastArticlePushDateByLabelId" resultType="java.time.LocalDateTime">
SELECT MAX(ca.push_date) AS last_push_date
FROM case_clinical_article ca
INNER JOIN case_clinical_article_label cd ON ca.article_id = cd.article_id
WHERE cd.app_iden = #{labelIden}
AND ca.article_status = 1
AND ca.delete_status = 0
</select>
</mapper>

Some files were not shown because too many files have changed in this diff Show More