From 29eb2681806cc0b1871010c60fec65818d00df58 Mon Sep 17 00:00:00 2001
From: zzy <2450266535@qq.com>
Date: Sun, 24 May 2026 00:24:56 +0800
Subject: [PATCH] init
---
.gitignore | 5 +
pom.xml | 90 +
.../com/example/SpringbootApplication.java | 18 +
.../java/com/example/common/Constants.java | 9 +
src/main/java/com/example/common/Result.java | 72 +
.../com/example/common/config/CorsConfig.java | 25 +
.../example/common/config/JwtInterceptor.java | 82 +
.../com/example/common/config/TokenUtils.java | 88 +
.../com/example/common/config/WebConfig.java | 24 +
.../example/common/enums/ResultCodeEnum.java | 27 +
.../example/config/RestTemplateConfig.java | 14 +
.../com/example/config/WebSocketConfig.java | 20 +
.../example/controller/AIChatController.java | 56 +
.../example/controller/AccountController.java | 48 +
.../example/controller/AdminController.java | 93 +
.../controller/AnnouncementController.java | 109 +
.../AssessmentReportController.java | 116 +
.../controller/ChatMessageController.java | 48 +
.../example/controller/DoctorController.java | 147 +
.../controller/DoctorPatientController.java | 137 +
.../example/controller/FileController.java | 102 +
.../example/controller/PatientController.java | 256 ++
.../controller/RecommendationController.java | 47 +
.../ResourceCategoryController.java | 86 +
.../controller/ResourceRatingController.java | 167 +
.../controller/SymptomRecordController.java | 91 +
.../SymptomStatisticsController.java | 66 +
.../TreatmentResourceController.java | 220 ++
.../com/example/controller/WebController.java | 93 +
src/main/java/com/example/entity/Account.java | 30 +
src/main/java/com/example/entity/Admin.java | 33 +
.../java/com/example/entity/Announcement.java | 59 +
.../com/example/entity/AssessmentReport.java | 41 +
.../java/com/example/entity/ChatMessage.java | 92 +
src/main/java/com/example/entity/Doctor.java | 41 +
.../com/example/entity/DoctorPatient.java | 56 +
src/main/java/com/example/entity/Patient.java | 35 +
.../com/example/entity/ResourceCategory.java | 17 +
.../com/example/entity/ResourceRating.java | 57 +
.../com/example/entity/SymptomRecord.java | 121 +
.../com/example/entity/TreatmentResource.java | 33 +
.../example/exception/CustomException.java | 35 +
.../exception/GlobalExceptionHandler.java | 30 +
.../java/com/example/mapper/AdminMapper.java | 32 +
.../example/mapper/AnnouncementMapper.java | 41 +
.../mapper/AssessmentReportMapper.java | 50 +
.../com/example/mapper/ChatMessageMapper.java | 51 +
.../java/com/example/mapper/DoctorMapper.java | 29 +
.../example/mapper/DoctorPatientMapper.java | 28 +
.../com/example/mapper/PatientMapper.java | 29 +
.../mapper/ResourceCategoryMapper.java | 20 +
.../example/mapper/ResourceRatingMapper.java | 46 +
.../example/mapper/SymptomRecordMapper.java | 36 +
.../mapper/TreatmentResourceMapper.java | 67 +
.../com/example/service/AIChatService.java | 171 +
.../com/example/service/AdminService.java | 134 +
.../example/service/AnnouncementService.java | 164 +
.../service/AssessmentReportService.java | 530 +++
.../example/service/ChatMessageService.java | 221 ++
.../example/service/DoctorPatientService.java | 121 +
.../com/example/service/DoctorService.java | 132 +
.../com/example/service/PatientService.java | 200 +
.../service/RecommendationService.java | 385 ++
.../service/ResourceCategoryService.java | 88 +
.../service/ResourceRatingService.java | 161 +
.../example/service/SymptomRecordService.java | 735 ++++
.../service/TreatmentResourceService.java | 256 ++
.../com/example/websocket/ChatWebSocket.java | 195 +
src/main/resources/application.yml | 28 +
src/main/resources/mapper/AdminMapper.xml | 26 +
src/main/resources/mapper/DoctorMapper.xml | 25 +
.../resources/mapper/DoctorPatientMapper.xml | 91 +
src/main/resources/mapper/PatientMapper.xml | 25 +
.../resources/mapper/SymptomRecordMapper.xml | 61 +
vue/.env.development | 1 +
vue/.env.production | 1 +
vue/.gitignore | 33 +
vue/index.html | 16 +
vue/jsconfig.json | 8 +
vue/package-lock.json | 3399 +++++++++++++++++
vue/package.json | 32 +
vue/src/App.vue | 3 +
vue/src/assets/css/global.css | 21 +
vue/src/assets/css/index.scss | 7 +
vue/src/assets/css/manager.css | 108 +
vue/src/assets/fonts/FontAwesome.otf | Bin 0 -> 134808 bytes
vue/src/assets/fonts/font-awesome.css | 2337 ++++++++++++
vue/src/assets/fonts/fontawesome-webfont.eot | Bin 0 -> 165742 bytes
vue/src/assets/fonts/fontawesome-webfont.svg | 2671 +++++++++++++
vue/src/assets/fonts/fontawesome-webfont.ttf | Bin 0 -> 165548 bytes
vue/src/assets/fonts/fontawesome-webfont.woff | Bin 0 -> 98024 bytes
.../assets/fonts/fontawesome-webfont.woff2 | Bin 0 -> 77160 bytes
vue/src/assets/imgs/404.jpg | Bin 0 -> 156674 bytes
vue/src/assets/imgs/VCG41N1408837996.jpg | Bin 0 -> 196997 bytes
vue/src/assets/imgs/avatar.png | Bin 0 -> 4097 bytes
vue/src/assets/imgs/login.svg | 1 +
vue/src/assets/imgs/logo.png | Bin 0 -> 6849 bytes
vue/src/assets/imgs/register.svg | 1 +
vue/src/assets/logo.png | Bin 0 -> 6849 bytes
vue/src/main.js | 21 +
vue/src/router/index.js | 46 +
vue/src/utils/request.js | 54 +
vue/src/views/404.vue | 28 +
vue/src/views/Login.vue | 339 ++
vue/src/views/Manager.vue | 408 ++
vue/src/views/Register.vue | 394 ++
vue/src/views/manager/AIChat.vue | 430 +++
vue/src/views/manager/Admin.vue | 159 +
vue/src/views/manager/Announcement.vue | 248 ++
vue/src/views/manager/AnnouncementList.vue | 252 ++
vue/src/views/manager/AssessmentReports.vue | 446 +++
vue/src/views/manager/Chat.vue | 733 ++++
vue/src/views/manager/Doctor.vue | 195 +
vue/src/views/manager/GenerateReport.vue | 232 ++
vue/src/views/manager/Home.vue | 692 ++++
vue/src/views/manager/MyReports.vue | 239 ++
vue/src/views/manager/MyResources.vue | 438 +++
vue/src/views/manager/Password.vue | 74 +
vue/src/views/manager/Patient.vue | 230 ++
vue/src/views/manager/PatientReports.vue | 253 ++
vue/src/views/manager/ReportDetail.vue | 366 ++
vue/src/views/manager/ResourceCategory.vue | 245 ++
.../views/manager/ResourceRecommendation.vue | 496 +++
vue/src/views/manager/SymptomRecord.vue | 490 +++
vue/src/views/manager/SymptomStatistics.vue | 641 ++++
vue/src/views/manager/TreatmentResource.vue | 791 ++++
vue/src/views/manager/User.vue | 167 +
vue/src/views/manager/pAdmin.vue | 110 +
vue/src/views/manager/pDoctor.vue | 171 +
vue/src/views/manager/pPatient.vue | 156 +
vue/vite.config.js | 103 +
131 files changed, 25500 insertions(+)
create mode 100644 .gitignore
create mode 100644 pom.xml
create mode 100644 src/main/java/com/example/SpringbootApplication.java
create mode 100644 src/main/java/com/example/common/Constants.java
create mode 100644 src/main/java/com/example/common/Result.java
create mode 100644 src/main/java/com/example/common/config/CorsConfig.java
create mode 100644 src/main/java/com/example/common/config/JwtInterceptor.java
create mode 100644 src/main/java/com/example/common/config/TokenUtils.java
create mode 100644 src/main/java/com/example/common/config/WebConfig.java
create mode 100644 src/main/java/com/example/common/enums/ResultCodeEnum.java
create mode 100644 src/main/java/com/example/config/RestTemplateConfig.java
create mode 100644 src/main/java/com/example/config/WebSocketConfig.java
create mode 100644 src/main/java/com/example/controller/AIChatController.java
create mode 100644 src/main/java/com/example/controller/AccountController.java
create mode 100644 src/main/java/com/example/controller/AdminController.java
create mode 100644 src/main/java/com/example/controller/AnnouncementController.java
create mode 100644 src/main/java/com/example/controller/AssessmentReportController.java
create mode 100644 src/main/java/com/example/controller/ChatMessageController.java
create mode 100644 src/main/java/com/example/controller/DoctorController.java
create mode 100644 src/main/java/com/example/controller/DoctorPatientController.java
create mode 100644 src/main/java/com/example/controller/FileController.java
create mode 100644 src/main/java/com/example/controller/PatientController.java
create mode 100644 src/main/java/com/example/controller/RecommendationController.java
create mode 100644 src/main/java/com/example/controller/ResourceCategoryController.java
create mode 100644 src/main/java/com/example/controller/ResourceRatingController.java
create mode 100644 src/main/java/com/example/controller/SymptomRecordController.java
create mode 100644 src/main/java/com/example/controller/SymptomStatisticsController.java
create mode 100644 src/main/java/com/example/controller/TreatmentResourceController.java
create mode 100644 src/main/java/com/example/controller/WebController.java
create mode 100644 src/main/java/com/example/entity/Account.java
create mode 100644 src/main/java/com/example/entity/Admin.java
create mode 100644 src/main/java/com/example/entity/Announcement.java
create mode 100644 src/main/java/com/example/entity/AssessmentReport.java
create mode 100644 src/main/java/com/example/entity/ChatMessage.java
create mode 100644 src/main/java/com/example/entity/Doctor.java
create mode 100644 src/main/java/com/example/entity/DoctorPatient.java
create mode 100644 src/main/java/com/example/entity/Patient.java
create mode 100644 src/main/java/com/example/entity/ResourceCategory.java
create mode 100644 src/main/java/com/example/entity/ResourceRating.java
create mode 100644 src/main/java/com/example/entity/SymptomRecord.java
create mode 100644 src/main/java/com/example/entity/TreatmentResource.java
create mode 100644 src/main/java/com/example/exception/CustomException.java
create mode 100644 src/main/java/com/example/exception/GlobalExceptionHandler.java
create mode 100644 src/main/java/com/example/mapper/AdminMapper.java
create mode 100644 src/main/java/com/example/mapper/AnnouncementMapper.java
create mode 100644 src/main/java/com/example/mapper/AssessmentReportMapper.java
create mode 100644 src/main/java/com/example/mapper/ChatMessageMapper.java
create mode 100644 src/main/java/com/example/mapper/DoctorMapper.java
create mode 100644 src/main/java/com/example/mapper/DoctorPatientMapper.java
create mode 100644 src/main/java/com/example/mapper/PatientMapper.java
create mode 100644 src/main/java/com/example/mapper/ResourceCategoryMapper.java
create mode 100644 src/main/java/com/example/mapper/ResourceRatingMapper.java
create mode 100644 src/main/java/com/example/mapper/SymptomRecordMapper.java
create mode 100644 src/main/java/com/example/mapper/TreatmentResourceMapper.java
create mode 100644 src/main/java/com/example/service/AIChatService.java
create mode 100644 src/main/java/com/example/service/AdminService.java
create mode 100644 src/main/java/com/example/service/AnnouncementService.java
create mode 100644 src/main/java/com/example/service/AssessmentReportService.java
create mode 100644 src/main/java/com/example/service/ChatMessageService.java
create mode 100644 src/main/java/com/example/service/DoctorPatientService.java
create mode 100644 src/main/java/com/example/service/DoctorService.java
create mode 100644 src/main/java/com/example/service/PatientService.java
create mode 100644 src/main/java/com/example/service/RecommendationService.java
create mode 100644 src/main/java/com/example/service/ResourceCategoryService.java
create mode 100644 src/main/java/com/example/service/ResourceRatingService.java
create mode 100644 src/main/java/com/example/service/SymptomRecordService.java
create mode 100644 src/main/java/com/example/service/TreatmentResourceService.java
create mode 100644 src/main/java/com/example/websocket/ChatWebSocket.java
create mode 100644 src/main/resources/application.yml
create mode 100644 src/main/resources/mapper/AdminMapper.xml
create mode 100644 src/main/resources/mapper/DoctorMapper.xml
create mode 100644 src/main/resources/mapper/DoctorPatientMapper.xml
create mode 100644 src/main/resources/mapper/PatientMapper.xml
create mode 100644 src/main/resources/mapper/SymptomRecordMapper.xml
create mode 100644 vue/.env.development
create mode 100644 vue/.env.production
create mode 100644 vue/.gitignore
create mode 100644 vue/index.html
create mode 100644 vue/jsconfig.json
create mode 100644 vue/package-lock.json
create mode 100644 vue/package.json
create mode 100644 vue/src/App.vue
create mode 100644 vue/src/assets/css/global.css
create mode 100644 vue/src/assets/css/index.scss
create mode 100644 vue/src/assets/css/manager.css
create mode 100644 vue/src/assets/fonts/FontAwesome.otf
create mode 100644 vue/src/assets/fonts/font-awesome.css
create mode 100644 vue/src/assets/fonts/fontawesome-webfont.eot
create mode 100644 vue/src/assets/fonts/fontawesome-webfont.svg
create mode 100644 vue/src/assets/fonts/fontawesome-webfont.ttf
create mode 100644 vue/src/assets/fonts/fontawesome-webfont.woff
create mode 100644 vue/src/assets/fonts/fontawesome-webfont.woff2
create mode 100644 vue/src/assets/imgs/404.jpg
create mode 100644 vue/src/assets/imgs/VCG41N1408837996.jpg
create mode 100644 vue/src/assets/imgs/avatar.png
create mode 100644 vue/src/assets/imgs/login.svg
create mode 100644 vue/src/assets/imgs/logo.png
create mode 100644 vue/src/assets/imgs/register.svg
create mode 100644 vue/src/assets/logo.png
create mode 100644 vue/src/main.js
create mode 100644 vue/src/router/index.js
create mode 100644 vue/src/utils/request.js
create mode 100644 vue/src/views/404.vue
create mode 100644 vue/src/views/Login.vue
create mode 100644 vue/src/views/Manager.vue
create mode 100644 vue/src/views/Register.vue
create mode 100644 vue/src/views/manager/AIChat.vue
create mode 100644 vue/src/views/manager/Admin.vue
create mode 100644 vue/src/views/manager/Announcement.vue
create mode 100644 vue/src/views/manager/AnnouncementList.vue
create mode 100644 vue/src/views/manager/AssessmentReports.vue
create mode 100644 vue/src/views/manager/Chat.vue
create mode 100644 vue/src/views/manager/Doctor.vue
create mode 100644 vue/src/views/manager/GenerateReport.vue
create mode 100644 vue/src/views/manager/Home.vue
create mode 100644 vue/src/views/manager/MyReports.vue
create mode 100644 vue/src/views/manager/MyResources.vue
create mode 100644 vue/src/views/manager/Password.vue
create mode 100644 vue/src/views/manager/Patient.vue
create mode 100644 vue/src/views/manager/PatientReports.vue
create mode 100644 vue/src/views/manager/ReportDetail.vue
create mode 100644 vue/src/views/manager/ResourceCategory.vue
create mode 100644 vue/src/views/manager/ResourceRecommendation.vue
create mode 100644 vue/src/views/manager/SymptomRecord.vue
create mode 100644 vue/src/views/manager/SymptomStatistics.vue
create mode 100644 vue/src/views/manager/TreatmentResource.vue
create mode 100644 vue/src/views/manager/User.vue
create mode 100644 vue/src/views/manager/pAdmin.vue
create mode 100644 vue/src/views/manager/pDoctor.vue
create mode 100644 vue/src/views/manager/pPatient.vue
create mode 100644 vue/vite.config.js
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bf068a3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+target/
+.idea/
+springboot.iml
+
+file/
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..846a7dd
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,90 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.2.0
+
+
+ com.example
+ springboot
+ 0.0.1-SNAPSHOT
+
+
+ UTF-8
+ UTF-8
+ 21
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+ com.mysql
+ mysql-connector-j
+
+
+
+ com.baomidou
+ mybatis-plus-spring-boot3-starter
+ 3.5.5
+
+
+
+ org.projectlombok
+ lombok
+
+
+
+ com.github.pagehelper
+ pagehelper-spring-boot-starter
+ 1.4.6
+
+
+ org.mybatis
+ mybatis
+
+
+
+
+
+ cn.hutool
+ hutool-all
+ 5.8.18
+
+
+
+ com.auth0
+ java-jwt
+ 4.3.0
+
+
+
+ org.apache.poi
+ poi-ooxml
+ 4.1.2
+
+
+
+ org.springframework.boot
+ spring-boot-starter-websocket
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/example/SpringbootApplication.java b/src/main/java/com/example/SpringbootApplication.java
new file mode 100644
index 0000000..dc8a215
--- /dev/null
+++ b/src/main/java/com/example/SpringbootApplication.java
@@ -0,0 +1,18 @@
+package com.example;
+
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@SpringBootApplication
+@MapperScan("com.example.mapper")
+@EnableScheduling
+public class SpringbootApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringbootApplication.class, args);
+ }
+
+}
diff --git a/src/main/java/com/example/common/Constants.java b/src/main/java/com/example/common/Constants.java
new file mode 100644
index 0000000..2c2b1af
--- /dev/null
+++ b/src/main/java/com/example/common/Constants.java
@@ -0,0 +1,9 @@
+package com.example.common;
+
+public interface Constants {
+
+ String TOKEN = "token";
+
+ String USER_DEFAULT_PASSWORD = "123456";
+
+}
diff --git a/src/main/java/com/example/common/Result.java b/src/main/java/com/example/common/Result.java
new file mode 100644
index 0000000..ac82767
--- /dev/null
+++ b/src/main/java/com/example/common/Result.java
@@ -0,0 +1,72 @@
+package com.example.common;
+
+public class Result {
+ private String code;
+ private String msg;
+ private Object data;
+
+ private Result(Object data) {
+ this.data = data;
+ }
+
+ public Result() {
+ }
+
+ public static Result success() {
+ Result result = new Result();
+ result.setCode("200");
+ result.setMsg("请求成功");
+ return result;
+ }
+
+ public static Result success(Object data) {
+ Result result = success();
+ result.setData(data);
+ return result;
+ }
+
+ public static Result error() {
+ Result result = new Result();
+ result.setCode("500");
+ result.setMsg("请求失败");
+ return result;
+ }
+
+ public static Result error(String code, String msg) {
+ Result result = new Result();
+ result.setCode(code);
+ result.setMsg(msg);
+ return result;
+ }
+
+ public static Result error(String msg) {
+ Result result = new Result();
+ result.setCode("500");
+ result.setMsg(msg);
+ return result;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ public Object getData() {
+ return data;
+ }
+
+ public void setData(Object data) {
+ this.data = data;
+ }
+}
diff --git a/src/main/java/com/example/common/config/CorsConfig.java b/src/main/java/com/example/common/config/CorsConfig.java
new file mode 100644
index 0000000..9be21e6
--- /dev/null
+++ b/src/main/java/com/example/common/config/CorsConfig.java
@@ -0,0 +1,25 @@
+package com.example.common.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+
+/**
+ * 跨域配置
+ */
+@Configuration
+public class CorsConfig {
+
+ @Bean
+ public CorsFilter corsFilter() {
+ UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+ CorsConfiguration corsConfiguration = new CorsConfiguration();
+ corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
+ corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
+ corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
+ source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置
+ return new CorsFilter(source);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/common/config/JwtInterceptor.java b/src/main/java/com/example/common/config/JwtInterceptor.java
new file mode 100644
index 0000000..6e7d347
--- /dev/null
+++ b/src/main/java/com/example/common/config/JwtInterceptor.java
@@ -0,0 +1,82 @@
+package com.example.common.config;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.JWTVerifier;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.exceptions.JWTVerificationException;
+import com.example.common.Constants;
+import com.example.common.enums.ResultCodeEnum;
+import com.example.entity.*;
+import com.example.exception.CustomException;
+import com.example.service.*;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+/**
+ * jwt拦截器
+ */
+@Component
+public class JwtInterceptor implements HandlerInterceptor {
+
+ private static final Logger log = LoggerFactory.getLogger(JwtInterceptor.class);
+
+ @Resource
+ private AdminService adminService;
+ @Resource
+ private DoctorService doctorService;
+ @Resource
+ private PatientService patientService;
+
+
+ @Override
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
+ // 1. 从http请求的header中获取token
+ String token = request.getHeader(Constants.TOKEN);
+ if (ObjectUtil.isEmpty(token)) {
+ // 如果没拿到,从参数里再拿一次
+ token = request.getParameter(Constants.TOKEN);
+ }
+ // 2. 开始执行认证
+ if (ObjectUtil.isEmpty(token)) {
+ throw new CustomException(ResultCodeEnum.TOKEN_INVALID_ERROR);
+ }
+ Account account = null;
+ try {
+ // 解析token获取存储的数据
+ String userRole = JWT.decode(token).getAudience().get(0);
+ String userId = userRole.split("-")[0];
+ String role = userRole.split("-")[1];
+ // 根据userId查询数据库
+ if ("admin".equals(role)) {
+ account = adminService.selectById(Integer.valueOf(userId));
+ }
+ if ("doctor".equals(role)) {
+ account = doctorService.selectById(Integer.valueOf(userId));
+ }
+ if ("patient".equals(role)) {
+ account = patientService.selectById(Integer.valueOf(userId));
+ }
+
+
+ } catch (Exception e) {
+ throw new CustomException(ResultCodeEnum.TOKEN_CHECK_ERROR);
+ }
+ if (ObjectUtil.isNull(account)) {
+ throw new CustomException(ResultCodeEnum.USER_NOT_EXIST_ERROR);
+ }
+ try {
+ // 用户密码加签验证 token
+ JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(account.getPassword())).build();
+ jwtVerifier.verify(token); // 验证token
+ } catch (JWTVerificationException e) {
+ throw new CustomException(ResultCodeEnum.TOKEN_CHECK_ERROR);
+ }
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/common/config/TokenUtils.java b/src/main/java/com/example/common/config/TokenUtils.java
new file mode 100644
index 0000000..fbe82e9
--- /dev/null
+++ b/src/main/java/com/example/common/config/TokenUtils.java
@@ -0,0 +1,88 @@
+package com.example.common.config;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.example.entity.Account;
+import com.example.service.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletRequest;
+import java.util.Date;
+
+@Component
+public class TokenUtils {
+
+ private static AdminService staticAdminService;
+ private static DoctorService staticDoctorService;
+ private static PatientService staticPatientService;
+
+ private static final Logger log = LoggerFactory.getLogger(TokenUtils.class);
+
+ @Resource
+ private AdminService adminService;
+ @Resource
+ private DoctorService doctorService;
+ @Resource
+ private PatientService patientService;
+
+ @PostConstruct
+ public void setUserService() {
+ staticAdminService = adminService;
+ staticDoctorService = doctorService;
+ staticPatientService = patientService;
+ }
+
+ /**
+ * 生成token
+ */
+ public static String genToken(String userRole, String password) {
+ return JWT.create().withAudience(userRole) // 将 userId-role 保存到 token 里面,作为载荷
+ .withExpiresAt(DateUtil.offsetHour(new Date(), 2)) // 2小时后token过期
+ .sign(Algorithm.HMAC256(password)); // 以 password 作为 token 的密钥
+ }
+
+ /**
+ * 获取当前登录的用户信息
+ */
+ public static Account getCurrentUser() {
+ String token = null;
+ try {
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+ token = request.getHeader("token");
+ if (StrUtil.isBlank(token)) {
+ token = request.getParameter("token");
+ }
+ if (StrUtil.isBlank(token)) {
+ log.error("获取当前登录的token失败, token: {}", token);
+ return null;
+ }
+ // 解析token,获取用户的id
+ String userRole = JWT.decode(token).getAudience().get(0);
+ String userId = userRole.split("-")[0];
+ String role = userRole.split("-")[1];
+ Account account = null;
+ if ("admin".equals(role)) {
+ account = staticAdminService.selectById(Integer.valueOf(userId));
+ }
+ if ("doctor".equals(role)) {
+ account = staticDoctorService.selectById(Integer.valueOf(userId));
+ }
+ if ("patient".equals(role)) {
+ account = staticPatientService.selectById(Integer.valueOf(userId));
+ }
+
+ return account;
+ } catch (Exception e) {
+ log.error("获取当前登录的管理员信息失败, token={}", token, e);
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/common/config/WebConfig.java b/src/main/java/com/example/common/config/WebConfig.java
new file mode 100644
index 0000000..5a0627b
--- /dev/null
+++ b/src/main/java/com/example/common/config/WebConfig.java
@@ -0,0 +1,24 @@
+package com.example.common.config;
+
+import jakarta.annotation.Resource;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class WebConfig implements WebMvcConfigurer {
+
+ @Resource
+ private JwtInterceptor jwtInterceptor;
+
+ // 加自定义拦截器JwtInterceptor,设置拦截规则
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(jwtInterceptor).addPathPatterns("/**")
+ .excludePathPatterns("/")
+ .excludePathPatterns("/login", "/register", "/files/**", "/role/selectAll","/institution/selectAll")
+ .excludePathPatterns("/doctor") // 放行医生列表获取接口,用于患者注册时选择医生
+ .excludePathPatterns("/ws/**", "/notification/**") // 放行WebSocket和通知相关的路径
+ .excludePathPatterns("/eventInstitution/checkAndUpdateEventStatus"); // 放行事件状态检查接口
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/common/enums/ResultCodeEnum.java b/src/main/java/com/example/common/enums/ResultCodeEnum.java
new file mode 100644
index 0000000..56a803f
--- /dev/null
+++ b/src/main/java/com/example/common/enums/ResultCodeEnum.java
@@ -0,0 +1,27 @@
+package com.example.common.enums;
+
+public enum ResultCodeEnum {
+ SUCCESS("200", "成功"),
+
+ PARAM_ERROR("400", "参数异常"),
+ TOKEN_INVALID_ERROR("401", "无效的token"),
+ TOKEN_CHECK_ERROR("401", "token验证失败,请重新登录"),
+ PARAM_LOST_ERROR("4001", "参数缺失"),
+ NO_AUTH_ERROR("403", "没有操作权限"),
+
+ SYSTEM_ERROR("500", "系统异常"),
+ USER_EXIST_ERROR("5001", "用户名已存在"),
+ USER_NOT_LOGIN("5002", "用户未登录"),
+ USER_ACCOUNT_ERROR("5003", "账号或密码错误"),
+ USER_NOT_EXIST_ERROR("5004", "用户不存在"),
+ PARAM_PASSWORD_ERROR("5005", "原密码输入错误"),
+ ;
+
+ public String code;
+ public String msg;
+
+ ResultCodeEnum(String code, String msg) {
+ this.code = code;
+ this.msg = msg;
+ }
+}
diff --git a/src/main/java/com/example/config/RestTemplateConfig.java b/src/main/java/com/example/config/RestTemplateConfig.java
new file mode 100644
index 0000000..88e398a
--- /dev/null
+++ b/src/main/java/com/example/config/RestTemplateConfig.java
@@ -0,0 +1,14 @@
+package com.example.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class RestTemplateConfig {
+
+ @Bean
+ public RestTemplate restTemplate() {
+ return new RestTemplate();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/config/WebSocketConfig.java b/src/main/java/com/example/config/WebSocketConfig.java
new file mode 100644
index 0000000..8c55302
--- /dev/null
+++ b/src/main/java/com/example/config/WebSocketConfig.java
@@ -0,0 +1,20 @@
+package com.example.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+/**
+ * WebSocket配置类
+ */
+@Configuration
+public class WebSocketConfig {
+
+ /**
+ * 注入ServerEndpointExporter,自动注册使用了@ServerEndpoint注解的bean
+ */
+ @Bean
+ public ServerEndpointExporter serverEndpointExporter() {
+ return new ServerEndpointExporter();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/controller/AIChatController.java b/src/main/java/com/example/controller/AIChatController.java
new file mode 100644
index 0000000..40a4a4d
--- /dev/null
+++ b/src/main/java/com/example/controller/AIChatController.java
@@ -0,0 +1,56 @@
+package com.example.controller;
+
+import com.example.common.Result;
+import com.example.common.config.TokenUtils;
+import com.example.entity.Account;
+import com.example.service.AIChatService;
+import jakarta.annotation.Resource;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * AI聊天控制器
+ */
+@RestController
+@RequestMapping("/aiChat")
+public class AIChatController {
+
+ @Resource
+ private AIChatService aiChatService;
+
+ /**
+ * 发送消息到AI并获取回复
+ */
+ @PostMapping("/sendMessage")
+ public Result sendMessage(@RequestBody Map params) {
+ String message = params.get("message");
+
+ // 获取当前登录用户
+ Account currentUser = TokenUtils.getCurrentUser();
+ if (currentUser == null) {
+ return Result.error("401", "请先登录");
+ }
+
+ // 获取AI回复
+ String aiReply = aiChatService.sendMessage(message);
+
+ Map userMessage = new HashMap<>();
+ userMessage.put("content", message);
+ userMessage.put("messageType", "user");
+ userMessage.put("createTime", LocalDateTime.now());
+
+ Map aiMessage = new HashMap<>();
+ aiMessage.put("content", aiReply);
+ aiMessage.put("messageType", "ai");
+ aiMessage.put("createTime", LocalDateTime.now());
+
+ Map resultMap = new HashMap<>();
+ resultMap.put("userMessage", userMessage);
+ resultMap.put("aiMessage", aiMessage);
+
+ return Result.success(resultMap);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/controller/AccountController.java b/src/main/java/com/example/controller/AccountController.java
new file mode 100644
index 0000000..b2865d0
--- /dev/null
+++ b/src/main/java/com/example/controller/AccountController.java
@@ -0,0 +1,48 @@
+package com.example.controller;
+
+import com.example.common.Result;
+import com.example.common.config.TokenUtils;
+import com.example.entity.Account;
+import com.example.entity.Patient;
+import com.example.service.PatientService;
+import jakarta.annotation.Resource;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * 账号相关接口
+ */
+@RestController
+@RequestMapping("/account")
+public class AccountController {
+
+ @Resource
+ private PatientService patientService;
+
+ /**
+ * 获取所有患者列表(仅管理员可用)
+ *
+ * @param name 可选的患者姓名过滤
+ * @return 患者列表
+ */
+ @GetMapping("/listPatients")
+ public Result listPatients(@RequestParam(required = false) String name) {
+ Account currentUser = TokenUtils.getCurrentUser();
+ if (currentUser == null || !"admin".equals(currentUser.getRole())) {
+ return Result.error("401", "无权限,只有管理员可以访问此接口");
+ }
+
+ Patient searchParam = null;
+ if (name != null && !name.isEmpty()) {
+ searchParam = new Patient();
+ searchParam.setName(name);
+ }
+
+ List patients = patientService.selectAll(searchParam);
+ return Result.success(patients);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/controller/AdminController.java b/src/main/java/com/example/controller/AdminController.java
new file mode 100644
index 0000000..2ef7f62
--- /dev/null
+++ b/src/main/java/com/example/controller/AdminController.java
@@ -0,0 +1,93 @@
+package com.example.controller;
+
+import com.example.common.Result;
+import com.example.entity.Admin;
+import com.example.service.AdminService;
+import com.github.pagehelper.PageInfo;
+import jakarta.annotation.Resource;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+* 描述:管理员相关接口
+*/
+@RestController
+@RequestMapping("/admin")
+public class AdminController {
+
+ @Resource
+ AdminService adminService;
+
+ /**
+ * 新增
+ */
+ @PostMapping("/add")
+ public Result add(@RequestBody Admin admin) {
+
+ adminService.add(admin);
+ return Result.success();
+ }
+
+ /**
+ * 删除
+ */
+ @DeleteMapping("/delete/{id}")
+ public Result delete(@PathVariable Integer id) {
+ adminService.deleteById(id);
+ return Result.success();
+ }
+
+ /**
+ * 批量删除
+ */
+ @DeleteMapping("/delete/batch")
+ public Result delete(@RequestBody List ids) {
+ adminService.deleteBatch(ids);
+ return Result.success();
+ }
+
+ /**
+ * 更新
+ */
+ @PutMapping("/update")
+ public Result update(@RequestBody Admin admin) {
+
+ adminService.updateById(admin);
+ return Result.success();
+ }
+
+ /**
+ * 查询单个
+ */
+ @GetMapping("/selectById/{id}")
+ public Result selectById(@PathVariable Integer id) {
+ Admin admin = adminService.selectById(id);
+ return Result.success(admin);
+ }
+
+ /**
+ * 查询所有
+ */
+ @GetMapping("/selectAll")
+ public Result selectAll(Admin admin) {
+ List list = adminService.selectAll(admin);
+ return Result.success(list);
+ }
+
+ /**
+ * 查询所有
+ */
+ @GetMapping("/selectPage")
+ public Result selectPage(
+ Admin admin,
+ @RequestParam(defaultValue = "1") Integer pageNum,
+ @RequestParam(defaultValue = "10") Integer pageSize) {
+ PageInfo pageInfo = adminService.selectPage(admin, pageNum, pageSize);
+ return Result.success(pageInfo);
+ }
+
+
+
+
+}
diff --git a/src/main/java/com/example/controller/AnnouncementController.java b/src/main/java/com/example/controller/AnnouncementController.java
new file mode 100644
index 0000000..fcc84e7
--- /dev/null
+++ b/src/main/java/com/example/controller/AnnouncementController.java
@@ -0,0 +1,109 @@
+package com.example.controller;
+
+import com.example.common.Result;
+import com.example.entity.Announcement;
+import com.example.service.AnnouncementService;
+import com.github.pagehelper.PageInfo;
+import jakarta.annotation.Resource;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 公告控制器
+ */
+@RestController
+@RequestMapping("/announcement")
+public class AnnouncementController {
+
+ @Resource
+ private AnnouncementService announcementService;
+
+ /**
+ * 添加公告
+ * @param announcement 公告信息
+ * @return 结果
+ */
+ @PostMapping
+ public Result add(@RequestBody Announcement announcement) {
+ announcementService.add(announcement);
+ return Result.success();
+ }
+
+ /**
+ * 更新公告
+ * @param announcement 公告信息
+ * @return 结果
+ */
+ @PutMapping
+ public Result update(@RequestBody Announcement announcement) {
+ announcementService.update(announcement);
+ return Result.success();
+ }
+
+ /**
+ * 删除公告
+ * @param id 公告ID
+ * @return 结果
+ */
+ @DeleteMapping("/{id}")
+ public Result delete(@PathVariable Integer id) {
+ announcementService.delete(id);
+ return Result.success();
+ }
+
+ /**
+ * 获取公告详情
+ * @param id 公告ID
+ * @return 公告信息
+ */
+ @GetMapping("/{id}")
+ public Result getById(@PathVariable Integer id) {
+ Announcement announcement = announcementService.getById(id);
+ return Result.success(announcement);
+ }
+
+ /**
+ * 获取所有已发布的公告(分页,所有用户可访问)
+ * @param pageNum 页码
+ * @param pageSize 每页大小
+ * @param title 标题关键字
+ * @return 分页公告列表
+ */
+ @GetMapping("/page")
+ public Result getPublishedPage(
+ @RequestParam(defaultValue = "1") Integer pageNum,
+ @RequestParam(defaultValue = "10") Integer pageSize,
+ @RequestParam(required = false) String title) {
+ PageInfo pageInfo = announcementService.getPublishedPage(pageNum, pageSize, title);
+ return Result.success(pageInfo);
+ }
+
+ /**
+ * 获取所有公告(分页,包括草稿,仅管理员可用)
+ * @param pageNum 页码
+ * @param pageSize 每页大小
+ * @param title 标题关键字
+ * @return 分页公告列表
+ */
+ @GetMapping("/adminPage")
+ public Result getAllForAdmin(
+ @RequestParam(defaultValue = "1") Integer pageNum,
+ @RequestParam(defaultValue = "10") Integer pageSize,
+ @RequestParam(required = false) String title) {
+ PageInfo pageInfo = announcementService.getAllForAdmin(pageNum, pageSize, title);
+ return Result.success(pageInfo);
+ }
+
+ /**
+ * 获取最新的几条已发布公告(用于首页展示)
+ * @param limit 限制条数
+ * @return 公告列表
+ */
+ @GetMapping("/latest")
+ public Result getLatestPublished(
+ @RequestParam(defaultValue = "5") Integer limit) {
+ List list = announcementService.getLatestPublished(limit);
+ return Result.success(list);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/controller/AssessmentReportController.java b/src/main/java/com/example/controller/AssessmentReportController.java
new file mode 100644
index 0000000..8abaeb4
--- /dev/null
+++ b/src/main/java/com/example/controller/AssessmentReportController.java
@@ -0,0 +1,116 @@
+package com.example.controller;
+
+import com.example.common.Result;
+import com.example.common.config.TokenUtils;
+import com.example.entity.Account;
+import com.example.entity.AssessmentReport;
+import com.example.service.AssessmentReportService;
+import jakarta.annotation.Resource;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 评估报告控制器
+ */
+@RestController
+@RequestMapping("/assessmentReport")
+public class AssessmentReportController {
+
+ @Resource
+ private AssessmentReportService assessmentReportService;
+
+ /**
+ * 手动生成评估报告
+ */
+ @PostMapping("/generate")
+ public Result generate(@RequestBody Map params) {
+ Integer patientId = params.get("patientId") != null ? Integer.valueOf(params.get("patientId").toString()) : null;
+ String reportPeriod = params.get("reportPeriod") != null ? params.get("reportPeriod").toString() : null;
+
+ if (patientId == null) {
+ return Result.error("400", "缺少必要参数patientId");
+ }
+ if (reportPeriod == null) {
+ return Result.error("400", "缺少必要参数reportPeriod");
+ }
+
+ AssessmentReport report = assessmentReportService.generateReport(patientId, reportPeriod);
+ return Result.success(report);
+ }
+
+ /**
+ * 获取患者的评估报告列表
+ */
+ @GetMapping("/patient/{patientId}")
+ public Result getReportsByPatientId(@PathVariable Integer patientId) {
+ List reports = assessmentReportService.getReportsByPatientId(patientId);
+ return Result.success(reports);
+ }
+
+ /**
+ * 获取医生负责的患者的评估报告列表
+ */
+ @GetMapping("/doctor")
+ public Result getReportsByDoctor() {
+ Account currentUser = TokenUtils.getCurrentUser();
+ if (currentUser == null) {
+ return Result.error("401", "未登录");
+ }
+
+ List reports = assessmentReportService.getReportsByDoctorId(currentUser.getId());
+ return Result.success(reports);
+ }
+
+ /**
+ * 获取所有评估报告列表(管理员使用)
+ */
+ @GetMapping("/admin")
+ public Result getAllReports() {
+ List reports = assessmentReportService.getAllReports();
+ return Result.success(reports);
+ }
+
+ /**
+ * 添加医生批注
+ */
+ @PutMapping("/comment/{reportId}")
+ public Result addComment(@PathVariable Integer reportId, @RequestParam(required = false) String comment) {
+ if (comment == null || comment.isEmpty()) {
+ return Result.error("400", "评论内容不能为空");
+ }
+ assessmentReportService.addDoctorComment(reportId, comment);
+ return Result.success();
+ }
+
+ /**
+ * 更新报告状态为已读
+ */
+ @PutMapping("/read/{reportId}")
+ public Result markAsRead(@PathVariable Integer reportId) {
+ assessmentReportService.markAsRead(reportId);
+ return Result.success();
+ }
+
+ /**
+ * 获取评估报告详情
+ */
+ @GetMapping("/{reportId}")
+ public Result getReportById(@PathVariable Integer reportId) {
+ // 获取当前用户
+ Account currentUser = TokenUtils.getCurrentUser();
+ if (currentUser == null) {
+ return Result.error("401", "未登录");
+ }
+
+ // 通过ID获取报告
+ AssessmentReport report = assessmentReportService.getReportById(reportId);
+
+ if (report == null) {
+ return Result.error("404", "报告不存在");
+ }
+
+ return Result.success(report);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/controller/ChatMessageController.java b/src/main/java/com/example/controller/ChatMessageController.java
new file mode 100644
index 0000000..9327ff7
--- /dev/null
+++ b/src/main/java/com/example/controller/ChatMessageController.java
@@ -0,0 +1,48 @@
+package com.example.controller;
+
+import com.example.common.Result;
+import com.example.entity.ChatMessage;
+import com.example.service.ChatMessageService;
+import jakarta.annotation.Resource;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 聊天消息控制器
+ */
+@RestController
+@RequestMapping("/chat")
+public class ChatMessageController {
+
+ @Resource
+ private ChatMessageService chatMessageService;
+
+ /**
+ * 发送消息
+ */
+ @PostMapping("/send")
+ public Result send(@RequestBody ChatMessage chatMessage) {
+ ChatMessage message = chatMessageService.sendMessage(chatMessage);
+ return Result.success(message);
+ }
+
+ /**
+ * 获取聊天历史记录
+ */
+ @GetMapping("/history")
+ public Result getChatHistory(@RequestParam Integer contactId, @RequestParam String contactType) {
+ List messages = chatMessageService.getChatHistory(contactId, contactType);
+ return Result.success(messages);
+ }
+
+ /**
+ * 获取聊天联系人列表
+ */
+ @GetMapping("/contacts")
+ public Result getContactList() {
+ List