Compare commits
488 Commits
V1.3
...
9b35fec931
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b35fec931 | ||
| e20e2b637f | |||
| ebd2e8aa75 | |||
| cb268fe26d | |||
| 23bd49d940 | |||
| 32adb984e2 | |||
| c1d453600b | |||
| 02eab2d932 | |||
| d5c8b7a1ad | |||
|
|
4053064a22 | ||
|
|
089e28f913 | ||
| cf9ab03b17 | |||
| d332650bfa | |||
| 840983ac94 | |||
|
|
86673d7be3 | ||
|
|
3753a916f5 | ||
|
|
0556f77870 | ||
|
|
b185c156ca | ||
|
|
a48308dcbf | ||
| e37f6a70f9 | |||
|
|
28629ccd35 | ||
|
|
fbd7f0be78 | ||
|
|
763f05da84 | ||
|
|
8c74d45332 | ||
| 8d62c0461b | |||
| 58936c957d | |||
| 062c4a92b8 | |||
| fb9f85e967 | |||
| 38ef377cbd | |||
| 240d5dc3f7 | |||
| 82702f16e0 | |||
| 0b4b63dfbe | |||
| b4422a0dca | |||
| d8627df2dd | |||
| 09ca077559 | |||
| 3091fc7337 | |||
| b0850257c8 | |||
| fa2884b320 | |||
| 941054734f | |||
| 8d69dc3c00 | |||
| 2157806ba5 | |||
| 2236cbea36 | |||
| 2128e717e7 | |||
| 1311e87e13 | |||
| ddf1553846 | |||
| 5d82800976 | |||
| 0c35044231 | |||
| 61f4020487 | |||
| aeb6b95970 | |||
| b5ce854eb6 | |||
| 4d4828ea71 | |||
| 10e738edd9 | |||
| 88a4e58130 | |||
| 76c324b0df | |||
| a65e8dd2cc | |||
| 1ac9b5ae0b | |||
| 8f77fe8bc9 | |||
| b567747901 | |||
| ed7004ae85 | |||
| d1670b79a0 | |||
| 54cde91aac | |||
| 7974bdc51c | |||
| 91cb465962 | |||
| 1b2c248fa2 | |||
| 1c16d6ba0f | |||
| 49b8a975a8 | |||
| d17a502da1 | |||
| 430adc2112 | |||
| 5f5c47f528 | |||
| 92d74c47ce | |||
| 5d8e7b667f | |||
| 58449fc2f9 | |||
| 4c541f43b9 | |||
| 9a037ae446 | |||
| bb0eb60eae | |||
| cf5dbc6133 | |||
| 5f6fa50000 | |||
| 08b2e76d47 | |||
| 5ffeab8999 | |||
| fc6640b846 | |||
| 8e11dde7c0 | |||
| e8f24ee290 | |||
| a1e07a204b | |||
| a080b4294c | |||
| 0827ce2908 | |||
| 5f600209b8 | |||
| 79ea4ed4f7 | |||
| cbd3e7f981 | |||
| 3c497417dc | |||
| 088861f66e | |||
| 8914c8b143 | |||
| 8c607c8749 | |||
| 3115e38cc4 | |||
| ae6c486114 | |||
| a41ffa4cfc | |||
| b1f74161f8 | |||
| 3bab56a19b | |||
| abc0674531 | |||
| 85fcb7c2e2 | |||
| fc6a7437a3 | |||
| 999a0992e7 | |||
| 55b3dfc077 | |||
|
|
32d1673667 | ||
| 17c7cc70ed | |||
| 44be570ffa | |||
| c6f4996ba7 | |||
| 6c20b15339 | |||
| c297072b36 | |||
| 4c6886be6a | |||
| 8beb7f3d3d | |||
| 91968530b4 | |||
| 0833f82fb4 | |||
| cce71f324b | |||
| ee6efafde4 | |||
| 2051807ecf | |||
| 0a4de15599 | |||
| 25b3c26ec2 | |||
| 91d673de77 | |||
| 0bfa7183f9 | |||
| 79d451931d | |||
| ae5f1c795b | |||
| c1074fc4fb | |||
| e832b6d38e | |||
| 5043466e84 | |||
| fcaeedb543 | |||
| 8cf434a46f | |||
| bfbc061b0b | |||
| f92cd830e9 | |||
| a7a1a18445 | |||
| d1331cd4e1 | |||
| 37d08b8545 | |||
| e69f499ac0 | |||
| 3baf7161f1 | |||
| 85188651ca | |||
| d6fbfb1427 | |||
| 966847499a | |||
| 1e91171001 | |||
| 51f495f81e | |||
| 1e6a5972b9 | |||
| 515f03a5cd | |||
| b27542ba6d | |||
| 4790855079 | |||
| 72cf9c6f2d | |||
| 19ecb65183 | |||
| d85a8684a6 | |||
| 574a9267bf | |||
| 27a7396c78 | |||
| 633cf2c17f | |||
| 3188ca5752 | |||
| c79e4c2623 | |||
| f3c451d0a1 | |||
| a077bd57d4 | |||
| cf16c497bd | |||
| fd1ab239a9 | |||
| caf65e3113 | |||
| c18c21ff4c | |||
| ab6849c9eb | |||
| 6b555f2563 | |||
| 7645405c5b | |||
| 5bfadb9174 | |||
| e1b9d36153 | |||
| fdb8d6c934 | |||
| 22a1ac57b2 | |||
| 4d243815a6 | |||
| 882e8c9199 | |||
| a0c87f6335 | |||
| 538dde55f7 | |||
| f33e3c6f15 | |||
| 0794782505 | |||
| d37fa46b5f | |||
| 8fcc229ad8 | |||
| 39aa710fd3 | |||
| 49f95b40ea | |||
| eb2d7302b7 | |||
| eb26f9db34 | |||
| bd6f3ca587 | |||
| a58e02f2cb | |||
| 8c8ef13021 | |||
| d9a0a98f52 | |||
| 8c84b6eb46 | |||
| 3d797cc0e0 | |||
| df7281a2d4 | |||
| f83d7ae520 | |||
| d9c8525b94 | |||
| bcc5cbb2fb | |||
| 67a8351d70 | |||
| 391506e423 | |||
| b1117b4157 | |||
| b0eb9861b9 | |||
| b863c14f2b | |||
| 18f6a845e6 | |||
| e1385cb3e6 | |||
| c8ca56c3f5 | |||
| b149f7d687 | |||
| 19702c25e5 | |||
|
|
eaa681c9ff | ||
| 205c58782b | |||
| 00e1c62de0 | |||
| 46c9787216 | |||
| e0a768de2e | |||
| fc7f931728 | |||
|
|
3ccb970a09 | ||
|
|
8a9a622aeb | ||
|
|
29e7f0937b | ||
| 029d534b3c | |||
|
|
213723b220 | ||
|
|
c636e77fd0 | ||
|
|
7407562ec5 | ||
|
|
b3c27ec789 | ||
|
|
601ae40666 | ||
| 3dda5ce72d | |||
|
|
99d4c28b95 | ||
|
|
0e70de6de7 | ||
| 72eb1088df | |||
| a853c16854 | |||
| 73a349f98a | |||
| 5fb7a3f488 | |||
| a8eb7d5697 | |||
| eb3b142ce4 | |||
| 9f6a39ba30 | |||
| f7f2f98bbe | |||
| 79e68ee14e | |||
| bc8987c463 | |||
| 3f7174fcd1 | |||
| 080008f447 | |||
| 5c3d935615 | |||
| a0845127c6 | |||
| ba65ab303b | |||
|
|
6fbdddf0ee | ||
| 173cbc7f87 | |||
|
|
2e341a123e | ||
|
|
8beff2ee14 | ||
| 1b939ba5b7 | |||
| 577daabe1c | |||
| 327e88e6d4 | |||
|
|
548fabcffe | ||
| 263e21e157 | |||
| d7955aa628 | |||
|
|
d197f7555f | ||
| a0e52da437 | |||
|
|
88d79729fe | ||
| 6dc6480e64 | |||
| 98c263a72b | |||
| 50a2ef9e00 | |||
| 065f7052c6 | |||
| e23d42404d | |||
| 4120d4e001 | |||
| 1bd2089047 | |||
| 6d9ff7dc10 | |||
| ae7ca984f8 | |||
| 69b7a4d865 | |||
| 864bf55025 | |||
| 249ef5f87e | |||
|
|
df3fb6c66c | ||
|
|
10ec9f4c1b | ||
| 0b98763c05 | |||
|
|
3d3b21a775 | ||
|
|
4ba4f80946 | ||
|
|
ed7cb2dab5 | ||
| 50ef9e6743 | |||
| 250d7dde34 | |||
| 69f3e066db | |||
|
|
afb0c3933c | ||
|
|
45ac07e57c | ||
|
|
262ea97824 | ||
|
|
dcfa13f239 | ||
|
|
27c3c850d6 | ||
| 122a15a73d | |||
| 61749aee4d | |||
| 97a29a31c5 | |||
| c3734f921c | |||
| c561586cfa | |||
|
|
60593233bc | ||
| 992b03f9c2 | |||
| 36628342dc | |||
|
|
3783e4a872 | ||
| 584f79294b | |||
| a5884ec069 | |||
| cc2f7db754 | |||
| fcccfc1959 | |||
| c5ec91e7d3 | |||
| 6b67e25d94 | |||
| 6da3b63012 | |||
|
|
ea0f0e2294 | ||
|
|
980f0aeb9c | ||
|
|
17b40118ce | ||
|
|
d10a78e5e8 | ||
|
|
f7ad010b2a | ||
|
|
1a7ff0a686 | ||
|
|
3ad3f21362 | ||
|
|
c84fc3c236 | ||
|
|
a6561e2ca6 | ||
|
|
dfe35bb7f0 | ||
| 18c96e006f | |||
| f5db504363 | |||
| deb31c969a | |||
| e7dac9762d | |||
|
|
89862878b5 | ||
|
|
e105919dab | ||
|
|
e83fc94334 | ||
| 5bf7ab481f | |||
| afa904bd83 | |||
| a343464d8d | |||
| 4a2485e434 | |||
|
|
4e2d4d85ec | ||
| 7ddf6211ee | |||
| d44600b641 | |||
| a68c4402de | |||
| 93103f7f40 | |||
| 7202151a41 | |||
| 491d8f8930 | |||
| b886726ecc | |||
|
|
9d0dde6794 | ||
|
|
f3578b3202 | ||
|
|
0610ba7cb5 | ||
|
|
8b848f787a | ||
| a794cd0ce3 | |||
|
|
d97fd0bed1 | ||
|
|
c0e67722d9 | ||
|
|
aca7fea69f | ||
| ce9344f9ce | |||
| 991ad61655 | |||
|
|
e4ac857461 | ||
|
|
24ab98ae89 | ||
| e79ab9ac4f | |||
| b66c2027d1 | |||
| 09bf895711 | |||
|
|
825cdd58ae | ||
| 0977eb8145 | |||
|
|
73efeecfc1 | ||
| fe8fb3d321 | |||
|
|
618fb1e340 | ||
|
|
215fe8b889 | ||
|
|
3e32458b7f | ||
| a8e170ea45 | |||
| 1856ae50fd | |||
| 1711e6c115 | |||
|
|
b3f226feab | ||
| c086dc8c77 | |||
| 6762341fbd | |||
| d5f8b0f23b | |||
|
|
38233110f2 | ||
| 6ebb59bc5e | |||
| 69aefab280 | |||
| 3d3ff82e24 | |||
| 69780d204f | |||
|
|
ef52f290fe | ||
| e9d1119777 | |||
|
|
cf182f0e34 | ||
|
|
626ae1a459 | ||
| 3d6977328f | |||
| 2dcd7ba1d5 | |||
|
|
16a4d38113 | ||
| 57c98ea39d | |||
| 08f7e35042 | |||
| 43f3d1ba94 | |||
| 2e45c6c029 | |||
| 945182c6f8 | |||
|
|
f7de87860b | ||
| 67e4de0d68 | |||
|
|
602d521424 | ||
|
|
01e14ee084 | ||
|
|
4a5572de26 | ||
| 88a516d1be | |||
| 9ce967002a | |||
| fd536a035e | |||
| df84a7eefa | |||
| 2804703eaa | |||
| e14a0e3d13 | |||
| 5a99fe8234 | |||
| 3ad5c5533f | |||
|
|
9997f4f7c9 | ||
|
|
3d4e4a8119 | ||
|
|
3deac74898 | ||
| 7bbc50ef47 | |||
| 4ae6765a15 | |||
| 1292853c5d | |||
|
|
41791c9ccc | ||
|
|
0674215b53 | ||
| e42d990304 | |||
| 0dbe9a57c8 | |||
| 85ea831a1c | |||
| 7ac26cf781 | |||
| b7412648b4 | |||
|
|
97571652e5 | ||
| b5d4da97f9 | |||
|
|
e5edb6bda2 | ||
|
|
0e1ae53194 | ||
| a1efd3f91b | |||
| 3211553d0d | |||
| a57a326b83 | |||
| f77d0a2567 | |||
| 72581466aa | |||
|
|
4b3471df06 | ||
|
|
68c65ae8bd | ||
| 1b879addc7 | |||
|
|
3888859b2b | ||
|
|
f03d2e1633 | ||
| bc91eb7cdc | |||
|
|
93120e973a | ||
| c6a27f6276 | |||
| 778704c9dc | |||
| ff227b40c1 | |||
| c7d8ab5b48 | |||
| 9c27b2a134 | |||
|
|
3f919188d2 | ||
| 8942058972 | |||
|
|
6c2dbf0418 | ||
|
|
85e185bab8 | ||
|
|
88aa1517ef | ||
|
|
c05118c427 | ||
|
|
2a7f1326b9 | ||
|
|
c07255fe5b | ||
|
|
749bfc89dd | ||
| 52cc5e3aae | |||
| 642c4a0941 | |||
| 30953d5771 | |||
| 83e0c663c9 | |||
| b19337e76a | |||
| ba607346bd | |||
|
|
433c452a40 | ||
|
|
a1be7fdbfd | ||
|
|
87409d0c93 | ||
| d5c8ae8d45 | |||
| bc45e9c8c6 | |||
|
|
42992382c0 | ||
|
|
22d7eba510 | ||
| 9728c8a6dd | |||
| c951144ac6 | |||
|
|
0b179fffd6 | ||
|
|
75374ac5d3 | ||
|
|
2a83719b87 | ||
|
|
e58f2d807b | ||
|
|
b2884def17 | ||
|
|
064840dd42 | ||
| 1aa814c766 | |||
|
|
b9719a51d1 | ||
|
|
03b83aaf7c | ||
|
|
d93976483b | ||
| dd0a3a915c | |||
| 2f3994c575 | |||
| daa78e128f | |||
| 2ca594cb39 | |||
|
|
7805c26f4a | ||
|
|
b7d34537c2 | ||
| c1213fcf59 | |||
| a64edace55 | |||
| 4afe0d107c | |||
|
|
d8af11412f | ||
|
|
00816c9834 | ||
|
|
4fb7bea80a | ||
|
|
0fc72cb270 | ||
|
|
eadf521903 | ||
| f786fdbc3f | |||
| 92c4c938a3 | |||
|
|
a94a1b7b69 | ||
|
|
48755c2d9e | ||
|
|
f99f8eb560 | ||
|
|
ddc7ce2fe7 | ||
|
|
c9899c62d2 | ||
| 8b9837d7dc | |||
| 2cba41331a | |||
| 4da5ca427b | |||
| f4605b1af7 | |||
|
|
d2babdc9ed | ||
| 4d0599eac1 | |||
|
|
35d99df274 | ||
|
|
ce76b2f98d | ||
| 8fbca1a898 | |||
| d548215123 | |||
| 953d17dc8c | |||
|
|
b71a21ea5c | ||
|
|
0a20b5e34e | ||
| 388425084e | |||
| 51ee8d1b43 | |||
|
|
d29d56e712 | ||
|
|
9084ddaa98 | ||
|
|
be6d5c1ccc | ||
| 1bba9e598a | |||
| d58a5e8ab3 | |||
| e6ffb7101f | |||
|
|
48b2188cf9 | ||
|
|
8bc5d45976 | ||
| 04f6e7e960 | |||
| 8fb58bdab8 | |||
|
|
fdfe5334a1 | ||
|
|
66b99009e6 | ||
|
|
2c7456531d |
76
.github/copilot-instructions.md
vendored
Normal file
76
.github/copilot-instructions.md
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
# OpenHIS — AI 编码助手 指南
|
||||
|
||||
目的:帮助自动化/AI 编码代理快速上手本仓库,包含架构要点、关键文件、常用构建/运行命令以及项目约定。请只按照仓库内真实可见的内容提出修改建议或补充说明。
|
||||
|
||||
- **代码组织**: 本项目是一个 Java 后端(多模块 Maven)+ Vue3 前端(Vite)的大型应用。
|
||||
- 后端主模块目录:`openhis-server-new/`(顶层为 `pom`,包含多个子模块)。关键子模块示例:`openhis-application`, `openhis-domain`, `openhis-common`, `core-*` 系列。
|
||||
- 前端目录:`openhis-ui-vue3/`(Vite + Vue 3,使用 Pinia、Element Plus 等)。
|
||||
|
||||
- **大局观(Big Picture)**: 后端以 Spring Boot(Java 17)实现,使用多模块 Maven 管理公共库与业务模块;前端由单独仓库目录通过 Vite 构建并以环境变量(`VITE_APP_BASE_API`)与后端交互。后端扫描 `com.core` 与 `com.openhis` 包(见 `OpenHisApplication.java`),启动类位于:`openhis-server-new/openhis-application/src/main/java/com/openhis/OpenHisApplication.java`。
|
||||
|
||||
- **运行/构建(Windows PowerShell 示例)**:
|
||||
- 构建后端(从仓库根执行):
|
||||
|
||||
```powershell
|
||||
cd openhis-server-new
|
||||
mvn clean package -DskipTests
|
||||
```
|
||||
|
||||
- 仅运行后端模块(开发时常用):
|
||||
|
||||
```powershell
|
||||
cd openhis-server-new/openhis-application
|
||||
mvn spring-boot:run
|
||||
# 或在 IDE 中运行 `com.openhis.OpenHisApplication` 的 main()
|
||||
```
|
||||
|
||||
- 前端启动与构建(需要 Node.js v16.x,仓库 README 建议 v16.15):
|
||||
|
||||
```powershell
|
||||
cd openhis-ui-vue3
|
||||
npm install
|
||||
npm run dev # 本地开发(热重载)
|
||||
npm run build:prod # 生产构建
|
||||
```
|
||||
|
||||
- **环境与配置**:
|
||||
- 后端配置:`openhis-server-new/openhis-application/src/main/resources/application.yml`(数据库、端口、profile 等)。README 还提及 `application-druid.yml`(若存在请优先查看)。
|
||||
- 前端配置:多个 `.env.*` 文件(例如 `.env.development`, `.env.staging`, `.env.production`),关键变量:`VITE_APP_BASE_API`(例如 `/dev-api`),前端通过 `import.meta.env.VITE_APP_BASE_API` 拼接后端 URL(见 `src/utils/request.js`、多个视图与组件)。
|
||||
|
||||
- **重要约定 / 模式**:
|
||||
- 后端采用 Java 17、Spring Boot 2.5.x 家族,父 POM在 `openhis-server-new/pom.xml` 定义。常用依赖版本在该 POM 的 `<properties>` 中集中维护。
|
||||
- 模块间以 Maven 模块依赖与 `com.core` / `com.openhis` 包名分层(见 `pom.xml` 的 `<modules>` 与 `dependencyManagement`)。
|
||||
- 前端通过 Vite 插件配置(`openhis-ui-vue3/vite/plugins`)管理 svg、自动导入等。UI 框架为 Element Plus,状态管理为 Pinia。
|
||||
|
||||
- **集成点 & 外部依赖**:
|
||||
- 数据库:PostgreSQL(README 建议 v16.2),仓库根含一个大型初始化 SQL:`数据库初始话脚本(请使用navicat16版本导入).sql`,用于初始化表与演示数据。
|
||||
- 缓存/会话:Redis(需自行配置)。
|
||||
- 其他:Flowable(工作流),Druid(连接池监控),第三方服务通过特定配置类(例如 `YbServiceConfig` 在 `OpenHisApplication` 中启用)。
|
||||
|
||||
- **调试与常见位置**:
|
||||
- 启动类:`openhis-server-new/openhis-application/src/main/java/com/openhis/OpenHisApplication.java`。
|
||||
- 全局配置:`openhis-server-new/openhis-application/src/main/resources/`(`application.yml`、profile 文件等)。
|
||||
- 前端入口:`openhis-ui-vue3/src/main.js`、路由在 `openhis-ui-vue3/src/router/index.js`。
|
||||
- API 文档与监控路径(通常由后端暴露并被前端访问):
|
||||
- Swagger UI: `<VITE_APP_BASE_API>/swagger-ui/index.html`(前端视图在 `src/views/tool/swagger/index.vue`)。
|
||||
- Druid: `<VITE_APP_BASE_API>/druid/login.html`(见前端相关视图引用)。
|
||||
|
||||
- **为 AI 代理的具体建议(如何安全、有效地修改代码)**:
|
||||
- 修改后端时:优先在子模块(例如 `openhis-application`)本地运行 `mvn spring-boot:run` 验证启动与基础 API;大量改动前先执行 `mvn -T1C -DskipTests clean package` 在 CI 环境上验证构建(本地机器也可用)。
|
||||
- 修改前端时:检查/调整对应 `.env.*` 文件中的 `VITE_APP_BASE_API`,使用 `npm run dev` 本地联调后端接口(可通过代理或将 `VITE_APP_BASE_API` 指向后端地址)。
|
||||
- 修改数据库结构或 seed:请参考仓库根的 SQL 初始化脚本,任何 DDL/数据变更需同步该脚本并通知数据库管理员/运维。
|
||||
|
||||
- **举例(常见任务示例)**:
|
||||
- 本地联调前端 + 后端(PowerShell):
|
||||
|
||||
```powershell
|
||||
# 启动后端
|
||||
cd openhis-server-new/openhis-application
|
||||
mvn spring-boot:run
|
||||
|
||||
# 启动前端(另开终端)
|
||||
cd openhis-ui-vue3
|
||||
npm run dev
|
||||
```
|
||||
|
||||
如需我把这些内容合并为更短或更详细的版本,或把其中某部分(例如后端模块依赖关系图、关键 Java 包说明)展开,请告诉我要增强哪一节。
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -57,4 +57,9 @@
|
||||
# 忽略设计书
|
||||
PostgreSQL/openHis_DB设计书.xlsx
|
||||
|
||||
public.sql
|
||||
public.sql
|
||||
发版记录/2025-11-12/~$发版日志.docx
|
||||
发版记录/2025-11-12/~$S-管理系统-调价管理.docx
|
||||
发版记录/2025-11-12/发版日志.docx
|
||||
.gitignore
|
||||
openhis-server-new/openhis-application/src/main/resources/application-dev.yml
|
||||
|
||||
26
.trae/documents/plan_20251231_062502.md
Normal file
26
.trae/documents/plan_20251231_062502.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# 修复门诊预约界面专家号查询结果显示问题
|
||||
|
||||
## 问题分析
|
||||
1. 前端传递的参数正确:`type=expert`,后端正确转换为`ticketType=专家`
|
||||
2. 实际查询返回了5条记录,但COUNT查询只返回了1条记录
|
||||
3. 这导致前端只显示了1条记录,而不是全部5条
|
||||
4. 原因:MyBatis-Plus自动生成的COUNT查询和实际查询使用了不同的条件,特别是逻辑删除条件
|
||||
|
||||
## 解决方案
|
||||
1. 修改TicketMapper.xml中的自定义COUNT查询,显式添加`delete_flag = '0'`条件
|
||||
2. 在selectTicketPage和selectTicketPage_mpCount查询中都添加逻辑删除条件
|
||||
3. 确保两个查询使用完全相同的WHERE条件
|
||||
|
||||
## 修复步骤
|
||||
1. 修改`selectTicketPage`查询,添加逻辑删除条件`and delete_flag = '0'`
|
||||
2. 修改`selectTicketPage_mpCount`查询,添加逻辑删除条件`and delete_flag = '0'`
|
||||
3. 确保两个查询的WHERE条件完全一致
|
||||
4. 测试修复后的功能,确保专家号能正确显示全部5条记录
|
||||
|
||||
## 代码修改点
|
||||
- 文件:`d:/work/openhis-server-new/openhis-domain/src/main/resources/mapper/clinical/TicketMapper.xml`
|
||||
- 查询:`selectTicketPage` 和 `selectTicketPage_mpCount`
|
||||
- 修改内容:添加逻辑删除条件`and delete_flag = '0'`
|
||||
|
||||
## 预期效果
|
||||
修复后,COUNT查询和实际查询将使用完全相同的条件,包括逻辑删除条件,从而确保COUNT查询返回正确的总记录数,前端能显示所有5条专家号记录。
|
||||
30
.trae/documents/plan_20251231_063300.md
Normal file
30
.trae/documents/plan_20251231_063300.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# 修复门诊预约界面专家号查询COUNT结果不正确问题
|
||||
|
||||
## 问题分析
|
||||
1. 前端传递的参数正确:`type=expert`,后端正确转换为`ticketType=专家`
|
||||
2. COUNT查询和实际查询的WHERE条件完全相同:`WHERE delete_flag = '0' AND ticket_type = '专家'`
|
||||
3. 但COUNT查询只返回1条记录,而实际查询返回5条记录
|
||||
4. 原因:MyBatis-Plus的分页插件在处理自定义COUNT查询时,存在bug,导致COUNT查询结果不正确
|
||||
|
||||
## 解决方案
|
||||
修改`TicketAppServiceImpl.java`中的`listTicket`方法,不使用MyBatis-Plus的自动分页功能,而是手动实现分页查询:
|
||||
1. 直接调用`ticketService.countTickets`方法获取总记录数
|
||||
2. 手动构建查询条件
|
||||
3. 确保COUNT查询和实际查询使用完全相同的条件
|
||||
|
||||
## 修复步骤
|
||||
1. 修改`TicketAppServiceImpl.java`中的`listTicket`方法
|
||||
2. 手动实现分页查询,包括:
|
||||
- 构建查询条件
|
||||
- 调用`countTickets`获取总记录数
|
||||
- 调用`selectTicketList`获取分页数据
|
||||
- 手动组装分页结果
|
||||
3. 测试修复后的功能,确保专家号能正确显示全部5条记录
|
||||
|
||||
## 代码修改点
|
||||
- 文件:`d:/work/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointmentmanage/appservice/impl/TicketAppServiceImpl.java`
|
||||
- 方法:`listTicket`
|
||||
- 修改内容:替换MyBatis-Plus的自动分页,改为手动分页实现
|
||||
|
||||
## 预期效果
|
||||
修复后,COUNT查询和实际查询将使用完全相同的条件,COUNT查询将返回正确的总记录数(5条),前端能显示所有5条专家号记录。
|
||||
32
.trae/documents/修复号源列表显示问题.md
Normal file
32
.trae/documents/修复号源列表显示问题.md
Normal file
@@ -0,0 +1,32 @@
|
||||
## 问题分析
|
||||
根据日志和代码分析,发现号源列表显示"没有更多数据了"的问题原因:
|
||||
|
||||
1. **后端查询正常**:成功查询到5条符合条件的专家号源记录
|
||||
2. **数据转换失败**:在`convertToDto`方法中,`fee`字段类型转换错误
|
||||
3. **响应返回空列表**:由于转换异常,最终返回给前端的号源列表为空
|
||||
|
||||
## 问题根源
|
||||
- `Ticket`实体类的`fee`字段为**BigDecimal类型**(数据库存储)
|
||||
- `TicketDto`类的`fee`字段为**String类型**(前端展示)
|
||||
- 在`convertToDto`方法中,直接将BigDecimal类型的`fee`赋值给String类型的`fee`,导致**ClassCastException**
|
||||
|
||||
## 修复方案
|
||||
修改`TicketAppServiceImpl.java`文件中的`convertToDto`方法,将BigDecimal类型的`fee`转换为String类型:
|
||||
|
||||
```java
|
||||
// 原代码
|
||||
dto.setFee(ticket.getFee());
|
||||
|
||||
// 修复后代码
|
||||
dto.setFee(ticket.getFee().toString());
|
||||
```
|
||||
|
||||
## 预期效果
|
||||
1. 修复后,后端能成功将`Ticket`实体转换为`TicketDto`
|
||||
2. 前端能接收到包含5条专家号源的完整列表
|
||||
3. 页面显示正常,不再出现"没有更多数据了"的提示
|
||||
|
||||
## 验证方法
|
||||
1. 重新启动项目,访问号源管理页面
|
||||
2. 选择"专家号"类型,查看是否能正确显示5条号源记录
|
||||
3. 检查日志,确认没有类型转换异常
|
||||
23
.trae/documents/修复门诊预约界面专家号查询问题.md
Normal file
23
.trae/documents/修复门诊预约界面专家号查询问题.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# 修复门诊预约界面专家号查询问题
|
||||
|
||||
## 问题分析
|
||||
从日志中发现关键问题:
|
||||
- 前端传递的ticket_type值是英文:`general` (普通号) 和 `expert` (专家号)
|
||||
- 数据库中存储的ticket_type值是中文:`普通` 和 `专家`
|
||||
- 导致查询条件不匹配,无法查询到数据
|
||||
|
||||
## 解决方案
|
||||
需要在后端添加类型映射转换,将前端传递的英文类型转换为数据库中存储的中文类型。
|
||||
|
||||
## 修复步骤
|
||||
1. 修改 `TicketAppServiceImpl.java` 文件,在处理type参数时添加映射转换逻辑
|
||||
2. 添加从英文类型到中文类型的映射关系
|
||||
3. 测试修复后的功能,确保普通号和专家号都能正确查询
|
||||
|
||||
## 代码修改点
|
||||
- 文件:`d:/work/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointmentmanage/appservice/impl/TicketAppServiceImpl.java`
|
||||
- 方法:`listTicket` 中的type参数处理部分
|
||||
- 修改内容:添加类型映射转换,将 "general" 转换为 "普通","expert" 转换为 "专家"
|
||||
|
||||
## 预期效果
|
||||
修复后,前端选择"普通号"或"专家号"时,系统能正确查询到对应的号源数据,不再出现"没有更多数据了"的提示。
|
||||
23
.trae/documents/修复门诊预约界面只显示1条数据的问题.md
Normal file
23
.trae/documents/修复门诊预约界面只显示1条数据的问题.md
Normal file
@@ -0,0 +1,23 @@
|
||||
**问题分析**:
|
||||
后端返回的响应格式是`{code: 200, msg: "操作成功", data: {total: 5, limit: 20, page: 1, list: [5条记录]}}`,而前端可能期望直接访问`list`属性,导致只能显示1条数据。
|
||||
|
||||
**修复方案**:
|
||||
|
||||
1. 修改`TicketAppServiceImpl.java`的`listTicket`方法,确保返回的分页数据格式正确
|
||||
2. 调整响应结构,使其更符合前端期望
|
||||
3. 保持与现有代码的兼容性
|
||||
|
||||
**修改点**:
|
||||
|
||||
* `TicketAppServiceImpl.java`:优化`listTicket`方法的响应格式
|
||||
|
||||
* 确保分页信息和列表数据都能正确返回给前端
|
||||
|
||||
**预期效果**:
|
||||
|
||||
* 后端返回正确格式的响应数据
|
||||
|
||||
* 前端能够正确显示所有5条专家号数据
|
||||
|
||||
* 保持与现有代码的兼容性
|
||||
|
||||
0
.trae/rules/project_rules.md
Normal file
0
.trae/rules/project_rules.md
Normal file
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
|
||||
68
README.md
68
README.md
@@ -1,68 +0,0 @@
|
||||
# 平台介绍
|
||||
|
||||
## 🏠【关于我们】
|
||||
|
||||

