Compare commits
115 Commits
6c36ae5340
...
test
| Author | SHA1 | Date | |
|---|---|---|---|
| d7b3403524 | |||
|
|
e9d4f57815 | ||
| e573d9f68b | |||
| 2584c8f076 | |||
| 7b6c972a12 | |||
|
|
c3f1b105e9 | ||
| 616c2d21a6 | |||
| 63a9e26abf | |||
|
|
d2dfc714ec | ||
|
|
5c8bfbc98b | ||
|
|
885a147420 | ||
|
|
afbf3f9075 | ||
|
|
720cac8a8f | ||
| 5497c99f0c | |||
|
|
d8b4aed16c | ||
| efc97c855c | |||
|
|
0c5353cf8b | ||
|
|
8a84b40ee5 | ||
| f6b39a4815 | |||
|
|
1b3d4e3dc0 | ||
|
|
cb46461ede | ||
| 3b0a359412 | |||
| 6fa26e895d | |||
| 8ab8691c17 | |||
|
|
35b8a7d10a | ||
| 22de02f132 | |||
| 11244aa48f | |||
| 0a5f26e9c0 | |||
| 4a8e9b5a22 | |||
| bfb2491842 | |||
|
|
b747f80507 | ||
| ced931a280 | |||
| b497eb853c | |||
| 7a2342ea2e | |||
|
|
09fdfa294a | ||
|
|
4ef9aa07d2 | ||
| 08085403b3 | |||
| 2d7dcb4aeb | |||
| ad29502488 | |||
| 5b0acede89 | |||
| ac1cd3afc8 | |||
|
|
8a863b4ecb | ||
|
|
882d63249c | ||
|
|
6315ca5658 | ||
|
|
9f802b67f0 | ||
| 6694ae52ba | |||
| 9491ceaa5d | |||
| db9a70a99d | |||
|
|
9105e687d6 | ||
| b1d6c6008e | |||
| 6b9f9a107e | |||
| 11a7f49162 | |||
| b4e5061b73 | |||
| f5a1ad7f3f | |||
| eeac88b1d1 | |||
| 1ab9b020c1 | |||
| 3055518d2b | |||
| 9f619ccdd4 | |||
| df78ff29bd | |||
| 4d13acacc2 | |||
| 67573c1d9d | |||
| b27d8a6703 | |||
| 6f3d4272e6 | |||
| 6e5315fdd6 | |||
| 544d7ee95c | |||
| 7f7f7d69f7 | |||
|
|
ae9a96822e | ||
| bbef0322a3 | |||
| a8a205aa48 | |||
| c052ea7c39 | |||
| 6accaa35c9 | |||
| 466e7296fa | |||
|
|
5678535d88 | ||
| b7993885bb | |||
| 3b8ef380ae | |||
|
|
2334a27467 | ||
|
|
92511c2777 | ||
| 64b02466b1 | |||
| 2ffbe73305 | |||
| 48d3941701 | |||
| 0ad1889029 | |||
| 7dc98dcf84 | |||
| 681fb695bd | |||
| 518d8385e6 | |||
|
|
7073ef0be0 | ||
| 2288162ad7 | |||
| 6f701d7fa6 | |||
| 34253f88b2 | |||
|
|
488c311788 | ||
|
|
b5527cc07f | ||
| 6d23d36a9c | |||
|
|
e2e5999276 | ||
|
|
112ec2e4a3 | ||
| 4b92be10b4 | |||
| 0b361df0a4 | |||
| 3a242074ff | |||
|
|
353f267488 | ||
|
|
2d705d2f81 | ||
| 184871e84f | |||
| ffcdaed087 | |||
| 91a0b48662 | |||
| c509a804ec | |||
| 1a7b6c0cd4 | |||
|
|
11cf88fd49 | ||
| 3f0fa3bbb3 | |||
| d7c15848f0 | |||
|
|
188b907907 | ||
| 71e3601d51 | |||
| f04c3d112c | |||
| 8739959be0 | |||
| 24bc049fa0 | |||
| b42cffdd8a | |||
| 927691a27b | |||
| 700e353b79 | |||
| 0b2c19d2c5 |
23
.playwright-mcp/page-2026-03-31T08-16-50-178Z.yml
Normal file
23
.playwright-mcp/page-2026-03-31T08-16-50-178Z.yml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
- generic [ref=e5]:
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- img [ref=e7]
|
||||||
|
- img [ref=e8]
|
||||||
|
- generic [ref=e9]:
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- heading "经创贺联项目管理系统" [level=2] [ref=e11]
|
||||||
|
- generic [ref=e12]: 简体
|
||||||
|
- generic [ref=e13]:
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e16]: 用户名
|
||||||
|
- textbox [active] [ref=e17]
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e20]: 密码
|
||||||
|
- textbox [ref=e21]
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e24]:
|
||||||
|
- checkbox "保持登录" [ref=e25]
|
||||||
|
- generic [ref=e26] [cursor=pointer]: 保持登录
|
||||||
|
- link "忘记密码" [ref=e27] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=user&f=reset
|
||||||
|
- button "登录" [ref=e29] [cursor=pointer]:
|
||||||
|
- generic [ref=e30]: 登录
|
||||||
91
.playwright-mcp/page-2026-03-31T08-17-18-473Z.yml
Normal file
91
.playwright-mcp/page-2026-03-31T08-17-18-473Z.yml
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic [ref=e1]:
|
||||||
|
- generic [ref=e2]:
|
||||||
|
- list [ref=e3]:
|
||||||
|
- listitem [ref=e4]:
|
||||||
|
- link " 地盘" [ref=e5] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=index
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- generic [ref=e7]: 地盘
|
||||||
|
- listitem [ref=e8]:
|
||||||
|
- link " 项目集" [ref=e9] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=program&f=browse
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- generic [ref=e11]: 项目集
|
||||||
|
- listitem [ref=e12]:
|
||||||
|
- link " 产品" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=product&f=all
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e15]: 产品
|
||||||
|
- listitem [ref=e16]:
|
||||||
|
- link " 项目" [ref=e17] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=browse
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e19]: 项目
|
||||||
|
- listitem [ref=e20]:
|
||||||
|
- link " 执行" [ref=e21] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=execution&f=task
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: 执行
|
||||||
|
- listitem [ref=e24]:
|
||||||
|
- link " 测试" [ref=e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- generic [ref=e27]: 测试
|
||||||
|
- listitem [ref=e28]:
|
||||||
|
- link " DevOps" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=repo&f=maintain
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]: DevOps
|
||||||
|
- listitem [ref=e32]
|
||||||
|
- listitem [ref=e33]:
|
||||||
|
- link " AI" [ref=e34] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=aiapp&f=square
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]: AI
|
||||||
|
- listitem [ref=e37]:
|
||||||
|
- link " BI" [ref=e38] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=screen&f=browse
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e40]: BI
|
||||||
|
- listitem [ref=e41]
|
||||||
|
- listitem [ref=e42]:
|
||||||
|
- link " 看板" [ref=e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=kanban&f=space
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- generic [ref=e45]: 看板
|
||||||
|
- listitem [ref=e46]:
|
||||||
|
- link " 文档" [ref=e47] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=doc&f=lastViewedSpace
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]: 文档
|
||||||
|
- listitem [ref=e50]
|
||||||
|
- listitem [ref=e51]:
|
||||||
|
- link " 组织" [ref=e52] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=team
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- generic [ref=e54]: 组织
|
||||||
|
- listitem [ref=e55]:
|
||||||
|
- link " 后台" [ref=e56] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=admin&f=index
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e58]: 后台
|
||||||
|
- text:
|
||||||
|
- list [ref=e60]:
|
||||||
|
- listitem [ref=e61]:
|
||||||
|
- generic [ref=e63] [cursor=pointer]:
|
||||||
|
- generic [ref=e65]:
|
||||||
|
- button " 研发综合界面" [ref=e67] [cursor=pointer]:
|
||||||
|
- generic [ref=e68]:
|
||||||
|
- generic [ref=e69]: 研发综合界面
|
||||||
|
- list
|
||||||
|
- generic [ref=e71]:
|
||||||
|
- button [ref=e73] [cursor=pointer]:
|
||||||
|
- img [ref=e75]
|
||||||
|
- link " 开源版21.7" [ref=e76] [cursor=pointer]:
|
||||||
|
- /url: https://www.zentao.net
|
||||||
|
- generic [ref=e77]:
|
||||||
|
- generic [ref=e78]: 开源版21.7
|
||||||
|
- button "升级 " [ref=e79] [cursor=pointer]:
|
||||||
|
- generic [ref=e80]: 升级
|
||||||
|
- generic [ref=e81]:
|
||||||
91
.playwright-mcp/page-2026-03-31T08-17-24-726Z.yml
Normal file
91
.playwright-mcp/page-2026-03-31T08-17-24-726Z.yml
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic [ref=e1]:
|
||||||
|
- generic [ref=e2]:
|
||||||
|
- list [ref=e3]:
|
||||||
|
- listitem [ref=e4]:
|
||||||
|
- link " 地盘" [ref=e5] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=index
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- generic [ref=e7]: 地盘
|
||||||
|
- listitem [ref=e8]:
|
||||||
|
- link " 项目集" [ref=e9] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=program&f=browse
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- generic [ref=e11]: 项目集
|
||||||
|
- listitem [ref=e12]:
|
||||||
|
- link " 产品" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=product&f=all
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e15]: 产品
|
||||||
|
- listitem [ref=e16]:
|
||||||
|
- link " 项目" [ref=e17] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=browse
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e19]: 项目
|
||||||
|
- listitem [ref=e20]:
|
||||||
|
- link " 执行" [ref=e21] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=execution&f=task
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: 执行
|
||||||
|
- listitem [ref=e24]:
|
||||||
|
- link " 测试" [ref=e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- generic [ref=e27]: 测试
|
||||||
|
- listitem [ref=e28]:
|
||||||
|
- link " DevOps" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=repo&f=maintain
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]: DevOps
|
||||||
|
- listitem [ref=e32]
|
||||||
|
- listitem [ref=e33]:
|
||||||
|
- link " AI" [ref=e34] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=aiapp&f=square
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]: AI
|
||||||
|
- listitem [ref=e37]:
|
||||||
|
- link " BI" [ref=e38] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=screen&f=browse
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e40]: BI
|
||||||
|
- listitem [ref=e41]
|
||||||
|
- listitem [ref=e42]:
|
||||||
|
- link " 看板" [ref=e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=kanban&f=space
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- generic [ref=e45]: 看板
|
||||||
|
- listitem [ref=e46]:
|
||||||
|
- link " 文档" [ref=e47] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=doc&f=lastViewedSpace
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]: 文档
|
||||||
|
- listitem [ref=e50]
|
||||||
|
- listitem [ref=e51]:
|
||||||
|
- link " 组织" [ref=e52] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=team
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- generic [ref=e54]: 组织
|
||||||
|
- listitem [ref=e55]:
|
||||||
|
- link " 后台" [ref=e56] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=admin&f=index
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e58]: 后台
|
||||||
|
- text:
|
||||||
|
- list [ref=e60]:
|
||||||
|
- listitem [ref=e61]:
|
||||||
|
- generic [ref=e63] [cursor=pointer]:
|
||||||
|
- generic [ref=e65]:
|
||||||
|
- button " 研发综合界面" [ref=e67] [cursor=pointer]:
|
||||||
|
- generic [ref=e68]:
|
||||||
|
- generic [ref=e69]: 研发综合界面
|
||||||
|
- list
|
||||||
|
- generic [ref=e71]:
|
||||||
|
- button [ref=e73] [cursor=pointer]:
|
||||||
|
- img [ref=e75]
|
||||||
|
- link " 开源版21.7" [ref=e76] [cursor=pointer]:
|
||||||
|
- /url: https://www.zentao.net
|
||||||
|
- generic [ref=e77]:
|
||||||
|
- generic [ref=e78]: 开源版21.7
|
||||||
|
- button "升级 " [ref=e79] [cursor=pointer]:
|
||||||
|
- generic [ref=e80]: 升级
|
||||||
|
- generic [ref=e81]:
|
||||||
93
.playwright-mcp/page-2026-03-31T08-17-44-802Z.yml
Normal file
93
.playwright-mcp/page-2026-03-31T08-17-44-802Z.yml
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic [ref=e1]:
|
||||||
|
- generic [ref=e2]:
|
||||||
|
- list [ref=e3]:
|
||||||
|
- listitem [ref=e4]:
|
||||||
|
- link " 地盘" [ref=e5] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=index
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- generic [ref=e7]: 地盘
|
||||||
|
- listitem [ref=e8]:
|
||||||
|
- link " 项目集" [ref=e9] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=program&f=browse
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- generic [ref=e11]: 项目集
|
||||||
|
- listitem [ref=e12]:
|
||||||
|
- link " 产品" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=product&f=all
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e15]: 产品
|
||||||
|
- listitem [ref=e16]:
|
||||||
|
- link " 项目" [ref=e17] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=browse
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e19]: 项目
|
||||||
|
- listitem [ref=e20]:
|
||||||
|
- link " 执行" [ref=e21] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=execution&f=task
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: 执行
|
||||||
|
- listitem [ref=e24]:
|
||||||
|
- link " 测试" [ref=e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- generic [ref=e27]: 测试
|
||||||
|
- listitem [ref=e28]:
|
||||||
|
- link " DevOps" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=repo&f=maintain
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]: DevOps
|
||||||
|
- listitem [ref=e32]
|
||||||
|
- listitem [ref=e33]:
|
||||||
|
- link " AI" [ref=e34] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=aiapp&f=square
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]: AI
|
||||||
|
- listitem [ref=e37]:
|
||||||
|
- link " BI" [ref=e38] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=screen&f=browse
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e40]: BI
|
||||||
|
- listitem [ref=e41]
|
||||||
|
- listitem [ref=e42]:
|
||||||
|
- link " 看板" [ref=e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=kanban&f=space
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- generic [ref=e45]: 看板
|
||||||
|
- listitem [ref=e46]:
|
||||||
|
- link " 文档" [ref=e47] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=doc&f=lastViewedSpace
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]: 文档
|
||||||
|
- listitem [ref=e50]
|
||||||
|
- listitem [ref=e51]:
|
||||||
|
- link " 组织" [ref=e52] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=team
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- generic [ref=e54]: 组织
|
||||||
|
- listitem [ref=e55]:
|
||||||
|
- link " 后台" [ref=e56] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=admin&f=index
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e58]: 后台
|
||||||
|
- text:
|
||||||
|
- list [ref=e60]:
|
||||||
|
- listitem [ref=e61]:
|
||||||
|
- generic [ref=e63] [cursor=pointer]:
|
||||||
|
- generic [ref=e65]:
|
||||||
|
- button " 研发综合界面" [ref=e67] [cursor=pointer]:
|
||||||
|
- generic [ref=e68]:
|
||||||
|
- generic [ref=e69]: 研发综合界面
|
||||||
|
- list
|
||||||
|
- generic [ref=e71]:
|
||||||
|
- textbox [ref=e77]:
|
||||||
|
- /placeholder: 搜索
|
||||||
|
- button [ref=e79] [cursor=pointer]:
|
||||||
|
- img [ref=e81]
|
||||||
|
- link " 开源版21.7" [ref=e82] [cursor=pointer]:
|
||||||
|
- /url: https://www.zentao.net
|
||||||
|
- generic [ref=e83]:
|
||||||
|
- generic [ref=e84]: 开源版21.7
|
||||||
|
- button "升级 " [ref=e85] [cursor=pointer]:
|
||||||
|
- generic [ref=e86]: 升级
|
||||||
|
- generic [ref=e87]:
|
||||||
93
.playwright-mcp/page-2026-03-31T08-17-49-298Z.yml
Normal file
93
.playwright-mcp/page-2026-03-31T08-17-49-298Z.yml
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic [ref=e1]:
|
||||||
|
- generic [ref=e2]:
|
||||||
|
- list [ref=e3]:
|
||||||
|
- listitem [ref=e4]:
|
||||||
|
- link " 地盘" [ref=e5] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=index
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- generic [ref=e7]: 地盘
|
||||||
|
- listitem [ref=e8]:
|
||||||
|
- link " 项目集" [ref=e9] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=program&f=browse
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- generic [ref=e11]: 项目集
|
||||||
|
- listitem [ref=e12]:
|
||||||
|
- link " 产品" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=product&f=all
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e15]: 产品
|
||||||
|
- listitem [ref=e16]:
|
||||||
|
- link " 项目" [ref=e17] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=browse
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e19]: 项目
|
||||||
|
- listitem [ref=e20]:
|
||||||
|
- link " 执行" [ref=e21] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=execution&f=task
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: 执行
|
||||||
|
- listitem [ref=e24]:
|
||||||
|
- link " 测试" [ref=e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- generic [ref=e27]: 测试
|
||||||
|
- listitem [ref=e28]:
|
||||||
|
- link " DevOps" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=repo&f=maintain
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]: DevOps
|
||||||
|
- listitem [ref=e32]
|
||||||
|
- listitem [ref=e33]:
|
||||||
|
- link " AI" [ref=e34] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=aiapp&f=square
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]: AI
|
||||||
|
- listitem [ref=e37]:
|
||||||
|
- link " BI" [ref=e38] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=screen&f=browse
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e40]: BI
|
||||||
|
- listitem [ref=e41]
|
||||||
|
- listitem [ref=e42]:
|
||||||
|
- link " 看板" [ref=e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=kanban&f=space
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- generic [ref=e45]: 看板
|
||||||
|
- listitem [ref=e46]:
|
||||||
|
- link " 文档" [ref=e47] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=doc&f=lastViewedSpace
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]: 文档
|
||||||
|
- listitem [ref=e50]
|
||||||
|
- listitem [ref=e51]:
|
||||||
|
- link " 组织" [ref=e52] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=team
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- generic [ref=e54]: 组织
|
||||||
|
- listitem [ref=e55]:
|
||||||
|
- link " 后台" [ref=e56] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=admin&f=index
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e58]: 后台
|
||||||
|
- text:
|
||||||
|
- list [ref=e60]:
|
||||||
|
- listitem [ref=e61]:
|
||||||
|
- generic [ref=e63] [cursor=pointer]:
|
||||||
|
- generic [ref=e65]:
|
||||||
|
- button " 研发综合界面" [ref=e67] [cursor=pointer]:
|
||||||
|
- generic [ref=e68]:
|
||||||
|
- generic [ref=e69]: 研发综合界面
|
||||||
|
- list
|
||||||
|
- generic [ref=e71]:
|
||||||
|
- textbox [ref=e77]:
|
||||||
|
- /placeholder: 搜索
|
||||||
|
- button [ref=e79] [cursor=pointer]:
|
||||||
|
- img [ref=e81]
|
||||||
|
- link " 开源版21.7" [ref=e82] [cursor=pointer]:
|
||||||
|
- /url: https://www.zentao.net
|
||||||
|
- generic [ref=e83]:
|
||||||
|
- generic [ref=e84]: 开源版21.7
|
||||||
|
- button "升级 " [ref=e85] [cursor=pointer]:
|
||||||
|
- generic [ref=e86]: 升级
|
||||||
|
- generic [ref=e87]:
|
||||||
91
.playwright-mcp/page-2026-03-31T08-18-07-157Z.yml
Normal file
91
.playwright-mcp/page-2026-03-31T08-18-07-157Z.yml
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic [ref=e1]:
|
||||||
|
- generic [ref=e2]:
|
||||||
|
- list [ref=e3]:
|
||||||
|
- listitem [ref=e4]:
|
||||||
|
- link " 地盘" [ref=e5] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=index
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- generic [ref=e7]: 地盘
|
||||||
|
- listitem [ref=e8]:
|
||||||
|
- link " 项目集" [ref=e9] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=program&f=browse
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- generic [ref=e11]: 项目集
|
||||||
|
- listitem [ref=e12]:
|
||||||
|
- link " 产品" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=product&f=all
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e15]: 产品
|
||||||
|
- listitem [ref=e16]:
|
||||||
|
- link " 项目" [ref=e17] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=browse
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e19]: 项目
|
||||||
|
- listitem [ref=e20]:
|
||||||
|
- link " 执行" [ref=e21] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=execution&f=task
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: 执行
|
||||||
|
- listitem [ref=e24]:
|
||||||
|
- link " 测试" [ref=e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- generic [ref=e27]: 测试
|
||||||
|
- listitem [ref=e28]:
|
||||||
|
- link " DevOps" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=repo&f=maintain
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]: DevOps
|
||||||
|
- listitem [ref=e32]
|
||||||
|
- listitem [ref=e33]:
|
||||||
|
- link " AI" [ref=e34] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=aiapp&f=square
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]: AI
|
||||||
|
- listitem [ref=e37]:
|
||||||
|
- link " BI" [ref=e38] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=screen&f=browse
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e40]: BI
|
||||||
|
- listitem [ref=e41]
|
||||||
|
- listitem [ref=e42]:
|
||||||
|
- link " 看板" [ref=e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=kanban&f=space
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- generic [ref=e45]: 看板
|
||||||
|
- listitem [ref=e46]:
|
||||||
|
- link " 文档" [ref=e47] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=doc&f=lastViewedSpace
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]: 文档
|
||||||
|
- listitem [ref=e50]
|
||||||
|
- listitem [ref=e51]:
|
||||||
|
- link " 组织" [ref=e52] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=team
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- generic [ref=e54]: 组织
|
||||||
|
- listitem [ref=e55]:
|
||||||
|
- link " 后台" [ref=e56] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=admin&f=index
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e58]: 后台
|
||||||
|
- text:
|
||||||
|
- list [ref=e60]:
|
||||||
|
- listitem [ref=e61]:
|
||||||
|
- generic [ref=e63] [cursor=pointer]:
|
||||||
|
- generic [ref=e65]:
|
||||||
|
- button " 研发综合界面" [ref=e67] [cursor=pointer]:
|
||||||
|
- generic [ref=e68]:
|
||||||
|
- generic [ref=e69]: 研发综合界面
|
||||||
|
- list
|
||||||
|
- generic [ref=e71]:
|
||||||
|
- button [ref=e73] [cursor=pointer]:
|
||||||
|
- img [ref=e75]
|
||||||
|
- link " 开源版21.7" [ref=e76] [cursor=pointer]:
|
||||||
|
- /url: https://www.zentao.net
|
||||||
|
- generic [ref=e77]:
|
||||||
|
- generic [ref=e78]: 开源版21.7
|
||||||
|
- button "升级 " [ref=e79] [cursor=pointer]:
|
||||||
|
- generic [ref=e80]: 升级
|
||||||
|
- generic [ref=e81]:
|
||||||
93
.playwright-mcp/page-2026-03-31T08-18-18-348Z.yml
Normal file
93
.playwright-mcp/page-2026-03-31T08-18-18-348Z.yml
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic [ref=e1]:
|
||||||
|
- generic [ref=e2]:
|
||||||
|
- list [ref=e3]:
|
||||||
|
- listitem [ref=e4]:
|
||||||
|
- link " 地盘" [ref=e5] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=index
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- generic [ref=e7]: 地盘
|
||||||
|
- listitem [ref=e8]:
|
||||||
|
- link " 项目集" [ref=e9] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=program&f=browse
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- generic [ref=e11]: 项目集
|
||||||
|
- listitem [ref=e12]:
|
||||||
|
- link " 产品" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=product&f=all
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e15]: 产品
|
||||||
|
- listitem [ref=e16]:
|
||||||
|
- link " 项目" [ref=e17] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=browse
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e19]: 项目
|
||||||
|
- listitem [ref=e20]:
|
||||||
|
- link " 执行" [ref=e21] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=execution&f=task
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: 执行
|
||||||
|
- listitem [ref=e24]:
|
||||||
|
- link " 测试" [ref=e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- generic [ref=e27]: 测试
|
||||||
|
- listitem [ref=e28]:
|
||||||
|
- link " DevOps" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=repo&f=maintain
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]: DevOps
|
||||||
|
- listitem [ref=e32]
|
||||||
|
- listitem [ref=e33]:
|
||||||
|
- link " AI" [ref=e34] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=aiapp&f=square
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]: AI
|
||||||
|
- listitem [ref=e37]:
|
||||||
|
- link " BI" [ref=e38] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=screen&f=browse
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e40]: BI
|
||||||
|
- listitem [ref=e41]
|
||||||
|
- listitem [ref=e42]:
|
||||||
|
- link " 看板" [ref=e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=kanban&f=space
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- generic [ref=e45]: 看板
|
||||||
|
- listitem [ref=e46]:
|
||||||
|
- link " 文档" [ref=e47] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=doc&f=lastViewedSpace
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]: 文档
|
||||||
|
- listitem [ref=e50]
|
||||||
|
- listitem [ref=e51]:
|
||||||
|
- link " 组织" [ref=e52] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=team
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- generic [ref=e54]: 组织
|
||||||
|
- listitem [ref=e55]:
|
||||||
|
- link " 后台" [ref=e56] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=admin&f=index
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e58]: 后台
|
||||||
|
- text:
|
||||||
|
- list [ref=e60]:
|
||||||
|
- listitem [ref=e61]:
|
||||||
|
- generic [ref=e63] [cursor=pointer]:
|
||||||
|
- generic [ref=e65]:
|
||||||
|
- button " 研发综合界面" [ref=e67] [cursor=pointer]:
|
||||||
|
- generic [ref=e68]:
|
||||||
|
- generic [ref=e69]: 研发综合界面
|
||||||
|
- list
|
||||||
|
- generic [ref=e71]:
|
||||||
|
- textbox [ref=e77]:
|
||||||
|
- /placeholder: 搜索
|
||||||
|
- button [ref=e79] [cursor=pointer]:
|
||||||
|
- img [ref=e81]
|
||||||
|
- link " 开源版21.7" [ref=e82] [cursor=pointer]:
|
||||||
|
- /url: https://www.zentao.net
|
||||||
|
- generic [ref=e83]:
|
||||||
|
- generic [ref=e84]: 开源版21.7
|
||||||
|
- button "升级 " [ref=e85] [cursor=pointer]:
|
||||||
|
- generic [ref=e86]: 升级
|
||||||
|
- generic [ref=e87]:
|
||||||
1039
.playwright-mcp/page-2026-03-31T08-18-21-578Z.yml
Normal file
1039
.playwright-mcp/page-2026-03-31T08-18-21-578Z.yml
Normal file
File diff suppressed because it is too large
Load Diff
91
.playwright-mcp/page-2026-03-31T08-18-34-499Z.yml
Normal file
91
.playwright-mcp/page-2026-03-31T08-18-34-499Z.yml
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic [ref=e1]:
|
||||||
|
- generic [ref=e2]:
|
||||||
|
- list [ref=e3]:
|
||||||
|
- listitem [ref=e4]:
|
||||||
|
- link " 地盘" [ref=e5] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=index
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- generic [ref=e7]: 地盘
|
||||||
|
- listitem [ref=e8]:
|
||||||
|
- link " 项目集" [ref=e9] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=program&f=browse
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- generic [ref=e11]: 项目集
|
||||||
|
- listitem [ref=e12]:
|
||||||
|
- link " 产品" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=product&f=all
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e15]: 产品
|
||||||
|
- listitem [ref=e16]:
|
||||||
|
- link " 项目" [ref=e17] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=browse
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e19]: 项目
|
||||||
|
- listitem [ref=e20]:
|
||||||
|
- link " 执行" [ref=e21] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=execution&f=task
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: 执行
|
||||||
|
- listitem [ref=e24]:
|
||||||
|
- link " 测试" [ref=e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- generic [ref=e27]: 测试
|
||||||
|
- listitem [ref=e28]:
|
||||||
|
- link " DevOps" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=repo&f=maintain
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]: DevOps
|
||||||
|
- listitem [ref=e32]
|
||||||
|
- listitem [ref=e33]:
|
||||||
|
- link " AI" [ref=e34] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=aiapp&f=square
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]: AI
|
||||||
|
- listitem [ref=e37]:
|
||||||
|
- link " BI" [ref=e38] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=screen&f=browse
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e40]: BI
|
||||||
|
- listitem [ref=e41]
|
||||||
|
- listitem [ref=e42]:
|
||||||
|
- link " 看板" [ref=e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=kanban&f=space
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- generic [ref=e45]: 看板
|
||||||
|
- listitem [ref=e46]:
|
||||||
|
- link " 文档" [ref=e47] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=doc&f=lastViewedSpace
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]: 文档
|
||||||
|
- listitem [ref=e50]
|
||||||
|
- listitem [ref=e51]:
|
||||||
|
- link " 组织" [ref=e52] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=team
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- generic [ref=e54]: 组织
|
||||||
|
- listitem [ref=e55]:
|
||||||
|
- link " 后台" [ref=e56] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=admin&f=index
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e58]: 后台
|
||||||
|
- text:
|
||||||
|
- list [ref=e60]:
|
||||||
|
- listitem [ref=e61]:
|
||||||
|
- generic [ref=e63] [cursor=pointer]:
|
||||||
|
- generic [ref=e65]:
|
||||||
|
- button " 研发综合界面" [ref=e67] [cursor=pointer]:
|
||||||
|
- generic [ref=e68]:
|
||||||
|
- generic [ref=e69]: 研发综合界面
|
||||||
|
- list
|
||||||
|
- generic [ref=e71]:
|
||||||
|
- button [ref=e73] [cursor=pointer]:
|
||||||
|
- img [ref=e75]
|
||||||
|
- link " 开源版21.7" [ref=e76] [cursor=pointer]:
|
||||||
|
- /url: https://www.zentao.net
|
||||||
|
- generic [ref=e77]:
|
||||||
|
- generic [ref=e78]: 开源版21.7
|
||||||
|
- button "升级 " [ref=e79] [cursor=pointer]:
|
||||||
|
- generic [ref=e80]: 升级
|
||||||
|
- generic [ref=e81]:
|
||||||
314
.playwright-mcp/page-2026-03-31T08-18-42-028Z.yml
Normal file
314
.playwright-mcp/page-2026-03-31T08-18-42-028Z.yml
Normal file
@@ -0,0 +1,314 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic [ref=e1]:
|
||||||
|
- generic [ref=e2]:
|
||||||
|
- list [ref=e3]:
|
||||||
|
- listitem [ref=e4]:
|
||||||
|
- link " 地盘" [ref=e5] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=index
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- generic [ref=e7]: 地盘
|
||||||
|
- listitem [ref=e8]:
|
||||||
|
- link " 项目集" [ref=e9] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=program&f=browse
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- generic [ref=e11]: 项目集
|
||||||
|
- listitem [ref=e12]:
|
||||||
|
- link " 产品" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=product&f=all
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e15]: 产品
|
||||||
|
- listitem [ref=e16]:
|
||||||
|
- link " 项目" [ref=e17] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=browse
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e19]: 项目
|
||||||
|
- listitem [ref=e20]:
|
||||||
|
- link " 执行" [ref=e21] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=execution&f=task
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: 执行
|
||||||
|
- listitem [ref=e24]:
|
||||||
|
- link " 测试" [ref=e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- generic [ref=e27]: 测试
|
||||||
|
- listitem [ref=e28]:
|
||||||
|
- link " DevOps" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=repo&f=maintain
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]: DevOps
|
||||||
|
- listitem [ref=e32]
|
||||||
|
- listitem [ref=e33]:
|
||||||
|
- link " AI" [ref=e34] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=aiapp&f=square
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]: AI
|
||||||
|
- listitem [ref=e37]:
|
||||||
|
- link " BI" [ref=e38] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=screen&f=browse
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e40]: BI
|
||||||
|
- listitem [ref=e41]
|
||||||
|
- listitem [ref=e42]:
|
||||||
|
- link " 看板" [ref=e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=kanban&f=space
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- generic [ref=e45]: 看板
|
||||||
|
- listitem [ref=e46]:
|
||||||
|
- link " 文档" [ref=e47] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=doc&f=lastViewedSpace
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]: 文档
|
||||||
|
- listitem [ref=e50]
|
||||||
|
- listitem [ref=e51]:
|
||||||
|
- link " 组织" [ref=e52] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=team
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- generic [ref=e54]: 组织
|
||||||
|
- listitem [ref=e55]:
|
||||||
|
- link " 后台" [ref=e56] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=admin&f=index
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e58]: 后台
|
||||||
|
- text:
|
||||||
|
- list [ref=e60]:
|
||||||
|
- listitem [ref=e61]:
|
||||||
|
- generic [ref=e63] [cursor=pointer]:
|
||||||
|
- iframe [ref=e66]:
|
||||||
|
- generic [active] [ref=f11e1]:
|
||||||
|
- banner [ref=f11e2]:
|
||||||
|
- generic [ref=f11e3]:
|
||||||
|
- generic [ref=f11e4]:
|
||||||
|
- link " 测试" [ref=f11e6] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=f11e7]:
|
||||||
|
- generic [ref=f11e8]: 测试
|
||||||
|
- button " 开源HIS改造落地" [ref=f11e10] [cursor=pointer]:
|
||||||
|
- generic [ref=f11e11]:
|
||||||
|
- generic "开源HIS改造落地" [ref=f11e12]
|
||||||
|
- navigation [ref=f11e15]:
|
||||||
|
- list [ref=f11e16]:
|
||||||
|
- listitem [ref=f11e17]:
|
||||||
|
- link "仪表盘" [ref=f11e18] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=f11e19]: 仪表盘
|
||||||
|
- listitem [ref=f11e20]
|
||||||
|
- listitem [ref=f11e21]:
|
||||||
|
- link "Bug" [ref=f11e22] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=browse&productID=4
|
||||||
|
- generic [ref=f11e23]: Bug
|
||||||
|
- listitem [ref=f11e24]:
|
||||||
|
- link "用例" [ref=f11e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testcase&f=browse&productID=4
|
||||||
|
- generic [ref=f11e26]: 用例
|
||||||
|
- listitem [ref=f11e27]:
|
||||||
|
- link "套件" [ref=f11e28] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testsuite&f=browse&productID=4
|
||||||
|
- generic [ref=f11e29]: 套件
|
||||||
|
- listitem [ref=f11e30]
|
||||||
|
- listitem [ref=f11e31]:
|
||||||
|
- link "测试单" [ref=f11e32] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testtask&f=browse&productID=4
|
||||||
|
- generic [ref=f11e33]: 测试单
|
||||||
|
- listitem [ref=f11e34]:
|
||||||
|
- link "测试报告" [ref=f11e35] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testreport&f=browse&productID=4
|
||||||
|
- generic [ref=f11e36]: 测试报告
|
||||||
|
- listitem [ref=f11e37]
|
||||||
|
- listitem [ref=f11e38]:
|
||||||
|
- link "用例库" [ref=f11e39] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=caselib&f=browse&libID=0
|
||||||
|
- generic [ref=f11e40]: 用例库
|
||||||
|
- listitem [ref=f11e41]
|
||||||
|
- listitem [ref=f11e42]:
|
||||||
|
- link "自动化" [ref=f11e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=zanode&f=instruction
|
||||||
|
- generic [ref=f11e44]: 自动化
|
||||||
|
- generic [ref=f11e46]:
|
||||||
|
- button "" [ref=f11e47] [cursor=pointer]:
|
||||||
|
- generic [ref=f11e48]:
|
||||||
|
- button " 9" [ref=f11e49] [cursor=pointer]:
|
||||||
|
- generic [ref=f11e50]:
|
||||||
|
- generic [ref=f11e51]: "9"
|
||||||
|
- generic [ref=f11e54] [cursor=pointer]: A
|
||||||
|
- generic [ref=f11e57]:
|
||||||
|
- generic [ref=f11e58]:
|
||||||
|
- generic [ref=f11e59]:
|
||||||
|
- button " 返回" [ref=f11e60] [cursor=pointer]:
|
||||||
|
- generic [ref=f11e61]:
|
||||||
|
- generic [ref=f11e62]: 返回
|
||||||
|
- generic [ref=f11e63]:
|
||||||
|
- generic [ref=f11e64]: "306"
|
||||||
|
- generic [ref=f11e65]: 手术管理-》门诊手术安排:手术申请查询未过滤掉已安排的手术申请单
|
||||||
|
- link " 提Bug" [ref=f11e68] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=create&productID=4&branch=0&extras=projectID=11,executionID=0,moduleID=126
|
||||||
|
- generic [ref=f11e69]:
|
||||||
|
- generic [ref=f11e70]: 提Bug
|
||||||
|
- generic [ref=f11e71]:
|
||||||
|
- generic [ref=f11e72]:
|
||||||
|
- generic [ref=f11e74]:
|
||||||
|
- generic [ref=f11e76]: 重现步骤
|
||||||
|
- generic [ref=f11e78]:
|
||||||
|
- paragraph [ref=f11e79]: "[步骤]"
|
||||||
|
- paragraph [ref=f11e80]:
|
||||||
|
- link "index.php?m=file&f=read&t=png&fileID=1415" [ref=f11e81] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=file&f=read&t=png&fileID=1415
|
||||||
|
- img "index.php?m=file&f=read&t=png&fileID=1415" [ref=f11e82]
|
||||||
|
- paragraph [ref=f11e83]: 图1
|
||||||
|
- paragraph [ref=f11e84]: 1、如上图1所示:手术管理-》门诊手术安排:手术申请查询未过滤掉已安排的手术申请单。
|
||||||
|
- paragraph [ref=f11e85]: "[结果]"
|
||||||
|
- paragraph [ref=f11e86]: 1、手术管理-》门诊手术安排:手术申请查询未过滤掉已安排的手术申请单。
|
||||||
|
- paragraph [ref=f11e87]: "[期望]"
|
||||||
|
- paragraph [ref=f11e88]: 1、手术管理-》门诊手术安排:手术申请查询过滤掉已安排的手术申请单。
|
||||||
|
- generic [ref=f11e90]:
|
||||||
|
- generic [ref=f11e94]:
|
||||||
|
- generic [ref=f11e95]: 历史记录
|
||||||
|
- navigation [ref=f11e96]:
|
||||||
|
- button "" [ref=f11e97] [cursor=pointer]:
|
||||||
|
- generic [ref=f11e98]:
|
||||||
|
- button " 添加备注" [ref=f11e99] [cursor=pointer]:
|
||||||
|
- generic [ref=f11e100]:
|
||||||
|
- generic [ref=f11e101]: 添加备注
|
||||||
|
- list [ref=f11e103]:
|
||||||
|
- listitem [ref=f11e104]:
|
||||||
|
- generic [ref=f11e105]:
|
||||||
|
- generic [ref=f11e107]: "1"
|
||||||
|
- generic [ref=f11e110]:
|
||||||
|
- text: 2026-03-30 17:01:33, 由
|
||||||
|
- strong [ref=f11e111]: 陈显精
|
||||||
|
- text: 创建。
|
||||||
|
- listitem [ref=f11e112]:
|
||||||
|
- generic [ref=f11e113]:
|
||||||
|
- generic [ref=f11e115]: "2"
|
||||||
|
- generic [ref=f11e118]:
|
||||||
|
- text: 2026-03-30 17:01:45, 由
|
||||||
|
- strong [ref=f11e119]: 陈显精
|
||||||
|
- text: 指派给
|
||||||
|
- strong [ref=f11e120]: 王怡哲
|
||||||
|
- text: 。
|
||||||
|
- generic [ref=f11e123]:
|
||||||
|
- button " 返回" [ref=f11e124] [cursor=pointer]:
|
||||||
|
- generic [ref=f11e125]:
|
||||||
|
- generic [ref=f11e126]: 返回
|
||||||
|
- link " 确认" [ref=f11e128] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=confirm&bugID=306
|
||||||
|
- generic [ref=f11e129]:
|
||||||
|
- generic [ref=f11e130]: 确认
|
||||||
|
- link " 指派" [ref=f11e131] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=assignTo&bugID=306
|
||||||
|
- generic [ref=f11e132]:
|
||||||
|
- generic [ref=f11e133]: 指派
|
||||||
|
- link " 解决" [ref=f11e134] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=resolve&bugID=306
|
||||||
|
- generic [ref=f11e135]:
|
||||||
|
- generic [ref=f11e136]: 解决
|
||||||
|
- button " 转研发需求" [ref=f11e137] [cursor=pointer]:
|
||||||
|
- generic [ref=f11e138]:
|
||||||
|
- generic [ref=f11e139]: 转研发需求
|
||||||
|
- button " 转任务" [ref=f11e140] [cursor=pointer]:
|
||||||
|
- generic [ref=f11e141]:
|
||||||
|
- generic [ref=f11e142]: 转任务
|
||||||
|
- link " 创建用例" [ref=f11e143] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testcase&f=create&productID=4&branch=0&moduleID=0&from=bug&bugID=306
|
||||||
|
- generic [ref=f11e144]:
|
||||||
|
- generic [ref=f11e145]: 创建用例
|
||||||
|
- link "" [ref=f11e147] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=edit&bugID=306
|
||||||
|
- generic [ref=f11e148]:
|
||||||
|
- link "" [ref=f11e149] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=create&productID=4&branch=0&extra=bugID=306,projectID=11,executionID=0
|
||||||
|
- generic [ref=f11e150]:
|
||||||
|
- link "" [ref=f11e151] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=delete&bugID=306
|
||||||
|
- generic [ref=f11e152]:
|
||||||
|
- generic [ref=f11e153]:
|
||||||
|
- generic [ref=f11e154]:
|
||||||
|
- generic [ref=f11e155]:
|
||||||
|
- list [ref=f11e156]:
|
||||||
|
- listitem [ref=f11e157]:
|
||||||
|
- link "基本信息" [ref=f11e158] [cursor=pointer]:
|
||||||
|
- /url: "#zin_bug_view_306_tabPane"
|
||||||
|
- generic [ref=f11e159]: 基本信息
|
||||||
|
- listitem [ref=f11e160]:
|
||||||
|
- link "Bug的一生" [ref=f11e161] [cursor=pointer]:
|
||||||
|
- /url: "#zin_bug_view_306_tabPane_1"
|
||||||
|
- generic [ref=f11e162]: Bug的一生
|
||||||
|
- button "" [ref=f11e163] [cursor=pointer]:
|
||||||
|
- generic [ref=f11e164]:
|
||||||
|
- generic [ref=f11e167]:
|
||||||
|
- generic [ref=f11e168]:
|
||||||
|
- generic "所属模块" [ref=f11e169]
|
||||||
|
- list [ref=f11e171]:
|
||||||
|
- listitem [ref=f11e172]: 手术麻醉管理
|
||||||
|
- generic "所属计划" [ref=f11e174]
|
||||||
|
- generic "来源用例" [ref=f11e177]
|
||||||
|
- generic [ref=f11e179]:
|
||||||
|
- generic "Bug类型" [ref=f11e180]
|
||||||
|
- generic [ref=f11e181]: 代码错误
|
||||||
|
- generic [ref=f11e182]:
|
||||||
|
- generic "严重程度" [ref=f11e183]
|
||||||
|
- generic [ref=f11e185]: 3 3
|
||||||
|
- generic [ref=f11e186]:
|
||||||
|
- generic "优先级" [ref=f11e187]
|
||||||
|
- generic [ref=f11e189]: "3"
|
||||||
|
- generic [ref=f11e190]:
|
||||||
|
- generic "Bug状态" [ref=f11e191]
|
||||||
|
- generic [ref=f11e193]: 激活
|
||||||
|
- generic "激活次数" [ref=f11e195]
|
||||||
|
- generic "激活时间" [ref=f11e198]
|
||||||
|
- generic [ref=f11e200]:
|
||||||
|
- generic "是否确认" [ref=f11e201]
|
||||||
|
- generic [ref=f11e202]: 未确认
|
||||||
|
- generic [ref=f11e203]:
|
||||||
|
- generic "指派给" [ref=f11e204]
|
||||||
|
- generic [ref=f11e205]: 王怡哲 于 2026-03-30 17:01:31
|
||||||
|
- generic "截止日期" [ref=f11e207]
|
||||||
|
- generic "反馈者" [ref=f11e210]
|
||||||
|
- generic "通知邮箱" [ref=f11e213]
|
||||||
|
- generic "操作系统" [ref=f11e216]
|
||||||
|
- generic "浏览器" [ref=f11e219]
|
||||||
|
- generic "关键词" [ref=f11e222]
|
||||||
|
- generic "抄送给" [ref=f11e225]
|
||||||
|
- generic [ref=f11e227]:
|
||||||
|
- generic [ref=f11e228]:
|
||||||
|
- list [ref=f11e229]:
|
||||||
|
- listitem [ref=f11e230]:
|
||||||
|
- link "项目/迭代/研发需求/任务" [ref=f11e231] [cursor=pointer]:
|
||||||
|
- /url: "#zin_bug_view_306_tabPane_2"
|
||||||
|
- generic [ref=f11e232]: 项目/迭代/研发需求/任务
|
||||||
|
- listitem [ref=f11e233]:
|
||||||
|
- link "其他相关" [ref=f11e234] [cursor=pointer]:
|
||||||
|
- /url: "#zin_bug_view_306_tabPane_3"
|
||||||
|
- generic [ref=f11e235]: 其他相关
|
||||||
|
- button "" [ref=f11e236] [cursor=pointer]:
|
||||||
|
- generic [ref=f11e237]:
|
||||||
|
- generic [ref=f11e240]:
|
||||||
|
- generic [ref=f11e241]:
|
||||||
|
- generic "所属项目" [ref=f11e242]
|
||||||
|
- link "开源HIS改造落地" [ref=f11e244] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=view&projectID=11
|
||||||
|
- generic "所属执行" [ref=f11e246]
|
||||||
|
- generic "相关需求" [ref=f11e249]
|
||||||
|
- generic "相关任务" [ref=f11e252]
|
||||||
|
- button "" [ref=f11e255] [cursor=pointer]:
|
||||||
|
- generic [ref=f11e256]:
|
||||||
|
- text: "* *"
|
||||||
|
- generic [ref=e67]:
|
||||||
|
- button " 研发综合界面" [ref=e69] [cursor=pointer]:
|
||||||
|
- generic [ref=e70]:
|
||||||
|
- generic [ref=e71]: 研发综合界面
|
||||||
|
- list [ref=e73]:
|
||||||
|
- listitem [ref=e74]:
|
||||||
|
- generic [ref=e76] [cursor=pointer]: 测试
|
||||||
|
- generic [ref=e77]:
|
||||||
|
- textbox [ref=e83]:
|
||||||
|
- /placeholder: 搜索
|
||||||
|
- button [ref=e85] [cursor=pointer]:
|
||||||
|
- img [ref=e87]
|
||||||
|
- link " 开源版21.7" [ref=e88] [cursor=pointer]:
|
||||||
|
- /url: https://www.zentao.net
|
||||||
|
- generic [ref=e89]:
|
||||||
|
- generic [ref=e90]: 开源版21.7
|
||||||
|
- button "升级 " [ref=e91] [cursor=pointer]:
|
||||||
|
- generic [ref=e92]: 升级
|
||||||
|
- generic [ref=e93]:
|
||||||
91
.playwright-mcp/page-2026-03-31T08-18-43-555Z.yml
Normal file
91
.playwright-mcp/page-2026-03-31T08-18-43-555Z.yml
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic [ref=e1]:
|
||||||
|
- generic [ref=e2]:
|
||||||
|
- list [ref=e3]:
|
||||||
|
- listitem [ref=e4]:
|
||||||
|
- link " 地盘" [ref=e5] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=index
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- generic [ref=e7]: 地盘
|
||||||
|
- listitem [ref=e8]:
|
||||||
|
- link " 项目集" [ref=e9] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=program&f=browse
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- generic [ref=e11]: 项目集
|
||||||
|
- listitem [ref=e12]:
|
||||||
|
- link " 产品" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=product&f=all
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e15]: 产品
|
||||||
|
- listitem [ref=e16]:
|
||||||
|
- link " 项目" [ref=e17] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=browse
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e19]: 项目
|
||||||
|
- listitem [ref=e20]:
|
||||||
|
- link " 执行" [ref=e21] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=execution&f=task
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: 执行
|
||||||
|
- listitem [ref=e24]:
|
||||||
|
- link " 测试" [ref=e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- generic [ref=e27]: 测试
|
||||||
|
- listitem [ref=e28]:
|
||||||
|
- link " DevOps" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=repo&f=maintain
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]: DevOps
|
||||||
|
- listitem [ref=e32]
|
||||||
|
- listitem [ref=e33]:
|
||||||
|
- link " AI" [ref=e34] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=aiapp&f=square
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]: AI
|
||||||
|
- listitem [ref=e37]:
|
||||||
|
- link " BI" [ref=e38] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=screen&f=browse
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e40]: BI
|
||||||
|
- listitem [ref=e41]
|
||||||
|
- listitem [ref=e42]:
|
||||||
|
- link " 看板" [ref=e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=kanban&f=space
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- generic [ref=e45]: 看板
|
||||||
|
- listitem [ref=e46]:
|
||||||
|
- link " 文档" [ref=e47] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=doc&f=lastViewedSpace
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]: 文档
|
||||||
|
- listitem [ref=e50]
|
||||||
|
- listitem [ref=e51]:
|
||||||
|
- link " 组织" [ref=e52] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=team
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- generic [ref=e54]: 组织
|
||||||
|
- listitem [ref=e55]:
|
||||||
|
- link " 后台" [ref=e56] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=admin&f=index
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e58]: 后台
|
||||||
|
- text:
|
||||||
|
- list [ref=e60]:
|
||||||
|
- listitem [ref=e61]:
|
||||||
|
- generic [ref=e63] [cursor=pointer]:
|
||||||
|
- generic [ref=e65]:
|
||||||
|
- button " 研发综合界面" [ref=e67] [cursor=pointer]:
|
||||||
|
- generic [ref=e68]:
|
||||||
|
- generic [ref=e69]: 研发综合界面
|
||||||
|
- list
|
||||||
|
- generic [ref=e71]:
|
||||||
|
- button [ref=e73] [cursor=pointer]:
|
||||||
|
- img [ref=e75]
|
||||||
|
- link " 开源版21.7" [ref=e76] [cursor=pointer]:
|
||||||
|
- /url: https://www.zentao.net
|
||||||
|
- generic [ref=e77]:
|
||||||
|
- generic [ref=e78]: 开源版21.7
|
||||||
|
- button "升级 " [ref=e79] [cursor=pointer]:
|
||||||
|
- generic [ref=e80]: 升级
|
||||||
|
- generic [ref=e81]:
|
||||||
91
.playwright-mcp/page-2026-03-31T08-18-46-583Z.yml
Normal file
91
.playwright-mcp/page-2026-03-31T08-18-46-583Z.yml
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic [ref=e1]:
|
||||||
|
- generic [ref=e2]:
|
||||||
|
- list [ref=e3]:
|
||||||
|
- listitem [ref=e4]:
|
||||||
|
- link " 地盘" [ref=e5] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=index
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- generic [ref=e7]: 地盘
|
||||||
|
- listitem [ref=e8]:
|
||||||
|
- link " 项目集" [ref=e9] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=program&f=browse
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- generic [ref=e11]: 项目集
|
||||||
|
- listitem [ref=e12]:
|
||||||
|
- link " 产品" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=product&f=all
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e15]: 产品
|
||||||
|
- listitem [ref=e16]:
|
||||||
|
- link " 项目" [ref=e17] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=browse
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e19]: 项目
|
||||||
|
- listitem [ref=e20]:
|
||||||
|
- link " 执行" [ref=e21] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=execution&f=task
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: 执行
|
||||||
|
- listitem [ref=e24]:
|
||||||
|
- link " 测试" [ref=e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- generic [ref=e27]: 测试
|
||||||
|
- listitem [ref=e28]:
|
||||||
|
- link " DevOps" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=repo&f=maintain
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]: DevOps
|
||||||
|
- listitem [ref=e32]
|
||||||
|
- listitem [ref=e33]:
|
||||||
|
- link " AI" [ref=e34] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=aiapp&f=square
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]: AI
|
||||||
|
- listitem [ref=e37]:
|
||||||
|
- link " BI" [ref=e38] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=screen&f=browse
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e40]: BI
|
||||||
|
- listitem [ref=e41]
|
||||||
|
- listitem [ref=e42]:
|
||||||
|
- link " 看板" [ref=e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=kanban&f=space
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- generic [ref=e45]: 看板
|
||||||
|
- listitem [ref=e46]:
|
||||||
|
- link " 文档" [ref=e47] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=doc&f=lastViewedSpace
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]: 文档
|
||||||
|
- listitem [ref=e50]
|
||||||
|
- listitem [ref=e51]:
|
||||||
|
- link " 组织" [ref=e52] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=team
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- generic [ref=e54]: 组织
|
||||||
|
- listitem [ref=e55]:
|
||||||
|
- link " 后台" [ref=e56] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=admin&f=index
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e58]: 后台
|
||||||
|
- text:
|
||||||
|
- list [ref=e60]:
|
||||||
|
- listitem [ref=e61]:
|
||||||
|
- generic [ref=e63] [cursor=pointer]:
|
||||||
|
- generic [ref=e65]:
|
||||||
|
- button " 研发综合界面" [ref=e67] [cursor=pointer]:
|
||||||
|
- generic [ref=e68]:
|
||||||
|
- generic [ref=e69]: 研发综合界面
|
||||||
|
- list
|
||||||
|
- generic [ref=e71]:
|
||||||
|
- button [ref=e73] [cursor=pointer]:
|
||||||
|
- img [ref=e75]
|
||||||
|
- link " 开源版21.7" [ref=e76] [cursor=pointer]:
|
||||||
|
- /url: https://www.zentao.net
|
||||||
|
- generic [ref=e77]:
|
||||||
|
- generic [ref=e78]: 开源版21.7
|
||||||
|
- button "升级 " [ref=e79] [cursor=pointer]:
|
||||||
|
- generic [ref=e80]: 升级
|
||||||
|
- generic [ref=e81]:
|
||||||
91
.playwright-mcp/page-2026-03-31T08-18-53-714Z.yml
Normal file
91
.playwright-mcp/page-2026-03-31T08-18-53-714Z.yml
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic [ref=e1]:
|
||||||
|
- generic [ref=e2]:
|
||||||
|
- list [ref=e3]:
|
||||||
|
- listitem [ref=e4]:
|
||||||
|
- link " 地盘" [ref=e5] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=index
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- generic [ref=e7]: 地盘
|
||||||
|
- listitem [ref=e8]:
|
||||||
|
- link " 项目集" [ref=e9] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=program&f=browse
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- generic [ref=e11]: 项目集
|
||||||
|
- listitem [ref=e12]:
|
||||||
|
- link " 产品" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=product&f=all
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e15]: 产品
|
||||||
|
- listitem [ref=e16]:
|
||||||
|
- link " 项目" [ref=e17] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=browse
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e19]: 项目
|
||||||
|
- listitem [ref=e20]:
|
||||||
|
- link " 执行" [ref=e21] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=execution&f=task
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: 执行
|
||||||
|
- listitem [ref=e24]:
|
||||||
|
- link " 测试" [ref=e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- generic [ref=e27]: 测试
|
||||||
|
- listitem [ref=e28]:
|
||||||
|
- link " DevOps" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=repo&f=maintain
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]: DevOps
|
||||||
|
- listitem [ref=e32]
|
||||||
|
- listitem [ref=e33]:
|
||||||
|
- link " AI" [ref=e34] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=aiapp&f=square
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]: AI
|
||||||
|
- listitem [ref=e37]:
|
||||||
|
- link " BI" [ref=e38] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=screen&f=browse
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e40]: BI
|
||||||
|
- listitem [ref=e41]
|
||||||
|
- listitem [ref=e42]:
|
||||||
|
- link " 看板" [ref=e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=kanban&f=space
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- generic [ref=e45]: 看板
|
||||||
|
- listitem [ref=e46]:
|
||||||
|
- link " 文档" [ref=e47] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=doc&f=lastViewedSpace
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]: 文档
|
||||||
|
- listitem [ref=e50]
|
||||||
|
- listitem [ref=e51]:
|
||||||
|
- link " 组织" [ref=e52] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=team
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- generic [ref=e54]: 组织
|
||||||
|
- listitem [ref=e55]:
|
||||||
|
- link " 后台" [ref=e56] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=admin&f=index
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e58]: 后台
|
||||||
|
- text:
|
||||||
|
- list [ref=e60]:
|
||||||
|
- listitem [ref=e61]:
|
||||||
|
- generic [ref=e63] [cursor=pointer]:
|
||||||
|
- generic [ref=e65]:
|
||||||
|
- button " 研发综合界面" [ref=e67] [cursor=pointer]:
|
||||||
|
- generic [ref=e68]:
|
||||||
|
- generic [ref=e69]: 研发综合界面
|
||||||
|
- list
|
||||||
|
- generic [ref=e71]:
|
||||||
|
- button [ref=e73] [cursor=pointer]:
|
||||||
|
- img [ref=e75]
|
||||||
|
- link " 开源版21.7" [ref=e76] [cursor=pointer]:
|
||||||
|
- /url: https://www.zentao.net
|
||||||
|
- generic [ref=e77]:
|
||||||
|
- generic [ref=e78]: 开源版21.7
|
||||||
|
- button "升级 " [ref=e79] [cursor=pointer]:
|
||||||
|
- generic [ref=e80]: 升级
|
||||||
|
- generic [ref=e81]:
|
||||||
91
.playwright-mcp/page-2026-03-31T08-19-16-938Z.yml
Normal file
91
.playwright-mcp/page-2026-03-31T08-19-16-938Z.yml
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic [ref=e1]:
|
||||||
|
- generic [ref=e2]:
|
||||||
|
- list [ref=e3]:
|
||||||
|
- listitem [ref=e4]:
|
||||||
|
- link " 地盘" [ref=e5] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=index
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- generic [ref=e7]: 地盘
|
||||||
|
- listitem [ref=e8]:
|
||||||
|
- link " 项目集" [ref=e9] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=program&f=browse
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- generic [ref=e11]: 项目集
|
||||||
|
- listitem [ref=e12]:
|
||||||
|
- link " 产品" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=product&f=all
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e15]: 产品
|
||||||
|
- listitem [ref=e16]:
|
||||||
|
- link " 项目" [ref=e17] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=browse
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e19]: 项目
|
||||||
|
- listitem [ref=e20]:
|
||||||
|
- link " 执行" [ref=e21] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=execution&f=task
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: 执行
|
||||||
|
- listitem [ref=e24]:
|
||||||
|
- link " 测试" [ref=e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- generic [ref=e27]: 测试
|
||||||
|
- listitem [ref=e28]:
|
||||||
|
- link " DevOps" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=repo&f=maintain
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]: DevOps
|
||||||
|
- listitem [ref=e32]
|
||||||
|
- listitem [ref=e33]:
|
||||||
|
- link " AI" [ref=e34] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=aiapp&f=square
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]: AI
|
||||||
|
- listitem [ref=e37]:
|
||||||
|
- link " BI" [ref=e38] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=screen&f=browse
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e40]: BI
|
||||||
|
- listitem [ref=e41]
|
||||||
|
- listitem [ref=e42]:
|
||||||
|
- link " 看板" [ref=e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=kanban&f=space
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- generic [ref=e45]: 看板
|
||||||
|
- listitem [ref=e46]:
|
||||||
|
- link " 文档" [ref=e47] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=doc&f=lastViewedSpace
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]: 文档
|
||||||
|
- listitem [ref=e50]
|
||||||
|
- listitem [ref=e51]:
|
||||||
|
- link " 组织" [ref=e52] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=team
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- generic [ref=e54]: 组织
|
||||||
|
- listitem [ref=e55]:
|
||||||
|
- link " 后台" [ref=e56] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=admin&f=index
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e58]: 后台
|
||||||
|
- text:
|
||||||
|
- list [ref=e60]:
|
||||||
|
- listitem [ref=e61]:
|
||||||
|
- generic [ref=e63] [cursor=pointer]:
|
||||||
|
- generic [ref=e65]:
|
||||||
|
- button " 研发综合界面" [ref=e67] [cursor=pointer]:
|
||||||
|
- generic [ref=e68]:
|
||||||
|
- generic [ref=e69]: 研发综合界面
|
||||||
|
- list
|
||||||
|
- generic [ref=e71]:
|
||||||
|
- button [ref=e73] [cursor=pointer]:
|
||||||
|
- img [ref=e75]
|
||||||
|
- link " 开源版21.7" [ref=e76] [cursor=pointer]:
|
||||||
|
- /url: https://www.zentao.net
|
||||||
|
- generic [ref=e77]:
|
||||||
|
- generic [ref=e78]: 开源版21.7
|
||||||
|
- button "升级 " [ref=e79] [cursor=pointer]:
|
||||||
|
- generic [ref=e80]: 升级
|
||||||
|
- generic [ref=e81]:
|
||||||
93
.playwright-mcp/page-2026-03-31T08-20-38-261Z.yml
Normal file
93
.playwright-mcp/page-2026-03-31T08-20-38-261Z.yml
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic [ref=e1]:
|
||||||
|
- generic [ref=e2]:
|
||||||
|
- list [ref=e3]:
|
||||||
|
- listitem [ref=e4]:
|
||||||
|
- link " 地盘" [ref=e5] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=index
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- generic [ref=e7]: 地盘
|
||||||
|
- listitem [ref=e8]:
|
||||||
|
- link " 项目集" [ref=e9] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=program&f=browse
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- generic [ref=e11]: 项目集
|
||||||
|
- listitem [ref=e12]:
|
||||||
|
- link " 产品" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=product&f=all
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e15]: 产品
|
||||||
|
- listitem [ref=e16]:
|
||||||
|
- link " 项目" [ref=e17] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=browse
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e19]: 项目
|
||||||
|
- listitem [ref=e20]:
|
||||||
|
- link " 执行" [ref=e21] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=execution&f=task
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: 执行
|
||||||
|
- listitem [ref=e24]:
|
||||||
|
- link " 测试" [ref=e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- generic [ref=e27]: 测试
|
||||||
|
- listitem [ref=e28]:
|
||||||
|
- link " DevOps" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=repo&f=maintain
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]: DevOps
|
||||||
|
- listitem [ref=e32]
|
||||||
|
- listitem [ref=e33]:
|
||||||
|
- link " AI" [ref=e34] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=aiapp&f=square
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]: AI
|
||||||
|
- listitem [ref=e37]:
|
||||||
|
- link " BI" [ref=e38] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=screen&f=browse
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e40]: BI
|
||||||
|
- listitem [ref=e41]
|
||||||
|
- listitem [ref=e42]:
|
||||||
|
- link " 看板" [ref=e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=kanban&f=space
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- generic [ref=e45]: 看板
|
||||||
|
- listitem [ref=e46]:
|
||||||
|
- link " 文档" [ref=e47] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=doc&f=lastViewedSpace
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]: 文档
|
||||||
|
- listitem [ref=e50]
|
||||||
|
- listitem [ref=e51]:
|
||||||
|
- link " 组织" [ref=e52] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=team
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- generic [ref=e54]: 组织
|
||||||
|
- listitem [ref=e55]:
|
||||||
|
- link " 后台" [ref=e56] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=admin&f=index
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e58]: 后台
|
||||||
|
- text:
|
||||||
|
- list [ref=e60]:
|
||||||
|
- listitem [ref=e61]:
|
||||||
|
- generic [ref=e63] [cursor=pointer]:
|
||||||
|
- generic [ref=e65]:
|
||||||
|
- button " 研发综合界面" [ref=e67] [cursor=pointer]:
|
||||||
|
- generic [ref=e68]:
|
||||||
|
- generic [ref=e69]: 研发综合界面
|
||||||
|
- list
|
||||||
|
- generic [ref=e71]:
|
||||||
|
- textbox [ref=e77]:
|
||||||
|
- /placeholder: 搜索
|
||||||
|
- button [ref=e79] [cursor=pointer]:
|
||||||
|
- img [ref=e81]
|
||||||
|
- link " 开源版21.7" [ref=e82] [cursor=pointer]:
|
||||||
|
- /url: https://www.zentao.net
|
||||||
|
- generic [ref=e83]:
|
||||||
|
- generic [ref=e84]: 开源版21.7
|
||||||
|
- button "升级 " [ref=e85] [cursor=pointer]:
|
||||||
|
- generic [ref=e86]: 升级
|
||||||
|
- generic [ref=e87]:
|
||||||
322
.playwright-mcp/page-2026-03-31T08-21-04-747Z.yml
Normal file
322
.playwright-mcp/page-2026-03-31T08-21-04-747Z.yml
Normal file
@@ -0,0 +1,322 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic [ref=e1]:
|
||||||
|
- generic [ref=e2]:
|
||||||
|
- list [ref=e3]:
|
||||||
|
- listitem [ref=e4]:
|
||||||
|
- link " 地盘" [ref=e5] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=index
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- generic [ref=e7]: 地盘
|
||||||
|
- listitem [ref=e8]:
|
||||||
|
- link " 项目集" [ref=e9] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=program&f=browse
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- generic [ref=e11]: 项目集
|
||||||
|
- listitem [ref=e12]:
|
||||||
|
- link " 产品" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=product&f=all
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e15]: 产品
|
||||||
|
- listitem [ref=e16]:
|
||||||
|
- link " 项目" [ref=e17] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=browse
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e19]: 项目
|
||||||
|
- listitem [ref=e20]:
|
||||||
|
- link " 执行" [ref=e21] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=execution&f=task
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: 执行
|
||||||
|
- listitem [ref=e24]:
|
||||||
|
- link " 测试" [ref=e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- generic [ref=e27]: 测试
|
||||||
|
- listitem [ref=e28]:
|
||||||
|
- link " DevOps" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=repo&f=maintain
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]: DevOps
|
||||||
|
- listitem [ref=e32]
|
||||||
|
- listitem [ref=e33]:
|
||||||
|
- link " AI" [ref=e34] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=aiapp&f=square
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]: AI
|
||||||
|
- listitem [ref=e37]:
|
||||||
|
- link " BI" [ref=e38] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=screen&f=browse
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e40]: BI
|
||||||
|
- listitem [ref=e41]
|
||||||
|
- listitem [ref=e42]:
|
||||||
|
- link " 看板" [ref=e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=kanban&f=space
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- generic [ref=e45]: 看板
|
||||||
|
- listitem [ref=e46]:
|
||||||
|
- link " 文档" [ref=e47] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=doc&f=lastViewedSpace
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]: 文档
|
||||||
|
- listitem [ref=e50]
|
||||||
|
- listitem [ref=e51]:
|
||||||
|
- link " 组织" [ref=e52] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=team
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- generic [ref=e54]: 组织
|
||||||
|
- listitem [ref=e55]:
|
||||||
|
- link " 后台" [ref=e56] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=admin&f=index
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e58]: 后台
|
||||||
|
- text:
|
||||||
|
- list [ref=e60]:
|
||||||
|
- listitem [ref=e61]:
|
||||||
|
- generic [ref=e63] [cursor=pointer]:
|
||||||
|
- iframe [ref=e89]:
|
||||||
|
- generic [active] [ref=f19e1]:
|
||||||
|
- banner [ref=f19e2]:
|
||||||
|
- generic [ref=f19e3]:
|
||||||
|
- generic [ref=f19e4]:
|
||||||
|
- link " 测试" [ref=f19e6] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=f19e7]:
|
||||||
|
- generic [ref=f19e8]: 测试
|
||||||
|
- button " 开源HIS改造落地" [ref=f19e10] [cursor=pointer]:
|
||||||
|
- generic [ref=f19e11]:
|
||||||
|
- generic "开源HIS改造落地" [ref=f19e12]
|
||||||
|
- navigation [ref=f19e15]:
|
||||||
|
- list [ref=f19e16]:
|
||||||
|
- listitem [ref=f19e17]:
|
||||||
|
- link "仪表盘" [ref=f19e18] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=f19e19]: 仪表盘
|
||||||
|
- listitem [ref=f19e20]
|
||||||
|
- listitem [ref=f19e21]:
|
||||||
|
- link "Bug" [ref=f19e22] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=browse&productID=4
|
||||||
|
- generic [ref=f19e23]: Bug
|
||||||
|
- listitem [ref=f19e24]:
|
||||||
|
- link "用例" [ref=f19e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testcase&f=browse&productID=4
|
||||||
|
- generic [ref=f19e26]: 用例
|
||||||
|
- listitem [ref=f19e27]:
|
||||||
|
- link "套件" [ref=f19e28] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testsuite&f=browse&productID=4
|
||||||
|
- generic [ref=f19e29]: 套件
|
||||||
|
- listitem [ref=f19e30]
|
||||||
|
- listitem [ref=f19e31]:
|
||||||
|
- link "测试单" [ref=f19e32] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testtask&f=browse&productID=4
|
||||||
|
- generic [ref=f19e33]: 测试单
|
||||||
|
- listitem [ref=f19e34]:
|
||||||
|
- link "测试报告" [ref=f19e35] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testreport&f=browse&productID=4
|
||||||
|
- generic [ref=f19e36]: 测试报告
|
||||||
|
- listitem [ref=f19e37]
|
||||||
|
- listitem [ref=f19e38]:
|
||||||
|
- link "用例库" [ref=f19e39] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=caselib&f=browse&libID=0
|
||||||
|
- generic [ref=f19e40]: 用例库
|
||||||
|
- listitem [ref=f19e41]
|
||||||
|
- listitem [ref=f19e42]:
|
||||||
|
- link "自动化" [ref=f19e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=zanode&f=instruction
|
||||||
|
- generic [ref=f19e44]: 自动化
|
||||||
|
- generic [ref=f19e46]:
|
||||||
|
- button "" [ref=f19e47] [cursor=pointer]:
|
||||||
|
- generic [ref=f19e48]:
|
||||||
|
- button " 9" [ref=f19e49] [cursor=pointer]:
|
||||||
|
- generic [ref=f19e50]:
|
||||||
|
- generic [ref=f19e51]: "9"
|
||||||
|
- generic [ref=f19e54] [cursor=pointer]: A
|
||||||
|
- generic [ref=f19e57]:
|
||||||
|
- generic [ref=f19e58]:
|
||||||
|
- generic [ref=f19e59]:
|
||||||
|
- button " 返回" [ref=f19e60] [cursor=pointer]:
|
||||||
|
- generic [ref=f19e61]:
|
||||||
|
- generic [ref=f19e62]: 返回
|
||||||
|
- generic [ref=f19e63]:
|
||||||
|
- generic [ref=f19e64]: "306"
|
||||||
|
- generic [ref=f19e65]: 手术管理-》门诊手术安排:手术申请查询未过滤掉已安排的手术申请单
|
||||||
|
- link " 提Bug" [ref=f19e68] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=create&productID=4&branch=0&extras=projectID=11,executionID=0,moduleID=126
|
||||||
|
- generic [ref=f19e69]:
|
||||||
|
- generic [ref=f19e70]: 提Bug
|
||||||
|
- generic [ref=f19e71]:
|
||||||
|
- generic [ref=f19e72]:
|
||||||
|
- generic [ref=f19e74]:
|
||||||
|
- generic [ref=f19e76]: 重现步骤
|
||||||
|
- generic [ref=f19e78]:
|
||||||
|
- paragraph [ref=f19e79]: "[步骤]"
|
||||||
|
- paragraph [ref=f19e80]:
|
||||||
|
- link "index.php?m=file&f=read&t=png&fileID=1415" [ref=f19e81] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=file&f=read&t=png&fileID=1415
|
||||||
|
- img "index.php?m=file&f=read&t=png&fileID=1415" [ref=f19e82]
|
||||||
|
- paragraph [ref=f19e83]: 图1
|
||||||
|
- paragraph [ref=f19e84]: 1、如上图1所示:手术管理-》门诊手术安排:手术申请查询未过滤掉已安排的手术申请单。
|
||||||
|
- paragraph [ref=f19e85]: "[结果]"
|
||||||
|
- paragraph [ref=f19e86]: 1、手术管理-》门诊手术安排:手术申请查询未过滤掉已安排的手术申请单。
|
||||||
|
- paragraph [ref=f19e87]: "[期望]"
|
||||||
|
- paragraph [ref=f19e88]: 1、手术管理-》门诊手术安排:手术申请查询过滤掉已安排的手术申请单。
|
||||||
|
- generic [ref=f19e90]:
|
||||||
|
- generic [ref=f19e94]:
|
||||||
|
- generic [ref=f19e95]: 历史记录
|
||||||
|
- navigation [ref=f19e96]:
|
||||||
|
- button "" [ref=f19e97] [cursor=pointer]:
|
||||||
|
- generic [ref=f19e98]:
|
||||||
|
- button " 添加备注" [ref=f19e99] [cursor=pointer]:
|
||||||
|
- generic [ref=f19e100]:
|
||||||
|
- generic [ref=f19e101]: 添加备注
|
||||||
|
- list [ref=f19e103]:
|
||||||
|
- listitem [ref=f19e104]:
|
||||||
|
- generic [ref=f19e105]:
|
||||||
|
- generic [ref=f19e107]: "1"
|
||||||
|
- generic [ref=f19e110]:
|
||||||
|
- text: 2026-03-30 17:01:33, 由
|
||||||
|
- strong [ref=f19e111]: 陈显精
|
||||||
|
- text: 创建。
|
||||||
|
- listitem [ref=f19e112]:
|
||||||
|
- generic [ref=f19e113]:
|
||||||
|
- generic [ref=f19e115]: "2"
|
||||||
|
- generic [ref=f19e118]:
|
||||||
|
- text: 2026-03-30 17:01:45, 由
|
||||||
|
- strong [ref=f19e119]: 陈显精
|
||||||
|
- text: 指派给
|
||||||
|
- strong [ref=f19e120]: 王怡哲
|
||||||
|
- text: 。
|
||||||
|
- generic [ref=f19e123]:
|
||||||
|
- button " 返回" [ref=f19e124] [cursor=pointer]:
|
||||||
|
- generic [ref=f19e125]:
|
||||||
|
- generic [ref=f19e126]: 返回
|
||||||
|
- link " 确认" [ref=f19e128] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=confirm&bugID=306
|
||||||
|
- generic [ref=f19e129]:
|
||||||
|
- generic [ref=f19e130]: 确认
|
||||||
|
- link " 指派" [ref=f19e131] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=assignTo&bugID=306
|
||||||
|
- generic [ref=f19e132]:
|
||||||
|
- generic [ref=f19e133]: 指派
|
||||||
|
- link " 解决" [ref=f19e134] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=resolve&bugID=306
|
||||||
|
- generic [ref=f19e135]:
|
||||||
|
- generic [ref=f19e136]: 解决
|
||||||
|
- button " 转研发需求" [ref=f19e137] [cursor=pointer]:
|
||||||
|
- generic [ref=f19e138]:
|
||||||
|
- generic [ref=f19e139]: 转研发需求
|
||||||
|
- button " 转任务" [ref=f19e140] [cursor=pointer]:
|
||||||
|
- generic [ref=f19e141]:
|
||||||
|
- generic [ref=f19e142]: 转任务
|
||||||
|
- link " 创建用例" [ref=f19e143] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testcase&f=create&productID=4&branch=0&moduleID=0&from=bug&bugID=306
|
||||||
|
- generic [ref=f19e144]:
|
||||||
|
- generic [ref=f19e145]: 创建用例
|
||||||
|
- link "" [ref=f19e147] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=edit&bugID=306
|
||||||
|
- generic [ref=f19e148]:
|
||||||
|
- link "" [ref=f19e149] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=create&productID=4&branch=0&extra=bugID=306,projectID=11,executionID=0
|
||||||
|
- generic [ref=f19e150]:
|
||||||
|
- link "" [ref=f19e151] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=delete&bugID=306
|
||||||
|
- generic [ref=f19e152]:
|
||||||
|
- generic [ref=f19e153]:
|
||||||
|
- generic [ref=f19e154]:
|
||||||
|
- generic [ref=f19e155]:
|
||||||
|
- list [ref=f19e156]:
|
||||||
|
- listitem [ref=f19e157]:
|
||||||
|
- link "基本信息" [ref=f19e158] [cursor=pointer]:
|
||||||
|
- /url: "#zin_bug_view_306_tabPane"
|
||||||
|
- generic [ref=f19e159]: 基本信息
|
||||||
|
- listitem [ref=f19e160]:
|
||||||
|
- link "Bug的一生" [ref=f19e161] [cursor=pointer]:
|
||||||
|
- /url: "#zin_bug_view_306_tabPane_1"
|
||||||
|
- generic [ref=f19e162]: Bug的一生
|
||||||
|
- button "" [ref=f19e163] [cursor=pointer]:
|
||||||
|
- generic [ref=f19e164]:
|
||||||
|
- generic [ref=f19e167]:
|
||||||
|
- generic [ref=f19e168]:
|
||||||
|
- generic "所属模块" [ref=f19e169]
|
||||||
|
- list [ref=f19e171]:
|
||||||
|
- listitem [ref=f19e172]: 手术麻醉管理
|
||||||
|
- generic "所属计划" [ref=f19e174]
|
||||||
|
- generic "来源用例" [ref=f19e177]
|
||||||
|
- generic [ref=f19e179]:
|
||||||
|
- generic "Bug类型" [ref=f19e180]
|
||||||
|
- generic [ref=f19e181]: 代码错误
|
||||||
|
- generic [ref=f19e182]:
|
||||||
|
- generic "严重程度" [ref=f19e183]
|
||||||
|
- generic [ref=f19e185]: 3 3
|
||||||
|
- generic [ref=f19e186]:
|
||||||
|
- generic "优先级" [ref=f19e187]
|
||||||
|
- generic [ref=f19e189]: "3"
|
||||||
|
- generic [ref=f19e190]:
|
||||||
|
- generic "Bug状态" [ref=f19e191]
|
||||||
|
- generic [ref=f19e193]: 激活
|
||||||
|
- generic "激活次数" [ref=f19e195]
|
||||||
|
- generic "激活时间" [ref=f19e198]
|
||||||
|
- generic [ref=f19e200]:
|
||||||
|
- generic "是否确认" [ref=f19e201]
|
||||||
|
- generic [ref=f19e202]: 未确认
|
||||||
|
- generic [ref=f19e203]:
|
||||||
|
- generic "指派给" [ref=f19e204]
|
||||||
|
- generic [ref=f19e205]: 王怡哲 于 2026-03-30 17:01:31
|
||||||
|
- generic "截止日期" [ref=f19e207]
|
||||||
|
- generic "反馈者" [ref=f19e210]
|
||||||
|
- generic "通知邮箱" [ref=f19e213]
|
||||||
|
- generic "操作系统" [ref=f19e216]
|
||||||
|
- generic "浏览器" [ref=f19e219]
|
||||||
|
- generic "关键词" [ref=f19e222]
|
||||||
|
- generic "抄送给" [ref=f19e225]
|
||||||
|
- generic [ref=f19e227]:
|
||||||
|
- generic [ref=f19e228]:
|
||||||
|
- list [ref=f19e229]:
|
||||||
|
- listitem [ref=f19e230]:
|
||||||
|
- link "项目/迭代/研发需求/任务" [ref=f19e231] [cursor=pointer]:
|
||||||
|
- /url: "#zin_bug_view_306_tabPane_2"
|
||||||
|
- generic [ref=f19e232]: 项目/迭代/研发需求/任务
|
||||||
|
- listitem [ref=f19e233]:
|
||||||
|
- link "其他相关" [ref=f19e234] [cursor=pointer]:
|
||||||
|
- /url: "#zin_bug_view_306_tabPane_3"
|
||||||
|
- generic [ref=f19e235]: 其他相关
|
||||||
|
- button "" [ref=f19e236] [cursor=pointer]:
|
||||||
|
- generic [ref=f19e237]:
|
||||||
|
- generic [ref=f19e240]:
|
||||||
|
- generic [ref=f19e241]:
|
||||||
|
- generic "所属项目" [ref=f19e242]
|
||||||
|
- link "开源HIS改造落地" [ref=f19e244] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=view&projectID=11
|
||||||
|
- generic "所属执行" [ref=f19e246]
|
||||||
|
- generic "相关需求" [ref=f19e249]
|
||||||
|
- generic "相关任务" [ref=f19e252]
|
||||||
|
- button "" [ref=f19e255] [cursor=pointer]:
|
||||||
|
- generic [ref=f19e256]:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- link "" [ref=f19e257] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=view&bugID=307
|
||||||
|
- generic [ref=f19e258]:
|
||||||
|
- link "" [ref=f19e259] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=view&bugID=305
|
||||||
|
- generic [ref=f19e260]:
|
||||||
|
- text: "* *"
|
||||||
|
- generic [ref=e65]:
|
||||||
|
- button " 研发综合界面" [ref=e67] [cursor=pointer]:
|
||||||
|
- generic [ref=e68]:
|
||||||
|
- generic [ref=e69]: 研发综合界面
|
||||||
|
- list [ref=e90]:
|
||||||
|
- listitem [ref=e91]:
|
||||||
|
- generic [ref=e93] [cursor=pointer]: 测试
|
||||||
|
- generic [ref=e71]:
|
||||||
|
- textbox [ref=e77]:
|
||||||
|
- /placeholder: 搜索
|
||||||
|
- button [ref=e79] [cursor=pointer]:
|
||||||
|
- img [ref=e81]
|
||||||
|
- link " 开源版21.7" [ref=e82] [cursor=pointer]:
|
||||||
|
- /url: https://www.zentao.net
|
||||||
|
- generic [ref=e83]:
|
||||||
|
- generic [ref=e84]: 开源版21.7
|
||||||
|
- button "升级 " [ref=e85] [cursor=pointer]:
|
||||||
|
- generic [ref=e86]: 升级
|
||||||
|
- generic [ref=e87]:
|
||||||
91
.playwright-mcp/page-2026-03-31T08-25-34-591Z.yml
Normal file
91
.playwright-mcp/page-2026-03-31T08-25-34-591Z.yml
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic [ref=e1]:
|
||||||
|
- generic [ref=e2]:
|
||||||
|
- list [ref=e3]:
|
||||||
|
- listitem [ref=e4]:
|
||||||
|
- link " 地盘" [ref=e5] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=index
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- generic [ref=e7]: 地盘
|
||||||
|
- listitem [ref=e8]:
|
||||||
|
- link " 项目集" [ref=e9] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=program&f=browse
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- generic [ref=e11]: 项目集
|
||||||
|
- listitem [ref=e12]:
|
||||||
|
- link " 产品" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=product&f=all
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e15]: 产品
|
||||||
|
- listitem [ref=e16]:
|
||||||
|
- link " 项目" [ref=e17] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=browse
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e19]: 项目
|
||||||
|
- listitem [ref=e20]:
|
||||||
|
- link " 执行" [ref=e21] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=execution&f=task
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: 执行
|
||||||
|
- listitem [ref=e24]:
|
||||||
|
- link " 测试" [ref=e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- generic [ref=e27]: 测试
|
||||||
|
- listitem [ref=e28]:
|
||||||
|
- link " DevOps" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=repo&f=maintain
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]: DevOps
|
||||||
|
- listitem [ref=e32]
|
||||||
|
- listitem [ref=e33]:
|
||||||
|
- link " AI" [ref=e34] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=aiapp&f=square
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]: AI
|
||||||
|
- listitem [ref=e37]:
|
||||||
|
- link " BI" [ref=e38] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=screen&f=browse
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e40]: BI
|
||||||
|
- listitem [ref=e41]
|
||||||
|
- listitem [ref=e42]:
|
||||||
|
- link " 看板" [ref=e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=kanban&f=space
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- generic [ref=e45]: 看板
|
||||||
|
- listitem [ref=e46]:
|
||||||
|
- link " 文档" [ref=e47] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=doc&f=lastViewedSpace
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]: 文档
|
||||||
|
- listitem [ref=e50]
|
||||||
|
- listitem [ref=e51]:
|
||||||
|
- link " 组织" [ref=e52] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=team
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- generic [ref=e54]: 组织
|
||||||
|
- listitem [ref=e55]:
|
||||||
|
- link " 后台" [ref=e56] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=admin&f=index
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e58]: 后台
|
||||||
|
- text:
|
||||||
|
- list [ref=e60]:
|
||||||
|
- listitem [ref=e61]:
|
||||||
|
- generic [ref=e63] [cursor=pointer]:
|
||||||
|
- generic [ref=e65]:
|
||||||
|
- button " 研发综合界面" [ref=e67] [cursor=pointer]:
|
||||||
|
- generic [ref=e68]:
|
||||||
|
- generic [ref=e69]: 研发综合界面
|
||||||
|
- list
|
||||||
|
- generic [ref=e71]:
|
||||||
|
- button [ref=e73] [cursor=pointer]:
|
||||||
|
- img [ref=e75]
|
||||||
|
- link " 开源版21.7" [ref=e76] [cursor=pointer]:
|
||||||
|
- /url: https://www.zentao.net
|
||||||
|
- generic [ref=e77]:
|
||||||
|
- generic [ref=e78]: 开源版21.7
|
||||||
|
- button "升级 " [ref=e79] [cursor=pointer]:
|
||||||
|
- generic [ref=e80]: 升级
|
||||||
|
- generic [ref=e81]:
|
||||||
322
.playwright-mcp/page-2026-03-31T08-26-17-242Z.yml
Normal file
322
.playwright-mcp/page-2026-03-31T08-26-17-242Z.yml
Normal file
@@ -0,0 +1,322 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic [ref=e1]:
|
||||||
|
- generic [ref=e2]:
|
||||||
|
- list [ref=e3]:
|
||||||
|
- listitem [ref=e4]:
|
||||||
|
- link " 地盘" [ref=e5] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=index
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- generic [ref=e7]: 地盘
|
||||||
|
- listitem [ref=e8]:
|
||||||
|
- link " 项目集" [ref=e9] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=program&f=browse
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- generic [ref=e11]: 项目集
|
||||||
|
- listitem [ref=e12]:
|
||||||
|
- link " 产品" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=product&f=all
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e15]: 产品
|
||||||
|
- listitem [ref=e16]:
|
||||||
|
- link " 项目" [ref=e17] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=browse
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e19]: 项目
|
||||||
|
- listitem [ref=e20]:
|
||||||
|
- link " 执行" [ref=e21] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=execution&f=task
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: 执行
|
||||||
|
- listitem [ref=e24]:
|
||||||
|
- link " 测试" [ref=e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- generic [ref=e27]: 测试
|
||||||
|
- listitem [ref=e28]:
|
||||||
|
- link " DevOps" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=repo&f=maintain
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]: DevOps
|
||||||
|
- listitem [ref=e32]
|
||||||
|
- listitem [ref=e33]:
|
||||||
|
- link " AI" [ref=e34] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=aiapp&f=square
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]: AI
|
||||||
|
- listitem [ref=e37]:
|
||||||
|
- link " BI" [ref=e38] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=screen&f=browse
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e40]: BI
|
||||||
|
- listitem [ref=e41]
|
||||||
|
- listitem [ref=e42]:
|
||||||
|
- link " 看板" [ref=e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=kanban&f=space
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- generic [ref=e45]: 看板
|
||||||
|
- listitem [ref=e46]:
|
||||||
|
- link " 文档" [ref=e47] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=doc&f=lastViewedSpace
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]: 文档
|
||||||
|
- listitem [ref=e50]
|
||||||
|
- listitem [ref=e51]:
|
||||||
|
- link " 组织" [ref=e52] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=team
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- generic [ref=e54]: 组织
|
||||||
|
- listitem [ref=e55]:
|
||||||
|
- link " 后台" [ref=e56] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=admin&f=index
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e58]: 后台
|
||||||
|
- text:
|
||||||
|
- list [ref=e60]:
|
||||||
|
- listitem [ref=e61]:
|
||||||
|
- generic [ref=e63] [cursor=pointer]:
|
||||||
|
- iframe [ref=e83]:
|
||||||
|
- generic [active] [ref=f20e1]:
|
||||||
|
- banner [ref=f20e2]:
|
||||||
|
- generic [ref=f20e3]:
|
||||||
|
- generic [ref=f20e4]:
|
||||||
|
- link " 测试" [ref=f20e6] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=f20e7]:
|
||||||
|
- generic [ref=f20e8]: 测试
|
||||||
|
- button " 开源HIS改造落地" [ref=f20e10] [cursor=pointer]:
|
||||||
|
- generic [ref=f20e11]:
|
||||||
|
- generic "开源HIS改造落地" [ref=f20e12]
|
||||||
|
- navigation [ref=f20e15]:
|
||||||
|
- list [ref=f20e16]:
|
||||||
|
- listitem [ref=f20e17]:
|
||||||
|
- link "仪表盘" [ref=f20e18] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=f20e19]: 仪表盘
|
||||||
|
- listitem [ref=f20e20]
|
||||||
|
- listitem [ref=f20e21]:
|
||||||
|
- link "Bug" [ref=f20e22] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=browse&productID=4
|
||||||
|
- generic [ref=f20e23]: Bug
|
||||||
|
- listitem [ref=f20e24]:
|
||||||
|
- link "用例" [ref=f20e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testcase&f=browse&productID=4
|
||||||
|
- generic [ref=f20e26]: 用例
|
||||||
|
- listitem [ref=f20e27]:
|
||||||
|
- link "套件" [ref=f20e28] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testsuite&f=browse&productID=4
|
||||||
|
- generic [ref=f20e29]: 套件
|
||||||
|
- listitem [ref=f20e30]
|
||||||
|
- listitem [ref=f20e31]:
|
||||||
|
- link "测试单" [ref=f20e32] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testtask&f=browse&productID=4
|
||||||
|
- generic [ref=f20e33]: 测试单
|
||||||
|
- listitem [ref=f20e34]:
|
||||||
|
- link "测试报告" [ref=f20e35] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testreport&f=browse&productID=4
|
||||||
|
- generic [ref=f20e36]: 测试报告
|
||||||
|
- listitem [ref=f20e37]
|
||||||
|
- listitem [ref=f20e38]:
|
||||||
|
- link "用例库" [ref=f20e39] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=caselib&f=browse&libID=0
|
||||||
|
- generic [ref=f20e40]: 用例库
|
||||||
|
- listitem [ref=f20e41]
|
||||||
|
- listitem [ref=f20e42]:
|
||||||
|
- link "自动化" [ref=f20e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=zanode&f=instruction
|
||||||
|
- generic [ref=f20e44]: 自动化
|
||||||
|
- generic [ref=f20e46]:
|
||||||
|
- button "" [ref=f20e47] [cursor=pointer]:
|
||||||
|
- generic [ref=f20e48]:
|
||||||
|
- button " 9" [ref=f20e49] [cursor=pointer]:
|
||||||
|
- generic [ref=f20e50]:
|
||||||
|
- generic [ref=f20e51]: "9"
|
||||||
|
- generic [ref=f20e54] [cursor=pointer]: A
|
||||||
|
- generic [ref=f20e57]:
|
||||||
|
- generic [ref=f20e58]:
|
||||||
|
- generic [ref=f20e59]:
|
||||||
|
- button " 返回" [ref=f20e60] [cursor=pointer]:
|
||||||
|
- generic [ref=f20e61]:
|
||||||
|
- generic [ref=f20e62]: 返回
|
||||||
|
- generic [ref=f20e63]:
|
||||||
|
- generic [ref=f20e64]: "306"
|
||||||
|
- generic [ref=f20e65]: 手术管理-》门诊手术安排:手术申请查询未过滤掉已安排的手术申请单
|
||||||
|
- link " 提Bug" [ref=f20e68] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=create&productID=4&branch=0&extras=projectID=11,executionID=0,moduleID=126
|
||||||
|
- generic [ref=f20e69]:
|
||||||
|
- generic [ref=f20e70]: 提Bug
|
||||||
|
- generic [ref=f20e71]:
|
||||||
|
- generic [ref=f20e72]:
|
||||||
|
- generic [ref=f20e74]:
|
||||||
|
- generic [ref=f20e76]: 重现步骤
|
||||||
|
- generic [ref=f20e78]:
|
||||||
|
- paragraph [ref=f20e79]: "[步骤]"
|
||||||
|
- paragraph [ref=f20e80]:
|
||||||
|
- link "index.php?m=file&f=read&t=png&fileID=1415" [ref=f20e81] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=file&f=read&t=png&fileID=1415
|
||||||
|
- img "index.php?m=file&f=read&t=png&fileID=1415" [ref=f20e82]
|
||||||
|
- paragraph [ref=f20e83]: 图1
|
||||||
|
- paragraph [ref=f20e84]: 1、如上图1所示:手术管理-》门诊手术安排:手术申请查询未过滤掉已安排的手术申请单。
|
||||||
|
- paragraph [ref=f20e85]: "[结果]"
|
||||||
|
- paragraph [ref=f20e86]: 1、手术管理-》门诊手术安排:手术申请查询未过滤掉已安排的手术申请单。
|
||||||
|
- paragraph [ref=f20e87]: "[期望]"
|
||||||
|
- paragraph [ref=f20e88]: 1、手术管理-》门诊手术安排:手术申请查询过滤掉已安排的手术申请单。
|
||||||
|
- generic [ref=f20e90]:
|
||||||
|
- generic [ref=f20e94]:
|
||||||
|
- generic [ref=f20e95]: 历史记录
|
||||||
|
- navigation [ref=f20e96]:
|
||||||
|
- button "" [ref=f20e97] [cursor=pointer]:
|
||||||
|
- generic [ref=f20e98]:
|
||||||
|
- button " 添加备注" [ref=f20e99] [cursor=pointer]:
|
||||||
|
- generic [ref=f20e100]:
|
||||||
|
- generic [ref=f20e101]: 添加备注
|
||||||
|
- list [ref=f20e103]:
|
||||||
|
- listitem [ref=f20e104]:
|
||||||
|
- generic [ref=f20e105]:
|
||||||
|
- generic [ref=f20e107]: "1"
|
||||||
|
- generic [ref=f20e110]:
|
||||||
|
- text: 2026-03-30 17:01:33, 由
|
||||||
|
- strong [ref=f20e111]: 陈显精
|
||||||
|
- text: 创建。
|
||||||
|
- listitem [ref=f20e112]:
|
||||||
|
- generic [ref=f20e113]:
|
||||||
|
- generic [ref=f20e115]: "2"
|
||||||
|
- generic [ref=f20e118]:
|
||||||
|
- text: 2026-03-30 17:01:45, 由
|
||||||
|
- strong [ref=f20e119]: 陈显精
|
||||||
|
- text: 指派给
|
||||||
|
- strong [ref=f20e120]: 王怡哲
|
||||||
|
- text: 。
|
||||||
|
- generic [ref=f20e123]:
|
||||||
|
- button " 返回" [ref=f20e124] [cursor=pointer]:
|
||||||
|
- generic [ref=f20e125]:
|
||||||
|
- generic [ref=f20e126]: 返回
|
||||||
|
- link " 确认" [ref=f20e128] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=confirm&bugID=306
|
||||||
|
- generic [ref=f20e129]:
|
||||||
|
- generic [ref=f20e130]: 确认
|
||||||
|
- link " 指派" [ref=f20e131] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=assignTo&bugID=306
|
||||||
|
- generic [ref=f20e132]:
|
||||||
|
- generic [ref=f20e133]: 指派
|
||||||
|
- link " 解决" [ref=f20e134] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=resolve&bugID=306
|
||||||
|
- generic [ref=f20e135]:
|
||||||
|
- generic [ref=f20e136]: 解决
|
||||||
|
- button " 转研发需求" [ref=f20e137] [cursor=pointer]:
|
||||||
|
- generic [ref=f20e138]:
|
||||||
|
- generic [ref=f20e139]: 转研发需求
|
||||||
|
- button " 转任务" [ref=f20e140] [cursor=pointer]:
|
||||||
|
- generic [ref=f20e141]:
|
||||||
|
- generic [ref=f20e142]: 转任务
|
||||||
|
- link " 创建用例" [ref=f20e143] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testcase&f=create&productID=4&branch=0&moduleID=0&from=bug&bugID=306
|
||||||
|
- generic [ref=f20e144]:
|
||||||
|
- generic [ref=f20e145]: 创建用例
|
||||||
|
- link "" [ref=f20e147] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=edit&bugID=306
|
||||||
|
- generic [ref=f20e148]:
|
||||||
|
- link "" [ref=f20e149] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=create&productID=4&branch=0&extra=bugID=306,projectID=11,executionID=0
|
||||||
|
- generic [ref=f20e150]:
|
||||||
|
- link "" [ref=f20e151] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=delete&bugID=306
|
||||||
|
- generic [ref=f20e152]:
|
||||||
|
- generic [ref=f20e153]:
|
||||||
|
- generic [ref=f20e154]:
|
||||||
|
- generic [ref=f20e155]:
|
||||||
|
- list [ref=f20e156]:
|
||||||
|
- listitem [ref=f20e157]:
|
||||||
|
- link "基本信息" [ref=f20e158] [cursor=pointer]:
|
||||||
|
- /url: "#zin_bug_view_306_tabPane"
|
||||||
|
- generic [ref=f20e159]: 基本信息
|
||||||
|
- listitem [ref=f20e160]:
|
||||||
|
- link "Bug的一生" [ref=f20e161] [cursor=pointer]:
|
||||||
|
- /url: "#zin_bug_view_306_tabPane_1"
|
||||||
|
- generic [ref=f20e162]: Bug的一生
|
||||||
|
- button "" [ref=f20e163] [cursor=pointer]:
|
||||||
|
- generic [ref=f20e164]:
|
||||||
|
- generic [ref=f20e167]:
|
||||||
|
- generic [ref=f20e168]:
|
||||||
|
- generic "所属模块" [ref=f20e169]
|
||||||
|
- list [ref=f20e171]:
|
||||||
|
- listitem [ref=f20e172]: 手术麻醉管理
|
||||||
|
- generic "所属计划" [ref=f20e174]
|
||||||
|
- generic "来源用例" [ref=f20e177]
|
||||||
|
- generic [ref=f20e179]:
|
||||||
|
- generic "Bug类型" [ref=f20e180]
|
||||||
|
- generic [ref=f20e181]: 代码错误
|
||||||
|
- generic [ref=f20e182]:
|
||||||
|
- generic "严重程度" [ref=f20e183]
|
||||||
|
- generic [ref=f20e185]: 3 3
|
||||||
|
- generic [ref=f20e186]:
|
||||||
|
- generic "优先级" [ref=f20e187]
|
||||||
|
- generic [ref=f20e189]: "3"
|
||||||
|
- generic [ref=f20e190]:
|
||||||
|
- generic "Bug状态" [ref=f20e191]
|
||||||
|
- generic [ref=f20e193]: 激活
|
||||||
|
- generic "激活次数" [ref=f20e195]
|
||||||
|
- generic "激活时间" [ref=f20e198]
|
||||||
|
- generic [ref=f20e200]:
|
||||||
|
- generic "是否确认" [ref=f20e201]
|
||||||
|
- generic [ref=f20e202]: 未确认
|
||||||
|
- generic [ref=f20e203]:
|
||||||
|
- generic "指派给" [ref=f20e204]
|
||||||
|
- generic [ref=f20e205]: 王怡哲 于 2026-03-30 17:01:31
|
||||||
|
- generic "截止日期" [ref=f20e207]
|
||||||
|
- generic "反馈者" [ref=f20e210]
|
||||||
|
- generic "通知邮箱" [ref=f20e213]
|
||||||
|
- generic "操作系统" [ref=f20e216]
|
||||||
|
- generic "浏览器" [ref=f20e219]
|
||||||
|
- generic "关键词" [ref=f20e222]
|
||||||
|
- generic "抄送给" [ref=f20e225]
|
||||||
|
- generic [ref=f20e227]:
|
||||||
|
- generic [ref=f20e228]:
|
||||||
|
- list [ref=f20e229]:
|
||||||
|
- listitem [ref=f20e230]:
|
||||||
|
- link "项目/迭代/研发需求/任务" [ref=f20e231] [cursor=pointer]:
|
||||||
|
- /url: "#zin_bug_view_306_tabPane_2"
|
||||||
|
- generic [ref=f20e232]: 项目/迭代/研发需求/任务
|
||||||
|
- listitem [ref=f20e233]:
|
||||||
|
- link "其他相关" [ref=f20e234] [cursor=pointer]:
|
||||||
|
- /url: "#zin_bug_view_306_tabPane_3"
|
||||||
|
- generic [ref=f20e235]: 其他相关
|
||||||
|
- button "" [ref=f20e236] [cursor=pointer]:
|
||||||
|
- generic [ref=f20e237]:
|
||||||
|
- generic [ref=f20e240]:
|
||||||
|
- generic [ref=f20e241]:
|
||||||
|
- generic "所属项目" [ref=f20e242]
|
||||||
|
- link "开源HIS改造落地" [ref=f20e244] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=view&projectID=11
|
||||||
|
- generic "所属执行" [ref=f20e246]
|
||||||
|
- generic "相关需求" [ref=f20e249]
|
||||||
|
- generic "相关任务" [ref=f20e252]
|
||||||
|
- button "" [ref=f20e255] [cursor=pointer]:
|
||||||
|
- generic [ref=f20e256]:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- link "" [ref=f20e257] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=view&bugID=307
|
||||||
|
- generic [ref=f20e258]:
|
||||||
|
- link "" [ref=f20e259] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=view&bugID=305
|
||||||
|
- generic [ref=f20e260]:
|
||||||
|
- text: "* *"
|
||||||
|
- generic [ref=e65]:
|
||||||
|
- button " 研发综合界面" [ref=e67] [cursor=pointer]:
|
||||||
|
- generic [ref=e68]:
|
||||||
|
- generic [ref=e69]: 研发综合界面
|
||||||
|
- list [ref=e84]:
|
||||||
|
- listitem [ref=e85]:
|
||||||
|
- generic [ref=e87] [cursor=pointer]: 测试
|
||||||
|
- generic [ref=e71]:
|
||||||
|
- textbox [ref=e93]:
|
||||||
|
- /placeholder: 搜索
|
||||||
|
- button [ref=e73] [cursor=pointer]:
|
||||||
|
- img [ref=e75]
|
||||||
|
- link " 开源版21.7" [ref=e76] [cursor=pointer]:
|
||||||
|
- /url: https://www.zentao.net
|
||||||
|
- generic [ref=e77]:
|
||||||
|
- generic [ref=e78]: 开源版21.7
|
||||||
|
- button "升级 " [ref=e79] [cursor=pointer]:
|
||||||
|
- generic [ref=e80]: 升级
|
||||||
|
- generic [ref=e81]:
|
||||||
93
.playwright-mcp/page-2026-03-31T08-27-31-803Z.yml
Normal file
93
.playwright-mcp/page-2026-03-31T08-27-31-803Z.yml
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic [ref=e1]:
|
||||||
|
- generic [ref=e2]:
|
||||||
|
- list [ref=e3]:
|
||||||
|
- listitem [ref=e4]:
|
||||||
|
- link " 地盘" [ref=e5] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=index
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- generic [ref=e7]: 地盘
|
||||||
|
- listitem [ref=e8]:
|
||||||
|
- link " 项目集" [ref=e9] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=program&f=browse
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- generic [ref=e11]: 项目集
|
||||||
|
- listitem [ref=e12]:
|
||||||
|
- link " 产品" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=product&f=all
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e15]: 产品
|
||||||
|
- listitem [ref=e16]:
|
||||||
|
- link " 项目" [ref=e17] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=browse
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e19]: 项目
|
||||||
|
- listitem [ref=e20]:
|
||||||
|
- link " 执行" [ref=e21] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=execution&f=task
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: 执行
|
||||||
|
- listitem [ref=e24]:
|
||||||
|
- link " 测试" [ref=e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- generic [ref=e27]: 测试
|
||||||
|
- listitem [ref=e28]:
|
||||||
|
- link " DevOps" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=repo&f=maintain
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]: DevOps
|
||||||
|
- listitem [ref=e32]
|
||||||
|
- listitem [ref=e33]:
|
||||||
|
- link " AI" [ref=e34] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=aiapp&f=square
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]: AI
|
||||||
|
- listitem [ref=e37]:
|
||||||
|
- link " BI" [ref=e38] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=screen&f=browse
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e40]: BI
|
||||||
|
- listitem [ref=e41]
|
||||||
|
- listitem [ref=e42]:
|
||||||
|
- link " 看板" [ref=e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=kanban&f=space
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- generic [ref=e45]: 看板
|
||||||
|
- listitem [ref=e46]:
|
||||||
|
- link " 文档" [ref=e47] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=doc&f=lastViewedSpace
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]: 文档
|
||||||
|
- listitem [ref=e50]
|
||||||
|
- listitem [ref=e51]:
|
||||||
|
- link " 组织" [ref=e52] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=team
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- generic [ref=e54]: 组织
|
||||||
|
- listitem [ref=e55]:
|
||||||
|
- link " 后台" [ref=e56] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=admin&f=index
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e58]: 后台
|
||||||
|
- text:
|
||||||
|
- list [ref=e60]:
|
||||||
|
- listitem [ref=e61]:
|
||||||
|
- generic [ref=e63] [cursor=pointer]:
|
||||||
|
- generic [ref=e65]:
|
||||||
|
- button " 研发综合界面" [ref=e67] [cursor=pointer]:
|
||||||
|
- generic [ref=e68]:
|
||||||
|
- generic [ref=e69]: 研发综合界面
|
||||||
|
- list
|
||||||
|
- generic [ref=e71]:
|
||||||
|
- textbox [ref=e77]:
|
||||||
|
- /placeholder: 搜索
|
||||||
|
- button [ref=e79] [cursor=pointer]:
|
||||||
|
- img [ref=e81]
|
||||||
|
- link " 开源版21.7" [ref=e82] [cursor=pointer]:
|
||||||
|
- /url: https://www.zentao.net
|
||||||
|
- generic [ref=e83]:
|
||||||
|
- generic [ref=e84]: 开源版21.7
|
||||||
|
- button "升级 " [ref=e85] [cursor=pointer]:
|
||||||
|
- generic [ref=e86]: 升级
|
||||||
|
- generic [ref=e87]:
|
||||||
337
.playwright-mcp/page-2026-03-31T08-28-02-195Z.yml
Normal file
337
.playwright-mcp/page-2026-03-31T08-28-02-195Z.yml
Normal file
@@ -0,0 +1,337 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic [ref=e1]:
|
||||||
|
- generic [ref=e2]:
|
||||||
|
- list [ref=e3]:
|
||||||
|
- listitem [ref=e4]:
|
||||||
|
- link " 地盘" [ref=e5] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=index
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- generic [ref=e7]: 地盘
|
||||||
|
- listitem [ref=e8]:
|
||||||
|
- link " 项目集" [ref=e9] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=program&f=browse
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- generic [ref=e11]: 项目集
|
||||||
|
- listitem [ref=e12]:
|
||||||
|
- link " 产品" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=product&f=all
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e15]: 产品
|
||||||
|
- listitem [ref=e16]:
|
||||||
|
- link " 项目" [ref=e17] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=browse
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e19]: 项目
|
||||||
|
- listitem [ref=e20]:
|
||||||
|
- link " 执行" [ref=e21] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=execution&f=task
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: 执行
|
||||||
|
- listitem [ref=e24]:
|
||||||
|
- link " 测试" [ref=e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- generic [ref=e27]: 测试
|
||||||
|
- listitem [ref=e28]:
|
||||||
|
- link " DevOps" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=repo&f=maintain
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]: DevOps
|
||||||
|
- listitem [ref=e32]
|
||||||
|
- listitem [ref=e33]:
|
||||||
|
- link " AI" [ref=e34] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=aiapp&f=square
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]: AI
|
||||||
|
- listitem [ref=e37]:
|
||||||
|
- link " BI" [ref=e38] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=screen&f=browse
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e40]: BI
|
||||||
|
- listitem [ref=e41]
|
||||||
|
- listitem [ref=e42]:
|
||||||
|
- link " 看板" [ref=e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=kanban&f=space
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- generic [ref=e45]: 看板
|
||||||
|
- listitem [ref=e46]:
|
||||||
|
- link " 文档" [ref=e47] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=doc&f=lastViewedSpace
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]: 文档
|
||||||
|
- listitem [ref=e50]
|
||||||
|
- listitem [ref=e51]:
|
||||||
|
- link " 组织" [ref=e52] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=team
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- generic [ref=e54]: 组织
|
||||||
|
- listitem [ref=e55]:
|
||||||
|
- link " 后台" [ref=e56] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=admin&f=index
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e58]: 后台
|
||||||
|
- text:
|
||||||
|
- list [ref=e60]:
|
||||||
|
- listitem [ref=e61]:
|
||||||
|
- generic [ref=e63] [cursor=pointer]:
|
||||||
|
- iframe [ref=e89]:
|
||||||
|
- generic [active] [ref=f1e1]:
|
||||||
|
- banner [ref=f1e2]:
|
||||||
|
- generic [ref=f1e3]:
|
||||||
|
- generic [ref=f1e4]:
|
||||||
|
- link " 测试" [ref=f1e6] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=f1e7]:
|
||||||
|
- generic [ref=f1e8]: 测试
|
||||||
|
- button " 开源HIS改造落地" [ref=f1e10] [cursor=pointer]:
|
||||||
|
- generic [ref=f1e11]:
|
||||||
|
- generic "开源HIS改造落地" [ref=f1e12]
|
||||||
|
- navigation [ref=f1e15]:
|
||||||
|
- list [ref=f1e16]:
|
||||||
|
- listitem [ref=f1e17]:
|
||||||
|
- link "仪表盘" [ref=f1e18] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=f1e19]: 仪表盘
|
||||||
|
- listitem [ref=f1e20]
|
||||||
|
- listitem [ref=f1e21]:
|
||||||
|
- link "Bug" [ref=f1e22] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=browse&productID=4
|
||||||
|
- generic [ref=f1e23]: Bug
|
||||||
|
- listitem [ref=f1e24]:
|
||||||
|
- link "用例" [ref=f1e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testcase&f=browse&productID=4
|
||||||
|
- generic [ref=f1e26]: 用例
|
||||||
|
- listitem [ref=f1e27]:
|
||||||
|
- link "套件" [ref=f1e28] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testsuite&f=browse&productID=4
|
||||||
|
- generic [ref=f1e29]: 套件
|
||||||
|
- listitem [ref=f1e30]
|
||||||
|
- listitem [ref=f1e31]:
|
||||||
|
- link "测试单" [ref=f1e32] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testtask&f=browse&productID=4
|
||||||
|
- generic [ref=f1e33]: 测试单
|
||||||
|
- listitem [ref=f1e34]:
|
||||||
|
- link "测试报告" [ref=f1e35] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testreport&f=browse&productID=4
|
||||||
|
- generic [ref=f1e36]: 测试报告
|
||||||
|
- listitem [ref=f1e37]
|
||||||
|
- listitem [ref=f1e38]:
|
||||||
|
- link "用例库" [ref=f1e39] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=caselib&f=browse&libID=0
|
||||||
|
- generic [ref=f1e40]: 用例库
|
||||||
|
- listitem [ref=f1e41]
|
||||||
|
- listitem [ref=f1e42]:
|
||||||
|
- link "自动化" [ref=f1e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=zanode&f=instruction
|
||||||
|
- generic [ref=f1e44]: 自动化
|
||||||
|
- generic [ref=f1e46]:
|
||||||
|
- button "" [ref=f1e47] [cursor=pointer]:
|
||||||
|
- generic [ref=f1e48]:
|
||||||
|
- button " 9" [ref=f1e49] [cursor=pointer]:
|
||||||
|
- generic [ref=f1e50]:
|
||||||
|
- generic [ref=f1e51]: "9"
|
||||||
|
- generic [ref=f1e54] [cursor=pointer]: A
|
||||||
|
- generic [ref=f1e57]:
|
||||||
|
- generic [ref=f1e58]:
|
||||||
|
- generic [ref=f1e59]:
|
||||||
|
- button " 返回" [ref=f1e60] [cursor=pointer]:
|
||||||
|
- generic [ref=f1e61]:
|
||||||
|
- generic [ref=f1e62]: 返回
|
||||||
|
- generic [ref=f1e63]:
|
||||||
|
- generic [ref=f1e64]: "307"
|
||||||
|
- generic [ref=f1e65]: 门诊医生站:开立的手术申请后未关联生成预手术收费明细记录
|
||||||
|
- link " 提Bug" [ref=f1e68] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=create&productID=4&branch=0&extras=projectID=11,executionID=0,moduleID=126
|
||||||
|
- generic [ref=f1e69]:
|
||||||
|
- generic [ref=f1e70]: 提Bug
|
||||||
|
- generic [ref=f1e71]:
|
||||||
|
- generic [ref=f1e72]:
|
||||||
|
- generic [ref=f1e74]:
|
||||||
|
- generic [ref=f1e76]: 重现步骤
|
||||||
|
- generic [ref=f1e78]:
|
||||||
|
- paragraph [ref=f1e79]: "[步骤]"
|
||||||
|
- paragraph [ref=f1e80]:
|
||||||
|
- link "index.php?m=file&f=read&t=png&fileID=1416" [ref=f1e81] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=file&f=read&t=png&fileID=1416
|
||||||
|
- img "index.php?m=file&f=read&t=png&fileID=1416" [ref=f1e82]
|
||||||
|
- paragraph [ref=f1e83]: 图1:门诊医生站:手术申请
|
||||||
|
- paragraph [ref=f1e84]
|
||||||
|
- paragraph [ref=f1e85]:
|
||||||
|
- link "index.php?m=file&f=read&t=png&fileID=1417" [ref=f1e86] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=file&f=read&t=png&fileID=1417
|
||||||
|
- img "index.php?m=file&f=read&t=png&fileID=1417" [ref=f1e87]
|
||||||
|
- paragraph [ref=f1e88]: 图2:手术申请开立成功
|
||||||
|
- paragraph [ref=f1e89]
|
||||||
|
- paragraph [ref=f1e90]:
|
||||||
|
- link "index.php?m=file&f=read&t=png&fileID=1418" [ref=f1e91] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=file&f=read&t=png&fileID=1418
|
||||||
|
- img "index.php?m=file&f=read&t=png&fileID=1418" [ref=f1e92]
|
||||||
|
- paragraph [ref=f1e93]: 图3:《门诊收费》检索不到待缴费手术费用。
|
||||||
|
- paragraph [ref=f1e94]: 1、如上图1、2、3所示:门诊医生站:开立的手术申请后未关联生成预手术收费明细记录。
|
||||||
|
- paragraph [ref=f1e95]: "[结果]"
|
||||||
|
- paragraph [ref=f1e96]: 1、门诊医生站:开立的手术申请后未关联生成预手术收费明细记录。
|
||||||
|
- paragraph [ref=f1e97]: "[期望]"
|
||||||
|
- paragraph [ref=f1e98]:
|
||||||
|
- text: 1、门诊医生站:开立的手术申请成功后,
|
||||||
|
- generic [ref=f1e99]:
|
||||||
|
- text: 系统应
|
||||||
|
- strong [ref=f1e100]: 自动将手术收项目明细插入预收费明细表
|
||||||
|
- text: 中,确保《门诊收费》处能够实时看见并进行结算,如下图4文档所示:
|
||||||
|
- paragraph [ref=f1e101]:
|
||||||
|
- link "index.php?m=file&f=read&t=png&fileID=1419" [ref=f1e102] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=file&f=read&t=png&fileID=1419
|
||||||
|
- img "index.php?m=file&f=read&t=png&fileID=1419" [ref=f1e103]
|
||||||
|
- paragraph [ref=f1e104]: 图4
|
||||||
|
- paragraph [ref=f1e105]
|
||||||
|
- generic [ref=f1e107]:
|
||||||
|
- generic [ref=f1e111]:
|
||||||
|
- generic [ref=f1e112]: 历史记录
|
||||||
|
- navigation [ref=f1e113]:
|
||||||
|
- button "" [ref=f1e114] [cursor=pointer]:
|
||||||
|
- generic [ref=f1e115]:
|
||||||
|
- button " 添加备注" [ref=f1e116] [cursor=pointer]:
|
||||||
|
- generic [ref=f1e117]:
|
||||||
|
- generic [ref=f1e118]: 添加备注
|
||||||
|
- list [ref=f1e120]:
|
||||||
|
- listitem [ref=f1e121]:
|
||||||
|
- generic [ref=f1e122]:
|
||||||
|
- generic [ref=f1e124]: "1"
|
||||||
|
- generic [ref=f1e127]:
|
||||||
|
- text: 2026-03-30 17:44:22, 由
|
||||||
|
- strong [ref=f1e128]: 陈显精
|
||||||
|
- text: 创建。
|
||||||
|
- listitem [ref=f1e129]:
|
||||||
|
- generic [ref=f1e130]:
|
||||||
|
- generic [ref=f1e132]: "2"
|
||||||
|
- generic [ref=f1e135]:
|
||||||
|
- text: 2026-03-30 17:44:26, 由
|
||||||
|
- strong [ref=f1e136]: 陈显精
|
||||||
|
- text: 指派给
|
||||||
|
- strong [ref=f1e137]: 王怡哲
|
||||||
|
- text: 。
|
||||||
|
- generic [ref=f1e140]:
|
||||||
|
- button " 返回" [ref=f1e141] [cursor=pointer]:
|
||||||
|
- generic [ref=f1e142]:
|
||||||
|
- generic [ref=f1e143]: 返回
|
||||||
|
- link " 确认" [ref=f1e145] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=confirm&bugID=307
|
||||||
|
- generic [ref=f1e146]:
|
||||||
|
- generic [ref=f1e147]: 确认
|
||||||
|
- link " 指派" [ref=f1e148] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=assignTo&bugID=307
|
||||||
|
- generic [ref=f1e149]:
|
||||||
|
- generic [ref=f1e150]: 指派
|
||||||
|
- link " 解决" [ref=f1e151] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=resolve&bugID=307
|
||||||
|
- generic [ref=f1e152]:
|
||||||
|
- generic [ref=f1e153]: 解决
|
||||||
|
- button " 转研发需求" [ref=f1e154] [cursor=pointer]:
|
||||||
|
- generic [ref=f1e155]:
|
||||||
|
- generic [ref=f1e156]: 转研发需求
|
||||||
|
- button " 转任务" [ref=f1e157] [cursor=pointer]:
|
||||||
|
- generic [ref=f1e158]:
|
||||||
|
- generic [ref=f1e159]: 转任务
|
||||||
|
- link " 创建用例" [ref=f1e160] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testcase&f=create&productID=4&branch=0&moduleID=0&from=bug&bugID=307
|
||||||
|
- generic [ref=f1e161]:
|
||||||
|
- generic [ref=f1e162]: 创建用例
|
||||||
|
- link "" [ref=f1e164] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=edit&bugID=307
|
||||||
|
- generic [ref=f1e165]:
|
||||||
|
- link "" [ref=f1e166] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=create&productID=4&branch=0&extra=bugID=307,projectID=11,executionID=0
|
||||||
|
- generic [ref=f1e167]:
|
||||||
|
- link "" [ref=f1e168] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=delete&bugID=307
|
||||||
|
- generic [ref=f1e169]:
|
||||||
|
- generic [ref=f1e170]:
|
||||||
|
- generic [ref=f1e171]:
|
||||||
|
- generic [ref=f1e172]:
|
||||||
|
- list [ref=f1e173]:
|
||||||
|
- listitem [ref=f1e174]:
|
||||||
|
- link "基本信息" [ref=f1e175] [cursor=pointer]:
|
||||||
|
- /url: "#zin_bug_view_307_tabPane"
|
||||||
|
- generic [ref=f1e176]: 基本信息
|
||||||
|
- listitem [ref=f1e177]:
|
||||||
|
- link "Bug的一生" [ref=f1e178] [cursor=pointer]:
|
||||||
|
- /url: "#zin_bug_view_307_tabPane_1"
|
||||||
|
- generic [ref=f1e179]: Bug的一生
|
||||||
|
- button "" [ref=f1e180] [cursor=pointer]:
|
||||||
|
- generic [ref=f1e181]:
|
||||||
|
- generic [ref=f1e184]:
|
||||||
|
- generic [ref=f1e185]:
|
||||||
|
- generic "所属模块" [ref=f1e186]
|
||||||
|
- list [ref=f1e188]:
|
||||||
|
- listitem [ref=f1e189]: 手术麻醉管理
|
||||||
|
- generic "所属计划" [ref=f1e191]
|
||||||
|
- generic "来源用例" [ref=f1e194]
|
||||||
|
- generic [ref=f1e196]:
|
||||||
|
- generic "Bug类型" [ref=f1e197]
|
||||||
|
- generic [ref=f1e198]: 设计缺陷
|
||||||
|
- generic [ref=f1e199]:
|
||||||
|
- generic "严重程度" [ref=f1e200]
|
||||||
|
- generic [ref=f1e202]: 3 3
|
||||||
|
- generic [ref=f1e203]:
|
||||||
|
- generic "优先级" [ref=f1e204]
|
||||||
|
- generic [ref=f1e206]: "3"
|
||||||
|
- generic [ref=f1e207]:
|
||||||
|
- generic "Bug状态" [ref=f1e208]
|
||||||
|
- generic [ref=f1e210]: 激活
|
||||||
|
- generic "激活次数" [ref=f1e212]
|
||||||
|
- generic "激活时间" [ref=f1e215]
|
||||||
|
- generic [ref=f1e217]:
|
||||||
|
- generic "是否确认" [ref=f1e218]
|
||||||
|
- generic [ref=f1e219]: 未确认
|
||||||
|
- generic [ref=f1e220]:
|
||||||
|
- generic "指派给" [ref=f1e221]
|
||||||
|
- generic [ref=f1e222]: 王怡哲 于 2026-03-30 17:44:22
|
||||||
|
- generic "截止日期" [ref=f1e224]
|
||||||
|
- generic "反馈者" [ref=f1e227]
|
||||||
|
- generic "通知邮箱" [ref=f1e230]
|
||||||
|
- generic "操作系统" [ref=f1e233]
|
||||||
|
- generic "浏览器" [ref=f1e236]
|
||||||
|
- generic "关键词" [ref=f1e239]
|
||||||
|
- generic "抄送给" [ref=f1e242]
|
||||||
|
- generic [ref=f1e244]:
|
||||||
|
- generic [ref=f1e245]:
|
||||||
|
- list [ref=f1e246]:
|
||||||
|
- listitem [ref=f1e247]:
|
||||||
|
- link "项目/迭代/研发需求/任务" [ref=f1e248] [cursor=pointer]:
|
||||||
|
- /url: "#zin_bug_view_307_tabPane_2"
|
||||||
|
- generic [ref=f1e249]: 项目/迭代/研发需求/任务
|
||||||
|
- listitem [ref=f1e250]:
|
||||||
|
- link "其他相关" [ref=f1e251] [cursor=pointer]:
|
||||||
|
- /url: "#zin_bug_view_307_tabPane_3"
|
||||||
|
- generic [ref=f1e252]: 其他相关
|
||||||
|
- button "" [ref=f1e253] [cursor=pointer]:
|
||||||
|
- generic [ref=f1e254]:
|
||||||
|
- generic [ref=f1e257]:
|
||||||
|
- generic [ref=f1e258]:
|
||||||
|
- generic "所属项目" [ref=f1e259]
|
||||||
|
- link "开源HIS改造落地" [ref=f1e261] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=view&projectID=11
|
||||||
|
- generic "所属执行" [ref=f1e263]
|
||||||
|
- generic "相关需求" [ref=f1e266]
|
||||||
|
- generic "相关任务" [ref=f1e269]
|
||||||
|
- button "" [ref=f1e272] [cursor=pointer]:
|
||||||
|
- generic [ref=f1e273]:
|
||||||
|
- text: "* *"
|
||||||
|
- generic [ref=e65]:
|
||||||
|
- button " 研发综合界面" [ref=e67] [cursor=pointer]:
|
||||||
|
- generic [ref=e68]:
|
||||||
|
- generic [ref=e69]: 研发综合界面
|
||||||
|
- list [ref=e90]:
|
||||||
|
- listitem [ref=e91]:
|
||||||
|
- generic [ref=e93] [cursor=pointer]: 测试
|
||||||
|
- generic [ref=e71]:
|
||||||
|
- textbox [ref=e77]:
|
||||||
|
- /placeholder: 搜索
|
||||||
|
- button [ref=e79] [cursor=pointer]:
|
||||||
|
- img [ref=e81]
|
||||||
|
- link " 开源版21.7" [ref=e82] [cursor=pointer]:
|
||||||
|
- /url: https://www.zentao.net
|
||||||
|
- generic [ref=e83]:
|
||||||
|
- generic [ref=e84]: 开源版21.7
|
||||||
|
- button "升级 " [ref=e85] [cursor=pointer]:
|
||||||
|
- generic [ref=e86]: 升级
|
||||||
|
- generic [ref=e87]:
|
||||||
23
.playwright-mcp/page-2026-04-02T03-09-24-226Z.yml
Normal file
23
.playwright-mcp/page-2026-04-02T03-09-24-226Z.yml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
- generic [ref=e5]:
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- img [ref=e7]
|
||||||
|
- img [ref=e8]
|
||||||
|
- generic [ref=e9]:
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- heading "经创贺联项目管理系统" [level=2] [ref=e11]
|
||||||
|
- generic [ref=e12]: 简体
|
||||||
|
- generic [ref=e13]:
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e16]: 用户名
|
||||||
|
- textbox [active] [ref=e17]: admin
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e20]: 密码
|
||||||
|
- textbox [ref=e21]: Jchl1528
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e24]:
|
||||||
|
- checkbox "保持登录" [checked] [ref=e25]
|
||||||
|
- generic [ref=e26] [cursor=pointer]: 保持登录
|
||||||
|
- link "忘记密码" [ref=e27] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=user&f=reset
|
||||||
|
- button "登录" [ref=e29] [cursor=pointer]:
|
||||||
|
- generic [ref=e30]: 登录
|
||||||
1039
.playwright-mcp/page-2026-04-02T03-09-41-642Z.yml
Normal file
1039
.playwright-mcp/page-2026-04-02T03-09-41-642Z.yml
Normal file
File diff suppressed because it is too large
Load Diff
93
.playwright-mcp/page-2026-04-02T03-09-57-124Z.yml
Normal file
93
.playwright-mcp/page-2026-04-02T03-09-57-124Z.yml
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic [ref=e1]:
|
||||||
|
- generic [ref=e2]:
|
||||||
|
- list [ref=e3]:
|
||||||
|
- listitem [ref=e4]:
|
||||||
|
- link " 地盘" [ref=e5] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=index
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- generic [ref=e7]: 地盘
|
||||||
|
- listitem [ref=e8]:
|
||||||
|
- link " 项目集" [ref=e9] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=program&f=browse
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- generic [ref=e11]: 项目集
|
||||||
|
- listitem [ref=e12]:
|
||||||
|
- link " 产品" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=product&f=all
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e15]: 产品
|
||||||
|
- listitem [ref=e16]:
|
||||||
|
- link " 项目" [ref=e17] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=browse
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e19]: 项目
|
||||||
|
- listitem [ref=e20]:
|
||||||
|
- link " 执行" [ref=e21] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=execution&f=task
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: 执行
|
||||||
|
- listitem [ref=e24]:
|
||||||
|
- link " 测试" [ref=e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- generic [ref=e27]: 测试
|
||||||
|
- listitem [ref=e28]:
|
||||||
|
- link " DevOps" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=repo&f=maintain
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]: DevOps
|
||||||
|
- listitem [ref=e32]
|
||||||
|
- listitem [ref=e33]:
|
||||||
|
- link " AI" [ref=e34] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=aiapp&f=square
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]: AI
|
||||||
|
- listitem [ref=e37]:
|
||||||
|
- link " BI" [ref=e38] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=screen&f=browse
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e40]: BI
|
||||||
|
- listitem [ref=e41]
|
||||||
|
- listitem [ref=e42]:
|
||||||
|
- link " 看板" [ref=e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=kanban&f=space
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- generic [ref=e45]: 看板
|
||||||
|
- listitem [ref=e46]:
|
||||||
|
- link " 文档" [ref=e47] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=doc&f=lastViewedSpace
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]: 文档
|
||||||
|
- listitem [ref=e50]
|
||||||
|
- listitem [ref=e51]:
|
||||||
|
- link " 组织" [ref=e52] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=team
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- generic [ref=e54]: 组织
|
||||||
|
- listitem [ref=e55]:
|
||||||
|
- link " 后台" [ref=e56] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=admin&f=index
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e58]: 后台
|
||||||
|
- text:
|
||||||
|
- list [ref=e60]:
|
||||||
|
- listitem [ref=e61]:
|
||||||
|
- generic [ref=e63] [cursor=pointer]:
|
||||||
|
- generic [ref=e65]:
|
||||||
|
- button " 研发综合界面" [ref=e67] [cursor=pointer]:
|
||||||
|
- generic [ref=e68]:
|
||||||
|
- generic [ref=e69]: 研发综合界面
|
||||||
|
- list
|
||||||
|
- generic [ref=e71]:
|
||||||
|
- textbox [ref=e77]:
|
||||||
|
- /placeholder: 搜索
|
||||||
|
- button [ref=e79] [cursor=pointer]:
|
||||||
|
- img [ref=e81]
|
||||||
|
- link " 开源版21.7" [ref=e82] [cursor=pointer]:
|
||||||
|
- /url: https://www.zentao.net
|
||||||
|
- generic [ref=e83]:
|
||||||
|
- generic [ref=e84]: 开源版21.7
|
||||||
|
- button "升级 " [ref=e85] [cursor=pointer]:
|
||||||
|
- generic [ref=e86]: 升级
|
||||||
|
- generic [ref=e87]:
|
||||||
328
.playwright-mcp/page-2026-04-02T03-10-05-854Z.yml
Normal file
328
.playwright-mcp/page-2026-04-02T03-10-05-854Z.yml
Normal file
@@ -0,0 +1,328 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic [ref=e1]:
|
||||||
|
- generic [ref=e2]:
|
||||||
|
- list [ref=e3]:
|
||||||
|
- listitem [ref=e4]:
|
||||||
|
- link " 地盘" [ref=e5] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=index
|
||||||
|
- generic [ref=e6]:
|
||||||
|
- generic [ref=e7]: 地盘
|
||||||
|
- listitem [ref=e8]:
|
||||||
|
- link " 项目集" [ref=e9] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=program&f=browse
|
||||||
|
- generic [ref=e10]:
|
||||||
|
- generic [ref=e11]: 项目集
|
||||||
|
- listitem [ref=e12]:
|
||||||
|
- link " 产品" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=product&f=all
|
||||||
|
- generic [ref=e14]:
|
||||||
|
- generic [ref=e15]: 产品
|
||||||
|
- listitem [ref=e16]:
|
||||||
|
- link " 项目" [ref=e17] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=browse
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- generic [ref=e19]: 项目
|
||||||
|
- listitem [ref=e20]:
|
||||||
|
- link " 执行" [ref=e21] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=execution&f=task
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: 执行
|
||||||
|
- listitem [ref=e24]:
|
||||||
|
- link " 测试" [ref=e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- generic [ref=e27]: 测试
|
||||||
|
- listitem [ref=e28]:
|
||||||
|
- link " DevOps" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=repo&f=maintain
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]: DevOps
|
||||||
|
- listitem [ref=e32]
|
||||||
|
- listitem [ref=e33]:
|
||||||
|
- link " AI" [ref=e34] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=aiapp&f=square
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]: AI
|
||||||
|
- listitem [ref=e37]:
|
||||||
|
- link " BI" [ref=e38] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=screen&f=browse
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e40]: BI
|
||||||
|
- listitem [ref=e41]
|
||||||
|
- listitem [ref=e42]:
|
||||||
|
- link " 看板" [ref=e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=kanban&f=space
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- generic [ref=e45]: 看板
|
||||||
|
- listitem [ref=e46]:
|
||||||
|
- link " 文档" [ref=e47] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=doc&f=lastViewedSpace
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]: 文档
|
||||||
|
- listitem [ref=e50]
|
||||||
|
- listitem [ref=e51]:
|
||||||
|
- link " 组织" [ref=e52] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=my&f=team
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- generic [ref=e54]: 组织
|
||||||
|
- listitem [ref=e55]:
|
||||||
|
- link " 后台" [ref=e56] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=admin&f=index
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e58]: 后台
|
||||||
|
- text:
|
||||||
|
- list [ref=e60]:
|
||||||
|
- listitem [ref=e61]:
|
||||||
|
- generic [ref=e63] [cursor=pointer]:
|
||||||
|
- iframe [ref=e89]:
|
||||||
|
- generic [active] [ref=f3e1]:
|
||||||
|
- banner [ref=f3e2]:
|
||||||
|
- generic [ref=f3e3]:
|
||||||
|
- generic [ref=f3e4]:
|
||||||
|
- link " 测试" [ref=f3e6] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=f3e7]:
|
||||||
|
- generic [ref=f3e8]: 测试
|
||||||
|
- button " 开源HIS改造落地" [ref=f3e10] [cursor=pointer]:
|
||||||
|
- generic [ref=f3e11]:
|
||||||
|
- generic "开源HIS改造落地" [ref=f3e12]
|
||||||
|
- navigation [ref=f3e15]:
|
||||||
|
- list [ref=f3e16]:
|
||||||
|
- listitem [ref=f3e17]:
|
||||||
|
- link "仪表盘" [ref=f3e18] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=qa&f=index
|
||||||
|
- generic [ref=f3e19]: 仪表盘
|
||||||
|
- listitem [ref=f3e20]
|
||||||
|
- listitem [ref=f3e21]:
|
||||||
|
- link "Bug" [ref=f3e22] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=browse&productID=4
|
||||||
|
- generic [ref=f3e23]: Bug
|
||||||
|
- listitem [ref=f3e24]:
|
||||||
|
- link "用例" [ref=f3e25] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testcase&f=browse&productID=4
|
||||||
|
- generic [ref=f3e26]: 用例
|
||||||
|
- listitem [ref=f3e27]:
|
||||||
|
- link "套件" [ref=f3e28] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testsuite&f=browse&productID=4
|
||||||
|
- generic [ref=f3e29]: 套件
|
||||||
|
- listitem [ref=f3e30]
|
||||||
|
- listitem [ref=f3e31]:
|
||||||
|
- link "测试单" [ref=f3e32] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testtask&f=browse&productID=4
|
||||||
|
- generic [ref=f3e33]: 测试单
|
||||||
|
- listitem [ref=f3e34]:
|
||||||
|
- link "测试报告" [ref=f3e35] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testreport&f=browse&productID=4
|
||||||
|
- generic [ref=f3e36]: 测试报告
|
||||||
|
- listitem [ref=f3e37]
|
||||||
|
- listitem [ref=f3e38]:
|
||||||
|
- link "用例库" [ref=f3e39] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=caselib&f=browse&libID=0
|
||||||
|
- generic [ref=f3e40]: 用例库
|
||||||
|
- listitem [ref=f3e41]
|
||||||
|
- listitem [ref=f3e42]:
|
||||||
|
- link "自动化" [ref=f3e43] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=zanode&f=instruction
|
||||||
|
- generic [ref=f3e44]: 自动化
|
||||||
|
- generic [ref=f3e46]:
|
||||||
|
- button "" [ref=f3e47] [cursor=pointer]:
|
||||||
|
- generic [ref=f3e48]:
|
||||||
|
- button " 9" [ref=f3e49] [cursor=pointer]:
|
||||||
|
- generic [ref=f3e50]:
|
||||||
|
- generic [ref=f3e51]: "9"
|
||||||
|
- generic [ref=f3e54] [cursor=pointer]: A
|
||||||
|
- generic [ref=f3e57]:
|
||||||
|
- generic [ref=f3e58]:
|
||||||
|
- generic [ref=f3e59]:
|
||||||
|
- button " 返回" [ref=f3e60] [cursor=pointer]:
|
||||||
|
- generic [ref=f3e61]:
|
||||||
|
- generic [ref=f3e62]: 返回
|
||||||
|
- generic [ref=f3e63]:
|
||||||
|
- generic [ref=f3e64]: "320"
|
||||||
|
- generic [ref=f3e65]: 手术管理-》门诊手术安排:新增手术安排界面的就诊卡号取值错误
|
||||||
|
- link " 提Bug" [ref=f3e68] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=create&productID=4&branch=0&extras=projectID=11,executionID=0,moduleID=126
|
||||||
|
- generic [ref=f3e69]:
|
||||||
|
- generic [ref=f3e70]: 提Bug
|
||||||
|
- generic [ref=f3e71]:
|
||||||
|
- generic [ref=f3e72]:
|
||||||
|
- generic [ref=f3e74]:
|
||||||
|
- generic [ref=f3e76]: 重现步骤
|
||||||
|
- generic [ref=f3e78]:
|
||||||
|
- paragraph [ref=f3e79]: "[步骤]"
|
||||||
|
- paragraph [ref=f3e80]:
|
||||||
|
- link "index.php?m=file&f=read&t=png&fileID=1450" [ref=f3e81] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=file&f=read&t=png&fileID=1450
|
||||||
|
- img "index.php?m=file&f=read&t=png&fileID=1450" [ref=f3e82]
|
||||||
|
- paragraph [ref=f3e83]: 图1:门诊手术安排:手术申请查询选中手术申请记录点击【确认】
|
||||||
|
- paragraph [ref=f3e84]:
|
||||||
|
- link "index.php?m=file&f=read&t=png&fileID=1451" [ref=f3e85] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=file&f=read&t=png&fileID=1451
|
||||||
|
- img "index.php?m=file&f=read&t=png&fileID=1451" [ref=f3e86]
|
||||||
|
- paragraph [ref=f3e87]: 图2:新增手术安排界面的就诊卡号取值错误
|
||||||
|
- paragraph [ref=f3e88]: 1、如上图1、2所示:手术管理-》门诊手术安排:新增手术安排界面的就诊卡号取值错误。
|
||||||
|
- paragraph [ref=f3e89]: "[结果]"
|
||||||
|
- paragraph [ref=f3e90]: 1、手术管理-》门诊手术安排:新增手术安排界面的就诊卡号取值错误。
|
||||||
|
- paragraph [ref=f3e91]: "[期望]"
|
||||||
|
- paragraph [ref=f3e92]:
|
||||||
|
- text: 1、如上图1、2所示:手术管理-》门诊手术安排:新增手术安排界面的就诊卡号取值于患者档案的就诊卡号字段的值,adm_
|
||||||
|
- link "patient.id" [ref=f3e93] [cursor=pointer]:
|
||||||
|
- /url: http://patient.id
|
||||||
|
- text: = adm_patient_identifier.patient_id;adm_patient_identifier.identifier_no 字段就是就诊卡号,如下图3所示
|
||||||
|
- paragraph [ref=f3e94]:
|
||||||
|
- link "index.php?m=file&f=read&t=png&fileID=1452" [ref=f3e95] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=file&f=read&t=png&fileID=1452
|
||||||
|
- img "index.php?m=file&f=read&t=png&fileID=1452" [ref=f3e96]
|
||||||
|
- paragraph [ref=f3e97]: 图3
|
||||||
|
- generic [ref=f3e99]:
|
||||||
|
- generic [ref=f3e103]:
|
||||||
|
- generic [ref=f3e104]: 历史记录
|
||||||
|
- navigation [ref=f3e105]:
|
||||||
|
- button "" [ref=f3e106] [cursor=pointer]:
|
||||||
|
- generic [ref=f3e107]:
|
||||||
|
- button " 添加备注" [ref=f3e108] [cursor=pointer]:
|
||||||
|
- generic [ref=f3e109]:
|
||||||
|
- generic [ref=f3e110]: 添加备注
|
||||||
|
- list [ref=f3e112]:
|
||||||
|
- listitem [ref=f3e113]:
|
||||||
|
- generic [ref=f3e114]:
|
||||||
|
- generic [ref=f3e116]: "1"
|
||||||
|
- generic [ref=f3e119]:
|
||||||
|
- text: 2026-03-31 22:53:45, 由
|
||||||
|
- strong [ref=f3e120]: 陈显精
|
||||||
|
- text: 创建。
|
||||||
|
- listitem [ref=f3e121]:
|
||||||
|
- generic [ref=f3e122]:
|
||||||
|
- generic [ref=f3e124]: "2"
|
||||||
|
- generic [ref=f3e127]:
|
||||||
|
- text: 2026-03-31 22:53:49, 由
|
||||||
|
- strong [ref=f3e128]: 陈显精
|
||||||
|
- text: 指派给
|
||||||
|
- strong [ref=f3e129]: 王怡哲
|
||||||
|
- text: 。
|
||||||
|
- generic [ref=f3e132]:
|
||||||
|
- button " 返回" [ref=f3e133] [cursor=pointer]:
|
||||||
|
- generic [ref=f3e134]:
|
||||||
|
- generic [ref=f3e135]: 返回
|
||||||
|
- link " 确认" [ref=f3e137] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=confirm&bugID=320
|
||||||
|
- generic [ref=f3e138]:
|
||||||
|
- generic [ref=f3e139]: 确认
|
||||||
|
- link " 指派" [ref=f3e140] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=assignTo&bugID=320
|
||||||
|
- generic [ref=f3e141]:
|
||||||
|
- generic [ref=f3e142]: 指派
|
||||||
|
- link " 解决" [ref=f3e143] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=resolve&bugID=320
|
||||||
|
- generic [ref=f3e144]:
|
||||||
|
- generic [ref=f3e145]: 解决
|
||||||
|
- button " 转研发需求" [ref=f3e146] [cursor=pointer]:
|
||||||
|
- generic [ref=f3e147]:
|
||||||
|
- generic [ref=f3e148]: 转研发需求
|
||||||
|
- button " 转任务" [ref=f3e149] [cursor=pointer]:
|
||||||
|
- generic [ref=f3e150]:
|
||||||
|
- generic [ref=f3e151]: 转任务
|
||||||
|
- link " 创建用例" [ref=f3e152] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=testcase&f=create&productID=4&branch=0&moduleID=0&from=bug&bugID=320
|
||||||
|
- generic [ref=f3e153]:
|
||||||
|
- generic [ref=f3e154]: 创建用例
|
||||||
|
- link "" [ref=f3e156] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=edit&bugID=320
|
||||||
|
- generic [ref=f3e157]:
|
||||||
|
- link "" [ref=f3e158] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=create&productID=4&branch=0&extra=bugID=320,projectID=11,executionID=0
|
||||||
|
- generic [ref=f3e159]:
|
||||||
|
- link "" [ref=f3e160] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=bug&f=delete&bugID=320
|
||||||
|
- generic [ref=f3e161]:
|
||||||
|
- generic [ref=f3e162]:
|
||||||
|
- generic [ref=f3e163]:
|
||||||
|
- generic [ref=f3e164]:
|
||||||
|
- list [ref=f3e165]:
|
||||||
|
- listitem [ref=f3e166]:
|
||||||
|
- link "基本信息" [ref=f3e167] [cursor=pointer]:
|
||||||
|
- /url: "#zin_bug_view_320_tabPane"
|
||||||
|
- generic [ref=f3e168]: 基本信息
|
||||||
|
- listitem [ref=f3e169]:
|
||||||
|
- link "Bug的一生" [ref=f3e170] [cursor=pointer]:
|
||||||
|
- /url: "#zin_bug_view_320_tabPane_1"
|
||||||
|
- generic [ref=f3e171]: Bug的一生
|
||||||
|
- button "" [ref=f3e172] [cursor=pointer]:
|
||||||
|
- generic [ref=f3e173]:
|
||||||
|
- generic [ref=f3e176]:
|
||||||
|
- generic [ref=f3e177]:
|
||||||
|
- generic "所属模块" [ref=f3e178]
|
||||||
|
- list [ref=f3e180]:
|
||||||
|
- listitem [ref=f3e181]: 手术麻醉管理
|
||||||
|
- generic "所属计划" [ref=f3e183]
|
||||||
|
- generic "来源用例" [ref=f3e186]
|
||||||
|
- generic [ref=f3e188]:
|
||||||
|
- generic "Bug类型" [ref=f3e189]
|
||||||
|
- generic [ref=f3e190]: 代码错误
|
||||||
|
- generic [ref=f3e191]:
|
||||||
|
- generic "严重程度" [ref=f3e192]
|
||||||
|
- generic [ref=f3e194]: 3 3
|
||||||
|
- generic [ref=f3e195]:
|
||||||
|
- generic "优先级" [ref=f3e196]
|
||||||
|
- generic [ref=f3e198]: "3"
|
||||||
|
- generic [ref=f3e199]:
|
||||||
|
- generic "Bug状态" [ref=f3e200]
|
||||||
|
- generic [ref=f3e202]: 激活
|
||||||
|
- generic "激活次数" [ref=f3e204]
|
||||||
|
- generic "激活时间" [ref=f3e207]
|
||||||
|
- generic [ref=f3e209]:
|
||||||
|
- generic "是否确认" [ref=f3e210]
|
||||||
|
- generic [ref=f3e211]: 未确认
|
||||||
|
- generic [ref=f3e212]:
|
||||||
|
- generic "指派给" [ref=f3e213]
|
||||||
|
- generic [ref=f3e214]: 王怡哲 于 2026-03-31 22:53:45
|
||||||
|
- generic "截止日期" [ref=f3e216]
|
||||||
|
- generic "反馈者" [ref=f3e219]
|
||||||
|
- generic "通知邮箱" [ref=f3e222]
|
||||||
|
- generic "操作系统" [ref=f3e225]
|
||||||
|
- generic "浏览器" [ref=f3e228]
|
||||||
|
- generic "关键词" [ref=f3e231]
|
||||||
|
- generic "抄送给" [ref=f3e234]
|
||||||
|
- generic [ref=f3e236]:
|
||||||
|
- generic [ref=f3e237]:
|
||||||
|
- list [ref=f3e238]:
|
||||||
|
- listitem [ref=f3e239]:
|
||||||
|
- link "项目/迭代/研发需求/任务" [ref=f3e240] [cursor=pointer]:
|
||||||
|
- /url: "#zin_bug_view_320_tabPane_2"
|
||||||
|
- generic [ref=f3e241]: 项目/迭代/研发需求/任务
|
||||||
|
- listitem [ref=f3e242]:
|
||||||
|
- link "其他相关" [ref=f3e243] [cursor=pointer]:
|
||||||
|
- /url: "#zin_bug_view_320_tabPane_3"
|
||||||
|
- generic [ref=f3e244]: 其他相关
|
||||||
|
- button "" [ref=f3e245] [cursor=pointer]:
|
||||||
|
- generic [ref=f3e246]:
|
||||||
|
- generic [ref=f3e249]:
|
||||||
|
- generic [ref=f3e250]:
|
||||||
|
- generic "所属项目" [ref=f3e251]
|
||||||
|
- link "开源HIS改造落地" [ref=f3e253] [cursor=pointer]:
|
||||||
|
- /url: /index.php?m=project&f=view&projectID=11
|
||||||
|
- generic "所属执行" [ref=f3e255]
|
||||||
|
- generic "相关需求" [ref=f3e258]
|
||||||
|
- generic "相关任务" [ref=f3e261]
|
||||||
|
- button "" [ref=f3e264] [cursor=pointer]:
|
||||||
|
- generic [ref=f3e265]:
|
||||||
|
- text: "* *"
|
||||||
|
- generic [ref=e65]:
|
||||||
|
- button " 研发综合界面" [ref=e67] [cursor=pointer]:
|
||||||
|
- generic [ref=e68]:
|
||||||
|
- generic [ref=e69]: 研发综合界面
|
||||||
|
- list [ref=e90]:
|
||||||
|
- listitem [ref=e91]:
|
||||||
|
- generic [ref=e93] [cursor=pointer]: 测试
|
||||||
|
- generic [ref=e71]:
|
||||||
|
- textbox [ref=e77]:
|
||||||
|
- /placeholder: 搜索
|
||||||
|
- button [ref=e79] [cursor=pointer]:
|
||||||
|
- img [ref=e81]
|
||||||
|
- link " 开源版21.7" [ref=e82] [cursor=pointer]:
|
||||||
|
- /url: https://www.zentao.net
|
||||||
|
- generic [ref=e83]:
|
||||||
|
- generic [ref=e84]: 开源版21.7
|
||||||
|
- button "升级 " [ref=e85] [cursor=pointer]:
|
||||||
|
- generic [ref=e86]: 升级
|
||||||
|
- generic [ref=e87]:
|
||||||
@@ -2,5 +2,5 @@
|
|||||||
"tools": {
|
"tools": {
|
||||||
"approvalMode": "yolo"
|
"approvalMode": "yolo"
|
||||||
},
|
},
|
||||||
"$version": 2
|
"$version": 3
|
||||||
}
|
}
|
||||||
6
.qwen/settings.json.orig
Normal file
6
.qwen/settings.json.orig
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"tools": {
|
||||||
|
"approvalMode": "yolo"
|
||||||
|
},
|
||||||
|
"$version": 2
|
||||||
|
}
|
||||||
91
BUGFIX_ANALYSIS.md
Normal file
91
BUGFIX_ANALYSIS.md
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
# Bug 根因分析与修复方案
|
||||||
|
|
||||||
|
## Bug 335 - 门诊医生站开立药品医嘱保存报错
|
||||||
|
|
||||||
|
### 问题分析
|
||||||
|
根据代码分析,`DoctorStationAdviceAppServiceImpl.saveAdvice()` 方法处理药品医嘱保存时可能报错的原因:
|
||||||
|
|
||||||
|
1. **patientId/encounterId 为 null** - 删除操作时前端可能未传
|
||||||
|
2. **accountId 为 null** - 患者账户信息未正确获取
|
||||||
|
3. **definitionId/definitionDetailId 为 null** - 定价信息缺失
|
||||||
|
4. **库存校验失败** - 药品库存不足
|
||||||
|
|
||||||
|
### 修复方案
|
||||||
|
✅ 已部分修复(见代码中的 BugFix 注释)
|
||||||
|
- 已添加 patientId/encounterId 自动补全逻辑
|
||||||
|
- 已添加 accountId 自动创建逻辑
|
||||||
|
- 需要进一步验证 definitionId 的处理
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Bug 336 - 门诊医生站开立诊疗项目保存报错
|
||||||
|
|
||||||
|
### 问题分析
|
||||||
|
诊疗项目保存与药品类似,但有以下特殊点:
|
||||||
|
|
||||||
|
1. **必须选择执行科室** - 代码中有校验 `throw new ServiceException("诊疗项目必须选择执行科室")`
|
||||||
|
2. **活动绑定设备处理** - 需要处理 `handService()` 中的设备绑定逻辑
|
||||||
|
3. **库存校验** - 诊疗项目可能关联耗材
|
||||||
|
|
||||||
|
### 修复方案
|
||||||
|
- 确保前端传递 executeDeptId(执行科室)
|
||||||
|
- 检查 handService() 方法中的异常处理
|
||||||
|
- 添加更详细的错误日志
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Bug 338 - 门诊划价新增时未校验就诊记录及诊断记录
|
||||||
|
|
||||||
|
### 问题分析
|
||||||
|
**这是患者安全问题!** 未接诊患者也可新增划价项目可能导致:
|
||||||
|
- 收费错误
|
||||||
|
- 医疗纠纷
|
||||||
|
- 数据不一致
|
||||||
|
|
||||||
|
当前代码问题:
|
||||||
|
- `OutpatientPricingAppServiceImpl.getAdviceBaseInfo()` 仅查询医嘱,未校验就诊状态
|
||||||
|
- 前端划价保存接口未找到(可能在其他地方)
|
||||||
|
|
||||||
|
### 修复方案
|
||||||
|
1. 在划价查询时增加就诊状态校验
|
||||||
|
2. 在划价保存时增加诊断记录校验
|
||||||
|
3. 未接诊患者禁止划价
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Bug 339 - 药房筛选条件失效
|
||||||
|
|
||||||
|
### 问题分析
|
||||||
|
查询结果中包含非选中药房的数据,可能原因:
|
||||||
|
- SQL WHERE 条件未正确应用 locationId
|
||||||
|
- 多表关联时过滤条件丢失
|
||||||
|
|
||||||
|
### 修复方案
|
||||||
|
- 检查 `DoctorStationAdviceAppMapper.getAdviceBaseInfo()` 的 SQL
|
||||||
|
- 确保 locationId 条件正确应用
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 修复优先级
|
||||||
|
|
||||||
|
1. **Bug 338** - 患者安全问题,最高优先级
|
||||||
|
2. **Bug 335/336** - 核心功能阻断,高优先级
|
||||||
|
3. **Bug 339** - 数据准确性问题,中优先级
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 测试用例
|
||||||
|
|
||||||
|
### Bug 338 测试
|
||||||
|
1. 选择未接诊患者,尝试划价 → 应禁止
|
||||||
|
2. 选择已接诊但无诊断的患者,尝试划价 → 应提示补充诊断
|
||||||
|
3. 选择正常接诊患者,划价 → 应成功
|
||||||
|
|
||||||
|
### Bug 335/336 测试
|
||||||
|
1. 门诊医生站开立药品医嘱 → 应成功保存
|
||||||
|
2. 门诊医生站开立诊疗项目 → 应成功保存
|
||||||
|
3. 签发医嘱 → 应成功
|
||||||
|
|
||||||
|
### Bug 339 测试
|
||||||
|
1. 选择"西药房"筛选 → 结果应仅包含西药房数据
|
||||||
|
2. 选择"中药房"筛选 → 结果应仅包含中药房数据
|
||||||
84
BUGFIX_PLAN.md
Normal file
84
BUGFIX_PLAN.md
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
# HIS 系统 Bug 修复计划
|
||||||
|
|
||||||
|
## 修复负责人
|
||||||
|
华佗 (AI 团队)
|
||||||
|
|
||||||
|
## 修复时间
|
||||||
|
2026-04-05 开始
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Bug 清单与修复优先级
|
||||||
|
|
||||||
|
### 🔴 高优先级(核心业务阻断)
|
||||||
|
|
||||||
|
#### Bug 335 - 门诊医生站开立药品医嘱保存报错
|
||||||
|
- **模块**: 医生工作站
|
||||||
|
- **文件**: `DoctorStationAdviceAppServiceImpl.java`
|
||||||
|
- **根因分析**: 待分析
|
||||||
|
- **修复状态**: 🔄 分析中
|
||||||
|
|
||||||
|
#### Bug 336 - 门诊医生站开立诊疗项目保存报错
|
||||||
|
- **模块**: 医生工作站
|
||||||
|
- **文件**: `DoctorStationAdviceAppServiceImpl.java`
|
||||||
|
- **根因分析**: 待分析
|
||||||
|
- **修复状态**: ⏳ 等待 335 修复后验证
|
||||||
|
|
||||||
|
#### Bug 338 - 门诊划价新增时未校验就诊记录及诊断记录
|
||||||
|
- **模块**: 门诊收费
|
||||||
|
- **问题**: 未接诊患者也可新增划价项目(患者安全问题)
|
||||||
|
- **修复方案**: 在划价保存前增加就诊状态和诊断记录校验
|
||||||
|
- **修复状态**: ⏳ 待修复
|
||||||
|
|
||||||
|
### 🟡 中优先级(数据准确性/用户体验)
|
||||||
|
|
||||||
|
#### Bug 339 - 药房筛选条件失效
|
||||||
|
- **模块**: 药房药库报表管理
|
||||||
|
- **问题**: 查询结果中包含非选中药房的数据
|
||||||
|
- **修复状态**: ⏳ 待分析
|
||||||
|
|
||||||
|
#### Bug 333 - 耗材医嘱类型错误
|
||||||
|
- **模块**: 医生工作站
|
||||||
|
- **问题**: 类型误转为"中成药"且保存报错
|
||||||
|
- **修复状态**: ⏳ 待分析
|
||||||
|
|
||||||
|
#### Bug 337 - 挂号时间显示异常
|
||||||
|
- **模块**: 建档挂号管理
|
||||||
|
- **问题**: 未显示当前实际挂号时间
|
||||||
|
- **修复状态**: ⏳ 待分析
|
||||||
|
|
||||||
|
#### Bug 334 - 检验申请界面布局优化
|
||||||
|
- **模块**: 门诊医生工作站
|
||||||
|
- **问题**: 按钮布局需要调整
|
||||||
|
- **修复状态**: ⏳ 待修复(前端)
|
||||||
|
|
||||||
|
### 🟢 低优先级(历史遗留问题)
|
||||||
|
|
||||||
|
#### Bug 249/253/280/300 - 3 月份遗留 bug
|
||||||
|
- **修复状态**: ⏳ 后续处理
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 修复流程
|
||||||
|
|
||||||
|
1. **分析根因** - 查看代码和日志,定位问题
|
||||||
|
2. **编写修复** - 修改代码并添加必要校验
|
||||||
|
3. **本地测试** - 确保修复有效且不引入新问题
|
||||||
|
4. **提交代码** - commit 并推送到 gitea
|
||||||
|
5. **验证关闭** - 在禅道更新 Bug 状态
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 测试要求
|
||||||
|
|
||||||
|
- 修复后必须测试
|
||||||
|
- 测试不通过继续修
|
||||||
|
- 确保不影响其他功能
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 备注
|
||||||
|
|
||||||
|
- 所有修复基于 develop 分支
|
||||||
|
- 修复完成后统一提交
|
||||||
|
- 重要修复添加详细注释
|
||||||
61
BUG_FIX_PROGRESS.md
Normal file
61
BUG_FIX_PROGRESS.md
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# HIS项目 Bug修复与需求开发进度表
|
||||||
|
|
||||||
|
## 项目信息
|
||||||
|
- **项目名称**: 开源HIS改造落地
|
||||||
|
- **当前分支**: develop
|
||||||
|
- **代码路径**:
|
||||||
|
- 前端: openhis-ui-vue3
|
||||||
|
- 后端: openhis-server-new
|
||||||
|
- ** Git仓库**: https://gitea.gentronhealth.com/wangyizhe/his
|
||||||
|
- **禅道地址**: https://zentao.gentronhealth.com
|
||||||
|
|
||||||
|
## 当前状态
|
||||||
|
- ✅ 代码已克隆完成
|
||||||
|
- ✅ Bug 已重新分配(管理员操作)
|
||||||
|
- ⏳ 等待修复人员开始工作
|
||||||
|
- 📋 张飞负责测试验证
|
||||||
|
|
||||||
|
## Bug修复任务列表(重新分配后)
|
||||||
|
|
||||||
|
| Bug ID | 严重程度 | 状态 | 模块 | 标题 | 原指派给 | **新指派给** | 进度 |
|
||||||
|
|--------|----------|------|------|------|----------|--------------|------|
|
||||||
|
| 339 | 3 | 激活 | 药房药库报表管理 | 药房筛选条件失效 | 王怡哲 | **关羽** | 待处理 |
|
||||||
|
| 338 | 3 | 激活 | 门诊收费管理 | 未校验就诊记录 | 王怡哲 | **关羽** | 待处理 |
|
||||||
|
| 337 | 3 | 激活 | 建档挂号管理 | 挂号时间显示异常 | 王怡哲 | **关羽** | 待处理 |
|
||||||
|
| 336 | 3 | 激活 | 门诊医生工作站 | 开立诊疗项目保存报错 | 王怡哲 | **关羽** | 待处理 |
|
||||||
|
| 335 | 3 | 激活 | 门诊医生工作站 | 开立药品医嘱保存报错 | 王怡哲 | **关羽** | 待处理 |
|
||||||
|
| 334 | 3 | 激活 | 门诊医生工作站 | 检验申请界面布局优化 | 王建 | **子龙** | 待处理 |
|
||||||
|
| 333 | 3 | 激活 | 门诊医生工作站 | 耗材医嘱类型误转 | 陈显精 | **关羽** | 待处理 |
|
||||||
|
|
||||||
|
## P0 级别 Bug(紧急,优先修复)
|
||||||
|
|
||||||
|
| Bug ID | 标题 | 严重程度 | 负责人 |
|
||||||
|
|--------|------|----------|--------|
|
||||||
|
| 335 | 开立药品医嘱保存报错 | 严重 | 关羽 |
|
||||||
|
| 336 | 开立诊疗项目保存报错 | 严重 | 关羽 |
|
||||||
|
| 338 | 未校验就诊记录 | 严重 | 关羽 |
|
||||||
|
|
||||||
|
## 需求开发任务列表(10个,全部未关闭)
|
||||||
|
|
||||||
|
待进一步确认分配情况...
|
||||||
|
|
||||||
|
## 工作流程
|
||||||
|
1. **认领任务** - 在禅道将 Bug 分配给自己
|
||||||
|
2. **修改代码** - 从 develop 分支创建新分支:`bug/bug-id`
|
||||||
|
3. **本地测试** - 确保本地 JDK 17 环境编译通过
|
||||||
|
4. **提交PR** - 提交 Pull Request 到 develop 分支
|
||||||
|
5. **测试验证** - 张飞进行测试
|
||||||
|
6. **合并分支** - 测试通过后合并到 develop
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
- 所有代码修改必须先创建新分支
|
||||||
|
- 分支命名:`bug/bug-id` 或 `feature/feedback-id`
|
||||||
|
- 提交信息必须包含禅道Bug/需求ID
|
||||||
|
- 修改前请先阅读 `AGENTS.md` 了解项目规范
|
||||||
|
- **JDK 17 配置** - 确保本地开发环境使用 JDK 17
|
||||||
|
|
||||||
|
## 今日会议纪要
|
||||||
|
- 2026-04-05 15:09: 管理员重新分配 Bug 给群内武将
|
||||||
|
- 2026-04-05 14:58: 确认将王怡哲的 Bug 分配给关羽、张飞、陈琳
|
||||||
|
- 2026-04-05 13:47: 统一调度分配人员任务
|
||||||
|
- 2026-04-05 12:45: 初始任务分配完成
|
||||||
89
Bug318_修复总结.md
Normal file
89
Bug318_修复总结.md
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
# Bug #318 修复总结 - 手术医嘱类型冲突解决
|
||||||
|
|
||||||
|
## 问题描述
|
||||||
|
手术医嘱的 `adviceType=4` 与耗材类型冲突,导致保存手术医嘱时被错误归类为耗材,进而引发 `device_def_id` 为 null 的数据库错误。
|
||||||
|
|
||||||
|
## 解决方案
|
||||||
|
引入新的手术类型值 **6**,避免与耗材类型(4)冲突。
|
||||||
|
|
||||||
|
## 类型映射表
|
||||||
|
|
||||||
|
| 类型 | 前端 adviceType | 后端 ItemType | 数据库 category_enum |
|
||||||
|
|------|----------------|---------------|---------------------|
|
||||||
|
| 药品 | 1 | MEDICINE(1) | 1 |
|
||||||
|
| 耗材 | 4 | DEVICE(2) | 2 |
|
||||||
|
| 诊疗 | 3 | ACTIVITY(3) | 3 |
|
||||||
|
| 会诊 | 5 | - | 31 |
|
||||||
|
| **手术** | **6** | **SURGERY(6)** | **6** |
|
||||||
|
|
||||||
|
## 修改的文件
|
||||||
|
|
||||||
|
### 1. 后端 - 枚举定义
|
||||||
|
**文件**: `openhis-server-new/openhis-common/src/main/java/com/openhis/common/enums/ItemType.java`
|
||||||
|
- 添加 `SURGERY(6, "6", "手术")` 枚举值
|
||||||
|
|
||||||
|
### 2. 后端 - SQL Mapper(医生站)
|
||||||
|
**文件**: `openhis-server-new/openhis-application/src/main/resources/mapper/doctorstation/DoctorStationAdviceAppMapper.xml`
|
||||||
|
- 修改 SQL:将 `category_enum=4` 映射为 `advice_type=6`
|
||||||
|
- 修改前: `COALESCE(T1.category_enum, 3) AS advice_type`
|
||||||
|
- 修改后: `CASE WHEN T1.category_enum = 4 THEN 6 ELSE COALESCE(T1.category_enum, 3) END AS advice_type`
|
||||||
|
|
||||||
|
### 3. 后端 - SQL Mapper(住院医生站)
|
||||||
|
**文件**: `openhis-server-new/openhis-application/src/main/resources/mapper/regdoctorstation/AdviceManageAppMapper.xml`
|
||||||
|
- 同上修改
|
||||||
|
|
||||||
|
### 4. 后端 - 分类逻辑
|
||||||
|
**文件**: `openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationAdviceAppServiceImpl.java`
|
||||||
|
- 更新 `deviceList` 筛选条件:处理 `adviceType=4`(耗材)
|
||||||
|
- 更新 `activityList` 筛选条件:处理 `adviceType=6`(手术)
|
||||||
|
|
||||||
|
### 5. 前端 - 医嘱类型选项
|
||||||
|
**文件**: `openhis-ui-vue3/src/views/inpatientDoctor/home/components/order/index.vue`
|
||||||
|
- 修改手术类型值从 4 改为 6
|
||||||
|
|
||||||
|
## 数据迁移
|
||||||
|
|
||||||
|
### 历史数据更新脚本
|
||||||
|
**文件**: `sql/迁移记录-DB变更记录/20260401_update_surgery_advice_type.sql`
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- 更新历史手术医嘱的 category_enum 从 4 改为 6
|
||||||
|
UPDATE wor_service_request
|
||||||
|
SET category_enum = 6
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0';
|
||||||
|
```
|
||||||
|
|
||||||
|
### 执行步骤
|
||||||
|
1. **备份数据库**(重要!)
|
||||||
|
2. 执行上述 UPDATE 语句
|
||||||
|
3. 重启后端服务
|
||||||
|
4. 清除前端缓存
|
||||||
|
|
||||||
|
## 验证方法
|
||||||
|
|
||||||
|
### 1. 后端日志验证
|
||||||
|
保存手术申请单后,检查日志:
|
||||||
|
```
|
||||||
|
BugFix#219: 医嘱分类完成 - 药品:{}, 耗材:{}, 诊疗:{}
|
||||||
|
```
|
||||||
|
手术医嘱应该被归类到"诊疗"中。
|
||||||
|
|
||||||
|
### 2. 数据库验证
|
||||||
|
```sql
|
||||||
|
-- 检查手术医嘱的 category_enum 是否为 6
|
||||||
|
SELECT id, bus_no, category_enum, content_json::jsonb->>'surgeryName'
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE category_enum = 6;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 前端验证
|
||||||
|
- 医嘱列表中手术医嘱显示正常
|
||||||
|
- 手术医嘱的 adviceType 为 6
|
||||||
|
- 耗材医嘱的 adviceType 为 4
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. **部署前必须执行数据迁移脚本**,否则历史手术医嘱无法正确显示
|
||||||
|
2. 修改后需要重新编译部署后端和前端
|
||||||
|
3. 建议先在测试环境验证后再部署到生产环境
|
||||||
2
GIT_TEST_GUANYU.md
Normal file
2
GIT_TEST_GUANYU.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# 关羽 Git 配置测试
|
||||||
|
测试时间: Mon Apr 6 07:03:56 AM CST 2026
|
||||||
105
analyze_empty_data.js
Normal file
105
analyze_empty_data.js
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
const { Pool } = require('pg');
|
||||||
|
const pool = new Pool({
|
||||||
|
host: '47.116.196.11',
|
||||||
|
port: 15432,
|
||||||
|
database: 'postgresql',
|
||||||
|
user: 'postgresql',
|
||||||
|
password: 'Jchl1528'
|
||||||
|
});
|
||||||
|
|
||||||
|
async function analyze() {
|
||||||
|
try {
|
||||||
|
// 1. 检查申请科室ID在adm_organization中是否存在
|
||||||
|
console.log('=== 分析申请科室ID是否有效 ===');
|
||||||
|
const deptResult = await pool.query(`
|
||||||
|
SELECT DISTINCT s.apply_dept_id
|
||||||
|
FROM hisdev.cli_surgery s
|
||||||
|
WHERE s.delete_flag = '0'
|
||||||
|
AND (s.apply_dept_name IS NULL OR s.apply_dept_name = '')
|
||||||
|
AND s.apply_dept_id IS NOT NULL
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1 FROM hisdev.adm_organization o WHERE o.id = s.apply_dept_id
|
||||||
|
)
|
||||||
|
`);
|
||||||
|
console.log(`申请科室ID无效的记录数: ${deptResult.rows.length}`);
|
||||||
|
if (deptResult.rows.length > 0) {
|
||||||
|
console.log('无效的apply_dept_id:', deptResult.rows.map(r => r.apply_dept_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 检查主刀医生ID在sys_user中是否存在
|
||||||
|
console.log('\n=== 分析主刀医生ID是否有效 ===');
|
||||||
|
const surgeonResult = await pool.query(`
|
||||||
|
SELECT DISTINCT s.main_surgeon_id
|
||||||
|
FROM hisdev.cli_surgery s
|
||||||
|
WHERE s.delete_flag = '0'
|
||||||
|
AND (s.main_surgeon_name IS NULL OR s.main_surgeon_name = '')
|
||||||
|
AND s.main_surgeon_id IS NOT NULL
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1 FROM hisdev.sys_user u WHERE u.user_id = s.main_surgeon_id
|
||||||
|
)
|
||||||
|
`);
|
||||||
|
console.log(`主刀医生ID无效的记录数: ${surgeonResult.rows.length}`);
|
||||||
|
if (surgeonResult.rows.length > 0) {
|
||||||
|
console.log('无效的main_surgeon_id:', surgeonResult.rows.map(r => r.main_surgeon_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 查看有ID但没有name的记录详情
|
||||||
|
console.log('\n=== 有ID但Name为空的记录详情 ===');
|
||||||
|
const detailResult = await pool.query(`
|
||||||
|
SELECT
|
||||||
|
s.id,
|
||||||
|
s.surgery_no,
|
||||||
|
s.apply_dept_id,
|
||||||
|
s.main_surgeon_id,
|
||||||
|
s.create_time,
|
||||||
|
EXISTS (SELECT 1 FROM hisdev.adm_organization o WHERE o.id = s.apply_dept_id) as dept_exists,
|
||||||
|
EXISTS (SELECT 1 FROM hisdev.sys_user u WHERE u.user_id = s.main_surgeon_id) as surgeon_exists
|
||||||
|
FROM hisdev.cli_surgery s
|
||||||
|
WHERE s.delete_flag = '0'
|
||||||
|
AND (
|
||||||
|
((s.apply_dept_name IS NULL OR s.apply_dept_name = '') AND s.apply_dept_id IS NOT NULL)
|
||||||
|
OR
|
||||||
|
((s.main_surgeon_name IS NULL OR s.main_surgeon_name = '') AND s.main_surgeon_id IS NOT NULL)
|
||||||
|
)
|
||||||
|
ORDER BY s.create_time DESC
|
||||||
|
LIMIT 10
|
||||||
|
`);
|
||||||
|
console.log(JSON.stringify(detailResult.rows, null, 2));
|
||||||
|
|
||||||
|
// 4. 检查最近创建的记录为什么name为空
|
||||||
|
console.log('\n=== 最近10条记录的创建情况 ===');
|
||||||
|
const recentResult = await pool.query(`
|
||||||
|
SELECT
|
||||||
|
s.id,
|
||||||
|
s.surgery_no,
|
||||||
|
s.apply_dept_id,
|
||||||
|
s.apply_dept_name,
|
||||||
|
s.main_surgeon_id,
|
||||||
|
s.main_surgeon_name,
|
||||||
|
s.create_time,
|
||||||
|
s.create_by,
|
||||||
|
CASE
|
||||||
|
WHEN s.apply_dept_id IS NULL THEN 'apply_dept_id为空'
|
||||||
|
WHEN NOT EXISTS (SELECT 1 FROM hisdev.adm_organization o WHERE o.id = s.apply_dept_id) THEN 'apply_dept_id无效'
|
||||||
|
ELSE 'apply_dept_id有效'
|
||||||
|
END as dept_status,
|
||||||
|
CASE
|
||||||
|
WHEN s.main_surgeon_id IS NULL THEN 'main_surgeon_id为空'
|
||||||
|
WHEN NOT EXISTS (SELECT 1 FROM hisdev.sys_user u WHERE u.user_id = s.main_surgeon_id) THEN 'main_surgeon_id无效'
|
||||||
|
ELSE 'main_surgeon_id有效'
|
||||||
|
END as surgeon_status
|
||||||
|
FROM hisdev.cli_surgery s
|
||||||
|
WHERE s.delete_flag = '0'
|
||||||
|
ORDER BY s.create_time DESC
|
||||||
|
LIMIT 10
|
||||||
|
`);
|
||||||
|
console.log(JSON.stringify(recentResult.rows, null, 2));
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error('分析失败:', err.message);
|
||||||
|
} finally {
|
||||||
|
pool.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
analyze();
|
||||||
73
analyze_surgery_relation.js
Normal file
73
analyze_surgery_relation.js
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
const { Pool } = require('pg');
|
||||||
|
const pool = new Pool({
|
||||||
|
host: '47.116.196.11',
|
||||||
|
port: 15432,
|
||||||
|
database: 'postgresql',
|
||||||
|
user: 'postgresql',
|
||||||
|
password: 'Jchl1528'
|
||||||
|
});
|
||||||
|
|
||||||
|
async function analyze() {
|
||||||
|
try {
|
||||||
|
// 1. 检查最近的手术安排及其关联的手术申请
|
||||||
|
console.log('=== 分析手术安排与手术申请的关联 ===\n');
|
||||||
|
|
||||||
|
const result = await pool.query(`
|
||||||
|
SELECT
|
||||||
|
os.schedule_id,
|
||||||
|
os.oper_code,
|
||||||
|
os.apply_id,
|
||||||
|
os.create_time,
|
||||||
|
os.creator_id,
|
||||||
|
cs.id as surgery_id,
|
||||||
|
cs.surgery_no,
|
||||||
|
cs.apply_dept_id,
|
||||||
|
cs.apply_dept_name,
|
||||||
|
cs.main_surgeon_id,
|
||||||
|
cs.main_surgeon_name,
|
||||||
|
cs.status_enum,
|
||||||
|
CASE
|
||||||
|
WHEN cs.id IS NULL THEN '手术申请记录不存在'
|
||||||
|
WHEN cs.apply_dept_name IS NULL THEN '申请科室名称为空'
|
||||||
|
WHEN cs.main_surgeon_name IS NULL THEN '主刀医生名称为空'
|
||||||
|
ELSE '正常'
|
||||||
|
END as status
|
||||||
|
FROM hisdev.op_schedule os
|
||||||
|
LEFT JOIN hisdev.cli_surgery cs ON os.apply_id = cs.id
|
||||||
|
WHERE os.delete_flag = '0'
|
||||||
|
ORDER BY os.create_time DESC
|
||||||
|
LIMIT 10
|
||||||
|
`);
|
||||||
|
|
||||||
|
console.table(result.rows);
|
||||||
|
|
||||||
|
// 2. 检查手术申请本身的字段情况
|
||||||
|
console.log('\n=== 最近创建的手术申请 ===');
|
||||||
|
const surgeryResult = await pool.query(`
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
surgery_no,
|
||||||
|
patient_name,
|
||||||
|
apply_dept_id,
|
||||||
|
apply_dept_name,
|
||||||
|
main_surgeon_id,
|
||||||
|
main_surgeon_name,
|
||||||
|
status_enum,
|
||||||
|
create_time,
|
||||||
|
create_by
|
||||||
|
FROM hisdev.cli_surgery
|
||||||
|
WHERE delete_flag = '0'
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
LIMIT 5
|
||||||
|
`);
|
||||||
|
|
||||||
|
console.table(surgeryResult.rows);
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error('查询失败:', err.message);
|
||||||
|
} finally {
|
||||||
|
pool.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
analyze();
|
||||||
1
auto-confirm-skill
Submodule
1
auto-confirm-skill
Submodule
Submodule auto-confirm-skill added at 569e5191a5
72
check_id_match.js
Normal file
72
check_id_match.js
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
const { Pool } = require('pg');
|
||||||
|
const pool = new Pool({
|
||||||
|
host: '47.116.196.11',
|
||||||
|
port: 15432,
|
||||||
|
database: 'postgresql',
|
||||||
|
user: 'postgresql',
|
||||||
|
password: 'Jchl1528'
|
||||||
|
});
|
||||||
|
|
||||||
|
async function checkIdMatch() {
|
||||||
|
try {
|
||||||
|
// 1. 检查 op_schedule 中的 apply_id
|
||||||
|
console.log('=== 手术安排中的 apply_id ===');
|
||||||
|
const scheduleResult = await pool.query(`
|
||||||
|
SELECT DISTINCT apply_id
|
||||||
|
FROM hisdev.op_schedule
|
||||||
|
WHERE delete_flag = '0'
|
||||||
|
ORDER BY apply_id DESC
|
||||||
|
LIMIT 10
|
||||||
|
`);
|
||||||
|
console.log('apply_id 列表:', scheduleResult.rows.map(r => r.apply_id));
|
||||||
|
|
||||||
|
// 2. 检查 cli_surgery 中存在的 id
|
||||||
|
console.log('\n=== 手术申请中的 id ===');
|
||||||
|
const surgeryResult = await pool.query(`
|
||||||
|
SELECT id, surgery_no
|
||||||
|
FROM hisdev.cli_surgery
|
||||||
|
WHERE delete_flag = '0'
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
LIMIT 10
|
||||||
|
`);
|
||||||
|
console.table(surgeryResult.rows);
|
||||||
|
|
||||||
|
// 3. 检查 ID 类型
|
||||||
|
console.log('\n=== 检查 ID 字段类型 ===');
|
||||||
|
const typeResult = await pool.query(`
|
||||||
|
SELECT
|
||||||
|
column_name,
|
||||||
|
data_type,
|
||||||
|
character_maximum_length
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_schema = 'hisdev'
|
||||||
|
AND table_name IN ('op_schedule', 'cli_surgery')
|
||||||
|
AND column_name IN ('id', 'apply_id')
|
||||||
|
ORDER BY table_name, column_name
|
||||||
|
`);
|
||||||
|
console.table(typeResult.rows);
|
||||||
|
|
||||||
|
// 4. 尝试匹配
|
||||||
|
console.log('\n=== 尝试匹配 ===');
|
||||||
|
const matchResult = await pool.query(`
|
||||||
|
SELECT
|
||||||
|
os.schedule_id,
|
||||||
|
os.apply_id,
|
||||||
|
cs.id as surgery_id,
|
||||||
|
CASE WHEN cs.id IS NULL THEN '未找到' ELSE '已找到' END as match_status
|
||||||
|
FROM hisdev.op_schedule os
|
||||||
|
LEFT JOIN hisdev.cli_surgery cs ON os.apply_id = cs.id
|
||||||
|
WHERE os.delete_flag = '0'
|
||||||
|
ORDER BY os.create_time DESC
|
||||||
|
LIMIT 5
|
||||||
|
`);
|
||||||
|
console.table(matchResult.rows);
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error('查询失败:', err.message);
|
||||||
|
} finally {
|
||||||
|
pool.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkIdMatch();
|
||||||
31
check_nulls.js
Normal file
31
check_nulls.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
const { Pool } = require('pg');
|
||||||
|
const pool = new Pool({
|
||||||
|
host: '47.116.196.11',
|
||||||
|
port: 15432,
|
||||||
|
database: 'postgresql',
|
||||||
|
user: 'postgresql',
|
||||||
|
password: 'Jchl1528'
|
||||||
|
});
|
||||||
|
|
||||||
|
const query = `
|
||||||
|
SELECT
|
||||||
|
COUNT(*) as total_count,
|
||||||
|
COUNT(apply_dept_id) as has_apply_dept_id_count,
|
||||||
|
COUNT(apply_dept_name) as has_apply_dept_name_count,
|
||||||
|
COUNT(*) - COUNT(apply_dept_name) as apply_dept_name_null_count,
|
||||||
|
COUNT(main_surgeon_id) as has_main_surgeon_id_count,
|
||||||
|
COUNT(main_surgeon_name) as has_main_surgeon_name_count,
|
||||||
|
COUNT(*) - COUNT(main_surgeon_name) as main_surgeon_name_null_count
|
||||||
|
FROM hisdev.cli_surgery
|
||||||
|
WHERE delete_flag = '0'
|
||||||
|
`;
|
||||||
|
|
||||||
|
pool.query(query, (err, res) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error:', err.message);
|
||||||
|
} else {
|
||||||
|
console.log('=== 当前 cli_surgery 表空值统计 ===');
|
||||||
|
console.log(JSON.stringify(res.rows[0], null, 2));
|
||||||
|
}
|
||||||
|
pool.end();
|
||||||
|
});
|
||||||
67
check_surgery_save.js
Normal file
67
check_surgery_save.js
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
const { Pool } = require('pg');
|
||||||
|
const pool = new Pool({
|
||||||
|
host: '47.116.196.11',
|
||||||
|
port: 15432,
|
||||||
|
database: 'postgresql',
|
||||||
|
user: 'postgresql',
|
||||||
|
password: 'Jchl1528'
|
||||||
|
});
|
||||||
|
|
||||||
|
async function checkLatestSurgery() {
|
||||||
|
try {
|
||||||
|
console.log('=== 检查最近创建的手术安排 ===\n');
|
||||||
|
|
||||||
|
// 1. 查询最近创建的手术安排
|
||||||
|
const latestSchedule = await pool.query(`
|
||||||
|
SELECT
|
||||||
|
os.schedule_id,
|
||||||
|
os.oper_code,
|
||||||
|
os.oper_name,
|
||||||
|
os.apply_id,
|
||||||
|
os.create_time,
|
||||||
|
cs.apply_dept_id,
|
||||||
|
cs.apply_dept_name,
|
||||||
|
cs.main_surgeon_id,
|
||||||
|
cs.main_surgeon_name,
|
||||||
|
cs.surgery_no
|
||||||
|
FROM hisdev.op_schedule os
|
||||||
|
LEFT JOIN hisdev.cli_surgery cs ON os.apply_id = cs.id
|
||||||
|
WHERE os.delete_flag = '0'
|
||||||
|
ORDER BY os.create_time DESC
|
||||||
|
LIMIT 5
|
||||||
|
`);
|
||||||
|
|
||||||
|
console.log('最近5条手术安排:');
|
||||||
|
console.table(latestSchedule.rows);
|
||||||
|
|
||||||
|
// 2. 检查是否有空值
|
||||||
|
const nullCheck = await pool.query(`
|
||||||
|
SELECT
|
||||||
|
COUNT(*) as total,
|
||||||
|
COUNT(CASE WHEN cs.apply_dept_name IS NULL OR cs.apply_dept_name = '' THEN 1 END) as null_apply_dept,
|
||||||
|
COUNT(CASE WHEN cs.main_surgeon_name IS NULL OR cs.main_surgeon_name = '' THEN 1 END) as null_surgeon
|
||||||
|
FROM hisdev.op_schedule os
|
||||||
|
LEFT JOIN hisdev.cli_surgery cs ON os.apply_id = cs.id
|
||||||
|
WHERE os.delete_flag = '0'
|
||||||
|
AND os.create_time > NOW() - INTERVAL '1 hour'
|
||||||
|
`);
|
||||||
|
|
||||||
|
console.log('\n=== 最近1小时内创建的手术安排 ===');
|
||||||
|
console.log(`总计: ${nullCheck.rows[0].total}`);
|
||||||
|
console.log(`申请科室为空的: ${nullCheck.rows[0].null_apply_dept}`);
|
||||||
|
console.log(`主刀医生为空的: ${nullCheck.rows[0].null_surgeon}`);
|
||||||
|
|
||||||
|
if (parseInt(nullCheck.rows[0].null_apply_dept) === 0 && parseInt(nullCheck.rows[0].null_surgeon) === 0) {
|
||||||
|
console.log('\n✅ 所有字段都已正确保存!');
|
||||||
|
} else {
|
||||||
|
console.log('\n⚠️ 仍有部分字段为空,请检查后端代码是否已部署');
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error('查询失败:', err.message);
|
||||||
|
} finally {
|
||||||
|
pool.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkLatestSurgery();
|
||||||
76
find_missing_ids.js
Normal file
76
find_missing_ids.js
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
const { Pool } = require('pg');
|
||||||
|
const pool = new Pool({
|
||||||
|
host: '47.116.196.11',
|
||||||
|
port: 15432,
|
||||||
|
database: 'postgresql',
|
||||||
|
user: 'postgresql',
|
||||||
|
password: 'Jchl1528'
|
||||||
|
});
|
||||||
|
|
||||||
|
async function findMissingIds() {
|
||||||
|
try {
|
||||||
|
// 1. 查找 op_schedule 中存在的 apply_id,但在 cli_surgery 中不存在的
|
||||||
|
console.log('=== 查找不匹配的 apply_id ===\n');
|
||||||
|
|
||||||
|
const result = await pool.query(`
|
||||||
|
SELECT DISTINCT os.apply_id
|
||||||
|
FROM hisdev.op_schedule os
|
||||||
|
LEFT JOIN hisdev.cli_surgery cs ON os.apply_id = cs.id
|
||||||
|
WHERE os.delete_flag = '0'
|
||||||
|
AND cs.id IS NULL
|
||||||
|
ORDER BY os.apply_id DESC
|
||||||
|
LIMIT 10
|
||||||
|
`);
|
||||||
|
|
||||||
|
console.log('在 op_schedule 中存在,但在 cli_surgery 中不存在的 apply_id:');
|
||||||
|
console.table(result.rows);
|
||||||
|
|
||||||
|
// 2. 尝试用这些 ID 直接查询 cli_surgery
|
||||||
|
if (result.rows.length > 0) {
|
||||||
|
console.log('\n=== 尝试直接查询这些 ID ===');
|
||||||
|
for (const row of result.rows) {
|
||||||
|
const id = row.apply_id;
|
||||||
|
const checkResult = await pool.query(`
|
||||||
|
SELECT id, surgery_no, patient_name, status_enum, delete_flag
|
||||||
|
FROM hisdev.cli_surgery
|
||||||
|
WHERE id = $1
|
||||||
|
`, [id]);
|
||||||
|
|
||||||
|
if (checkResult.rows.length === 0) {
|
||||||
|
console.log(`ID ${id}: 在 cli_surgery 表中不存在`);
|
||||||
|
} else {
|
||||||
|
console.log(`ID ${id}: 找到记录`, checkResult.rows[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 检查是否有可能是手术单号匹配而不是 ID 匹配
|
||||||
|
console.log('\n=== 检查手术单号关联 ===');
|
||||||
|
const operCodeResult = await pool.query(`
|
||||||
|
SELECT
|
||||||
|
os.schedule_id,
|
||||||
|
os.oper_code,
|
||||||
|
os.apply_id,
|
||||||
|
cs.id as surgery_id_by_apply_id,
|
||||||
|
cs2.id as surgery_id_by_oper_code,
|
||||||
|
cs2.surgery_no,
|
||||||
|
cs2.apply_dept_name,
|
||||||
|
cs2.main_surgeon_name
|
||||||
|
FROM hisdev.op_schedule os
|
||||||
|
LEFT JOIN hisdev.cli_surgery cs ON os.apply_id = cs.id
|
||||||
|
LEFT JOIN hisdev.cli_surgery cs2 ON os.oper_code = cs2.surgery_no
|
||||||
|
WHERE os.delete_flag = '0'
|
||||||
|
ORDER BY os.create_time DESC
|
||||||
|
LIMIT 5
|
||||||
|
`);
|
||||||
|
|
||||||
|
console.table(operCodeResult.rows);
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error('查询失败:', err.message);
|
||||||
|
} finally {
|
||||||
|
pool.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
findMissingIds();
|
||||||
105
fix_surgery_data.js
Normal file
105
fix_surgery_data.js
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
const { Pool } = require('pg');
|
||||||
|
const pool = new Pool({
|
||||||
|
host: '47.116.196.11',
|
||||||
|
port: 15432,
|
||||||
|
database: 'postgresql',
|
||||||
|
user: 'postgresql',
|
||||||
|
password: 'Jchl1528'
|
||||||
|
});
|
||||||
|
|
||||||
|
async function fixData() {
|
||||||
|
const client = await pool.connect();
|
||||||
|
|
||||||
|
try {
|
||||||
|
await client.query('BEGIN');
|
||||||
|
|
||||||
|
// 1. 修复申请科室名称
|
||||||
|
console.log('步骤1: 修复申请科室名称...');
|
||||||
|
const fixDeptResult = await client.query(`
|
||||||
|
UPDATE hisdev.cli_surgery s
|
||||||
|
SET apply_dept_name = o.name
|
||||||
|
FROM hisdev.adm_organization o
|
||||||
|
WHERE s.apply_dept_id = o.id
|
||||||
|
AND (s.apply_dept_name IS NULL OR s.apply_dept_name = '')
|
||||||
|
AND s.delete_flag = '0'
|
||||||
|
`);
|
||||||
|
console.log(` 修复了 ${fixDeptResult.rowCount} 条申请科室记录`);
|
||||||
|
|
||||||
|
// 2. 修复主刀医生姓名
|
||||||
|
console.log('步骤2: 修复主刀医生姓名...');
|
||||||
|
const fixSurgeonResult = await client.query(`
|
||||||
|
UPDATE hisdev.cli_surgery s
|
||||||
|
SET main_surgeon_name = u.nick_name
|
||||||
|
FROM hisdev.sys_user u
|
||||||
|
WHERE s.main_surgeon_id = u.user_id
|
||||||
|
AND (s.main_surgeon_name IS NULL OR s.main_surgeon_name = '')
|
||||||
|
AND s.delete_flag = '0'
|
||||||
|
`);
|
||||||
|
console.log(` 修复了 ${fixSurgeonResult.rowCount} 条主刀医生记录`);
|
||||||
|
|
||||||
|
// 3. 对于 apply_dept_id 为空但有 org_id 的记录,使用 org_name
|
||||||
|
console.log('步骤3: 使用 org_name 填充剩余空申请科室...');
|
||||||
|
const fixOrgResult = await client.query(`
|
||||||
|
UPDATE hisdev.cli_surgery s
|
||||||
|
SET apply_dept_name = o.name,
|
||||||
|
apply_dept_id = s.org_id
|
||||||
|
FROM hisdev.adm_organization o
|
||||||
|
WHERE s.org_id = o.id
|
||||||
|
AND (s.apply_dept_name IS NULL OR s.apply_dept_name = '')
|
||||||
|
AND s.delete_flag = '0'
|
||||||
|
`);
|
||||||
|
console.log(` 修复了 ${fixOrgResult.rowCount} 条使用org_name的记录`);
|
||||||
|
|
||||||
|
// 4. 验证修复结果
|
||||||
|
console.log('步骤4: 验证修复结果...');
|
||||||
|
const checkResult = await client.query(`
|
||||||
|
SELECT
|
||||||
|
COUNT(*) as total_count,
|
||||||
|
COUNT(apply_dept_name) as has_apply_dept_name_count,
|
||||||
|
COUNT(*) - COUNT(apply_dept_name) as apply_dept_name_null_count,
|
||||||
|
COUNT(main_surgeon_name) as has_main_surgeon_name_count,
|
||||||
|
COUNT(*) - COUNT(main_surgeon_name) as main_surgeon_name_null_count
|
||||||
|
FROM hisdev.cli_surgery
|
||||||
|
WHERE delete_flag = '0'
|
||||||
|
`);
|
||||||
|
|
||||||
|
console.log('\n=== 修复后统计 ===');
|
||||||
|
console.log(JSON.stringify(checkResult.rows[0], null, 2));
|
||||||
|
|
||||||
|
// 5. 查看仍有空值的记录
|
||||||
|
const nullRecords = await client.query(`
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
surgery_no,
|
||||||
|
patient_name,
|
||||||
|
apply_dept_id,
|
||||||
|
apply_dept_name,
|
||||||
|
main_surgeon_id,
|
||||||
|
main_surgeon_name
|
||||||
|
FROM hisdev.cli_surgery
|
||||||
|
WHERE delete_flag = '0'
|
||||||
|
AND (apply_dept_name IS NULL OR apply_dept_name = '' OR main_surgeon_name IS NULL OR main_surgeon_name = '')
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
LIMIT 10
|
||||||
|
`);
|
||||||
|
|
||||||
|
if (nullRecords.rows.length > 0) {
|
||||||
|
console.log('\n=== 仍有空值的记录 ===');
|
||||||
|
console.log(JSON.stringify(nullRecords.rows, null, 2));
|
||||||
|
} else {
|
||||||
|
console.log('\n✅ 所有记录的申请科室和主刀医生姓名已修复完毕!');
|
||||||
|
}
|
||||||
|
|
||||||
|
await client.query('COMMIT');
|
||||||
|
console.log('\n修复完成!');
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
await client.query('ROLLBACK');
|
||||||
|
console.error('修复失败:', err.message);
|
||||||
|
} finally {
|
||||||
|
client.release();
|
||||||
|
pool.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fixData();
|
||||||
70
md/BUG_ANALYSIS.md
Normal file
70
md/BUG_ANALYSIS.md
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
# HIS项目 Bug 分析与修复日志
|
||||||
|
|
||||||
|
## 2026-04-05 23:55 - 子龙开始工作
|
||||||
|
|
||||||
|
### Bug 334 分析:门诊医生站-检验申请界面按钮布局优化
|
||||||
|
|
||||||
|
**文件位置**:
|
||||||
|
- `/openhis-ui-vue3/src/views/doctorstation/components/inspection/inspectionApplication.vue`
|
||||||
|
|
||||||
|
**当前布局问题**:
|
||||||
|
1. 顶部操作按钮区高度 60px,可能有优化空间
|
||||||
|
2. 表单区域 padding 较大
|
||||||
|
3. 需要优化垂直空间利用率
|
||||||
|
|
||||||
|
**修复方案**:
|
||||||
|
- 减少不必要的 padding 和 margin
|
||||||
|
- 优化表单字段布局
|
||||||
|
- 调整按钮区域高度
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Bug 335 分析:门诊医生站开立药品医嘱点击【保存】时报错
|
||||||
|
|
||||||
|
**文件位置**:
|
||||||
|
- `/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationAdviceAppServiceImpl.java`
|
||||||
|
|
||||||
|
**问题定位**:
|
||||||
|
- 方法:`saveAdvice()` -> `handMedication()`
|
||||||
|
- 可能原因:
|
||||||
|
1. encounterId 或 patientId 为 null
|
||||||
|
2. 库存校验失败
|
||||||
|
3. 账户ID缺失
|
||||||
|
|
||||||
|
**代码已修复**:
|
||||||
|
- 行 488-588:已添加 encounterId 和 patientId 校验
|
||||||
|
- 行 497-588:自动补全逻辑
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Bug 336 分析:门诊医生站开立诊疗项目后点击【保存】报错
|
||||||
|
|
||||||
|
**文件位置**:
|
||||||
|
- 同上文件
|
||||||
|
|
||||||
|
**问题定位**:
|
||||||
|
- 方法:`saveAdvice()` -> `handService()`
|
||||||
|
- 可能原因:
|
||||||
|
1. effectiveOrgId(执行科室)为 null
|
||||||
|
2. accountId 为 null
|
||||||
|
|
||||||
|
**代码已修复**:
|
||||||
|
- 行 1290-1390:已添加 accountId 自动补全
|
||||||
|
- 行 1338-1343:诊疗项目执行科室非空校验
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 工作分工
|
||||||
|
|
||||||
|
| Bug ID | 负责人 | 状态 |
|
||||||
|
|--------|--------|------|
|
||||||
|
| 334 | 子龙 | 分析中 |
|
||||||
|
| 335 | 关羽 | 待修复 |
|
||||||
|
| 336 | 关羽 | 待修复 |
|
||||||
|
| 338 | 关羽 | 待修复 |
|
||||||
|
|
||||||
|
## 下一步行动
|
||||||
|
|
||||||
|
1. 子龙修复 Bug 334(检验申请界面布局优化)
|
||||||
|
2. 关羽修复 Bug 335、336、338
|
||||||
|
3. 张飞测试验证
|
||||||
10
md/test.html
Normal file
10
md/test.html
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>测试合并11111</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
193
null_key_error_analysis.md
Normal file
193
null_key_error_analysis.md
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
# "element cannot be mapped to a null key" 错误分析报告
|
||||||
|
|
||||||
|
## 错误根本原因
|
||||||
|
|
||||||
|
该错误发生在 Java Stream 使用 `Collectors.groupingBy` 或 `Collectors.toMap` 时,**key 为 null** 导致的。
|
||||||
|
|
||||||
|
Java 的 `HashMap` 不允许 null key(与 `HashMap` 的实现有关),当试图将元素映射到 null key 时,就会抛出此异常。
|
||||||
|
|
||||||
|
## 问题定位
|
||||||
|
|
||||||
|
### 1. 数据层问题 - SQL 查询返回 null
|
||||||
|
|
||||||
|
#### 位置1: ChargeItemMapper.xml (第71行)
|
||||||
|
**文件**: `openhis-server-new/openhis-domain/src/main/resources/mapper/administration/ChargeItemMapper.xml`
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT
|
||||||
|
...
|
||||||
|
contract.bus_no as contract_no, -- 第71行
|
||||||
|
...
|
||||||
|
FROM adm_charge_item a
|
||||||
|
...
|
||||||
|
LEFT JOIN adm_account acc ON a.account_id = acc.id
|
||||||
|
LEFT JOIN fin_contract contract ON acc.contract_no = contract.bus_no -- LEFT JOIN
|
||||||
|
```
|
||||||
|
|
||||||
|
**问题**: 使用 LEFT JOIN 关联 `fin_contract` 表,当 `acc.contract_no` 为 null 或没有匹配的合同记录时,`contract.bus_no` 会返回 null。
|
||||||
|
|
||||||
|
#### 位置2: PaymentRecDetailMapper.xml (第37行)
|
||||||
|
**文件**: `openhis-server-new/openhis-domain/src/main/resources/mapper/financial/PaymentRecDetailMapper.xml`
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT
|
||||||
|
...
|
||||||
|
T2.contract_no, -- 第37行
|
||||||
|
...
|
||||||
|
FROM fin_payment_rec_detail T1
|
||||||
|
LEFT JOIN adm_account T2 ON T1.account_id = T2."id" -- LEFT JOIN
|
||||||
|
```
|
||||||
|
|
||||||
|
**问题**: 使用 LEFT JOIN 关联 `adm_account` 表,当 `T1.account_id` 为 null 或没有匹配的账户记录时,`T2.contract_no` 会返回 null。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. 业务层问题 - 使用 groupingBy 时 key 可能为 null
|
||||||
|
|
||||||
|
#### 位置1: PaymentRecServiceImpl.java (第2334行)
|
||||||
|
**文件**: `openhis-server-new/openhis-application/src/main/java/com/openhis/web/paymentmanage/appservice/impl/PaymentRecServiceImpl.java`
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 2333-2334行
|
||||||
|
Map<String, List<ChargeItemBaseInfoDto>> chargeItemKVByContractNo
|
||||||
|
= chargeItemBaseInfoByIds.stream().collect(Collectors.groupingBy(ChargeItemBaseInfoDto::getContractNo));
|
||||||
|
```
|
||||||
|
|
||||||
|
**风险**: 如果 `ChargeItemBaseInfoDto.contractNo` 为 null(来自上述 SQL 查询),将抛出异常。
|
||||||
|
|
||||||
|
#### 位置2: PaymentRecServiceImpl.java (第2462行)
|
||||||
|
**文件**: `openhis-server-new/openhis-application/src/main/java/com/openhis/web/paymentmanage/appservice/impl/PaymentRecServiceImpl.java`
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 2461-2462行
|
||||||
|
Map<String, List<ChargeItemBaseInfoDto>> chargeItemKVByContractNo
|
||||||
|
= chargeItemBaseInfoByIds.stream().collect(Collectors.groupingBy(ChargeItemBaseInfoDto::getContractNo));
|
||||||
|
```
|
||||||
|
|
||||||
|
**风险**: 同上,如果 `contractNo` 为 null,将抛出异常。
|
||||||
|
|
||||||
|
#### 位置3: PaymentRecServiceImpl.java (第2478行)
|
||||||
|
**文件**: `openhis-server-new/openhis-application/src/main/java/com/openhis/web/paymentmanage/appservice/impl/PaymentRecServiceImpl.java`
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 2477-2478行
|
||||||
|
Map<Long, List<PaymentRecDetail>> payTransNoMap
|
||||||
|
= paymentRecDetails.stream().collect(Collectors.groupingBy(PaymentRecDetail::getAccountId));
|
||||||
|
```
|
||||||
|
|
||||||
|
**风险**: 如果 `PaymentRecDetail.accountId` 为 null,将抛出异常。
|
||||||
|
|
||||||
|
#### 位置4: IChargeBillServiceImpl.java (第936行)
|
||||||
|
**文件**: `openhis-server-new/openhis-application/src/main/java/com/openhis/web/paymentmanage/appservice/impl/IChargeBillServiceImpl.java`
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 935-936行
|
||||||
|
Map<String, List<PaymentRecDetailAccountResult>> paymentDetailsMapByContract = PaymentRecDetailAccountResultList
|
||||||
|
.stream().collect(Collectors.groupingBy(PaymentRecDetailAccountResult::getContractNo));
|
||||||
|
```
|
||||||
|
|
||||||
|
**风险**: 如果 `PaymentRecDetailAccountResult.contractNo` 为 null(来自上述 SQL 查询),将抛出异常。
|
||||||
|
|
||||||
|
#### 位置5: IChargeBillServiceImpl.java (第1485行)
|
||||||
|
**文件**: `openhis-server-new/openhis-application/src/main/java/com/openhis/web/paymentmanage/appservice/impl/IChargeBillServiceImpl.java`
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 1484-1485行
|
||||||
|
Map<String, List<PaymentRecDetailAccountResult>> paymentDetailsMapByContract = PaymentRecDetailAccountResultList
|
||||||
|
.stream().collect(Collectors.groupingBy(PaymentRecDetailAccountResult::getContractNo));
|
||||||
|
```
|
||||||
|
|
||||||
|
**风险**: 同上,如果 `contractNo` 为 null,将抛出异常。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 修复建议
|
||||||
|
|
||||||
|
### 方案1: 修改 SQL 查询,使用 COALESCE 处理 null (推荐)
|
||||||
|
|
||||||
|
修改 `ChargeItemMapper.xml` 第71行:
|
||||||
|
```sql
|
||||||
|
-- 修改前
|
||||||
|
contract.bus_no as contract_no,
|
||||||
|
|
||||||
|
-- 修改后
|
||||||
|
COALESCE(contract.bus_no, 'DEFAULT') as contract_no,
|
||||||
|
```
|
||||||
|
|
||||||
|
修改 `PaymentRecDetailMapper.xml` 第37行:
|
||||||
|
```sql
|
||||||
|
-- 修改前
|
||||||
|
T2.contract_no,
|
||||||
|
|
||||||
|
-- 修改后
|
||||||
|
COALESCE(T2.contract_no, 'DEFAULT') as contract_no,
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方案2: 修改 Java 代码,过滤 null key
|
||||||
|
|
||||||
|
在使用 `groupingBy` 之前过滤掉 key 为 null 的数据:
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 修改前
|
||||||
|
Map<String, List<ChargeItemBaseInfoDto>> chargeItemKVByContractNo
|
||||||
|
= chargeItemBaseInfoByIds.stream().collect(Collectors.groupingBy(ChargeItemBaseInfoDto::getContractNo));
|
||||||
|
|
||||||
|
// 修改后
|
||||||
|
Map<String, List<ChargeItemBaseInfoDto>> chargeItemKVByContractNo
|
||||||
|
= chargeItemBaseInfoByIds.stream()
|
||||||
|
.filter(dto -> dto.getContractNo() != null)
|
||||||
|
.collect(Collectors.groupingBy(ChargeItemBaseInfoDto::getContractNo));
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方案3: 使用 null-safe 的收集器
|
||||||
|
|
||||||
|
自定义一个处理 null key 的收集器:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public static <T, K> Collector<T, ?, Map<K, List<T>>> groupingByNullSafe(
|
||||||
|
Function<? super T, ? extends K> classifier) {
|
||||||
|
return Collectors.groupingBy(
|
||||||
|
classifier,
|
||||||
|
HashMap::new,
|
||||||
|
Collectors.toList()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 建议修复优先级
|
||||||
|
|
||||||
|
1. **高优先级**: 修改 `ChargeItemMapper.xml` 和 `PaymentRecDetailMapper.xml` 的 SQL 查询
|
||||||
|
- 这是根本原因,修复后可以防止 null 值传播到 Java 层
|
||||||
|
|
||||||
|
2. **中优先级**: 修改 `PaymentRecServiceImpl.java` 第2334行和第2462行
|
||||||
|
- 这是门诊收费和住院结算的关键路径
|
||||||
|
|
||||||
|
3. **低优先级**: 修改 `IChargeBillServiceImpl.java` 第936行和第1485行
|
||||||
|
- 这是收费账单相关功能
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 与最近修改的关系
|
||||||
|
|
||||||
|
用户提到最近修改了 `OutpatientChargeAppMapper.xml`,增加了 `cli_surgery` 表关联。
|
||||||
|
|
||||||
|
虽然这个修改本身不会直接导致 `contract_no` 为 null,但可能触发了某些收费流程,使得原本不会执行的代码路径被执行,从而暴露了这个潜在问题。
|
||||||
|
|
||||||
|
根本原因还是 `ChargeItemMapper.xml` 中的 SQL 查询使用了 LEFT JOIN 导致 `contract_no` 可能为 null。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 验证方法
|
||||||
|
|
||||||
|
1. 检查数据库中是否存在 `account_id` 为 null 的 `adm_charge_item` 记录
|
||||||
|
2. 检查数据库中是否存在 `contract_no` 为 null 的 `adm_account` 记录
|
||||||
|
3. 在出现错误的收费操作中,打印相关 DTO 对象的 `contractNo` 字段值
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 调试代码示例
|
||||||
|
chargeItemBaseInfoByIds.forEach(dto -> {
|
||||||
|
System.out.println("ChargeItem ID: " + dto.getId() + ", contractNo: " + dto.getContractNo());
|
||||||
|
});
|
||||||
|
```
|
||||||
@@ -1,11 +1,15 @@
|
|||||||
package com.core.framework.config;
|
package com.core.framework.config;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||||
import org.mybatis.spring.annotation.MapperScan;
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,6 +28,14 @@ public class ApplicationConfig {
|
|||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
|
public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
|
||||||
return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault());
|
return builder -> {
|
||||||
|
// 设置默认时区
|
||||||
|
builder.timeZone(TimeZone.getDefault());
|
||||||
|
// 设置日期格式为 yyyy/M/d HH:mm:ss,支持多种格式反序列化
|
||||||
|
builder.simpleDateFormat("yyyy/M/d HH:mm:ss");
|
||||||
|
// 添加JavaTimeModule支持,用于LocalDateTime
|
||||||
|
builder.modules(new JavaTimeModule());
|
||||||
|
builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy/M/d HH:mm:ss")));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.openhis.web.appointmentmanage.appservice;
|
||||||
|
|
||||||
|
import com.core.common.core.domain.R;
|
||||||
|
import com.openhis.appointmentmanage.domain.AppointmentConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预约配置AppService接口
|
||||||
|
*
|
||||||
|
* @author openhis
|
||||||
|
* @date 2026-03-23
|
||||||
|
*/
|
||||||
|
public interface IAppointmentConfigAppService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前机构的预约配置
|
||||||
|
*
|
||||||
|
* @return 预约配置
|
||||||
|
*/
|
||||||
|
R<?> getAppointmentConfig();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存预约配置
|
||||||
|
*
|
||||||
|
* @param appointmentConfig 预约配置
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
R<?> saveAppointmentConfig(AppointmentConfig appointmentConfig);
|
||||||
|
}
|
||||||
@@ -2,7 +2,9 @@ package com.openhis.web.appointmentmanage.appservice;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.core.common.core.domain.R;
|
import com.core.common.core.domain.R;
|
||||||
|
import com.openhis.appointmentmanage.dto.TicketQueryDTO;
|
||||||
import com.openhis.web.appointmentmanage.dto.TicketDto;
|
import com.openhis.web.appointmentmanage.dto.TicketDto;
|
||||||
|
import com.openhis.appointmentmanage.dto.TicketQueryDTO;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -14,36 +16,52 @@ import java.util.Map;
|
|||||||
public interface ITicketAppService {
|
public interface ITicketAppService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预约号源
|
* 分页查询门诊号源列表(真分页)
|
||||||
*
|
*
|
||||||
* @param params 预约参数
|
* @param query 查询参数
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
R<?> bookTicket(Map<String, Object> params);
|
R<?> listTicket(TicketQueryDTO query);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询医生余号汇总(基于号源池,不受分页影响)
|
||||||
|
*
|
||||||
|
* @param query 查询参数
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
R<?> listDoctorAvailability(TicketQueryDTO query);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预约号源
|
||||||
|
*
|
||||||
|
* @param dto 预约参数
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
R<?> bookTicket(com.openhis.appointmentmanage.domain.AppointmentBookDTO dto);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 取消预约
|
* 取消预约
|
||||||
*
|
*
|
||||||
* @param ticketId 号源ID
|
* @param slotId 槽位ID
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
R<?> cancelTicket(Long ticketId);
|
R<?> cancelTicket(Long slotId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 取号
|
* 取号
|
||||||
*
|
*
|
||||||
* @param ticketId 号源ID
|
* @param slotId 槽位ID
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
R<?> checkInTicket(Long ticketId);
|
R<?> checkInTicket(Long slotId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 停诊
|
* 停诊
|
||||||
*
|
*
|
||||||
* @param ticketId 号源ID
|
* @param slotId 槽位ID
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
R<?> cancelConsultation(Long ticketId);
|
R<?> cancelConsultation(Long slotId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询所有号源(用于测试)
|
* 查询所有号源(用于测试)
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package com.openhis.web.appointmentmanage.appservice.impl;
|
||||||
|
|
||||||
|
import com.core.common.core.domain.R;
|
||||||
|
import com.core.common.utils.SecurityUtils;
|
||||||
|
import com.openhis.appointmentmanage.domain.AppointmentConfig;
|
||||||
|
import com.openhis.appointmentmanage.service.IAppointmentConfigService;
|
||||||
|
import com.openhis.web.appointmentmanage.appservice.IAppointmentConfigAppService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预约配置AppService实现类
|
||||||
|
*
|
||||||
|
* @author openhis
|
||||||
|
* @date 2026-03-23
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class AppointmentConfigAppServiceImpl implements IAppointmentConfigAppService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IAppointmentConfigService appointmentConfigService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<?> getAppointmentConfig() {
|
||||||
|
// 获取当前登录用户的机构ID
|
||||||
|
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
||||||
|
if (tenantId == null) {
|
||||||
|
return R.fail("获取机构信息失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
AppointmentConfig config = appointmentConfigService.getConfigByTenantId(tenantId);
|
||||||
|
return R.ok(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<?> saveAppointmentConfig(AppointmentConfig appointmentConfig) {
|
||||||
|
// 获取当前登录用户的机构ID
|
||||||
|
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
||||||
|
if (tenantId == null) {
|
||||||
|
return R.fail("获取机构信息失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询是否已存在配置
|
||||||
|
AppointmentConfig existingConfig = appointmentConfigService.getConfigByTenantId(tenantId);
|
||||||
|
|
||||||
|
if (existingConfig != null) {
|
||||||
|
// 更新现有配置
|
||||||
|
existingConfig.setCancelAppointmentType(appointmentConfig.getCancelAppointmentType());
|
||||||
|
existingConfig.setCancelAppointmentCount(appointmentConfig.getCancelAppointmentCount());
|
||||||
|
existingConfig.setValidFlag(appointmentConfig.getValidFlag());
|
||||||
|
appointmentConfigService.saveOrUpdate(existingConfig);
|
||||||
|
return R.ok(existingConfig);
|
||||||
|
} else {
|
||||||
|
// 新增配置
|
||||||
|
appointmentConfig.setTenantId(tenantId);
|
||||||
|
appointmentConfig.setValidFlag(1);
|
||||||
|
appointmentConfigService.saveOrUpdateConfig(appointmentConfig);
|
||||||
|
return R.ok(appointmentConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
package com.openhis.web.appointmentmanage.appservice.impl;
|
package com.openhis.web.appointmentmanage.appservice.impl;
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.core.common.core.domain.R;
|
import com.core.common.core.domain.R;
|
||||||
import com.core.common.utils.SecurityUtils;
|
import com.core.common.utils.SecurityUtils;
|
||||||
|
import com.openhis.common.constant.CommonConstants;
|
||||||
import com.openhis.appointmentmanage.domain.DoctorSchedule;
|
import com.openhis.appointmentmanage.domain.DoctorSchedule;
|
||||||
import com.openhis.appointmentmanage.domain.DoctorScheduleWithDateDto;
|
import com.openhis.appointmentmanage.domain.DoctorScheduleWithDateDto;
|
||||||
import com.openhis.appointmentmanage.domain.SchedulePool;
|
import com.openhis.appointmentmanage.domain.SchedulePool;
|
||||||
@@ -260,7 +262,10 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
|||||||
|| doctorSchedule.getLimitNumber() != null
|
|| doctorSchedule.getLimitNumber() != null
|
||||||
|| doctorSchedule.getStopReason() != null
|
|| doctorSchedule.getStopReason() != null
|
||||||
|| doctorSchedule.getRegType() != null
|
|| doctorSchedule.getRegType() != null
|
||||||
|| doctorSchedule.getRegisterFee() != null;
|
|| doctorSchedule.getRegisterFee() != null
|
||||||
|
|| doctorSchedule.getRegisterItem() != null
|
||||||
|
|| doctorSchedule.getDiagnosisItem() != null
|
||||||
|
|| doctorSchedule.getDiagnosisFee() != null;
|
||||||
|
|
||||||
if (needSyncPool) {
|
if (needSyncPool) {
|
||||||
schedulePoolService.lambdaUpdate()
|
schedulePoolService.lambdaUpdate()
|
||||||
@@ -274,9 +279,9 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
|||||||
doctorSchedule.getLimitNumber())
|
doctorSchedule.getLimitNumber())
|
||||||
.set(doctorSchedule.getStopReason() != null, SchedulePool::getStopReason, doctorSchedule.getStopReason())
|
.set(doctorSchedule.getStopReason() != null, SchedulePool::getStopReason, doctorSchedule.getStopReason())
|
||||||
.set(doctorSchedule.getRegType() != null, SchedulePool::getRegType, String.valueOf(doctorSchedule.getRegType()))
|
.set(doctorSchedule.getRegType() != null, SchedulePool::getRegType, String.valueOf(doctorSchedule.getRegType()))
|
||||||
.set(doctorSchedule.getRegisterFee() != null, SchedulePool::getFee, doctorSchedule.getRegisterFee() / 100.0)
|
.set(doctorSchedule.getRegisterFee() != null, SchedulePool::getFee, Double.valueOf(doctorSchedule.getRegisterFee().toString()))
|
||||||
.set(doctorSchedule.getRegisterFee() != null, SchedulePool::getInsurancePrice,
|
.set(doctorSchedule.getRegisterFee() != null, SchedulePool::getInsurancePrice,
|
||||||
doctorSchedule.getRegisterFee() / 100.0)
|
Double.valueOf(doctorSchedule.getRegisterFee().toString()))
|
||||||
.update();
|
.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,7 +311,7 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
|||||||
// 不设置available_num,因为它是数据库生成列
|
// 不设置available_num,因为它是数据库生成列
|
||||||
// pool.setAvailableNum(0); // 初始为0,稍后更新
|
// pool.setAvailableNum(0); // 初始为0,稍后更新
|
||||||
pool.setRegType(schedule.getRegisterItem() != null ? schedule.getRegisterItem() : "普通");
|
pool.setRegType(schedule.getRegisterItem() != null ? schedule.getRegisterItem() : "普通");
|
||||||
pool.setFee(schedule.getRegisterFee() != null ? schedule.getRegisterFee() / 100.0 : 0.0); // 假设数据库中以分为单位存储
|
pool.setFee(schedule.getRegisterFee() != null ? Double.valueOf(schedule.getRegisterFee().toString()) : 0.0); // 直接使用原始价格
|
||||||
pool.setInsurancePrice(pool.getFee()); // 医保价格暂时与原价相同
|
pool.setInsurancePrice(pool.getFee()); // 医保价格暂时与原价相同
|
||||||
// 暂时设置support_channel为空字符串,避免JSON类型问题
|
// 暂时设置support_channel为空字符串,避免JSON类型问题
|
||||||
pool.setSupportChannel("");
|
pool.setSupportChannel("");
|
||||||
@@ -359,7 +364,7 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
|||||||
// 不设置available_num,因为它是数据库生成列
|
// 不设置available_num,因为它是数据库生成列
|
||||||
// pool.setAvailableNum(0); // 初始为0,稍后更新
|
// pool.setAvailableNum(0); // 初始为0,稍后更新
|
||||||
pool.setRegType(schedule.getRegisterItem() != null ? schedule.getRegisterItem() : "普通");
|
pool.setRegType(schedule.getRegisterItem() != null ? schedule.getRegisterItem() : "普通");
|
||||||
pool.setFee(schedule.getRegisterFee() != null ? schedule.getRegisterFee() / 100.0 : 0.0); // 假设数据库中以分为单位存储
|
pool.setFee(schedule.getRegisterFee() != null ? Double.valueOf(schedule.getRegisterFee().toString()) : 0.0); // 直接使用原始价格
|
||||||
pool.setInsurancePrice(pool.getFee()); // 医保价格暂时与原价相同
|
pool.setInsurancePrice(pool.getFee()); // 医保价格暂时与原价相同
|
||||||
// 暂时设置support_channel为空字符串,避免JSON类型问题
|
// 暂时设置support_channel为空字符串,避免JSON类型问题
|
||||||
pool.setSupportChannel("");
|
pool.setSupportChannel("");
|
||||||
@@ -494,6 +499,15 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
|||||||
if (ObjectUtil.isNotEmpty(pools)) {
|
if (ObjectUtil.isNotEmpty(pools)) {
|
||||||
List<Long> poolIds = pools.stream().map(SchedulePool::getId).collect(java.util.stream.Collectors.toList());
|
List<Long> poolIds = pools.stream().map(SchedulePool::getId).collect(java.util.stream.Collectors.toList());
|
||||||
|
|
||||||
|
// 该排班下存在有效患者预约(号源槽:已预约/已锁定/已取号)则禁止删除;已退号、仅可用/已取消槽位不计入
|
||||||
|
long appointmentCount = scheduleSlotService.count(new QueryWrapper<ScheduleSlot>()
|
||||||
|
.in("pool_id", poolIds)
|
||||||
|
.in("status", CommonConstants.SlotStatus.BOOKED, CommonConstants.SlotStatus.LOCKED,
|
||||||
|
CommonConstants.SlotStatus.CHECKED_IN));
|
||||||
|
if (appointmentCount > 0) {
|
||||||
|
return R.fail("该排班已有患者预约,禁止删除!如需取消请先处理患者退预约或使用'停诊'功能。");
|
||||||
|
}
|
||||||
|
|
||||||
// 2. 根据号源池ID找到所有关联的号源槽
|
// 2. 根据号源池ID找到所有关联的号源槽
|
||||||
List<ScheduleSlot> slots = scheduleSlotService.list(
|
List<ScheduleSlot> slots = scheduleSlotService.list(
|
||||||
new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<ScheduleSlot>()
|
new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<ScheduleSlot>()
|
||||||
|
|||||||
@@ -4,28 +4,22 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|||||||
import com.core.common.core.domain.R;
|
import com.core.common.core.domain.R;
|
||||||
import com.openhis.administration.domain.Patient;
|
import com.openhis.administration.domain.Patient;
|
||||||
import com.openhis.administration.service.IPatientService;
|
import com.openhis.administration.service.IPatientService;
|
||||||
import com.openhis.appointmentmanage.domain.DoctorSchedule;
|
import com.openhis.appointmentmanage.mapper.ScheduleSlotMapper;
|
||||||
import com.openhis.appointmentmanage.mapper.DoctorScheduleMapper;
|
|
||||||
import com.openhis.appointmentmanage.service.IDoctorScheduleService;
|
|
||||||
import com.openhis.clinical.domain.Order;
|
|
||||||
import com.openhis.clinical.domain.Ticket;
|
import com.openhis.clinical.domain.Ticket;
|
||||||
import com.openhis.clinical.mapper.OrderMapper;
|
|
||||||
import com.openhis.clinical.service.ITicketService;
|
import com.openhis.clinical.service.ITicketService;
|
||||||
import com.openhis.web.appointmentmanage.appservice.IDoctorScheduleAppService;
|
|
||||||
import com.openhis.web.appointmentmanage.appservice.ITicketAppService;
|
import com.openhis.web.appointmentmanage.appservice.ITicketAppService;
|
||||||
import com.openhis.web.appointmentmanage.dto.TicketDto;
|
import com.openhis.web.appointmentmanage.dto.TicketDto;
|
||||||
|
import com.openhis.common.constant.CommonConstants.SlotStatus;
|
||||||
|
import com.openhis.common.constant.CommonConstants.AppointmentOrderStatus;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.time.*;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Locale;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 号源管理应用服务实现类
|
* 号源管理应用服务实现类
|
||||||
*
|
*
|
||||||
@@ -36,73 +30,41 @@ public class TicketAppServiceImpl implements ITicketAppService {
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ITicketService ticketService;
|
private ITicketService ticketService;
|
||||||
|
@Resource
|
||||||
|
private ScheduleSlotMapper scheduleSlotMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private IPatientService patientService;
|
private IPatientService patientService;
|
||||||
@Resource
|
|
||||||
private IDoctorScheduleAppService doctorScheduleAppService;
|
|
||||||
@Resource
|
|
||||||
private DoctorScheduleMapper doctorScheduleMapper;
|
|
||||||
@Resource
|
|
||||||
private OrderMapper orderMapper;
|
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(TicketAppServiceImpl.class);
|
private static final Logger log = LoggerFactory.getLogger(TicketAppServiceImpl.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预约号源
|
* 预约号源 (重构版:精准锁定单一槽位)
|
||||||
*
|
*
|
||||||
* @param params 预约参数
|
* @param dto 预约参数
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public R<?> bookTicket(Map<String, Object> params) {
|
public R<?> bookTicket(com.openhis.appointmentmanage.domain.AppointmentBookDTO dto) {
|
||||||
// 1. 获取 ticketId 和 slotId
|
Long slotId = dto.getSlotId();
|
||||||
Long ticketId = null;
|
if (slotId == null) {
|
||||||
Long slotId = null;
|
return R.fail("参数校验失败:缺少排班槽位唯一标识");
|
||||||
if (params.get("ticketId") != null) {
|
|
||||||
ticketId = Long.valueOf(params.get("ticketId").toString());
|
|
||||||
}
|
}
|
||||||
if (params.get("slotId") != null) {
|
|
||||||
slotId = Long.valueOf(params.get("slotId").toString());
|
|
||||||
}
|
|
||||||
// 2. 参数校验
|
|
||||||
if (ticketId == null || slotId == null) {
|
|
||||||
return R.fail("参数错误:ticketId 或 slotId 不能为空");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 3. 执行原有的预约逻辑
|
int result = ticketService.bookTicket(dto);
|
||||||
int result = ticketService.bookTicket(params);
|
|
||||||
if (result > 0) {
|
if (result > 0) {
|
||||||
// 4. 预约成功后,更新排班表状态
|
return R.ok("预约成功!号源已安全锁定。");
|
||||||
DoctorSchedule schedule = new DoctorSchedule();
|
|
||||||
schedule.setId(slotId); // 对应 XML 中的 WHERE id = #{id}
|
|
||||||
schedule.setIsStopped(true); // 设置为已预约
|
|
||||||
schedule.setStopReason("booked"); // 设置停用原因
|
|
||||||
|
|
||||||
// 执行更新
|
|
||||||
int updateCount = doctorScheduleMapper.updateDoctorSchedule(schedule);
|
|
||||||
|
|
||||||
if (updateCount > 0) {
|
|
||||||
return R.ok("预约成功并已更新排班状态");
|
|
||||||
} else {
|
|
||||||
// 如果更新失败,可能需要根据业务逻辑决定是否回滚预约
|
|
||||||
return R.ok("预约成功,但排班状态更新失败");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return R.fail("预约失败");
|
|
||||||
}
|
}
|
||||||
|
return R.fail("预约挂单核发失败");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// e.printStackTrace();
|
log.error("大厅挂号捕获系统异常", e);
|
||||||
log.error(e.getMessage());
|
|
||||||
return R.fail("系统异常:" + e.getMessage());
|
return R.fail("系统异常:" + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 取消预约
|
* 取消预约 (重构版:精准释放单一槽位)
|
||||||
*
|
*
|
||||||
* @param slotId 医生排班ID
|
* @param slotId 医生槽位排班ID
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@@ -111,18 +73,8 @@ public class TicketAppServiceImpl implements ITicketAppService {
|
|||||||
return R.fail("参数错误");
|
return R.fail("参数错误");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
ticketService.cancelTicket(slotId);
|
int result = ticketService.cancelTicket(slotId);
|
||||||
DoctorSchedule schedule = new DoctorSchedule();
|
return R.ok(result > 0 ? "取消成功,号源已重新释放回市场" : "取消失败");
|
||||||
schedule.setId(slotId); // 对应 WHERE id = #{id}
|
|
||||||
schedule.setIsStopped(false); // 设置为 false
|
|
||||||
schedule.setStopReason(""); // 将原因清空 (设为空字符串)
|
|
||||||
// 3. 调用自定义更新方法
|
|
||||||
int updateCount = doctorScheduleMapper.updateDoctorSchedule(schedule);
|
|
||||||
if (updateCount > 0) {
|
|
||||||
return R.ok("取消成功");
|
|
||||||
} else {
|
|
||||||
return R.ok("取消成功");
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return R.fail(e.getMessage());
|
return R.fail(e.getMessage());
|
||||||
}
|
}
|
||||||
@@ -131,16 +83,16 @@ public class TicketAppServiceImpl implements ITicketAppService {
|
|||||||
/**
|
/**
|
||||||
* 取号
|
* 取号
|
||||||
*
|
*
|
||||||
* @param ticketId 号源ID
|
* @param slotId 槽位ID
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public R<?> checkInTicket(Long ticketId) {
|
public R<?> checkInTicket(Long slotId) {
|
||||||
if (ticketId == null) {
|
if (slotId == null) {
|
||||||
return R.fail("参数错误");
|
return R.fail("参数错误");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
int result = ticketService.checkInTicket(ticketId);
|
int result = ticketService.checkInTicket(slotId);
|
||||||
return R.ok(result > 0 ? "取号成功" : "取号失败");
|
return R.ok(result > 0 ? "取号成功" : "取号失败");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return R.fail(e.getMessage());
|
return R.fail(e.getMessage());
|
||||||
@@ -150,16 +102,16 @@ public class TicketAppServiceImpl implements ITicketAppService {
|
|||||||
/**
|
/**
|
||||||
* 停诊
|
* 停诊
|
||||||
*
|
*
|
||||||
* @param ticketId 号源ID
|
* @param slotId 槽位ID
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public R<?> cancelConsultation(Long ticketId) {
|
public R<?> cancelConsultation(Long slotId) {
|
||||||
if (ticketId == null) {
|
if (slotId == null) {
|
||||||
return R.fail("参数错误");
|
return R.fail("参数错误");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
int result = ticketService.cancelConsultation(ticketId);
|
int result = ticketService.cancelConsultation(slotId);
|
||||||
return R.ok(result > 0 ? "停诊成功" : "停诊失败");
|
return R.ok(result > 0 ? "停诊成功" : "停诊失败");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return R.fail(e.getMessage());
|
return R.fail(e.getMessage());
|
||||||
@@ -167,92 +119,283 @@ public class TicketAppServiceImpl implements ITicketAppService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public R<?> listAllTickets() {
|
public R<?> listTicket(com.openhis.appointmentmanage.dto.TicketQueryDTO query) {
|
||||||
// 1. 从 AppService 获取排班数据
|
// 1. 防空指针处理
|
||||||
R<?> response = doctorScheduleAppService.getDoctorScheduleList();
|
if (query == null) {
|
||||||
// 获取返回的 List 数据 (假设 R.ok 里的数据是 List<DoctorSchedule>)
|
query = new com.openhis.appointmentmanage.dto.TicketQueryDTO();
|
||||||
List<DoctorSchedule> scheduleList = (List<DoctorSchedule>) response.getData();
|
}
|
||||||
|
normalizeQueryStatus(query);
|
||||||
|
|
||||||
// 2. 转换数据为 TicketDto
|
// 2. 构造 MyBatis 的分页对象 (传入前端给的当前页和每页条数)
|
||||||
List<TicketDto> tickets = new ArrayList<>();
|
com.baomidou.mybatisplus.extension.plugins.pagination.Page<com.openhis.appointmentmanage.domain.TicketSlotDTO> pageParam = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(
|
||||||
|
query.getPage(), query.getLimit());
|
||||||
|
|
||||||
if (scheduleList != null) {
|
// 3. 调用刚才写的底层动态 SQL 查询!
|
||||||
for (DoctorSchedule schedule : scheduleList) {
|
com.baomidou.mybatisplus.extension.plugins.pagination.Page<com.openhis.appointmentmanage.domain.TicketSlotDTO> rawPage = scheduleSlotMapper
|
||||||
|
.selectTicketSlotsPage(pageParam, query);
|
||||||
|
|
||||||
|
// 4. 将查出来的数据翻译为前端可以直接渲染的结构
|
||||||
|
java.util.List<TicketDto> tickets = new java.util.ArrayList<>();
|
||||||
|
if (rawPage.getRecords() != null) {
|
||||||
|
for (com.openhis.appointmentmanage.domain.TicketSlotDTO raw : rawPage.getRecords()) {
|
||||||
TicketDto dto = new TicketDto();
|
TicketDto dto = new TicketDto();
|
||||||
|
|
||||||
// 基础信息映射
|
// 基础字段映射
|
||||||
dto.setSlot_id(Long.valueOf(schedule.getId())); // Integer 转 Long
|
dto.setSlot_id(raw.getSlotId());
|
||||||
dto.setBusNo(String.valueOf(schedule.getId())); // 生成一个业务编号
|
dto.setSeqNo(raw.getSeqNo());
|
||||||
dto.setDepartment(String.valueOf(schedule.getDeptId())); // 如果有科室名建议关联查询,这里暂填ID
|
dto.setBusNo(String.valueOf(raw.getSlotId()));
|
||||||
dto.setDoctor(schedule.getDoctor());
|
dto.setDoctor(raw.getDoctor());
|
||||||
|
dto.setDepartment(raw.getDepartmentName()); // 注意:以前这里传成了ID,导致前端出Bug,现在修复成了真正的科室名
|
||||||
|
dto.setFee(raw.getFee());
|
||||||
|
dto.setPatientName(raw.getPatientName());
|
||||||
|
dto.setPatientId(raw.getMedicalCard());
|
||||||
|
dto.setPhone(raw.getPhone());
|
||||||
|
dto.setIdCard(raw.getIdCard());
|
||||||
|
dto.setDoctorId(raw.getDoctorId());
|
||||||
|
dto.setDepartmentId(raw.getDepartmentId());
|
||||||
|
dto.setRealPatientId(raw.getPatientId());
|
||||||
|
|
||||||
// 号源类型处理:根据挂号项目判断是普通号还是专家号
|
// 性别处理:直接读取优先级最高的订单性别字段 (SQL 已处理优先级)
|
||||||
String registerItem = schedule.getRegisterItem();
|
if (raw.getPatientGender() != null) {
|
||||||
if (registerItem != null && registerItem.contains("专家")) {
|
String pg = raw.getPatientGender().trim();
|
||||||
|
dto.setGender("1".equals(pg) ? "男" : ("2".equals(pg) ? "女" : "未知"));
|
||||||
|
} else {
|
||||||
|
dto.setGender("未知");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (raw.getRegType() != null && raw.getRegType() == 1) {
|
||||||
dto.setTicketType("expert");
|
dto.setTicketType("expert");
|
||||||
} else {
|
} else {
|
||||||
dto.setTicketType("general");
|
dto.setTicketType("general");
|
||||||
}
|
}
|
||||||
// 时间处理:格式化为日期+时间范围,如 "2025-12-01 08:00-12:00"
|
|
||||||
String currentDate = LocalDate.now().toString(); // 或者从schedule中获取具体日期
|
|
||||||
String timeRange = schedule.getStartTime() + "-" + schedule.getEndTime();
|
|
||||||
dto.setDateTime(currentDate + " " + timeRange);
|
|
||||||
LocalTime nowTime = LocalTime.now();
|
|
||||||
LocalTime endTime = schedule.getEndTime();
|
|
||||||
String stopReason1 = schedule.getStopReason();
|
|
||||||
if ("cancelled".equals(stopReason1)||(endTime != null && nowTime.isAfter(endTime))) {
|
|
||||||
dto.setStatus("已停诊");
|
|
||||||
}else if (Boolean.TRUE.equals(schedule.getIsStopped())) {
|
|
||||||
// 获取原因并处理可能的空值
|
|
||||||
String stopReason = schedule.getStopReason();
|
|
||||||
// 使用 .equals() 比较内容,并将常量放在前面防止空指针
|
|
||||||
if ("booked".equals(stopReason)) {
|
|
||||||
dto.setStatus("已预约");
|
|
||||||
// --- 新增:获取患者信息 ---
|
|
||||||
List<Order> Order = orderMapper.selectOrderBySlotId(Long.valueOf(schedule.getId()));
|
|
||||||
Order latestOrder=Order.get(0);
|
|
||||||
|
|
||||||
if (latestOrder != null) {
|
if (raw.getScheduleDate() != null && raw.getExpectTime() != null) {
|
||||||
dto.setPatientName(latestOrder.getPatientName());
|
dto.setDateTime(raw.getScheduleDate().toString() + " " + raw.getExpectTime().toString());
|
||||||
dto.setPatientId(String.valueOf(latestOrder.getPatientId()));
|
try {
|
||||||
dto.setPhone(latestOrder.getPhone());
|
String timeStr = raw.getAppointmentTime() != null ? raw.getAppointmentTime() : (raw.getScheduleDate().toString() + " " + raw.getExpectTime().toString());
|
||||||
|
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(timeStr.length() > 10 ? "yyyy-MM-dd HH:mm" : "yyyy-MM-dd");
|
||||||
|
java.util.Date date = sdf.parse(timeStr);
|
||||||
|
dto.setAppointmentDate(date);
|
||||||
|
dto.setAppointmentTime(date);
|
||||||
|
} catch (Exception e) {
|
||||||
|
dto.setAppointmentDate(new java.util.Date());
|
||||||
}
|
}
|
||||||
// -----------------------
|
}
|
||||||
} else if ("checked".equals(stopReason)) {
|
|
||||||
|
if (Boolean.TRUE.equals(raw.getIsStopped())) {
|
||||||
|
dto.setStatus("已停诊");
|
||||||
|
} else {
|
||||||
|
Integer slotStatus = raw.getSlotStatus();
|
||||||
|
if (slotStatus != null) {
|
||||||
|
if (SlotStatus.CHECKED_IN.equals(slotStatus)) {
|
||||||
dto.setStatus("已取号");
|
dto.setStatus("已取号");
|
||||||
|
} else if (SlotStatus.BOOKED.equals(slotStatus)) {
|
||||||
|
if (AppointmentOrderStatus.CHECKED_IN.equals(raw.getOrderStatus())) {
|
||||||
|
dto.setStatus("已取号");
|
||||||
|
} else if (AppointmentOrderStatus.RETURNED.equals(raw.getOrderStatus())) {
|
||||||
|
dto.setStatus("已退号");
|
||||||
} else {
|
} else {
|
||||||
// 兜底逻辑:如果 is_stopped 为 true 但没有匹配到原因
|
dto.setStatus("已预约");
|
||||||
dto.setStatus("不可预约");
|
}
|
||||||
|
} else if (SlotStatus.RETURNED.equals(slotStatus)) {
|
||||||
|
dto.setStatus("已退号");
|
||||||
|
} else if (SlotStatus.CANCELLED.equals(slotStatus)) {
|
||||||
|
dto.setStatus("已停诊");
|
||||||
|
} else if (SlotStatus.LOCKED.equals(slotStatus)) {
|
||||||
|
dto.setStatus("已锁定");
|
||||||
|
} else {
|
||||||
|
dto.setStatus("未预约");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// is_stopped 为 false 或 null 时
|
|
||||||
dto.setStatus("未预约");
|
dto.setStatus("未预约");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 费用处理 (挂号费 + 诊疗费)
|
|
||||||
int totalFee = schedule.getRegisterFee() + schedule.getDiagnosisFee();
|
|
||||||
dto.setFee(String.valueOf(totalFee));
|
|
||||||
|
|
||||||
// 日期处理:LocalDateTime 转 Date
|
|
||||||
if (schedule.getCreateTime() != null) {
|
|
||||||
// 1. 先转成 Instant
|
|
||||||
Instant instant = schedule.getCreateTime().toInstant();
|
|
||||||
// 2. 结合时区转成 ZonedDateTime
|
|
||||||
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
|
|
||||||
// 3. 再转回 Date (如果 DTO 需要的是 Date)
|
|
||||||
dto.setAppointmentDate(Date.from(zdt.toInstant()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tickets.add(dto);
|
tickets.add(dto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 封装分页响应结构
|
// 5. 按照前端组件需要的【真分页】格式进行包装,并返回
|
||||||
Map<String, Object> result = new HashMap<>();
|
java.util.Map<String, Object> result = new java.util.HashMap<>();
|
||||||
|
result.put("list", tickets);
|
||||||
|
result.put("total", rawPage.getTotal()); // 这个 total 就是底层用 COUNT(*) 算出来的真实总条数!
|
||||||
|
result.put("page", query.getPage());
|
||||||
|
result.put("limit", query.getLimit());
|
||||||
|
|
||||||
|
return R.ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一状态入参,避免前端状态值大小写/中文/数字差异导致 SQL 条件失效后回全量数据
|
||||||
|
*/
|
||||||
|
private void normalizeQueryStatus(com.openhis.appointmentmanage.dto.TicketQueryDTO query) {
|
||||||
|
String rawStatus = query.getStatus();
|
||||||
|
if (rawStatus == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String normalized = rawStatus.trim();
|
||||||
|
if (normalized.isEmpty()) {
|
||||||
|
query.setStatus(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String lower = normalized.toLowerCase(Locale.ROOT);
|
||||||
|
switch (lower) {
|
||||||
|
case "all":
|
||||||
|
case "全部":
|
||||||
|
query.setStatus("all");
|
||||||
|
break;
|
||||||
|
case "unbooked":
|
||||||
|
case "0":
|
||||||
|
case "未预约":
|
||||||
|
query.setStatus("unbooked");
|
||||||
|
break;
|
||||||
|
case "booked":
|
||||||
|
case "1":
|
||||||
|
case "已预约":
|
||||||
|
query.setStatus("booked");
|
||||||
|
break;
|
||||||
|
case "checked":
|
||||||
|
case "checkin":
|
||||||
|
case "checkedin":
|
||||||
|
case "2":
|
||||||
|
case "已取号":
|
||||||
|
query.setStatus("checked");
|
||||||
|
break;
|
||||||
|
case "cancelled":
|
||||||
|
case "canceled":
|
||||||
|
case "3":
|
||||||
|
case "已停诊":
|
||||||
|
case "已取消":
|
||||||
|
query.setStatus("cancelled");
|
||||||
|
break;
|
||||||
|
case "returned":
|
||||||
|
case "4":
|
||||||
|
case "5":
|
||||||
|
case "已退号":
|
||||||
|
query.setStatus("returned");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// 设置为 impossible 值,配合 mapper 的 otherwise 分支直接返回空
|
||||||
|
query.setStatus("__invalid__");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<?> listDoctorAvailability(com.openhis.appointmentmanage.dto.TicketQueryDTO query) {
|
||||||
|
if (query == null) {
|
||||||
|
query = new com.openhis.appointmentmanage.dto.TicketQueryDTO();
|
||||||
|
}
|
||||||
|
|
||||||
|
java.util.List<com.openhis.appointmentmanage.domain.DoctorAvailabilityDTO> rawList = scheduleSlotMapper
|
||||||
|
.selectDoctorAvailabilitySummary(query);
|
||||||
|
java.util.List<java.util.Map<String, Object>> doctors = new java.util.ArrayList<>();
|
||||||
|
if (rawList != null) {
|
||||||
|
for (com.openhis.appointmentmanage.domain.DoctorAvailabilityDTO item : rawList) {
|
||||||
|
java.util.Map<String, Object> row = new java.util.HashMap<>();
|
||||||
|
String doctorName = item.getDoctorName();
|
||||||
|
Long doctorId = item.getDoctorId();
|
||||||
|
row.put("id", doctorId != null ? String.valueOf(doctorId) : doctorName);
|
||||||
|
row.put("name", doctorName);
|
||||||
|
row.put("available", item.getAvailable() == null ? 0 : item.getAvailable());
|
||||||
|
row.put("type", item.getTicketType() == null ? "general" : item.getTicketType());
|
||||||
|
doctors.add(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return R.ok(doctors);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<?> listAllTickets() {
|
||||||
|
// 1. 调用最新的 Mapper,直接从数据库抽出我们半成品的 DTO(强类型!)
|
||||||
|
List<com.openhis.appointmentmanage.domain.TicketSlotDTO> rawDtos = scheduleSlotMapper.selectAllTicketSlots();
|
||||||
|
|
||||||
|
// 这是真正要发给前端展示的包裹外卖盒
|
||||||
|
List<TicketDto> tickets = new ArrayList<>();
|
||||||
|
|
||||||
|
if (rawDtos != null) {
|
||||||
|
for (com.openhis.appointmentmanage.domain.TicketSlotDTO raw : rawDtos) {
|
||||||
|
TicketDto dto = new TicketDto();
|
||||||
|
|
||||||
|
// --- 基础字段处理 ---
|
||||||
|
// 注意:这里已经变成了极其舒服的 .getSlotId() 方法调用,告别魔鬼字符串!
|
||||||
|
dto.setSlot_id(raw.getSlotId());
|
||||||
|
dto.setSeqNo(raw.getSeqNo());
|
||||||
|
dto.setBusNo(String.valueOf(raw.getSlotId())); // 暂时借用真实槽位ID做唯一流水号
|
||||||
|
dto.setDoctor(raw.getDoctor());
|
||||||
|
dto.setDepartment(raw.getDepartmentName());
|
||||||
|
dto.setFee(raw.getFee());
|
||||||
|
dto.setPatientName(raw.getPatientName());
|
||||||
|
dto.setPatientId(raw.getMedicalCard());
|
||||||
|
dto.setPhone(raw.getPhone());
|
||||||
|
|
||||||
|
// --- 号源类型处理 (普通/专家) ---
|
||||||
|
// 改用底层 adm_doctor_schedule 传来的标准数字字典:0=普通,1=专家
|
||||||
|
if (raw.getRegType() != null && raw.getRegType() == 1) {
|
||||||
|
dto.setTicketType("expert");
|
||||||
|
} else {
|
||||||
|
dto.setTicketType("general");
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- 就诊时间严谨拼接 ---
|
||||||
|
// 拼接出来给前端展示的,如 "2026-03-20 08:30"
|
||||||
|
if (raw.getScheduleDate() != null && raw.getExpectTime() != null) {
|
||||||
|
dto.setDateTime(raw.getScheduleDate().toString() + " " + raw.getExpectTime().toString());
|
||||||
|
try {
|
||||||
|
String timeStr = raw.getAppointmentTime() != null ? raw.getAppointmentTime() : (raw.getScheduleDate().toString() + " " + raw.getExpectTime().toString());
|
||||||
|
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(timeStr.length() > 10 ? "yyyy-MM-dd HH:mm" : "yyyy-MM-dd");
|
||||||
|
java.util.Date date = sdf.parse(timeStr);
|
||||||
|
dto.setAppointmentDate(date);
|
||||||
|
dto.setAppointmentTime(date);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("时间解析失败", e);
|
||||||
|
dto.setAppointmentDate(new java.util.Date());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- 核心逻辑:精准状态分类 ---
|
||||||
|
// 第一关:底层硬性停诊拦截
|
||||||
|
if (Boolean.TRUE.equals(raw.getIsStopped())) {
|
||||||
|
dto.setStatus("已停诊");
|
||||||
|
} else {
|
||||||
|
// 第二关:看独立的细分槽位状态 (0: 可用, 1: 已预约, 2: 已取消...)
|
||||||
|
Integer slotStatus = raw.getSlotStatus();
|
||||||
|
if (slotStatus != null) {
|
||||||
|
if (SlotStatus.CHECKED_IN.equals(slotStatus)) {
|
||||||
|
dto.setStatus("已取号");
|
||||||
|
} else if (SlotStatus.BOOKED.equals(slotStatus)) {
|
||||||
|
if (AppointmentOrderStatus.CHECKED_IN.equals(raw.getOrderStatus())) {
|
||||||
|
dto.setStatus("已取号");
|
||||||
|
} else if (AppointmentOrderStatus.RETURNED.equals(raw.getOrderStatus())) {
|
||||||
|
dto.setStatus("已退号");
|
||||||
|
} else {
|
||||||
|
dto.setStatus("已预约");
|
||||||
|
}
|
||||||
|
} else if (SlotStatus.RETURNED.equals(slotStatus)) {
|
||||||
|
dto.setStatus("已退号");
|
||||||
|
} else if (SlotStatus.CANCELLED.equals(slotStatus)) {
|
||||||
|
dto.setStatus("已停诊");
|
||||||
|
} else if (SlotStatus.LOCKED.equals(slotStatus)) {
|
||||||
|
dto.setStatus("已锁定");
|
||||||
|
} else {
|
||||||
|
dto.setStatus("未预约");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dto.setStatus("未预约");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tickets.add(dto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 封装分页响应结构并吐给前端
|
||||||
|
java.util.Map<String, Object> result = new java.util.HashMap<>();
|
||||||
result.put("list", tickets);
|
result.put("list", tickets);
|
||||||
result.put("total", tickets.size());
|
result.put("total", tickets.size());
|
||||||
result.put("page", 1);
|
result.put("page", 1);
|
||||||
result.put("limit", 20);
|
result.put("limit", 20);
|
||||||
|
|
||||||
return R.ok(result);
|
return R.ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,14 +455,11 @@ public class TicketAppServiceImpl implements ITicketAppService {
|
|||||||
if (patient != null) {
|
if (patient != null) {
|
||||||
Integer genderEnum = patient.getGenderEnum();
|
Integer genderEnum = patient.getGenderEnum();
|
||||||
if (genderEnum != null) {
|
if (genderEnum != null) {
|
||||||
switch (genderEnum) {
|
if (Integer.valueOf(1).equals(genderEnum)) {
|
||||||
case 1:
|
|
||||||
dto.setGender("男");
|
dto.setGender("男");
|
||||||
break;
|
} else if (Integer.valueOf(2).equals(genderEnum)) {
|
||||||
case 2:
|
|
||||||
dto.setGender("女");
|
dto.setGender("女");
|
||||||
break;
|
} else {
|
||||||
default:
|
|
||||||
dto.setGender("未知");
|
dto.setGender("未知");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
package com.openhis.web.appointmentmanage.controller;
|
package com.openhis.web.appointmentmanage.controller;
|
||||||
|
|
||||||
import com.core.common.core.domain.R;
|
import com.core.common.core.domain.R;
|
||||||
|
import com.openhis.appointmentmanage.domain.AppointmentConfig;
|
||||||
|
import com.openhis.web.appointmentmanage.appservice.IAppointmentConfigAppService;
|
||||||
import com.openhis.web.appointmentmanage.appservice.IDeptAppService;
|
import com.openhis.web.appointmentmanage.appservice.IDeptAppService;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
@@ -16,6 +15,9 @@ public class DeptController {
|
|||||||
@Resource
|
@Resource
|
||||||
private IDeptAppService deptAppService;
|
private IDeptAppService deptAppService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IAppointmentConfigAppService appointmentConfigAppService;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 获取科室列表
|
* 获取科室列表
|
||||||
*
|
*
|
||||||
@@ -38,4 +40,22 @@ public class DeptController {
|
|||||||
){
|
){
|
||||||
return R.ok(deptAppService.searchDept(pageNo,pageSize,orgName,deptName));
|
return R.ok(deptAppService.searchDept(pageNo,pageSize,orgName,deptName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 获取预约配置
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
@GetMapping("/config")
|
||||||
|
public R<?> getAppointmentConfig(){
|
||||||
|
return appointmentConfigAppService.getAppointmentConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 保存预约配置
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
@PostMapping("/config")
|
||||||
|
public R<?> saveAppointmentConfig(@RequestBody AppointmentConfig appointmentConfig){
|
||||||
|
return appointmentConfigAppService.saveAppointmentConfig(appointmentConfig);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,12 @@ package com.openhis.web.appointmentmanage.controller;
|
|||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.core.common.annotation.Anonymous;
|
import com.core.common.annotation.Anonymous;
|
||||||
import com.core.common.core.domain.R;
|
import com.core.common.core.domain.R;
|
||||||
|
import com.openhis.appointmentmanage.domain.AppointmentBookDTO;
|
||||||
|
import com.openhis.appointmentmanage.dto.TicketQueryDTO;
|
||||||
import com.openhis.web.appointmentmanage.appservice.ITicketAppService;
|
import com.openhis.web.appointmentmanage.appservice.ITicketAppService;
|
||||||
import com.openhis.web.appointmentmanage.dto.TicketDto;
|
import com.openhis.web.appointmentmanage.dto.TicketDto;
|
||||||
|
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
@@ -19,11 +23,35 @@ import java.util.Map;
|
|||||||
@RequestMapping("/appointment/ticket")
|
@RequestMapping("/appointment/ticket")
|
||||||
public class TicketController {
|
public class TicketController {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询门诊号源列表 (带多条件过滤)
|
||||||
|
*
|
||||||
|
* @param query 查询条件
|
||||||
|
* @return 分页号源列表
|
||||||
|
*/
|
||||||
|
@Anonymous
|
||||||
|
@PostMapping("/list")
|
||||||
|
public R<?> listTicket(@RequestBody @Validated TicketQueryDTO query) {
|
||||||
|
return ticketAppService.listTicket(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询医生余号汇总(基于号源池,不受分页影响)
|
||||||
|
*
|
||||||
|
* @param query 查询条件
|
||||||
|
* @return 医生余号列表
|
||||||
|
*/
|
||||||
|
@Anonymous
|
||||||
|
@PostMapping("/doctorSummary")
|
||||||
|
public R<?> listDoctorAvailability(@RequestBody @Validated TicketQueryDTO query) {
|
||||||
|
return ticketAppService.listDoctorAvailability(query);
|
||||||
|
}
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ITicketAppService ticketAppService;
|
private ITicketAppService ticketAppService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询所有号源(用于测试)
|
* 查询所有号源
|
||||||
*
|
*
|
||||||
* @return 所有号源列表
|
* @return 所有号源列表
|
||||||
*/
|
*/
|
||||||
@@ -36,44 +64,44 @@ public class TicketController {
|
|||||||
/**
|
/**
|
||||||
* 预约号源
|
* 预约号源
|
||||||
*
|
*
|
||||||
* @param params 预约参数
|
* @param dto 预约参数
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@PostMapping("/book")
|
@PostMapping("/book")
|
||||||
public R<?> bookTicket(@RequestBody Map<String, Object> params) {
|
public R<?> bookTicket(@RequestBody @Validated AppointmentBookDTO dto) {
|
||||||
return ticketAppService.bookTicket(params);
|
return ticketAppService.bookTicket(dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 取消预约
|
* 取消预约
|
||||||
*
|
*
|
||||||
* @param ticketId 号源ID
|
* @param slotId 槽位ID
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@PostMapping("/cancel")
|
@PostMapping("/cancel")
|
||||||
public R<?> cancelTicket(@RequestParam Long ticketId) {
|
public R<?> cancelTicket(@RequestParam Long slotId) {
|
||||||
return ticketAppService.cancelTicket(ticketId);
|
return ticketAppService.cancelTicket(slotId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 取号
|
* 取号
|
||||||
*
|
*
|
||||||
* @param ticketId 号源ID
|
* @param slotId 槽位ID
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@PostMapping("/checkin")
|
@PostMapping("/checkin")
|
||||||
public R<?> checkInTicket(@RequestParam Long ticketId) {
|
public R<?> checkInTicket(@RequestParam Long slotId) {
|
||||||
return ticketAppService.checkInTicket(ticketId);
|
return ticketAppService.checkInTicket(slotId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 停诊
|
* 停诊
|
||||||
*
|
*
|
||||||
* @param ticketId 号源ID
|
* @param slotId 槽位ID
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@PostMapping("/cancelConsultation")
|
@PostMapping("/cancelConsultation")
|
||||||
public R<?> cancelConsultation(@RequestParam Long ticketId) {
|
public R<?> cancelConsultation(@RequestParam Long slotId) {
|
||||||
return ticketAppService.cancelConsultation(ticketId);
|
return ticketAppService.cancelConsultation(slotId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,11 @@ public class TicketDto {
|
|||||||
@JsonSerialize(using = ToStringSerializer.class)
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
private Long slot_id;
|
private Long slot_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 号源序号(对应 adm_schedule_slot.seq_no)
|
||||||
|
*/
|
||||||
|
private Integer seqNo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 号源编码
|
* 号源编码
|
||||||
*/
|
*/
|
||||||
@@ -49,7 +54,7 @@ public class TicketDto {
|
|||||||
private String dateTime;
|
private String dateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态 (unbooked:未预约, booked:已预约, checked:已取号, cancelled:已取消, locked:已锁定)
|
* 状态
|
||||||
*/
|
*/
|
||||||
private String status;
|
private String status;
|
||||||
|
|
||||||
@@ -99,4 +104,15 @@ public class TicketDto {
|
|||||||
*/
|
*/
|
||||||
@JsonSerialize(using = ToStringSerializer.class)
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
private Long doctorId;
|
private Long doctorId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 真实患者ID(数据库主键,区别于 patientId 存的就诊卡号)
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long realPatientId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 身份证号
|
||||||
|
*/
|
||||||
|
private String idCard;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ public class OutpatientChargeAppServiceImpl implements IOutpatientChargeAppServi
|
|||||||
= outpatientChargeAppMapper.selectEncounterPatientPrescription(encounterId,
|
= outpatientChargeAppMapper.selectEncounterPatientPrescription(encounterId,
|
||||||
ChargeItemContext.ACTIVITY.getValue(), ChargeItemContext.MEDICATION.getValue(),
|
ChargeItemContext.ACTIVITY.getValue(), ChargeItemContext.MEDICATION.getValue(),
|
||||||
ChargeItemContext.DEVICE.getValue(), ChargeItemContext.REGISTER.getValue(),
|
ChargeItemContext.DEVICE.getValue(), ChargeItemContext.REGISTER.getValue(),
|
||||||
|
ChargeItemContext.WESTERN_MEDICINE.getValue(), ChargeItemContext.CHINESE_PATENT_MEDICINE.getValue(),
|
||||||
ChargeItemStatus.PLANNED.getValue(), ChargeItemStatus.BILLABLE.getValue(),
|
ChargeItemStatus.PLANNED.getValue(), ChargeItemStatus.BILLABLE.getValue(),
|
||||||
ChargeItemStatus.BILLED.getValue(), ChargeItemStatus.REFUNDING.getValue(),
|
ChargeItemStatus.BILLED.getValue(), ChargeItemStatus.REFUNDING.getValue(),
|
||||||
ChargeItemStatus.REFUNDED.getValue(), ChargeItemStatus.PART_REFUND.getValue(),
|
ChargeItemStatus.REFUNDED.getValue(), ChargeItemStatus.PART_REFUND.getValue(),
|
||||||
|
|||||||
@@ -73,10 +73,10 @@ public class OutpatientPricingAppServiceImpl implements IOutpatientPricingAppSer
|
|||||||
} else {
|
} else {
|
||||||
adviceTypes = List.of(1, 2, 3);
|
adviceTypes = List.of(1, 2, 3);
|
||||||
}
|
}
|
||||||
// 门诊划价:不要强制 pricingFlag=1 参与过滤(wor_activity_definition.pricing_flag 可能为 0),
|
String categoryCode = adviceBaseDto != null ? adviceBaseDto.getCategoryCode() : null;
|
||||||
// 否则会导致诊疗项目(adviceType=3)查询结果为空 records=[]
|
// 门诊划价:仅返回划价标记为“是”的项目
|
||||||
return iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, searchKey, locationId, null,
|
return iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, searchKey, locationId, null,
|
||||||
organizationId, pageNo, pageSize, null, adviceTypes, null);
|
organizationId, pageNo, pageSize, Whether.YES.getValue(), adviceTypes, null, categoryCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,10 @@ import com.openhis.common.enums.ybenums.YbPayment;
|
|||||||
import com.openhis.common.utils.EnumUtils;
|
import com.openhis.common.utils.EnumUtils;
|
||||||
import com.openhis.common.utils.HisPageUtils;
|
import com.openhis.common.utils.HisPageUtils;
|
||||||
import com.openhis.common.utils.HisQueryUtils;
|
import com.openhis.common.utils.HisQueryUtils;
|
||||||
|
import com.openhis.appointmentmanage.mapper.SchedulePoolMapper;
|
||||||
|
import com.openhis.appointmentmanage.mapper.ScheduleSlotMapper;
|
||||||
|
import com.openhis.clinical.domain.Order;
|
||||||
|
import com.openhis.clinical.service.IOrderService;
|
||||||
import com.openhis.financial.domain.PaymentReconciliation;
|
import com.openhis.financial.domain.PaymentReconciliation;
|
||||||
import com.openhis.financial.domain.RefundLog;
|
import com.openhis.financial.domain.RefundLog;
|
||||||
import com.openhis.financial.service.IRefundLogService;
|
import com.openhis.financial.service.IRefundLogService;
|
||||||
@@ -48,6 +52,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -97,6 +102,15 @@ public class OutpatientRegistrationAppServiceImpl implements IOutpatientRegistra
|
|||||||
@Resource
|
@Resource
|
||||||
IRefundLogService iRefundLogService;
|
IRefundLogService iRefundLogService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
IOrderService orderService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
ScheduleSlotMapper scheduleSlotMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
SchedulePoolMapper schedulePoolMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 门诊挂号 - 查询患者信息
|
* 门诊挂号 - 查询患者信息
|
||||||
*
|
*
|
||||||
@@ -291,6 +305,11 @@ public class OutpatientRegistrationAppServiceImpl implements IOutpatientRegistra
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果本次门诊挂号来自预约签到,同步把预约订单与号源槽位状态改为已退号
|
||||||
|
if (result != null && result.getCode() == 200) {
|
||||||
|
syncAppointmentReturnStatus(byId, cancelRegPaymentDto.getReason());
|
||||||
|
}
|
||||||
|
|
||||||
// 记录退号日志
|
// 记录退号日志
|
||||||
recordRefundLog(cancelRegPaymentDto, byId, result, paymentRecon);
|
recordRefundLog(cancelRegPaymentDto, byId, result, paymentRecon);
|
||||||
|
|
||||||
@@ -399,6 +418,74 @@ public class OutpatientRegistrationAppServiceImpl implements IOutpatientRegistra
|
|||||||
return R.ok("已取消挂号");
|
return R.ok("已取消挂号");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步预约号源状态为已退号。
|
||||||
|
* 说明:
|
||||||
|
* 1) 门诊退号主流程不依赖该步骤成功与否,因此此方法内部异常仅记录日志,不向上抛出。
|
||||||
|
* 2) 通过患者、科室、日期以及状态筛选最近一条预约订单,尽量避免误匹配。
|
||||||
|
*/
|
||||||
|
private void syncAppointmentReturnStatus(Encounter encounter, String reason) {
|
||||||
|
if (encounter == null || encounter.getPatientId() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<Order>()
|
||||||
|
.eq(Order::getPatientId, encounter.getPatientId())
|
||||||
|
.in(Order::getStatus, CommonConstants.AppointmentOrderStatus.BOOKED,
|
||||||
|
CommonConstants.AppointmentOrderStatus.CHECKED_IN)
|
||||||
|
.orderByDesc(Order::getUpdateTime)
|
||||||
|
.orderByDesc(Order::getCreateTime)
|
||||||
|
.last("LIMIT 1");
|
||||||
|
|
||||||
|
if (encounter.getOrganizationId() != null) {
|
||||||
|
queryWrapper.eq(Order::getDepartmentId, encounter.getOrganizationId());
|
||||||
|
}
|
||||||
|
if (encounter.getTenantId() != null) {
|
||||||
|
queryWrapper.eq(Order::getTenantId, encounter.getTenantId());
|
||||||
|
}
|
||||||
|
if (encounter.getCreateTime() != null) {
|
||||||
|
LocalDate encounterDate = encounter.getCreateTime().toInstant()
|
||||||
|
.atZone(ZoneId.systemDefault()).toLocalDate();
|
||||||
|
Date startOfDay = Date.from(encounterDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
||||||
|
Date nextDayStart = Date.from(encounterDate.plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant());
|
||||||
|
queryWrapper.ge(Order::getAppointmentDate, startOfDay)
|
||||||
|
.lt(Order::getAppointmentDate, nextDayStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
Order appointmentOrder = orderService.getOne(queryWrapper, false);
|
||||||
|
if (appointmentOrder == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Date now = new Date();
|
||||||
|
if (!CommonConstants.AppointmentOrderStatus.RETURNED.equals(appointmentOrder.getStatus())) {
|
||||||
|
Order updateOrder = new Order();
|
||||||
|
updateOrder.setId(appointmentOrder.getId());
|
||||||
|
updateOrder.setStatus(CommonConstants.AppointmentOrderStatus.RETURNED);
|
||||||
|
updateOrder.setCancelTime(now);
|
||||||
|
updateOrder.setCancelReason(
|
||||||
|
StringUtils.isNotEmpty(reason) ? reason : "门诊退号");
|
||||||
|
updateOrder.setUpdateTime(now);
|
||||||
|
orderService.updateById(updateOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
Long slotId = appointmentOrder.getSlotId();
|
||||||
|
if (slotId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int slotRows = scheduleSlotMapper.updateSlotStatus(slotId, CommonConstants.SlotStatus.RETURNED);
|
||||||
|
if (slotRows > 0) {
|
||||||
|
Long poolId = scheduleSlotMapper.selectPoolIdBySlotId(slotId);
|
||||||
|
if (poolId != null) {
|
||||||
|
schedulePoolMapper.refreshPoolStats(poolId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("同步预约号源已退号状态失败, encounterId={}", encounter.getId(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 补打挂号
|
* 补打挂号
|
||||||
* 补打挂号不需要修改数据库,只需要返回成功即可,前端已有所有需要的数据用于打印
|
* 补打挂号不需要修改数据库,只需要返回成功即可,前端已有所有需要的数据用于打印
|
||||||
|
|||||||
@@ -61,7 +61,12 @@ public class OutpatientPricingController {
|
|||||||
@RequestParam(value = "locationId", required = false) Long locationId,
|
@RequestParam(value = "locationId", required = false) Long locationId,
|
||||||
@RequestParam(value = "organizationId") Long organizationId,
|
@RequestParam(value = "organizationId") Long organizationId,
|
||||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
|
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||||
|
@RequestParam(value = "categoryCode", required = false) String categoryCode) {
|
||||||
|
// 将 categoryCode 设置到 adviceBaseDto 中
|
||||||
|
if (categoryCode != null && !categoryCode.isEmpty()) {
|
||||||
|
adviceBaseDto.setCategoryCode(categoryCode);
|
||||||
|
}
|
||||||
return R.ok(iOutpatientPricingAppService.getAdviceBaseInfo(adviceBaseDto, searchKey, locationId, organizationId,
|
return R.ok(iOutpatientPricingAppService.getAdviceBaseInfo(adviceBaseDto, searchKey, locationId, organizationId,
|
||||||
pageNo, pageSize));
|
pageNo, pageSize));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ public interface OutpatientChargeAppMapper {
|
|||||||
* @param medication 药品
|
* @param medication 药品
|
||||||
* @param device 耗材
|
* @param device 耗材
|
||||||
* @param register 挂号费
|
* @param register 挂号费
|
||||||
|
* @param westernMedicine 西药
|
||||||
|
* @param chinesePatentMedicine 中成药
|
||||||
* @param planned 收费状态:待收费
|
* @param planned 收费状态:待收费
|
||||||
* @param billable 收费状态:待结算
|
* @param billable 收费状态:待结算
|
||||||
* @param billed 收费状态:已结算
|
* @param billed 收费状态:已结算
|
||||||
@@ -53,7 +55,9 @@ public interface OutpatientChargeAppMapper {
|
|||||||
*/
|
*/
|
||||||
List<EncounterPatientPrescriptionDto> selectEncounterPatientPrescription(@Param("encounterId") Long encounterId,
|
List<EncounterPatientPrescriptionDto> selectEncounterPatientPrescription(@Param("encounterId") Long encounterId,
|
||||||
@Param("activity") Integer activity, @Param("medication") Integer medication, @Param("device") Integer device,
|
@Param("activity") Integer activity, @Param("medication") Integer medication, @Param("device") Integer device,
|
||||||
@Param("register") Integer register, @Param("planned") Integer planned, @Param("billable") Integer billable,
|
@Param("register") Integer register, @Param("westernMedicine") Integer westernMedicine,
|
||||||
|
@Param("chinesePatentMedicine") Integer chinesePatentMedicine,
|
||||||
|
@Param("planned") Integer planned, @Param("billable") Integer billable,
|
||||||
@Param("billed") Integer billed, @Param("refunding") Integer refunding, @Param("refunded") Integer refunded,
|
@Param("billed") Integer billed, @Param("refunding") Integer refunding, @Param("refunded") Integer refunded,
|
||||||
@Param("partRefund") Integer partRefund, @Param("worDeviceRequest") String worDeviceRequest);
|
@Param("partRefund") Integer partRefund, @Param("worDeviceRequest") String worDeviceRequest);
|
||||||
|
|
||||||
|
|||||||
@@ -24,5 +24,5 @@ public interface ICheckMethodAppService{
|
|||||||
|
|
||||||
R<?> searchCheckMethodList(Integer pageNo, Integer pageSize, String checkType, String name, String packageName);
|
R<?> searchCheckMethodList(Integer pageNo, Integer pageSize, String checkType, String name, String packageName);
|
||||||
|
|
||||||
R<?> exportCheckMethod(String checkType, String name, String packageName, HttpServletResponse response);
|
void exportCheckMethod(String checkType, String name, String packageName, HttpServletResponse response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,5 +16,5 @@ public interface ICheckPartAppService {
|
|||||||
|
|
||||||
R<?> searchCheckPartList(Integer pageNo, Integer pageSize, String checkType, String name, String packageName);
|
R<?> searchCheckPartList(Integer pageNo, Integer pageSize, String checkType, String name, String packageName);
|
||||||
|
|
||||||
R<?> exportCheckPart(String checkType, String name, String packageName, HttpServletResponse response);
|
void exportCheckPart(String checkType, String name, String packageName, HttpServletResponse response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ public class CheckMethodAppServiceImpl implements ICheckMethodAppService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public R<?> exportCheckMethod(String checkType, String name, String packageName, HttpServletResponse response) {
|
public void exportCheckMethod(String checkType, String name, String packageName, HttpServletResponse response) {
|
||||||
LambdaQueryWrapper<CheckMethod> wrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<CheckMethod> wrapper = new LambdaQueryWrapper<>();
|
||||||
if (checkType != null && ObjectUtil.isNotEmpty(checkType)) {
|
if (checkType != null && ObjectUtil.isNotEmpty(checkType)) {
|
||||||
wrapper.eq(CheckMethod::getCheckType, checkType);
|
wrapper.eq(CheckMethod::getCheckType, checkType);
|
||||||
@@ -103,7 +103,13 @@ public class CheckMethodAppServiceImpl implements ICheckMethodAppService {
|
|||||||
List<CheckMethod> list = checkMethodService.list(wrapper);
|
List<CheckMethod> list = checkMethodService.list(wrapper);
|
||||||
|
|
||||||
if (list.isEmpty()) {
|
if (list.isEmpty()) {
|
||||||
return R.fail("导出Excel失败,无数据。");
|
try {
|
||||||
|
response.setContentType("application/json;charset=UTF-8");
|
||||||
|
response.getWriter().write("{\"code\":500,\"msg\":\"导出Excel失败,无数据。\"}");
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("写入响应失败", e);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -123,9 +129,12 @@ public class CheckMethodAppServiceImpl implements ICheckMethodAppService {
|
|||||||
ExcelFillerUtil.makeExcelFile(response, list, headers, excelName, null);
|
ExcelFillerUtil.makeExcelFile(response, list, headers, excelName, null);
|
||||||
} catch (IOException | IllegalAccessException e) {
|
} catch (IOException | IllegalAccessException e) {
|
||||||
log.error("导出Excel失败", e);
|
log.error("导出Excel失败", e);
|
||||||
return R.fail("导出Excel失败:" + e.getMessage());
|
try {
|
||||||
|
response.setContentType("application/json;charset=UTF-8");
|
||||||
|
response.getWriter().write("{\"code\":500,\"msg\":\"导出Excel失败:" + e.getMessage() + "\"}");
|
||||||
|
} catch (IOException ex) {
|
||||||
|
log.error("写入响应失败", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return R.ok(null, "导出Excel成功");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import java.util.List;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查套餐AppService实现
|
* 检查套餐 AppService 实现
|
||||||
*
|
*
|
||||||
* @author system
|
* @author system
|
||||||
* @date 2025-11-26
|
* @date 2025-11-26
|
||||||
@@ -35,6 +35,32 @@ public class CheckPackageAppServiceImpl implements ICheckPackageAppService {
|
|||||||
private final ICheckPackageService checkPackageService;
|
private final ICheckPackageService checkPackageService;
|
||||||
private final ICheckPackageDetailService checkPackageDetailService;
|
private final ICheckPackageDetailService checkPackageDetailService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换明细 DTO 列表为实体列表
|
||||||
|
* @param detailDtos 明细 DTO 列表
|
||||||
|
* @param packageId 套餐 ID
|
||||||
|
* @param orderNumStart 起始序号
|
||||||
|
* @return 明细实体列表
|
||||||
|
*/
|
||||||
|
private List<CheckPackageDetail> convertToDetails(List<CheckPackageDetailDto> detailDtos, Long packageId, int orderNumStart) {
|
||||||
|
if (detailDtos == null || detailDtos.isEmpty()) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<CheckPackageDetail> details = new ArrayList<>();
|
||||||
|
int orderNum = orderNumStart;
|
||||||
|
for (CheckPackageDetailDto detailDto : detailDtos) {
|
||||||
|
CheckPackageDetail detail = new CheckPackageDetail();
|
||||||
|
BeanUtils.copyProperties(detailDto, detail);
|
||||||
|
detail.setPackageId(packageId);
|
||||||
|
detail.setOrderNum(orderNum++);
|
||||||
|
detail.setCreateTime(LocalDateTime.now());
|
||||||
|
detail.setUpdateTime(LocalDateTime.now());
|
||||||
|
details.add(detail);
|
||||||
|
}
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public R<?> getCheckPackageList() {
|
public R<?> getCheckPackageList() {
|
||||||
try {
|
try {
|
||||||
@@ -61,7 +87,7 @@ public class CheckPackageAppServiceImpl implements ICheckPackageAppService {
|
|||||||
.orderByAsc(CheckPackageDetail::getOrderNum)
|
.orderByAsc(CheckPackageDetail::getOrderNum)
|
||||||
);
|
);
|
||||||
|
|
||||||
// 转换为DTO
|
// 转换为 DTO
|
||||||
CheckPackageDto dto = new CheckPackageDto();
|
CheckPackageDto dto = new CheckPackageDto();
|
||||||
BeanUtils.copyProperties(checkPackage, dto);
|
BeanUtils.copyProperties(checkPackage, dto);
|
||||||
|
|
||||||
@@ -101,28 +127,21 @@ public class CheckPackageAppServiceImpl implements ICheckPackageAppService {
|
|||||||
|
|
||||||
// 保存套餐明细
|
// 保存套餐明细
|
||||||
if (checkPackageDto.getItems() != null && !checkPackageDto.getItems().isEmpty()) {
|
if (checkPackageDto.getItems() != null && !checkPackageDto.getItems().isEmpty()) {
|
||||||
List<CheckPackageDetail> details = new ArrayList<>();
|
List<CheckPackageDetail> details = convertToDetails(checkPackageDto.getItems(), checkPackage.getId(), 1);
|
||||||
int orderNum = 1;
|
boolean detailSaveResult = checkPackageDetailService.saveBatch(details);
|
||||||
for (CheckPackageDetailDto detailDto : checkPackageDto.getItems()) {
|
if (!detailSaveResult) {
|
||||||
CheckPackageDetail detail = new CheckPackageDetail();
|
throw new RuntimeException("保存套餐明细失败");
|
||||||
BeanUtils.copyProperties(detailDto, detail);
|
|
||||||
detail.setPackageId(checkPackage.getId());
|
|
||||||
detail.setOrderNum(orderNum++);
|
|
||||||
detail.setCreateTime(LocalDateTime.now());
|
|
||||||
detail.setUpdateTime(LocalDateTime.now());
|
|
||||||
details.add(detail);
|
|
||||||
}
|
}
|
||||||
checkPackageDetailService.saveBatch(details);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return R.ok(checkPackage.getId(), "保存成功");
|
return R.ok(checkPackage.getId(), "保存成功");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("新增检查套餐失败", e);
|
log.error("新增检查套餐失败", e);
|
||||||
|
|
||||||
// 捕获PostgreSQL唯一约束冲突异常
|
// 捕获 PostgreSQL 唯一约束冲突异常
|
||||||
String errorMessage = e.getMessage();
|
String errorMessage = e.getMessage();
|
||||||
if (errorMessage != null) {
|
if (errorMessage != null) {
|
||||||
// PostgreSQL唯一约束错误通常包含 "duplicate key value" 或约束名称
|
// PostgreSQL 唯一约束错误通常包含 "duplicate key value" 或约束名称
|
||||||
if (errorMessage.contains("duplicate key value") ||
|
if (errorMessage.contains("duplicate key value") ||
|
||||||
errorMessage.contains("违反唯一约束") ||
|
errorMessage.contains("违反唯一约束") ||
|
||||||
errorMessage.contains("unique constraint")) {
|
errorMessage.contains("unique constraint")) {
|
||||||
@@ -135,7 +154,7 @@ public class CheckPackageAppServiceImpl implements ICheckPackageAppService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return R.fail("新增检查套餐失败: " + errorMessage);
|
return R.fail("新增检查套餐失败:" + errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,24 +189,14 @@ public class CheckPackageAppServiceImpl implements ICheckPackageAppService {
|
|||||||
|
|
||||||
// 保存新的套餐明细
|
// 保存新的套餐明细
|
||||||
if (checkPackageDto.getItems() != null && !checkPackageDto.getItems().isEmpty()) {
|
if (checkPackageDto.getItems() != null && !checkPackageDto.getItems().isEmpty()) {
|
||||||
List<CheckPackageDetail> details = new ArrayList<>();
|
List<CheckPackageDetail> details = convertToDetails(checkPackageDto.getItems(), checkPackage.getId(), 1);
|
||||||
int orderNum = 1;
|
|
||||||
for (CheckPackageDetailDto detailDto : checkPackageDto.getItems()) {
|
|
||||||
CheckPackageDetail detail = new CheckPackageDetail();
|
|
||||||
BeanUtils.copyProperties(detailDto, detail);
|
|
||||||
detail.setPackageId(checkPackage.getId());
|
|
||||||
detail.setOrderNum(orderNum++);
|
|
||||||
detail.setCreateTime(LocalDateTime.now());
|
|
||||||
detail.setUpdateTime(LocalDateTime.now());
|
|
||||||
details.add(detail);
|
|
||||||
}
|
|
||||||
checkPackageDetailService.saveBatch(details);
|
checkPackageDetailService.saveBatch(details);
|
||||||
}
|
}
|
||||||
|
|
||||||
return R.ok("更新成功");
|
return R.ok("更新成功");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("更新检查套餐失败", e);
|
log.error("更新检查套餐失败", e);
|
||||||
return R.fail("更新检查套餐失败: " + e.getMessage());
|
return R.fail("更新检查套餐失败:" + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,11 +210,14 @@ public class CheckPackageAppServiceImpl implements ICheckPackageAppService {
|
|||||||
return R.fail("套餐不存在");
|
return R.fail("套餐不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除套餐明细
|
// 删除套餐明细 - 先删除子表数据
|
||||||
checkPackageDetailService.remove(
|
boolean removeDetailsResult = checkPackageDetailService.remove(
|
||||||
new LambdaQueryWrapper<CheckPackageDetail>()
|
new LambdaQueryWrapper<CheckPackageDetail>()
|
||||||
.eq(CheckPackageDetail::getPackageId, id)
|
.eq(CheckPackageDetail::getPackageId, id)
|
||||||
);
|
);
|
||||||
|
if (!removeDetailsResult) {
|
||||||
|
log.warn("删除套餐明细失败,套餐 ID: {}", id);
|
||||||
|
}
|
||||||
|
|
||||||
// 删除套餐主表
|
// 删除套餐主表
|
||||||
boolean deleteResult = checkPackageService.removeById(id);
|
boolean deleteResult = checkPackageService.removeById(id);
|
||||||
@@ -213,11 +225,11 @@ public class CheckPackageAppServiceImpl implements ICheckPackageAppService {
|
|||||||
return R.fail("删除套餐失败");
|
return R.fail("删除套餐失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.info("删除检查套餐成功,套餐 ID: {}", id);
|
||||||
return R.ok("删除成功");
|
return R.ok("删除成功");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("删除检查套餐失败", e);
|
log.error("删除检查套餐失败", e);
|
||||||
return R.fail("删除检查套餐失败: " + e.getMessage());
|
return R.fail("删除检查套餐失败:" + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public class CheckPartAppServiceImpl implements ICheckPartAppService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public R<?> exportCheckPart(String checkType, String name, String packageName, HttpServletResponse response) {
|
public void exportCheckPart(String checkType, String name, String packageName, HttpServletResponse response) {
|
||||||
LambdaQueryWrapper<CheckPart> wrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<CheckPart> wrapper = new LambdaQueryWrapper<>();
|
||||||
if (checkType != null && ObjectUtil.isNotEmpty(checkType)) {
|
if (checkType != null && ObjectUtil.isNotEmpty(checkType)) {
|
||||||
wrapper.eq(CheckPart::getCheckType, checkType);
|
wrapper.eq(CheckPart::getCheckType, checkType);
|
||||||
@@ -79,7 +79,13 @@ public class CheckPartAppServiceImpl implements ICheckPartAppService {
|
|||||||
List<CheckPart> list = checkPartService.list(wrapper);
|
List<CheckPart> list = checkPartService.list(wrapper);
|
||||||
|
|
||||||
if (list.isEmpty()) {
|
if (list.isEmpty()) {
|
||||||
return R.fail("导出Excel失败,无数据。");
|
try {
|
||||||
|
response.setContentType("application/json;charset=UTF-8");
|
||||||
|
response.getWriter().write("{\"code\":500,\"msg\":\"导出Excel失败,无数据。\"}");
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("写入响应失败", e);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -102,8 +108,12 @@ public class CheckPartAppServiceImpl implements ICheckPartAppService {
|
|||||||
ExcelFillerUtil.makeExcelFile(response, list, headers, excelName, null);
|
ExcelFillerUtil.makeExcelFile(response, list, headers, excelName, null);
|
||||||
} catch (IOException | IllegalAccessException e) {
|
} catch (IOException | IllegalAccessException e) {
|
||||||
log.error("导出Excel失败", e);
|
log.error("导出Excel失败", e);
|
||||||
return R.fail("导出Excel失败:" + e.getMessage());
|
try {
|
||||||
|
response.setContentType("application/json;charset=UTF-8");
|
||||||
|
response.getWriter().write("{\"code\":500,\"msg\":\"导出Excel失败:" + e.getMessage() + "\"}");
|
||||||
|
} catch (IOException ex) {
|
||||||
|
log.error("写入响应失败", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return R.ok(null, "导出Excel成功");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ public class CheckPackageDetailDto {
|
|||||||
@NotNull(message = "数量不能为空")
|
@NotNull(message = "数量不能为空")
|
||||||
private Integer quantity;
|
private Integer quantity;
|
||||||
|
|
||||||
|
/** 单位 */
|
||||||
|
private String unit;
|
||||||
|
|
||||||
/** 单价 */
|
/** 单价 */
|
||||||
@NotNull(message = "单价不能为空")
|
@NotNull(message = "单价不能为空")
|
||||||
private BigDecimal unitPrice;
|
private BigDecimal unitPrice;
|
||||||
|
|||||||
@@ -343,11 +343,28 @@ public class SurgeryAppServiceImpl implements ISurgeryAppService {
|
|||||||
serviceRequest.setEncounterId(surgeryDto.getEncounterId()); // 就诊id
|
serviceRequest.setEncounterId(surgeryDto.getEncounterId()); // 就诊id
|
||||||
serviceRequest.setAuthoredTime(curDate); // 请求签发时间
|
serviceRequest.setAuthoredTime(curDate); // 请求签发时间
|
||||||
serviceRequest.setOrgId(orgId); // 执行科室
|
serviceRequest.setOrgId(orgId); // 执行科室
|
||||||
|
// 🔧 BugFix#318: 设置 contentJson,包含手术名称
|
||||||
|
Map<String, String> serviceContentMap = new HashMap<>();
|
||||||
|
String surgeryNameFromDto = surgeryDto.getSurgeryName();
|
||||||
|
String surgeryCodeFromDto = surgeryDto.getSurgeryCode();
|
||||||
|
log.info("【DEBUG】surgeryName from DTO: {}", surgeryNameFromDto);
|
||||||
|
log.info("【DEBUG】surgeryCode from DTO: {}", surgeryCodeFromDto);
|
||||||
|
serviceContentMap.put("surgeryName", surgeryNameFromDto != null ? surgeryNameFromDto : "");
|
||||||
|
serviceContentMap.put("surgeryCode", surgeryCodeFromDto != null ? surgeryCodeFromDto : "");
|
||||||
|
try {
|
||||||
|
String contentJson = new ObjectMapper().writeValueAsString(serviceContentMap);
|
||||||
|
log.info("【DEBUG】Setting contentJson: {}", contentJson);
|
||||||
|
serviceRequest.setContentJson(contentJson);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
log.error("【DEBUG】设置手术医嘱 contentJson 失败", e);
|
||||||
|
}
|
||||||
serviceRequestService.save(serviceRequest);
|
serviceRequestService.save(serviceRequest);
|
||||||
|
log.info("【DEBUG】Saved serviceRequest with ID: {}, contentJson: {}",
|
||||||
|
serviceRequest.getId(), serviceRequest.getContentJson());
|
||||||
|
|
||||||
// 生成收费项目
|
// 生成收费项目
|
||||||
ChargeItem chargeItem = new ChargeItem();
|
ChargeItem chargeItem = new ChargeItem();
|
||||||
chargeItem.setStatusEnum(ChargeItemStatus.DRAFT.getValue()); // 收费状态
|
chargeItem.setStatusEnum(ChargeItemStatus.PLANNED.getValue()); // 收费状态:待收费
|
||||||
chargeItem.setBusNo("CI" + serviceRequest.getBusNo());
|
chargeItem.setBusNo("CI" + serviceRequest.getBusNo());
|
||||||
chargeItem.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue()); // 生成来源
|
chargeItem.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue()); // 生成来源
|
||||||
chargeItem.setPatientId(surgeryDto.getPatientId()); // 患者
|
chargeItem.setPatientId(surgeryDto.getPatientId()); // 患者
|
||||||
@@ -541,15 +558,33 @@ public class SurgeryAppServiceImpl implements ISurgeryAppService {
|
|||||||
// 收集所有需要查询的ID
|
// 收集所有需要查询的ID
|
||||||
Set<Long> practitionerIds = new HashSet<>();
|
Set<Long> practitionerIds = new HashSet<>();
|
||||||
Set<Long> orgIds = new HashSet<>();
|
Set<Long> orgIds = new HashSet<>();
|
||||||
Set<Long> otherIds = new HashSet<>();
|
Set<Long> userIds = new HashSet<>(); // 用于查询sys_user表
|
||||||
|
|
||||||
// 收集Practitioner IDs
|
// 收集Practitioner IDs (医生相关)
|
||||||
if (surgery.getMainSurgeonId() != null) practitionerIds.add(surgery.getMainSurgeonId());
|
if (surgery.getMainSurgeonId() != null) {
|
||||||
if (surgery.getAnesthetistId() != null) practitionerIds.add(surgery.getAnesthetistId());
|
practitionerIds.add(surgery.getMainSurgeonId());
|
||||||
if (surgery.getAssistant1Id() != null) practitionerIds.add(surgery.getAssistant1Id());
|
userIds.add(surgery.getMainSurgeonId());
|
||||||
if (surgery.getAssistant2Id() != null) practitionerIds.add(surgery.getAssistant2Id());
|
}
|
||||||
if (surgery.getScrubNurseId() != null) practitionerIds.add(surgery.getScrubNurseId());
|
if (surgery.getAnesthetistId() != null) {
|
||||||
if (surgery.getApplyDoctorId() != null) practitionerIds.add(surgery.getApplyDoctorId());
|
practitionerIds.add(surgery.getAnesthetistId());
|
||||||
|
userIds.add(surgery.getAnesthetistId());
|
||||||
|
}
|
||||||
|
if (surgery.getAssistant1Id() != null) {
|
||||||
|
practitionerIds.add(surgery.getAssistant1Id());
|
||||||
|
userIds.add(surgery.getAssistant1Id());
|
||||||
|
}
|
||||||
|
if (surgery.getAssistant2Id() != null) {
|
||||||
|
practitionerIds.add(surgery.getAssistant2Id());
|
||||||
|
userIds.add(surgery.getAssistant2Id());
|
||||||
|
}
|
||||||
|
if (surgery.getScrubNurseId() != null) {
|
||||||
|
practitionerIds.add(surgery.getScrubNurseId());
|
||||||
|
userIds.add(surgery.getScrubNurseId());
|
||||||
|
}
|
||||||
|
if (surgery.getApplyDoctorId() != null) {
|
||||||
|
practitionerIds.add(surgery.getApplyDoctorId());
|
||||||
|
userIds.add(surgery.getApplyDoctorId());
|
||||||
|
}
|
||||||
|
|
||||||
// 收集Organization IDs
|
// 收集Organization IDs
|
||||||
if (surgery.getOrgId() != null) orgIds.add(surgery.getOrgId());
|
if (surgery.getOrgId() != null) orgIds.add(surgery.getOrgId());
|
||||||
@@ -558,69 +593,151 @@ public class SurgeryAppServiceImpl implements ISurgeryAppService {
|
|||||||
// 批量查询并缓存结果
|
// 批量查询并缓存结果
|
||||||
Map<Long, String> practitionerNameMap = new HashMap<>();
|
Map<Long, String> practitionerNameMap = new HashMap<>();
|
||||||
Map<Long, String> orgNameMap = new HashMap<>();
|
Map<Long, String> orgNameMap = new HashMap<>();
|
||||||
|
Map<Long, String> userNameMap = new HashMap<>(); // 从sys_user查询的名称
|
||||||
|
|
||||||
// 批量查询Practitioner
|
// 批量查询Practitioner
|
||||||
if (!practitionerIds.isEmpty()) {
|
if (!practitionerIds.isEmpty()) {
|
||||||
|
try {
|
||||||
List<com.openhis.administration.domain.Practitioner> practitioners = practitionerService.listByIds(practitionerIds);
|
List<com.openhis.administration.domain.Practitioner> practitioners = practitionerService.listByIds(practitionerIds);
|
||||||
for (com.openhis.administration.domain.Practitioner p : practitioners) {
|
for (com.openhis.administration.domain.Practitioner p : practitioners) {
|
||||||
|
if (p.getName() != null && !p.getName().isEmpty()) {
|
||||||
practitionerNameMap.put(p.getId(), p.getName());
|
practitionerNameMap.put(p.getId(), p.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("查询Practitioner名称失败: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量查询SysUser (作为备选) - 使用逐个查询
|
||||||
|
if (!userIds.isEmpty()) {
|
||||||
|
try {
|
||||||
|
for (Long userId : userIds) {
|
||||||
|
SysUser u = sysUserService.selectUserById(userId);
|
||||||
|
if (u != null) {
|
||||||
|
String userName = u.getNickName() != null && !u.getNickName().isEmpty()
|
||||||
|
? u.getNickName()
|
||||||
|
: u.getUserName();
|
||||||
|
if (userName != null && !userName.isEmpty()) {
|
||||||
|
userNameMap.put(u.getUserId(), userName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("查询SysUser名称失败: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 批量查询Organization
|
// 批量查询Organization
|
||||||
if (!orgIds.isEmpty()) {
|
if (!orgIds.isEmpty()) {
|
||||||
|
try {
|
||||||
List<Organization> orgs = organizationService.listByIds(orgIds);
|
List<Organization> orgs = organizationService.listByIds(orgIds);
|
||||||
for (Organization o : orgs) {
|
for (Organization o : orgs) {
|
||||||
|
if (o.getName() != null && !o.getName().isEmpty()) {
|
||||||
orgNameMap.put(o.getId(), o.getName());
|
orgNameMap.put(o.getId(), o.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("查询Organization名称失败: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 填充患者姓名
|
// 填充患者姓名
|
||||||
if (surgery.getPatientId() != null && surgery.getPatientName() == null) {
|
if (surgery.getPatientId() != null && surgery.getPatientName() == null) {
|
||||||
|
try {
|
||||||
Patient patient = patientService.getById(surgery.getPatientId());
|
Patient patient = patientService.getById(surgery.getPatientId());
|
||||||
if (patient != null) {
|
if (patient != null) {
|
||||||
surgery.setPatientName(patient.getName());
|
surgery.setPatientName(patient.getName());
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("查询患者名称失败: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用缓存填充名称
|
// 填充医生名称 - 优先使用practitioner,如果不存在则使用sys_user
|
||||||
if (surgery.getMainSurgeonId() != null && surgery.getMainSurgeonName() == null) {
|
if (surgery.getMainSurgeonId() != null && surgery.getMainSurgeonName() == null) {
|
||||||
surgery.setMainSurgeonName(practitionerNameMap.get(surgery.getMainSurgeonId()));
|
String name = practitionerNameMap.get(surgery.getMainSurgeonId());
|
||||||
|
if (name == null || name.isEmpty()) {
|
||||||
|
name = userNameMap.get(surgery.getMainSurgeonId());
|
||||||
|
}
|
||||||
|
if (name != null && !name.isEmpty()) {
|
||||||
|
surgery.setMainSurgeonName(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (surgery.getAnesthetistId() != null && surgery.getAnesthetistName() == null) {
|
if (surgery.getAnesthetistId() != null && surgery.getAnesthetistName() == null) {
|
||||||
surgery.setAnesthetistName(practitionerNameMap.get(surgery.getAnesthetistId()));
|
String name = practitionerNameMap.get(surgery.getAnesthetistId());
|
||||||
|
if (name == null || name.isEmpty()) {
|
||||||
|
name = userNameMap.get(surgery.getAnesthetistId());
|
||||||
|
}
|
||||||
|
if (name != null && !name.isEmpty()) {
|
||||||
|
surgery.setAnesthetistName(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (surgery.getAssistant1Id() != null && surgery.getAssistant1Name() == null) {
|
if (surgery.getAssistant1Id() != null && surgery.getAssistant1Name() == null) {
|
||||||
surgery.setAssistant1Name(practitionerNameMap.get(surgery.getAssistant1Id()));
|
String name = practitionerNameMap.get(surgery.getAssistant1Id());
|
||||||
|
if (name == null || name.isEmpty()) {
|
||||||
|
name = userNameMap.get(surgery.getAssistant1Id());
|
||||||
|
}
|
||||||
|
if (name != null && !name.isEmpty()) {
|
||||||
|
surgery.setAssistant1Name(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (surgery.getAssistant2Id() != null && surgery.getAssistant2Name() == null) {
|
if (surgery.getAssistant2Id() != null && surgery.getAssistant2Name() == null) {
|
||||||
surgery.setAssistant2Name(practitionerNameMap.get(surgery.getAssistant2Id()));
|
String name = practitionerNameMap.get(surgery.getAssistant2Id());
|
||||||
|
if (name == null || name.isEmpty()) {
|
||||||
|
name = userNameMap.get(surgery.getAssistant2Id());
|
||||||
|
}
|
||||||
|
if (name != null && !name.isEmpty()) {
|
||||||
|
surgery.setAssistant2Name(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (surgery.getScrubNurseId() != null && surgery.getScrubNurseName() == null) {
|
if (surgery.getScrubNurseId() != null && surgery.getScrubNurseName() == null) {
|
||||||
surgery.setScrubNurseName(practitionerNameMap.get(surgery.getScrubNurseId()));
|
String name = practitionerNameMap.get(surgery.getScrubNurseId());
|
||||||
|
if (name == null || name.isEmpty()) {
|
||||||
|
name = userNameMap.get(surgery.getScrubNurseId());
|
||||||
|
}
|
||||||
|
if (name != null && !name.isEmpty()) {
|
||||||
|
surgery.setScrubNurseName(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (surgery.getApplyDoctorId() != null && surgery.getApplyDoctorName() == null) {
|
if (surgery.getApplyDoctorId() != null && surgery.getApplyDoctorName() == null) {
|
||||||
surgery.setApplyDoctorName(practitionerNameMap.get(surgery.getApplyDoctorId()));
|
String name = practitionerNameMap.get(surgery.getApplyDoctorId());
|
||||||
|
if (name == null || name.isEmpty()) {
|
||||||
|
name = userNameMap.get(surgery.getApplyDoctorId());
|
||||||
|
}
|
||||||
|
if (name != null && !name.isEmpty()) {
|
||||||
|
surgery.setApplyDoctorName(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 填充手术室名称
|
// 填充手术室名称
|
||||||
if (surgery.getOperatingRoomId() != null && surgery.getOperatingRoomName() == null) {
|
if (surgery.getOperatingRoomId() != null && surgery.getOperatingRoomName() == null) {
|
||||||
|
try {
|
||||||
OperatingRoom operatingRoom = operatingRoomService.getById(surgery.getOperatingRoomId());
|
OperatingRoom operatingRoom = operatingRoomService.getById(surgery.getOperatingRoomId());
|
||||||
if (operatingRoom != null) {
|
if (operatingRoom != null) {
|
||||||
surgery.setOperatingRoomName(operatingRoom.getName());
|
surgery.setOperatingRoomName(operatingRoom.getName());
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("查询手术室名称失败: {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用缓存填充组织名称
|
// 使用缓存填充组织名称
|
||||||
if (surgery.getOrgId() != null && surgery.getOrgName() == null) {
|
if (surgery.getOrgId() != null && surgery.getOrgName() == null) {
|
||||||
surgery.setOrgName(orgNameMap.get(surgery.getOrgId()));
|
String name = orgNameMap.get(surgery.getOrgId());
|
||||||
|
if (name != null && !name.isEmpty()) {
|
||||||
|
surgery.setOrgName(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (surgery.getApplyDeptId() != null && surgery.getApplyDeptName() == null) {
|
if (surgery.getApplyDeptId() != null && surgery.getApplyDeptName() == null) {
|
||||||
surgery.setApplyDeptName(orgNameMap.get(surgery.getApplyDeptId()));
|
String name = orgNameMap.get(surgery.getApplyDeptId());
|
||||||
|
if (name != null && !name.isEmpty()) {
|
||||||
|
surgery.setApplyDeptName(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("填充手术名称字段完成 - patientName: {}, mainSurgeonName: {}, orgName: {}",
|
log.debug("填充手术名称字段完成 - patientName: {}, mainSurgeonName: {}, applyDeptName: {}",
|
||||||
surgery.getPatientName(), surgery.getMainSurgeonName(), surgery.getOrgName());
|
surgery.getPatientName(), surgery.getMainSurgeonName(), surgery.getApplyDeptName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
package com.openhis.web.clinicalmanage.appservice.impl;
|
package com.openhis.web.clinicalmanage.appservice.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.core.common.core.domain.R;
|
import com.core.common.core.domain.R;
|
||||||
import com.core.common.core.domain.model.LoginUser;
|
import com.core.common.core.domain.model.LoginUser;
|
||||||
import com.core.common.utils.SecurityUtils;
|
import com.core.common.utils.SecurityUtils;
|
||||||
import com.openhis.administration.domain.Patient;
|
import com.openhis.administration.domain.Patient;
|
||||||
|
import com.openhis.administration.service.IOrganizationService;
|
||||||
import com.openhis.administration.service.IPatientService;
|
import com.openhis.administration.service.IPatientService;
|
||||||
|
import com.openhis.clinical.domain.Surgery;
|
||||||
|
import com.openhis.clinical.service.ISurgeryService;
|
||||||
import com.openhis.surgicalschedule.domain.OpSchedule;
|
import com.openhis.surgicalschedule.domain.OpSchedule;
|
||||||
import com.openhis.surgicalschedule.service.IOpScheduleService;
|
import com.openhis.surgicalschedule.service.IOpScheduleService;
|
||||||
import com.openhis.web.clinicalmanage.appservice.ISurgicalScheduleAppService;
|
import com.openhis.web.clinicalmanage.appservice.ISurgicalScheduleAppService;
|
||||||
@@ -29,6 +33,8 @@ import java.time.LocalDateTime;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.core.framework.datasource.DynamicDataSourceContextHolder.log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 手术安排业务层实现类
|
* 手术安排业务层实现类
|
||||||
*
|
*
|
||||||
@@ -47,6 +53,15 @@ public class SurgicalScheduleAppServiceImpl implements ISurgicalScheduleAppServi
|
|||||||
@Resource
|
@Resource
|
||||||
private SurgicalScheduleAppMapper surgicalScheduleAppMapper;
|
private SurgicalScheduleAppMapper surgicalScheduleAppMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ISurgeryService surgeryService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private com.openhis.administration.service.IOrganizationService organizationService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private com.core.system.service.ISysUserService sysUserService;
|
||||||
|
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private RequestFormManageAppMapper requestFormManageAppMapper;
|
private RequestFormManageAppMapper requestFormManageAppMapper;
|
||||||
@@ -183,12 +198,34 @@ public class SurgicalScheduleAppServiceImpl implements ISurgicalScheduleAppServi
|
|||||||
|
|
||||||
// 保存手术安排
|
// 保存手术安排
|
||||||
boolean saved = opScheduleService.save(opSchedule);
|
boolean saved = opScheduleService.save(opSchedule);
|
||||||
//修改申请单状态为已排期
|
|
||||||
|
|
||||||
if (!saved) {
|
if (!saved) {
|
||||||
return R.fail("新增手术安排失败");
|
return R.fail("新增手术安排失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bug #247 修复:更新手术申请单状态为已排期 (1)
|
||||||
|
if (opCreateScheduleDto.getApplyId() != null) {
|
||||||
|
try {
|
||||||
|
// 通过手术单号查找手术申请记录并更新状态
|
||||||
|
LambdaQueryWrapper<com.openhis.clinical.domain.Surgery> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(com.openhis.clinical.domain.Surgery::getSurgeryNo, opSchedule.getOperCode())
|
||||||
|
.eq(com.openhis.clinical.domain.Surgery::getDeleteFlag, "0");
|
||||||
|
com.openhis.clinical.domain.Surgery surgery = surgeryService.getOne(queryWrapper);
|
||||||
|
if (surgery != null) {
|
||||||
|
surgery.setStatusEnum(1); // 1 = 已排期
|
||||||
|
surgery.setUpdateTime(new Date());
|
||||||
|
|
||||||
|
// 填充缺失的申请科室和主刀医生名称
|
||||||
|
fillSurgeryMissingNames(surgery);
|
||||||
|
|
||||||
|
surgeryService.updateById(surgery);
|
||||||
|
log.info("更新手术申请单状态为已排期 - surgeryNo: {}, surgeryId: {}", opSchedule.getOperCode(), surgery.getId());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("更新手术申请单状态失败 - operCode: {}", opSchedule.getOperCode(), e);
|
||||||
|
// 状态更新失败不影响主流程,只记录日志
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return R.ok("新增手术安排成功");
|
return R.ok("新增手术安排成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,7 +371,7 @@ public class SurgicalScheduleAppServiceImpl implements ISurgicalScheduleAppServi
|
|||||||
index, // 序号从1开始
|
index, // 序号从1开始
|
||||||
schedule.getOrgName() != null ? schedule.getOrgName() : "",
|
schedule.getOrgName() != null ? schedule.getOrgName() : "",
|
||||||
schedule.getPatientName() != null ? schedule.getPatientName() : "",
|
schedule.getPatientName() != null ? schedule.getPatientName() : "",
|
||||||
schedule.getVisitId() != null ? schedule.getVisitId().toString() : "",
|
schedule.getIdentifierNo() != null ? schedule.getIdentifierNo() : "",
|
||||||
schedule.getOperCode() != null ? schedule.getOperCode() : "",
|
schedule.getOperCode() != null ? schedule.getOperCode() : "",
|
||||||
schedule.getOperName() != null ? schedule.getOperName() : "",
|
schedule.getOperName() != null ? schedule.getOperName() : "",
|
||||||
schedule.getApplyDeptName() != null ? schedule.getApplyDeptName() : "",
|
schedule.getApplyDeptName() != null ? schedule.getApplyDeptName() : "",
|
||||||
@@ -387,10 +424,84 @@ public class SurgicalScheduleAppServiceImpl implements ISurgicalScheduleAppServi
|
|||||||
/**
|
/**
|
||||||
* 格式化安排时间
|
* 格式化安排时间
|
||||||
*/
|
*/
|
||||||
private String formatScheduleDate(LocalDate scheduleDate) {
|
private String formatScheduleDate(LocalDateTime scheduleDate) {
|
||||||
if (scheduleDate == null) return "";
|
if (scheduleDate == null) return "";
|
||||||
|
|
||||||
// 格式化为 yyyy-MM-dd
|
// 格式化为 yyyy-MM-dd HH:mm:ss
|
||||||
return scheduleDate.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
return scheduleDate.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 填充手术申请中缺失的名称字段
|
||||||
|
* 在创建手术安排时调用,确保关联的cli_surgery表中的名称字段有值
|
||||||
|
*
|
||||||
|
* @param surgery 手术申请对象
|
||||||
|
*/
|
||||||
|
private void fillSurgeryMissingNames(com.openhis.clinical.domain.Surgery surgery) {
|
||||||
|
// 填充申请科室名称
|
||||||
|
if ((surgery.getApplyDeptName() == null || surgery.getApplyDeptName().isEmpty())
|
||||||
|
&& surgery.getApplyDeptId() != null) {
|
||||||
|
try {
|
||||||
|
com.openhis.administration.domain.Organization org = organizationService.getById(surgery.getApplyDeptId());
|
||||||
|
if (org != null && org.getName() != null) {
|
||||||
|
surgery.setApplyDeptName(org.getName());
|
||||||
|
log.info("填充申请科室名称 - surgeryId: {}, deptId: {}, deptName: {}",
|
||||||
|
surgery.getId(), surgery.getApplyDeptId(), org.getName());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("查询申请科室名称失败 - deptId: {}, error: {}", surgery.getApplyDeptId(), e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 填充主刀医生名称
|
||||||
|
if ((surgery.getMainSurgeonName() == null || surgery.getMainSurgeonName().isEmpty())
|
||||||
|
&& surgery.getMainSurgeonId() != null) {
|
||||||
|
try {
|
||||||
|
com.core.common.core.domain.entity.SysUser user = sysUserService.selectUserById(surgery.getMainSurgeonId());
|
||||||
|
if (user != null) {
|
||||||
|
String surgeonName = user.getNickName() != null && !user.getNickName().isEmpty()
|
||||||
|
? user.getNickName()
|
||||||
|
: user.getUserName();
|
||||||
|
if (surgeonName != null) {
|
||||||
|
surgery.setMainSurgeonName(surgeonName);
|
||||||
|
log.info("填充主刀医生名称 - surgeryId: {}, surgeonId: {}, surgeonName: {}",
|
||||||
|
surgery.getId(), surgery.getMainSurgeonId(), surgeonName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("查询主刀医生名称失败 - surgeonId: {}, error: {}", surgery.getMainSurgeonId(), e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 填充麻醉医生名称
|
||||||
|
if ((surgery.getAnesthetistName() == null || surgery.getAnesthetistName().isEmpty())
|
||||||
|
&& surgery.getAnesthetistId() != null) {
|
||||||
|
try {
|
||||||
|
com.core.common.core.domain.entity.SysUser user = sysUserService.selectUserById(surgery.getAnesthetistId());
|
||||||
|
if (user != null) {
|
||||||
|
String anesthetistName = user.getNickName() != null && !user.getNickName().isEmpty()
|
||||||
|
? user.getNickName()
|
||||||
|
: user.getUserName();
|
||||||
|
if (anesthetistName != null) {
|
||||||
|
surgery.setAnesthetistName(anesthetistName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("查询麻醉医生名称失败 - anesthetistId: {}, error: {}", surgery.getAnesthetistId(), e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 填充执行科室名称
|
||||||
|
if ((surgery.getOrgName() == null || surgery.getOrgName().isEmpty())
|
||||||
|
&& surgery.getOrgId() != null) {
|
||||||
|
try {
|
||||||
|
com.openhis.administration.domain.Organization org = organizationService.getById(surgery.getOrgId());
|
||||||
|
if (org != null && org.getName() != null) {
|
||||||
|
surgery.setOrgName(org.getName());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("查询执行科室名称失败 - orgId: {}, error: {}", surgery.getOrgId(), e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,11 @@ public class OpCreateScheduleDto {
|
|||||||
*/
|
*/
|
||||||
private Long visitId;
|
private Long visitId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 就诊卡号
|
||||||
|
*/
|
||||||
|
private String identifierNo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 手术编码
|
* 手术编码
|
||||||
*/
|
*/
|
||||||
@@ -45,9 +50,10 @@ public class OpCreateScheduleDto {
|
|||||||
private String postoperativeDiagnosis;
|
private String postoperativeDiagnosis;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 手术安排日期
|
* 手术安排日期时间
|
||||||
*/
|
*/
|
||||||
private LocalDate scheduleDate;
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private LocalDateTime scheduleDate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 手术台次序号
|
* 手术台次序号
|
||||||
@@ -82,11 +88,13 @@ public class OpCreateScheduleDto {
|
|||||||
/**
|
/**
|
||||||
* 入院时间
|
* 入院时间
|
||||||
*/
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
private LocalDateTime admissionTime;
|
private LocalDateTime admissionTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 入手术室时间
|
* 入手术室时间
|
||||||
*/
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
private LocalDateTime entryTime;
|
private LocalDateTime entryTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -167,21 +175,25 @@ public class OpCreateScheduleDto {
|
|||||||
/**
|
/**
|
||||||
* 手术开始时间
|
* 手术开始时间
|
||||||
*/
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
private LocalDateTime startTime;
|
private LocalDateTime startTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 手术结束时间
|
* 手术结束时间
|
||||||
*/
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
private LocalDateTime endTime;
|
private LocalDateTime endTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 麻醉开始时间
|
* 麻醉开始时间
|
||||||
*/
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
private LocalDateTime anesStart;
|
private LocalDateTime anesStart;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 麻醉结束时间
|
* 麻醉结束时间
|
||||||
*/
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
private LocalDateTime anesEnd;
|
private LocalDateTime anesEnd;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonFormat;
|
|||||||
import com.openhis.surgicalschedule.domain.OpSchedule;
|
import com.openhis.surgicalschedule.domain.OpSchedule;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
|
||||||
@@ -18,6 +19,20 @@ import java.time.LocalDate;
|
|||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class OpScheduleDto extends OpSchedule {
|
public class OpScheduleDto extends OpSchedule {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手术安排日期开始(查询用)
|
||||||
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||||
|
private LocalDate scheduleDateStart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手术安排日期结束(查询用)
|
||||||
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||||
|
private LocalDate scheduleDateEnd;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 患者姓名
|
* 患者姓名
|
||||||
*/
|
*/
|
||||||
@@ -28,6 +43,11 @@ public class OpScheduleDto extends OpSchedule {
|
|||||||
*/
|
*/
|
||||||
private Long encounterId;
|
private Long encounterId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 就诊卡号
|
||||||
|
*/
|
||||||
|
private String patientCardNo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 性别
|
* 性别
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.openhis.web.clinicalmanage.dto;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import com.openhis.common.annotation.Dict;
|
import com.openhis.common.annotation.Dict;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
@@ -45,6 +46,9 @@ public class SurgeryDto {
|
|||||||
/** 就诊流水号 */
|
/** 就诊流水号 */
|
||||||
private String encounterNo;
|
private String encounterNo;
|
||||||
|
|
||||||
|
/** 就诊卡号 */
|
||||||
|
private String patientCardNo;
|
||||||
|
|
||||||
/** 申请医生ID */
|
/** 申请医生ID */
|
||||||
@JsonSerialize(using = ToStringSerializer.class)
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
private Long applyDoctorId;
|
private Long applyDoctorId;
|
||||||
@@ -84,6 +88,7 @@ public class SurgeryDto {
|
|||||||
private String statusEnum_dictText;
|
private String statusEnum_dictText;
|
||||||
|
|
||||||
/** 计划手术时间 */
|
/** 计划手术时间 */
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss", timezone = "GMT+8")
|
||||||
private Date plannedTime;
|
private Date plannedTime;
|
||||||
|
|
||||||
/** 实际开始时间 */
|
/** 实际开始时间 */
|
||||||
|
|||||||
@@ -149,6 +149,14 @@ public interface IConsultationAppService {
|
|||||||
* @return 会诊意见列表
|
* @return 会诊意见列表
|
||||||
*/
|
*/
|
||||||
List<ConsultationOpinionDto> getConsultationOpinions(String consultationId);
|
List<ConsultationOpinionDto> getConsultationOpinions(String consultationId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID查询会诊申请详情
|
||||||
|
*
|
||||||
|
* @param id 会诊申请ID
|
||||||
|
* @return 会诊申请详情
|
||||||
|
*/
|
||||||
|
ConsultationRequestDto getConsultationById(Long id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -186,6 +186,11 @@ public class ConsultationAppServiceImpl implements IConsultationAppService {
|
|||||||
wrapper.like(ConsultationRequest::getPatientName, dto.getPatientName());
|
wrapper.like(ConsultationRequest::getPatientName, dto.getPatientName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 会诊ID查询(支持模糊匹配)
|
||||||
|
if (StringUtils.hasText(dto.getConsultationId())) {
|
||||||
|
wrapper.like(ConsultationRequest::getConsultationId, dto.getConsultationId());
|
||||||
|
}
|
||||||
|
|
||||||
// 按创建时间倒序排列
|
// 按创建时间倒序排列
|
||||||
wrapper.orderByDesc(ConsultationRequest::getConsultationRequestDate);
|
wrapper.orderByDesc(ConsultationRequest::getConsultationRequestDate);
|
||||||
|
|
||||||
@@ -240,6 +245,11 @@ public class ConsultationAppServiceImpl implements IConsultationAppService {
|
|||||||
wrapper.like(ConsultationRequest::getPatientName, dto.getPatientName());
|
wrapper.like(ConsultationRequest::getPatientName, dto.getPatientName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 会诊ID查询(支持模糊匹配)
|
||||||
|
if (StringUtils.hasText(dto.getConsultationId())) {
|
||||||
|
wrapper.like(ConsultationRequest::getConsultationId, dto.getConsultationId());
|
||||||
|
}
|
||||||
|
|
||||||
// 按创建时间倒序排列
|
// 按创建时间倒序排列
|
||||||
wrapper.orderByDesc(ConsultationRequest::getConsultationRequestDate);
|
wrapper.orderByDesc(ConsultationRequest::getConsultationRequestDate);
|
||||||
|
|
||||||
@@ -411,6 +421,20 @@ public class ConsultationAppServiceImpl implements IConsultationAppService {
|
|||||||
|
|
||||||
// 新增:更新门诊医嘱表状态为已提交
|
// 新增:更新门诊医嘱表状态为已提交
|
||||||
updateServiceRequestStatus(entity.getOrderId(), RequestStatus.ACTIVE.getValue());
|
updateServiceRequestStatus(entity.getOrderId(), RequestStatus.ACTIVE.getValue());
|
||||||
|
|
||||||
|
// 🎯 更新会诊关联费用项状态为"待收费",提交后即可在收费界面看到
|
||||||
|
if (entity.getOrderId() != null) {
|
||||||
|
LambdaQueryWrapper<ChargeItem> chargeItemWrapper = new LambdaQueryWrapper<>();
|
||||||
|
chargeItemWrapper.eq(ChargeItem::getServiceId, entity.getOrderId())
|
||||||
|
.eq(ChargeItem::getServiceTable, "wor_service_request");
|
||||||
|
List<ChargeItem> chargeItems = iChargeItemService.list(chargeItemWrapper);
|
||||||
|
for (ChargeItem chargeItem : chargeItems) {
|
||||||
|
chargeItem.setStatusEnum(ChargeItemStatus.PLANNED.getValue());
|
||||||
|
iChargeItemService.updateById(chargeItem);
|
||||||
|
}
|
||||||
|
log.info("会诊提交,更新关联费用项状态为待收费,更新数量: {}", chargeItems.size());
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("提交会诊申请失败", e);
|
log.error("提交会诊申请失败", e);
|
||||||
@@ -435,7 +459,15 @@ public class ConsultationAppServiceImpl implements IConsultationAppService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 判断是"取消提交"还是"作废"
|
// 判断是"取消提交"还是"作废"
|
||||||
if ("取消提交".equals(cancelReason) && ConsultationStatusEnum.SUBMITTED.getCode().equals(entity.getConsultationStatus())) {
|
if ("取消提交".equals(cancelReason)) {
|
||||||
|
// 状态校验:禁止已确认 (20)、已签名 (30)、已完成 (40) 的会诊申请取消提交
|
||||||
|
if (entity.getConsultationStatus() >= ConsultationStatusEnum.CONFIRMED.getCode()) {
|
||||||
|
throw new IllegalArgumentException("当前状态不允许取消提交,只有已提交状态的会诊申请才能取消提交");
|
||||||
|
}
|
||||||
|
// 只有状态为 10(已提交) 才允许取消提交
|
||||||
|
if (!ConsultationStatusEnum.SUBMITTED.getCode().equals(entity.getConsultationStatus())) {
|
||||||
|
throw new IllegalArgumentException("只有已提交状态的会诊申请才能取消提交");
|
||||||
|
}
|
||||||
// 取消提交:将状态从"已提交"改回"新开"
|
// 取消提交:将状态从"已提交"改回"新开"
|
||||||
entity.setConsultationStatus(ConsultationStatusEnum.NEW.getCode());
|
entity.setConsultationStatus(ConsultationStatusEnum.NEW.getCode());
|
||||||
entity.setConfirmingPhysician(null);
|
entity.setConfirmingPhysician(null);
|
||||||
@@ -446,8 +478,26 @@ public class ConsultationAppServiceImpl implements IConsultationAppService {
|
|||||||
// 更新门诊医嘱表状态为新开
|
// 更新门诊医嘱表状态为新开
|
||||||
updateServiceRequestStatus(entity.getOrderId(), RequestStatus.DRAFT.getValue());
|
updateServiceRequestStatus(entity.getOrderId(), RequestStatus.DRAFT.getValue());
|
||||||
|
|
||||||
|
// 更新关联费用项状态为草稿
|
||||||
|
if (entity.getOrderId() != null) {
|
||||||
|
LambdaQueryWrapper<ChargeItem> chargeItemWrapper = new LambdaQueryWrapper<>();
|
||||||
|
chargeItemWrapper.eq(ChargeItem::getServiceId, entity.getOrderId())
|
||||||
|
.eq(ChargeItem::getServiceTable, "wor_service_request");
|
||||||
|
List<ChargeItem> chargeItems = iChargeItemService.list(chargeItemWrapper);
|
||||||
|
for (ChargeItem chargeItem : chargeItems) {
|
||||||
|
chargeItem.setStatusEnum(ChargeItemStatus.DRAFT.getValue());
|
||||||
|
iChargeItemService.updateById(chargeItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// 作废:将状态改为"已取消"
|
// 作废:状态校验 - 已确认(20)、已签名(30)、已完成(40) 状态禁止作废
|
||||||
|
ConsultationStatusEnum currentStatus = ConsultationStatusEnum.getByCode(entity.getConsultationStatus());
|
||||||
|
if (currentStatus != null && !currentStatus.canCancel()) {
|
||||||
|
throw new IllegalArgumentException("当前状态【" + currentStatus.getDescription() + "】不允许作废,只有新开或已提交状态的会诊申请才能作废");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将状态改为"已取消"
|
||||||
entity.setConsultationStatus(CANCELLED.getCode());
|
entity.setConsultationStatus(CANCELLED.getCode());
|
||||||
entity.setCancelReason(cancelReason);
|
entity.setCancelReason(cancelReason);
|
||||||
entity.setCancelNatureDate(new Date());
|
entity.setCancelNatureDate(new Date());
|
||||||
@@ -456,6 +506,18 @@ public class ConsultationAppServiceImpl implements IConsultationAppService {
|
|||||||
// 更新门诊医嘱表状态为已作废
|
// 更新门诊医嘱表状态为已作废
|
||||||
updateServiceRequestStatus(entity.getOrderId(), RequestStatus.CANCELLED.getValue());
|
updateServiceRequestStatus(entity.getOrderId(), RequestStatus.CANCELLED.getValue());
|
||||||
|
|
||||||
|
// 更新关联费用项状态为终止
|
||||||
|
if (entity.getOrderId() != null) {
|
||||||
|
LambdaQueryWrapper<ChargeItem> chargeItemWrapper = new LambdaQueryWrapper<>();
|
||||||
|
chargeItemWrapper.eq(ChargeItem::getServiceId, entity.getOrderId())
|
||||||
|
.eq(ChargeItem::getServiceTable, "wor_service_request");
|
||||||
|
List<ChargeItem> chargeItems = iChargeItemService.list(chargeItemWrapper);
|
||||||
|
for (ChargeItem chargeItem : chargeItems) {
|
||||||
|
chargeItem.setStatusEnum(ChargeItemStatus.ABORTED.getValue());
|
||||||
|
iChargeItemService.updateById(chargeItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -644,12 +706,14 @@ public class ConsultationAppServiceImpl implements IConsultationAppService {
|
|||||||
@Override
|
@Override
|
||||||
public List<ConsultationRequestDto> getMyInvitations() {
|
public List<ConsultationRequestDto> getMyInvitations() {
|
||||||
try {
|
try {
|
||||||
// 获取当前登录医生ID
|
// 获取当前登录医生ID和租户ID
|
||||||
Long currentPhysicianId = SecurityUtils.getLoginUser().getPractitionerId();
|
Long currentPhysicianId = SecurityUtils.getLoginUser().getPractitionerId();
|
||||||
|
Long tenantId = SecurityUtils.getLoginUser().getTenantId().longValue();
|
||||||
|
|
||||||
// 查询邀请我的会诊申请
|
// 查询邀请我的会诊申请
|
||||||
LambdaQueryWrapper<ConsultationInvited> invitedWrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<ConsultationInvited> invitedWrapper = new LambdaQueryWrapper<>();
|
||||||
invitedWrapper.eq(ConsultationInvited::getInvitedPhysicianId, currentPhysicianId)
|
invitedWrapper.eq(ConsultationInvited::getTenantId, tenantId)
|
||||||
|
.eq(ConsultationInvited::getInvitedPhysicianId, currentPhysicianId)
|
||||||
.orderByDesc(ConsultationInvited::getCreateTime);
|
.orderByDesc(ConsultationInvited::getCreateTime);
|
||||||
|
|
||||||
List<ConsultationInvited> invitedList = consultationInvitedMapper.selectList(invitedWrapper);
|
List<ConsultationInvited> invitedList = consultationInvitedMapper.selectList(invitedWrapper);
|
||||||
@@ -717,38 +781,64 @@ public class ConsultationAppServiceImpl implements IConsultationAppService {
|
|||||||
|
|
||||||
dto.setInvitedList(invitedDtoList);
|
dto.setInvitedList(invitedDtoList);
|
||||||
|
|
||||||
// 🎯 如果会诊已完成或已签名,填充会诊记录信息(从已签名的医生中获取)
|
|
||||||
|
// 🎯 如果会诊已确认、已签名或已完成,填充会诊记录信息(从会诊确认表中获取)
|
||||||
|
// 会诊状态:20=已确认,30=已签名,40=已完成
|
||||||
if (entity.getConsultationStatus() != null &&
|
if (entity.getConsultationStatus() != null &&
|
||||||
(entity.getConsultationStatus() == ConsultationStatusEnum.SIGNED.getCode() ||
|
entity.getConsultationStatus() >= ConsultationStatusEnum.CONFIRMED.getCode()) {
|
||||||
entity.getConsultationStatus() == ConsultationStatusEnum.COMPLETED.getCode())) {
|
|
||||||
|
// 查询会诊确认记录
|
||||||
|
LambdaQueryWrapper<ConsultationConfirmation> confirmWrapper = new LambdaQueryWrapper<>();
|
||||||
|
confirmWrapper.eq(ConsultationConfirmation::getConsultationRequestId, entity.getId());
|
||||||
|
ConsultationConfirmation confirmation = consultationConfirmationMapper.selectOne(confirmWrapper);
|
||||||
|
|
||||||
|
// 查询所有已确认和已签名的医生(invited_status >= 2)
|
||||||
|
List<ConsultationInvited> confirmedAndSignedPhysicians = invitedList.stream()
|
||||||
|
.filter(inv -> inv.getInvitedStatus() != null && inv.getInvitedStatus() >= 2)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
// 查询所有已签名的医生(invited_status >= 3)
|
// 查询所有已签名的医生(invited_status >= 3)
|
||||||
List<ConsultationInvited> signedPhysicians = invitedList.stream()
|
List<ConsultationInvited> signedPhysicians = invitedList.stream()
|
||||||
.filter(inv -> inv.getInvitedStatus() != null && inv.getInvitedStatus() >= 3)
|
.filter(inv -> inv.getInvitedStatus() != null && inv.getInvitedStatus() >= 3)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
if (!signedPhysicians.isEmpty()) {
|
if (confirmation != null) {
|
||||||
// 1. 会诊邀请参加医师:拼接所有已签名医生的"科室-姓名"
|
// 1. 会诊确认参加医师:优先从确认表的confirming_physicians字段取值
|
||||||
String invitedPhysiciansText = signedPhysicians.stream()
|
if (StringUtils.hasText(confirmation.getConfirmingPhysicians())) {
|
||||||
|
dto.setInvitedPhysiciansText(confirmation.getConfirmingPhysicians());
|
||||||
|
} else if (!confirmedAndSignedPhysicians.isEmpty()) {
|
||||||
|
// 备用:从invitedList拼接
|
||||||
|
String invitedPhysiciansText = confirmedAndSignedPhysicians.stream()
|
||||||
.map(inv -> inv.getInvitedDepartmentName() + "-" + inv.getInvitedPhysicianName())
|
.map(inv -> inv.getInvitedDepartmentName() + "-" + inv.getInvitedPhysicianName())
|
||||||
.collect(Collectors.joining("、"));
|
.collect(Collectors.joining("、"));
|
||||||
dto.setInvitedPhysiciansText(invitedPhysiciansText);
|
dto.setInvitedPhysiciansText(invitedPhysiciansText);
|
||||||
|
}
|
||||||
|
|
||||||
// 2. 会诊意见:汇总所有已签名医生的意见
|
// 2. 会诊意见:优先从确认表取值
|
||||||
String consultationOpinion = signedPhysicians.stream()
|
if (StringUtils.hasText(confirmation.getConsultationOpinion())) {
|
||||||
|
dto.setConsultationOpinion(confirmation.getConsultationOpinion());
|
||||||
|
} else if (!confirmedAndSignedPhysicians.isEmpty()) {
|
||||||
|
// 备用:从invitedList汇总
|
||||||
|
String consultationOpinion = confirmedAndSignedPhysicians.stream()
|
||||||
.filter(inv -> StringUtils.hasText(inv.getConfirmOpinion()))
|
.filter(inv -> StringUtils.hasText(inv.getConfirmOpinion()))
|
||||||
.map(ConsultationInvited::getConfirmOpinion)
|
.map(ConsultationInvited::getConfirmOpinion)
|
||||||
.collect(Collectors.joining("\n"));
|
.collect(Collectors.joining("\n"));
|
||||||
dto.setConsultationOpinion(consultationOpinion);
|
dto.setConsultationOpinion(consultationOpinion);
|
||||||
|
}
|
||||||
|
|
||||||
// 3. 所属医生、代表科室、签名医生、签名时间:使用第一个签名的医生
|
// 3. 签名医生、签名时间:从确认表取值
|
||||||
ConsultationInvited firstSigned = signedPhysicians.get(0);
|
dto.setSignPhysician(confirmation.getSignature());
|
||||||
dto.setAttendingPhysician(firstSigned.getInvitedPhysicianName());
|
dto.setSignTime(confirmation.getSignatureDate());
|
||||||
dto.setRepresentDepartment(firstSigned.getInvitedDepartmentName());
|
}
|
||||||
dto.setSignPhysician(firstSigned.getInvitedPhysicianName());
|
|
||||||
dto.setSignTime(firstSigned.getSignatureTime());
|
|
||||||
|
|
||||||
log.info("填充会诊记录信息,已签名医生数:{}", signedPhysicians.size());
|
// 4. 所属医生、代表科室:使用第一个确认的医生(向后兼容)
|
||||||
|
if (!confirmedAndSignedPhysicians.isEmpty()) {
|
||||||
|
ConsultationInvited firstConfirmed = confirmedAndSignedPhysicians.get(0);
|
||||||
|
dto.setAttendingPhysician(firstConfirmed.getInvitedPhysicianName());
|
||||||
|
dto.setRepresentDepartment(firstConfirmed.getInvitedDepartmentName());
|
||||||
|
|
||||||
|
log.info("填充会诊记录信息,已确认和已签名医生数:{},已签名医生数:{}",
|
||||||
|
confirmedAndSignedPhysicians.size(), signedPhysicians.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1151,14 +1241,16 @@ public class ConsultationAppServiceImpl implements IConsultationAppService {
|
|||||||
@Override
|
@Override
|
||||||
public List<ConsultationConfirmationDto> getPendingConfirmationList() {
|
public List<ConsultationConfirmationDto> getPendingConfirmationList() {
|
||||||
try {
|
try {
|
||||||
// 获取当前登录医生ID
|
// 获取当前登录医生ID和租户ID
|
||||||
Long currentPhysicianId = SecurityUtils.getLoginUser().getPractitionerId();
|
Long currentPhysicianId = SecurityUtils.getLoginUser().getPractitionerId();
|
||||||
|
Long tenantId = SecurityUtils.getLoginUser().getTenantId().longValue();
|
||||||
log.info("获取待确认会诊列表,当前医生ID: {}", currentPhysicianId);
|
log.info("获取待确认会诊列表,当前医生ID: {}", currentPhysicianId);
|
||||||
|
|
||||||
// 🎯 关键修改:查询当前医生个人状态为"待确认"、"已确认"或"已签名"的邀请记录
|
// 🎯 关键修改:查询当前医生个人状态为"待确认"、"已确认"或"已签名"的邀请记录
|
||||||
// 10=已提交(待确认)、20=已确认(待签名)、30=已签名,排除40=已完成
|
// 10=已提交(待确认)、20=已确认(待签名)、30=已签名,排除40=已完成
|
||||||
LambdaQueryWrapper<ConsultationInvited> invitedWrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<ConsultationInvited> invitedWrapper = new LambdaQueryWrapper<>();
|
||||||
invitedWrapper.eq(ConsultationInvited::getInvitedPhysicianId, currentPhysicianId)
|
invitedWrapper.eq(ConsultationInvited::getTenantId, tenantId)
|
||||||
|
.eq(ConsultationInvited::getInvitedPhysicianId, currentPhysicianId)
|
||||||
.in(ConsultationInvited::getInvitedStatus,
|
.in(ConsultationInvited::getInvitedStatus,
|
||||||
ConsultationStatusEnum.SUBMITTED.getCode(), // 10-待确认
|
ConsultationStatusEnum.SUBMITTED.getCode(), // 10-待确认
|
||||||
ConsultationStatusEnum.CONFIRMED.getCode(), // 20-已确认(待签名)
|
ConsultationStatusEnum.CONFIRMED.getCode(), // 20-已确认(待签名)
|
||||||
@@ -1183,7 +1275,8 @@ public class ConsultationAppServiceImpl implements IConsultationAppService {
|
|||||||
// 🎯 查询会诊申请详情(白名单:只查询正在进行中的会诊,明确业务范围)
|
// 🎯 查询会诊申请详情(白名单:只查询正在进行中的会诊,明确业务范围)
|
||||||
// 查询已提交、已确认、已签名状态的会诊,排除已完成(40)
|
// 查询已提交、已确认、已签名状态的会诊,排除已完成(40)
|
||||||
LambdaQueryWrapper<ConsultationRequest> requestWrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<ConsultationRequest> requestWrapper = new LambdaQueryWrapper<>();
|
||||||
requestWrapper.in(ConsultationRequest::getId, requestIds)
|
requestWrapper.eq(ConsultationRequest::getTenantId, tenantId)
|
||||||
|
.in(ConsultationRequest::getId, requestIds)
|
||||||
.in(ConsultationRequest::getConsultationStatus,
|
.in(ConsultationRequest::getConsultationStatus,
|
||||||
ConsultationStatusEnum.SUBMITTED.getCode(), // 10-已提交
|
ConsultationStatusEnum.SUBMITTED.getCode(), // 10-已提交
|
||||||
ConsultationStatusEnum.CONFIRMED.getCode(), // 20-已确认
|
ConsultationStatusEnum.CONFIRMED.getCode(), // 20-已确认
|
||||||
@@ -1272,10 +1365,13 @@ public class ConsultationAppServiceImpl implements IConsultationAppService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 4. 更新邀请记录(存储会诊意见)
|
// 4. 更新邀请记录(存储会诊意见)
|
||||||
// 格式:科室-医生:意见内容
|
// 格式:科室-会诊确认参加医师:意见内容
|
||||||
|
// 兼容:若前端未填写“会诊确认参加医师”,则回退为当前医生姓名
|
||||||
|
String confirmingPhysicianText =
|
||||||
|
StringUtils.hasText(dto.getConfirmingPhysician()) ? dto.getConfirmingPhysician().trim() : currentPhysicianName;
|
||||||
String formattedOpinion = String.format("%s-%s:%s",
|
String formattedOpinion = String.format("%s-%s:%s",
|
||||||
currentDeptName,
|
currentDeptName,
|
||||||
currentPhysicianName,
|
confirmingPhysicianText,
|
||||||
dto.getConsultationOpinion());
|
dto.getConsultationOpinion());
|
||||||
|
|
||||||
invited.setInvitedStatus(ConsultationStatusEnum.CONFIRMED.getCode()); // 已确认
|
invited.setInvitedStatus(ConsultationStatusEnum.CONFIRMED.getCode()); // 已确认
|
||||||
@@ -1584,6 +1680,19 @@ public class ConsultationAppServiceImpl implements IConsultationAppService {
|
|||||||
// 更新医嘱状态为"已完成"
|
// 更新医嘱状态为"已完成"
|
||||||
updateServiceRequestStatus(request.getOrderId(), RequestStatus.COMPLETED.getValue());
|
updateServiceRequestStatus(request.getOrderId(), RequestStatus.COMPLETED.getValue());
|
||||||
|
|
||||||
|
// 🎯 更新会诊关联费用项状态为"待收费",这样收费界面就能看到了
|
||||||
|
if (request.getOrderId() != null) {
|
||||||
|
LambdaQueryWrapper<ChargeItem> chargeItemWrapper = new LambdaQueryWrapper<>();
|
||||||
|
chargeItemWrapper.eq(ChargeItem::getServiceId, request.getOrderId())
|
||||||
|
.eq(ChargeItem::getServiceTable, "wor_service_request");
|
||||||
|
List<ChargeItem> chargeItems = iChargeItemService.list(chargeItemWrapper);
|
||||||
|
for (ChargeItem chargeItem : chargeItems) {
|
||||||
|
chargeItem.setStatusEnum(ChargeItemStatus.PLANNED.getValue());
|
||||||
|
iChargeItemService.updateById(chargeItem);
|
||||||
|
}
|
||||||
|
log.info("会诊完成,更新关联费用项状态为待收费,更新数量: {}", chargeItems.size());
|
||||||
|
}
|
||||||
|
|
||||||
log.info("所有医生都已签名,会诊申请状态更新为:已签名(30)");
|
log.info("所有医生都已签名,会诊申请状态更新为:已签名(30)");
|
||||||
} else {
|
} else {
|
||||||
// 🎯 关键修改:部分医生签名,整体状态不变(保持为10或20)
|
// 🎯 关键修改:部分医生签名,整体状态不变(保持为10或20)
|
||||||
@@ -1783,5 +1892,26 @@ public class ConsultationAppServiceImpl implements IConsultationAppService {
|
|||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConsultationRequestDto getConsultationById(Long id) {
|
||||||
|
try {
|
||||||
|
if (id == null) {
|
||||||
|
throw new IllegalArgumentException("会诊申请ID不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 查询会诊申请
|
||||||
|
ConsultationRequest request = consultationRequestMapper.selectById(id);
|
||||||
|
if (request == null) {
|
||||||
|
throw new IllegalArgumentException("会诊申请不存在,ID: " + id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 转换为DTO并返回
|
||||||
|
return convertToDto(request);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询会诊申请详情失败", e);
|
||||||
|
throw new RuntimeException("查询会诊申请详情失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -302,5 +302,21 @@ public class ConsultationController {
|
|||||||
return R.fail("获取会诊意见列表失败: " + e.getMessage());
|
return R.fail("获取会诊意见列表失败: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID查询会诊申请详情
|
||||||
|
*/
|
||||||
|
@ApiOperation("根据ID查询会诊申请详情")
|
||||||
|
@GetMapping("/detail/{id}")
|
||||||
|
public R<ConsultationRequestDto> getConsultationById(
|
||||||
|
@ApiParam("会诊申请ID") @PathVariable Long id) {
|
||||||
|
try {
|
||||||
|
ConsultationRequestDto detail = consultationAppService.getConsultationById(id);
|
||||||
|
return R.ok(detail);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询会诊申请详情失败", e);
|
||||||
|
return R.fail("查询会诊申请详情失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -76,10 +76,12 @@ public enum ConsultationStatusEnum {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断是否可以取消
|
* 判断是否可以取消/作废
|
||||||
|
* 只有新开(0)和已提交(10)状态可以作废
|
||||||
|
* 已确认(20)、已签名(30)、已完成(40)状态禁止作废
|
||||||
*/
|
*/
|
||||||
public boolean canCancel() {
|
public boolean canCancel() {
|
||||||
return this == NEW || this == SUBMITTED || this == CONFIRMED;
|
return this == NEW || this == SUBMITTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,6 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
|
|||||||
private IOperationRecordService operationRecordService;
|
private IOperationRecordService operationRecordService;
|
||||||
@Resource
|
@Resource
|
||||||
private IServiceRequestService serviceRequestService;
|
private IServiceRequestService serviceRequestService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 诊疗目录初期查询
|
* 诊疗目录初期查询
|
||||||
*
|
*
|
||||||
@@ -186,6 +185,14 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
|
|||||||
public R<?> getDiseaseTreatmentPage(DiagnosisTreatmentSelParam DiagnosisTreatmentSelParam, String searchKey,
|
public R<?> getDiseaseTreatmentPage(DiagnosisTreatmentSelParam DiagnosisTreatmentSelParam, String searchKey,
|
||||||
Integer pageNo, Integer pageSize, HttpServletRequest request) {
|
Integer pageNo, Integer pageSize, HttpServletRequest request) {
|
||||||
|
|
||||||
|
// 如果没有指定状态,默认只查询启用状态(status_enum=2),避免显示未启用的项目导致保存失败
|
||||||
|
if (DiagnosisTreatmentSelParam == null) {
|
||||||
|
DiagnosisTreatmentSelParam = new DiagnosisTreatmentSelParam();
|
||||||
|
}
|
||||||
|
if (DiagnosisTreatmentSelParam.getStatusEnum() == null) {
|
||||||
|
DiagnosisTreatmentSelParam.setStatusEnum(PublicationStatus.ACTIVE.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
// 临时保存ybType值并从参数对象中移除,避免HisQueryUtils构建yb_type条件
|
// 临时保存ybType值并从参数对象中移除,避免HisQueryUtils构建yb_type条件
|
||||||
String ybTypeValue = null;
|
String ybTypeValue = null;
|
||||||
if (DiagnosisTreatmentSelParam != null && StringUtils.isNotEmpty(DiagnosisTreatmentSelParam.getYbType())) {
|
if (DiagnosisTreatmentSelParam != null && StringUtils.isNotEmpty(DiagnosisTreatmentSelParam.getYbType())) {
|
||||||
@@ -232,9 +239,8 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
|
|||||||
DiagnosisTreatmentSelParam.setPricingFlag(pricingFlagValue);
|
DiagnosisTreatmentSelParam.setPricingFlag(pricingFlagValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分页查询
|
|
||||||
IPage<DiagnosisTreatmentDto> diseaseTreatmentPage
|
IPage<DiagnosisTreatmentDto> diseaseTreatmentPage
|
||||||
= activityDefinitionManageMapper.getDiseaseTreatmentPage(new Page<DiagnosisTreatmentDto>(pageNo, pageSize), queryWrapper);
|
= activityDefinitionManageMapper.getDiseaseTreatmentPage(new Page<>(pageNo, pageSize), queryWrapper);
|
||||||
|
|
||||||
diseaseTreatmentPage.getRecords().forEach(e -> {
|
diseaseTreatmentPage.getRecords().forEach(e -> {
|
||||||
// 医保标记枚举类回显赋值
|
// 医保标记枚举类回显赋值
|
||||||
@@ -439,24 +445,17 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public R<?> editDiseaseTreatmentStop(List<Long> ids) {
|
public R<?> editDiseaseTreatmentStop(List<Long> ids) {
|
||||||
|
List<ActivityDefinition> actList = new CopyOnWriteArrayList<>();
|
||||||
List<ActivityDefinition> ActivityDefinitionList = new CopyOnWriteArrayList<>();
|
for (Long id : ids) {
|
||||||
|
ActivityDefinition act = new ActivityDefinition();
|
||||||
// 取得更新值
|
act.setId(id);
|
||||||
for (Long detail : ids) {
|
act.setStatusEnum(PublicationStatus.RETIRED.getValue());
|
||||||
ActivityDefinition ActivityDefinition = new ActivityDefinition();
|
actList.add(act);
|
||||||
ActivityDefinition.setId(detail);
|
|
||||||
ActivityDefinition.setStatusEnum(PublicationStatus.RETIRED.getValue());
|
|
||||||
ActivityDefinitionList.add(ActivityDefinition);
|
|
||||||
}
|
}
|
||||||
// 插入操作记录
|
|
||||||
operationRecordService.addIdsOperationRecord(DbOpType.STOP.getCode(),
|
operationRecordService.addIdsOperationRecord(DbOpType.STOP.getCode(),
|
||||||
CommonConstants.TableName.WOR_ACTIVITY_DEFINITION, ids);
|
CommonConstants.TableName.WOR_ACTIVITY_DEFINITION, ids);
|
||||||
// 更新诊疗信息
|
activityDefinitionService.updateBatchById(actList);
|
||||||
return activityDefinitionService.updateBatchById(ActivityDefinitionList)
|
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"\u8bca\u7597\u76ee\u5f55"}));
|
||||||
? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"诊疗目录"}))
|
|
||||||
: R.fail(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -467,24 +466,17 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public R<?> editDiseaseTreatmentStart(List<Long> ids) {
|
public R<?> editDiseaseTreatmentStart(List<Long> ids) {
|
||||||
|
List<ActivityDefinition> actList = new CopyOnWriteArrayList<>();
|
||||||
List<ActivityDefinition> ActivityDefinitionList = new CopyOnWriteArrayList<>();
|
for (Long id : ids) {
|
||||||
|
ActivityDefinition act = new ActivityDefinition();
|
||||||
// 取得更新值
|
act.setId(id);
|
||||||
for (Long detail : ids) {
|
act.setStatusEnum(PublicationStatus.ACTIVE.getValue());
|
||||||
ActivityDefinition ActivityDefinition = new ActivityDefinition();
|
actList.add(act);
|
||||||
ActivityDefinition.setId(detail);
|
|
||||||
ActivityDefinition.setStatusEnum(PublicationStatus.ACTIVE.getValue());
|
|
||||||
ActivityDefinitionList.add(ActivityDefinition);
|
|
||||||
}
|
}
|
||||||
// 插入操作记录
|
|
||||||
operationRecordService.addIdsOperationRecord(DbOpType.START.getCode(),
|
operationRecordService.addIdsOperationRecord(DbOpType.START.getCode(),
|
||||||
CommonConstants.TableName.WOR_ACTIVITY_DEFINITION, ids);
|
CommonConstants.TableName.WOR_ACTIVITY_DEFINITION, ids);
|
||||||
// 更新诊疗信息
|
activityDefinitionService.updateBatchById(actList);
|
||||||
return activityDefinitionService.updateBatchById(ActivityDefinitionList)
|
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"诊疗目录"}));
|
||||||
? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"诊疗目录"}))
|
|
||||||
: R.fail(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package com.openhis.web.datadictionary.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentDto;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检验项目定义管理 Mapper(操作 lab_activity_definition 表)
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
public interface LabActivityDefinitionManageMapper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检验项目分页查询
|
||||||
|
*
|
||||||
|
* @param page 分页参数
|
||||||
|
* @param queryWrapper 查询条件
|
||||||
|
* @return 分页结果
|
||||||
|
*/
|
||||||
|
IPage<DiagnosisTreatmentDto> getLabActivityDefinitionPage(
|
||||||
|
@Param("page") Page<DiagnosisTreatmentDto> page,
|
||||||
|
@Param(Constants.WRAPPER) QueryWrapper<DiagnosisTreatmentDto> queryWrapper);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检验项目详情
|
||||||
|
*
|
||||||
|
* @param id 项目ID
|
||||||
|
* @param tenantId 租户ID
|
||||||
|
* @return 详情
|
||||||
|
*/
|
||||||
|
DiagnosisTreatmentDto getLabActivityDefinitionOne(@Param("id") Long id, @Param("tenantId") Integer tenantId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检验项目下拉列表(轻量级)
|
||||||
|
*
|
||||||
|
* @param statusEnum 状态
|
||||||
|
* @param tenantId 租户ID
|
||||||
|
* @param searchKey 搜索关键词(可选)
|
||||||
|
* @return 列表
|
||||||
|
*/
|
||||||
|
List<DiagnosisTreatmentDto> getLabActivityDefinitionSimpleList(
|
||||||
|
@Param("statusEnum") Integer statusEnum,
|
||||||
|
@Param("tenantId") Integer tenantId,
|
||||||
|
@Param("searchKey") String searchKey);
|
||||||
|
}
|
||||||
@@ -31,7 +31,7 @@ public interface IDoctorStationAdviceAppService {
|
|||||||
*/
|
*/
|
||||||
IPage<AdviceBaseDto> getAdviceBaseInfo(AdviceBaseDto adviceBaseDto, String searchKey, Long locationId,
|
IPage<AdviceBaseDto> getAdviceBaseInfo(AdviceBaseDto adviceBaseDto, String searchKey, Long locationId,
|
||||||
List<Long> adviceDefinitionIdParamList, Long organizationId, Integer pageNo, Integer pageSize,
|
List<Long> adviceDefinitionIdParamList, Long organizationId, Integer pageNo, Integer pageSize,
|
||||||
Integer pricingFlag, List<Integer> adviceTypes, String orderPricing);
|
Integer pricingFlag, List<Integer> adviceTypes, String orderPricing, String categoryCode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询医嘱绑定信息
|
* 查询医嘱绑定信息
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import com.openhis.common.constant.PromptMsgConstant;
|
|||||||
import com.openhis.common.enums.*;
|
import com.openhis.common.enums.*;
|
||||||
import com.openhis.common.utils.EnumUtils;
|
import com.openhis.common.utils.EnumUtils;
|
||||||
import com.openhis.common.utils.HisQueryUtils;
|
import com.openhis.common.utils.HisQueryUtils;
|
||||||
|
import com.openhis.medication.domain.MedicationDispense;
|
||||||
import com.openhis.medication.domain.MedicationRequest;
|
import com.openhis.medication.domain.MedicationRequest;
|
||||||
import com.openhis.medication.service.IMedicationDispenseService;
|
import com.openhis.medication.service.IMedicationDispenseService;
|
||||||
import com.openhis.medication.service.IMedicationRequestService;
|
import com.openhis.medication.service.IMedicationRequestService;
|
||||||
@@ -44,6 +45,8 @@ import com.openhis.workflow.service.IActivityDefinitionService;
|
|||||||
import com.openhis.workflow.service.IDeviceDispenseService;
|
import com.openhis.workflow.service.IDeviceDispenseService;
|
||||||
import com.openhis.workflow.service.IDeviceRequestService;
|
import com.openhis.workflow.service.IDeviceRequestService;
|
||||||
import com.openhis.workflow.service.IServiceRequestService;
|
import com.openhis.workflow.service.IServiceRequestService;
|
||||||
|
import com.openhis.workflow.domain.InventoryItem;
|
||||||
|
import com.openhis.workflow.service.IInventoryItemService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -111,6 +114,9 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
@Resource
|
@Resource
|
||||||
IEncounterService iEncounterService;
|
IEncounterService iEncounterService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
IInventoryItemService inventoryItemService;
|
||||||
|
|
||||||
// 缓存 key 前缀
|
// 缓存 key 前缀
|
||||||
private static final String ADVICE_BASE_INFO_CACHE_PREFIX = "advice:base:info:";
|
private static final String ADVICE_BASE_INFO_CACHE_PREFIX = "advice:base:info:";
|
||||||
// 缓存过期时间(小时)
|
// 缓存过期时间(小时)
|
||||||
@@ -135,7 +141,7 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
@Override
|
@Override
|
||||||
public IPage<AdviceBaseDto> getAdviceBaseInfo(AdviceBaseDto adviceBaseDto, String searchKey, Long locationId,
|
public IPage<AdviceBaseDto> getAdviceBaseInfo(AdviceBaseDto adviceBaseDto, String searchKey, Long locationId,
|
||||||
List<Long> adviceDefinitionIdParamList, Long organizationId, Integer pageNo, Integer pageSize,
|
List<Long> adviceDefinitionIdParamList, Long organizationId, Integer pageNo, Integer pageSize,
|
||||||
Integer pricingFlag, List<Integer> adviceTypes, String orderPricing) {
|
Integer pricingFlag, List<Integer> adviceTypes, String orderPricing, String categoryCode) {
|
||||||
|
|
||||||
// 生成缓存键,处理可能的null值
|
// 生成缓存键,处理可能的null值
|
||||||
String safeSearchKey = searchKey != null ? searchKey : "";
|
String safeSearchKey = searchKey != null ? searchKey : "";
|
||||||
@@ -199,11 +205,16 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
// 构建查询条件
|
// 构建查询条件
|
||||||
QueryWrapper<AdviceBaseDto> queryWrapper = HisQueryUtils.buildQueryWrapper(adviceBaseDto, searchKey,
|
QueryWrapper<AdviceBaseDto> queryWrapper = HisQueryUtils.buildQueryWrapper(adviceBaseDto, searchKey,
|
||||||
new HashSet<>(Arrays.asList("advice_name", "py_str", "wb_str")), null);
|
new HashSet<>(Arrays.asList("advice_name", "py_str", "wb_str")), null);
|
||||||
|
// 🔧 BugFix#339: 药房筛选条件失效 - 添加 locationId 过滤条件
|
||||||
|
if (locationId != null) {
|
||||||
|
queryWrapper.eq("location_id", locationId);
|
||||||
|
log.info("BugFix#339: 添加药房筛选条件 locationId={}", locationId);
|
||||||
|
}
|
||||||
IPage<AdviceBaseDto> adviceBaseInfo = doctorStationAdviceAppMapper.getAdviceBaseInfo(
|
IPage<AdviceBaseDto> adviceBaseInfo = doctorStationAdviceAppMapper.getAdviceBaseInfo(
|
||||||
new Page<>(pageNo, pageSize), PublicationStatus.ACTIVE.getValue(), organizationId,
|
new Page<>(pageNo, pageSize), PublicationStatus.ACTIVE.getValue(), organizationId,
|
||||||
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION,
|
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION,
|
||||||
CommonConstants.TableName.WOR_ACTIVITY_DEFINITION, pricingFlag, adviceDefinitionIdParamList,
|
CommonConstants.TableName.WOR_ACTIVITY_DEFINITION, pricingFlag, adviceDefinitionIdParamList,
|
||||||
adviceTypes, searchKey,
|
adviceTypes, searchKey, categoryCode,
|
||||||
queryWrapper);
|
queryWrapper);
|
||||||
List<AdviceBaseDto> adviceBaseDtoList = adviceBaseInfo.getRecords();
|
List<AdviceBaseDto> adviceBaseDtoList = adviceBaseInfo.getRecords();
|
||||||
|
|
||||||
@@ -555,6 +566,25 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
return R.fail(null, "无法获取患者信息,请重新选择患者");
|
return R.fail(null, "无法获取患者信息,请重新选择患者");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🔧 BugFix#338: 门诊划价新增时校验就诊状态和诊断记录(患者安全)
|
||||||
|
// 仅对新增/修改操作进行校验,删除操作不需要
|
||||||
|
if (!DbOpType.DELETE.getCode().equals(adviceSaveDto.getDbOpType())) {
|
||||||
|
// 1. 校验就诊状态:必须是已接诊状态
|
||||||
|
Encounter encounterCheck = iEncounterService.getById(adviceSaveDto.getEncounterId());
|
||||||
|
if (encounterCheck != null) {
|
||||||
|
// 就诊状态:1=待诊(PLANNED),允许保存的状态 = 2(IN_PROGRESS在诊)、3(ON_HOLD暂离)、4(DISCHARGED诊毕)、5(COMPLETED完成)
|
||||||
|
if (encounterCheck.getStatusEnum() != null &&
|
||||||
|
encounterCheck.getStatusEnum() != EncounterStatus.IN_PROGRESS.getValue() &&
|
||||||
|
encounterCheck.getStatusEnum() != EncounterStatus.ON_HOLD.getValue() &&
|
||||||
|
encounterCheck.getStatusEnum() != EncounterStatus.DISCHARGED.getValue() &&
|
||||||
|
encounterCheck.getStatusEnum() != EncounterStatus.COMPLETED.getValue()) {
|
||||||
|
log.error("BugFix#338: 患者未接诊,禁止划价/保存医嘱:encounterId={}, status={}",
|
||||||
|
adviceSaveDto.getEncounterId(), encounterCheck.getStatusEnum());
|
||||||
|
return R.fail(null, "患者尚未接诊,无法保存医嘱。请先完成接诊操作!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 药品(前端adviceType=1)
|
// 药品(前端adviceType=1)
|
||||||
@@ -564,13 +594,15 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
// 耗材(前端adviceType=4,后端ItemType.DEVICE=2)
|
// 耗材(前端adviceType=4,后端ItemType.DEVICE=2)
|
||||||
List<AdviceSaveDto> deviceList = adviceSaveList.stream()
|
List<AdviceSaveDto> deviceList = adviceSaveList.stream()
|
||||||
.filter(e -> ItemType.DEVICE.getValue().equals(e.getAdviceType())
|
.filter(e -> ItemType.DEVICE.getValue().equals(e.getAdviceType())
|
||||||
|| e.getAdviceType() == 4) // 🔧 BugFix: 前端耗材类型值为4
|
|| e.getAdviceType() == 4) // 前端耗材类型值为4
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
// 诊疗活动(包括普通诊疗:前端adviceType=3,会诊:前端adviceType=5)
|
|
||||||
|
// 诊疗活动(前端adviceType=3诊疗、adviceType=5会诊、adviceType=6手术)
|
||||||
List<AdviceSaveDto> activityList = adviceSaveList.stream()
|
List<AdviceSaveDto> activityList = adviceSaveList.stream()
|
||||||
.filter(e -> ItemType.ACTIVITY.getValue().equals(e.getAdviceType())
|
.filter(e -> ItemType.ACTIVITY.getValue().equals(e.getAdviceType())
|
||||||
|| e.getAdviceType() == 3 // 🔧 BugFix: 前端诊疗类型值为3
|
|| e.getAdviceType() == 3 // 前端诊疗类型值为3
|
||||||
|| e.getAdviceType() == 5) // 🔧 BugFix: 前端会诊类型值为5
|
|| e.getAdviceType() == 5 // 前端会诊类型值为5
|
||||||
|
|| ItemType.SURGERY.getValue().equals(e.getAdviceType())) // 🔧 BugFix#318: 手术类型值为6
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
// 🔍 Debug日志: 记录分类结果
|
// 🔍 Debug日志: 记录分类结果
|
||||||
@@ -599,11 +631,12 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
iDeviceDispenseService.deleteDeviceDispense(adviceSaveDto.getRequestId());
|
iDeviceDispenseService.deleteDeviceDispense(adviceSaveDto.getRequestId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🔧 Bug Fix: 跳过耗材的库存校验(耗材的库存校验逻辑不同)
|
// 🔧 Bug Fix: 跳过耗材、诊疗、手术的库存校验
|
||||||
List<AdviceSaveDto> needCheckList = adviceSaveList.stream()
|
List<AdviceSaveDto> needCheckList = adviceSaveList.stream()
|
||||||
.filter(e -> !DbOpType.DELETE.getCode().equals(e.getDbOpType())
|
.filter(e -> !DbOpType.DELETE.getCode().equals(e.getDbOpType())
|
||||||
&& !ItemType.ACTIVITY.getValue().equals(e.getAdviceType())
|
&& !ItemType.ACTIVITY.getValue().equals(e.getAdviceType())
|
||||||
&& !ItemType.DEVICE.getValue().equals(e.getAdviceType())) // 排除耗材
|
&& !ItemType.DEVICE.getValue().equals(e.getAdviceType())
|
||||||
|
&& !ItemType.SURGERY.getValue().equals(e.getAdviceType())) // 🔧 BugFix#318: 排除手术类型
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
// 校验库存
|
// 校验库存
|
||||||
String tipRes = adviceUtils.checkInventory(needCheckList);
|
String tipRes = adviceUtils.checkInventory(needCheckList);
|
||||||
@@ -641,11 +674,13 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
// 就诊id
|
// 就诊id
|
||||||
Long encounterId = adviceSaveList.get(0).getEncounterId();
|
Long encounterId = adviceSaveList.get(0).getEncounterId();
|
||||||
iChargeItemService.update(new LambdaUpdateWrapper<ChargeItem>()
|
|
||||||
.set(ChargeItem::getStatusEnum, ChargeItemStatus.PLANNED.getValue())
|
// 使用安全的更新方法,避免并发冲突
|
||||||
.eq(ChargeItem::getEncounterId, encounterId)
|
iChargeItemService.updateChargeStatusByConditionSafe(
|
||||||
.eq(ChargeItem::getStatusEnum, ChargeItemStatus.DRAFT.getValue())
|
encounterId,
|
||||||
.in(ChargeItem::getServiceId, requestIds));
|
ChargeItemStatus.DRAFT.getValue(),
|
||||||
|
ChargeItemStatus.PLANNED.getValue(),
|
||||||
|
requestIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 数据变更后清理相关缓存
|
// 数据变更后清理相关缓存
|
||||||
@@ -737,6 +772,40 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
|
|
||||||
List<String> medRequestIdList = new ArrayList<>();
|
List<String> medRequestIdList = new ArrayList<>();
|
||||||
for (AdviceSaveDto adviceSaveDto : insertOrUpdateList) {
|
for (AdviceSaveDto adviceSaveDto : insertOrUpdateList) {
|
||||||
|
// 🔧 Bug Fix: 确保accountId不为null,与handleBoundDevices保持一致
|
||||||
|
if (adviceSaveDto.getAccountId() == null) {
|
||||||
|
// 尝试从患者就诊中获取默认账户ID(自费账户)
|
||||||
|
Account selfAccount = iAccountService.getSelfAccount(adviceSaveDto.getEncounterId());
|
||||||
|
if (selfAccount != null) {
|
||||||
|
adviceSaveDto.setAccountId(selfAccount.getId());
|
||||||
|
} else {
|
||||||
|
// 自动创建自费账户
|
||||||
|
Account newAccount = new Account();
|
||||||
|
newAccount.setPatientId(adviceSaveDto.getPatientId());
|
||||||
|
newAccount.setEncounterId(adviceSaveDto.getEncounterId());
|
||||||
|
newAccount.setContractNo(CommonConstants.BusinessName.DEFAULT_CONTRACT_NO);
|
||||||
|
newAccount.setTypeCode(AccountType.PERSONAL_CASH_ACCOUNT.getCode());
|
||||||
|
newAccount.setBalanceAmount(BigDecimal.ZERO);
|
||||||
|
newAccount.setStatusEnum(AccountStatus.ACTIVE.getValue());
|
||||||
|
newAccount.setEncounterFlag(Whether.YES.getValue());
|
||||||
|
newAccount.setName(AccountType.PERSONAL_CASH_ACCOUNT.getInfo());
|
||||||
|
Long newAccountId = iAccountService.saveAccountByRegister(newAccount);
|
||||||
|
adviceSaveDto.setAccountId(newAccountId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔧 Bug Fix: 确保practitionerId不为null
|
||||||
|
if (adviceSaveDto.getPractitionerId() == null) {
|
||||||
|
adviceSaveDto.setPractitionerId(SecurityUtils.getLoginUser().getPractitionerId());
|
||||||
|
log.info("handMedication - 自动补全practitionerId: practitionerId={}", adviceSaveDto.getPractitionerId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔧 Bug Fix: 确保founderOrgId不为null
|
||||||
|
if (adviceSaveDto.getFounderOrgId() == null) {
|
||||||
|
adviceSaveDto.setFounderOrgId(SecurityUtils.getLoginUser().getOrgId());
|
||||||
|
log.info("handMedication - 自动补全founderOrgId: founderOrgId={}", adviceSaveDto.getFounderOrgId());
|
||||||
|
}
|
||||||
|
|
||||||
boolean firstTimeSave = false;// 第一次保存
|
boolean firstTimeSave = false;// 第一次保存
|
||||||
medicationRequest = new MedicationRequest();
|
medicationRequest = new MedicationRequest();
|
||||||
medicationRequest.setId(adviceSaveDto.getRequestId()); // 主键id
|
medicationRequest.setId(adviceSaveDto.getRequestId()); // 主键id
|
||||||
@@ -899,13 +968,20 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
// 处理耗材发放
|
// 处理耗材发放
|
||||||
Long dispenseId = iDeviceDispenseService.handleDeviceDispense(deviceRequest, DbOpType.INSERT.getCode());
|
Long dispenseId = iDeviceDispenseService.handleDeviceDispense(deviceRequest, DbOpType.INSERT.getCode());
|
||||||
|
|
||||||
// 查询耗材定价信息
|
// 查询耗材定价信息 - 直接使用mapper查询,避免递归调用getAdviceBaseInfo导致栈溢出
|
||||||
AdviceBaseDto deviceAdviceDto = new AdviceBaseDto();
|
IPage<AdviceBaseDto> devicePage = doctorStationAdviceAppMapper.getAdviceBaseInfo(
|
||||||
deviceAdviceDto.setAdviceDefinitionId(boundDevice.getDevActId());
|
new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(1, 1),
|
||||||
deviceAdviceDto.setAdviceTableName(CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
PublicationStatus.ACTIVE.getValue(),
|
||||||
IPage<AdviceBaseDto> devicePage = getAdviceBaseInfo(deviceAdviceDto, null, null, null,
|
adviceSaveDto.getFounderOrgId(),
|
||||||
adviceSaveDto.getFounderOrgId(), 1, 1, Whether.NO.getValue(),
|
null,
|
||||||
List.of(ItemType.DEVICE.getValue()), null);
|
CommonConstants.TableName.ADM_DEVICE_DEFINITION,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
List.of(boundDevice.getDevActId()),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null);
|
||||||
|
|
||||||
if (devicePage == null || devicePage.getRecords().isEmpty()) {
|
if (devicePage == null || devicePage.getRecords().isEmpty()) {
|
||||||
log.warn("无法找到耗材定价信息: deviceDefId={}", boundDevice.getDevActId());
|
log.warn("无法找到耗材定价信息: deviceDefId={}", boundDevice.getDevActId());
|
||||||
@@ -913,12 +989,19 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
}
|
}
|
||||||
|
|
||||||
AdviceBaseDto deviceBaseInfo = devicePage.getRecords().get(0);
|
AdviceBaseDto deviceBaseInfo = devicePage.getRecords().get(0);
|
||||||
if (deviceBaseInfo.getPriceList() == null || deviceBaseInfo.getPriceList().isEmpty()) {
|
|
||||||
|
// 查询价格信息 - 直接查询定价主表
|
||||||
|
List<AdvicePriceDto> mainCharge = doctorStationAdviceAppMapper.getMainCharge(
|
||||||
|
List.of(deviceBaseInfo.getChargeItemDefinitionId()), PublicationStatus.ACTIVE.getValue());
|
||||||
|
|
||||||
|
if (mainCharge == null || mainCharge.isEmpty()) {
|
||||||
log.warn("耗材没有定价信息: deviceDefId={}", boundDevice.getDevActId());
|
log.warn("耗材没有定价信息: deviceDefId={}", boundDevice.getDevActId());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
AdvicePriceDto devicePrice = deviceBaseInfo.getPriceList().get(0);
|
AdvicePriceDto devicePrice = mainCharge.get(0);
|
||||||
|
devicePrice.setDefinitionId(deviceBaseInfo.getChargeItemDefinitionId());
|
||||||
|
// 如果需要定价子表ID,可以从mainCharge中获取
|
||||||
|
|
||||||
// 创建耗材费用项
|
// 创建耗材费用项
|
||||||
ChargeItem deviceChargeItem = new ChargeItem();
|
ChargeItem deviceChargeItem = new ChargeItem();
|
||||||
@@ -941,7 +1024,29 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
deviceChargeItem.setServiceId(deviceRequest.getId());
|
deviceChargeItem.setServiceId(deviceRequest.getId());
|
||||||
deviceChargeItem.setProductTable(CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
deviceChargeItem.setProductTable(CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
||||||
deviceChargeItem.setProductId(boundDevice.getDevActId());
|
deviceChargeItem.setProductId(boundDevice.getDevActId());
|
||||||
deviceChargeItem.setAccountId(adviceSaveDto.getAccountId());
|
// 🔧 Bug Fix #281: 如果accountId为null,从就诊中获取账户ID,如果没有则自动创建
|
||||||
|
Long deviceAccountId = adviceSaveDto.getAccountId();
|
||||||
|
if (deviceAccountId == null) {
|
||||||
|
// 尝试从患者就诊中获取默认账户ID(自费账户)
|
||||||
|
Account selfAccount = iAccountService.getSelfAccount(adviceSaveDto.getEncounterId());
|
||||||
|
if (selfAccount != null) {
|
||||||
|
deviceAccountId = selfAccount.getId();
|
||||||
|
} else {
|
||||||
|
// 自动创建自费账户
|
||||||
|
Account newAccount = new Account();
|
||||||
|
newAccount.setPatientId(adviceSaveDto.getPatientId());
|
||||||
|
newAccount.setEncounterId(adviceSaveDto.getEncounterId());
|
||||||
|
newAccount.setContractNo(CommonConstants.BusinessName.DEFAULT_CONTRACT_NO);
|
||||||
|
newAccount.setTypeCode(AccountType.PERSONAL_CASH_ACCOUNT.getCode());
|
||||||
|
newAccount.setBalanceAmount(BigDecimal.ZERO);
|
||||||
|
newAccount.setStatusEnum(AccountStatus.ACTIVE.getValue());
|
||||||
|
newAccount.setEncounterFlag(Whether.YES.getValue());
|
||||||
|
// 🔧 Bug Fix: 设置账户名称,避免数据库NOT NULL约束错误
|
||||||
|
newAccount.setName(AccountType.PERSONAL_CASH_ACCOUNT.getInfo());
|
||||||
|
deviceAccountId = iAccountService.saveAccountByRegister(newAccount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deviceChargeItem.setAccountId(deviceAccountId);
|
||||||
deviceChargeItem.setConditionId(adviceSaveDto.getConditionId());
|
deviceChargeItem.setConditionId(adviceSaveDto.getConditionId());
|
||||||
deviceChargeItem.setEncounterDiagnosisId(adviceSaveDto.getEncounterDiagnosisId());
|
deviceChargeItem.setEncounterDiagnosisId(adviceSaveDto.getEncounterDiagnosisId());
|
||||||
deviceChargeItem.setDispenseId(dispenseId);
|
deviceChargeItem.setDispenseId(dispenseId);
|
||||||
@@ -1060,6 +1165,40 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
log.info("BugFix#219: ========== handDevice END ==========");
|
log.info("BugFix#219: ========== handDevice END ==========");
|
||||||
|
|
||||||
for (AdviceSaveDto adviceSaveDto : insertOrUpdateList) {
|
for (AdviceSaveDto adviceSaveDto : insertOrUpdateList) {
|
||||||
|
// 🔧 Bug Fix: 确保accountId不为null
|
||||||
|
if (adviceSaveDto.getAccountId() == null) {
|
||||||
|
// 尝试从患者就诊中获取默认账户ID(自费账户)
|
||||||
|
Account selfAccount = iAccountService.getSelfAccount(adviceSaveDto.getEncounterId());
|
||||||
|
if (selfAccount != null) {
|
||||||
|
adviceSaveDto.setAccountId(selfAccount.getId());
|
||||||
|
} else {
|
||||||
|
// 自动创建自费账户
|
||||||
|
Account newAccount = new Account();
|
||||||
|
newAccount.setPatientId(adviceSaveDto.getPatientId());
|
||||||
|
newAccount.setEncounterId(adviceSaveDto.getEncounterId());
|
||||||
|
newAccount.setContractNo(CommonConstants.BusinessName.DEFAULT_CONTRACT_NO);
|
||||||
|
newAccount.setTypeCode(AccountType.PERSONAL_CASH_ACCOUNT.getCode());
|
||||||
|
newAccount.setBalanceAmount(BigDecimal.ZERO);
|
||||||
|
newAccount.setStatusEnum(AccountStatus.ACTIVE.getValue());
|
||||||
|
newAccount.setEncounterFlag(Whether.YES.getValue());
|
||||||
|
newAccount.setName(AccountType.PERSONAL_CASH_ACCOUNT.getInfo());
|
||||||
|
Long newAccountId = iAccountService.saveAccountByRegister(newAccount);
|
||||||
|
adviceSaveDto.setAccountId(newAccountId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔧 Bug Fix: 确保practitionerId不为null
|
||||||
|
if (adviceSaveDto.getPractitionerId() == null) {
|
||||||
|
adviceSaveDto.setPractitionerId(SecurityUtils.getLoginUser().getPractitionerId());
|
||||||
|
log.info("自动补全practitionerId: practitionerId={}", adviceSaveDto.getPractitionerId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔧 Bug Fix: 确保founderOrgId不为null
|
||||||
|
if (adviceSaveDto.getFounderOrgId() == null) {
|
||||||
|
adviceSaveDto.setFounderOrgId(SecurityUtils.getLoginUser().getOrgId());
|
||||||
|
log.info("自动补全founderOrgId: founderOrgId={}", adviceSaveDto.getFounderOrgId());
|
||||||
|
}
|
||||||
|
|
||||||
deviceRequest = new DeviceRequest();
|
deviceRequest = new DeviceRequest();
|
||||||
deviceRequest.setId(adviceSaveDto.getRequestId()); // 主键id
|
deviceRequest.setId(adviceSaveDto.getRequestId()); // 主键id
|
||||||
deviceRequest.setStatusEnum(is_save ? RequestStatus.DRAFT.getValue() : RequestStatus.ACTIVE.getValue()); // 请求状态
|
deviceRequest.setStatusEnum(is_save ? RequestStatus.DRAFT.getValue() : RequestStatus.ACTIVE.getValue()); // 请求状态
|
||||||
@@ -1124,6 +1263,47 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
chargeItem.setServiceId(deviceRequest.getId()); // 医疗服务ID
|
chargeItem.setServiceId(deviceRequest.getId()); // 医疗服务ID
|
||||||
chargeItem.setProductTable(adviceSaveDto.getAdviceTableName());// 产品所在表
|
chargeItem.setProductTable(adviceSaveDto.getAdviceTableName());// 产品所在表
|
||||||
chargeItem.setProductId(adviceSaveDto.getAdviceDefinitionId());// 收费项id
|
chargeItem.setProductId(adviceSaveDto.getAdviceDefinitionId());// 收费项id
|
||||||
|
|
||||||
|
// 🔧 Bug Fix: 如果 definitionId 或 definitionDetailId 为 null,从定价信息中获取
|
||||||
|
if (chargeItem.getDefinitionId() == null || chargeItem.getDefDetailId() == null) {
|
||||||
|
log.warn("耗材的 definitionId 或 definitionDetailId 为 null,尝试从定价信息中获取: deviceDefId={}",
|
||||||
|
adviceSaveDto.getAdviceDefinitionId());
|
||||||
|
// 查询耗材定价信息
|
||||||
|
IPage<AdviceBaseDto> devicePage = doctorStationAdviceAppMapper.getAdviceBaseInfo(
|
||||||
|
new Page<>(1, 1),
|
||||||
|
PublicationStatus.ACTIVE.getValue(),
|
||||||
|
orgId,
|
||||||
|
CommonConstants.TableName.ADM_DEVICE_DEFINITION,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
Arrays.asList(adviceSaveDto.getAdviceDefinitionId()),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null);
|
||||||
|
if (devicePage != null && !devicePage.getRecords().isEmpty()) {
|
||||||
|
AdviceBaseDto deviceBaseInfo = devicePage.getRecords().get(0);
|
||||||
|
if (deviceBaseInfo.getPriceList() != null && !deviceBaseInfo.getPriceList().isEmpty()) {
|
||||||
|
AdvicePriceDto devicePrice = deviceBaseInfo.getPriceList().get(0);
|
||||||
|
if (chargeItem.getDefinitionId() == null) {
|
||||||
|
chargeItem.setDefinitionId(devicePrice.getDefinitionId());
|
||||||
|
log.info("从定价信息中获取 definitionId: {}", devicePrice.getDefinitionId());
|
||||||
|
}
|
||||||
|
if (chargeItem.getDefDetailId() == null) {
|
||||||
|
chargeItem.setDefDetailId(devicePrice.getDefinitionDetailId());
|
||||||
|
log.info("从定价信息中获取 definitionDetailId: {}", devicePrice.getDefinitionDetailId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔧 Bug Fix: 确保定义ID不为null
|
||||||
|
if (chargeItem.getDefinitionId() == null) {
|
||||||
|
log.error("无法获取耗材的 definitionId: deviceDefId={}", adviceSaveDto.getAdviceDefinitionId());
|
||||||
|
throw new ServiceException("无法获取耗材的定价信息,请联系管理员");
|
||||||
|
}
|
||||||
|
|
||||||
// 🔧 Bug Fix: 如果accountId为null,从就诊中获取账户ID,如果没有则自动创建
|
// 🔧 Bug Fix: 如果accountId为null,从就诊中获取账户ID,如果没有则自动创建
|
||||||
Long accountId = adviceSaveDto.getAccountId();
|
Long accountId = adviceSaveDto.getAccountId();
|
||||||
if (accountId == null) {
|
if (accountId == null) {
|
||||||
@@ -1141,6 +1321,8 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
newAccount.setBalanceAmount(BigDecimal.ZERO);
|
newAccount.setBalanceAmount(BigDecimal.ZERO);
|
||||||
newAccount.setStatusEnum(AccountStatus.ACTIVE.getValue());
|
newAccount.setStatusEnum(AccountStatus.ACTIVE.getValue());
|
||||||
newAccount.setEncounterFlag(Whether.YES.getValue());
|
newAccount.setEncounterFlag(Whether.YES.getValue());
|
||||||
|
// 🔧 Bug Fix: 设置账户名称,避免数据库NOT NULL约束错误
|
||||||
|
newAccount.setName(AccountType.PERSONAL_CASH_ACCOUNT.getInfo());
|
||||||
accountId = iAccountService.saveAccountByRegister(newAccount);
|
accountId = iAccountService.saveAccountByRegister(newAccount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1222,6 +1404,40 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (AdviceSaveDto adviceSaveDto : insertOrUpdateList) {
|
for (AdviceSaveDto adviceSaveDto : insertOrUpdateList) {
|
||||||
|
// 🔧 Bug Fix: 确保accountId不为null
|
||||||
|
if (adviceSaveDto.getAccountId() == null) {
|
||||||
|
// 尝试从患者就诊中获取默认账户ID(自费账户)
|
||||||
|
Account selfAccount = iAccountService.getSelfAccount(adviceSaveDto.getEncounterId());
|
||||||
|
if (selfAccount != null) {
|
||||||
|
adviceSaveDto.setAccountId(selfAccount.getId());
|
||||||
|
} else {
|
||||||
|
// 自动创建自费账户
|
||||||
|
Account newAccount = new Account();
|
||||||
|
newAccount.setPatientId(adviceSaveDto.getPatientId());
|
||||||
|
newAccount.setEncounterId(adviceSaveDto.getEncounterId());
|
||||||
|
newAccount.setContractNo(CommonConstants.BusinessName.DEFAULT_CONTRACT_NO);
|
||||||
|
newAccount.setTypeCode(AccountType.PERSONAL_CASH_ACCOUNT.getCode());
|
||||||
|
newAccount.setBalanceAmount(BigDecimal.ZERO);
|
||||||
|
newAccount.setStatusEnum(AccountStatus.ACTIVE.getValue());
|
||||||
|
newAccount.setEncounterFlag(Whether.YES.getValue());
|
||||||
|
newAccount.setName(AccountType.PERSONAL_CASH_ACCOUNT.getInfo());
|
||||||
|
Long newAccountId = iAccountService.saveAccountByRegister(newAccount);
|
||||||
|
adviceSaveDto.setAccountId(newAccountId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔧 Bug Fix: 确保practitionerId不为null
|
||||||
|
if (adviceSaveDto.getPractitionerId() == null) {
|
||||||
|
adviceSaveDto.setPractitionerId(SecurityUtils.getLoginUser().getPractitionerId());
|
||||||
|
log.info("handService - 自动补全practitionerId: practitionerId={}", adviceSaveDto.getPractitionerId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔧 Bug Fix: 确保founderOrgId不为null
|
||||||
|
if (adviceSaveDto.getFounderOrgId() == null) {
|
||||||
|
adviceSaveDto.setFounderOrgId(SecurityUtils.getLoginUser().getOrgId());
|
||||||
|
log.info("handService - 自动补全founderOrgId: founderOrgId={}", adviceSaveDto.getFounderOrgId());
|
||||||
|
}
|
||||||
|
|
||||||
// 🔧 Bug Fix #238: 诊疗项目执行科室非空校验
|
// 🔧 Bug Fix #238: 诊疗项目执行科室非空校验
|
||||||
if (adviceSaveDto.getAdviceType() != null && adviceSaveDto.getAdviceType() == 3) {
|
if (adviceSaveDto.getAdviceType() != null && adviceSaveDto.getAdviceType() == 3) {
|
||||||
Long effectiveOrgId = adviceSaveDto.getEffectiveOrgId();
|
Long effectiveOrgId = adviceSaveDto.getEffectiveOrgId();
|
||||||
@@ -1333,26 +1549,35 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
|
|
||||||
// 只有在签发时
|
// 只有在签发时
|
||||||
if (is_sign) {
|
if (is_sign) {
|
||||||
// 发送跨系统申请
|
// 发送跨系统申请 - 已注释,项目未使用LIS/PACS系统
|
||||||
adviceSaveDto.setRequestId(serviceRequest.getId());
|
// adviceSaveDto.setRequestId(serviceRequest.getId());
|
||||||
try {
|
// try {
|
||||||
// 查询诊疗定义
|
// // 查询诊疗定义
|
||||||
ActivityDefinition activityDefinition
|
// ActivityDefinition activityDefinition
|
||||||
= iActivityDefinitionService.getById(adviceSaveDto.getAdviceDefinitionId());
|
// = iActivityDefinitionService.getById(adviceSaveDto.getAdviceDefinitionId());
|
||||||
if (activityDefinition != null) {
|
// if (activityDefinition != null) {
|
||||||
// 检验 或 检查
|
// // 检验 或 检查
|
||||||
if (ActivityType.PROOF.getValue().equals(activityDefinition.getTypeEnum())
|
// if (ActivityType.PROOF.getValue().equals(activityDefinition.getTypeEnum())
|
||||||
|| ActivityType.TEST.getValue().equals(activityDefinition.getTypeEnum())) {
|
// || ActivityType.TEST.getValue().equals(activityDefinition.getTypeEnum())) {
|
||||||
doctorStationSendApplyUtil.sendCrossSystemApply(adviceSaveDto, organizationId, curDate);
|
// doctorStationSendApplyUtil.sendCrossSystemApply(adviceSaveDto, organizationId, curDate);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// if (!Whether.YES.getCode()
|
||||||
|
// .equals(TenantOptionUtil.getOptionContent(TenantOptionDict.LIS_PACS_ERROR_IGNORE))) {
|
||||||
|
// throw e;
|
||||||
|
// }
|
||||||
|
// log.error(e.getMessage(), e);
|
||||||
|
// }
|
||||||
|
// 签发时将收费项目状态从草稿改为待收费
|
||||||
|
Long chargeItemId = adviceSaveDto.getChargeItemId();
|
||||||
|
if (chargeItemId != null) {
|
||||||
|
ChargeItem existingChargeItem = iChargeItemService.getById(chargeItemId);
|
||||||
|
if (existingChargeItem != null) {
|
||||||
|
existingChargeItem.setStatusEnum(ChargeItemStatus.PLANNED.getValue());
|
||||||
|
iChargeItemService.updateById(existingChargeItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
if (!Whether.YES.getCode()
|
|
||||||
.equals(TenantOptionUtil.getOptionContent(TenantOptionDict.LIS_PACS_ERROR_IGNORE))) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
log.error(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1417,15 +1642,60 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
iChargeItemService.updatePaymentStatus(chargeItemIdList, ChargeItemStatus.DRAFT.getValue());
|
iChargeItemService.updatePaymentStatus(chargeItemIdList, ChargeItemStatus.DRAFT.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🔧 BugFix: 直接对所有requestId进行作废操作
|
// 🔧 新增:签退时回滚库存
|
||||||
log.info("BugFix#219: signOffAdvice - 作废所有请求, requestIdList={}", requestIdList);
|
// 查询已发放的药品记录(用于回滚库存)
|
||||||
|
List<MedicationDispense> dispensedList = iMedicationDispenseService.list(
|
||||||
|
new LambdaQueryWrapper<MedicationDispense>()
|
||||||
|
.in(MedicationDispense::getMedReqId, requestIdList)
|
||||||
|
.eq(MedicationDispense::getStatusEnum, DispenseStatus.COMPLETED.getValue())
|
||||||
|
);
|
||||||
|
|
||||||
// 尝试作废药品请求(只有存在的才会更新)
|
if (dispensedList != null && !dispensedList.isEmpty()) {
|
||||||
iMedicationRequestService.updateCancelledStatusBatch(requestIdList, null, null);
|
// 需要回滚的库存列表
|
||||||
// 尝试作废耗材请求(只有存在的才会更新)
|
List<InventoryItem> inventoryUpdateList = new ArrayList<>();
|
||||||
iDeviceRequestService.updateCancelledStatusBatch(requestIdList);
|
|
||||||
// 尝试作废诊疗请求(只有存在的才会更新)
|
for (MedicationDispense dispense : dispensedList) {
|
||||||
iServiceRequestService.updateCancelledStatusBatch(requestIdList);
|
// 查询对应的库存记录(根据批号和药品ID)
|
||||||
|
if (dispense.getMedicationId() != null && dispense.getLotNumber() != null) {
|
||||||
|
InventoryItem inventoryItem = inventoryItemService.getOne(
|
||||||
|
new LambdaQueryWrapper<InventoryItem>()
|
||||||
|
.eq(InventoryItem::getItemId, dispense.getMedicationId())
|
||||||
|
.eq(InventoryItem::getLotNumber, dispense.getLotNumber())
|
||||||
|
);
|
||||||
|
|
||||||
|
if (inventoryItem != null) {
|
||||||
|
// 计算回滚后的数量(加上已发放的数量)
|
||||||
|
BigDecimal currentQuantity = inventoryItem.getQuantity() != null ? inventoryItem.getQuantity() : BigDecimal.ZERO;
|
||||||
|
BigDecimal dispenseQuantity = dispense.getQuantity() != null ? dispense.getQuantity() : BigDecimal.ZERO;
|
||||||
|
inventoryUpdateList.add(new InventoryItem()
|
||||||
|
.setId(inventoryItem.getId())
|
||||||
|
.setQuantity(currentQuantity.add(dispenseQuantity))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新发药记录状态为已退药
|
||||||
|
dispense.setStatusEnum(DispenseStatus.RETURNED.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量更新库存(回滚数量)
|
||||||
|
if (!inventoryUpdateList.isEmpty()) {
|
||||||
|
inventoryItemService.updateBatchById(inventoryUpdateList);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新发药记录状态
|
||||||
|
iMedicationDispenseService.updateBatchById(dispensedList);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔧 BugFix: 直接对所有requestId进行签退操作,将状态改为待签发
|
||||||
|
log.info("BugFix: signOffAdvice - 签退所有请求,状态改为待签发, requestIdList={}", requestIdList);
|
||||||
|
|
||||||
|
// 尝试签退药品请求(只有存在的才会更新)
|
||||||
|
iMedicationRequestService.updateDraftStatusBatch(requestIdList, null, null);
|
||||||
|
// 尝试签退耗材请求(只有存在的才会更新)
|
||||||
|
iDeviceRequestService.updateDraftStatusBatch(requestIdList);
|
||||||
|
// 尝试签退诊疗请求(只有存在的才会更新)
|
||||||
|
iServiceRequestService.updateDraftStatusBatch(requestIdList);
|
||||||
|
|
||||||
log.info("BugFix#219: signOffAdvice - 所有请求作废完成");
|
log.info("BugFix#219: signOffAdvice - 所有请求作废完成");
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,10 @@ import com.core.common.utils.AssignSeqUtil;
|
|||||||
import com.core.common.utils.MessageUtils;
|
import com.core.common.utils.MessageUtils;
|
||||||
import com.core.common.utils.SecurityUtils;
|
import com.core.common.utils.SecurityUtils;
|
||||||
import com.core.common.utils.StringUtils;
|
import com.core.common.utils.StringUtils;
|
||||||
|
import com.openhis.administration.domain.Account;
|
||||||
import com.openhis.administration.domain.ChargeItem;
|
import com.openhis.administration.domain.ChargeItem;
|
||||||
import com.openhis.administration.domain.EncounterDiagnosis;
|
import com.openhis.administration.domain.EncounterDiagnosis;
|
||||||
|
import com.openhis.administration.service.IAccountService;
|
||||||
import com.openhis.administration.service.IChargeItemService;
|
import com.openhis.administration.service.IChargeItemService;
|
||||||
import com.openhis.administration.service.IEncounterDiagnosisService;
|
import com.openhis.administration.service.IEncounterDiagnosisService;
|
||||||
import com.openhis.clinical.domain.Condition;
|
import com.openhis.clinical.domain.Condition;
|
||||||
@@ -80,6 +82,9 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
|
|||||||
@Resource
|
@Resource
|
||||||
AdviceUtils adviceUtils;
|
AdviceUtils adviceUtils;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
IAccountService iAccountService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询中医诊断数据
|
* 查询中医诊断数据
|
||||||
*
|
*
|
||||||
@@ -364,7 +369,7 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
|
|||||||
adviceBaseDto.setAdviceType(1); // 医嘱类型为药品
|
adviceBaseDto.setAdviceType(1); // 医嘱类型为药品
|
||||||
adviceBaseDto.setCategoryCode(MedCategoryCode.CHINESE_HERBAL_MEDICINE.getValue());// 中草药
|
adviceBaseDto.setCategoryCode(MedCategoryCode.CHINESE_HERBAL_MEDICINE.getValue());// 中草药
|
||||||
return iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, searchKey, locationId,
|
return iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, searchKey, locationId,
|
||||||
adviceDefinitionIdParamList, organizationId, pageNo, pageSize, pricingFlag, List.of(1, 2, 3), null);
|
adviceDefinitionIdParamList, organizationId, pageNo, pageSize, pricingFlag, List.of(1, 2, 3), null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -475,6 +480,28 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
|
|||||||
// 医嘱签发编码
|
// 医嘱签发编码
|
||||||
String signCode = assignSeqUtil.getSeq(AssignSeqEnum.ADVICE_SIGN.getPrefix(), 10);
|
String signCode = assignSeqUtil.getSeq(AssignSeqEnum.ADVICE_SIGN.getPrefix(), 10);
|
||||||
for (AdviceSaveDto adviceSaveDto : insertOrUpdateList) {
|
for (AdviceSaveDto adviceSaveDto : insertOrUpdateList) {
|
||||||
|
// 🔧 Bug Fix: 确保accountId不为null
|
||||||
|
if (adviceSaveDto.getAccountId() == null) {
|
||||||
|
// 尝试从患者就诊中获取默认账户ID(自费账户)
|
||||||
|
Account selfAccount = iAccountService.getSelfAccount(adviceSaveDto.getEncounterId());
|
||||||
|
if (selfAccount != null) {
|
||||||
|
adviceSaveDto.setAccountId(selfAccount.getId());
|
||||||
|
} else {
|
||||||
|
// 自动创建自费账户
|
||||||
|
Account newAccount = new Account();
|
||||||
|
newAccount.setPatientId(adviceSaveDto.getPatientId());
|
||||||
|
newAccount.setEncounterId(adviceSaveDto.getEncounterId());
|
||||||
|
newAccount.setContractNo(CommonConstants.BusinessName.DEFAULT_CONTRACT_NO);
|
||||||
|
newAccount.setTypeCode(AccountType.PERSONAL_CASH_ACCOUNT.getCode());
|
||||||
|
newAccount.setBalanceAmount(BigDecimal.ZERO);
|
||||||
|
newAccount.setStatusEnum(AccountStatus.ACTIVE.getValue());
|
||||||
|
newAccount.setEncounterFlag(Whether.YES.getValue());
|
||||||
|
newAccount.setName(AccountType.PERSONAL_CASH_ACCOUNT.getInfo());
|
||||||
|
Long newAccountId = iAccountService.saveAccountByRegister(newAccount);
|
||||||
|
adviceSaveDto.setAccountId(newAccountId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 中药付数
|
// 中药付数
|
||||||
BigDecimal chineseHerbsDoseQuantity = adviceSaveDto.getChineseHerbsDoseQuantity();
|
BigDecimal chineseHerbsDoseQuantity = adviceSaveDto.getChineseHerbsDoseQuantity();
|
||||||
medicationRequest = new MedicationRequest();
|
medicationRequest = new MedicationRequest();
|
||||||
@@ -586,7 +613,7 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
|
|||||||
|
|
||||||
// 对应的诊疗医嘱信息
|
// 对应的诊疗医嘱信息
|
||||||
AdviceBaseDto activityAdviceBaseDto = iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, null,
|
AdviceBaseDto activityAdviceBaseDto = iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, null,
|
||||||
null, null, organizationId, 1, 1, Whether.NO.getValue(), List.of(3), null).getRecords().get(0);
|
null, null, organizationId, 1, 1, Whether.NO.getValue(), List.of(3), null, null).getRecords().get(0);
|
||||||
if (activityAdviceBaseDto != null) {
|
if (activityAdviceBaseDto != null) {
|
||||||
// 费用定价
|
// 费用定价
|
||||||
AdvicePriceDto advicePriceDto = activityAdviceBaseDto.getPriceList().get(0);
|
AdvicePriceDto advicePriceDto = activityAdviceBaseDto.getPriceList().get(0);
|
||||||
|
|||||||
@@ -273,12 +273,28 @@ public class DoctorStationDiagnosisAppServiceImpl implements IDoctorStationDiagn
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public R<?> saveDoctorDiagnosisNew(SaveDiagnosisParam saveDiagnosisParam) {
|
public R<?> saveDoctorDiagnosisNew(SaveDiagnosisParam saveDiagnosisParam) {
|
||||||
|
// 参数校验:确保诊断列表不为空
|
||||||
|
if (saveDiagnosisParam == null) {
|
||||||
|
return R.fail(MessageUtils.message(PromptMsgConstant.Common.M00009, new Object[] { "保存诊断参数" }));
|
||||||
|
}
|
||||||
|
|
||||||
// 患者id
|
// 患者id
|
||||||
Long patientId = saveDiagnosisParam.getPatientId();
|
Long patientId = saveDiagnosisParam.getPatientId();
|
||||||
// 就诊ID
|
// 就诊ID
|
||||||
Long encounterId = saveDiagnosisParam.getEncounterId();
|
Long encounterId = saveDiagnosisParam.getEncounterId();
|
||||||
// 诊断定义集合
|
// 诊断定义集合
|
||||||
List<SaveDiagnosisChildParam> diagnosisChildList = saveDiagnosisParam.getDiagnosisChildList();
|
List<SaveDiagnosisChildParam> diagnosisChildList = saveDiagnosisParam.getDiagnosisChildList();
|
||||||
|
|
||||||
|
// 校验患者ID和就诊ID
|
||||||
|
if (patientId == null || encounterId == null) {
|
||||||
|
return R.fail(MessageUtils.message(PromptMsgConstant.Common.M00009, new Object[] { "患者ID或就诊ID" }));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验诊断列表不为空
|
||||||
|
if (diagnosisChildList == null || diagnosisChildList.isEmpty()) {
|
||||||
|
return R.fail(MessageUtils.message(PromptMsgConstant.Common.M00009, new Object[] { "诊断列表" }));
|
||||||
|
}
|
||||||
|
|
||||||
// 先删除再保存
|
// 先删除再保存
|
||||||
// iEncounterDiagnosisService.deleteEncounterDiagnosisInfos(encounterId);
|
// iEncounterDiagnosisService.deleteEncounterDiagnosisInfos(encounterId);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.openhis.web.doctorstation.appservice.impl;
|
package com.openhis.web.doctorstation.appservice.impl;
|
||||||
|
|
||||||
import com.core.common.core.domain.R;
|
import com.core.common.core.domain.R;
|
||||||
|
import com.core.common.core.redis.RedisCache;
|
||||||
import com.core.common.enums.DelFlag;
|
import com.core.common.enums.DelFlag;
|
||||||
import com.core.common.utils.SecurityUtils;
|
import com.core.common.utils.SecurityUtils;
|
||||||
import com.openhis.common.enums.DbOpType;
|
import com.openhis.common.enums.DbOpType;
|
||||||
@@ -35,6 +36,8 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|||||||
import com.github.pagehelper.PageHelper;
|
import com.github.pagehelper.PageHelper;
|
||||||
import com.github.pagehelper.PageInfo;
|
import com.github.pagehelper.PageInfo;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -76,6 +79,9 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IServiceRequestService serviceRequestService;
|
private IServiceRequestService serviceRequestService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisCache redisCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存检验申请单信息
|
* 保存检验申请单信息
|
||||||
* @param doctorStationLabApplyDto
|
* @param doctorStationLabApplyDto
|
||||||
@@ -88,8 +94,39 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
|
|||||||
* 保存检验申请单信息逻辑
|
* 保存检验申请单信息逻辑
|
||||||
* 保存检验申请单信息同时根据检验申请单检验项目数据保存检验申请单明细信息
|
* 保存检验申请单信息同时根据检验申请单检验项目数据保存检验申请单明细信息
|
||||||
*/
|
*/
|
||||||
log.debug("保存检验申请单信息:{}", doctorStationLabApplyDto);
|
|
||||||
log.debug("保存申请单明细信息:{}",doctorStationLabApplyDto.getLabApplyItemList());
|
// 申请单号为空或"待生成"时,由后端生成新单号
|
||||||
|
String applyNo = doctorStationLabApplyDto.getApplyNo();
|
||||||
|
boolean isNewApplyNo = false;
|
||||||
|
if (applyNo == null || applyNo.trim().isEmpty() || "待生成".equals(applyNo) || "自动生成".equals(applyNo)) {
|
||||||
|
applyNo = generateApplyNo();
|
||||||
|
isNewApplyNo = true;
|
||||||
|
}
|
||||||
|
// 将生成的单号设置回 DTO
|
||||||
|
doctorStationLabApplyDto.setApplyNo(applyNo);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 执行保存逻辑
|
||||||
|
doSaveInspectionLabApply(doctorStationLabApplyDto, applyNo);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 记录废号日志(申请单号已生成但保存失败)
|
||||||
|
if (isNewApplyNo) {
|
||||||
|
log.error("申请单号 {} 因保存失败成为废号,原因:{}", applyNo, e.getMessage());
|
||||||
|
}
|
||||||
|
throw e; // 重新抛出异常,让事务回滚
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回生成的申请单号
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
result.put("applyNo", applyNo);
|
||||||
|
return R.ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行保存检验申请单的实际逻辑
|
||||||
|
*/
|
||||||
|
private void doSaveInspectionLabApply(DoctorStationLabApplyDto doctorStationLabApplyDto, String applyNo) {
|
||||||
|
|
||||||
//获取当前登陆用户 ID
|
//获取当前登陆用户 ID
|
||||||
String userId = String.valueOf(SecurityUtils.getLoginUser().getUserId());
|
String userId = String.valueOf(SecurityUtils.getLoginUser().getUserId());
|
||||||
InspectionLabApply inspectionLabApply = new InspectionLabApply();
|
InspectionLabApply inspectionLabApply = new InspectionLabApply();
|
||||||
@@ -102,22 +139,34 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
|
|||||||
inspectionLabApply.setOperatorId(userId);
|
inspectionLabApply.setOperatorId(userId);
|
||||||
inspectionLabApply.setCreateTime(new Date());
|
inspectionLabApply.setCreateTime(new Date());
|
||||||
inspectionLabApply.setDeleteFlag(DelFlag.NO.getCode());
|
inspectionLabApply.setDeleteFlag(DelFlag.NO.getCode());
|
||||||
|
// 申请日期使用服务器当前系统时间
|
||||||
|
inspectionLabApply.setApplyTime(new Date());
|
||||||
|
|
||||||
log.debug("保存检验申请单信息:{}", inspectionLabApply);
|
|
||||||
inspectionLabApplyService.saveOrUpdate(inspectionLabApply);
|
inspectionLabApplyService.saveOrUpdate(inspectionLabApply);
|
||||||
|
|
||||||
|
// 金额校验和重算:后端重新计算金额,防止前端篡改
|
||||||
|
java.math.BigDecimal totalAmount = java.math.BigDecimal.ZERO;
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
//遍历 doctorStationLabApplyDto.getLabApplyItemList()
|
//遍历 doctorStationLabApplyDto.getLabApplyItemList()
|
||||||
int index = 0;
|
|
||||||
for (DoctorStationLabApplyItemDto doctorStationLabApplyItemDto : doctorStationLabApplyDto.getLabApplyItemList()) {
|
for (DoctorStationLabApplyItemDto doctorStationLabApplyItemDto : doctorStationLabApplyDto.getLabApplyItemList()) {
|
||||||
//将 dto 数据复制到 InspectionLabApplyItem 对象中
|
//将 dto 数据复制到 InspectionLabApplyItem 对象中
|
||||||
InspectionLabApplyItem inspectionLabApplyItem = new InspectionLabApplyItem();
|
InspectionLabApplyItem inspectionLabApplyItem = new InspectionLabApplyItem();
|
||||||
BeanUtils.copyProperties(doctorStationLabApplyItemDto, inspectionLabApplyItem);
|
BeanUtils.copyProperties(doctorStationLabApplyItemDto, inspectionLabApplyItem);
|
||||||
|
|
||||||
|
// 后端重新计算金额:金额 = 单价 × 数量
|
||||||
|
java.math.BigDecimal itemPrice = doctorStationLabApplyItemDto.getItemPrice();
|
||||||
|
java.math.BigDecimal itemQty = doctorStationLabApplyItemDto.getItemQty();
|
||||||
|
if (itemPrice != null && itemQty != null) {
|
||||||
|
java.math.BigDecimal calculatedAmount = itemPrice.multiply(itemQty).setScale(2, java.math.RoundingMode.HALF_UP);
|
||||||
|
inspectionLabApplyItem.setItemAmount(calculatedAmount);
|
||||||
|
totalAmount = totalAmount.add(calculatedAmount);
|
||||||
|
}
|
||||||
|
|
||||||
//设置从表申请单明细的申请单号
|
//设置从表申请单明细的申请单号
|
||||||
inspectionLabApplyItem.setApplyNo(doctorStationLabApplyDto.getApplyNo());
|
inspectionLabApplyItem.setApplyNo(doctorStationLabApplyDto.getApplyNo());
|
||||||
//检验科代码,取值于检验申请单
|
//执行科室代码,取值于检验申请单明细(前端传递的字典值)
|
||||||
inspectionLabApplyItem.setPerformDeptCode(doctorStationLabApplyDto.getApplyDeptCode());
|
inspectionLabApplyItem.setPerformDeptCode(doctorStationLabApplyItemDto.getPerformDeptCode());
|
||||||
//同主表状态,可单独回写
|
//同主表状态,可单独回写
|
||||||
inspectionLabApplyItem.setItemStatus(doctorStationLabApplyDto.getApplyStatus());
|
inspectionLabApplyItem.setItemStatus(doctorStationLabApplyDto.getApplyStatus());
|
||||||
// 设置项目序号 (打印顺序),按照遍历序号进行排序
|
// 设置项目序号 (打印顺序),按照遍历序号进行排序
|
||||||
@@ -125,7 +174,6 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
|
|||||||
index++;
|
index++;
|
||||||
|
|
||||||
inspectionLabApplyItem.setDeleteFlag(DelFlag.NO.getCode());
|
inspectionLabApplyItem.setDeleteFlag(DelFlag.NO.getCode());
|
||||||
log.debug("保存申请单明细信息:{}", inspectionLabApplyItem);
|
|
||||||
inspectionLabApplyItemService.saveOrUpdate(inspectionLabApplyItem);
|
inspectionLabApplyItemService.saveOrUpdate(inspectionLabApplyItem);
|
||||||
|
|
||||||
//创建条码对象
|
//创建条码对象
|
||||||
@@ -141,8 +189,6 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
|
|||||||
barCode.setCreateTime(new Date());
|
barCode.setCreateTime(new Date());
|
||||||
barCode.setDeleteFlag(DelFlag.NO.getCode());
|
barCode.setDeleteFlag(DelFlag.NO.getCode());
|
||||||
|
|
||||||
|
|
||||||
log.debug("插入条码数据前,barCode:{}",barCode);
|
|
||||||
inspectionLabBarCodeService.saveOrUpdate(barCode);
|
inspectionLabBarCodeService.saveOrUpdate(barCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,11 +235,14 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
|
|||||||
);
|
);
|
||||||
if (organization != null) {
|
if (organization != null) {
|
||||||
positionId = organization.getId();
|
positionId = organization.getId();
|
||||||
} else {
|
|
||||||
log.warn("未找到执行科室代码对应的科室:{}", performDeptCode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果没有指定执行科室,使用当前医生所在的科室作为默认执行科室
|
||||||
|
if (positionId == null) {
|
||||||
|
positionId = SecurityUtils.getDeptId();
|
||||||
|
}
|
||||||
|
|
||||||
// 4. 创建医嘱保存对象
|
// 4. 创建医嘱保存对象
|
||||||
AdviceSaveDto adviceSaveDto = new AdviceSaveDto();
|
AdviceSaveDto adviceSaveDto = new AdviceSaveDto();
|
||||||
// 设置医嘱操作类型
|
// 设置医嘱操作类型
|
||||||
@@ -270,23 +319,45 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
|
|||||||
adviceSaveParam.setAdviceSaveList(adviceSaveList);
|
adviceSaveParam.setAdviceSaveList(adviceSaveList);
|
||||||
|
|
||||||
// 调用门诊医嘱保存接口,创建关联的医嘱记录
|
// 调用门诊医嘱保存接口,创建关联的医嘱记录
|
||||||
try {
|
|
||||||
iDoctorStationAdviceAppService.saveAdvice(adviceSaveParam, "1"); // "1"表示保存操作
|
iDoctorStationAdviceAppService.saveAdvice(adviceSaveParam, "1"); // "1"表示保存操作
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("创建关联医嘱记录失败", e);
|
|
||||||
}
|
|
||||||
return R.ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据申请单号查询检验申请单
|
* 根据申请单号查询检验申请单(包含检验项目明细)
|
||||||
*
|
*
|
||||||
* @param applyNo
|
* @param applyNo
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Object getInspectionApplyByApplyNo(String applyNo) {
|
public Object getInspectionApplyByApplyNo(String applyNo) {
|
||||||
return doctorStationLabApplyMapper.getInspectionApplyByApplyNo(applyNo);
|
// 查询主表数据
|
||||||
|
DoctorStationLabApplyDto applyDto = (DoctorStationLabApplyDto) doctorStationLabApplyMapper.getInspectionApplyByApplyNo(applyNo);
|
||||||
|
if (applyDto == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询检验项目明细
|
||||||
|
List<InspectionLabApplyItem> itemList = inspectionLabApplyItemService.list(
|
||||||
|
new QueryWrapper<InspectionLabApplyItem>()
|
||||||
|
.eq("apply_no", applyNo)
|
||||||
|
.eq("delete_flag", "0")
|
||||||
|
.orderByAsc("item_seq")
|
||||||
|
);
|
||||||
|
|
||||||
|
// 转换为 DTO 列表
|
||||||
|
List<DoctorStationLabApplyItemDto> itemDtoList = new ArrayList<>();
|
||||||
|
if (itemList != null && !itemList.isEmpty()) {
|
||||||
|
for (InspectionLabApplyItem item : itemList) {
|
||||||
|
DoctorStationLabApplyItemDto itemDto = new DoctorStationLabApplyItemDto();
|
||||||
|
BeanUtils.copyProperties(item, itemDto);
|
||||||
|
itemDtoList.add(itemDto);
|
||||||
|
}
|
||||||
|
// 从第一个明细项获取执行科室代码
|
||||||
|
applyDto.setExecuteDepartment(itemList.get(0).getPerformDeptCode());
|
||||||
|
}
|
||||||
|
applyDto.setLabApplyItemList(itemDtoList);
|
||||||
|
|
||||||
|
return applyDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -303,11 +374,11 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
|
|||||||
|
|
||||||
// 查询检验申请单列表
|
// 查询检验申请单列表
|
||||||
log.debug("查询申请单数据前");
|
log.debug("查询申请单数据前");
|
||||||
List<InspectionLabApply> list = doctorStationLabApplyMapper.getInspectionApplyListPage(encounterId);
|
List<DoctorStationLabApplyDto> list = doctorStationLabApplyMapper.getInspectionApplyListPage(encounterId);
|
||||||
log.debug("查询申请单数据后");
|
log.debug("查询申请单数据后");
|
||||||
|
|
||||||
// 使用 PageInfo 包装查询结果
|
// 使用 PageInfo 包装查询结果
|
||||||
PageInfo<InspectionLabApply> pageInfo = new PageInfo<>(list);
|
PageInfo<DoctorStationLabApplyDto> pageInfo = new PageInfo<>(list);
|
||||||
|
|
||||||
// 构建返回结果
|
// 构建返回结果
|
||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
@@ -514,4 +585,36 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成检验申请单号
|
||||||
|
* 规则:LS + YYYYMMDD + 5位流水号(每日从1开始递增)
|
||||||
|
* 支持并发安全:使用 Redis 原子递增保证唯一性
|
||||||
|
* @return 申请单号
|
||||||
|
*/
|
||||||
|
private String generateApplyNo() {
|
||||||
|
// 获取当前日期
|
||||||
|
LocalDate today = LocalDate.now();
|
||||||
|
String dateStr = today.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
|
||||||
|
|
||||||
|
// 生成前缀:LS + 日期
|
||||||
|
String prefix = "LS" + dateStr;
|
||||||
|
|
||||||
|
// Redis key 用于存储当天的流水号
|
||||||
|
String redisKey = "lab_apply_no:" + dateStr;
|
||||||
|
|
||||||
|
// 使用 Redis 原子递增获取流水号(并发安全)
|
||||||
|
long sequence = redisCache.incr(redisKey, 1);
|
||||||
|
|
||||||
|
// 设置 Redis key 过期时间(每天的 key 按日期独立,隔天不再使用,25小时确保跨午夜场景安全)
|
||||||
|
redisCache.expire(redisKey, 25 * 60 * 60);
|
||||||
|
|
||||||
|
// 格式化流水号为5位,不足前补0
|
||||||
|
String sequenceStr = String.format("%05d", sequence);
|
||||||
|
|
||||||
|
// 生成完整的申请单号
|
||||||
|
String applyNo = prefix + sequenceStr;
|
||||||
|
|
||||||
|
return applyNo;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.openhis.web.doctorstation.appservice.impl;
|
package com.openhis.web.doctorstation.appservice.impl;
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
@@ -16,21 +17,23 @@ import com.openhis.common.constant.CommonConstants;
|
|||||||
import com.openhis.common.enums.*;
|
import com.openhis.common.enums.*;
|
||||||
import com.openhis.common.utils.EnumUtils;
|
import com.openhis.common.utils.EnumUtils;
|
||||||
import com.openhis.common.utils.HisQueryUtils;
|
import com.openhis.common.utils.HisQueryUtils;
|
||||||
|
import com.openhis.triageandqueuemanage.domain.TriageQueueItem;
|
||||||
|
import com.openhis.triageandqueuemanage.service.TriageQueueItemService;
|
||||||
import com.openhis.web.doctorstation.appservice.*;
|
import com.openhis.web.doctorstation.appservice.*;
|
||||||
import com.openhis.web.doctorstation.dto.PatientInfoDto;
|
import com.openhis.web.doctorstation.dto.PatientInfoDto;
|
||||||
import com.openhis.web.doctorstation.dto.PrescriptionInfoBaseDto;
|
import com.openhis.web.doctorstation.dto.PrescriptionInfoBaseDto;
|
||||||
import com.openhis.web.doctorstation.dto.PrescriptionInfoDetailDto;
|
import com.openhis.web.doctorstation.dto.PrescriptionInfoDetailDto;
|
||||||
import com.openhis.web.doctorstation.dto.ReceptionStatisticsDto;
|
import com.openhis.web.doctorstation.dto.ReceptionStatisticsDto;
|
||||||
import com.openhis.web.doctorstation.mapper.DoctorStationMainAppMapper;
|
import com.openhis.web.doctorstation.mapper.DoctorStationMainAppMapper;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -64,6 +67,9 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private JdbcTemplate jdbcTemplate;
|
private JdbcTemplate jdbcTemplate;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TriageQueueItemService triageQueueItemService;
|
||||||
/**
|
/**
|
||||||
* 查询就诊患者信息
|
* 查询就诊患者信息
|
||||||
*
|
*
|
||||||
@@ -124,14 +130,40 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public R<?> receiveEncounter(Long encounterId) {
|
public R<?> receiveEncounter(Long encounterId) {
|
||||||
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
||||||
String currentUsername = SecurityUtils.getUsername();
|
String currentUsername = SecurityUtils.getUsername();
|
||||||
|
|
||||||
|
// 检查就诊记录是否存在
|
||||||
|
Encounter encounter = encounterMapper.selectById(encounterId);
|
||||||
|
if (encounter == null) {
|
||||||
|
return R.fail("就诊记录不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查患者状态,防止重复接诊
|
||||||
|
Integer currentStatus = encounter.getStatusEnum();
|
||||||
|
if (EncounterStatus.IN_PROGRESS.getValue().equals(currentStatus)) {
|
||||||
|
return R.fail("已接诊,请勿重复点击,已为您刷新");
|
||||||
|
}
|
||||||
|
|
||||||
int update = encounterMapper.update(null,
|
int update = encounterMapper.update(null,
|
||||||
new LambdaUpdateWrapper<Encounter>().eq(Encounter::getId, encounterId)
|
new LambdaUpdateWrapper<Encounter>().eq(Encounter::getId, encounterId)
|
||||||
|
.eq(Encounter::getStatusEnum, EncounterStatus.PLANNED.getValue()) // 只更新待诊状态的患者
|
||||||
.set(Encounter::getReceptionTime, new Date())
|
.set(Encounter::getReceptionTime, new Date())
|
||||||
.set(Encounter::getStatusEnum, EncounterStatus.IN_PROGRESS.getValue())
|
.set(Encounter::getStatusEnum, EncounterStatus.IN_PROGRESS.getValue())
|
||||||
.set(Encounter::getSubjectStatusEnum, EncounterSubjectStatus.RECEIVING_CARE.getValue()));
|
.set(Encounter::getSubjectStatusEnum, EncounterSubjectStatus.RECEIVING_CARE.getValue()));
|
||||||
|
|
||||||
|
// 如果更新失败,说明状态已被其他医生修改
|
||||||
|
if (update <= 0) {
|
||||||
|
// 重新查询当前状态
|
||||||
|
encounter = encounterMapper.selectById(encounterId);
|
||||||
|
if (EncounterStatus.IN_PROGRESS.getValue().equals(encounter.getStatusEnum())) {
|
||||||
|
return R.fail("已接诊,请勿重复接诊");
|
||||||
|
}
|
||||||
|
return R.fail("接诊失败,请刷新后重试");
|
||||||
|
}
|
||||||
|
|
||||||
// 先把之前的接诊记录更新为已完成
|
// 先把之前的接诊记录更新为已完成
|
||||||
iEncounterParticipantService.update(new LambdaUpdateWrapper<EncounterParticipant>()
|
iEncounterParticipantService.update(new LambdaUpdateWrapper<EncounterParticipant>()
|
||||||
.eq(EncounterParticipant::getTypeCode, ParticipantType.ADMITTER.getCode())
|
.eq(EncounterParticipant::getTypeCode, ParticipantType.ADMITTER.getCode())
|
||||||
@@ -148,7 +180,28 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
|||||||
encounterParticipant.setCreateBy(currentUsername);
|
encounterParticipant.setCreateBy(currentUsername);
|
||||||
encounterParticipant.setCreateTime(new Date());
|
encounterParticipant.setCreateTime(new Date());
|
||||||
iEncounterParticipantService.save(encounterParticipant);
|
iEncounterParticipantService.save(encounterParticipant);
|
||||||
return update > 0 ? R.ok() : R.fail();
|
|
||||||
|
// 更新 triage_queue_item 队列记录状态为 CALLING
|
||||||
|
try {
|
||||||
|
TriageQueueItem queueItem = triageQueueItemService.getOne(
|
||||||
|
new LambdaQueryWrapper<TriageQueueItem>()
|
||||||
|
.eq(TriageQueueItem::getTenantId, tenantId)
|
||||||
|
.eq(TriageQueueItem::getEncounterId, encounterId)
|
||||||
|
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||||
|
);
|
||||||
|
if (queueItem != null) {
|
||||||
|
queueItem.setStatus("CALLING");
|
||||||
|
queueItem.setUpdateTime(LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS));
|
||||||
|
triageQueueItemService.updateById(queueItem);
|
||||||
|
log.info("接诊时更新队列状态为CALLING,encounterId={}, queueItemId={}", encounterId, queueItem.getId());
|
||||||
|
} else {
|
||||||
|
log.warn("接诊时未找到队列记录,encounterId={}", encounterId);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("接诊时更新队列状态失败,encounterId={}", encounterId, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return R.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -181,11 +234,54 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
|||||||
return R.fail("就诊记录不存在");
|
return R.fail("就诊记录不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!EncounterStatus.IN_PROGRESS.getValue().equals(encounter.getStatusEnum())) {
|
// 检查患者状态,防止重复完诊
|
||||||
return R.fail("当前患者不在就诊中状态");
|
Integer currentStatus = encounter.getStatusEnum();
|
||||||
|
if (EncounterStatus.DISCHARGED.getValue().equals(currentStatus) ||
|
||||||
|
EncounterStatus.COMPLETED.getValue().equals(currentStatus)) {
|
||||||
|
// 患者已完成就诊,返回特定提示
|
||||||
|
return R.fail("患者已完成就诊,已为您自动刷新患者列表");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 更新状态、完成时间以及初复诊标识
|
if (!EncounterStatus.IN_PROGRESS.getValue().equals(currentStatus)) {
|
||||||
|
return R.fail("非就诊中患者不能完诊");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 查找队列项
|
||||||
|
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
||||||
|
TriageQueueItem queueItem = triageQueueItemService.getOne(
|
||||||
|
new LambdaQueryWrapper<TriageQueueItem>()
|
||||||
|
.eq(TriageQueueItem::getTenantId, tenantId)
|
||||||
|
.eq(TriageQueueItem::getEncounterId, encounterId)
|
||||||
|
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||||
|
);
|
||||||
|
|
||||||
|
// 如果队列项存在,检查状态并更新
|
||||||
|
if (queueItem != null && "CALLING".equals(queueItem.getStatus())) {
|
||||||
|
// 更新队列状态为已完成
|
||||||
|
java.time.LocalDateTime nowLocal = java.time.LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS);
|
||||||
|
queueItem.setStatus("COMPLETED");
|
||||||
|
queueItem.setUpdateTime(nowLocal);
|
||||||
|
triageQueueItemService.updateById(queueItem);
|
||||||
|
|
||||||
|
// 写入 div_log 审计日志
|
||||||
|
try {
|
||||||
|
Long userId = SecurityUtils.getLoginUser().getUserId();
|
||||||
|
String divLogSql = "INSERT INTO hisdev.div_log "
|
||||||
|
+ "(pool_id, slot_id, queue_no, op_user_id, action, create_time) "
|
||||||
|
+ "VALUES (?, ?, ?, ?, 'COMPLETE', NOW()::timestamp(0))";
|
||||||
|
|
||||||
|
jdbcTemplate.update(divLogSql,
|
||||||
|
queueItem.getOrganizationId(), // pool_id: 候选池ID(科室)
|
||||||
|
queueItem.getPractitionerId(), // slot_id: 槽位ID(医生)
|
||||||
|
queueItem.getQueueOrder(), // queue_no: 队列号
|
||||||
|
userId); // op_user_id: 操作用户ID
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("写入div_log审计日志失败", e);
|
||||||
|
// 审计日志失败不影响主流程
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 更新状态、完成时间以及初复诊标识
|
||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
int update = encounterMapper.update(null,
|
int update = encounterMapper.update(null,
|
||||||
new LambdaUpdateWrapper<Encounter>()
|
new LambdaUpdateWrapper<Encounter>()
|
||||||
@@ -198,7 +294,7 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
|||||||
|
|
||||||
if (update <= 0) return R.fail("完诊失败");
|
if (update <= 0) return R.fail("完诊失败");
|
||||||
|
|
||||||
// 3. 审计日志
|
// 4. 审计日志(sys_oper_log)
|
||||||
try {
|
try {
|
||||||
String username = SecurityUtils.getUsernameSafe();
|
String username = SecurityUtils.getUsernameSafe();
|
||||||
String sql = "INSERT INTO sys_oper_log "
|
String sql = "INSERT INTO sys_oper_log "
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.openhis.web.doctorstation.controller;
|
package com.openhis.web.doctorstation.controller;
|
||||||
|
|
||||||
|
import com.core.common.annotation.RepeatSubmit;
|
||||||
import com.core.common.core.domain.R;
|
import com.core.common.core.domain.R;
|
||||||
import com.openhis.common.enums.AdviceOpType;
|
import com.openhis.common.enums.AdviceOpType;
|
||||||
import com.openhis.common.enums.Whether;
|
import com.openhis.common.enums.Whether;
|
||||||
@@ -51,7 +52,7 @@ public class DoctorStationAdviceController {
|
|||||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
|
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||||
return R.ok(iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, searchKey, locationId,
|
return R.ok(iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, searchKey, locationId,
|
||||||
adviceDefinitionIdParamList, organizationId, pageNo, pageSize, Whether.NO.getValue(), adviceTypes, null));
|
adviceDefinitionIdParamList, organizationId, pageNo, pageSize, Whether.NO.getValue(), adviceTypes, null, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -85,6 +86,7 @@ public class DoctorStationAdviceController {
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@PostMapping(value = "/sign-advice")
|
@PostMapping(value = "/sign-advice")
|
||||||
|
@RepeatSubmit(interval = 5000, message = "请勿重复签发医嘱,请稍候再试")
|
||||||
public R<?> signAdvice(@RequestBody AdviceSaveParam adviceSaveParam) {
|
public R<?> signAdvice(@RequestBody AdviceSaveParam adviceSaveParam) {
|
||||||
return iDoctorStationAdviceAppService.saveAdvice(adviceSaveParam, AdviceOpType.SIGN_ADVICE.getCode());
|
return iDoctorStationAdviceAppService.saveAdvice(adviceSaveParam, AdviceOpType.SIGN_ADVICE.getCode());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import org.springframework.web.bind.annotation.*;
|
|||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 门诊医生站-检验控制器
|
* 门诊医生站-检验控制器
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ import java.util.List;
|
|||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
public class DoctorStationLabApplyDto {
|
public class DoctorStationLabApplyDto {
|
||||||
|
/**
|
||||||
|
* 申请单ID(数据库自增主键)
|
||||||
|
*/
|
||||||
|
private Long applicationId;
|
||||||
/**
|
/**
|
||||||
* 申请单编号
|
* 申请单编号
|
||||||
*/
|
*/
|
||||||
@@ -135,6 +139,10 @@ public class DoctorStationLabApplyDto {
|
|||||||
* 就诊id
|
* 就诊id
|
||||||
*/
|
*/
|
||||||
private Long encounterId;
|
private Long encounterId;
|
||||||
|
/**
|
||||||
|
* 执行科室代码(从明细项获取)
|
||||||
|
*/
|
||||||
|
private String executeDepartment;
|
||||||
/**
|
/**
|
||||||
* 检验项目数据列表
|
* 检验项目数据列表
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -79,6 +79,11 @@ public class RequestBaseDto {
|
|||||||
@JsonSerialize(using = ToStringSerializer.class)
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
private Long chargeItemId;
|
private Long chargeItemId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 医嘱定义对应表名
|
||||||
|
*/
|
||||||
|
private String adviceTableName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 医嘱名称
|
* 医嘱名称
|
||||||
*/
|
*/
|
||||||
@@ -156,6 +161,11 @@ public class RequestBaseDto {
|
|||||||
private String doseUnitCode;
|
private String doseUnitCode;
|
||||||
private String doseUnitCode_dictText;
|
private String doseUnitCode_dictText;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单价
|
||||||
|
*/
|
||||||
|
private BigDecimal unitPrice;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 总价
|
* 总价
|
||||||
*/
|
*/
|
||||||
@@ -210,4 +220,16 @@ public class RequestBaseDto {
|
|||||||
@JsonSerialize(using = ToStringSerializer.class)
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
private Long basedOnId;
|
private Long basedOnId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 就诊id
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long encounterId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 患者id
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long patientId;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.openhis.web.doctorstation.dto;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
@@ -73,12 +74,16 @@ public class SaveDiagnosisChildParam {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 诊断时间
|
* 诊断时间
|
||||||
|
* 添加 pattern 以支持前端传来的 "yyyy/M/d HH:mm:ss" 格式
|
||||||
*/
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy/M/d HH:mm:ss", timezone = "GMT+8")
|
||||||
private Date diagnosisTime;
|
private Date diagnosisTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发病时间
|
* 发病时间
|
||||||
|
* 同样添加 pattern 以防前端传来相同格式的发病时间
|
||||||
*/
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy/M/d HH:mm:ss", timezone = "GMT+8")
|
||||||
private Date onsetDate;
|
private Date onsetDate;
|
||||||
|
|
||||||
/** 患者疾病诊断类型代码 */
|
/** 患者疾病诊断类型代码 */
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public interface DoctorStationAdviceAppMapper {
|
|||||||
@Param("adviceDefinitionIdParamList") List<Long> adviceDefinitionIdParamList,
|
@Param("adviceDefinitionIdParamList") List<Long> adviceDefinitionIdParamList,
|
||||||
@Param("adviceTypes") List<Integer> adviceTypes,
|
@Param("adviceTypes") List<Integer> adviceTypes,
|
||||||
@Param("searchKey") String searchKey,
|
@Param("searchKey") String searchKey,
|
||||||
|
@Param("categoryCode") String categoryCode,
|
||||||
@Param(Constants.WRAPPER) QueryWrapper<AdviceBaseDto> queryWrapper);
|
@Param(Constants.WRAPPER) QueryWrapper<AdviceBaseDto> queryWrapper);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.openhis.web.doctorstation.mapper;
|
package com.openhis.web.doctorstation.mapper;
|
||||||
|
|
||||||
import com.openhis.lab.domain.InspectionLabApply;
|
import com.openhis.web.doctorstation.dto.DoctorStationLabApplyDto;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
@@ -11,6 +11,11 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
@Repository
|
@Repository
|
||||||
public interface DoctorStationLabApplyMapper {
|
public interface DoctorStationLabApplyMapper {
|
||||||
|
/**
|
||||||
|
* 根据申请单号查询检验申请单
|
||||||
|
* @param applyNo 申请单号
|
||||||
|
* @return 检验申请单DTO
|
||||||
|
*/
|
||||||
Object getInspectionApplyByApplyNo(String applyNo);
|
Object getInspectionApplyByApplyNo(String applyNo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -18,5 +23,5 @@ public interface DoctorStationLabApplyMapper {
|
|||||||
* @param encounterId 就诊 ID
|
* @param encounterId 就诊 ID
|
||||||
* @return 检验申请单列表
|
* @return 检验申请单列表
|
||||||
*/
|
*/
|
||||||
List<InspectionLabApply> getInspectionApplyListPage(@Param("encounterId") Long encounterId);
|
List<DoctorStationLabApplyDto> getInspectionApplyListPage(@Param("encounterId") Long encounterId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
import com.openhis.administration.domain.ChargeItem;
|
import com.openhis.administration.domain.ChargeItem;
|
||||||
|
import com.openhis.administration.domain.Account;
|
||||||
|
import com.openhis.administration.service.IAccountService;
|
||||||
import com.openhis.administration.service.IChargeItemService;
|
import com.openhis.administration.service.IChargeItemService;
|
||||||
import com.openhis.common.constant.CommonConstants;
|
import com.openhis.common.constant.CommonConstants;
|
||||||
import com.openhis.common.enums.*;
|
import com.openhis.common.enums.*;
|
||||||
@@ -71,6 +73,9 @@ public class AdviceUtils {
|
|||||||
@Resource
|
@Resource
|
||||||
IDoctorStationAdviceAppService iDoctorStationAdviceAppService;
|
IDoctorStationAdviceAppService iDoctorStationAdviceAppService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
IAccountService iAccountService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验库存
|
* 校验库存
|
||||||
*
|
*
|
||||||
@@ -110,6 +115,15 @@ public class AdviceUtils {
|
|||||||
matched = true;
|
matched = true;
|
||||||
// 检查库存是否充足
|
// 检查库存是否充足
|
||||||
BigDecimal minUnitQuantity = saveDto.getMinUnitQuantity();
|
BigDecimal minUnitQuantity = saveDto.getMinUnitQuantity();
|
||||||
|
// 🔧 Bug Fix: 对于耗材类型,如果没有设置minUnitQuantity,则使用quantity作为默认值
|
||||||
|
if (minUnitQuantity == null) {
|
||||||
|
if (CommonConstants.TableName.ADM_DEVICE_DEFINITION.equals(inventoryDto.getItemTable())) {
|
||||||
|
// 耗材只有一个单位,minUnitQuantity等于quantity
|
||||||
|
minUnitQuantity = saveDto.getQuantity();
|
||||||
|
} else {
|
||||||
|
return saveDto.getAdviceName() + "的小单位数量不能为空";
|
||||||
|
}
|
||||||
|
}
|
||||||
BigDecimal chineseHerbsDoseQuantity = saveDto.getChineseHerbsDoseQuantity(); // 中药付数
|
BigDecimal chineseHerbsDoseQuantity = saveDto.getChineseHerbsDoseQuantity(); // 中药付数
|
||||||
// 中草药医嘱的情况
|
// 中草药医嘱的情况
|
||||||
if (chineseHerbsDoseQuantity != null && chineseHerbsDoseQuantity.compareTo(BigDecimal.ZERO) > 0) {
|
if (chineseHerbsDoseQuantity != null && chineseHerbsDoseQuantity.compareTo(BigDecimal.ZERO) > 0) {
|
||||||
@@ -305,6 +319,28 @@ public class AdviceUtils {
|
|||||||
*/
|
*/
|
||||||
public void handleActivityChild(String childrenJson, Long organizationId,
|
public void handleActivityChild(String childrenJson, Long organizationId,
|
||||||
ActivityChildrenJsonParams activityChildrenJsonParams) {
|
ActivityChildrenJsonParams activityChildrenJsonParams) {
|
||||||
|
// 🔧 Bug Fix: 确保accountId不为null
|
||||||
|
if (activityChildrenJsonParams.getAccountId() == null) {
|
||||||
|
// 尝试从患者就诊中获取默认账户ID(自费账户)
|
||||||
|
Account selfAccount = iAccountService.getSelfAccount(activityChildrenJsonParams.getEncounterId());
|
||||||
|
if (selfAccount != null) {
|
||||||
|
activityChildrenJsonParams.setAccountId(selfAccount.getId());
|
||||||
|
} else {
|
||||||
|
// 自动创建自费账户
|
||||||
|
Account newAccount = new Account();
|
||||||
|
newAccount.setPatientId(activityChildrenJsonParams.getPatientId());
|
||||||
|
newAccount.setEncounterId(activityChildrenJsonParams.getEncounterId());
|
||||||
|
newAccount.setContractNo(CommonConstants.BusinessName.DEFAULT_CONTRACT_NO);
|
||||||
|
newAccount.setTypeCode(AccountType.PERSONAL_CASH_ACCOUNT.getCode());
|
||||||
|
newAccount.setBalanceAmount(BigDecimal.ZERO);
|
||||||
|
newAccount.setStatusEnum(AccountStatus.ACTIVE.getValue());
|
||||||
|
newAccount.setEncounterFlag(Whether.YES.getValue());
|
||||||
|
newAccount.setName(AccountType.PERSONAL_CASH_ACCOUNT.getInfo());
|
||||||
|
Long newAccountId = iAccountService.saveAccountByRegister(newAccount);
|
||||||
|
activityChildrenJsonParams.setAccountId(newAccountId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 治疗类型 (长期/临时)
|
// 治疗类型 (长期/临时)
|
||||||
Integer therapyEnum = activityChildrenJsonParams.getTherapyEnum();
|
Integer therapyEnum = activityChildrenJsonParams.getTherapyEnum();
|
||||||
// 当前登录账号的科室id
|
// 当前登录账号的科室id
|
||||||
@@ -337,7 +373,7 @@ public class AdviceUtils {
|
|||||||
// 对应的子项诊疗医嘱信息
|
// 对应的子项诊疗医嘱信息
|
||||||
AdviceBaseDto activityAdviceBaseDto
|
AdviceBaseDto activityAdviceBaseDto
|
||||||
= iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, null, null, null, organizationId, 1,
|
= iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, null, null, null, organizationId, 1,
|
||||||
1, Whether.NO.getValue(), List.of(1, 2, 3), null).getRecords().get(0);
|
1, Whether.NO.getValue(), List.of(1, 2, 3), null, null).getRecords().get(0);
|
||||||
if (activityAdviceBaseDto != null) {
|
if (activityAdviceBaseDto != null) {
|
||||||
// 费用定价
|
// 费用定价
|
||||||
AdvicePriceDto advicePriceDto = activityAdviceBaseDto.getPriceList().get(0);
|
AdvicePriceDto advicePriceDto = activityAdviceBaseDto.getPriceList().get(0);
|
||||||
|
|||||||
@@ -32,9 +32,11 @@ public class PrescriptionUtils {
|
|||||||
if (medicineList == null || medicineList.isEmpty()) {
|
if (medicineList == null || medicineList.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 1. 按诊断ID分组(不同诊断必须分开)
|
// 1. 按诊断ID分组(不同诊断必须分开,null值归为一组)
|
||||||
Map<Long, List<AdviceSaveDto>> diagnosisGroups =
|
Map<Long, List<AdviceSaveDto>> diagnosisGroups =
|
||||||
medicineList.stream().collect(Collectors.groupingBy(AdviceSaveDto::getConditionDefinitionId));
|
medicineList.stream().collect(Collectors.groupingBy(dto ->
|
||||||
|
dto.getConditionDefinitionId() != null ? dto.getConditionDefinitionId() : 0L
|
||||||
|
));
|
||||||
// 2. 处理每个诊断组
|
// 2. 处理每个诊断组
|
||||||
diagnosisGroups.values().forEach(this::processDiagnosisGroup);
|
diagnosisGroups.values().forEach(this::processDiagnosisGroup);
|
||||||
}
|
}
|
||||||
@@ -46,9 +48,11 @@ public class PrescriptionUtils {
|
|||||||
if (diagnosisGroup.isEmpty()) {
|
if (diagnosisGroup.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 1. 按药品性质分组
|
// 1. 按药品性质分组(null值归为普通药品)
|
||||||
Map<String, List<AdviceSaveDto>> pharmacologyGroups =
|
Map<String, List<AdviceSaveDto>> pharmacologyGroups =
|
||||||
diagnosisGroup.stream().collect(Collectors.groupingBy(AdviceSaveDto::getPharmacologyCategoryCode));
|
diagnosisGroup.stream().collect(Collectors.groupingBy(dto ->
|
||||||
|
dto.getPharmacologyCategoryCode() != null ? dto.getPharmacologyCategoryCode() : "0"
|
||||||
|
));
|
||||||
// 2. 处理每个药品性质组
|
// 2. 处理每个药品性质组
|
||||||
pharmacologyGroups.values().forEach(pharmaGroup -> {
|
pharmacologyGroups.values().forEach(pharmaGroup -> {
|
||||||
// 2.1 先处理有分组ID的药品(确保它们不会被拆分)
|
// 2.1 先处理有分组ID的药品(确保它们不会被拆分)
|
||||||
|
|||||||
@@ -702,7 +702,7 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
|||||||
= medUseExeList.stream().map(MedicationRequestUseExe::getMedicationId).collect(Collectors.toList());
|
= medUseExeList.stream().map(MedicationRequestUseExe::getMedicationId).collect(Collectors.toList());
|
||||||
// 医嘱详细信息
|
// 医嘱详细信息
|
||||||
List<AdviceBaseDto> medicationInfos = doctorStationAdviceAppService.getAdviceBaseInfo(null, null, null,
|
List<AdviceBaseDto> medicationInfos = doctorStationAdviceAppService.getAdviceBaseInfo(null, null, null,
|
||||||
medicationDefinitionIdList, 0L, 1, 500, Whether.NO.getValue(), List.of(1), null).getRecords();
|
medicationDefinitionIdList, 0L, 1, 500, Whether.NO.getValue(), List.of(1), null, null).getRecords();
|
||||||
|
|
||||||
// 当前时间
|
// 当前时间
|
||||||
Date curDate = new Date();
|
Date curDate = new Date();
|
||||||
@@ -979,7 +979,7 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
|||||||
= actUseExeList.stream().map(ServiceRequestUseExe::getActivityId).collect(Collectors.toList());
|
= actUseExeList.stream().map(ServiceRequestUseExe::getActivityId).collect(Collectors.toList());
|
||||||
// 医嘱详细信息
|
// 医嘱详细信息
|
||||||
List<AdviceBaseDto> activityInfos = doctorStationAdviceAppService.getAdviceBaseInfo(null, null, null,
|
List<AdviceBaseDto> activityInfos = doctorStationAdviceAppService.getAdviceBaseInfo(null, null, null,
|
||||||
activityDefinitionIdList, 0L, 1, 500, Whether.NO.getValue(), List.of(3), null).getRecords();
|
activityDefinitionIdList, 0L, 1, 500, Whether.NO.getValue(), List.of(3), null, null).getRecords();
|
||||||
|
|
||||||
// 当前时间
|
// 当前时间
|
||||||
Date curDate = new Date();
|
Date curDate = new Date();
|
||||||
@@ -1146,7 +1146,7 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
|||||||
|
|
||||||
// 耗材医嘱详细信息
|
// 耗材医嘱详细信息
|
||||||
List<AdviceBaseDto> deviceInfos = doctorStationAdviceAppService
|
List<AdviceBaseDto> deviceInfos = doctorStationAdviceAppService
|
||||||
.getAdviceBaseInfo(null, null, null, deviceIds, 0L, 1, 500, Whether.NO.getValue(), List.of(2), null)
|
.getAdviceBaseInfo(null, null, null, deviceIds, 0L, 1, 500, Whether.NO.getValue(), List.of(2), null, null)
|
||||||
.getRecords();
|
.getRecords();
|
||||||
|
|
||||||
DeviceRequest deviceRequest;
|
DeviceRequest deviceRequest;
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ public class EncounterAutoRollAppServiceImpl implements IEncounterAutoRollAppSer
|
|||||||
.map(AutoRollNursingDto::getActivityDefinitionId).collect(Collectors.toList());
|
.map(AutoRollNursingDto::getActivityDefinitionId).collect(Collectors.toList());
|
||||||
// 诊疗医嘱信息
|
// 诊疗医嘱信息
|
||||||
List<AdviceBaseDto> activityInfos = doctorStationAdviceAppService.getAdviceBaseInfo(null, null, null,
|
List<AdviceBaseDto> activityInfos = doctorStationAdviceAppService.getAdviceBaseInfo(null, null, null,
|
||||||
activityDefinitionIdList, 0L, 1, 500, Whether.NO.getValue(), List.of(3), orderPricing).getRecords();
|
activityDefinitionIdList, 0L, 1, 500, Whether.NO.getValue(), List.of(3), orderPricing, null).getRecords();
|
||||||
|
|
||||||
// 计费
|
// 计费
|
||||||
ChargeItem chargeItem;
|
ChargeItem chargeItem;
|
||||||
@@ -295,7 +295,7 @@ public class EncounterAutoRollAppServiceImpl implements IEncounterAutoRollAppSer
|
|||||||
.map(AutoRollBasicServiceDto::getActivityDefinitionId).collect(Collectors.toList());
|
.map(AutoRollBasicServiceDto::getActivityDefinitionId).collect(Collectors.toList());
|
||||||
// 诊疗医嘱信息
|
// 诊疗医嘱信息
|
||||||
List<AdviceBaseDto> activityInfos = doctorStationAdviceAppService.getAdviceBaseInfo(null, null, null,
|
List<AdviceBaseDto> activityInfos = doctorStationAdviceAppService.getAdviceBaseInfo(null, null, null,
|
||||||
activityDefinitionIdList, 0L, 1, 500, Whether.NO.getValue(), List.of(3), orderPricing).getRecords();
|
activityDefinitionIdList, 0L, 1, 500, Whether.NO.getValue(), List.of(3), orderPricing, null).getRecords();
|
||||||
// 计费
|
// 计费
|
||||||
ChargeItem chargeItem;
|
ChargeItem chargeItem;
|
||||||
for (AutoRollBasicServiceDto autoRollBasicServiceDto : autoRollBasicService) {
|
for (AutoRollBasicServiceDto autoRollBasicServiceDto : autoRollBasicService) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
package com.openhis.web.inventorymanage.dto;
|
package com.openhis.web.inventorymanage.dto;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.core.common.annotation.Excel;
|
import com.core.common.annotation.Excel;
|
||||||
import com.core.common.annotation.ExcelExtra;
|
import com.core.common.annotation.ExcelExtra;
|
||||||
@@ -248,7 +249,8 @@ public class ProductTransferDetailDto {
|
|||||||
private Date occurrenceTime;
|
private Date occurrenceTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 单位列表
|
* 单位列表(非数据库字段,业务逻辑填充)
|
||||||
*/
|
*/
|
||||||
|
@TableField(exist = false)
|
||||||
private List<UnitDto> unitList;
|
private List<UnitDto> unitList;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package com.openhis.web.lab.appservice;
|
||||||
|
|
||||||
|
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentSelParam;
|
||||||
|
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentUpDto;
|
||||||
|
import com.core.common.core.domain.R;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检验项目 AppService 接口(独立操作 lab_activity_definition 表)
|
||||||
|
*/
|
||||||
|
public interface ILabActivityDefinitionAppService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询检验项目列表
|
||||||
|
*/
|
||||||
|
R<?> getLabActivityDefinitionPage(DiagnosisTreatmentSelParam selParam, String searchKey,
|
||||||
|
Integer pageNo, Integer pageSize, HttpServletRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据id查询检验项目详情
|
||||||
|
*/
|
||||||
|
R<?> getLabActivityDefinitionOne(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增检验项目
|
||||||
|
*/
|
||||||
|
R<?> addLabActivityDefinition(DiagnosisTreatmentUpDto dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑检验项目
|
||||||
|
*/
|
||||||
|
R<?> editLabActivityDefinition(DiagnosisTreatmentUpDto dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停用检验项目
|
||||||
|
*/
|
||||||
|
R<?> stopLabActivityDefinition(List<Long> ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用检验项目
|
||||||
|
*/
|
||||||
|
R<?> startLabActivityDefinition(List<Long> ids);
|
||||||
|
}
|
||||||
@@ -0,0 +1,189 @@
|
|||||||
|
package com.openhis.web.lab.appservice.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.core.common.core.domain.R;
|
||||||
|
import com.core.common.core.domain.model.LoginUser;
|
||||||
|
import com.core.common.utils.*;
|
||||||
|
import com.core.common.utils.bean.BeanUtils;
|
||||||
|
import com.openhis.common.constant.PromptMsgConstant;
|
||||||
|
import com.openhis.common.enums.ActivityType;
|
||||||
|
import com.openhis.common.enums.PublicationStatus;
|
||||||
|
import com.openhis.common.enums.Whether;
|
||||||
|
import com.core.common.utils.ChineseConvertUtils;
|
||||||
|
import com.openhis.common.utils.EnumUtils;
|
||||||
|
import com.openhis.common.utils.HisQueryUtils;
|
||||||
|
import com.openhis.common.enums.AssignSeqEnum;
|
||||||
|
import com.openhis.lab.domain.LabActivityDefinition;
|
||||||
|
import com.openhis.lab.service.ILabActivityDefinitionService;
|
||||||
|
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentDto;
|
||||||
|
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentSelParam;
|
||||||
|
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentUpDto;
|
||||||
|
import com.openhis.web.lab.appservice.ILabActivityDefinitionAppService;
|
||||||
|
import com.openhis.web.datadictionary.mapper.LabActivityDefinitionManageMapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检验项目 AppService 实现(独立操作 lab_activity_definition 表)
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class LabActivityDefinitionAppServiceImpl implements ILabActivityDefinitionAppService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ILabActivityDefinitionService labActivityDefinitionService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private LabActivityDefinitionManageMapper labActivityDefinitionManageMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AssignSeqUtil assignSeqUtil;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<?> getLabActivityDefinitionPage(DiagnosisTreatmentSelParam selParam, String searchKey,
|
||||||
|
Integer pageNo, Integer pageSize, HttpServletRequest request) {
|
||||||
|
if (selParam == null) {
|
||||||
|
selParam = new DiagnosisTreatmentSelParam();
|
||||||
|
}
|
||||||
|
if (selParam.getStatusEnum() == null) {
|
||||||
|
selParam.setStatusEnum(PublicationStatus.ACTIVE.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 临时移除需要手动拼别名条件的字段
|
||||||
|
Long inspectionTypeIdValue = null;
|
||||||
|
if (selParam.getInspectionTypeId() != null) {
|
||||||
|
inspectionTypeIdValue = selParam.getInspectionTypeId();
|
||||||
|
selParam.setInspectionTypeId(null);
|
||||||
|
}
|
||||||
|
Integer pricingFlagValue = null;
|
||||||
|
if (selParam.getPricingFlag() != null) {
|
||||||
|
pricingFlagValue = selParam.getPricingFlag();
|
||||||
|
selParam.setPricingFlag(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryWrapper<DiagnosisTreatmentDto> queryWrapper = HisQueryUtils.buildQueryWrapper(selParam,
|
||||||
|
searchKey, new HashSet<>(Arrays.asList("T1.bus_no", "T1.name", "T1.py_str", "T1.wb_str")), request);
|
||||||
|
|
||||||
|
if (inspectionTypeIdValue != null) {
|
||||||
|
queryWrapper.eq("T1.inspection_type_id", inspectionTypeIdValue);
|
||||||
|
selParam.setInspectionTypeId(inspectionTypeIdValue);
|
||||||
|
}
|
||||||
|
if (pricingFlagValue != null) {
|
||||||
|
queryWrapper.eq("T1.pricing_flag", pricingFlagValue);
|
||||||
|
selParam.setPricingFlag(pricingFlagValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
IPage<DiagnosisTreatmentDto> page = labActivityDefinitionManageMapper
|
||||||
|
.getLabActivityDefinitionPage(new Page<>(pageNo, pageSize), queryWrapper);
|
||||||
|
|
||||||
|
page.getRecords().forEach(e -> {
|
||||||
|
e.setYbFlag_enumText(EnumUtils.getInfoByValue(Whether.class, e.getYbFlag()));
|
||||||
|
e.setYbMatchFlag_enumText(EnumUtils.getInfoByValue(Whether.class, e.getYbMatchFlag()));
|
||||||
|
e.setTypeEnum_enumText(EnumUtils.getInfoByValue(ActivityType.class, e.getTypeEnum()));
|
||||||
|
e.setStatusEnum_enumText(EnumUtils.getInfoByValue(PublicationStatus.class, e.getStatusEnum()));
|
||||||
|
e.setPricingFlag_enumText(EnumUtils.getInfoByValue(Whether.class, e.getPricingFlag()));
|
||||||
|
});
|
||||||
|
|
||||||
|
return R.ok(page);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<?> getLabActivityDefinitionOne(Long id) {
|
||||||
|
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
||||||
|
DiagnosisTreatmentDto dto = labActivityDefinitionManageMapper.getLabActivityDefinitionOne(id, tenantId);
|
||||||
|
return R.ok(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<?> addLabActivityDefinition(DiagnosisTreatmentUpDto dto) {
|
||||||
|
if (dto.getOrgId() == null) {
|
||||||
|
dto.setOrgId(SecurityUtils.getLoginUser().getHospitalId());
|
||||||
|
}
|
||||||
|
|
||||||
|
LabActivityDefinition lab = new LabActivityDefinition();
|
||||||
|
BeanUtils.copyProperties(dto, lab);
|
||||||
|
lab.setSortOrder(dto.getSortOrder())
|
||||||
|
.setServiceRange(dto.getServiceRange())
|
||||||
|
.setInspectionTypeId(dto.getInspectionTypeId())
|
||||||
|
.setFeePackageId(dto.getFeePackageId())
|
||||||
|
.setSubItemId(dto.getSubItemId());
|
||||||
|
|
||||||
|
if (StringUtils.isEmpty(lab.getBusNo())) {
|
||||||
|
lab.setBusNo(assignSeqUtil.getSeq(AssignSeqEnum.ACTIVITY_DEFINITION_NUM.getPrefix(), 10));
|
||||||
|
}
|
||||||
|
lab.setPyStr(ChineseConvertUtils.toPinyinFirstLetter(lab.getName()));
|
||||||
|
lab.setWbStr(ChineseConvertUtils.toWBFirstLetter(lab.getName()));
|
||||||
|
lab.setStatusEnum(PublicationStatus.ACTIVE.getValue());
|
||||||
|
|
||||||
|
// 设置创建者和租户ID
|
||||||
|
String createBy = "system";
|
||||||
|
Integer tenantId = null;
|
||||||
|
try {
|
||||||
|
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||||
|
if (loginUser != null) {
|
||||||
|
createBy = loginUser.getUsername();
|
||||||
|
tenantId = loginUser.getTenantId();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 使用默认值
|
||||||
|
}
|
||||||
|
lab.setCreateBy(createBy);
|
||||||
|
lab.setTenantId(tenantId != null ? tenantId : 1);
|
||||||
|
if (lab.getCreateTime() == null) {
|
||||||
|
lab.setCreateTime(new java.util.Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
return labActivityDefinitionService.addLabActivityDefinition(lab)
|
||||||
|
? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"检验项目"}))
|
||||||
|
: R.fail(null, "检验编码已存在:" + lab.getBusNo());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<?> editLabActivityDefinition(DiagnosisTreatmentUpDto dto) {
|
||||||
|
LabActivityDefinition lab = new LabActivityDefinition();
|
||||||
|
BeanUtils.copyProperties(dto, lab);
|
||||||
|
lab.setSortOrder(dto.getSortOrder())
|
||||||
|
.setServiceRange(dto.getServiceRange())
|
||||||
|
.setInspectionTypeId(dto.getInspectionTypeId())
|
||||||
|
.setFeePackageId(dto.getFeePackageId())
|
||||||
|
.setSubItemId(dto.getSubItemId())
|
||||||
|
.setPricingFlag(dto.getPricingFlag());
|
||||||
|
lab.setPyStr(ChineseConvertUtils.toPinyinFirstLetter(lab.getName()));
|
||||||
|
lab.setWbStr(ChineseConvertUtils.toWBFirstLetter(lab.getName()));
|
||||||
|
|
||||||
|
return labActivityDefinitionService.updateById(lab)
|
||||||
|
? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"检验项目"}))
|
||||||
|
: R.fail(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<?> stopLabActivityDefinition(List<Long> ids) {
|
||||||
|
List<LabActivityDefinition> labList = new CopyOnWriteArrayList<>();
|
||||||
|
for (Long id : ids) {
|
||||||
|
LabActivityDefinition lab = new LabActivityDefinition();
|
||||||
|
lab.setId(id).setStatusEnum(PublicationStatus.RETIRED.getValue());
|
||||||
|
labList.add(lab);
|
||||||
|
}
|
||||||
|
labActivityDefinitionService.updateBatchById(labList);
|
||||||
|
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"检验项目"}));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<?> startLabActivityDefinition(List<Long> ids) {
|
||||||
|
List<LabActivityDefinition> labList = new CopyOnWriteArrayList<>();
|
||||||
|
for (Long id : ids) {
|
||||||
|
LabActivityDefinition lab = new LabActivityDefinition();
|
||||||
|
lab.setId(id).setStatusEnum(PublicationStatus.ACTIVE.getValue());
|
||||||
|
labList.add(lab);
|
||||||
|
}
|
||||||
|
labActivityDefinitionService.updateBatchById(labList);
|
||||||
|
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"检验项目"}));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -146,6 +146,9 @@ public class InspectionPackageController extends BaseController {
|
|||||||
if (inspectionPackage.getIsDisabled() != null) {
|
if (inspectionPackage.getIsDisabled() != null) {
|
||||||
queryWrapper.eq("is_disabled", inspectionPackage.getIsDisabled());
|
queryWrapper.eq("is_disabled", inspectionPackage.getIsDisabled());
|
||||||
}
|
}
|
||||||
|
if (inspectionPackage.getUserId() != null && !inspectionPackage.getUserId().isEmpty()) {
|
||||||
|
queryWrapper.like("user_id", inspectionPackage.getUserId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 默认只查询未删除的记录
|
// 默认只查询未删除的记录
|
||||||
|
|||||||
@@ -94,7 +94,6 @@ public class InspectionTypeController extends BaseController {
|
|||||||
|
|
||||||
// 查询是否存在相同编码的记录
|
// 查询是否存在相同编码的记录
|
||||||
List<InspectionType> existingRecords = inspectionTypeService.list(queryWrapper);
|
List<InspectionType> existingRecords = inspectionTypeService.list(queryWrapper);
|
||||||
log.debug("检查编码唯一性:code={}, 数据库中存在记录数={}", inspectionType.getCode(), existingRecords.size());
|
|
||||||
|
|
||||||
if (!existingRecords.isEmpty()) {
|
if (!existingRecords.isEmpty()) {
|
||||||
return AjaxResult.error("检验类型编码已存在");
|
return AjaxResult.error("检验类型编码已存在");
|
||||||
@@ -119,8 +118,6 @@ public class InspectionTypeController extends BaseController {
|
|||||||
return toAjax(result);
|
return toAjax(result);
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("新增检验类型失败:code={}, 错误信息:{}", inspectionType.getCode(), e.getMessage(), e);
|
|
||||||
|
|
||||||
// 捕获唯一性约束冲突异常
|
// 捕获唯一性约束冲突异常
|
||||||
if (e.getMessage().contains("uk_inspection_type_code") ||
|
if (e.getMessage().contains("uk_inspection_type_code") ||
|
||||||
e.getMessage().contains("duplicate key value") ||
|
e.getMessage().contains("duplicate key value") ||
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package com.openhis.web.lab.controller;
|
||||||
|
|
||||||
|
import com.core.common.core.domain.R;
|
||||||
|
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentSelParam;
|
||||||
|
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentUpDto;
|
||||||
|
import com.openhis.web.lab.appservice.ILabActivityDefinitionAppService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检验项目维护 Controller(独立操作 lab_activity_definition 表)
|
||||||
|
* 路径前缀:/lab/activity-definition
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/lab/activity-definition")
|
||||||
|
@Slf4j
|
||||||
|
public class LabActivityDefinitionController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ILabActivityDefinitionAppService labActivityDefinitionAppService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询检验项目列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/page")
|
||||||
|
public R<?> getPage(DiagnosisTreatmentSelParam selParam,
|
||||||
|
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
|
||||||
|
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||||
|
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
return labActivityDefinitionAppService.getLabActivityDefinitionPage(selParam, searchKey, pageNo, pageSize, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据id查询检验项目详情
|
||||||
|
*/
|
||||||
|
@GetMapping("/one")
|
||||||
|
public R<?> getOne(@RequestParam Long id) {
|
||||||
|
return labActivityDefinitionAppService.getLabActivityDefinitionOne(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增检验项目
|
||||||
|
*/
|
||||||
|
@PostMapping("/add")
|
||||||
|
public R<?> add(@Validated @RequestBody DiagnosisTreatmentUpDto dto) {
|
||||||
|
return labActivityDefinitionAppService.addLabActivityDefinition(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑检验项目
|
||||||
|
*/
|
||||||
|
@PutMapping("/edit")
|
||||||
|
public R<?> edit(@RequestBody DiagnosisTreatmentUpDto dto) {
|
||||||
|
return labActivityDefinitionAppService.editLabActivityDefinition(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停用检验项目
|
||||||
|
*/
|
||||||
|
@PutMapping("/stop")
|
||||||
|
public R<?> stop(@RequestBody List<Long> ids) {
|
||||||
|
return labActivityDefinitionAppService.stopLabActivityDefinition(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用检验项目
|
||||||
|
*/
|
||||||
|
@PutMapping("/start")
|
||||||
|
public R<?> start(@RequestBody List<Long> ids) {
|
||||||
|
return labActivityDefinitionAppService.startLabActivityDefinition(ids);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -55,6 +55,8 @@ import com.openhis.web.paymentmanage.dto.CancelPaymentDto;
|
|||||||
import com.openhis.web.paymentmanage.dto.Clinic2207OrderResultDto;
|
import com.openhis.web.paymentmanage.dto.Clinic2207OrderResultDto;
|
||||||
import com.openhis.web.paymentmanage.mapper.PaymentMapper;
|
import com.openhis.web.paymentmanage.mapper.PaymentMapper;
|
||||||
import com.openhis.web.personalization.dto.ActivityDeviceDto;
|
import com.openhis.web.personalization.dto.ActivityDeviceDto;
|
||||||
|
import com.openhis.triageandqueuemanage.domain.TriageQueueItem;
|
||||||
|
import com.openhis.triageandqueuemanage.service.TriageQueueItemService;
|
||||||
import com.openhis.workflow.domain.ServiceRequest;
|
import com.openhis.workflow.domain.ServiceRequest;
|
||||||
import com.openhis.workflow.service.IDeviceDispenseService;
|
import com.openhis.workflow.service.IDeviceDispenseService;
|
||||||
import com.openhis.workflow.service.IDeviceRequestService;
|
import com.openhis.workflow.service.IDeviceRequestService;
|
||||||
@@ -81,9 +83,11 @@ import javax.annotation.Resource;
|
|||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -149,6 +153,8 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
|||||||
@Resource
|
@Resource
|
||||||
private OutpatientRegistrationAppMapper outpatientRegistrationAppMapper;
|
private OutpatientRegistrationAppMapper outpatientRegistrationAppMapper;
|
||||||
@Resource
|
@Resource
|
||||||
|
private TriageQueueItemService triageQueueItemService;
|
||||||
|
@Resource
|
||||||
private IRegService iRegService;
|
private IRegService iRegService;
|
||||||
@Resource
|
@Resource
|
||||||
private IPatientService iPatientService;
|
private IPatientService iPatientService;
|
||||||
@@ -255,7 +261,9 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
|||||||
|
|
||||||
// 账户id,对应的账单列表
|
// 账户id,对应的账单列表
|
||||||
Map<Long, List<ChargeItem>> chargeItemMapByAccountId
|
Map<Long, List<ChargeItem>> chargeItemMapByAccountId
|
||||||
= chargeItemList.stream().collect(Collectors.groupingBy(ChargeItem::getAccountId));
|
= chargeItemList.stream()
|
||||||
|
.filter(item -> item.getAccountId() != null)
|
||||||
|
.collect(Collectors.groupingBy(ChargeItem::getAccountId));
|
||||||
// 查询合同信息
|
// 查询合同信息
|
||||||
List<Contract> contractList = contractService.list();
|
List<Contract> contractList = contractService.list();
|
||||||
|
|
||||||
@@ -1928,6 +1936,80 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
|||||||
|
|
||||||
// 就诊ID
|
// 就诊ID
|
||||||
Long encounterId = iEncounterService.saveEncounterByRegister(encounter);
|
Long encounterId = iEncounterService.saveEncounterByRegister(encounter);
|
||||||
|
|
||||||
|
// 创建 triage_queue_item 队列记录
|
||||||
|
try {
|
||||||
|
Integer tenantId = encounter.getTenantId() != null ? encounter.getTenantId() : SecurityUtils.getLoginUser().getTenantId();
|
||||||
|
LocalDate queueDate = LocalDate.now();
|
||||||
|
|
||||||
|
// 查询当前科室当天的最大排队序号
|
||||||
|
Integer maxOrder = triageQueueItemService.list(
|
||||||
|
new LambdaQueryWrapper<TriageQueueItem>()
|
||||||
|
.eq(TriageQueueItem::getTenantId, tenantId)
|
||||||
|
.eq(TriageQueueItem::getOrganizationId, encounter.getOrganizationId())
|
||||||
|
.eq(TriageQueueItem::getQueueDate, queueDate)
|
||||||
|
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||||
|
.ne(TriageQueueItem::getStatus, "COMPLETED")
|
||||||
|
).stream()
|
||||||
|
.map(TriageQueueItem::getQueueOrder)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.max(Integer::compareTo)
|
||||||
|
.orElse(0);
|
||||||
|
|
||||||
|
// 获取患者信息
|
||||||
|
Patient patient = iPatientService.getById(encounter.getPatientId());
|
||||||
|
String patientName = patient != null ? patient.getName() : null;
|
||||||
|
|
||||||
|
// 获取挂号医生信息
|
||||||
|
String practitionerName = null;
|
||||||
|
Long queuePractitionerId = null;
|
||||||
|
if (encounterParticipantFormData.getPractitionerId() != null) {
|
||||||
|
Practitioner practitioner = iPractitionerService.getById(encounterParticipantFormData.getPractitionerId());
|
||||||
|
if (practitioner != null) {
|
||||||
|
practitionerName = practitioner.getName();
|
||||||
|
queuePractitionerId = practitioner.getId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取科室信息
|
||||||
|
Organization organization = iOrganizationService.getById(encounter.getOrganizationId());
|
||||||
|
String organizationName = organization != null ? organization.getName() : null;
|
||||||
|
|
||||||
|
// 获取服务项目信息(挂号类型)
|
||||||
|
String healthcareName = null;
|
||||||
|
if (encounter.getServiceTypeId() != null) {
|
||||||
|
HealthcareService healthcareService = healthcareServiceService.getById(encounter.getServiceTypeId());
|
||||||
|
if (healthcareService != null) {
|
||||||
|
healthcareName = healthcareService.getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建队列项
|
||||||
|
TriageQueueItem queueItem = new TriageQueueItem()
|
||||||
|
.setTenantId(tenantId)
|
||||||
|
.setQueueDate(queueDate)
|
||||||
|
.setOrganizationId(encounter.getOrganizationId())
|
||||||
|
.setOrganizationName(organizationName)
|
||||||
|
.setEncounterId(encounterId)
|
||||||
|
.setPatientId(encounter.getPatientId())
|
||||||
|
.setPatientName(patientName)
|
||||||
|
.setHealthcareName(healthcareName)
|
||||||
|
.setPractitionerId(queuePractitionerId)
|
||||||
|
.setPractitionerName(practitionerName)
|
||||||
|
.setRoomNo(null)
|
||||||
|
.setStatus("WAITING")
|
||||||
|
.setQueueOrder(maxOrder + 1)
|
||||||
|
.setDeleteFlag("0")
|
||||||
|
.setCreateTime(LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS))
|
||||||
|
.setUpdateTime(LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS));
|
||||||
|
|
||||||
|
triageQueueItemService.save(queueItem);
|
||||||
|
logger.info("挂号时创建队列记录成功,encounterId={}, queueItemId={}", encounterId, queueItem.getId());
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("挂号时创建队列记录失败,encounterId={}", encounterId, e);
|
||||||
|
// 队列记录创建失败不影响挂号流程
|
||||||
|
}
|
||||||
|
|
||||||
// 保存就诊位置信息
|
// 保存就诊位置信息
|
||||||
// 挂号时不选Location了
|
// 挂号时不选Location了
|
||||||
// encounterLocationFormData.setEncounterId(encounterId);
|
// encounterLocationFormData.setEncounterId(encounterId);
|
||||||
@@ -2095,7 +2177,7 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
|||||||
adviceBaseDto.setAdviceDefinitionId(activityDeviceDto.getDevActId());
|
adviceBaseDto.setAdviceDefinitionId(activityDeviceDto.getDevActId());
|
||||||
// 对应的诊疗医嘱信息
|
// 对应的诊疗医嘱信息
|
||||||
AdviceBaseDto activityAdviceBaseDto = iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, null,
|
AdviceBaseDto activityAdviceBaseDto = iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, null,
|
||||||
null, null, organizationId, 1, 1, Whether.NO.getValue(), List.of(1, 2, 3), null).getRecords().get(0);
|
null, null, organizationId, 1, 1, Whether.NO.getValue(), List.of(1, 2, 3), null, null).getRecords().get(0);
|
||||||
// 价格信息
|
// 价格信息
|
||||||
if (activityAdviceBaseDto != null) {
|
if (activityAdviceBaseDto != null) {
|
||||||
// 费用定价
|
// 费用定价
|
||||||
@@ -2251,7 +2333,9 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
|||||||
= iChargeItemService.getChargeItemBaseInfoByIds(prePaymentDto.getChargeItemIds());
|
= iChargeItemService.getChargeItemBaseInfoByIds(prePaymentDto.getChargeItemIds());
|
||||||
|
|
||||||
Map<String, List<ChargeItemBaseInfoDto>> chargeItemKVByContractNo
|
Map<String, List<ChargeItemBaseInfoDto>> chargeItemKVByContractNo
|
||||||
= chargeItemBaseInfoByIds.stream().collect(Collectors.groupingBy(ChargeItemBaseInfoDto::getContractNo));
|
= chargeItemBaseInfoByIds.stream()
|
||||||
|
.filter(dto -> dto.getContractNo() != null && !dto.getContractNo().isEmpty())
|
||||||
|
.collect(Collectors.groupingBy(ChargeItemBaseInfoDto::getContractNo));
|
||||||
|
|
||||||
List<InpatientPreSettleDto> yb2303OutputSetInfos = new ArrayList<>();
|
List<InpatientPreSettleDto> yb2303OutputSetInfos = new ArrayList<>();
|
||||||
Yb2303OutputSetInfo yb2303OutputSetInfo;
|
Yb2303OutputSetInfo yb2303OutputSetInfo;
|
||||||
@@ -2379,13 +2463,17 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
|||||||
List<ChargeItemBaseInfoDto> chargeItemBaseInfoByIds
|
List<ChargeItemBaseInfoDto> chargeItemBaseInfoByIds
|
||||||
= iChargeItemService.getChargeItemBaseInfoByIds(paymentDto.getChargeItemIds());
|
= iChargeItemService.getChargeItemBaseInfoByIds(paymentDto.getChargeItemIds());
|
||||||
Map<String, List<ChargeItemBaseInfoDto>> chargeItemKVByContractNo
|
Map<String, List<ChargeItemBaseInfoDto>> chargeItemKVByContractNo
|
||||||
= chargeItemBaseInfoByIds.stream().collect(Collectors.groupingBy(ChargeItemBaseInfoDto::getContractNo));
|
= chargeItemBaseInfoByIds.stream()
|
||||||
|
.filter(dto -> dto.getContractNo() != null && !dto.getContractNo().isEmpty())
|
||||||
|
.collect(Collectors.groupingBy(ChargeItemBaseInfoDto::getContractNo));
|
||||||
|
|
||||||
List<Account> accountList = iAccountService.getAccountListByEncounter(paymentDto.getEncounterId());
|
List<Account> accountList = iAccountService.getAccountListByEncounter(paymentDto.getEncounterId());
|
||||||
if (accountList.isEmpty()) {
|
if (accountList.isEmpty()) {
|
||||||
throw new ServiceException("未查询到账户信息");
|
throw new ServiceException("未查询到账户信息");
|
||||||
}
|
}
|
||||||
Map<Long, List<Account>> accountKVById = accountList.stream().collect(Collectors.groupingBy(Account::getId));
|
Map<Long, List<Account>> accountKVById = accountList.stream()
|
||||||
|
.filter(acc -> acc.getId() != null)
|
||||||
|
.collect(Collectors.groupingBy(Account::getId));
|
||||||
|
|
||||||
com.openhis.financial.model.PaymentResult paymentResult;
|
com.openhis.financial.model.PaymentResult paymentResult;
|
||||||
List<com.openhis.financial.model.PaymentResult> paymentResultList = new ArrayList<>();
|
List<com.openhis.financial.model.PaymentResult> paymentResultList = new ArrayList<>();
|
||||||
@@ -2395,7 +2483,9 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
|||||||
|
|
||||||
// <3>收费详情按照收费批次进行分组后结算
|
// <3>收费详情按照收费批次进行分组后结算
|
||||||
Map<Long, List<PaymentRecDetail>> payTransNoMap
|
Map<Long, List<PaymentRecDetail>> payTransNoMap
|
||||||
= paymentRecDetails.stream().collect(Collectors.groupingBy(PaymentRecDetail::getAccountId));
|
= paymentRecDetails.stream()
|
||||||
|
.filter(detail -> detail.getAccountId() != null)
|
||||||
|
.collect(Collectors.groupingBy(PaymentRecDetail::getAccountId));
|
||||||
|
|
||||||
for (Map.Entry<Long, List<PaymentRecDetail>> stringListEntry : payTransNoMap.entrySet()) {
|
for (Map.Entry<Long, List<PaymentRecDetail>> stringListEntry : payTransNoMap.entrySet()) {
|
||||||
// paymentResult = new PaymentResult();
|
// paymentResult = new PaymentResult();
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ public class OrdersGroupPackageAppServiceImpl implements IOrdersGroupPackageAppS
|
|||||||
// 医嘱下拉详细信息
|
// 医嘱下拉详细信息
|
||||||
List<AdviceBaseDto> personalRecords =
|
List<AdviceBaseDto> personalRecords =
|
||||||
iDoctorStationAdviceAppService.getAdviceBaseInfo(null, null, null, orderDefinitionIdParamList,
|
iDoctorStationAdviceAppService.getAdviceBaseInfo(null, null, null, orderDefinitionIdParamList,
|
||||||
organizationId, 1, 100, Whether.NO.getValue(), List.of(1, 2, 3), null).getRecords();
|
organizationId, 1, 100, Whether.NO.getValue(), List.of(1, 2, 3), null, null).getRecords();
|
||||||
// 创建AdviceBaseDto的映射,以adviceDefinitionId为key
|
// 创建AdviceBaseDto的映射,以adviceDefinitionId为key
|
||||||
Map<Long, AdviceBaseDto> adviceMap = personalRecords.stream().collect(Collectors
|
Map<Long, AdviceBaseDto> adviceMap = personalRecords.stream().collect(Collectors
|
||||||
.toMap(AdviceBaseDto::getAdviceDefinitionId, advice -> advice, (existing, replacement) -> existing // 如果有重复key,保留第一个
|
.toMap(AdviceBaseDto::getAdviceDefinitionId, advice -> advice, (existing, replacement) -> existing // 如果有重复key,保留第一个
|
||||||
@@ -248,7 +248,7 @@ public class OrdersGroupPackageAppServiceImpl implements IOrdersGroupPackageAppS
|
|||||||
// 医嘱下拉详细信息
|
// 医嘱下拉详细信息
|
||||||
List<AdviceBaseDto> personalRecords =
|
List<AdviceBaseDto> personalRecords =
|
||||||
iDoctorStationAdviceAppService.getAdviceBaseInfo(null, null, null, orderDefinitionIdParamList,
|
iDoctorStationAdviceAppService.getAdviceBaseInfo(null, null, null, orderDefinitionIdParamList,
|
||||||
organizationId, 1, 100, Whether.NO.getValue(), List.of(1, 2, 3), null).getRecords();
|
organizationId, 1, 100, Whether.NO.getValue(), List.of(1, 2, 3), null, null).getRecords();
|
||||||
// 创建AdviceBaseDto的映射,以adviceDefinitionId为key
|
// 创建AdviceBaseDto的映射,以adviceDefinitionId为key
|
||||||
Map<Long, AdviceBaseDto> adviceMap = personalRecords.stream().collect(Collectors
|
Map<Long, AdviceBaseDto> adviceMap = personalRecords.stream().collect(Collectors
|
||||||
.toMap(AdviceBaseDto::getAdviceDefinitionId, advice -> advice, (existing, replacement) -> existing // 如果有重复key,保留第一个
|
.toMap(AdviceBaseDto::getAdviceDefinitionId, advice -> advice, (existing, replacement) -> existing // 如果有重复key,保留第一个
|
||||||
@@ -297,7 +297,7 @@ public class OrdersGroupPackageAppServiceImpl implements IOrdersGroupPackageAppS
|
|||||||
// 医嘱下拉详细信息
|
// 医嘱下拉详细信息
|
||||||
List<AdviceBaseDto> personalRecords =
|
List<AdviceBaseDto> personalRecords =
|
||||||
iDoctorStationAdviceAppService.getAdviceBaseInfo(null, null, null, orderDefinitionIdParamList,
|
iDoctorStationAdviceAppService.getAdviceBaseInfo(null, null, null, orderDefinitionIdParamList,
|
||||||
organizationId, 1, 100, Whether.NO.getValue(), List.of(1, 2, 3), null).getRecords();
|
organizationId, 1, 100, Whether.NO.getValue(), List.of(1, 2, 3), null, null).getRecords();
|
||||||
// 创建AdviceBaseDto的映射,以adviceDefinitionId为key
|
// 创建AdviceBaseDto的映射,以adviceDefinitionId为key
|
||||||
Map<Long, AdviceBaseDto> adviceMap = personalRecords.stream().collect(Collectors
|
Map<Long, AdviceBaseDto> adviceMap = personalRecords.stream().collect(Collectors
|
||||||
.toMap(AdviceBaseDto::getAdviceDefinitionId, advice -> advice, (existing, replacement) -> existing // 如果有重复key,保留第一个
|
.toMap(AdviceBaseDto::getAdviceDefinitionId, advice -> advice, (existing, replacement) -> existing // 如果有重复key,保留第一个
|
||||||
|
|||||||
@@ -394,7 +394,7 @@ public class MedicalDeviceDispenseAppServiceImpl implements IMedicalDeviceDispen
|
|||||||
}
|
}
|
||||||
List<ChargeItem> chargeItemList = chargeItemService.listByIds(chargeItemIds);
|
List<ChargeItem> chargeItemList = chargeItemService.listByIds(chargeItemIds);
|
||||||
if (chargeItemList == null || chargeItemList.isEmpty()) {
|
if (chargeItemList == null || chargeItemList.isEmpty()) {
|
||||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
return R.fail("未查询到耗材收费项目信息");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取发申请id列表
|
// 获取发申请id列表
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import com.core.common.exception.ServiceException;
|
|||||||
import com.core.common.utils.AssignSeqUtil;
|
import com.core.common.utils.AssignSeqUtil;
|
||||||
import com.core.common.utils.MessageUtils;
|
import com.core.common.utils.MessageUtils;
|
||||||
import com.core.common.utils.SecurityUtils;
|
import com.core.common.utils.SecurityUtils;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.openhis.administration.domain.ChargeItem;
|
import com.openhis.administration.domain.ChargeItem;
|
||||||
import com.openhis.administration.service.IChargeItemService;
|
import com.openhis.administration.service.IChargeItemService;
|
||||||
import com.openhis.common.constant.CommonConstants;
|
import com.openhis.common.constant.CommonConstants;
|
||||||
@@ -28,8 +29,10 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -132,6 +135,7 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
|
|||||||
ChargeItem chargeItem;
|
ChargeItem chargeItem;
|
||||||
// 诊疗集合
|
// 诊疗集合
|
||||||
List<ActivitySaveDto> activityList = requestFormSaveDto.getActivityList();
|
List<ActivitySaveDto> activityList = requestFormSaveDto.getActivityList();
|
||||||
|
log.info("保存申请单,typeCode={}, activityListSize={}, encounterId={}", typeCode, activityList != null ? activityList.size() : 0, encounterId);
|
||||||
// 诊疗执行科室配置
|
// 诊疗执行科室配置
|
||||||
List<ActivityOrganizationConfigDto> activityOrganizationConfig =
|
List<ActivityOrganizationConfigDto> activityOrganizationConfig =
|
||||||
requestFormManageAppMapper.getActivityOrganizationConfig(typeCode);
|
requestFormManageAppMapper.getActivityOrganizationConfig(typeCode);
|
||||||
@@ -211,6 +215,189 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果是手术申请单,需要额外生成手术医嘱
|
||||||
|
log.info("【调试】判断手术医嘱生成条件: typeCode={}, PROCEDURE.code={}, typeCode类型={}, PROCEDURE.code类型={}",
|
||||||
|
typeCode, ActivityDefCategory.PROCEDURE.getCode(),
|
||||||
|
typeCode != null ? typeCode.getClass().getName() : "null",
|
||||||
|
ActivityDefCategory.PROCEDURE.getCode().getClass().getName());
|
||||||
|
boolean isProcedure = ActivityDefCategory.PROCEDURE.getCode().equals(typeCode);
|
||||||
|
log.info("【调试】判断结果: isProcedure={}, typeCode字符串={}, PROCEDURE.code字符串={}",
|
||||||
|
isProcedure,
|
||||||
|
typeCode != null ? "'" + typeCode + "'" : "null",
|
||||||
|
"'" + ActivityDefCategory.PROCEDURE.getCode() + "'");
|
||||||
|
if (isProcedure) {
|
||||||
|
log.info("开始生成手术医嘱,encounterId={}, patientId={}, typeCode={}, activityListSize={}",
|
||||||
|
encounterId, patientId, typeCode, activityList != null ? activityList.size() : 0);
|
||||||
|
try {
|
||||||
|
// 从 descJson 中解析手术信息
|
||||||
|
String descJson = requestFormSaveDto.getDescJson();
|
||||||
|
Map<String, Object> descMap = null;
|
||||||
|
if (descJson != null && !descJson.isEmpty()) {
|
||||||
|
try {
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
descMap = objectMapper.readValue(descJson, Map.class);
|
||||||
|
log.info("解析手术申请单 descJson 成功: {}", descMap);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("解析手术申请单 descJson 失败: {}", descJson, e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("手术申请单 descJson 为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取手术信息
|
||||||
|
String surgeryName = descMap != null ? (String) descMap.get("surgeryName") : null;
|
||||||
|
String surgeryCode = descMap != null ? (String) descMap.get("surgeryCode") : null;
|
||||||
|
String surgeryFee = descMap != null ? (String) descMap.get("surgeryFee") : null;
|
||||||
|
String anesthesiaFee = descMap != null ? (String) descMap.get("anesthesiaFee") : null;
|
||||||
|
String plannedTime = descMap != null ? (String) descMap.get("plannedTime") : null;
|
||||||
|
String surgeryIndication = descMap != null ? (String) descMap.get("surgeryIndication") : null;
|
||||||
|
String preoperativeDiagnosis = descMap != null ? (String) descMap.get("preoperativeDiagnosis") : null;
|
||||||
|
|
||||||
|
// 🔧 BugFix#318: 从 activityList 获取手术项目名称
|
||||||
|
String adviceDefinitionName = null;
|
||||||
|
if (activityList != null && !activityList.isEmpty()) {
|
||||||
|
adviceDefinitionName = activityList.get(0).getAdviceDefinitionName();
|
||||||
|
log.info("从 activityList 获取手术项目名称: {}", adviceDefinitionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("手术信息: surgeryName={}, surgeryCode={}, surgeryFee={}, anesthesiaFee={}, adviceDefinitionName={}",
|
||||||
|
surgeryName, surgeryCode, surgeryFee, anesthesiaFee, adviceDefinitionName);
|
||||||
|
|
||||||
|
// 生成手术医嘱
|
||||||
|
ServiceRequest surgeryServiceRequest = new ServiceRequest();
|
||||||
|
surgeryServiceRequest.setStatusEnum(RequestStatus.DRAFT.getValue());
|
||||||
|
surgeryServiceRequest.setBusNo(String.format("%04d", (int) (Math.random() * 10000)));
|
||||||
|
surgeryServiceRequest.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue());
|
||||||
|
surgeryServiceRequest.setPrescriptionNo(prescriptionNo);
|
||||||
|
surgeryServiceRequest.setTherapyEnum(TherapyTimeType.TEMPORARY.getValue());
|
||||||
|
surgeryServiceRequest.setQuantity(BigDecimal.valueOf(1));
|
||||||
|
surgeryServiceRequest.setUnitCode("次");
|
||||||
|
surgeryServiceRequest.setCategoryEnum(4); // 4-手术
|
||||||
|
// 优先从 activityList 获取手术 ID
|
||||||
|
if (activityList != null && !activityList.isEmpty()) {
|
||||||
|
Long activityId = activityList.get(0).getAdviceDefinitionId();
|
||||||
|
surgeryServiceRequest.setActivityId(activityId);
|
||||||
|
log.info("从 activityList 获取手术ID: {}", activityId);
|
||||||
|
} else {
|
||||||
|
log.warn("activityList 为空,无法获取手术ID");
|
||||||
|
}
|
||||||
|
surgeryServiceRequest.setPatientId(patientId);
|
||||||
|
surgeryServiceRequest.setRequesterId(practitionerId);
|
||||||
|
surgeryServiceRequest.setEncounterId(encounterId);
|
||||||
|
surgeryServiceRequest.setAuthoredTime(curDate);
|
||||||
|
surgeryServiceRequest.setOrgId(orgId);
|
||||||
|
|
||||||
|
// 设置手术相关信息到 contentJson 字段
|
||||||
|
Map<String, String> contentMap = new java.util.HashMap<>();
|
||||||
|
// 🔧 BugFix#318: 优先使用 activityList 中的手术项目名称
|
||||||
|
if (adviceDefinitionName != null && !adviceDefinitionName.isEmpty()) {
|
||||||
|
contentMap.put("surgeryName", adviceDefinitionName);
|
||||||
|
} else if (surgeryName != null && !surgeryName.isEmpty()) {
|
||||||
|
contentMap.put("surgeryName", surgeryName);
|
||||||
|
}
|
||||||
|
if (surgeryCode != null && !surgeryCode.isEmpty()) {
|
||||||
|
contentMap.put("surgeryCode", surgeryCode);
|
||||||
|
}
|
||||||
|
if (plannedTime != null && !plannedTime.isEmpty()) {
|
||||||
|
contentMap.put("plannedTime", plannedTime);
|
||||||
|
}
|
||||||
|
if (surgeryIndication != null && !surgeryIndication.isEmpty()) {
|
||||||
|
contentMap.put("surgeryIndication", surgeryIndication);
|
||||||
|
}
|
||||||
|
if (preoperativeDiagnosis != null && !preoperativeDiagnosis.isEmpty()) {
|
||||||
|
contentMap.put("preoperativeDiagnosis", preoperativeDiagnosis);
|
||||||
|
}
|
||||||
|
if (!contentMap.isEmpty()) {
|
||||||
|
try {
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
surgeryServiceRequest.setContentJson(objectMapper.writeValueAsString(contentMap));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("序列化手术信息失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
iServiceRequestService.save(surgeryServiceRequest);
|
||||||
|
log.info("手术医嘱生成成功,serviceRequestId={}, prescriptionNo={}", surgeryServiceRequest.getId(), prescriptionNo);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("保存手术医嘱失败", e);
|
||||||
|
throw new ServiceException("保存手术医嘱失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成手术收费项目
|
||||||
|
try {
|
||||||
|
ChargeItem surgeryChargeItem = new ChargeItem();
|
||||||
|
surgeryChargeItem.setStatusEnum(ChargeItemStatus.DRAFT.getValue());
|
||||||
|
surgeryChargeItem.setBusNo(AssignSeqEnum.CHARGE_ITEM_NO.getPrefix().concat(surgeryServiceRequest.getBusNo()));
|
||||||
|
surgeryChargeItem.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue());
|
||||||
|
surgeryChargeItem.setPatientId(patientId);
|
||||||
|
surgeryChargeItem.setContextEnum(6); // 6-手术
|
||||||
|
surgeryChargeItem.setEncounterId(encounterId);
|
||||||
|
surgeryChargeItem.setEntererId(practitionerId);
|
||||||
|
surgeryChargeItem.setEnteredDate(curDate);
|
||||||
|
surgeryChargeItem.setServiceTable(CommonConstants.TableName.WOR_SERVICE_REQUEST);
|
||||||
|
surgeryChargeItem.setServiceId(surgeryServiceRequest.getId());
|
||||||
|
surgeryChargeItem.setProductTable(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION);
|
||||||
|
// 优先从 activityList 获取 productId
|
||||||
|
if (activityList != null && !activityList.isEmpty()) {
|
||||||
|
surgeryChargeItem.setProductId(activityList.get(0).getAdviceDefinitionId());
|
||||||
|
surgeryChargeItem.setAccountId(activityList.get(0).getAccountId());
|
||||||
|
}
|
||||||
|
surgeryChargeItem.setRequestingOrgId(orgId);
|
||||||
|
surgeryChargeItem.setQuantityValue(BigDecimal.valueOf(1));
|
||||||
|
surgeryChargeItem.setQuantityUnit("次");
|
||||||
|
// 设置手术费用
|
||||||
|
if (surgeryFee != null && !surgeryFee.isEmpty()) {
|
||||||
|
try {
|
||||||
|
surgeryChargeItem.setUnitPrice(new BigDecimal(surgeryFee));
|
||||||
|
surgeryChargeItem.setTotalPrice(new BigDecimal(surgeryFee));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
log.warn("手术费用格式不正确:{}", surgeryFee);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iChargeItemService.save(surgeryChargeItem);
|
||||||
|
log.info("手术收费项目生成成功,chargeItemId={}", surgeryChargeItem.getId());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("生成手术收费项目失败", e);
|
||||||
|
throw new ServiceException("生成手术收费项目失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果存在麻醉费用,生成麻醉收费项目
|
||||||
|
if (anesthesiaFee != null && !anesthesiaFee.isEmpty()) {
|
||||||
|
try {
|
||||||
|
BigDecimal anesthesiaFeeAmount = new BigDecimal(anesthesiaFee);
|
||||||
|
if (anesthesiaFeeAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||||
|
ChargeItem anesthesiaChargeItem = new ChargeItem();
|
||||||
|
anesthesiaChargeItem.setStatusEnum(ChargeItemStatus.DRAFT.getValue());
|
||||||
|
anesthesiaChargeItem.setBusNo(AssignSeqEnum.CHARGE_ITEM_NO.getPrefix().concat(surgeryServiceRequest.getBusNo()));
|
||||||
|
anesthesiaChargeItem.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue());
|
||||||
|
anesthesiaChargeItem.setPatientId(patientId);
|
||||||
|
anesthesiaChargeItem.setContextEnum(3); // 3-诊疗
|
||||||
|
anesthesiaChargeItem.setEncounterId(encounterId);
|
||||||
|
anesthesiaChargeItem.setEntererId(practitionerId);
|
||||||
|
anesthesiaChargeItem.setEnteredDate(curDate);
|
||||||
|
anesthesiaChargeItem.setServiceTable(CommonConstants.TableName.WOR_SERVICE_REQUEST);
|
||||||
|
anesthesiaChargeItem.setServiceId(surgeryServiceRequest.getId());
|
||||||
|
anesthesiaChargeItem.setProductTable(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION);
|
||||||
|
anesthesiaChargeItem.setRequestingOrgId(orgId);
|
||||||
|
anesthesiaChargeItem.setQuantityValue(BigDecimal.valueOf(1));
|
||||||
|
anesthesiaChargeItem.setQuantityUnit("次");
|
||||||
|
anesthesiaChargeItem.setUnitPrice(anesthesiaFeeAmount);
|
||||||
|
anesthesiaChargeItem.setTotalPrice(anesthesiaFeeAmount);
|
||||||
|
iChargeItemService.save(anesthesiaChargeItem);
|
||||||
|
log.info("麻醉收费项目生成成功");
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
log.warn("麻醉费用格式不正确:{}", anesthesiaFee);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("生成手术医嘱过程中发生异常", e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.info("不是手术申请单,跳过手术医嘱生成,typeCode={}", typeCode);
|
||||||
|
}
|
||||||
|
|
||||||
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"申请单"}));
|
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"申请单"}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user