|
||||
|
||||
天天开源致⼒于打造中国应⽤管理软件开源⽣态,⾯向医疗、企业、教育三⼤⾏业信息化需求,提供优质的开源软件产品与解决⽅案。平台现已发布OpenHIS、OpenCOM、OpenEDU系列开源产品,并持续招募⽣态合作伙伴,期待共同构建开源创新的⾏业协作模式,加速⾏业的数字化进程。
|
||||
|
||||
天天开源的前⾝是新致开源,最早于2022年6⽉发布开源医疗软件平台OpenHIS.org.cn,于2023年6⽉发布开源企业软件平台OpenCOM.com.cn。2025年7⽉,新致开源品牌更新为天天开源,我们始终秉持开源、专业、协作的理念,致⼒于为医疗、教育、中⼩企业等⾏业提供优质的开源解决⽅案。
|
||||
|
||||
了解我们:https://open.tntlinking.com/about?site=gitee
|
||||
|
||||
## 💾【部署包下载】
|
||||
|
||||
请访问官网产品中心下载部署包:https://open.tntlinking.com/resource/productCenter?site=gitee
|
||||
|
||||
## 📚【支持文档】
|
||||
|
||||
技术支持资源:https://open.tntlinking.com/resource/technicalSupport?site=gitee
|
||||
(含演示环境、操作手册、部署手册、开发手册、常见问题等)
|
||||
|
||||
产品介绍:https://open.tntlinking.com/resource/industryKnowledge?site=gitee
|
||||
|
||||
操作教程:https://open.tntlinking.com/resource/operationTutorial?site=gitee
|
||||
|
||||
沙龙回顾:https://open.tntlinking.com/resource/openSourceSalon#23?site=gitee
|
||||
|
||||
## 🤝【合作方式】
|
||||
|
||||
产品服务价格:https://open.tntlinking.com/cost?site=gitee
|
||||
|
||||
加入生态伙伴:https://open.tntlinking.com/ecology/becomePartner?site=gitee
|
||||
|
||||
## 🤗【技术社区】
|
||||
|
||||
请访问官网扫码加入技术社区交流:https://open.tntlinking.com/ecology/joinCommunity?site=gitee
|
||||
|
||||
请关注公众号【天天开源软件】以便获得最新产品更新信息。
|
||||
|
||||
|
||||
|
||||
# 项目介绍
|
||||
|
||||
OpenHIS医院系统(信创版)集十大核心模块于一体,涵盖目录管理、基础数据配置、个性化设置、门诊/住院全流程管理、药房药库智能管控、精细化耗材管理、财务核算体系、医保合规对接及多维报表分析等功能模块,共计372项标准化功能。
|
||||
|
||||
系统深度适配民营及公立一二级医院业务场景,支持单体医院、集团化运营及区域医疗协同等多种部署模式,并通过国家信创认证体系,确保全栈技术自主可控。如有项目需求,可联系官方平台合作。
|
||||
|
||||
|
||||
|
||||
## 运行环境
|
||||
|
||||
jdk17 (必须)
|
||||
node.js-v16.15 (推荐)
|
||||
PostgreSQL-v16.2 (必须)
|
||||
redis (常用稳定版本即可)
|
||||
|
||||
## 开发提示
|
||||
|
||||
需要修改数据库和redis的连接信息,详见:
|
||||
application.yml
|
||||
application-druid.yml
|
||||
|
||||
## 目录解释
|
||||
|
||||
前端: openhis-ui-vue3
|
||||
后端: openhis-server
|
||||
启动类: OpenHisApplication
|
||||
|
||||
179
md/中医诊断主诊断功能实现说明.md
Normal file
179
md/中医诊断主诊断功能实现说明.md
Normal file
@@ -0,0 +1,179 @@
|
||||
# 中医诊断主诊断功能实现说明
|
||||
|
||||
## 问题描述
|
||||
中医诊断在添加时无法设置主诊断标记,导致保存后无法正确标识主诊断。
|
||||
|
||||
## 问题原因
|
||||
在 `addDiagnosisDialog.vue` 中保存中医诊断时,没有传递 `maindiseFlag`(主诊断标记)字段到后端。
|
||||
|
||||
## 解决方案
|
||||
|
||||
### 1. 前端修改
|
||||
|
||||
#### 1.1 添加主诊断UI(addDiagnosisDialog.vue)
|
||||
在诊断详情区域为每个中医诊断添加了主诊断复选框:
|
||||
|
||||
```vue
|
||||
<el-checkbox
|
||||
v-model="item.isMain"
|
||||
label="主诊断"
|
||||
:true-label="true"
|
||||
:false-label="false"
|
||||
border
|
||||
size="small"
|
||||
style="margin-right: 10px;"
|
||||
@change="(value) => handleMaindise(value, index)"
|
||||
/>
|
||||
```
|
||||
|
||||
#### 1.2 添加主诊断逻辑处理
|
||||
|
||||
**新增诊断时的默认行为:**
|
||||
- 第一个添加的中医诊断自动设置为主诊断
|
||||
- 后续添加的诊断默认不是主诊断
|
||||
|
||||
**主诊断唯一性校验:**
|
||||
```javascript
|
||||
function handleMaindise(value, index) {
|
||||
if (value) {
|
||||
// 检查是否已有其他主诊断
|
||||
let mainCount = 0;
|
||||
tcmDiagonsisList.value.forEach((item, idx) => {
|
||||
if (item.isMain && idx !== index) {
|
||||
mainCount++;
|
||||
}
|
||||
});
|
||||
|
||||
if (mainCount > 0) {
|
||||
// 取消当前选择
|
||||
tcmDiagonsisList.value[index].isMain = false;
|
||||
proxy.$modal.msgWarning('只能有一条主诊断');
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新保存列表中的主诊断标记
|
||||
const syndromeGroupNo = tcmDiagonsisList.value[index].syndromeGroupNo;
|
||||
tcmDiagonsisSaveList.value.forEach((item, idx) => {
|
||||
if (item.syndromeGroupNo === syndromeGroupNo) {
|
||||
// 每个证候组有两条记录(病和证),只有第一条(病)设置主诊断标记
|
||||
if (idx % 2 === 0 || tcmDiagonsisSaveList.value[idx - 1]?.syndromeGroupNo !== syndromeGroupNo) {
|
||||
item.maindiseFlag = 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 取消主诊断
|
||||
const syndromeGroupNo = tcmDiagonsisList.value[index].syndromeGroupNo;
|
||||
tcmDiagonsisSaveList.value.forEach((item) => {
|
||||
if (item.syndromeGroupNo === syndromeGroupNo) {
|
||||
item.maindiseFlag = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.3 保存时包含主诊断字段
|
||||
|
||||
**新增诊断时:**
|
||||
```javascript
|
||||
tcmDiagonsisSaveList.value.push({
|
||||
definitionId: row.id,
|
||||
ybNo: row.ybNo,
|
||||
syndromeGroupNo: timestamp.value,
|
||||
verificationStatusEnum: 4,
|
||||
medTypeCode: '11',
|
||||
maindiseFlag: isFirstDiagnosis ? 1 : 0, // 添加主诊断标记
|
||||
});
|
||||
```
|
||||
|
||||
**修改诊断时:**
|
||||
```javascript
|
||||
tcmDiagonsisSaveList.value.push({
|
||||
conditionId: item.conditionId,
|
||||
updateId: updateIds[0],
|
||||
definitionId: item.illnessDefinitionId,
|
||||
ybNo: item.ybNo,
|
||||
syndromeGroupNo: item.syndromeGroupNo,
|
||||
verificationStatusEnum: 4,
|
||||
medTypeCode: '11',
|
||||
diagSrtNo: item.diagSrtNo,
|
||||
maindiseFlag: isMain ? 1 : 0, // 保留原有的主诊断标记
|
||||
});
|
||||
```
|
||||
|
||||
#### 1.4 诊断列表显示(diagnosis.vue)
|
||||
|
||||
在获取中医诊断列表时,正确读取并显示主诊断标记:
|
||||
|
||||
```javascript
|
||||
form.value.diagnosisList.push({
|
||||
name: item.name + '-' + res.data.symptom[index].name,
|
||||
diagSrtNo: item.diagSrtNo,
|
||||
ybNo: item.ybNo,
|
||||
medTypeCode: item.medTypeCode,
|
||||
syndromeGroupNo: item.syndromeGroupNo,
|
||||
typeName: '中医诊断',
|
||||
conditionId: item.conditionId,
|
||||
symptomConditionId: res.data.symptom[index].conditionId,
|
||||
updateId: item.encounterDiagnosisId + '-' + res.data.symptom[index].encounterDiagnosisId,
|
||||
illnessDefinitionId: item.definitionId,
|
||||
symptomDefinitionId: res.data.symptom[index].definitionId,
|
||||
symptomYbNo: res.data.symptom[index].ybNo,
|
||||
maindiseFlag: item.maindiseFlag || 0, // 添加主诊断标记
|
||||
});
|
||||
```
|
||||
|
||||
### 2. 后端支持
|
||||
|
||||
后端已经支持 `maindiseFlag` 字段的保存和读取:
|
||||
|
||||
**SaveDiagnosisChildParam.java:**
|
||||
```java
|
||||
/**
|
||||
* 主诊断标记 (1:是,0:否)
|
||||
*/
|
||||
private Integer maindiseFlag;
|
||||
```
|
||||
|
||||
**DoctorStationChineseMedicalAppServiceImpl.java:**
|
||||
```java
|
||||
encounterDiagnosis.setMaindiseFlag(saveDiagnosisChildParam.getMaindiseFlag());
|
||||
```
|
||||
|
||||
## 业务规则
|
||||
|
||||
1. **主诊断标记位置**:主诊断标记在"病"上(每个病-证组合的第一条记录)
|
||||
2. **主诊断唯一性**:中医诊断只能有一个主诊断
|
||||
3. **与西医诊断的关系**:中医诊断和西医诊断可以各有一个主诊断(互不冲突)
|
||||
4. **默认行为**:第一个添加的中医诊断自动设置为主诊断
|
||||
|
||||
## 修改文件清单
|
||||
|
||||
1. `openhis-ui-vue3/src/views/doctorstation/components/diagnosis/addDiagnosisDialog.vue`
|
||||
- 添加主诊断复选框UI
|
||||
- 添加主诊断逻辑处理函数
|
||||
- 修改保存数据时包含 maindiseFlag 字段
|
||||
|
||||
2. `openhis-ui-vue3/src/views/doctorstation/components/diagnosis/diagnosis.vue`
|
||||
- 修改获取中医诊断列表时读取 maindiseFlag 字段
|
||||
- 修改传递给对话框的数据包含 maindiseFlag 字段
|
||||
|
||||
## 测试要点
|
||||
|
||||
1. ✅ 新增中医诊断时,第一个诊断自动设置为主诊断
|
||||
2. ✅ 可以手动勾选/取消主诊断复选框
|
||||
3. ✅ 只能有一个主诊断(尝试勾选第二个时会提示错误)
|
||||
4. ✅ 保存后主诊断标记正确保存到数据库
|
||||
5. ✅ 刷新页面后主诊断标记正确显示
|
||||
6. ✅ 修改已有诊断时,主诊断标记正确回显
|
||||
7. ✅ 中医诊断和西医诊断的主诊断互不影响
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 中医诊断是"病-证"成对出现的,主诊断标记只设置在"病"上
|
||||
2. 证候记录的 maindiseFlag 始终为 0
|
||||
3. 主诊断唯一性校验只在中医诊断内部进行,不影响西医诊断
|
||||
|
||||
## 完成时间
|
||||
2026年1月9日
|
||||
178
md/公告通知弹窗功能说明.md
Normal file
178
md/公告通知弹窗功能说明.md
Normal file
@@ -0,0 +1,178 @@
|
||||
# 公告通知弹窗功能说明
|
||||
|
||||
## 功能概述
|
||||
用户登录后,系统会自动弹出公告通知窗口,显示未读的系统公告和通知。
|
||||
|
||||
## 功能特性
|
||||
|
||||
### 1. 自动弹出
|
||||
- 登录后 1 秒自动加载公告列表
|
||||
- 如果有未读公告,自动弹出弹窗显示
|
||||
- 延迟加载避免影响页面初始渲染
|
||||
|
||||
### 2. 优先级显示
|
||||
- **高优先级**(1):红色背景 `#fff1f0`,红色文字 `#ff4d4f`
|
||||
- **中优先级**(2):橙色背景 `#fff7e6`,橙色文字 `#faad14`
|
||||
- **低优先级**(3):灰色背景 `#f0f2f5`,灰色文字 `#909399`
|
||||
|
||||
### 3. 排序规则
|
||||
- 按优先级升序排列(高 -> 中 -> 低)
|
||||
- 相同优先级按创建时间降序排列
|
||||
|
||||
### 4. 已读状态
|
||||
- 未读公告:黄色背景高亮显示
|
||||
- 已读公告:默认白色背景
|
||||
- 点击公告自动标记为已读
|
||||
|
||||
### 5. 分类显示
|
||||
- **通知**(1):蓝色图标
|
||||
- **紧急**(2):红色警告图标
|
||||
- **信息**(3):绿色信息图标
|
||||
- **成功**(4):紫色成功图标
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
src/
|
||||
├── components/
|
||||
│ ├── NoticePopup/
|
||||
│ │ └── index.vue # 登录后自动弹窗组件
|
||||
│ └── NoticePanel/
|
||||
│ └── index.vue # 手动打开的公告面板
|
||||
├── layout/
|
||||
│ └── index.vue # 主布局,引入 NoticePopup
|
||||
└── views/
|
||||
└── system/
|
||||
└── notice/
|
||||
└── index.vue # 公告管理页面
|
||||
```
|
||||
|
||||
## API 接口
|
||||
|
||||
### 前端 API
|
||||
```javascript
|
||||
// 获取用户公告列表
|
||||
getUserNotices()
|
||||
|
||||
// 标记为已读
|
||||
markAsRead(noticeId)
|
||||
|
||||
// 全部标记为已读
|
||||
markAllAsRead(noticeIds)
|
||||
|
||||
// 获取未读数量
|
||||
getUnreadCount()
|
||||
```
|
||||
|
||||
### 后端接口
|
||||
```java
|
||||
// GET /system/notice/public/notice
|
||||
// 获取当前用户的公告列表(含已读状态)
|
||||
|
||||
// GET /system/notice/public/unread/count
|
||||
// 获取未读公告数量
|
||||
|
||||
// POST /system/notice/public/read/{noticeId}
|
||||
// 标记公告为已读
|
||||
|
||||
// POST /system/notice/public/read/all
|
||||
// 批量标记为已读
|
||||
```
|
||||
|
||||
## 数据库字段
|
||||
|
||||
### sys_notice 表新增字段
|
||||
```sql
|
||||
-- 优先级字段
|
||||
priority VARCHAR(1) DEFAULT '3'
|
||||
|
||||
-- 发布状态字段
|
||||
publish_status VARCHAR(1) DEFAULT '0'
|
||||
```
|
||||
|
||||
## 使用说明
|
||||
|
||||
### 1. 数据库迁移
|
||||
执行 SQL 脚本添加必要的字段:
|
||||
```bash
|
||||
# 添加优先级字段
|
||||
ALTER TABLE sys_notice ADD COLUMN priority VARCHAR(1) DEFAULT '3';
|
||||
|
||||
# 添加发布状态字段
|
||||
ALTER TABLE sys_notice ADD COLUMN publish_status VARCHAR(1) DEFAULT '0';
|
||||
```
|
||||
|
||||
### 2. 后台管理
|
||||
在 `系统管理 > 公告管理` 中:
|
||||
1. 点击"新增"创建公告
|
||||
2. 选择优先级:高/中/低
|
||||
3. 选择公告类型:通知/紧急/信息/成功
|
||||
4. 填写标题和内容
|
||||
5. 点击"发布"按钮
|
||||
|
||||
### 3. 用户端显示
|
||||
- 登录后自动弹出未读公告
|
||||
- 点击顶部导航栏铃铛图标可手动打开
|
||||
- 点击公告查看详情
|
||||
- 支持全部标记为已读
|
||||
|
||||
## 样式说明
|
||||
|
||||
### 弹窗样式
|
||||
- 宽度:800px
|
||||
- 高度:最大 600px
|
||||
- 标题栏:渐变紫色背景 `linear-gradient(135deg, #667eea 0%, #764ba2 100%)`
|
||||
- 左右分栏布局
|
||||
|
||||
### 列表样式
|
||||
- 列表宽度:380px
|
||||
- 滚动区域:最大高度 500px
|
||||
- 未读高亮:黄色背景 `#fffbe6`
|
||||
- 激活项:蓝色左边框 `#1890ff`
|
||||
|
||||
### 详情样式
|
||||
- 自适应宽度
|
||||
- 标题字号:18px
|
||||
- 内容字号:14px
|
||||
- 行高:1.8
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **权限控制**
|
||||
- 只有已发布的公告才会显示
|
||||
- 只有正常状态的公告才会显示
|
||||
|
||||
2. **性能优化**
|
||||
- 使用延迟加载(1秒)
|
||||
- 使用虚拟滚动(el-scrollbar)
|
||||
- 按需加载详情
|
||||
|
||||
3. **用户体验**
|
||||
- 支持点击空白处关闭
|
||||
- 支持ESC键关闭
|
||||
- 未读状态醒目标识
|
||||
- 优先级颜色区分明显
|
||||
|
||||
## 故障排查
|
||||
|
||||
### 弹窗不显示
|
||||
1. 检查后端接口 `/system/notice/public/notice` 是否正常返回
|
||||
2. 检查是否有未读公告
|
||||
3. 检查浏览器控制台是否有错误
|
||||
4. 清除浏览器缓存重试
|
||||
|
||||
### 样式错乱
|
||||
1. 检查 Element Plus 版本是否兼容
|
||||
2. 检查样式是否被其他 CSS 覆盖
|
||||
3. 使用浏览器开发者工具检查样式
|
||||
|
||||
### 数据不更新
|
||||
1. 检查后端返回的数据格式
|
||||
2. 检查 API 调用是否成功
|
||||
3. 检查响应拦截器处理
|
||||
|
||||
## 版本信息
|
||||
- 创建日期:2025-12-30
|
||||
- 功能版本:v1.0
|
||||
- 前端框架:Vue 3 + Element Plus
|
||||
- 后端框架:Spring Boot + MyBatis Plus
|
||||
332
md/前端UI规范文档.md
Normal file
332
md/前端UI规范文档.md
Normal file
@@ -0,0 +1,332 @@
|
||||
# OpenHIS UI 风格规范文档
|
||||
|
||||
## 1. 整体布局
|
||||
|
||||
### 1.1 容器结构
|
||||
```
|
||||
<div class="app-container [page-name]-container">
|
||||
<div class="components-container">
|
||||
<!-- 查询表单 -->
|
||||
<el-form class="query-form">...</el-form>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row class="button-group">...</el-row>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<el-table border>...</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-container">...</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
### 1.2 样式说明
|
||||
- `app-container`: 最外层容器,全屏背景
|
||||
- `components-container`: 白色卡片容器,带阴影
|
||||
- `query-form`: 查询表单,底部无间距
|
||||
- `button-group`: 按钮组,间距 8px
|
||||
- `pagination-container`: 分页容器,顶部间距 16px
|
||||
|
||||
## 2. 统一样式规范
|
||||
|
||||
### 2.1 颜色规范
|
||||
```scss
|
||||
// 主色调
|
||||
--color-primary: #409EFF;
|
||||
--color-success: #67C23A;
|
||||
--color-warning: #E6A23C;
|
||||
--color-danger: #F56C6C;
|
||||
--color-info: #909399;
|
||||
|
||||
// 文字颜色
|
||||
--text-regular: #606266; // 常规文字
|
||||
--text-secondary: #909399; // 次要文字
|
||||
--text-placeholder: #A8ABB2; // 占位符
|
||||
```
|
||||
|
||||
### 2.2 间距规范
|
||||
```scss
|
||||
// 容器内边距
|
||||
$spacing-xs: 4px;
|
||||
$spacing-sm: 8px;
|
||||
$spacing-md: 16px;
|
||||
$spacing-lg: 20px;
|
||||
$spacing-xl: 24px;
|
||||
|
||||
// 表单项间距
|
||||
$form-item-margin-bottom: 18px;
|
||||
```
|
||||
|
||||
### 2.3 圆角规范
|
||||
```scss
|
||||
$border-radius-sm: 4px; // 小圆角 - 按钮、输入框
|
||||
$border-radius-md: 8px; // 中圆角 - 卡片、对话框
|
||||
$border-radius-lg: 12px; // 大圆角 - 特殊组件
|
||||
```
|
||||
|
||||
### 2.4 阴影规范
|
||||
```scss
|
||||
// 卡片阴影
|
||||
$box-shadow-card: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
|
||||
// 表格阴影
|
||||
$box-shadow-table: 0 1px 4px rgba(0, 0, 0, 0.05);
|
||||
|
||||
// 浮动元素阴影
|
||||
$box-shadow-float: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
```
|
||||
|
||||
### 2.5 字体规范
|
||||
```scss
|
||||
$font-size-base: 14px; // 基础字号
|
||||
$font-size-sm: 12px; // 小字号
|
||||
$font-size-lg: 16px; // 大字号
|
||||
$font-size-xl: 18px; // 特大字号
|
||||
|
||||
$font-weight-regular: 400; // 常规
|
||||
$font-weight-medium: 500; // 中等
|
||||
$font-weight-bold: 600; // 加粗
|
||||
```
|
||||
|
||||
## 3. 组件规范
|
||||
|
||||
### 3.1 表单组件
|
||||
|
||||
#### 输入框
|
||||
```vue
|
||||
<el-input
|
||||
v-model="value"
|
||||
placeholder="请输入xxx"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
```
|
||||
|
||||
#### 下拉框
|
||||
```vue
|
||||
<el-select
|
||||
v-model="value"
|
||||
placeholder="请选择xxx"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in dictList"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
```
|
||||
|
||||
#### 按钮规范
|
||||
```vue
|
||||
<!-- 主按钮 -->
|
||||
<el-button type="primary" icon="IconName">按钮文字</el-button>
|
||||
|
||||
<!-- 次要按钮 -->
|
||||
<el-button type="success">按钮文字</el-button>
|
||||
<el-button type="warning">按钮文字</el-button>
|
||||
<el-button type="danger">按钮文字</el-button>
|
||||
|
||||
<!-- 次要按钮(plain) -->
|
||||
<el-button type="primary" plain icon="IconName">按钮文字</el-button>
|
||||
|
||||
<!-- 链接按钮(table内) -->
|
||||
<el-button link type="primary" class="action-button">文字</el-button>
|
||||
```
|
||||
|
||||
### 3.2 表格组件
|
||||
|
||||
```vue
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="tableData"
|
||||
@selection-change="handleSelectionChange"
|
||||
border
|
||||
>
|
||||
<!-- 复选列 -->
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
|
||||
<!-- 序号列 -->
|
||||
<el-table-column label="序号" align="center" prop="id" width="80" />
|
||||
|
||||
<!-- 普通列 -->
|
||||
<el-table-column
|
||||
label="列名"
|
||||
align="center"
|
||||
prop="fieldName"
|
||||
min-width="200"
|
||||
:show-overflow-tooltip="true"
|
||||
/>
|
||||
|
||||
<!-- 带标签列 -->
|
||||
<el-table-column label="状态" align="center" prop="status" width="90">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="dictType" :value="scope.row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 操作列 -->
|
||||
<el-table-column label="操作" align="center" min-width="280">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" @click="handleEdit(scope.row)" class="action-button">编辑</el-button>
|
||||
<el-button link type="danger" @click="handleDelete(scope.row)" class="action-button">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
```
|
||||
|
||||
### 3.3 对话框组件
|
||||
|
||||
```vue
|
||||
<el-dialog
|
||||
:title="dialogTitle"
|
||||
v-model="dialogVisible"
|
||||
width="800px"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form :model="form" :rules="rules" label-width="80px">
|
||||
<!-- 表单内容 -->
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="handleSubmit">确 定</el-button>
|
||||
<el-button @click="handleCancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
```
|
||||
|
||||
## 4. 响应式设计
|
||||
|
||||
### 4.1 断点规范
|
||||
```scss
|
||||
$screen-xs: 480px;
|
||||
$screen-sm: 768px;
|
||||
$screen-md: 992px;
|
||||
$screen-lg: 1200px;
|
||||
```
|
||||
|
||||
### 4.2 响应式规范
|
||||
```vue
|
||||
<!-- 栅格系统 -->
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="6" :xs="12" :sm="8">...</el-col>
|
||||
<el-col :span="18" :xs="12" :sm="16">...</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 移动端表单 -->
|
||||
<el-form :label-width="isMobile ? '80px' : '120px'">
|
||||
```
|
||||
|
||||
## 5. 交互规范
|
||||
|
||||
### 5.1 加载状态
|
||||
```vue
|
||||
<!-- 表格加载 -->
|
||||
<el-table v-loading="loading" :data="tableData">
|
||||
|
||||
<!-- 按钮加载 -->
|
||||
<el-button :loading="saving">保存</el-button>
|
||||
|
||||
<!-- 全屏加载 -->
|
||||
<el-button type="primary" :loading="true">提交</el-button>
|
||||
```
|
||||
|
||||
### 5.2 空状态
|
||||
```vue
|
||||
<el-empty
|
||||
description="暂无数据"
|
||||
:image="emptyImage"
|
||||
/>
|
||||
```
|
||||
|
||||
### 5.3 确认对话框
|
||||
```vue
|
||||
<el-dialog title="确认提示" v-model="confirmVisible">
|
||||
<p>{{ confirmMessage }}</p>
|
||||
<template #footer>
|
||||
<el-button @click="confirmVisible = false">取 消</el-button>
|
||||
<el-button type="danger" @click="handleConfirm">确 定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
```
|
||||
|
||||
## 6. 命名规范
|
||||
|
||||
### 6.1 CSS 类名
|
||||
- 使用 kebab-case(短横线命名)
|
||||
- 遵循 BEM 命名规范
|
||||
- 示例:`notice-container`, `button-group`, `action-button`
|
||||
|
||||
### 6.2 变量命名
|
||||
- Vue:使用 camelCase
|
||||
- 事件处理:以 `handle` 开头
|
||||
- 数据获取:以 `get`/`load` 开头
|
||||
- 示例:`handleQuery`, `loadData`, `handleSubmit`
|
||||
|
||||
### 6.3 组件命名
|
||||
- 使用 PascalCase
|
||||
- 多个单词时使用驼峰命名
|
||||
- 示例:`NoticePanel`, `TableHeader`, `SearchForm`
|
||||
|
||||
## 7. 国际化规范
|
||||
|
||||
```vue
|
||||
<!-- 使用字典标签 -->
|
||||
<dict-tag :options="dictType" :value="row.status" />
|
||||
|
||||
<!-- 使用占位符 -->
|
||||
<el-input :placeholder="$t('common.placeholder')"/>
|
||||
```
|
||||
|
||||
## 8. 性能优化
|
||||
|
||||
### 8.1 图片优化
|
||||
- 使用 WebP 格式
|
||||
- 图片懒加载
|
||||
- 响应式图片
|
||||
|
||||
### 8.2 列表优化
|
||||
- 虚拟滚动(大列表)
|
||||
- 分页加载
|
||||
- 骨架屏
|
||||
|
||||
### 8.3 缓存策略
|
||||
- 使用 Vuex/Pinia 缓存用户数据
|
||||
- 本地存储持久化配置
|
||||
- 请求去重
|
||||
|
||||
## 9. 无障碍规范
|
||||
|
||||
### 9.1 语义化标签
|
||||
```vue
|
||||
<nav> <!-- 导航 -->
|
||||
<main> <!-- 主内容 -->
|
||||
<header> <!-- 头部 -->
|
||||
<footer> <!-- 底部 -->
|
||||
```
|
||||
|
||||
### 9.2 ARIA 属性
|
||||
```vue
|
||||
<el-button aria-label="提交按钮">提交</el-button>
|
||||
<el-input aria-label="搜索框" />
|
||||
```
|
||||
|
||||
### 9.3 键盘导航
|
||||
- 支持键盘操作
|
||||
- Tab 键焦点管理
|
||||
- 快捷键支持
|
||||
|
||||
---
|
||||
|
||||
**注意事项:**
|
||||
1. 所有新增页面必须遵循此规范
|
||||
2. 修改现有页面时尽量统一样式
|
||||
3. 保持与系统整体风格一致
|
||||
4. 优先使用已有的组件和样式
|
||||
5. 遵循响应式设计原则
|
||||
254
md/手术人员字段不显示问题解决方案.md
Normal file
254
md/手术人员字段不显示问题解决方案.md
Normal file
@@ -0,0 +1,254 @@
|
||||
# 手术人员字段不显示问题解决方案
|
||||
|
||||
## 问题描述
|
||||
主刀医生、麻醉医生、助手1、助手2、执行科这些字段在手术查看页面中没有显示数据。
|
||||
|
||||
## 问题原因
|
||||
这些字段在数据库中可能为 **null 或空值**,虽然保存了 ID(如 `main_surgeon_id`),但没有保存对应的姓名(如 `main_surgeon_name`)。
|
||||
|
||||
## 解决步骤
|
||||
|
||||
### 步骤 1:检查数据库中字段的实际值
|
||||
|
||||
执行以下 SQL 查看当前数据:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
id,
|
||||
surgery_no,
|
||||
main_surgeon_id,
|
||||
main_surgeon_name,
|
||||
anesthetist_id,
|
||||
anesthetist_name,
|
||||
assistant_1_id,
|
||||
assistant_1_name,
|
||||
assistant_2_id,
|
||||
assistant_2_name,
|
||||
operating_room_id,
|
||||
operating_room_name,
|
||||
org_id,
|
||||
org_name
|
||||
FROM public.cli_surgery
|
||||
WHERE delete_flag = '0'
|
||||
ORDER BY create_time DESC
|
||||
LIMIT 5;
|
||||
```
|
||||
|
||||
**请告诉我结果**:特别是 `main_surgeon_name`、`anesthetist_name`、`assistant_1_name`、`assistant_2_name`、`operating_room_name`、`org_name` 这些字段的值。
|
||||
|
||||
### 步骤 2:检查用户表结构
|
||||
|
||||
执行以下 SQL 查看用户表的结构:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
column_name,
|
||||
data_type
|
||||
FROM information_schema.columns
|
||||
WHERE table_name = 'sys_user'
|
||||
AND column_name IN ('user_id', 'nick_name', 'user_name', 'practitioner_id')
|
||||
ORDER BY column_name;
|
||||
```
|
||||
|
||||
**目的**:确定人员ID和姓名的对应关系。
|
||||
|
||||
### 步骤 3:填充人员姓名字段(推荐方法)
|
||||
|
||||
使用以下 SQL 脚本填充人员姓名:
|
||||
|
||||
```sql
|
||||
-- 填充主刀医生姓名
|
||||
UPDATE public.cli_surgery s
|
||||
SET main_surgeon_name = u.nick_name
|
||||
FROM public.sys_user u
|
||||
WHERE s.main_surgeon_id = u.user_id
|
||||
AND s.main_surgeon_name IS NULL
|
||||
AND s.delete_flag = '0';
|
||||
|
||||
-- 填充麻醉医生姓名
|
||||
UPDATE public.cli_surgery s
|
||||
SET anesthetist_name = u.nick_name
|
||||
FROM public.sys_user u
|
||||
WHERE s.anesthetist_id = u.user_id
|
||||
AND s.anesthetist_name IS NULL
|
||||
AND s.delete_flag = '0';
|
||||
|
||||
-- 填充助手1姓名
|
||||
UPDATE public.cli_surgery s
|
||||
SET assistant_1_name = u.nick_name
|
||||
FROM public.sys_user u
|
||||
WHERE s.assistant_1_id = u.user_id
|
||||
AND s.assistant_1_name IS NULL
|
||||
AND s.delete_flag = '0';
|
||||
|
||||
-- 填充助手2姓名
|
||||
UPDATE public.cli_surgery s
|
||||
SET assistant_2_name = u.nick_name
|
||||
FROM public.sys_user u
|
||||
WHERE s.assistant_2_id = u.user_id
|
||||
AND s.assistant_2_name IS NULL
|
||||
AND s.delete_flag = '0';
|
||||
|
||||
-- 填充手术室名称
|
||||
UPDATE public.cli_surgery s
|
||||
SET operating_room_name = r.name
|
||||
FROM public.cli_operating_room r
|
||||
WHERE s.operating_room_id = r.id
|
||||
AND s.operating_room_name IS NULL
|
||||
AND s.delete_flag = '0';
|
||||
|
||||
-- 填充执行科室名称
|
||||
UPDATE public.cli_surgery s
|
||||
SET org_name = o.name
|
||||
FROM public.adm_organization o
|
||||
WHERE s.org_id = o.id
|
||||
AND s.org_name IS NULL
|
||||
AND s.delete_flag = '0';
|
||||
```
|
||||
|
||||
### 步骤 4:验证更新结果
|
||||
|
||||
执行以下 SQL 验证是否更新成功:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
id,
|
||||
surgery_no,
|
||||
main_surgeon_id,
|
||||
main_surgeon_name,
|
||||
anesthetist_id,
|
||||
anesthetist_name,
|
||||
assistant_1_id,
|
||||
assistant_1_name,
|
||||
assistant_2_id,
|
||||
assistant_2_name,
|
||||
operating_room_id,
|
||||
operating_room_name,
|
||||
org_id,
|
||||
org_name
|
||||
FROM public.cli_surgery
|
||||
WHERE delete_flag = '0'
|
||||
ORDER BY create_time DESC
|
||||
LIMIT 5;
|
||||
```
|
||||
|
||||
**预期结果**:所有 `*_name` 字段都应该有值。
|
||||
|
||||
### 步骤 5:刷新前端页面
|
||||
|
||||
1. 刷新手术管理页面
|
||||
2. 点击某个手术记录的"查看"按钮
|
||||
3. 检查详情对话框中是否显示这些字段
|
||||
|
||||
## 前端代码检查
|
||||
|
||||
### 1. 检查详情对话框显示
|
||||
|
||||
打开 `surgerymanage/index.vue` 文件,查看详情对话框部分:
|
||||
|
||||
```vue
|
||||
<el-descriptions-item label="主刀医生">{{ viewData.mainSurgeonName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="麻醉医生">{{ viewData.anesthetistName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="助手1">{{ viewData.assistant1Name }}</el-descriptions-item>
|
||||
<el-descriptions-item label="助手2">{{ viewData.assistant2Name }}</el-descriptions-item>
|
||||
<el-descriptions-item label="手术室">{{ viewData.operatingRoomName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="执行科室">{{ viewData.orgName }}</el-descriptions-item>
|
||||
```
|
||||
|
||||
**确认**:这些字段名是否正确(注意驼峰命名)。
|
||||
|
||||
### 2. 检查浏览器控制台
|
||||
|
||||
1. 打开浏览器开发者工具(F12)
|
||||
2. 切换到 Console 标签
|
||||
3. 点击"查看"按钮
|
||||
4. 查看是否有 JavaScript 错误
|
||||
|
||||
### 3. 检查 Network 响应
|
||||
|
||||
1. 切换到 Network 标签
|
||||
2. 点击"查看"按钮
|
||||
3. 找到 `/clinical-manage/surgery/surgery-detail` 请求
|
||||
4. 查看响应内容
|
||||
|
||||
**检查**:响应数据中是否包含这些字段,值是什么。
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 问题 1:UPDATE SQL 执行失败
|
||||
|
||||
**症状**:报错 "relation does not exist" 或 "column does not exist"
|
||||
|
||||
**解决**:
|
||||
1. 检查表名是否正确(sys_user 或 adm_practitioner)
|
||||
2. 检查字段名是否正确(user_id 或 practitioner_id)
|
||||
|
||||
### 问题 2:UPDATE 后字段仍为 null
|
||||
|
||||
**症状**:UPDATE 执行成功,但字段仍为 null
|
||||
|
||||
**原因**:关联表中没有对应的记录
|
||||
|
||||
**解决**:检查人员ID是否存在于人员表中
|
||||
|
||||
```sql
|
||||
-- 检查主刀医生ID是否存在
|
||||
SELECT s.main_surgeon_id, u.nick_name
|
||||
FROM public.cli_surgery s
|
||||
LEFT JOIN public.sys_user u ON s.main_surgeon_id = u.user_id
|
||||
WHERE s.main_surgeon_id IS NOT NULL
|
||||
AND u.user_id IS NULL
|
||||
LIMIT 5;
|
||||
```
|
||||
|
||||
### 问题 3:前端仍然不显示
|
||||
|
||||
**症状**:数据库中有值,但前端不显示
|
||||
|
||||
**原因**:
|
||||
1. 前端字段名不匹配
|
||||
2. 前端数据绑定有问题
|
||||
|
||||
**解决**:
|
||||
1. 检查 MyBatis XML 映射是否正确
|
||||
2. 检查后端返回的 JSON 数据结构
|
||||
3. 检查前端变量名是否正确
|
||||
|
||||
## 后续改进建议
|
||||
|
||||
### 1. 保存时自动填充姓名
|
||||
|
||||
在前端或后端保存手术信息时,根据选择的医生ID自动查询并填充姓名字段。
|
||||
|
||||
### 2. 提供人员选择功能
|
||||
|
||||
在前端提供医生、科室等选择下拉框,而不是手动输入ID。
|
||||
|
||||
### 3. 添加数据完整性校验
|
||||
|
||||
在保存前检查:如果选择了人员ID,必须填充对应的姓名字段。
|
||||
|
||||
## 相关文件
|
||||
|
||||
1. **检查和填充脚本**:`e:/his/检查和填充手术人员字段.sql`
|
||||
2. **填充脚本**:`e:/his/填充手术人员字段姓名.sql`
|
||||
3. **MyBatis 映射**:`e:/his/openhis-server-new/openhis-application/src/main/resources/mapper/clinicalmanage/SurgeryMapper.xml`
|
||||
|
||||
## 验证清单
|
||||
|
||||
- [ ] 数据库查询显示字段为 null
|
||||
- [ ] 执行了填充 SQL 脚本
|
||||
- [ ] 验证更新后字段有值
|
||||
- [ ] 刷新前端页面
|
||||
- [ ] 详情对话框中正确显示
|
||||
|
||||
## 联系支持
|
||||
|
||||
如果以上步骤都无法解决问题,请提供:
|
||||
|
||||
1. **步骤 1 的查询结果**:当前数据库中这些字段的值
|
||||
2. **步骤 2 的查询结果**:sys_user 表的结构
|
||||
3. **UPDATE SQL 执行结果**:是否有错误,更新了多少条记录
|
||||
4. **步骤 4 的验证结果**:更新后的字段值
|
||||
5. **浏览器控制台错误**:是否有 JavaScript 错误
|
||||
6. **Network 响应数据**:后端返回的完整数据
|
||||
120
md/手术和麻醉信息Redis缓存实现说明.md
Normal file
120
md/手术和麻醉信息Redis缓存实现说明.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# 手术和麻醉信息Redis缓存实现说明
|
||||
|
||||
## 概述
|
||||
为提高手术和麻醉信息的查询性能,已将手术信息缓存到Redis中。接口查询时先从Redis缓存获取,如果没有则从数据库查询并更新到Redis缓存。
|
||||
|
||||
## 实现细节
|
||||
|
||||
### 1. Redis缓存Key定义
|
||||
在 `openhis-common/src/main/java/com/openhis/common/utils/RedisKeys.java` 中定义了以下缓存Key:
|
||||
|
||||
```java
|
||||
// 单个手术信息缓存
|
||||
public static String getSurgeryKey(Long surgeryId)
|
||||
|
||||
// 按患者ID查询的手术列表缓存
|
||||
public static String getSurgeryListByPatientKey(Long patientId)
|
||||
|
||||
// 按就诊ID查询的手术列表缓存
|
||||
public static String getSurgeryListByEncounterKey(Long encounterId)
|
||||
```
|
||||
|
||||
### 2. 缓存实现
|
||||
|
||||
#### 2.1 SurgeryServiceImpl (Domain层)
|
||||
- **getSurgeryById(Long id)**: 根据手术ID查询单个手术信息
|
||||
- 先从Redis缓存获取
|
||||
- 缓存未命中则从数据库查询
|
||||
- 查询结果存入Redis缓存(30分钟过期)
|
||||
|
||||
- **getSurgeryListByPatientId(Long patientId)**: 根据患者ID查询手术列表
|
||||
- 先从Redis缓存获取
|
||||
- 缓存未命中则从数据库查询
|
||||
- 查询结果存入Redis缓存(30分钟过期)
|
||||
|
||||
- **getSurgeryListByEncounterId(Long encounterId)**: 根据就诊ID查询手术列表
|
||||
- 先从Redis缓存获取
|
||||
- 缓存未命中则从数据库查询
|
||||
- 查询结果存入Redis缓存(30分钟过期)
|
||||
|
||||
- **insertSurgery(Surgery surgery)**: 新增手术信息
|
||||
- 插入成功后清除相关缓存
|
||||
|
||||
- **updateSurgery(Surgery surgery)**: 更新手术信息
|
||||
- 更新成功后清除相关缓存
|
||||
|
||||
- **deleteSurgery(Long id)**: 删除手术信息
|
||||
- 删除成功后清除相关缓存
|
||||
|
||||
- **updateSurgeryStatus(Long id, Integer statusEnum)**: 更新手术状态
|
||||
- 更新成功后清除相关缓存
|
||||
|
||||
#### 2.2 SurgeryAppServiceImpl (Application层)
|
||||
- **getSurgeryDetail(Long id)**: 根据ID查询手术详情
|
||||
- 先从Redis缓存获取
|
||||
- 缓存未命中则从数据库查询
|
||||
- 查询结果存入Redis缓存(30分钟过期)
|
||||
|
||||
- **addSurgery(SurgeryDto surgeryDto)**: 新增手术信息
|
||||
- 插入成功后清除相关缓存
|
||||
|
||||
- **updateSurgery(SurgeryDto surgeryDto)**: 更新手术信息
|
||||
- 更新成功后清除相关缓存
|
||||
|
||||
- **deleteSurgery(Long id)**: 删除手术信息
|
||||
- 删除成功后清除相关缓存
|
||||
|
||||
- **updateSurgeryStatus(Long id, Integer statusEnum)**: 更新手术状态
|
||||
- 更新成功后清除相关缓存
|
||||
|
||||
### 3. 缓存清除策略
|
||||
当手术信息发生变化时(新增、更新、删除),会清除以下相关缓存:
|
||||
1. 单个手术信息缓存
|
||||
2. 患者手术列表缓存
|
||||
3. 就诊手术列表缓存
|
||||
|
||||
### 4. 缓存配置
|
||||
- **缓存时间**: 30分钟
|
||||
- **时间单位**: TimeUnit.MINUTES
|
||||
- **序列化**: 使用RedisTemplate默认序列化方式
|
||||
|
||||
## 关于麻醉信息
|
||||
当前项目中,麻醉信息是手术表(`cli_surgery`)中的字段,包括:
|
||||
- 麻醉医生ID (anesthetistId)
|
||||
- 麻醉医生姓名 (anesthetistName)
|
||||
- 麻醉方式编码 (anesthesiaTypeEnum)
|
||||
- 麻醉费用 (anesthesiaFee)
|
||||
|
||||
这些字段已经包含在手术实体的缓存中,无需单独实现麻醉信息的缓存。
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 查询手术信息(自动使用缓存)
|
||||
```java
|
||||
// 自动从缓存获取,未命中则查询数据库
|
||||
Surgery surgery = surgeryService.getSurgeryById(surgeryId);
|
||||
```
|
||||
|
||||
### 更新手术信息(自动清除缓存)
|
||||
```java
|
||||
// 更新数据库,同时清除相关缓存
|
||||
surgeryService.updateSurgery(surgery);
|
||||
```
|
||||
|
||||
### 手动清除缓存(如需要)
|
||||
```java
|
||||
String cacheKey = RedisKeys.getSurgeryKey(surgeryId);
|
||||
redisCache.deleteObject(cacheKey);
|
||||
```
|
||||
|
||||
## 性能优化建议
|
||||
1. 对于频繁访问的手术信息,缓存命中率高,可显著提升查询性能
|
||||
2. 对于不常访问的手术信息,30分钟缓存时间可避免占用过多Redis内存
|
||||
3. 如需调整缓存时间,可修改代码中的 `30, TimeUnit.MINUTES` 参数
|
||||
4. 如需更精细的缓存控制,可考虑使用不同的缓存时间策略(如根据手术状态设置不同过期时间)
|
||||
|
||||
## 监控建议
|
||||
建议监控以下指标:
|
||||
- Redis缓存命中率
|
||||
- Redis内存使用情况
|
||||
- 查询响应时间对比(缓存命中 vs 缓存未命中)
|
||||
256
md/手术室管理添加类型和所属科室字段说明.md
Normal file
256
md/手术室管理添加类型和所属科室字段说明.md
Normal file
@@ -0,0 +1,256 @@
|
||||
# 手术室管理添加类型和所属科室字段功能说明
|
||||
|
||||
## 概述
|
||||
|
||||
本次更新为手术室管理模块添加了"类型"和"所属科室"字段,优化了手术室信息的分类管理。
|
||||
|
||||
**数据库类型**:PostgreSQL
|
||||
|
||||
## 功能特点
|
||||
|
||||
### 1. 手术室类型
|
||||
|
||||
支持四种手术室类型:
|
||||
- **急诊手术室**:用于急诊手术的手术室
|
||||
- **择期手术室**:用于择期手术的手术室(默认类型)
|
||||
- **日间手术室**:用于日间手术的手术室
|
||||
- **复合手术室**:用于复合手术的手术室
|
||||
|
||||
### 2. 所属科室
|
||||
|
||||
每个手术室可以关联到具体的科室,便于科室级别的资源管理。
|
||||
|
||||
## 修改内容
|
||||
|
||||
### 前端修改(Vue3)
|
||||
|
||||
#### 1. 手术室列表页面 (`operatingroom/index.vue`)
|
||||
|
||||
**列表表格新增列**:
|
||||
- 类型列:显示手术室类型(急诊手术室、择期手术室等)
|
||||
- 所属科室列:显示手术室所属的科室名称
|
||||
|
||||
**新增/修改对话框新增字段**:
|
||||
- 类型选择器:下拉选择手术室类型
|
||||
- 所属科室选择器:可搜索的科室下拉框
|
||||
|
||||
**查询表单保持原样**:
|
||||
- 仍支持按手术室名称和状态查询
|
||||
|
||||
**查看对话框新增显示**:
|
||||
- 类型信息
|
||||
- 所属科室信息
|
||||
|
||||
#### 2. 表单数据结构
|
||||
|
||||
```javascript
|
||||
const form = ref({
|
||||
id: undefined,
|
||||
busNo: undefined,
|
||||
name: undefined,
|
||||
roomTypeEnum: undefined, // 新增:手术室类型
|
||||
organizationId: undefined, // 已有:所属科室ID
|
||||
organizationName: undefined, // 已有:所属科室名称
|
||||
locationDescription: undefined,
|
||||
equipmentConfig: undefined,
|
||||
capacity: 1,
|
||||
statusEnum: 1,
|
||||
displayOrder: 0,
|
||||
remark: undefined
|
||||
})
|
||||
```
|
||||
|
||||
#### 3. 类型选项配置
|
||||
|
||||
```javascript
|
||||
const roomTypeOptions = ref([
|
||||
{ value: 1, label: '急诊手术室' },
|
||||
{ value: 2, label: '择期手术室' },
|
||||
{ value: 3, label: '日间手术室' },
|
||||
{ value: 4, label: '复合手术室' }
|
||||
])
|
||||
```
|
||||
|
||||
### 后端修改(Java)
|
||||
|
||||
#### 1. 实体类 (`OperatingRoom.java`)
|
||||
|
||||
**新增字段**:
|
||||
```java
|
||||
/** 手术室类型 */
|
||||
@Dict(dictCode = "operating_room_type")
|
||||
private Integer roomTypeEnum;
|
||||
private String roomTypeEnum_dictText;
|
||||
|
||||
/** 所属机构ID */
|
||||
private Long organizationId;
|
||||
|
||||
/** 所属机构名称 */
|
||||
private String organizationName;
|
||||
```
|
||||
|
||||
#### 2. DTO类 (`OperatingRoomDto.java`)
|
||||
|
||||
**新增字段**:
|
||||
```java
|
||||
/** 手术室类型 */
|
||||
@Dict(dictCode = "operating_room_type")
|
||||
private Integer roomTypeEnum;
|
||||
private String roomTypeEnum_dictText;
|
||||
|
||||
/** 所属机构ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long organizationId;
|
||||
|
||||
/** 机构名称 */
|
||||
private String organizationName;
|
||||
```
|
||||
|
||||
#### 3. Service实现类 (`OperatingRoomAppServiceImpl.java`)
|
||||
|
||||
**查询列表方法优化**:
|
||||
- 添加类型字段的枚举值转换逻辑
|
||||
- 根据类型编码设置对应的中文描述
|
||||
|
||||
**详情查询方法优化**:
|
||||
- 添加类型字段的枚举值转换
|
||||
- 查询所属科室的名称并回显
|
||||
|
||||
### 数据库修改
|
||||
|
||||
#### SQL脚本文件:`add_operating_room_type_fields.sql`(PostgreSQL版本)
|
||||
|
||||
**1. 添加字段**:
|
||||
```sql
|
||||
ALTER TABLE public.adm_operating_room
|
||||
ADD COLUMN room_type_enum INTEGER DEFAULT 2;
|
||||
|
||||
COMMENT ON COLUMN public.adm_operating_room.room_type_enum IS
|
||||
'手术室类型:1-急诊手术室,2-择期手术室,3-日间手术室,4-复合手术室';
|
||||
```
|
||||
|
||||
**2. 更新现有数据**:
|
||||
```sql
|
||||
UPDATE public.adm_operating_room
|
||||
SET room_type_enum = 2
|
||||
WHERE room_type_enum IS NULL;
|
||||
```
|
||||
|
||||
**3. 添加索引**:
|
||||
```sql
|
||||
CREATE INDEX idx_room_type ON public.adm_operating_room(room_type_enum);
|
||||
CREATE INDEX idx_org_id ON public.adm_operating_room(organization_id);
|
||||
```
|
||||
|
||||
**4. 字典数据**:
|
||||
- 新增字典类型:`operating_room_type`(手术室类型)
|
||||
- 新增字典项:
|
||||
- 急诊手术室(1)
|
||||
- 择期手术室(2)
|
||||
- 日间手术室(3)
|
||||
- 复合手术室(4)
|
||||
|
||||
**PostgreSQL特定语法说明**:
|
||||
- 使用 `public.adm_operating_room` 替代 `` `adm_operating_room` ``
|
||||
- 使用 `COMMENT ON COLUMN` 替代 `COMMENT` 在 `ALTER TABLE` 中
|
||||
- 使用 `nextval()` 和序列来生成字典类型ID
|
||||
- 使用 `information_schema.columns` 获取列信息
|
||||
- 使用 `CASE WHEN` 语句进行条件判断
|
||||
|
||||
## 部署步骤
|
||||
|
||||
### 1. 数据库部署
|
||||
|
||||
执行SQL脚本(PostgreSQL):
|
||||
```bash
|
||||
psql -U postgres -d his_database -f add_operating_room_type_fields.sql
|
||||
```
|
||||
|
||||
或者使用 pgAdmin 等图形化工具执行SQL脚本。
|
||||
|
||||
### 2. 后端部署
|
||||
|
||||
重启后端服务,使新的代码生效。
|
||||
|
||||
### 3. 前端部署
|
||||
|
||||
重新编译并部署前端代码:
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
## 使用说明
|
||||
|
||||
### 新增手术室
|
||||
|
||||
1. 进入手术室管理页面
|
||||
2. 点击"新增手术室"按钮
|
||||
3. 填写手术室信息:
|
||||
- 手术室名称(必填)
|
||||
- 类型(可选,默认为择期手术室)
|
||||
- 所属科室(必填)
|
||||
- 位置描述
|
||||
- 设备配置
|
||||
- 容纳人数
|
||||
- 状态(默认为启用)
|
||||
- 显示顺序
|
||||
- 备注
|
||||
4. 点击"确定"保存
|
||||
|
||||
### 修改手术室
|
||||
|
||||
1. 在手术室列表中找到要修改的记录
|
||||
2. 点击"编辑"按钮
|
||||
3. 修改相关信息(包括类型和所属科室)
|
||||
4. 点击"确定"保存
|
||||
|
||||
### 查看手术室详情
|
||||
|
||||
1. 在手术室列表中点击"查看"按钮
|
||||
2. 查看完整的手术室信息,包括类型和所属科室
|
||||
|
||||
### 查询手术室
|
||||
|
||||
- 按手术室名称模糊查询
|
||||
- 按状态筛选(启用/停用)
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **数据迁移**:现有手术室的类型默认设置为"择期手术室"(2),可以根据实际需要调整。
|
||||
|
||||
2. **科室关联**:所属科室是必填字段,需要在科室管理中先配置好科室信息。
|
||||
|
||||
3. **类型字典**:手术室类型字典已自动创建,可以在系统字典管理中进行维护。
|
||||
|
||||
4. **索引优化**:已为类型和科室字段添加索引,提升查询性能。
|
||||
|
||||
5. **兼容性**:此次修改保持了向后兼容性,不影响现有功能。
|
||||
|
||||
## 验证清单
|
||||
|
||||
- [ ] 数据库字段添加成功
|
||||
- [ ] 字典数据创建成功
|
||||
- [ ] 前端列表正确显示类型和所属科室
|
||||
- [ ] 新增手术室时可选择类型和所属科室
|
||||
- [ ] 修改手术室时可更新类型和所属科室
|
||||
- [ ] 查看手术室详情时正确显示类型和所属科室
|
||||
- [ ] 类型下拉选项显示正确
|
||||
- [ ] 所属科室选择器可正常搜索和选择
|
||||
- [ ] 查询功能正常工作
|
||||
- [ ] 没有语法错误和运行时错误
|
||||
|
||||
## 回滚方案
|
||||
|
||||
如需撤销本次修改,请执行SQL脚本中的回滚语句(PostgreSQL):
|
||||
|
||||
```sql
|
||||
DROP INDEX idx_room_type ON public.adm_operating_room;
|
||||
DROP INDEX idx_org_id ON public.adm_operating_room;
|
||||
DELETE FROM public.sys_dict_data WHERE dict_type = 'operating_room_type';
|
||||
DELETE FROM public.sys_dict_type WHERE dict_type = 'operating_room_type';
|
||||
ALTER TABLE public.adm_operating_room DROP COLUMN room_type_enum;
|
||||
```
|
||||
|
||||
## 技术支持
|
||||
|
||||
如有问题,请联系技术支持团队。
|
||||
215
md/手术申请医生科室字段保存问题解决方案.md
Normal file
215
md/手术申请医生科室字段保存问题解决方案.md
Normal file
@@ -0,0 +1,215 @@
|
||||
# 手术申请医生科室字段保存问题解决方案
|
||||
|
||||
## 问题确认
|
||||
数据库中只保存了 ID 字段(`apply_doctor_id`、`apply_dept_id`),但没有保存名称字段(`apply_doctor_name`、`apply_dept_name`)。
|
||||
|
||||
## 根本原因
|
||||
**数据库表中缺少 `apply_doctor_name` 和 `apply_dept_name` 这两个字段!**
|
||||
|
||||
虽然 MyBatis 映射文件和实体类都配置了这些字段,但如果数据库表中不存在这些列,MyBatis 在插入时会静默忽略这些字段(不会报错),导致只有 ID 被保存。
|
||||
|
||||
## 解决步骤
|
||||
|
||||
### 步骤 1:执行数据库迁移脚本(必须!)
|
||||
|
||||
使用 Navicat Premium 17 执行以下 SQL:
|
||||
|
||||
```sql
|
||||
-- 方法1:使用 IF NOT EXISTS 语法(推荐)
|
||||
ALTER TABLE public.cli_surgery ADD COLUMN IF NOT EXISTS apply_doctor_name VARCHAR(100);
|
||||
COMMENT ON COLUMN public.cli_surgery.apply_doctor_name IS '申请医生姓名';
|
||||
|
||||
ALTER TABLE public.cli_surgery ADD COLUMN IF NOT EXISTS apply_dept_name VARCHAR(100);
|
||||
COMMENT ON COLUMN public.cli_surgery.apply_dept_name IS '申请科室名称';
|
||||
|
||||
-- 验证字段是否添加成功
|
||||
SELECT column_name, data_type, character_maximum_length
|
||||
FROM information_schema.columns
|
||||
WHERE table_name = 'cli_surgery'
|
||||
AND column_name IN ('apply_doctor_name', 'apply_dept_name');
|
||||
```
|
||||
|
||||
**预期结果**:
|
||||
```
|
||||
apply_doctor_name | character varying | 100
|
||||
apply_dept_name | character varying | 100
|
||||
```
|
||||
|
||||
### 步骤 2:重启后端服务
|
||||
|
||||
执行数据库迁移后,必须重启后端服务以重新加载表结构。
|
||||
|
||||
### 步骤 3:新增手术并查看日志
|
||||
|
||||
1. 打开后端控制台或日志文件
|
||||
2. 在前端新增一条手术记录
|
||||
3. 查看后端日志,应该能看到:
|
||||
|
||||
```
|
||||
设置申请医生信息 - doctorId: 123, doctorName: 张医生, deptId: 456, deptName: 普外科
|
||||
前端提交的数据 - applyDoctorId: 123, applyDoctorName: 张医生, applyDeptId: 456, applyDeptName: 普外科
|
||||
准备插入手术记录 - applyDoctorId: 123, applyDoctorName: 张医生, applyDeptId: 456, deptName: 普外科
|
||||
准备插入手术记录 - applyDoctorId: 123, applyDoctorName: 张医生, applyDeptId: 456, deptName: 普外科
|
||||
插入后查询结果 - applyDoctorId: 123, applyDoctorName: 张医生, applyDeptId: 456, deptName: 普外科
|
||||
手术记录插入成功 - surgeryId: 1234567890123456789, surgeryNo: OP202501051234
|
||||
```
|
||||
|
||||
**关键检查点**:
|
||||
- `准备插入手术记录` 这行日志中,`applyDoctorName` 和 `applyDeptName` 必须有值(不能为 null)
|
||||
- `插入后查询结果` 这行日志中,这两个字段也必须有值
|
||||
|
||||
### 步骤 4:验证数据库
|
||||
|
||||
执行以下 SQL 查询最新插入的记录:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
id,
|
||||
surgery_no,
|
||||
apply_doctor_id,
|
||||
apply_doctor_name,
|
||||
apply_dept_id,
|
||||
apply_dept_name,
|
||||
surgery_name,
|
||||
create_time
|
||||
FROM public.cli_surgery
|
||||
WHERE delete_flag = '0'
|
||||
ORDER BY create_time DESC
|
||||
LIMIT 1;
|
||||
```
|
||||
|
||||
**预期结果**:
|
||||
- `apply_doctor_id`:有值(例如:123)
|
||||
- `apply_doctor_name`:有值(例如:张医生)
|
||||
- `apply_dept_id`:有值(例如:456)
|
||||
- `apply_dept_name`:有值(例如:普外科)
|
||||
|
||||
### 步骤 5:测试前端显示
|
||||
|
||||
1. 刷新手术管理页面
|
||||
2. 查看列表中是否显示申请医生和申请科室列
|
||||
3. 点击"查看"或"编辑"按钮,检查详情对话框是否显示这些信息
|
||||
|
||||
## 常见问题和解决
|
||||
|
||||
### 问题 1:执行 SQL 后报错 "column does not exist"
|
||||
|
||||
**原因**:数据库表结构可能不同,或者表名不是 `cli_surgery`
|
||||
|
||||
**解决**:先执行以下 SQL 检查表名:
|
||||
|
||||
```sql
|
||||
SELECT table_name
|
||||
FROM information_schema.tables
|
||||
WHERE table_name LIKE '%surgery%'
|
||||
AND table_schema = 'public';
|
||||
```
|
||||
|
||||
### 问题 2:执行 SQL 后字段仍然不存在
|
||||
|
||||
**原因**:可能是权限问题或 SQL 语法问题
|
||||
|
||||
**解决**:尝试使用更简单的方式:
|
||||
|
||||
```sql
|
||||
-- 先检查表结构
|
||||
\d public.cli_surgery
|
||||
|
||||
-- 手动添加字段(如果不存在)
|
||||
-- 注意:如果字段已存在,这个语句会报错,这是正常的
|
||||
ALTER TABLE public.cli_surgery ADD COLUMN apply_doctor_name VARCHAR(100);
|
||||
ALTER TABLE public.cli_surgery ADD COLUMN apply_dept_name VARCHAR(100);
|
||||
```
|
||||
|
||||
### 问题 3:字段添加成功,但插入时仍然为空
|
||||
|
||||
**原因**:MyBatis 或 MyBatis-Plus 配置问题
|
||||
|
||||
**解决**:
|
||||
1. 检查实体类字段是否有 `@TableField` 注解
|
||||
2. 检查字段名是否与数据库列名一致
|
||||
3. 查看后端日志中的 `插入后查询结果`
|
||||
|
||||
### 问题 4:后端日志显示字段为 null
|
||||
|
||||
**原因**:后端代码中 `applyDoctorName` 或 `applyDeptName` 被设置为 null
|
||||
|
||||
**解决**:
|
||||
1. 检查 `SecurityUtils.getLoginUser().getUser().getNickName()` 是否返回 null
|
||||
2. 检查 `SecurityUtils.getLoginUser().getOrgId()` 是否返回 null
|
||||
3. 检查 `organizationService.getById(orgId)` 是否返回 null
|
||||
|
||||
## 验证清单
|
||||
|
||||
- [ ] 数据库迁移脚本已执行
|
||||
- [ ] 数据库字段已添加(步骤 1 验证 SQL 有结果)
|
||||
- [ ] 后端服务已重启
|
||||
- [ ] 后端日志显示 `准备插入手术记录` 且字段有值
|
||||
- [ ] 后端日志显示 `插入后查询结果` 且字段有值
|
||||
- [ ] 数据库查询显示字段有值(步骤 4)
|
||||
- [ ] 前端列表正确显示
|
||||
- [ ] 前端详情正确显示
|
||||
|
||||
## 调试 SQL 脚本
|
||||
|
||||
如果需要手动测试插入功能,可以执行:
|
||||
|
||||
```sql
|
||||
-- 测试插入(确保字段存在)
|
||||
INSERT INTO public.cli_surgery (
|
||||
surgery_no,
|
||||
patient_id,
|
||||
encounter_id,
|
||||
apply_doctor_id,
|
||||
apply_doctor_name,
|
||||
apply_dept_id,
|
||||
apply_dept_name,
|
||||
surgery_name,
|
||||
status_enum,
|
||||
delete_flag,
|
||||
create_time,
|
||||
update_time
|
||||
) VALUES (
|
||||
'TEST202501050002',
|
||||
(SELECT id FROM public.adm_patient WHERE delete_flag = '0' LIMIT 1),
|
||||
(SELECT id FROM public.adm_encounter WHERE delete_flag = '0' LIMIT 1),
|
||||
999,
|
||||
'手动测试医生',
|
||||
999,
|
||||
'手动测试科室',
|
||||
'手动测试手术',
|
||||
0,
|
||||
'0',
|
||||
NOW(),
|
||||
NOW()
|
||||
);
|
||||
|
||||
-- 查询刚才插入的数据
|
||||
SELECT
|
||||
surgery_no,
|
||||
apply_doctor_id,
|
||||
apply_doctor_name,
|
||||
apply_dept_id,
|
||||
apply_dept_name,
|
||||
surgery_name
|
||||
FROM public.cli_surgery
|
||||
WHERE surgery_no = 'TEST202501050002';
|
||||
|
||||
-- 清理测试数据
|
||||
-- DELETE FROM public.cli_surgery WHERE surgery_no = 'TEST202501050002';
|
||||
```
|
||||
|
||||
## 联系支持
|
||||
|
||||
如果以上步骤都无法解决问题,请提供:
|
||||
|
||||
1. **数据库表结构查询结果**:
|
||||
```sql
|
||||
\d public.cli_surgery
|
||||
```
|
||||
|
||||
2. **后端日志**:特别是 `准备插入手术记录` 和 `插入后查询结果` 这两行
|
||||
|
||||
3. **数据库查询结果**:执行步骤 4 中的 SQL,告诉我结果
|
||||
|
||||
4. **错误信息**:如果有任何错误提示
|
||||
194
md/手术申请医生科室数据保存问题排查指南.md
Normal file
194
md/手术申请医生科室数据保存问题排查指南.md
Normal file
@@ -0,0 +1,194 @@
|
||||
# 手术申请医生科室数据保存问题排查指南
|
||||
|
||||
## 问题现象
|
||||
新增手术后,列表页面和编辑查看页面没有显示申请医生名称和科室名称。
|
||||
|
||||
## 排查步骤
|
||||
|
||||
### 步骤1:检查数据库字段是否存在
|
||||
执行以下 SQL 检查字段是否已添加:
|
||||
|
||||
```sql
|
||||
SELECT column_name, data_type
|
||||
FROM information_schema.columns
|
||||
WHERE table_name = 'cli_surgery'
|
||||
AND column_name IN ('apply_doctor_name', 'apply_dept_name');
|
||||
```
|
||||
|
||||
**预期结果**:应该返回两条记录
|
||||
```
|
||||
apply_doctor_name | character varying
|
||||
apply_dept_name | character varying
|
||||
```
|
||||
|
||||
**如果结果为空**:说明字段未添加,需要执行迁移脚本。
|
||||
|
||||
### 步骤2:检查数据库迁移脚本是否执行
|
||||
执行迁移脚本(如果未执行):
|
||||
|
||||
```sql
|
||||
-- 检查并添加申请医生姓名字段
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_name = 'cli_surgery'
|
||||
AND column_name = 'apply_doctor_name'
|
||||
) THEN
|
||||
ALTER TABLE public.cli_surgery ADD COLUMN apply_doctor_name VARCHAR(100);
|
||||
COMMENT ON COLUMN public.cli_surgery.apply_doctor_name IS '申请医生姓名';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- 检查并添加申请科室名称字段
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_name = 'cli_surgery'
|
||||
AND column_name = 'apply_dept_name'
|
||||
) THEN
|
||||
ALTER TABLE public.cli_surgery ADD COLUMN apply_dept_name VARCHAR(100);
|
||||
COMMENT ON COLUMN public.cli_surgery.apply_dept_name IS '申请科室名称';
|
||||
END IF;
|
||||
END $$;
|
||||
```
|
||||
|
||||
### 步骤3:重启后端服务
|
||||
执行数据库迁移后,必须重启后端服务。
|
||||
|
||||
### 步骤4:新增手术并查看后端日志
|
||||
1. 打开后端控制台或日志文件
|
||||
2. 在前端新增一条手术记录
|
||||
3. 查看后端日志,应该能看到以下信息:
|
||||
|
||||
```
|
||||
设置申请医生信息 - doctorId: 123, doctorName: 张医生, deptId: 456, deptName: 普外科
|
||||
前端提交的数据 - applyDoctorId: 123, applyDoctorName: 张医生, applyDeptId: 456, applyDeptName: 普外科
|
||||
准备插入手术记录 - applyDoctorId: 123, applyDoctorName: 张医生, applyDeptId: 456, deptName: 普外科
|
||||
手术记录插入成功 - surgeryId: 1234567890123456789, surgeryNo: OP202501051234
|
||||
```
|
||||
|
||||
**如果看不到这些日志**:说明代码没有执行到这里,检查是否有异常抛出。
|
||||
|
||||
**如果看到 "前端提交的数据 - applyDoctorName: null"**:说明前端提交的数据为空,需要检查前端代码。
|
||||
|
||||
### 步骤5:检查数据库中是否保存成功
|
||||
执行以下 SQL 查询最新插入的记录:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
id,
|
||||
surgery_no,
|
||||
patient_id,
|
||||
apply_doctor_id,
|
||||
apply_doctor_name,
|
||||
apply_dept_id,
|
||||
apply_dept_name,
|
||||
surgery_name,
|
||||
status_enum,
|
||||
create_time
|
||||
FROM public.cli_surgery
|
||||
WHERE delete_flag = '0'
|
||||
ORDER BY create_time DESC
|
||||
LIMIT 5;
|
||||
```
|
||||
|
||||
**如果 apply_doctor_name 和 apply_dept_name 字段为空**:说明数据没有保存成功。
|
||||
|
||||
**如果字段有值**:说明保存成功,问题出在前端显示。
|
||||
|
||||
### 步骤6:检查前端 API 响应
|
||||
1. 打开浏览器开发者工具(F12)
|
||||
2. 切换到 Network 标签
|
||||
3. 新增手术
|
||||
4. 找到 `/clinical-manage/surgery/surgery-page` 请求
|
||||
5. 点击查看响应内容
|
||||
|
||||
检查响应数据中是否包含 `applyDoctorName` 和 `applyDeptName` 字段。
|
||||
|
||||
**如果响应中没有这些字段**:说明 MyBatis 映射有问题,检查 XML 配置。
|
||||
|
||||
**如果响应中有这些字段但值为 null**:说明数据库中为空,回到步骤5。
|
||||
|
||||
### 步骤7:检查前端表格显示
|
||||
查看前端代码中的表格列配置:
|
||||
|
||||
```vue
|
||||
<el-table-column label="申请医生" align="center" prop="applyDoctorName" width="100" />
|
||||
<el-table-column label="申请科室" align="center" prop="applyDeptName" width="120" show-overflow-tooltip />
|
||||
```
|
||||
|
||||
确保 `prop` 属性与后端返回的字段名一致(注意大小写)。
|
||||
|
||||
## 常见问题和解决方案
|
||||
|
||||
### 问题1:数据库字段未添加
|
||||
**症状**:后端报错 "column apply_doctor_name does not exist"
|
||||
**解决**:执行数据库迁移脚本
|
||||
|
||||
### 问题2:后端日志显示 applyDoctorName 为 null
|
||||
**症状**:日志中 "前端提交的数据 - applyDoctorName: null"
|
||||
**原因**:前端提交数据时,disabled 字段没有被包含
|
||||
**解决**:检查前端 submitForm 函数,确保手动设置了这些字段
|
||||
|
||||
### 问题3:数据库中有值,但前端不显示
|
||||
**症状**:数据库查询有值,前端响应也有值,但表格不显示
|
||||
**原因**:
|
||||
1. 前端 prop 属性名与后端字段名不一致(大小写问题)
|
||||
2. 前端数据未正确绑定
|
||||
**解决**:
|
||||
1. 检查 prop 属性名,确保与后端返回的 JSON 字段名一致
|
||||
2. 检查浏览器控制台是否有 JavaScript 错误
|
||||
|
||||
### 问题4:MyBatis 映射未生效
|
||||
**症状**:后端保存成功,但查询时字段为 null
|
||||
**原因**:XML 映射文件未正确配置
|
||||
**解决**:
|
||||
1. 检查 SurgeryMapper.xml 中的 resultMap 配置
|
||||
2. 检查 SQL 查询中是否包含这些字段
|
||||
3. 重启后端服务
|
||||
|
||||
## 验证清单
|
||||
|
||||
- [ ] 数据库迁移脚本已执行
|
||||
- [ ] 数据库字段已添加(步骤1)
|
||||
- [ ] 后端服务已重启
|
||||
- [ ] 后端日志显示申请医生信息(步骤4)
|
||||
- [ ] 数据库中已保存数据(步骤5)
|
||||
- [ ] 前端 API 响应包含这些字段(步骤6)
|
||||
- [ ] 前端表格正确显示(步骤7)
|
||||
|
||||
## 附加 SQL 脚本
|
||||
|
||||
### 查看统计信息
|
||||
```sql
|
||||
SELECT
|
||||
COUNT(*) as total_count,
|
||||
COUNT(apply_doctor_name) as has_doctor_name_count,
|
||||
COUNT(apply_dept_name) as has_dept_name_count
|
||||
FROM public.cli_surgery
|
||||
WHERE delete_flag = '0';
|
||||
```
|
||||
|
||||
### 手动更新测试数据
|
||||
如果需要手动更新已有的测试数据:
|
||||
|
||||
```sql
|
||||
UPDATE public.cli_surgery
|
||||
SET apply_doctor_name = '测试医生',
|
||||
apply_dept_name = '测试科室'
|
||||
WHERE apply_doctor_name IS NULL
|
||||
AND delete_flag = '0';
|
||||
```
|
||||
|
||||
## 联系支持
|
||||
|
||||
如果以上步骤都无法解决问题,请提供以下信息:
|
||||
1. 数据库字段查询结果(步骤1)
|
||||
2. 后端日志截图(步骤4)
|
||||
3. 数据库查询结果(步骤5)
|
||||
4. 浏览器 Network 响应截图(步骤6)
|
||||
5. 浏览器 Console 错误信息
|
||||
351
md/手术管理模块开发说明.md
Normal file
351
md/手术管理模块开发说明.md
Normal file
@@ -0,0 +1,351 @@
|
||||
# 手术管理模块开发说明
|
||||
|
||||
## 模块概述
|
||||
|
||||
手术管理模块是一个完整的医疗手术管理系统,涵盖从手术排期、执行到记录的全流程管理。本模块基于经典的Spring Boot + Vue3前后端分离架构开发。
|
||||
|
||||
## 功能特性
|
||||
|
||||
### 1. 手术信息管理
|
||||
- 手术基本信息录入(手术名称、编码、类型、等级)
|
||||
- 患者信息关联
|
||||
- 就诊信息关联
|
||||
- 手术部位描述
|
||||
|
||||
### 2. 手术团队管理
|
||||
- 主刀医生选择
|
||||
- 麻醉医生选择
|
||||
- 助手1/助手2选择
|
||||
- 巡回护士选择
|
||||
- 麻醉方式选择
|
||||
|
||||
### 3. 手术状态管理
|
||||
- 待排期
|
||||
- 已排期
|
||||
- 手术中
|
||||
- 已完成
|
||||
- 已取消
|
||||
- 暂停
|
||||
|
||||
### 4. 手术时间管理
|
||||
- 计划手术时间
|
||||
- 实际开始时间
|
||||
- 实际结束时间
|
||||
|
||||
### 5. 诊断信息管理
|
||||
- 术前诊断
|
||||
- 术后诊断
|
||||
- 手术经过描述
|
||||
- 术后医嘱
|
||||
- 并发症描述
|
||||
|
||||
### 6. 手术费用管理
|
||||
- 手术费用
|
||||
- 麻醉费用
|
||||
- 总费用自动计算
|
||||
|
||||
### 7. 手术切口管理
|
||||
- 切口等级(I级、II级、III级、IV级)
|
||||
- 愈合等级(甲级、乙级、丙级)
|
||||
|
||||
## 技术架构
|
||||
|
||||
### 后端技术栈
|
||||
- Spring Boot 2.x
|
||||
- MyBatis Plus
|
||||
- PostgreSQL 12+
|
||||
- JDK 1.8+
|
||||
|
||||
### 前端技术栈
|
||||
- Vue 3.x
|
||||
- Element Plus
|
||||
- Axios
|
||||
- Vite
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
openh-is/
|
||||
├── openhis-server-new/ # 后端项目
|
||||
│ ├── openhis-domain/ # 领域层
|
||||
│ │ └── src/main/java/com/openhis/
|
||||
│ │ ├── clinical/
|
||||
│ │ │ ├── domain/
|
||||
│ │ │ │ └── Surgery.java # 手术实体类
|
||||
│ │ │ ├── mapper/
|
||||
│ │ │ │ └── SurgeryMapper.java # 手术Mapper接口
|
||||
│ │ │ └── service/
|
||||
│ │ │ ├── ISurgeryService.java # 手术Service接口
|
||||
│ │ │ └── impl/
|
||||
│ │ │ └── SurgeryServiceImpl.java # 手术Service实现
|
||||
│ │ └── common/ # 公共模块
|
||||
│ │ └── src/main/java/com/openhis/common/
|
||||
│ │ └── enums/ # 枚举类
|
||||
│ │ ├── SurgeryTypeEnum.java # 手术类型枚举
|
||||
│ │ ├── SurgeryStatusEnum.java # 手术状态枚举
|
||||
│ │ ├── SurgeryLevelEnum.java # 手术等级枚举
|
||||
│ │ ├── AnesthesiaTypeEnum.java # 麻醉方式枚举
|
||||
│ │ ├── IncisionLevelEnum.java # 切口等级枚举
|
||||
│ │ └── HealingLevelEnum.java # 愈合等级枚举
|
||||
│ │
|
||||
│ ├── openhis-application/ # 应用层
|
||||
│ │ └── src/main/java/com/openhis/web/clinicalmanage/
|
||||
│ │ ├── controller/
|
||||
│ │ │ └── SurgeryController.java # 手术控制器
|
||||
│ │ ├── dto/
|
||||
│ │ │ └── SurgeryDto.java # 手术数据传输对象
|
||||
│ │ ├── appservice/
|
||||
│ │ │ ├── ISurgeryAppService.java # 手术应用服务接口
|
||||
│ │ │ └── impl/
|
||||
│ │ │ └── SurgeryAppServiceImpl.java # 手术应用服务实现
|
||||
│ │ └── mapper/
|
||||
│ │ └── SurgeryAppMapper.java # 手术应用Mapper
|
||||
│ │
|
||||
│ └── src/main/resources/mapper/
|
||||
│ ├── clinical/
|
||||
│ │ └── SurgeryMapper.xml # 手术Mapper XML
|
||||
│ └── clinicalmanage/
|
||||
│ └── SurgeryMapper.xml # 手术应用Mapper XML
|
||||
│
|
||||
├── openhis-ui-vue3/ # 前端项目
|
||||
│ └── src/
|
||||
│ ├── api/
|
||||
│ │ └── surgerymanage.js # 手术API接口
|
||||
│ └── views/
|
||||
│ └── surgerymanage/
|
||||
│ └── index.vue # 手术管理页面
|
||||
│
|
||||
└── surgery_manage_init.sql # 数据库初始化脚本
|
||||
```
|
||||
|
||||
## 数据库设计
|
||||
|
||||
### 主表:cli_surgery(手术管理表)
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| id | bigint | 主键ID |
|
||||
| surgery_no | varchar(50) | 手术编号(唯一) |
|
||||
| patient_id | bigint | 患者ID |
|
||||
| patient_name | varchar(100) | 患者姓名 |
|
||||
| encounter_id | bigint | 就诊ID |
|
||||
| surgery_name | varchar(200) | 手术名称 |
|
||||
| surgery_code | varchar(100) | 手术编码 |
|
||||
| surgery_type_enum | int2 | 手术类型 |
|
||||
| surgery_level | int2 | 手术等级 |
|
||||
| status_enum | int2 | 手术状态 |
|
||||
| planned_time | timestamp | 计划手术时间 |
|
||||
| actual_start_time | timestamp | 实际开始时间 |
|
||||
| actual_end_time | timestamp | 实际结束时间 |
|
||||
| main_surgeon_id | bigint | 主刀医生ID |
|
||||
| main_surgeon_name | varchar(100) | 主刀医生姓名 |
|
||||
| anesthetist_id | bigint | 麻醉医生ID |
|
||||
| anesthetist_name | varchar(100) | 麻醉医生姓名 |
|
||||
| anesthesia_type_enum | int2 | 麻醉方式 |
|
||||
| body_site | varchar(200) | 手术部位 |
|
||||
| preoperative_diagnosis | text | 术前诊断 |
|
||||
| postoperative_diagnosis | text | 术后诊断 |
|
||||
| surgery_fee | numeric(10,2) | 手术费用 |
|
||||
| anesthesia_fee | numeric(10,2) | 麻醉费用 |
|
||||
| total_fee | numeric(10,2) | 总费用 |
|
||||
|
||||
### 字典表
|
||||
|
||||
手术管理模块包含以下字典类型:
|
||||
- surgery_status(手术状态)
|
||||
- surgery_type(手术类型)
|
||||
- surgery_level(手术等级)
|
||||
- anesthesia_type(麻醉方式)
|
||||
- incision_level(切口等级)
|
||||
- healing_level(愈合等级)
|
||||
|
||||
## 安装部署
|
||||
|
||||
### 1. 数据库初始化
|
||||
|
||||
执行SQL脚本初始化数据库表和字典数据:
|
||||
|
||||
```bash
|
||||
psql -U postgres -d his_database -f surgery_manage_init.sql
|
||||
```
|
||||
|
||||
或者使用psql客户端执行:
|
||||
|
||||
```sql
|
||||
\i /path/to/surgery_manage_init.sql
|
||||
```
|
||||
|
||||
### 2. 后端配置
|
||||
|
||||
1. 将后端代码复制到对应目录
|
||||
2. 修改数据库连接配置(application.yml)
|
||||
3. 启动Spring Boot应用
|
||||
|
||||
### 3. 前端配置
|
||||
|
||||
1. 将前端代码复制到对应目录
|
||||
2. 配置API接口地址(.env.development)
|
||||
3. 启动前端开发服务器
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## API接口说明
|
||||
|
||||
### 1. 分页查询手术列表
|
||||
|
||||
**接口地址:** `GET /clinical-manage/surgery/surgery-page`
|
||||
|
||||
**请求参数:**
|
||||
```json
|
||||
{
|
||||
"pageNo": 1,
|
||||
"pageSize": 10,
|
||||
"surgeryNo": "SS20251230001",
|
||||
"surgeryName": "阑尾切除术",
|
||||
"patientName": "张三",
|
||||
"statusEnum": 1,
|
||||
"surgeryTypeEnum": 2
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 查询手术详情
|
||||
|
||||
**接口地址:** `GET /clinical-manage/surgery/surgery-detail`
|
||||
|
||||
**请求参数:**
|
||||
```
|
||||
id: 手术ID
|
||||
```
|
||||
|
||||
### 3. 新增手术
|
||||
|
||||
**接口地址:** `POST /clinical-manage/surgery/surgery`
|
||||
|
||||
**请求参数:**
|
||||
```json
|
||||
{
|
||||
"patientId": 1,
|
||||
"surgeryName": "阑尾切除术",
|
||||
"surgeryCode": "ICD-9-CM:47.09",
|
||||
"surgeryTypeEnum": 2,
|
||||
"surgeryLevel": 2,
|
||||
"plannedTime": "2025-12-31 09:00:00",
|
||||
"mainSurgeonId": 10,
|
||||
"anesthetistId": 11,
|
||||
"anesthesiaTypeEnum": 3,
|
||||
"bodySite": "腹部"
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 修改手术
|
||||
|
||||
**接口地址:** `PUT /clinical-manage/surgery/surgery`
|
||||
|
||||
**请求参数:** 同新增手术,需包含id
|
||||
|
||||
### 5. 删除手术
|
||||
|
||||
**接口地址:** `DELETE /clinical-manage/surgery/surgery`
|
||||
|
||||
**请求参数:**
|
||||
```
|
||||
id: 手术ID
|
||||
```
|
||||
|
||||
### 6. 更新手术状态
|
||||
|
||||
**接口地址:** `PUT /clinical-manage/surgery/surgery-status`
|
||||
|
||||
**请求参数:**
|
||||
```
|
||||
id: 手术ID
|
||||
statusEnum: 状态值
|
||||
```
|
||||
|
||||
## 前端页面功能
|
||||
|
||||
### 1. 查询功能
|
||||
- 支持按手术编号、手术名称、患者姓名模糊查询
|
||||
- 支持按手术状态、手术类型精确查询
|
||||
- 支持按计划时间范围查询
|
||||
|
||||
### 2. 新增功能
|
||||
- 完整的手术信息录入表单
|
||||
- 患者下拉选择
|
||||
- 医生/护士下拉选择
|
||||
- 费用自动计算
|
||||
|
||||
### 3. 编辑功能
|
||||
- 仅待排期和已排期状态的手术可编辑
|
||||
- 手术中或已完成的手术不可编辑
|
||||
|
||||
### 4. 状态流转
|
||||
- 已排期 → 手术中
|
||||
- 手术中 → 已完成
|
||||
- 待排期/已排期 → 已取消
|
||||
|
||||
### 5. 删除功能
|
||||
- 仅待排期和已排期状态的手术可删除
|
||||
- 已完成的手术不能删除
|
||||
|
||||
## 扩展开发建议
|
||||
|
||||
### 1. 手术排期管理
|
||||
- 可增加手术排期日历视图
|
||||
- 手术室资源冲突检测
|
||||
- 手术排队优先级管理
|
||||
|
||||
### 2. 手术统计报表
|
||||
- 手术量统计
|
||||
- 手术类型分布
|
||||
- 手术成功率统计
|
||||
- 手术费用统计
|
||||
|
||||
### 3. 手术文档管理
|
||||
- 手术知情同意书
|
||||
- 手术安全核查表
|
||||
- 手术记录单
|
||||
- 麻醉记录单
|
||||
|
||||
### 4. 手术质控管理
|
||||
- 手术质量评估
|
||||
- 并发症统计
|
||||
- 术后恢复跟踪
|
||||
- 手术质量指标管理
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **手术编号生成**:手术编号采用自动生成机制,格式为SS + 10位数字
|
||||
2. **权限控制**:需要配置相应的菜单权限和操作权限
|
||||
3. **数据校验**:新增手术时必须选择患者和主刀医生
|
||||
4. **状态流转**:手术状态的流转需要符合业务逻辑
|
||||
5. **费用计算**:总费用自动计算,不允许手动修改
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q1: 手术编号重复怎么办?
|
||||
A: 手术编号是系统自动生成的唯一编号,不会重复。如果需要自定义编号,需要修改SurgeryServiceImpl中的生成逻辑。
|
||||
|
||||
### Q2: 如何添加新的手术类型?
|
||||
A: 在数据库sys_dict_data表中添加新的surgery_type字典数据即可。
|
||||
|
||||
### Q3: 手术开始后还能修改信息吗?
|
||||
A: 根据业务规则,手术开始后不允许修改基本信息,但可以补充术后诊断等信息。
|
||||
|
||||
### Q4: 如何实现手术室资源管理?
|
||||
A: 可以新增手术室管理模块,建立手术排期与手术室的关联关系,实现资源冲突检测。
|
||||
|
||||
## 版本历史
|
||||
|
||||
- v1.0.0 (2025-12-30)
|
||||
- 初始版本发布
|
||||
- 实现手术基本管理功能
|
||||
- 实现手术状态流转
|
||||
- 实现手术团队管理
|
||||
|
||||
## 联系方式
|
||||
|
||||
如有问题或建议,请联系开发团队。
|
||||
0
md/未读公告弹窗实现方案.md
Normal file
0
md/未读公告弹窗实现方案.md
Normal file
160
md/门诊就诊记录SQL优化建议.md
Normal file
160
md/门诊就诊记录SQL优化建议.md
Normal file
@@ -0,0 +1,160 @@
|
||||
# 门诊就诊记录SQL查询优化建议
|
||||
|
||||
## 当前查询分析
|
||||
|
||||
### 主要查询表
|
||||
```sql
|
||||
SELECT
|
||||
enc.id as encounterId,
|
||||
pt.name,
|
||||
pt.id_card,
|
||||
pt.bus_no as patientBusNo,
|
||||
enc.bus_no as encounterBusNo,
|
||||
pt.gender_enum,
|
||||
pt.phone,
|
||||
enc.create_time as encounterTime,
|
||||
enc.status_enum as subjectStatusEnum,
|
||||
org.name as organizationName,
|
||||
prac.name as doctorName
|
||||
FROM adm_encounter AS enc
|
||||
LEFT JOIN adm_organization AS org ON enc.organization_id = org.ID AND org.delete_flag = '0'
|
||||
LEFT JOIN adm_encounter_participant AS ep
|
||||
ON enc.ID = ep.encounter_id AND ep.type_code = #{participantType} AND ep.delete_flag = '0'
|
||||
LEFT JOIN adm_practitioner AS prac ON ep.practitioner_id = prac.ID AND prac.delete_flag = '0'
|
||||
LEFT JOIN adm_patient AS pt ON enc.patient_id = pt.ID AND pt.delete_flag = '0'
|
||||
```
|
||||
|
||||
### 常见查询条件
|
||||
1. `enc.delete_flag = '0'`
|
||||
2. `enc.tenant_id = ?`
|
||||
3. `pt.name LIKE ?`
|
||||
4. `pt.id_card LIKE ?`
|
||||
5. `pt.bus_no LIKE ?`
|
||||
6. `enc.bus_no LIKE ?`
|
||||
7. `pt.gender_enum = ?`
|
||||
8. `enc.status_enum = ?`
|
||||
9. `prac.name LIKE ?`
|
||||
10. `pt.phone LIKE ?`
|
||||
11. `enc.create_time BETWEEN ? AND ?`
|
||||
|
||||
## 索引优化建议
|
||||
|
||||
### 1. adm_encounter 表索引
|
||||
```sql
|
||||
-- 复合索引:提高查询性能
|
||||
CREATE INDEX idx_encounter_tenant_delete_status ON adm_encounter(tenant_id, delete_flag, status_enum);
|
||||
|
||||
-- 时间范围查询索引
|
||||
CREATE INDEX idx_encounter_create_time ON adm_encounter(create_time);
|
||||
|
||||
-- 业务编号查询索引
|
||||
CREATE INDEX idx_encounter_bus_no ON adm_encounter(bus_no);
|
||||
|
||||
-- 患者ID关联索引
|
||||
CREATE INDEX idx_encounter_patient_id ON adm_encounter(patient_id);
|
||||
```
|
||||
|
||||
### 2. adm_patient 表索引
|
||||
```sql
|
||||
-- 姓名模糊查询索引
|
||||
CREATE INDEX idx_patient_name ON adm_patient(name);
|
||||
|
||||
-- 身份证号查询索引
|
||||
CREATE INDEX idx_patient_id_card ON adm_patient(id_card);
|
||||
|
||||
-- 业务编号查询索引
|
||||
CREATE INDEX idx_patient_bus_no ON adm_patient(bus_no);
|
||||
|
||||
-- 电话查询索引
|
||||
CREATE INDEX idx_patient_phone ON adm_patient(phone);
|
||||
|
||||
-- 复合索引:常用查询条件
|
||||
CREATE INDEX idx_patient_delete_gender ON adm_patient(delete_flag, gender_enum);
|
||||
```
|
||||
|
||||
### 3. adm_encounter_participant 表索引
|
||||
```sql
|
||||
-- 复合索引:提高连接性能
|
||||
CREATE INDEX idx_ep_encounter_type ON adm_encounter_participant(encounter_id, type_code, delete_flag);
|
||||
|
||||
-- 参与者ID索引
|
||||
CREATE INDEX idx_ep_practitioner ON adm_encounter_participant(practitioner_id);
|
||||
```
|
||||
|
||||
### 4. adm_practitioner 表索引
|
||||
```sql
|
||||
-- 姓名查询索引
|
||||
CREATE INDEX idx_practitioner_name ON adm_practitioner(name);
|
||||
|
||||
-- 复合索引:常用查询条件
|
||||
CREATE INDEX idx_practitioner_delete_tenant ON adm_practitioner(delete_flag, tenant_id);
|
||||
```
|
||||
|
||||
### 5. adm_organization 表索引
|
||||
```sql
|
||||
-- 主键关联索引
|
||||
CREATE INDEX idx_organization_id_delete ON adm_organization(id, delete_flag);
|
||||
```
|
||||
|
||||
## 查询优化建议
|
||||
|
||||
### 1. 添加查询统计信息收集
|
||||
```sql
|
||||
-- 定期分析表统计信息
|
||||
ANALYZE TABLE adm_encounter;
|
||||
ANALYZE TABLE adm_patient;
|
||||
ANALYZE TABLE adm_encounter_participant;
|
||||
ANALYZE TABLE adm_practitioner;
|
||||
ANALYZE TABLE adm_organization;
|
||||
```
|
||||
|
||||
### 2. 考虑分区表(针对大数据量)
|
||||
如果 `adm_encounter` 表数据量超过100万条,考虑按时间分区:
|
||||
```sql
|
||||
-- 按月分区
|
||||
PARTITION BY RANGE (YEAR(create_time) * 100 + MONTH(create_time))
|
||||
(
|
||||
PARTITION p202501 VALUES LESS THAN (202501),
|
||||
PARTITION p202502 VALUES LESS THAN (202502),
|
||||
-- ... 更多分区
|
||||
);
|
||||
```
|
||||
|
||||
### 3. 添加覆盖索引(Covering Index)
|
||||
对于常用查询字段,创建覆盖索引避免回表:
|
||||
```sql
|
||||
CREATE INDEX idx_encounter_cover ON adm_encounter(
|
||||
tenant_id, delete_flag, create_time,
|
||||
status_enum, bus_no, patient_id
|
||||
) INCLUDE (organization_id);
|
||||
```
|
||||
|
||||
## 执行计划检查
|
||||
|
||||
建议定期检查查询执行计划:
|
||||
```sql
|
||||
EXPLAIN ANALYZE
|
||||
SELECT -- 完整查询语句
|
||||
FROM adm_encounter AS enc
|
||||
-- ... 连接条件
|
||||
WHERE enc.delete_flag = '0'
|
||||
AND enc.tenant_id = 1
|
||||
-- ... 其他条件
|
||||
ORDER BY enc.create_time DESC;
|
||||
```
|
||||
|
||||
## 监控建议
|
||||
|
||||
1. **慢查询监控**:监控执行时间超过1秒的查询
|
||||
2. **索引使用监控**:定期检查未使用的索引
|
||||
3. **表空间监控**:监控表增长和碎片情况
|
||||
4. **连接性能监控**:监控JOIN操作的性能
|
||||
|
||||
## 实施步骤
|
||||
|
||||
1. 在测试环境创建建议的索引
|
||||
2. 执行查询性能测试
|
||||
3. 分析执行计划,确认索引有效性
|
||||
4. 在生产环境非高峰期创建索引
|
||||
5. 监控生产环境性能变化
|
||||
6. 定期维护和优化索引
|
||||
45
openhis-server-new/com/openhis/tool/DatabaseFieldAdder.java
Normal file
45
openhis-server-new/com/openhis/tool/DatabaseFieldAdder.java
Normal file
@@ -0,0 +1,45 @@
|
||||
package com.openhis.tool;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.Statement;
|
||||
|
||||
/**
|
||||
* Database field adder tool
|
||||
*/
|
||||
public class DatabaseFieldAdder {
|
||||
public static void main(String[] args) {
|
||||
String url = "jdbc:postgresql://192.168.110.252:15432/postgresql?currentSchema=public";
|
||||
String username = "postgresql";
|
||||
String password = "Jchl1528";
|
||||
|
||||
try (Connection conn = DriverManager.getConnection(url, username, password);
|
||||
Statement stmt = conn.createStatement()) {
|
||||
|
||||
// Check if field exists
|
||||
String checkSql = "SELECT column_name FROM information_schema.columns " +
|
||||
"WHERE table_name = 'adm_healthcare_service' AND column_name = 'practitioner_id'";
|
||||
|
||||
boolean fieldExists = stmt.executeQuery(checkSql).next();
|
||||
|
||||
if (!fieldExists) {
|
||||
// Add field
|
||||
String addSql = "ALTER TABLE \"public\".\"adm_healthcare_service\" " +
|
||||
"ADD COLUMN \"practitioner_id\" int8";
|
||||
stmt.execute(addSql);
|
||||
|
||||
// Add comment
|
||||
String commentSql = "COMMENT ON COLUMN \"public\".\"adm_healthcare_service\".\"practitioner_id\" IS 'practitioner_id'";
|
||||
stmt.execute(commentSql);
|
||||
|
||||
System.out.println("Successfully added practitioner_id field to adm_healthcare_service table");
|
||||
} else {
|
||||
System.out.println("practitioner_id field already exists");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("Error executing SQL: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.openhis</groupId>
|
||||
<artifactId>openhis-server</artifactId>
|
||||
@@ -25,6 +25,11 @@
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<optional>true</optional> <!-- 表示依赖不会传递 -->
|
||||
</dependency>
|
||||
<!-- lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- swagger3-->
|
||||
<dependency>
|
||||
@@ -36,7 +41,6 @@
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-models</artifactId>
|
||||
<version>1.6.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Mysql驱动包 -->
|
||||
@@ -68,45 +72,12 @@
|
||||
<groupId>com.core</groupId>
|
||||
<artifactId>core-flowable</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 通用工具-->
|
||||
<dependency>
|
||||
<groupId>com.core</groupId>
|
||||
<artifactId>core-common</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<!-- <build>-->
|
||||
<!-- <plugins>-->
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>org.springframework.boot</groupId>-->
|
||||
<!-- <artifactId>spring-boot-maven-plugin</artifactId>-->
|
||||
<!-- <version>2.5.15</version>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <fork>true</fork> <!– 如果没有该配置,devtools不会生效 –>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- <executions>-->
|
||||
<!-- <execution>-->
|
||||
<!-- <goals>-->
|
||||
<!-- <goal>repackage</goal>-->
|
||||
<!-- </goals>-->
|
||||
<!-- </execution>-->
|
||||
<!-- </executions>-->
|
||||
<!-- </plugin>-->
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>org.apache.maven.plugins</groupId>-->
|
||||
<!-- <artifactId>maven-war-plugin</artifactId>-->
|
||||
<!-- <version>3.1.0</version>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <failOnMissingWebXml>false</failOnMissingWebXml>-->
|
||||
<!-- <warName>${project.artifactId}</warName>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- </plugin>-->
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>org.apache.maven.plugins</groupId>-->
|
||||
<!-- <artifactId>maven-compiler-plugin</artifactId>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <source>8</source>-->
|
||||
<!-- <target>8</target>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- </plugin>-->
|
||||
<!-- </plugins>-->
|
||||
<!-- <finalName>${project.artifactId}</finalName>-->
|
||||
<!-- </build>-->
|
||||
|
||||
</project>
|
||||
@@ -1,18 +1,5 @@
|
||||
package com.core.web.controller.common;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.util.FastByteArrayOutputStream;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.core.common.config.CoreConfig;
|
||||
import com.core.common.constant.CacheConstants;
|
||||
import com.core.common.constant.Constants;
|
||||
@@ -22,6 +9,17 @@ import com.core.common.utils.sign.Base64;
|
||||
import com.core.common.utils.uuid.IdUtils;
|
||||
import com.core.system.service.ISysConfigService;
|
||||
import com.google.code.kaptcha.Producer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.util.FastByteArrayOutputStream;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 验证码操作处理
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package com.core.web.controller.common;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.core.common.config.CoreConfig;
|
||||
import com.core.common.constant.Constants;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import com.core.common.utils.file.FileUploadUtils;
|
||||
import com.core.common.utils.file.FileUtils;
|
||||
import com.core.framework.config.ServerConfig;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -16,13 +17,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import com.core.common.config.CoreConfig;
|
||||
import com.core.common.constant.Constants;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import com.core.common.utils.file.FileUploadUtils;
|
||||
import com.core.common.utils.file.FileUtils;
|
||||
import com.core.framework.config.ServerConfig;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 通用请求处理
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
package com.core.web.controller.common;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import com.core.common.annotation.Anonymous;
|
||||
import com.core.common.config.CoreConfig;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
@@ -16,6 +8,13 @@ import com.core.common.utils.StringUtils;
|
||||
import com.core.common.utils.file.FileUploadUtils;
|
||||
import com.core.common.utils.file.FileUtils;
|
||||
import com.core.framework.config.ServerConfig;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/file")
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
package com.core.web.controller.monitor;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import com.core.common.constant.CacheConstants;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import com.core.system.domain.SysCache;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisCallback;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.core.common.constant.CacheConstants;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import com.core.system.domain.SysCache;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 缓存监控
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package com.core.web.controller.monitor;
|
||||
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.core.framework.web.domain.Server;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.core.framework.web.domain.Server;
|
||||
|
||||
/**
|
||||
* 服务器监控
|
||||
*
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
package com.core.web.controller.monitor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.core.common.annotation.Log;
|
||||
import com.core.common.core.controller.BaseController;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
@@ -17,15 +9,23 @@ import com.core.common.utils.poi.ExcelUtil;
|
||||
import com.core.framework.web.service.SysPasswordService;
|
||||
import com.core.system.domain.SysLogininfor;
|
||||
import com.core.system.service.ISysLogininforService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 系统访问记录
|
||||
*
|
||||
*
|
||||
*
|
||||
* @author system
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/monitor/logininfor")
|
||||
|
||||
public class SysLogininforController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private ISysLogininforService logininforService;
|
||||
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
package com.core.web.controller.monitor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.core.common.annotation.Log;
|
||||
import com.core.common.core.controller.BaseController;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
@@ -16,6 +8,12 @@ import com.core.common.enums.BusinessType;
|
||||
import com.core.common.utils.poi.ExcelUtil;
|
||||
import com.core.system.domain.SysOperLog;
|
||||
import com.core.system.service.ISysOperLogService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 操作日志记录
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
package com.core.web.controller.monitor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.core.common.annotation.Log;
|
||||
import com.core.common.constant.CacheConstants;
|
||||
import com.core.common.core.controller.BaseController;
|
||||
@@ -20,6 +11,14 @@ import com.core.common.enums.BusinessType;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import com.core.system.domain.SysUserOnline;
|
||||
import com.core.system.service.ISysUserOnlineService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 在线用户监控
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
package com.core.web.controller.system;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.core.common.annotation.Log;
|
||||
import com.core.common.core.controller.BaseController;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
@@ -17,6 +8,13 @@ import com.core.common.enums.BusinessType;
|
||||
import com.core.common.utils.poi.ExcelUtil;
|
||||
import com.core.system.domain.SysConfig;
|
||||
import com.core.system.service.ISysConfigService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 参数配置 信息操作处理
|
||||
@@ -63,7 +61,25 @@ public class SysConfigController extends BaseController {
|
||||
*/
|
||||
@GetMapping(value = "/configKey/{configKey}")
|
||||
public AjaxResult getConfigKey(@PathVariable String configKey) {
|
||||
return success(configService.selectConfigByKey(configKey));
|
||||
String configValue = configService.selectConfigByKey(configKey);
|
||||
// 确保即使返回 null 或空字符串,也明确设置 data 字段
|
||||
// 如果 configValue 是 null,转换为空字符串
|
||||
if (configValue == null) {
|
||||
configValue = "";
|
||||
}
|
||||
// 直接创建 AjaxResult 并明确设置 data 字段,确保 data 字段始终存在
|
||||
AjaxResult result = new AjaxResult();
|
||||
result.put("code", 200);
|
||||
result.put("msg", "操作成功");
|
||||
result.put("data", configValue); // 明确设置 data 字段,即使值为空字符串
|
||||
System.out.println("=== getConfigKey 调试信息 ===");
|
||||
System.out.println("configKey: " + configKey);
|
||||
System.out.println("configValue: [" + configValue + "]");
|
||||
System.out.println("result.data: " + result.get("data"));
|
||||
System.out.println("result.msg: " + result.get("msg"));
|
||||
System.out.println("result.code: " + result.get("code"));
|
||||
System.out.println("============================");
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
package com.core.web.controller.system;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.core.common.annotation.Log;
|
||||
import com.core.common.constant.UserConstants;
|
||||
import com.core.common.core.controller.BaseController;
|
||||
@@ -16,6 +8,13 @@ import com.core.common.core.domain.entity.SysDept;
|
||||
import com.core.common.enums.BusinessType;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import com.core.system.service.ISysDeptService;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 部门信息
|
||||
|
||||
@@ -1,15 +1,5 @@
|
||||
package com.core.web.controller.system;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.core.common.annotation.Log;
|
||||
import com.core.common.core.controller.BaseController;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
@@ -20,6 +10,14 @@ import com.core.common.utils.StringUtils;
|
||||
import com.core.common.utils.poi.ExcelUtil;
|
||||
import com.core.system.service.ISysDictDataService;
|
||||
import com.core.system.service.ISysDictTypeService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据字典信息
|
||||
@@ -62,11 +60,12 @@ public class SysDictDataController extends BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典类型查询字典数据信息
|
||||
* 根据字典类型查询字典数据信息(支持拼音搜索)
|
||||
*/
|
||||
@GetMapping(value = "/type/{dictType}")
|
||||
public AjaxResult dictType(@PathVariable String dictType) {
|
||||
List<SysDictData> data = dictTypeService.selectDictDataByType(dictType);
|
||||
public AjaxResult dictType(@PathVariable String dictType,
|
||||
@RequestParam(value = "searchKey", required = false) String searchKey) {
|
||||
List<SysDictData> data = dictTypeService.selectDictDataByType(dictType, searchKey);
|
||||
if (StringUtils.isNull(data)) {
|
||||
data = new ArrayList<SysDictData>();
|
||||
}
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
package com.core.web.controller.system;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.core.common.annotation.Log;
|
||||
import com.core.common.core.controller.BaseController;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
@@ -17,6 +8,13 @@ import com.core.common.core.page.TableDataInfo;
|
||||
import com.core.common.enums.BusinessType;
|
||||
import com.core.common.utils.poi.ExcelUtil;
|
||||
import com.core.system.service.ISysDictTypeService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据字典信息
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package com.core.web.controller.system;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.core.common.config.CoreConfig;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 首页
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
package com.core.web.controller.system;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.core.common.constant.Constants;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.core.common.core.domain.entity.SysMenu;
|
||||
@@ -20,6 +11,15 @@ import com.core.framework.web.service.SysLoginService;
|
||||
import com.core.framework.web.service.SysPermissionService;
|
||||
import com.core.framework.web.service.TokenService;
|
||||
import com.core.system.service.ISysMenuService;
|
||||
import com.core.system.service.ISysTenantService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**已评审
|
||||
* 登录验证
|
||||
@@ -40,6 +40,9 @@ public class SysLoginController {
|
||||
@Autowired
|
||||
private TokenService tokenService;
|
||||
|
||||
@Autowired
|
||||
private ISysTenantService tenantService;
|
||||
|
||||
/**已评审
|
||||
* 登录方法
|
||||
*
|
||||
@@ -73,12 +76,22 @@ public class SysLoginController {
|
||||
loginUser.setPermissions(permissions);
|
||||
tokenService.refreshToken(loginUser);
|
||||
}
|
||||
// 获取租户名称
|
||||
String tenantName = null;
|
||||
if (loginUser.getTenantId() != null) {
|
||||
com.core.system.domain.SysTenant tenant = tenantService.getById(loginUser.getTenantId());
|
||||
if (tenant != null) {
|
||||
tenantName = tenant.getTenantName();
|
||||
}
|
||||
}
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
ajax.put("optionJson", loginUser.getOptionJson());
|
||||
ajax.put("optionMap", loginUser.getOptionMap());
|
||||
ajax.put("practitionerId", String.valueOf(loginUser.getPractitionerId()));
|
||||
ajax.put("user", user);
|
||||
ajax.put("roles", roles);
|
||||
ajax.put("permissions", permissions);
|
||||
ajax.put("tenantName", tenantName);
|
||||
return ajax;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
package com.core.web.controller.system;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.core.common.annotation.Log;
|
||||
import com.core.common.constant.UserConstants;
|
||||
import com.core.common.core.controller.BaseController;
|
||||
@@ -15,6 +8,12 @@ import com.core.common.core.domain.entity.SysMenu;
|
||||
import com.core.common.enums.BusinessType;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import com.core.system.service.ISysMenuService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 菜单信息
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
package com.core.web.controller.system;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.core.common.annotation.Log;
|
||||
import com.core.common.core.controller.BaseController;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.core.common.core.domain.entity.SysUser;
|
||||
import com.core.common.core.domain.model.LoginUser;
|
||||
import com.core.common.core.page.TableDataInfo;
|
||||
import com.core.common.enums.BusinessType;
|
||||
import com.core.system.domain.SysNotice;
|
||||
import com.core.system.service.ISysNoticeReadService;
|
||||
import com.core.system.service.ISysNoticeService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.core.common.annotation.Log;
|
||||
import com.core.common.core.controller.BaseController;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.core.common.core.page.TableDataInfo;
|
||||
import com.core.common.enums.BusinessType;
|
||||
import com.core.system.domain.SysNotice;
|
||||
import com.core.system.service.ISysNoticeService;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 公告 信息操作处理
|
||||
@@ -26,6 +28,9 @@ public class SysNoticeController extends BaseController {
|
||||
@Autowired
|
||||
private ISysNoticeService noticeService;
|
||||
|
||||
@Autowired
|
||||
private ISysNoticeReadService noticeReadService;
|
||||
|
||||
/**
|
||||
* 获取通知公告列表
|
||||
*/
|
||||
@@ -37,6 +42,108 @@ public class SysNoticeController extends BaseController {
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户的公告列表(公开接口)
|
||||
* 公告类型:通常 noticeType = '1' 代表通知,noticeType = '2' 代表公告
|
||||
*/
|
||||
@GetMapping("/public/list")
|
||||
public TableDataInfo getPublicList(SysNotice notice) {
|
||||
// 只查询状态为正常(0)且已发布(1)的公告
|
||||
notice.setStatus("0");
|
||||
notice.setPublishStatus("1");
|
||||
// 公告类型设置为 '2'(公告)
|
||||
notice.setNoticeType("2");
|
||||
// 设置分页参数
|
||||
startPage();
|
||||
List<SysNotice> list = noticeService.selectNoticeList(notice);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户的通知列表(公开接口)
|
||||
* 通知类型:通常 noticeType = '1' 代表通知,noticeType = '2' 代表公告
|
||||
* 返回已发布且状态正常的所有公告和通知,并标注已读状态
|
||||
* 按优先级排序,高优先级在前
|
||||
*/
|
||||
@GetMapping("/public/notice")
|
||||
public AjaxResult getUserNotices() {
|
||||
// 获取当前用户信息
|
||||
LoginUser loginUser = getLoginUser();
|
||||
SysUser currentUser = loginUser.getUser();
|
||||
|
||||
// 查询已发布且状态正常的所有公告和通知
|
||||
SysNotice notice = new SysNotice();
|
||||
notice.setStatus("0");
|
||||
notice.setPublishStatus("1");
|
||||
|
||||
List<SysNotice> list = noticeService.selectNoticeList(notice);
|
||||
|
||||
// 按优先级排序(1高 2中 3低),相同优先级按创建时间降序
|
||||
list.sort((a, b) -> {
|
||||
String priorityA = a.getPriority() != null ? a.getPriority() : "3";
|
||||
String priorityB = b.getPriority() != null ? b.getPriority() : "3";
|
||||
int priorityCompare = priorityA.compareTo(priorityB);
|
||||
if (priorityCompare != 0) {
|
||||
return priorityCompare;
|
||||
}
|
||||
// 相同优先级,按创建时间降序
|
||||
return b.getCreateTime().compareTo(a.getCreateTime());
|
||||
});
|
||||
|
||||
// 获取用户已读的公告/通知ID列表
|
||||
List<Long> readIds = noticeReadService.selectReadNoticeIdsByUserId(currentUser.getUserId());
|
||||
|
||||
// 为每个公告/通知添加已读状态
|
||||
for (SysNotice item : list) {
|
||||
boolean isRead = readIds.contains(item.getNoticeId());
|
||||
item.setIsRead(isRead);
|
||||
}
|
||||
|
||||
return success(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户未读公告/通知数量(公开接口)
|
||||
*/
|
||||
@GetMapping("/public/unread/count")
|
||||
public AjaxResult getUnreadCount() {
|
||||
LoginUser loginUser = getLoginUser();
|
||||
SysUser currentUser = loginUser.getUser();
|
||||
int count = noticeReadService.getUnreadCount(currentUser.getUserId());
|
||||
return success(count);
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记公告/通知为已读(公开接口)
|
||||
*/
|
||||
@PostMapping("/public/read/{noticeId}")
|
||||
public AjaxResult markAsRead(@PathVariable Long noticeId) {
|
||||
LoginUser loginUser = getLoginUser();
|
||||
SysUser currentUser = loginUser.getUser();
|
||||
return noticeReadService.markAsRead(noticeId, currentUser.getUserId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量标记公告/通知为已读(公开接口)
|
||||
*/
|
||||
@PostMapping("/public/read/all")
|
||||
public AjaxResult markAllAsRead(@RequestBody Long[] noticeIds) {
|
||||
LoginUser loginUser = getLoginUser();
|
||||
SysUser currentUser = loginUser.getUser();
|
||||
return noticeReadService.markAllAsRead(noticeIds, currentUser.getUserId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户已读公告/通知ID列表(公开接口)
|
||||
*/
|
||||
@GetMapping("/public/read/ids")
|
||||
public AjaxResult getReadNoticeIds() {
|
||||
LoginUser loginUser = getLoginUser();
|
||||
SysUser currentUser = loginUser.getUser();
|
||||
List<Long> readIds = noticeReadService.selectReadNoticeIdsByUserId(currentUser.getUserId());
|
||||
return success(readIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据通知公告编号获取详细信息
|
||||
*/
|
||||
@@ -54,6 +161,14 @@ public class SysNoticeController extends BaseController {
|
||||
@PostMapping
|
||||
public AjaxResult add(@Validated @RequestBody SysNotice notice) {
|
||||
notice.setCreateBy(getUsername());
|
||||
// 新建的公告默认为未发布状态
|
||||
if (notice.getPublishStatus() == null || notice.getPublishStatus().isEmpty()) {
|
||||
notice.setPublishStatus("0");
|
||||
}
|
||||
// 设置默认优先级为中(2)
|
||||
if (notice.getPriority() == null || notice.getPriority().isEmpty()) {
|
||||
notice.setPriority("2");
|
||||
}
|
||||
return toAjax(noticeService.insertNotice(notice));
|
||||
}
|
||||
|
||||
@@ -77,4 +192,42 @@ public class SysNoticeController extends BaseController {
|
||||
public AjaxResult remove(@PathVariable Long[] noticeIds) {
|
||||
return toAjax(noticeService.deleteNoticeByIds(noticeIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布公告/通知
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:notice:edit')")
|
||||
@Log(title = "发布公告", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/publish/{noticeId}")
|
||||
public AjaxResult publish(@PathVariable Long noticeId) {
|
||||
SysNotice notice = noticeService.selectNoticeById(noticeId);
|
||||
if (notice == null) {
|
||||
return error("公告不存在");
|
||||
}
|
||||
if ("1".equals(notice.getPublishStatus())) {
|
||||
return error("该公告已发布");
|
||||
}
|
||||
notice.setPublishStatus("1");
|
||||
notice.setUpdateBy(getUsername());
|
||||
return toAjax(noticeService.updateNotice(notice));
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消发布公告/通知
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:notice:edit')")
|
||||
@Log(title = "取消发布", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/unpublish/{noticeId}")
|
||||
public AjaxResult unpublish(@PathVariable Long noticeId) {
|
||||
SysNotice notice = noticeService.selectNoticeById(noticeId);
|
||||
if (notice == null) {
|
||||
return error("公告不存在");
|
||||
}
|
||||
if ("0".equals(notice.getPublishStatus())) {
|
||||
return error("该公告未发布");
|
||||
}
|
||||
notice.setPublishStatus("0");
|
||||
notice.setUpdateBy(getUsername());
|
||||
return toAjax(noticeService.updateNotice(notice));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
package com.core.web.controller.system;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.core.common.annotation.Log;
|
||||
import com.core.common.core.controller.BaseController;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
@@ -17,6 +8,13 @@ import com.core.common.enums.BusinessType;
|
||||
import com.core.common.utils.poi.ExcelUtil;
|
||||
import com.core.system.domain.SysPost;
|
||||
import com.core.system.service.ISysPostService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 岗位信息操作处理
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
package com.core.web.controller.system;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import com.core.common.annotation.Log;
|
||||
import com.core.common.config.CoreConfig;
|
||||
import com.core.common.core.controller.BaseController;
|
||||
@@ -17,6 +13,9 @@ import com.core.common.utils.file.FileUploadUtils;
|
||||
import com.core.common.utils.file.MimeTypeUtils;
|
||||
import com.core.framework.web.service.TokenService;
|
||||
import com.core.system.service.ISysUserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 个人信息 业务处理
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package com.core.web.controller.system;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.core.common.core.controller.BaseController;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.core.common.core.domain.model.RegisterBody;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import com.core.framework.web.service.SysRegisterService;
|
||||
import com.core.system.service.ISysConfigService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 注册验证
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
package com.core.web.controller.system;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.core.common.annotation.Log;
|
||||
import com.core.common.core.controller.BaseController;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
@@ -26,6 +17,13 @@ import com.core.system.domain.SysUserRole;
|
||||
import com.core.system.service.ISysDeptService;
|
||||
import com.core.system.service.ISysRoleService;
|
||||
import com.core.system.service.ISysUserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色信息
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
package com.core.web.controller.system;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.core.common.annotation.Anonymous;
|
||||
import com.core.common.core.controller.BaseController;
|
||||
@@ -13,6 +7,11 @@ import com.core.common.core.domain.R;
|
||||
import com.core.common.core.domain.entity.SysUser;
|
||||
import com.core.system.domain.SysTenant;
|
||||
import com.core.system.service.ISysTenantService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 租户信息controller
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package com.core.web.controller.system;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.core.common.core.controller.BaseController;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.core.system.domain.dto.SaveTenantOptionDetailDto;
|
||||
import com.core.system.domain.dto.TenantOptionDto;
|
||||
import com.core.system.service.ISysTenantOptionService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 租户配置项信息controller
|
||||
|
||||
@@ -1,17 +1,5 @@
|
||||
package com.core.web.controller.system;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import com.core.common.annotation.Log;
|
||||
import com.core.common.core.controller.BaseController;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
@@ -27,6 +15,16 @@ import com.core.system.service.ISysDeptService;
|
||||
import com.core.system.service.ISysPostService;
|
||||
import com.core.system.service.ISysRoleService;
|
||||
import com.core.system.service.ISysUserService;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
package com.core.web.controller.tool;
|
||||
|
||||
import com.core.common.core.controller.BaseController;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import io.swagger.annotations.*;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.core.common.core.controller.BaseController;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.core.common.utils.StringUtils;
|
||||
|
||||
import io.swagger.annotations.*;
|
||||
|
||||
/**
|
||||
* swagger 用户测试方法
|
||||
*
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
package com.core.web.core.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.core.common.config.CoreConfig;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.models.auth.In;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import com.core.common.config.CoreConfig;
|
||||
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.models.auth.In;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
@@ -20,6 +15,9 @@ import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spi.service.contexts.SecurityContext;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Swagger2的接口配置
|
||||
*
|
||||
|
||||
@@ -16,6 +16,31 @@
|
||||
common通用工具
|
||||
</description>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<configuration>
|
||||
<source>17</source>
|
||||
<target>17</target>
|
||||
<encoding>UTF-8</encoding>
|
||||
<compilerArgs>
|
||||
<arg>-parameters</arg>
|
||||
</compilerArgs>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.34</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- mybatis-plus 增强CRUD -->
|
||||
@@ -54,6 +79,12 @@
|
||||
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- jsr250 annotations -->
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 自定义验证注解 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.core.common.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
import com.core.common.enums.DataSourceType;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 自定义多数据源切换注解
|
||||
*
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package com.core.common.annotation;
|
||||
|
||||
import com.core.common.utils.poi.ExcelHandlerAdapter;
|
||||
import org.apache.poi.ss.usermodel.HorizontalAlignment;
|
||||
import org.apache.poi.ss.usermodel.IndexedColors;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.apache.poi.ss.usermodel.HorizontalAlignment;
|
||||
import org.apache.poi.ss.usermodel.IndexedColors;
|
||||
|
||||
import com.core.common.utils.poi.ExcelHandlerAdapter;
|
||||
|
||||
/**
|
||||
* 自定义导出Excel数据注解
|
||||
*
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.core.common.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
import com.core.common.enums.BusinessType;
|
||||
import com.core.common.enums.OperatorType;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 自定义操作日志记录注解
|
||||
*
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.core.common.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
import com.core.common.constant.CacheConstants;
|
||||
import com.core.common.enums.LimitType;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 限流注解
|
||||
*
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package com.core.common.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import com.core.common.config.serializer.SensitiveJsonSerializer;
|
||||
import com.core.common.enums.DesensitizedType;
|
||||
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 数据脱敏注解
|
||||
*
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package com.core.common.config.serializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.core.common.annotation.Sensitive;
|
||||
import com.core.common.core.domain.model.LoginUser;
|
||||
import com.core.common.enums.DesensitizedType;
|
||||
@@ -14,6 +11,9 @@ import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 数据脱敏序列化过滤
|
||||
*
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.core.common.constant;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* 通用常量信息
|
||||
*
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
package com.core.common.core.controller;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.annotation.InitBinder;
|
||||
|
||||
import com.core.common.constant.HttpStatus;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.core.common.core.domain.model.LoginUser;
|
||||
@@ -22,6 +13,14 @@ import com.core.common.utils.StringUtils;
|
||||
import com.core.common.utils.sql.SqlUtil;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.annotation.InitBinder;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* web层通用数据处理
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.core.common.core.domain;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.core.common.constant.HttpStatus;
|
||||
import com.core.common.utils.StringUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 操作消息提醒
|
||||
*
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package com.core.common.core.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Entity基类
|
||||
*
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package com.core.common.core.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Entity基类
|
||||
*
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.core.common.core.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.core.common.constant.HttpStatus;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 响应信息主体
|
||||
*
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package com.core.common.core.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.core.common.core.domain.entity.SysDept;
|
||||
import com.core.common.core.domain.entity.SysMenu;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Treeselect树结构实体类
|
||||
*
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
package com.core.common.core.domain.entity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.core.common.core.domain.BaseEntity;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import javax.validation.constraints.Email;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import com.core.common.core.domain.BaseEntity;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 部门表 sys_dept
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
package com.core.common.core.domain.entity;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import com.core.common.annotation.Excel;
|
||||
import com.core.common.annotation.Excel.ColumnType;
|
||||
import com.core.common.constant.UserConstants;
|
||||
import com.core.common.core.domain.BaseEntity;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
/**
|
||||
* 字典数据表 sys_dict_data
|
||||
@@ -53,6 +52,9 @@ public class SysDictData extends BaseEntity {
|
||||
@Excel(name = "状态", readConverterExp = "0=正常,1=停用")
|
||||
private String status;
|
||||
|
||||
/** 拼音首字母 */
|
||||
private String pyStr;
|
||||
|
||||
public Long getDictCode() {
|
||||
return dictCode;
|
||||
}
|
||||
@@ -136,13 +138,21 @@ public class SysDictData extends BaseEntity {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getPyStr() {
|
||||
return pyStr;
|
||||
}
|
||||
|
||||
public void setPyStr(String pyStr) {
|
||||
this.pyStr = pyStr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).append("dictCode", getDictCode())
|
||||
.append("dictSort", getDictSort()).append("dictLabel", getDictLabel()).append("dictValue", getDictValue())
|
||||
.append("dictType", getDictType()).append("cssClass", getCssClass()).append("listClass", getListClass())
|
||||
.append("isDefault", getIsDefault()).append("status", getStatus()).append("createBy", getCreateBy())
|
||||
.append("createTime", getCreateTime()).append("updateBy", getUpdateBy())
|
||||
.append("isDefault", getIsDefault()).append("status", getStatus()).append("pyStr", getPyStr())
|
||||
.append("createBy", getCreateBy()).append("createTime", getCreateTime()).append("updateBy", getUpdateBy())
|
||||
.append("updateTime", getUpdateTime()).append("remark", getRemark()).toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
package com.core.common.core.domain.entity;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Pattern;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import com.core.common.annotation.Excel;
|
||||
import com.core.common.annotation.Excel.ColumnType;
|
||||
import com.core.common.core.domain.BaseEntity;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Pattern;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
/**
|
||||
* 字典类型表 sys_dict_type
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
package com.core.common.core.domain.entity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.core.common.core.domain.BaseEntity;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import com.core.common.core.domain.BaseEntity;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 菜单权限表 sys_menu
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
package com.core.common.core.domain.entity;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import com.core.common.annotation.Excel;
|
||||
import com.core.common.annotation.Excel.ColumnType;
|
||||
import com.core.common.core.domain.BaseEntity;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 角色表 sys_role
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
package com.core.common.core.domain.entity;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.validation.constraints.Email;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.core.common.annotation.Excel;
|
||||
import com.core.common.annotation.Excel.ColumnType;
|
||||
import com.core.common.annotation.Excel.Type;
|
||||
@@ -19,8 +11,15 @@ import com.core.common.core.domain.BaseEntity;
|
||||
import com.core.common.xss.Xss;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import javax.validation.constraints.Email;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户对象 sys_user
|
||||
@@ -32,6 +31,7 @@ public class SysUser extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 用户ID */
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@Excel(name = "用户序号", type = Type.EXPORT, cellType = ColumnType.NUMERIC, prompt = "用户编号")
|
||||
private Long userId;
|
||||
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
package com.core.common.core.domain.model;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import com.core.common.core.domain.entity.SysRole;
|
||||
import com.core.common.core.domain.entity.SysUser;
|
||||
import lombok.Data;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.core.common.core.domain.entity.SysRole;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.alibaba.fastjson2.annotation.JSONField;
|
||||
import com.core.common.core.domain.entity.SysUser;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 登录用户身份权限
|
||||
*
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
package com.core.common.core.redis;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.core.common.exception.UtilException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.*;
|
||||
import org.springframework.data.redis.core.BoundSetOperations;
|
||||
import org.springframework.data.redis.core.HashOperations;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.ValueOperations;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* spring redis 工具类
|
||||
*
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.core.common.core.text;
|
||||
|
||||
import com.core.common.utils.StringUtils;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import com.core.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 字符集工具类
|
||||
*
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.core.common.core.text;
|
||||
|
||||
import com.core.common.utils.StringUtils;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.math.RoundingMode;
|
||||
@@ -8,10 +11,6 @@ import java.nio.charset.Charset;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import com.core.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 类型转换器
|
||||
*
|
||||
|
||||
@@ -33,10 +33,23 @@ public enum DelFlag {
|
||||
return null;
|
||||
}
|
||||
for (DelFlag val : values()) {
|
||||
if (val.getValue().equals(value)) {
|
||||
if (val.value.equals(value)) {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// 手动添加 getter 方法以解决 Lombok 兼容性问题
|
||||
public Integer getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getInfo() {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.core.common.enums;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.core.common.utils.DesensitizedUtil;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* 脱敏类型
|
||||
*
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.core.common.enums;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* 请求方式
|
||||
*
|
||||
|
||||
@@ -11,7 +11,6 @@ public enum TenantOptionDict {
|
||||
* 医院名称
|
||||
*/
|
||||
YB_HOSPITAL_NAME("hospitalName", "医保-医院名称", 0),
|
||||
|
||||
/**
|
||||
* 医保-医疗机构等级(3101接口)
|
||||
*/
|
||||
@@ -24,37 +23,30 @@ public enum TenantOptionDict {
|
||||
* 电子发票appid
|
||||
*/
|
||||
EINVOICE_APP_ID("app_id", "电子发票-appid", 3),
|
||||
|
||||
/**
|
||||
* 电子发票key
|
||||
*/
|
||||
EINVOICE_KEY("key", "电子发票-key", 4),
|
||||
|
||||
/**
|
||||
* 电子发票url
|
||||
*/
|
||||
EINVOICE_URL("url", "电子发票-url", 5),
|
||||
|
||||
/**
|
||||
* 医保开关
|
||||
*/
|
||||
YB_SWITCH("yb_switch", "医保开关", 6),
|
||||
|
||||
/**
|
||||
* 电子地址
|
||||
*/
|
||||
ELE_ADDRESS("eleAddress", "电子处方-请求地址", 22),
|
||||
|
||||
/**
|
||||
* 服务地址
|
||||
*/
|
||||
ADDRESS("address", "服务地址", 23),
|
||||
|
||||
/**
|
||||
* 超时时间
|
||||
*/
|
||||
TIME("time", "超时时间", 24),
|
||||
|
||||
/**
|
||||
* 是否加密
|
||||
*/
|
||||
@@ -63,32 +55,26 @@ public enum TenantOptionDict {
|
||||
* 医保区划
|
||||
*/
|
||||
YB_INSUPLC_ADMDVS("insuplc_admdvs", "医保-区划", 26),
|
||||
|
||||
/**
|
||||
* 电子处方appId
|
||||
*/
|
||||
ELE_PRE_APP_ID("pre_app_id", "电子处方-appId", 27),
|
||||
|
||||
/**
|
||||
* 电子处方appSecret
|
||||
*/
|
||||
ELE_PRE_APP_SECRET("pre_app_secret", "电子处方-appSecret", 28),
|
||||
|
||||
/**
|
||||
* 电子处方私钥
|
||||
*/
|
||||
ELE_APP_PRVKEY("APP_PRVKEY", "电子处方-私钥", 29),
|
||||
|
||||
/**
|
||||
* 电子处方公钥
|
||||
*/
|
||||
ELE_PLAF_PUBKEY("PLAF_PUBKEY", "电子处方-公钥", 30),
|
||||
|
||||
/**
|
||||
* 医院等级
|
||||
*/
|
||||
EINVOICE_HOSPITAL_LV("hospital_lv", "电子发票-医院等级", 39),
|
||||
|
||||
/**
|
||||
* 无视LIS&PACS报错
|
||||
*/
|
||||
@@ -161,12 +147,10 @@ public enum TenantOptionDict {
|
||||
* 电子发票开关
|
||||
*/
|
||||
INVOICE_SWITCH("invoiceSwitch", "电子发票开关", 56),
|
||||
|
||||
/**
|
||||
* 医嘱定价来源
|
||||
*/
|
||||
ORDER_PRICING_SOURCE("orderPricingSource", "定价来源 batchSellingPrice/retailPrice", 57),
|
||||
|
||||
/**
|
||||
* 三方支付(签到)
|
||||
*/
|
||||
@@ -199,7 +183,6 @@ public enum TenantOptionDict {
|
||||
* 三方支付(消费)
|
||||
*/
|
||||
THREE_PART_PAY_MAPPING_METHOD("threePartPayMappingMethod", "三方支付【消费】请求方式", 65),
|
||||
|
||||
/**
|
||||
* 三方支付(退费)
|
||||
*/
|
||||
@@ -216,7 +199,6 @@ public enum TenantOptionDict {
|
||||
* 三方支付(退费)
|
||||
*/
|
||||
THREE_PART_RETURN_MAPPING_METHOD("threePartReturnMappingMethod", "三方支付【退费】请求方式", 69),
|
||||
|
||||
/**
|
||||
* 三方支付(隔天退费)
|
||||
*/
|
||||
@@ -233,7 +215,6 @@ public enum TenantOptionDict {
|
||||
* 三方支付(隔天退费)
|
||||
*/
|
||||
THREE_PART_NEXT_DAY_RETURN_MAPPING_METHOD("threePartNextDayReturnMappingMethod", "三方支付【隔天退费】请求方式", 73),
|
||||
|
||||
/**
|
||||
* 三方支付路径(支付结果查询)
|
||||
*/
|
||||
@@ -250,7 +231,6 @@ public enum TenantOptionDict {
|
||||
* 三方支付(支付结果查询)
|
||||
*/
|
||||
THREE_PART_PAY_QUERY_MAPPING_METHOD("threePartPayQueryMappingMethod", "三方支付【支付结果查询】请求方式", 77),
|
||||
|
||||
/**
|
||||
* 三方支付路径(退费结果查询)
|
||||
*/
|
||||
@@ -267,7 +247,6 @@ public enum TenantOptionDict {
|
||||
* 三方支付(退费结果查询)
|
||||
*/
|
||||
THREE_PART_RETURN_QUERY_MAPPING_METHOD("threePartReturnQueryMappingMethod", "三方支付【退费结果查询】请求方式", 81),
|
||||
|
||||
/**
|
||||
* 三方支付路径(隔天退费结果查询)
|
||||
*/
|
||||
@@ -284,8 +263,7 @@ public enum TenantOptionDict {
|
||||
* 三方支付(隔天退费结果查询)
|
||||
*/
|
||||
THREE_PART_NEXT_DAY_RETURN_QUERY_MAPPING_METHOD("threePartNextDayReturnQueryMappingMethod", "三方支付【隔天退费结果查询】请求方式",
|
||||
85),
|
||||
|
||||
85),
|
||||
/**
|
||||
* 三方支付(签出)
|
||||
*/
|
||||
@@ -302,27 +280,22 @@ public enum TenantOptionDict {
|
||||
* 三方支付(签出)
|
||||
*/
|
||||
THREE_PART_SIGN_OUT_MAPPING_METHOD("threePartSignOutMappingMethod", "三方支付【签出】请求方式", 89),
|
||||
|
||||
/**
|
||||
* 三方支付(签出)
|
||||
*/
|
||||
YB_INPATIENT_SETTLEMENT_UP_URL("ybInpatientSetlUp", "选填4101或4101A", 90),
|
||||
|
||||
/**
|
||||
* PACS查看报告地址
|
||||
*/
|
||||
PACS_REPORT_URL("pacsReportUrl", "PACS查看报告地址", 91),
|
||||
|
||||
/**
|
||||
* LIS查看报告地址
|
||||
*/
|
||||
LIS_REPORT_URL("lisReportUrl", "LIS查看报告地址", 92),
|
||||
|
||||
/**
|
||||
* 开药时药房允许多选开关
|
||||
*/
|
||||
PHARMACY_MULTIPLE_CHOICE_SWITCH("pharmacyMultipleChoiceSwitch", "开药时药房允许多选开关", 93),
|
||||
|
||||
/**
|
||||
* PEIS服务地址
|
||||
*/
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
package com.core.common.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import com.core.common.utils.StringUtils;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Repeatable 过滤器
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
package com.core.common.filter;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import com.core.common.constant.Constants;
|
||||
import com.core.common.utils.http.HttpHelper;
|
||||
|
||||
import javax.servlet.ReadListener;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
|
||||
import com.core.common.constant.Constants;
|
||||
import com.core.common.utils.http.HttpHelper;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
/**
|
||||
* 构建可重复读取inputStream的request
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
package com.core.common.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.core.common.enums.HttpMethod;
|
||||
import com.core.common.utils.StringUtils;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.core.common.enums.HttpMethod;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 防止XSS攻击的过滤器
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
package com.core.common.filter;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import com.core.common.utils.html.EscapeUtil;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import javax.servlet.ReadListener;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import com.core.common.utils.StringUtils;
|
||||
import com.core.common.utils.html.EscapeUtil;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* XSS过滤处理
|
||||
|
||||
@@ -37,6 +37,10 @@ public final class AgeCalculatorUtil {
|
||||
* 当前年龄取得(床位列表表示年龄用)
|
||||
*/
|
||||
public static String getAge(Date date) {
|
||||
// 添加空值检查
|
||||
if (date == null) {
|
||||
return "";
|
||||
}
|
||||
// 将 Date 转换为 LocalDateTime
|
||||
LocalDateTime dateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
@@ -3,16 +3,15 @@
|
||||
*/
|
||||
package com.core.common.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.core.common.constant.CacheConstants;
|
||||
import com.core.common.core.redis.RedisCache;
|
||||
import com.core.common.exception.UtilException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.core.common.constant.CacheConstants;
|
||||
import com.core.common.core.redis.RedisCache;
|
||||
import com.core.common.exception.UtilException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 排番组件
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.core.common.utils;
|
||||
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
@@ -9,8 +11,6 @@ import java.time.format.DateTimeParseException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
|
||||
/**
|
||||
* 时间工具类
|
||||
*
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package com.core.common.utils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.core.common.constant.CacheConstants;
|
||||
import com.core.common.core.domain.entity.SysDictData;
|
||||
import com.core.common.core.redis.RedisCache;
|
||||
import com.core.common.utils.spring.SpringUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 字典工具类
|
||||
*
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.core.common.utils;
|
||||
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
|
||||
/**
|
||||
* 错误信息处理类。
|
||||
*
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package com.core.common.utils;
|
||||
|
||||
import com.core.common.utils.spring.SpringUtils;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
|
||||
import com.core.common.utils.spring.SpringUtils;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
package com.core.common.utils;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.DecimalFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.core.common.annotation.Excel;
|
||||
import com.core.common.annotation.Excel.ColumnType;
|
||||
import com.core.common.annotation.Excel.Type;
|
||||
import com.core.common.annotation.ExcelExtra;
|
||||
import com.core.common.annotation.Excels;
|
||||
import com.core.common.config.CoreConfig;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.core.common.core.text.Convert;
|
||||
import com.core.common.exception.UtilException;
|
||||
import com.core.common.utils.file.FileTypeUtils;
|
||||
import com.core.common.utils.file.FileUtils;
|
||||
import com.core.common.utils.file.ImageUtils;
|
||||
import com.core.common.utils.poi.ExcelHandlerAdapter;
|
||||
import com.core.common.utils.reflect.ReflectUtils;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.RegExUtils;
|
||||
import org.apache.commons.lang3.reflect.FieldUtils;
|
||||
@@ -29,20 +30,17 @@ import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.core.common.annotation.Excel;
|
||||
import com.core.common.annotation.Excel.ColumnType;
|
||||
import com.core.common.annotation.Excel.Type;
|
||||
import com.core.common.annotation.ExcelExtra;
|
||||
import com.core.common.annotation.Excels;
|
||||
import com.core.common.config.CoreConfig;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.core.common.core.text.Convert;
|
||||
import com.core.common.exception.UtilException;
|
||||
import com.core.common.utils.file.FileTypeUtils;
|
||||
import com.core.common.utils.file.FileUtils;
|
||||
import com.core.common.utils.file.ImageUtils;
|
||||
import com.core.common.utils.poi.ExcelHandlerAdapter;
|
||||
import com.core.common.utils.reflect.ReflectUtils;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.DecimalFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Excel相关处理
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
package com.core.common.utils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.util.PatternMatchUtils;
|
||||
|
||||
import com.core.common.constant.Constants;
|
||||
import com.core.common.constant.HttpStatus;
|
||||
import com.core.common.core.domain.entity.SysRole;
|
||||
import com.core.common.core.domain.model.LoginUser;
|
||||
import com.core.common.exception.ServiceException;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.util.PatternMatchUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 安全服务工具类
|
||||
@@ -77,6 +76,25 @@ public class SecurityUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全获取用户名(失败时返回默认值)
|
||||
**/
|
||||
public static String getUsernameSafe() {
|
||||
try {
|
||||
Authentication authentication = getAuthentication();
|
||||
if (authentication != null && authentication.getPrincipal() != null) {
|
||||
if (authentication.getPrincipal() instanceof LoginUser) {
|
||||
return ((LoginUser) authentication.getPrincipal()).getUsername();
|
||||
} else {
|
||||
return authentication.getPrincipal().toString();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 静默处理异常,返回默认值
|
||||
}
|
||||
return "anonymous";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Authentication
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
package com.core.common.utils;
|
||||
|
||||
import com.core.common.constant.Constants;
|
||||
import com.core.common.core.text.Convert;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
@@ -8,18 +18,6 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import com.core.common.constant.Constants;
|
||||
import com.core.common.core.text.Convert;
|
||||
|
||||
/**
|
||||
* 客户端工具类
|
||||
*
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package com.core.common.utils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
|
||||
import com.core.common.constant.Constants;
|
||||
import com.core.common.core.text.StrFormatter;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 字符串工具类
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.core.common.utils;
|
||||
|
||||
import java.util.concurrent.*;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
* 线程相关工具类.
|
||||
*
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
package com.core.common.utils;
|
||||
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.*;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package com.core.common.utils.bean;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.ConstraintViolationException;
|
||||
import javax.validation.Validator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* bean对象属性验证
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.core.common.utils.file;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 文件类型工具类
|
||||
*
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
package com.core.common.utils.file;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import com.core.common.config.CoreConfig;
|
||||
import com.core.common.constant.Constants;
|
||||
import com.core.common.exception.file.FileNameLengthLimitExceededException;
|
||||
@@ -16,6 +8,13 @@ import com.core.common.exception.file.InvalidExtensionException;
|
||||
import com.core.common.utils.DateUtils;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import com.core.common.utils.uuid.Seq;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 文件上传工具类
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
package com.core.common.utils.file;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import com.core.common.config.CoreConfig;
|
||||
import com.core.common.utils.DateUtils;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import com.core.common.utils.uuid.IdUtils;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* 文件处理工具类
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
package com.core.common.utils.file;
|
||||
|
||||
import com.core.common.config.CoreConfig;
|
||||
import com.core.common.constant.Constants;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
@@ -7,14 +14,6 @@ import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.core.common.config.CoreConfig;
|
||||
import com.core.common.constant.Constants;
|
||||
import com.core.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 图片处理工具类
|
||||
*
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
package com.core.common.utils.http;
|
||||
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* 通用http工具封装
|
||||
*
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
package com.core.common.utils.http;
|
||||
|
||||
import com.core.common.constant.Constants;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.io.*;
|
||||
import java.net.ConnectException;
|
||||
import java.net.SocketTimeoutException;
|
||||
@@ -8,14 +14,6 @@ import java.net.URLConnection;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.core.common.constant.Constants;
|
||||
import com.core.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 通用http发送方法
|
||||
*
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
package com.core.common.utils.ip;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.core.common.config.CoreConfig;
|
||||
import com.core.common.constant.Constants;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import com.core.common.utils.http.HttpUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* 获取地址类
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user