Compare commits
18 Commits
bug/334
...
d7b3403524
| Author | SHA1 | Date | |
|---|---|---|---|
| d7b3403524 | |||
|
|
e9d4f57815 | ||
| e573d9f68b | |||
| 2584c8f076 | |||
| 7b6c972a12 | |||
|
|
c3f1b105e9 | ||
| 616c2d21a6 | |||
| 63a9e26abf | |||
|
|
d2dfc714ec | ||
|
|
5c8bfbc98b | ||
|
|
885a147420 | ||
|
|
afbf3f9075 | ||
|
|
720cac8a8f | ||
| 5497c99f0c | |||
|
|
d8b4aed16c | ||
| efc97c855c | |||
| 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]:
|
||||||
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,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;
|
||||||
@@ -497,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>()
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -87,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;
|
||||||
|
|
||||||
/** 实际开始时间 */
|
/** 实际开始时间 */
|
||||||
|
|||||||
@@ -421,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);
|
||||||
@@ -464,6 +478,18 @@ 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) 状态禁止作废
|
// 作废:状态校验 - 已确认(20)、已签名(30)、已完成(40) 状态禁止作废
|
||||||
ConsultationStatusEnum currentStatus = ConsultationStatusEnum.getByCode(entity.getConsultationStatus());
|
ConsultationStatusEnum currentStatus = ConsultationStatusEnum.getByCode(entity.getConsultationStatus());
|
||||||
@@ -480,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;
|
||||||
@@ -668,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);
|
||||||
@@ -1201,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-已确认(待签名)
|
||||||
@@ -1233,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-已确认
|
||||||
@@ -1322,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()); // 已确认
|
||||||
@@ -1634,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)
|
||||||
|
|||||||
@@ -205,6 +205,11 @@ 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,
|
||||||
@@ -561,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)
|
||||||
@@ -770,6 +794,18 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🔧 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
|
||||||
@@ -932,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, 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());
|
||||||
@@ -946,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();
|
||||||
@@ -1137,6 +1187,18 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🔧 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()); // 请求状态
|
||||||
@@ -1364,6 +1426,18 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🔧 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();
|
||||||
@@ -1495,6 +1569,15 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
// }
|
// }
|
||||||
// log.error(e.getMessage(), 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@
|
|||||||
T9.gender_enum AS genderEnum,
|
T9.gender_enum AS genderEnum,
|
||||||
T9.id_card AS idCard,
|
T9.id_card AS idCard,
|
||||||
T9.status_enum AS statusEnum,
|
T9.status_enum AS statusEnum,
|
||||||
T9.register_time AS registerTime,
|
T9.register_time AS register_time,
|
||||||
T9.total_price AS totalPrice,
|
T9.total_price AS totalPrice,
|
||||||
T9.account_name AS accountName,
|
T9.account_name AS accountName,
|
||||||
T9.enterer_name AS entererName,
|
T9.enterer_name AS entererName,
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
T8.gender_enum AS gender_enum,
|
T8.gender_enum AS gender_enum,
|
||||||
T8.id_card AS id_card,
|
T8.id_card AS id_card,
|
||||||
T1.status_enum AS status_enum,
|
T1.status_enum AS status_enum,
|
||||||
T1.create_time AS register_time,
|
T1.create_time AS "register_time",
|
||||||
T10.total_price,
|
T10.total_price,
|
||||||
T11."name" AS account_name,
|
T11."name" AS account_name,
|
||||||
T12."name" AS enterer_name,
|
T12."name" AS enterer_name,
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
T8.phone AS phone,
|
T8.phone AS phone,
|
||||||
T8.birth_date AS birth_date,
|
T8.birth_date AS birth_date,
|
||||||
T1.status_enum AS status_enum,
|
T1.status_enum AS status_enum,
|
||||||
T1.create_time AS register_time,
|
T1.create_time AS "register_time",
|
||||||
T1.reception_time AS reception_time,
|
T1.reception_time AS reception_time,
|
||||||
T1.organization_id AS org_id,
|
T1.organization_id AS org_id,
|
||||||
T8.bus_no AS bus_no,
|
T8.bus_no AS bus_no,
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
T8.gender_enum AS gender_enum,
|
T8.gender_enum AS gender_enum,
|
||||||
T8.id_card AS id_card,
|
T8.id_card AS id_card,
|
||||||
T1.status_enum AS status_enum,
|
T1.status_enum AS status_enum,
|
||||||
T1.create_time AS register_time,
|
T1.create_time AS "register_time",
|
||||||
T10.total_price,
|
T10.total_price,
|
||||||
T11."name" AS account_name,
|
T11."name" AS account_name,
|
||||||
T12."name" AS enterer_name,
|
T12."name" AS enterer_name,
|
||||||
@@ -140,7 +140,7 @@
|
|||||||
T8.phone AS phone,
|
T8.phone AS phone,
|
||||||
T8.birth_date AS birth_date,
|
T8.birth_date AS birth_date,
|
||||||
T1.status_enum AS status_enum,
|
T1.status_enum AS status_enum,
|
||||||
T1.create_time AS register_time,
|
T1.create_time AS "register_time",
|
||||||
T1.reception_time AS reception_time,
|
T1.reception_time AS reception_time,
|
||||||
T1.organization_id AS org_id,
|
T1.organization_id AS org_id,
|
||||||
T8.bus_no AS bus_no,
|
T8.bus_no AS bus_no,
|
||||||
|
|||||||
@@ -42,4 +42,20 @@ public interface OrderMapper extends BaseMapper<Order> {
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
int updatePayStatus(@Param("orderId") Long orderId, @Param("payStatus") Integer payStatus, @Param("payTime") Date payTime);
|
int updatePayStatus(@Param("orderId") Long orderId, @Param("payStatus") Integer payStatus, @Param("payTime") Date payTime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计同一患者在同一科室、同一时段(上午/下午)内的有效预约订单数量
|
||||||
|
*
|
||||||
|
* @param patientId 患者ID
|
||||||
|
* @param departmentId 科室ID
|
||||||
|
* @param startTime 时段起始时间(含)
|
||||||
|
* @param endTime 时段结束时间(不含)
|
||||||
|
* @param statuses 订单状态集合(如 1=已预约,2=已取号)
|
||||||
|
* @return 数量
|
||||||
|
*/
|
||||||
|
int countPatientDeptOrdersInPeriod(@Param("patientId") Long patientId,
|
||||||
|
@Param("departmentId") Long departmentId,
|
||||||
|
@Param("startTime") Date startTime,
|
||||||
|
@Param("endTime") Date endTime,
|
||||||
|
@Param("statuses") List<Integer> statuses);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import java.time.LocalTime;
|
|||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.temporal.TemporalAdjusters;
|
import java.time.temporal.TemporalAdjusters;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -182,6 +183,28 @@ public class TicketServiceImpl extends ServiceImpl<TicketMapper, Ticket> impleme
|
|||||||
throw new RuntimeException("该排班医生已停诊");
|
throw new RuntimeException("该排班医生已停诊");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2.1 同一患者同一天/同一科室/同一时段(上午/下午)不可重复预约
|
||||||
|
if (dto.getPatientId() != null && slot.getDepartmentId() != null && slot.getScheduleDate() != null && slot.getExpectTime() != null) {
|
||||||
|
boolean isMorning = slot.getExpectTime().isBefore(LocalTime.NOON);
|
||||||
|
LocalDate scheduleDateForCheck = slot.getScheduleDate();
|
||||||
|
LocalDateTime periodStart = isMorning
|
||||||
|
? LocalDateTime.of(scheduleDateForCheck, LocalTime.MIN)
|
||||||
|
: LocalDateTime.of(scheduleDateForCheck, LocalTime.NOON);
|
||||||
|
LocalDateTime periodEnd = isMorning
|
||||||
|
? LocalDateTime.of(scheduleDateForCheck, LocalTime.NOON)
|
||||||
|
: LocalDateTime.of(scheduleDateForCheck.plusDays(1), LocalTime.MIN);
|
||||||
|
|
||||||
|
Date startTime = Date.from(periodStart.atZone(ZoneId.systemDefault()).toInstant());
|
||||||
|
Date endTime = Date.from(periodEnd.atZone(ZoneId.systemDefault()).toInstant());
|
||||||
|
|
||||||
|
// 预约去重以订单为准(order_main),因为预约成功会先落订单;clinical_ticket 不一定在此链路写入
|
||||||
|
List<Integer> effectiveOrderStatuses = Arrays.asList(AppointmentOrderStatus.BOOKED, AppointmentOrderStatus.CHECKED_IN);
|
||||||
|
int exists = orderMapper.countPatientDeptOrdersInPeriod(dto.getPatientId(), slot.getDepartmentId(), startTime, endTime, effectiveOrderStatuses);
|
||||||
|
if (exists > 0) {
|
||||||
|
throw new RuntimeException("该患者已在当前科室该时段存在预约记录,不可重复预约");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 原子抢占:避免并发下同一槽位被重复预约
|
// 原子抢占:避免并发下同一槽位被重复预约
|
||||||
int lockRows = scheduleSlotMapper.lockSlotForBooking(slotId);
|
int lockRows = scheduleSlotMapper.lockSlotForBooking(slotId);
|
||||||
if (lockRows <= 0) {
|
if (lockRows <= 0) {
|
||||||
@@ -264,9 +287,6 @@ public class TicketServiceImpl extends ServiceImpl<TicketMapper, Ticket> impleme
|
|||||||
throw new RuntimeException("当前号源没有可取消的预约订单");
|
throw new RuntimeException("当前号源没有可取消的预约订单");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取订单信息
|
|
||||||
Order latestOrder = orders.get(0);
|
|
||||||
|
|
||||||
// 直接执行取消,不再检查取消限制
|
// 直接执行取消,不再检查取消限制
|
||||||
// 根据需求,取消限制应在预约挂号时检查,而非取消预约时
|
// 根据需求,取消限制应在预约挂号时检查,而非取消预约时
|
||||||
for (Order order : orders) {
|
for (Order order : orders) {
|
||||||
|
|||||||
@@ -217,6 +217,23 @@
|
|||||||
where id = #{id}
|
where id = #{id}
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
|
<select id="countPatientDeptOrdersInPeriod" resultType="int">
|
||||||
|
select count(*)
|
||||||
|
from order_main
|
||||||
|
<where>
|
||||||
|
and patient_id = #{patientId}
|
||||||
|
and department_id = #{departmentId}
|
||||||
|
and appointment_time >= #{startTime}
|
||||||
|
and appointment_time < #{endTime}
|
||||||
|
<if test="statuses != null and statuses.size() > 0">
|
||||||
|
and status in
|
||||||
|
<foreach item="s" collection="statuses" open="(" separator="," close=")">
|
||||||
|
#{s}
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
</select>
|
||||||
|
|
||||||
<update id="updateOrderStatusById">
|
<update id="updateOrderStatusById">
|
||||||
update order_main set status = #{status} where id = #{id}
|
update order_main set status = #{status} where id = #{id}
|
||||||
</update>
|
</update>
|
||||||
|
|||||||
@@ -313,6 +313,37 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
// 全部号源经过日期过期过滤后的数据(不按医生过滤,不按患者搜索过滤),用于统计医生余号
|
||||||
|
allTicketsForDoctorCount() {
|
||||||
|
let filtered = [...this.tickets];
|
||||||
|
|
||||||
|
// 🎯 只过滤过期号源,不按医生过滤,不按患者搜索过滤
|
||||||
|
// 这样余号统计总是基于该日期下所有号源,得到正确的每个医生余号
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
filtered = filtered.filter(ticket => {
|
||||||
|
// dateTime 格式示例:"2024-01-01 08:00-09:00"
|
||||||
|
const parts = (ticket.dateTime || '').split(' ');
|
||||||
|
if (parts.length < 2) return true; // 如果格式不正确,保留显示
|
||||||
|
|
||||||
|
const dateStr = parts[0];
|
||||||
|
const timeRangeStr = parts[1];
|
||||||
|
if (!dateStr || !timeRangeStr) return true;
|
||||||
|
|
||||||
|
// 提取开始时间
|
||||||
|
const startTimeStr = timeRangeStr.split('-')[0]; // "08:00"
|
||||||
|
if (!startTimeStr) return true;
|
||||||
|
|
||||||
|
// 构建号源开始时间的完整 Date 对象
|
||||||
|
const ticketStartStr = `${dateStr} ${startTimeStr}`;
|
||||||
|
const ticketStart = new Date(ticketStartStr);
|
||||||
|
|
||||||
|
// 只显示开始时间晚于当前时间的号源
|
||||||
|
return ticketStart > now;
|
||||||
|
});
|
||||||
|
|
||||||
|
return filtered;
|
||||||
|
},
|
||||||
filteredDoctors() {
|
filteredDoctors() {
|
||||||
let filtered = [...this.doctors];
|
let filtered = [...this.doctors];
|
||||||
|
|
||||||
@@ -330,10 +361,96 @@ export default {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🎯 实时更新余号数量:统计该医生当前筛选条件下剩余可预约(未预约 + 未过期)号源数量
|
||||||
|
// 使用全部未过期号源统计(不按选中医生过滤),这样所有医生余号都正确显示
|
||||||
|
const availableCountMap = {};
|
||||||
|
this.allTicketsForDoctorCount.forEach(ticket => {
|
||||||
|
const doctorId = String(ticket.doctorId || ticket.doctor_id);
|
||||||
|
if (!availableCountMap[doctorId]) {
|
||||||
|
availableCountMap[doctorId] = 0;
|
||||||
|
}
|
||||||
|
// 只有未预约的号源才算作可预约余号
|
||||||
|
if (ticket.status === '未预约') {
|
||||||
|
availableCountMap[doctorId]++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 更新每个医生的余号数量
|
||||||
|
filtered = filtered.map(doctor => {
|
||||||
|
const actualAvailable = availableCountMap[String(doctor.id)] || 0;
|
||||||
|
return {
|
||||||
|
...doctor,
|
||||||
|
available: actualAvailable
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
return filtered;
|
return filtered;
|
||||||
},
|
},
|
||||||
|
// 过滤并排序后的完整号源列表(用于右侧显示)
|
||||||
|
filteredAndSortedTickets() {
|
||||||
|
// 从已经过滤掉过期的全部数据开始
|
||||||
|
let filtered = [...this.allTicketsForDoctorCount];
|
||||||
|
|
||||||
|
// 🎯 根据选中的医生过滤(右侧只显示选中医生的号源)
|
||||||
|
if (this.selectedDoctorId) {
|
||||||
|
const doctorIdStr = String(this.selectedDoctorId);
|
||||||
|
filtered = filtered.filter(ticket => {
|
||||||
|
const ticketDoctorId = String(ticket.doctorId || ticket.doctor_id || '');
|
||||||
|
return ticketDoctorId === doctorIdStr;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🎯 根据患者搜索条件过滤
|
||||||
|
if (this.patientName?.trim()) {
|
||||||
|
const keyword = this.patientName.trim().toLowerCase();
|
||||||
|
filtered = filtered.filter(ticket =>
|
||||||
|
(ticket.patientName || '').toLowerCase().includes(keyword)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (this.patientCard?.trim()) {
|
||||||
|
const keyword = this.patientCard.trim().toLowerCase();
|
||||||
|
filtered = filtered.filter(ticket =>
|
||||||
|
(ticket.patientId || '').toLowerCase().includes(keyword) ||
|
||||||
|
(ticket.medicalCard || '').toLowerCase().includes(keyword)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (this.patientPhone?.trim()) {
|
||||||
|
const keyword = this.patientPhone.trim().toLowerCase();
|
||||||
|
filtered = filtered.filter(ticket =>
|
||||||
|
(ticket.phone || '').toLowerCase().includes(keyword)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🎯 按开始时间升序排序 → 较早的号源排在前面
|
||||||
|
filtered.sort((a, b) => {
|
||||||
|
const getStartTime = (ticket) => {
|
||||||
|
const parts = (ticket.dateTime || '').split(' ');
|
||||||
|
if (parts.length < 2) return new Date(0).getTime();
|
||||||
|
const dateStr = parts[0];
|
||||||
|
const timeRangeStr = parts[1];
|
||||||
|
const startTimeStr = (timeRangeStr || '').split('-')[0];
|
||||||
|
if (!startTimeStr) return new Date(0).getTime();
|
||||||
|
const ticketStartStr = `${dateStr} ${startTimeStr}`;
|
||||||
|
return new Date(ticketStartStr).getTime();
|
||||||
|
};
|
||||||
|
|
||||||
|
const timeA = getStartTime(a);
|
||||||
|
const timeB = getStartTime(b);
|
||||||
|
return timeA - timeB;
|
||||||
|
});
|
||||||
|
|
||||||
|
return filtered;
|
||||||
|
},
|
||||||
|
// 🎯 分页:按照用户选择的每页条数分页,返回当前页的数据
|
||||||
filteredTickets() {
|
filteredTickets() {
|
||||||
return [...this.tickets];
|
const filtered = this.filteredAndSortedTickets;
|
||||||
|
const startIndex = (this.currentPage - 1) * this.pageSize;
|
||||||
|
const endIndex = startIndex + this.pageSize;
|
||||||
|
return filtered.slice(startIndex, endIndex);
|
||||||
|
},
|
||||||
|
// 更新总条数为过滤后的实际条数,分页自动处理
|
||||||
|
totalTickets() {
|
||||||
|
return this.filteredAndSortedTickets.length;
|
||||||
},
|
},
|
||||||
hasSearchCriteria() {
|
hasSearchCriteria() {
|
||||||
return !!this.patientKeyword?.trim();
|
return !!this.patientKeyword?.trim();
|
||||||
@@ -343,6 +460,8 @@ export default {
|
|||||||
selectDoctor(doctorId) {
|
selectDoctor(doctorId) {
|
||||||
this.selectedDoctorId = this.selectedDoctorId === doctorId ? null : doctorId;
|
this.selectedDoctorId = this.selectedDoctorId === doctorId ? null : doctorId;
|
||||||
this.currentPage = 1;
|
this.currentPage = 1;
|
||||||
|
// 🔧 BugFix: 选择医生后不改变医生列表,余号计算基于 filteredAndSortedTickets 已经正确过滤
|
||||||
|
// 只需要重新获取号源,医生列表保持不变,余号计算会自动正确
|
||||||
this.fetchTickets({ refreshDepartments: false, refreshDoctors: false }).catch(() => {});
|
this.fetchTickets({ refreshDepartments: false, refreshDoctors: false }).catch(() => {});
|
||||||
},
|
},
|
||||||
onTypeChange() {
|
onTypeChange() {
|
||||||
@@ -683,21 +802,20 @@ export default {
|
|||||||
return STATUS_CLASS_MAP[status] || 'status-unbooked';
|
return STATUS_CLASS_MAP[status] || 'status-unbooked';
|
||||||
},
|
},
|
||||||
buildQueryParams(page = this.currentPage) {
|
buildQueryParams(page = this.currentPage) {
|
||||||
const doctorId =
|
|
||||||
this.selectedDoctorId === null || this.selectedDoctorId === undefined || this.selectedDoctorId === ''
|
|
||||||
? null
|
|
||||||
: String(this.selectedDoctorId);
|
|
||||||
return {
|
return {
|
||||||
date: this.selectedDate,
|
date: this.selectedDate,
|
||||||
status: this.selectedStatus === 'all' ? null : this.selectedStatus,
|
status: null, // 状态过滤在前端做
|
||||||
type: this.selectedType === 'all' ? null : this.selectedType,
|
type: this.selectedType === 'all' ? null : this.selectedType,
|
||||||
department: this.selectedDepartment === 'all' ? null : this.selectedDepartment,
|
department: this.selectedDepartment === 'all' ? null : this.selectedDepartment,
|
||||||
doctorId,
|
doctorId: null, // 🎯 关键:永远不传 doctorId 给后端,后端返回全量数据
|
||||||
name: this.patientName?.trim() || null,
|
// 医生过滤、状态过滤、患者搜索都在前端做,才能保证所有医生余号统计正确
|
||||||
card: this.patientCard?.trim() || null,
|
name: null,
|
||||||
phone: this.patientPhone?.trim() || null,
|
card: null,
|
||||||
page,
|
phone: null,
|
||||||
limit: this.pageSize
|
// 🎯 获取全量数据到前端,由前端做过滤和分页,保证余号统计总是正确
|
||||||
|
// 号源数量每个日期每个科室不会太多,全量获取可行
|
||||||
|
page: 1,
|
||||||
|
limit: 10000
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
buildDoctorQueryParams() {
|
buildDoctorQueryParams() {
|
||||||
@@ -725,20 +843,14 @@ export default {
|
|||||||
if (!payload) {
|
if (!payload) {
|
||||||
this.tickets = [];
|
this.tickets = [];
|
||||||
this.allTickets = [];
|
this.allTickets = [];
|
||||||
this.totalTickets = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const records = payload.list || payload.records || [];
|
let records = payload.list || payload.records || [];
|
||||||
const filteredRecords = this.applyStatusFilter(records);
|
// 获取全量数据,应用状态过滤后保存所有数据到 tickets
|
||||||
const total = Number(payload.total);
|
// 过滤、余号统计、分页都由前端完成,保证余号计算正确
|
||||||
this.tickets = [...filteredRecords];
|
records = this.applyStatusFilter(records);
|
||||||
this.allTickets = [...filteredRecords];
|
this.tickets = [...records];
|
||||||
// 当按状态筛选时,优先使用前端过滤后的数量,避免后端状态未生效导致“显示全部”
|
this.allTickets = [...records];
|
||||||
if (this.selectedStatus && this.selectedStatus !== 'all') {
|
|
||||||
this.totalTickets = this.tickets.length;
|
|
||||||
} else {
|
|
||||||
this.totalTickets = Number.isFinite(total) ? total : this.tickets.length;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
applyStatusFilter(records = []) {
|
applyStatusFilter(records = []) {
|
||||||
if (!Array.isArray(records) || records.length === 0) {
|
if (!Array.isArray(records) || records.length === 0) {
|
||||||
|
|||||||
@@ -352,7 +352,20 @@ const applyRowToForm = (row) => {
|
|||||||
|
|
||||||
if (myOpinion) {
|
if (myOpinion) {
|
||||||
// 如果当前医生已确认,回显其信息
|
// 如果当前医生已确认,回显其信息
|
||||||
formData.value.confirmingPhysician = myOpinion.physicianName || ''
|
// 回显“会诊确认参加医师”:优先从 opinion 前缀解析(格式:科室-参加医师:意见)
|
||||||
|
// 兼容旧数据(格式:科室-医生:意见)以及异常格式
|
||||||
|
if (myOpinion.opinion) {
|
||||||
|
const opinionText = myOpinion.opinion
|
||||||
|
const colonIndex = opinionText.indexOf(':')
|
||||||
|
const dashIndex = opinionText.indexOf('-')
|
||||||
|
if (dashIndex >= 0 && colonIndex > dashIndex) {
|
||||||
|
formData.value.confirmingPhysician = opinionText.substring(dashIndex + 1, colonIndex).trim()
|
||||||
|
} else {
|
||||||
|
formData.value.confirmingPhysician = myOpinion.physicianName || ''
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
formData.value.confirmingPhysician = myOpinion.physicianName || ''
|
||||||
|
}
|
||||||
formData.value.confirmingPhysicianName = myOpinion.physicianName
|
formData.value.confirmingPhysicianName = myOpinion.physicianName
|
||||||
formData.value.confirmingDeptName = myOpinion.deptName
|
formData.value.confirmingDeptName = myOpinion.deptName
|
||||||
|
|
||||||
|
|||||||
@@ -257,15 +257,16 @@ function fetchFromApi(searchKey) {
|
|||||||
searchKey: searchKey || '',
|
searchKey: searchKey || '',
|
||||||
statusEnum: 2,
|
statusEnum: 2,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
console.log('[Debug] 耗材列表返回数据:', res.data);
|
console.log('[BugFix] 耗材列表返回数据:', res.data);
|
||||||
if (res.data && res.data.records) {
|
if (res.data && res.data.records) {
|
||||||
adviceBaseList.value = res.data.records.map((item) => {
|
adviceBaseList.value = res.data.records.map((item) => {
|
||||||
console.log('[Debug] 耗材项:', item.name, 'price:', item.price, 'retailPrice:', item.retailPrice);
|
console.log('[BugFix] 耗材项:', item.name, 'price:', item.price, 'retailPrice:', item.retailPrice);
|
||||||
return {
|
const mappedItem = {
|
||||||
...item,
|
...item,
|
||||||
// 🔧 Bug Fix: 强制覆盖后端返回的字段,确保数据正确
|
// 🔧 Bug Fix: 强制覆盖后端返回的字段,确保数据正确
|
||||||
adviceName: item.name || item.busNo,
|
adviceName: item.name || item.busNo,
|
||||||
adviceType: 4, // 强制设置为前端耗材类型
|
adviceType: 4, // 强制设置为前端耗材类型
|
||||||
|
adviceType_dictText: '耗材', // 🔧 Bug Fix: 设置医嘱类型显示文本
|
||||||
adviceTableName: 'adm_device_definition',
|
adviceTableName: 'adm_device_definition',
|
||||||
unitCode: item.unitCode || '',
|
unitCode: item.unitCode || '',
|
||||||
unitCode_dictText: item.unitCode_dictText || '',
|
unitCode_dictText: item.unitCode_dictText || '',
|
||||||
@@ -299,6 +300,8 @@ function fetchFromApi(searchKey) {
|
|||||||
? [{ price: item.price }]
|
? [{ price: item.price }]
|
||||||
: []),
|
: []),
|
||||||
};
|
};
|
||||||
|
console.log('[BugFix] 映射后的耗材项:', mappedItem.adviceName, 'adviceType:', mappedItem.adviceType, 'adviceType_dictText:', mappedItem.adviceType_dictText);
|
||||||
|
return mappedItem;
|
||||||
});
|
});
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
currentIndex.value = 0;
|
currentIndex.value = 0;
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-container class="inspection-application-container">
|
<el-container class="inspection-application-container">
|
||||||
|
|
||||||
<!-- 顶部操作按钮区 -->
|
<!-- 顶部操作按钮区 - Bug#334: 优化垂直空间利用率 -->
|
||||||
<el-header class="top-action-bar" height="60px">
|
<el-header class="top-action-bar" height="48px">
|
||||||
<el-row class="action-buttons" type="flex" justify="end" :gutter="10">
|
<el-row class="action-buttons" type="flex" justify="end" :gutter="8">
|
||||||
<el-button type="primary" size="large" @click="handleSave" class="save-btn" :loading="saving">
|
<el-button type="primary" size="default" @click="handleSave" class="save-btn" :loading="saving">
|
||||||
<el-icon><Document /></el-icon>
|
<el-icon><Document /></el-icon>
|
||||||
保存
|
保存
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="primary" size="large" @click="handleNewApplication" class="new-btn">
|
<el-button type="primary" size="default" @click="handleNewApplication" class="new-btn">
|
||||||
<el-icon><Plus /></el-icon>
|
<el-icon><Plus /></el-icon>
|
||||||
新增
|
新增
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -1647,19 +1647,20 @@ defineExpose({
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 顶部操作按钮区 */
|
/* Bug#334: 顶部操作按钮区 - 优化垂直空间利用率 */
|
||||||
.top-action-bar {
|
.top-action-bar {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
border-bottom: 1px solid var(--el-border-color-light);
|
border-bottom: 1px solid var(--el-border-color-light);
|
||||||
background: var(--el-bg-color);
|
background: var(--el-bg-color);
|
||||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
|
||||||
|
padding: 0 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-buttons {
|
.action-buttons {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 10px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 新增按钮样式 - PRD要求蓝色背景 #4a89dc */
|
/* 新增按钮样式 - PRD要求蓝色背景 #4a89dc */
|
||||||
@@ -1686,9 +1687,9 @@ defineExpose({
|
|||||||
border-color: #58dfbd !important;
|
border-color: #58dfbd !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 检验信息表格区 - 紧凑高度 */
|
/* Bug#334: 检验信息表格区 - 优化垂直空间利用率 */
|
||||||
.inspection-section {
|
.inspection-section {
|
||||||
padding: 4px 10px 0 10px;
|
padding: 2px 10px 0 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-card {
|
.table-card {
|
||||||
@@ -1696,7 +1697,7 @@ defineExpose({
|
|||||||
}
|
}
|
||||||
|
|
||||||
.table-card :deep(.el-card__body) {
|
.table-card :deep(.el-card__body) {
|
||||||
padding-bottom: 8px;
|
padding-bottom: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-header {
|
.card-header {
|
||||||
@@ -1707,9 +1708,9 @@ defineExpose({
|
|||||||
color: var(--el-text-color-primary);
|
color: var(--el-text-color-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 底部内容区域 */
|
/* Bug#334: 底部内容区域 - 优化垂直空间利用率 */
|
||||||
.bottom-content-area {
|
.bottom-content-area {
|
||||||
padding: 4px 10px;
|
padding: 2px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 表单区域 */
|
/* 表单区域 */
|
||||||
@@ -1732,7 +1733,7 @@ defineExpose({
|
|||||||
|
|
||||||
.application-form {
|
.application-form {
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
padding: 6px 8px;
|
padding: 4px 8px;
|
||||||
border: 1px solid #e4e7ed;
|
border: 1px solid #e4e7ed;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
margin: 2px;
|
margin: 2px;
|
||||||
|
|||||||
@@ -223,7 +223,12 @@
|
|||||||
style="width: 70px; margin-right: 20px" />
|
style="width: 70px; margin-right: 20px" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<span class="medicine-info"> 诊断:{{ diagnosisName }} </span>
|
<span class="medicine-info"> 诊断:{{ diagnosisName }} </span>
|
||||||
<span class="medicine-info"> 皮试:{{ scope.row.skinTestFlag_enumText }} </span>
|
<span class="medicine-info" style="display: flex; align-items: center; gap: 5px;">
|
||||||
|
皮试:<el-checkbox v-model="scope.row.skinTestFlag" :true-value="1" :false-value="0"
|
||||||
|
@change="handleSkinTestChange(scope.row, scope.$index)">
|
||||||
|
是
|
||||||
|
</el-checkbox>
|
||||||
|
</span>
|
||||||
<span class="medicine-info"> 注射药品:{{ scope.row.injectFlag_enumText }} </span>
|
<span class="medicine-info"> 注射药品:{{ scope.row.injectFlag_enumText }} </span>
|
||||||
<span class="total-amount">
|
<span class="total-amount">
|
||||||
总金额:{{
|
总金额:{{
|
||||||
@@ -470,6 +475,12 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<span class="medicine-info" style="display: flex; align-items: center; gap: 5px;">
|
||||||
|
皮试:<el-checkbox v-model="scope.row.skinTestFlag" :true-value="1" :false-value="0"
|
||||||
|
@change="handleSkinTestChange(scope.row, scope.$index)">
|
||||||
|
是
|
||||||
|
</el-checkbox>
|
||||||
|
</span>
|
||||||
<span class="total-amount">
|
<span class="total-amount">
|
||||||
总金额:{{
|
总金额:{{
|
||||||
(scope.row.totalPrice !== undefined && scope.row.totalPrice !== null && !isNaN(scope.row.totalPrice)
|
(scope.row.totalPrice !== undefined && scope.row.totalPrice !== null && !isNaN(scope.row.totalPrice)
|
||||||
@@ -761,7 +772,13 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="皮试" align="center" prop="" width="80">
|
<el-table-column label="皮试" align="center" prop="" width="80">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<span v-if="!scope.row.isEdit">
|
<template v-if="scope.row.isEdit">
|
||||||
|
<el-checkbox v-model="scope.row.skinTestFlag" :true-value="1" :false-value="0"
|
||||||
|
@change="handleSkinTestChange(scope.row, scope.$index)">
|
||||||
|
是
|
||||||
|
</el-checkbox>
|
||||||
|
</template>
|
||||||
|
<span v-else>
|
||||||
{{ scope.row.skinTestFlag_enumText || '-' }}
|
{{ scope.row.skinTestFlag_enumText || '-' }}
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -1908,6 +1925,34 @@ const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|||||||
* 选择药品回调
|
* 选择药品回调
|
||||||
*/
|
*/
|
||||||
function selectAdviceBase(key, row) {
|
function selectAdviceBase(key, row) {
|
||||||
|
// 🔧 Bug Fix: 检查药品是否需要皮试,如果需要则弹出确认框
|
||||||
|
if (row.skinTestFlag == 1) {
|
||||||
|
ElMessageBox.confirm(`药品:${row.adviceName}需要做皮试,是否做皮试?`, '提示', {
|
||||||
|
confirmButtonText: '是',
|
||||||
|
cancelButtonText: '否',
|
||||||
|
type: 'warning',
|
||||||
|
center: true,
|
||||||
|
customClass: 'skin-test-confirm-dialog',
|
||||||
|
beforeClose: (action, instance, done) => {
|
||||||
|
if (action === 'confirm') {
|
||||||
|
// 用户点击右边的按钮(confirm),保持皮试标记为1
|
||||||
|
setNewRow(key, row);
|
||||||
|
done();
|
||||||
|
} else if (action === 'cancel') {
|
||||||
|
// 用户点击左边的按钮(cancel),将皮试标记改为0
|
||||||
|
row.skinTestFlag = 0;
|
||||||
|
row.skinTestFlag_enumText = '否';
|
||||||
|
setNewRow(key, row);
|
||||||
|
done();
|
||||||
|
} else {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查检查检验项目是否有历史记录(30天内)
|
||||||
if (row.categoryCode == 22 || row.categoryCode == 23) {
|
if (row.categoryCode == 22 || row.categoryCode == 23) {
|
||||||
checkServicesHistory({
|
checkServicesHistory({
|
||||||
patientId: props.patientInfo.patientId,
|
patientId: props.patientInfo.patientId,
|
||||||
@@ -1930,6 +1975,7 @@ function selectAdviceBase(key, row) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function setNewRow(key, row) {
|
async function setNewRow(key, row) {
|
||||||
|
console.log('[BugFix] setNewRow - row.adviceType:', row.adviceType, 'row.adviceType_dictText:', row.adviceType_dictText, 'row.adviceTableName:', row.adviceTableName);
|
||||||
// 每次选择药品时,将当前行数据完全重置,清空所有旧数据
|
// 每次选择药品时,将当前行数据完全重置,清空所有旧数据
|
||||||
const preservedData = {
|
const preservedData = {
|
||||||
uniqueKey: prescriptionList.value[rowIndex.value].uniqueKey,
|
uniqueKey: prescriptionList.value[rowIndex.value].uniqueKey,
|
||||||
@@ -1943,6 +1989,8 @@ function selectAdviceBase(key, row) {
|
|||||||
|
|
||||||
setValue(row);
|
setValue(row);
|
||||||
|
|
||||||
|
console.log('[BugFix] setNewRow after setValue - prescriptionList[rowIndex].adviceType:', prescriptionList.value[rowIndex.value].adviceType, 'adviceType_dictText:', prescriptionList.value[rowIndex.value].adviceType_dictText);
|
||||||
|
|
||||||
// 🔧 Bug #220 修复:确保在setValue之后重新计算耗材类型的总金额
|
// 🔧 Bug #220 修复:确保在setValue之后重新计算耗材类型的总金额
|
||||||
// 耗材(adviceType=4)和诊疗(adviceType=3)需要重新计算以确保显示正确
|
// 耗材(adviceType=4)和诊疗(adviceType=3)需要重新计算以确保显示正确
|
||||||
const currentRow = prescriptionList.value[rowIndex.value];
|
const currentRow = prescriptionList.value[rowIndex.value];
|
||||||
@@ -3067,10 +3115,8 @@ function handleSaveBatch(prescriptionId) {
|
|||||||
|
|
||||||
// 🔧 Bug Fix: 处理accountId,如果是'ZIFEI'或0则转为null,让后端查询默认账户
|
// 🔧 Bug Fix: 处理accountId,如果是'ZIFEI'或0则转为null,让后端查询默认账户
|
||||||
let itemAccountId = finalAccountId;
|
let itemAccountId = finalAccountId;
|
||||||
if (itemAccountId === 'ZIFEI' || itemAccountId === 0) {
|
if (itemAccountId === 'ZIFEI' || itemAccountId === 0 || itemAccountId === '0') {
|
||||||
itemAccountId = null;
|
itemAccountId = null;
|
||||||
} else if (itemAccountId && !isNaN(Number(itemAccountId))) {
|
|
||||||
itemAccountId = Number(itemAccountId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🔧 Bug Fix: 确保库存匹配成功的关键字段
|
// 🔧 Bug Fix: 确保库存匹配成功的关键字段
|
||||||
@@ -3117,7 +3163,11 @@ function handleSaveBatch(prescriptionId) {
|
|||||||
accountId: itemAccountId,
|
accountId: itemAccountId,
|
||||||
// 🔧 Bug Fix: 确保库存匹配成功
|
// 🔧 Bug Fix: 确保库存匹配成功
|
||||||
adviceTableName: adviceTableNameVal,
|
adviceTableName: adviceTableNameVal,
|
||||||
locationId: locationIdVal
|
locationId: locationIdVal,
|
||||||
|
// 🔧 Bug Fix: 确保 minUnitQuantity、minUnitCode 等字段被传递(药品必填字段)
|
||||||
|
minUnitQuantity: item.minUnitQuantity,
|
||||||
|
minUnitCode: item.minUnitCode,
|
||||||
|
minUnitCode_dictText: item.minUnitCode_dictText
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
// --- 【修改结束】 ---
|
// --- 【修改结束】 ---
|
||||||
@@ -3279,10 +3329,13 @@ function setValue(row) {
|
|||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
// 创建一个新的对象,而不是合并旧数据,以避免残留数据问题
|
// 创建一个新的对象,而不是合并旧数据,以避免残留数据问题
|
||||||
|
console.log('[BugFix] setValue - row.adviceType:', row.adviceType, 'row.adviceType_dictText:', row.adviceType_dictText, 'row.adviceTableName:', row.adviceTableName);
|
||||||
prescriptionList.value[rowIndex.value] = {
|
prescriptionList.value[rowIndex.value] = {
|
||||||
...JSON.parse(JSON.stringify(row)),
|
...JSON.parse(JSON.stringify(row)),
|
||||||
// 确保adviceType为数字类型,避免类型不匹配导致的显示问题
|
// 确保adviceType为数字类型,避免类型不匹配导致的显示问题
|
||||||
adviceType: Number(row.adviceType),
|
adviceType: Number(row.adviceType),
|
||||||
|
// 🔧 Bug Fix: 确保adviceType_dictText被正确设置,避免展开行时显示错误
|
||||||
|
adviceType_dictText: row.adviceType_dictText || mapAdviceTypeLabel(row.adviceType, row.adviceTableName),
|
||||||
skinTestFlag: skinTestFlag, // 确保皮试字段是数字类型
|
skinTestFlag: skinTestFlag, // 确保皮试字段是数字类型
|
||||||
skinTestFlag_enumText: skinTestFlag == 1 ? '是' : '否', // 更新显示文本
|
skinTestFlag_enumText: skinTestFlag == 1 ? '是' : '否', // 更新显示文本
|
||||||
// 保留原来设置的初始状态值
|
// 保留原来设置的初始状态值
|
||||||
@@ -3291,6 +3344,7 @@ function setValue(row) {
|
|||||||
statusEnum: prescriptionList.value[rowIndex.value].statusEnum,
|
statusEnum: prescriptionList.value[rowIndex.value].statusEnum,
|
||||||
showPopover: false, // 确保查询框关闭
|
showPopover: false, // 确保查询框关闭
|
||||||
};
|
};
|
||||||
|
console.log('[BugFix] setValue - prescriptionList[rowIndex].adviceType_dictText:', prescriptionList.value[rowIndex.value].adviceType_dictText);
|
||||||
// 🔧 Bug #218 修复:保留组套中的值,不要强制设为undefined
|
// 🔧 Bug #218 修复:保留组套中的值,不要强制设为undefined
|
||||||
// 只有当值未定义时才使用默认值
|
// 只有当值未定义时才使用默认值
|
||||||
prescriptionList.value[rowIndex.value].orgId = row.positionId || row.orgId;
|
prescriptionList.value[rowIndex.value].orgId = row.positionId || row.orgId;
|
||||||
@@ -4511,6 +4565,36 @@ function handleOrderSetSaved() {
|
|||||||
defineExpose({ getListInfo, getDiagnosisInfo });
|
defineExpose({ getListInfo, getDiagnosisInfo });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
/* 皮试确认弹窗全局样式 - 反转按钮顺序,左边是是,右边是否 */
|
||||||
|
.skin-test-confirm-dialog.el-message-box {
|
||||||
|
.el-message-box__btns {
|
||||||
|
display: flex !important;
|
||||||
|
flex-direction: row-reverse !important;
|
||||||
|
justify-content: center !important;
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
margin-left: 10px !important;
|
||||||
|
margin-right: 10px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 如果自定义类名不生效,使用更强的选择器 */
|
||||||
|
.el-message-box.skin-test-confirm-dialog {
|
||||||
|
.el-message-box__btns {
|
||||||
|
display: flex !important;
|
||||||
|
flex-direction: row-reverse !important;
|
||||||
|
justify-content: center !important;
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
margin-left: 10px !important;
|
||||||
|
margin-right: 10px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
:deep(.el-table__expand-icon) {
|
:deep(.el-table__expand-icon) {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
|
|||||||
20
openhis-ui-vue3/vite/plugins/vue-mcp.js
Normal file
20
openhis-ui-vue3/vite/plugins/vue-mcp.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* @Description: Vue MCP Plugin - Enable MCP server for Vue application debugging
|
||||||
|
*/
|
||||||
|
import { VueMcp } from 'vite-plugin-vue-mcp'
|
||||||
|
|
||||||
|
export default function createVueMcpPlugin() {
|
||||||
|
return VueMcp({
|
||||||
|
// The host to listen on, default is `localhost`
|
||||||
|
host: 'localhost',
|
||||||
|
|
||||||
|
// Print the MCP server URL in the console
|
||||||
|
printUrl: true,
|
||||||
|
|
||||||
|
// Update the address of the MCP server in the cursor config file `.cursor/mcp.json`
|
||||||
|
updateCursorMcpJson: false, // Disable for OpenCode environment
|
||||||
|
|
||||||
|
// The path to the MCP server, default is `/__mcp`
|
||||||
|
mcpPath: '/__mcp',
|
||||||
|
})
|
||||||
|
}
|
||||||
1
openhis-v1.3
Submodule
1
openhis-v1.3
Submodule
Submodule openhis-v1.3 added at 582c2c8ac6
26
scripts/api_check.sh
Normal file
26
scripts/api_check.sh
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# 诊断脚本 - 检查API返回
|
||||||
|
|
||||||
|
echo "=========================================="
|
||||||
|
echo "API 诊断工具"
|
||||||
|
echo "=========================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 请替换为实际的token和服务器地址
|
||||||
|
SERVER_URL="http://192.168.110.252:18080"
|
||||||
|
ENCOUNTER_ID="2038823905749327873"
|
||||||
|
|
||||||
|
echo "1. 检查 doctor-station API:"
|
||||||
|
echo "URL: ${SERVER_URL}/openhis/doctor-station/advice/request-base-info?encounterId=${ENCOUNTER_ID}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "2. 检查 reg-doctorstation API:"
|
||||||
|
echo "URL: ${SERVER_URL}/openhis/reg-doctorstation/advice-manage/reg-request-base-info?encounterId=${ENCOUNTER_ID}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "请在浏览器中访问上述URL,查看返回的JSON数据"
|
||||||
|
echo ""
|
||||||
|
echo "需要确认:"
|
||||||
|
echo " - 是否有 adviceType=4 的记录?"
|
||||||
|
echo " - adviceName 是否有值?"
|
||||||
|
echo " - 手术医嘱是否包含在返回数据中?"
|
||||||
120
scripts/api_test.py
Normal file
120
scripts/api_test.py
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
直接调用 API 检查返回数据
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# 配置
|
||||||
|
BASE_URL = "http://192.168.110.252:18080/openhis"
|
||||||
|
ENCOUNTER_ID = "2038823905749327873"
|
||||||
|
|
||||||
|
# 尝试不登录直接访问(如果允许)
|
||||||
|
# 或者需要添加 token
|
||||||
|
|
||||||
|
|
||||||
|
def check_api():
|
||||||
|
"""检查 API 返回"""
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
print("直接调用 API 检查")
|
||||||
|
print("=" * 80)
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 如果有 token,请在这里设置
|
||||||
|
headers = {
|
||||||
|
# "Authorization": "Bearer YOUR_TOKEN_HERE",
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查 doctor-station API
|
||||||
|
print("1. 检查 doctor-station API:")
|
||||||
|
url = f"{BASE_URL}/doctor-station/advice/request-base-info"
|
||||||
|
params = {"encounterId": ENCOUNTER_ID}
|
||||||
|
|
||||||
|
try:
|
||||||
|
print(f" URL: {url}")
|
||||||
|
print(f" 参数: {params}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
response = requests.get(url, params=params, headers=headers, timeout=10)
|
||||||
|
print(f" 状态码: {response.status_code}")
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
print(f" 返回 code: {data.get('code')}")
|
||||||
|
print(f" 返回 msg: {data.get('msg')}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
if data.get("code") == 200:
|
||||||
|
records = data.get("data", [])
|
||||||
|
print(f" 记录总数: {len(records)}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 查找手术医嘱 (adviceType=4)
|
||||||
|
surgery_records = []
|
||||||
|
for record in records:
|
||||||
|
if record.get("adviceType") == 4 or record.get("categoryEnum") == 4:
|
||||||
|
surgery_records.append(record)
|
||||||
|
|
||||||
|
print(f" 手术医嘱数量: {len(surgery_records)}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
if surgery_records:
|
||||||
|
print(" 手术医嘱详情:")
|
||||||
|
for idx, record in enumerate(surgery_records, 1):
|
||||||
|
print(f"\n [{idx}]:")
|
||||||
|
print(f" requestId: {record.get('requestId')}")
|
||||||
|
print(f" adviceType: {record.get('adviceType')}")
|
||||||
|
print(f" adviceName: {record.get('adviceName')}")
|
||||||
|
print(f" categoryEnum: {record.get('categoryEnum')}")
|
||||||
|
content = record.get("contentJson", "{}")
|
||||||
|
if content:
|
||||||
|
try:
|
||||||
|
content_obj = (
|
||||||
|
json.loads(content)
|
||||||
|
if isinstance(content, str)
|
||||||
|
else content
|
||||||
|
)
|
||||||
|
print(
|
||||||
|
f" contentJson.surgeryName: {content_obj.get('surgeryName', 'N/A')}"
|
||||||
|
)
|
||||||
|
except:
|
||||||
|
print(f" contentJson: {content[:100]}...")
|
||||||
|
else:
|
||||||
|
print(" ✗ 未找到手术医嘱 (adviceType=4)")
|
||||||
|
print()
|
||||||
|
print(" 可能原因:")
|
||||||
|
print(" 1. 后端代码未正确部署")
|
||||||
|
print(" 2. 浏览器缓存了旧数据")
|
||||||
|
print(" 3. SQL 未生效")
|
||||||
|
|
||||||
|
# 打印所有记录查看 adviceType 分布
|
||||||
|
print()
|
||||||
|
print(" 所有记录的 adviceType 分布:")
|
||||||
|
type_count = {}
|
||||||
|
for record in records:
|
||||||
|
atype = record.get("adviceType")
|
||||||
|
type_count[atype] = type_count.get(atype, 0) + 1
|
||||||
|
for atype, count in sorted(type_count.items()):
|
||||||
|
print(f" adviceType={atype}: {count}条")
|
||||||
|
else:
|
||||||
|
print(f" ✗ 返回错误: {data}")
|
||||||
|
else:
|
||||||
|
print(f" ✗ 请求失败: {response.status_code}")
|
||||||
|
print(f" 返回: {response.text[:500]}")
|
||||||
|
print()
|
||||||
|
print(" 可能需要登录 token,请修改脚本添加 Authorization header")
|
||||||
|
except Exception as e:
|
||||||
|
print(f" ✗ 请求异常: {e}")
|
||||||
|
print()
|
||||||
|
print(" 请确认:")
|
||||||
|
print(" 1. 服务器地址是否正确")
|
||||||
|
print(" 2. 网络是否连通")
|
||||||
|
print(" 3. 是否需要登录 token")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
check_api()
|
||||||
4
scripts/build.bat
Normal file
4
scripts/build.bat
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
cd /d D:\his\openhis-server-new
|
||||||
|
call mvn clean package -DskipTests
|
||||||
|
echo Build complete!
|
||||||
|
pause
|
||||||
60
scripts/check_activity_id.py
Normal file
60
scripts/check_activity_id.py
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import psycopg2
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.stdout.reconfigure(encoding="utf-8")
|
||||||
|
|
||||||
|
conn = psycopg2.connect(
|
||||||
|
host="192.168.110.252",
|
||||||
|
port=15432,
|
||||||
|
database="postgresql",
|
||||||
|
user="postgresql",
|
||||||
|
password="Jchl1528",
|
||||||
|
)
|
||||||
|
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("SET search_path TO hisdev, public")
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
print("检查手术医嘱的 activity_id 和 advice_name")
|
||||||
|
print("=" * 80)
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 查询手术医嘱的 activity_id
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
sr.id,
|
||||||
|
sr.prescription_no,
|
||||||
|
sr.activity_id,
|
||||||
|
ad.name as activity_name,
|
||||||
|
sr.content_json
|
||||||
|
FROM wor_service_request sr
|
||||||
|
LEFT JOIN wor_activity_definition ad ON ad.id = sr.activity_id AND ad.delete_flag = '0'
|
||||||
|
WHERE sr.category_enum = 4
|
||||||
|
AND sr.delete_flag = '0'
|
||||||
|
AND sr.encounter_id = 2038823905749327873
|
||||||
|
""")
|
||||||
|
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
for row in rows:
|
||||||
|
print(f"医嘱ID: {row[0]}")
|
||||||
|
print(f"单号: {row[1]}")
|
||||||
|
print(f"activity_id: {row[2]}")
|
||||||
|
print(f"activity_name: {row[3]}")
|
||||||
|
if row[4]:
|
||||||
|
import json
|
||||||
|
|
||||||
|
try:
|
||||||
|
content = json.loads(row[4]) if isinstance(row[4], str) else row[4]
|
||||||
|
print(f"手术名称: {content.get('surgeryName', 'N/A')}")
|
||||||
|
except:
|
||||||
|
print(f"content_json: {row[4][:100]}")
|
||||||
|
print("-" * 80)
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("问题:SQL查询使用 activity_id 关联 wor_activity_definition 获取 advice_name")
|
||||||
|
print("但手术医嘱的 activity_id 可能为 null 或指向不存在的记录!")
|
||||||
|
print()
|
||||||
|
print("解决方案:应该从 content_json 中解析 surgeryName 作为 advice_name")
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
71
scripts/check_api_response.py
Normal file
71
scripts/check_api_response.py
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
|
# API配置
|
||||||
|
BASE_URL = "http://192.168.110.252:18080/openhis"
|
||||||
|
ENCOUNTER_ID = "2038823905749327873"
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
print("API 返回数据检查")
|
||||||
|
print("=" * 80)
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 检查 doctor-station API
|
||||||
|
print("1. 检查 doctor-station API:")
|
||||||
|
print(
|
||||||
|
f" URL: {BASE_URL}/doctor-station/advice/request-base-info?encounterId={ENCOUNTER_ID}"
|
||||||
|
)
|
||||||
|
print()
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = requests.get(
|
||||||
|
f"{BASE_URL}/doctor-station/advice/request-base-info",
|
||||||
|
params={"encounterId": ENCOUNTER_ID},
|
||||||
|
timeout=10,
|
||||||
|
)
|
||||||
|
print(f" 状态码: {response.status_code}")
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
if data.get("code") == 200:
|
||||||
|
records = data.get("data", [])
|
||||||
|
print(f" 返回记录数: {len(records)}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 查找手术医嘱 (adviceType=4)
|
||||||
|
surgery_records = [
|
||||||
|
r
|
||||||
|
for r in records
|
||||||
|
if r.get("adviceType") == 4 or r.get("categoryEnum") == 4
|
||||||
|
]
|
||||||
|
print(f" 手术医嘱数量: {len(surgery_records)}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
for record in surgery_records:
|
||||||
|
print(f" 手术医嘱详情:")
|
||||||
|
print(f" - requestId: {record.get('requestId')}")
|
||||||
|
print(f" - adviceType: {record.get('adviceType')}")
|
||||||
|
print(f" - adviceName: {record.get('adviceName')}")
|
||||||
|
print(f" - categoryEnum: {record.get('categoryEnum')}")
|
||||||
|
print(
|
||||||
|
f" - contentJson: {record.get('contentJson', '')[:100] if record.get('contentJson') else 'None'}..."
|
||||||
|
)
|
||||||
|
print()
|
||||||
|
else:
|
||||||
|
print(f" 返回错误: {data.get('msg')}")
|
||||||
|
else:
|
||||||
|
print(f" 请求失败: {response.status_code}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f" 请求异常: {e}")
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("=" * 80)
|
||||||
|
print("诊断建议:")
|
||||||
|
print("=" * 80)
|
||||||
|
print()
|
||||||
|
print("如果手术医嘱未显示,可能原因:")
|
||||||
|
print(" 1. adviceType 仍为 3 (不是 4)")
|
||||||
|
print(" 2. adviceName 为空")
|
||||||
|
print(" 3. 前端过滤逻辑排除了该记录")
|
||||||
|
print(" 4. API返回了数据但前端未正确渲染")
|
||||||
|
print()
|
||||||
115
scripts/check_column_index.py
Normal file
115
scripts/check_column_index.py
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
import psycopg2
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.stdout.reconfigure(encoding="utf-8")
|
||||||
|
|
||||||
|
conn = psycopg2.connect(
|
||||||
|
host="192.168.110.252",
|
||||||
|
port=15432,
|
||||||
|
database="postgresql",
|
||||||
|
user="postgresql",
|
||||||
|
password="Jchl1528",
|
||||||
|
)
|
||||||
|
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("SET search_path TO hisdev, public")
|
||||||
|
|
||||||
|
print("检查SQL查询的列顺序...")
|
||||||
|
print()
|
||||||
|
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
3 AS advice_type, -- 0
|
||||||
|
'test-id' AS request_id, -- 1
|
||||||
|
'test-key' AS unique_key, -- 2
|
||||||
|
123 AS requester_id, -- 3
|
||||||
|
NOW() AS request_time, -- 4
|
||||||
|
'1' AS biz_request_flag, -- 5
|
||||||
|
'{}' AS content_json, -- 6
|
||||||
|
null AS skin_test_flag, -- 7
|
||||||
|
null AS inject_flag, -- 8
|
||||||
|
null AS group_id, -- 9
|
||||||
|
'test-name' AS advice_name, -- 10
|
||||||
|
'' AS volume, -- 11
|
||||||
|
'' AS lot_number, -- 12
|
||||||
|
1 AS quantity, -- 13
|
||||||
|
'次' AS unit_code, -- 14
|
||||||
|
1 AS status_enum, -- 15
|
||||||
|
'' AS method_code, -- 16
|
||||||
|
'' AS rate_code, -- 17
|
||||||
|
NULL AS dose, -- 18
|
||||||
|
'' AS dose_unit_code, -- 19
|
||||||
|
'ci-id' AS charge_item_id, -- 20
|
||||||
|
100 AS total_price, -- 21
|
||||||
|
1 AS charge_status, -- 22
|
||||||
|
'pos-id' AS position_id, -- 23
|
||||||
|
'pos-name' AS position_name, -- 24
|
||||||
|
null AS dispense_per_duration, -- 25
|
||||||
|
1 AS part_percent, -- 26
|
||||||
|
'' AS condition_definition_name, -- 27
|
||||||
|
COALESCE(null, 2) AS therapyEnum, -- 28 <- 这里
|
||||||
|
99 AS sort_number, -- 29
|
||||||
|
null AS based_on_id -- 30
|
||||||
|
""")
|
||||||
|
|
||||||
|
row = cursor.fetchone()
|
||||||
|
print(f"therapyEnum 列索引: 28, 值: {row[28]}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 现在用实际的SQL查询
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
3 AS advice_type,
|
||||||
|
T1.id AS request_id,
|
||||||
|
T1.id || '-3' AS unique_key,
|
||||||
|
T1.requester_id AS requester_id,
|
||||||
|
T1.create_time AS request_time,
|
||||||
|
CASE WHEN T1.requester_id = 1980296166230962178 THEN '1' ELSE '0' END AS biz_request_flag,
|
||||||
|
T1.content_json AS content_json,
|
||||||
|
null AS skin_test_flag,
|
||||||
|
null AS inject_flag,
|
||||||
|
null AS group_id,
|
||||||
|
COALESCE(T2.NAME, T1.content_json::jsonb->>'surgeryName') AS advice_name,
|
||||||
|
'' AS volume,
|
||||||
|
'' AS lot_number,
|
||||||
|
T1.quantity AS quantity,
|
||||||
|
T1.unit_code AS unit_code,
|
||||||
|
T1.status_enum AS status_enum,
|
||||||
|
'' AS method_code,
|
||||||
|
'' AS rate_code,
|
||||||
|
NULL AS dose,
|
||||||
|
'' AS dose_unit_code,
|
||||||
|
T3.id AS charge_item_id,
|
||||||
|
T3.total_price AS total_price,
|
||||||
|
T3.status_enum AS charge_status,
|
||||||
|
ao.id AS position_id,
|
||||||
|
ao.name AS position_name,
|
||||||
|
null AS dispense_per_duration,
|
||||||
|
1 AS part_percent,
|
||||||
|
'' AS condition_definition_name,
|
||||||
|
COALESCE(T1.therapy_enum, 2) AS therapyEnum,
|
||||||
|
99 AS sort_number,
|
||||||
|
T1.based_on_id AS based_on_id
|
||||||
|
FROM wor_service_request AS T1
|
||||||
|
LEFT JOIN wor_activity_definition AS T2
|
||||||
|
ON T2.ID = T1.activity_id AND T2.delete_flag = '0'
|
||||||
|
LEFT JOIN adm_charge_item AS T3 ON T3.service_id = T1.ID AND T3.delete_flag = '0' AND
|
||||||
|
T3.service_table = 'wor_service_request'
|
||||||
|
LEFT JOIN adm_organization AS ao ON ao.ID = T1.org_id AND ao.delete_flag = '0'
|
||||||
|
WHERE T1.delete_flag = '0' AND T1.generate_source_enum = 1
|
||||||
|
AND T1.parent_id IS NULL
|
||||||
|
AND T1.encounter_id = 2038823905749327873
|
||||||
|
AND T1.category_enum = 4
|
||||||
|
""")
|
||||||
|
|
||||||
|
row = cursor.fetchone()
|
||||||
|
if row:
|
||||||
|
print("实际查询结果:")
|
||||||
|
print(f" advice_name (索引10): {row[10]}")
|
||||||
|
print(f" therapyEnum (索引28): {row[28]}")
|
||||||
|
print(f" status_enum (索引15): {row[15]}")
|
||||||
|
else:
|
||||||
|
print("未找到记录")
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
40
scripts/check_columns.py
Normal file
40
scripts/check_columns.py
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import psycopg2
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.stdout.reconfigure(encoding="utf-8")
|
||||||
|
|
||||||
|
conn = psycopg2.connect(
|
||||||
|
host="192.168.110.252",
|
||||||
|
port=15432,
|
||||||
|
database="postgresql",
|
||||||
|
user="postgresql",
|
||||||
|
password="Jchl1528",
|
||||||
|
)
|
||||||
|
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("SET search_path TO hisdev, public")
|
||||||
|
|
||||||
|
print("doc_request_form 表字段:")
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT column_name
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_schema = 'hisdev'
|
||||||
|
AND table_name = 'doc_request_form'
|
||||||
|
ORDER BY ordinal_position
|
||||||
|
""")
|
||||||
|
for row in cursor.fetchall():
|
||||||
|
print(f" {row[0]}")
|
||||||
|
|
||||||
|
print("\nwor_service_request 表字段:")
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT column_name
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_schema = 'hisdev'
|
||||||
|
AND table_name = 'wor_service_request'
|
||||||
|
ORDER BY ordinal_position
|
||||||
|
""")
|
||||||
|
for row in cursor.fetchall():
|
||||||
|
print(f" {row[0]}")
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
63
scripts/check_db.py
Normal file
63
scripts/check_db.py
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import psycopg2
|
||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
DB_CONFIG = {
|
||||||
|
"host": "192.168.110.252",
|
||||||
|
"port": 15432,
|
||||||
|
"database": "postgresql",
|
||||||
|
"user": "postgresql",
|
||||||
|
"password": "Jchl1528",
|
||||||
|
"options": "-c search_path=hisdev",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def check_surgery():
|
||||||
|
conn = None
|
||||||
|
try:
|
||||||
|
print("Connecting to database...")
|
||||||
|
conn = psycopg2.connect(**DB_CONFIG)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
print("Connected!\n")
|
||||||
|
|
||||||
|
# Query recent surgery advice
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
content_json::jsonb->>'surgeryName' as surgery_name,
|
||||||
|
content_json::jsonb->>'surgeryCode' as surgery_code,
|
||||||
|
create_time
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
LIMIT 3
|
||||||
|
""")
|
||||||
|
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
print("=" * 60)
|
||||||
|
print("Surgery Advice Check")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
if not rows:
|
||||||
|
print("No surgery advice found!")
|
||||||
|
else:
|
||||||
|
for row in rows:
|
||||||
|
print(f"\nID: {row[0]}")
|
||||||
|
print(f"surgeryName: {row[1] if row[1] else 'EMPTY'}")
|
||||||
|
print(f"surgeryCode: {row[2] if row[2] else 'EMPTY'}")
|
||||||
|
print(f"create_time: {row[3]}")
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error: {e}")
|
||||||
|
finally:
|
||||||
|
if conn:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
check_surgery()
|
||||||
59
scripts/check_empty.py
Normal file
59
scripts/check_empty.py
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import psycopg2
|
||||||
|
|
||||||
|
DB_CONFIG = {
|
||||||
|
"host": "192.168.110.252",
|
||||||
|
"port": 15432,
|
||||||
|
"database": "postgresql",
|
||||||
|
"user": "postgresql",
|
||||||
|
"password": "Jchl1528",
|
||||||
|
"options": "-c search_path=hisdev",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def check():
|
||||||
|
conn = None
|
||||||
|
try:
|
||||||
|
conn = psycopg2.connect(**DB_CONFIG)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
print("Records WITHOUT surgeryName (need fix)")
|
||||||
|
print("=" * 80)
|
||||||
|
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
wsr.id,
|
||||||
|
wsr.activity_id,
|
||||||
|
wsr.create_time,
|
||||||
|
cs.surgery_name,
|
||||||
|
cs.surgery_code
|
||||||
|
FROM wor_service_request wsr
|
||||||
|
LEFT JOIN cli_surgery cs ON cs.id = wsr.activity_id
|
||||||
|
WHERE wsr.category_enum = 4
|
||||||
|
AND wsr.delete_flag = '0'
|
||||||
|
AND (wsr.content_json::jsonb->>'surgeryName' IS NULL OR wsr.content_json::jsonb->>'surgeryName' = '')
|
||||||
|
ORDER BY wsr.create_time DESC
|
||||||
|
""")
|
||||||
|
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
print(f"\nTotal: {len(rows)} records\n")
|
||||||
|
|
||||||
|
for row in rows:
|
||||||
|
print(f"ID: {row[0]}")
|
||||||
|
print(f" activity_id: {row[1]}")
|
||||||
|
print(f" create_time: {row[2]}")
|
||||||
|
print(f" cli_surgery.surgery_name: {'[HAS]' if row[3] else '[NULL]'}")
|
||||||
|
print(f" cli_surgery.surgery_code: {'[HAS]' if row[4] else '[NULL]'}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error: {e}")
|
||||||
|
finally:
|
||||||
|
if conn:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
check()
|
||||||
246
scripts/check_filter.py
Normal file
246
scripts/check_filter.py
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
import psycopg2
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.stdout.reconfigure(encoding="utf-8")
|
||||||
|
|
||||||
|
conn = psycopg2.connect(
|
||||||
|
host="192.168.110.252",
|
||||||
|
port=15432,
|
||||||
|
database="postgresql",
|
||||||
|
user="postgresql",
|
||||||
|
password="Jchl1528",
|
||||||
|
)
|
||||||
|
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("SET search_path TO hisdev, public")
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
print("检查前端过滤条件")
|
||||||
|
print("=" * 80)
|
||||||
|
print()
|
||||||
|
|
||||||
|
encounter_id = 2038823905749327873
|
||||||
|
practitioner_id = 1980296166230962178
|
||||||
|
|
||||||
|
# 查询所有数据
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
(SELECT 1 AS advice_type,
|
||||||
|
T1.id AS request_id,
|
||||||
|
T1.id || '-1' AS unique_key,
|
||||||
|
T1.practitioner_id AS requester_id,
|
||||||
|
T1.create_time AS request_time,
|
||||||
|
CASE WHEN T1.practitioner_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
|
||||||
|
T1.content_json AS content_json,
|
||||||
|
T1.skin_test_flag AS skin_test_flag,
|
||||||
|
T1.infusion_flag AS inject_flag,
|
||||||
|
T1.group_id AS group_id,
|
||||||
|
T2.NAME AS advice_name,
|
||||||
|
T3.total_volume AS volume,
|
||||||
|
T1.lot_number AS lot_number,
|
||||||
|
T1.quantity AS quantity,
|
||||||
|
T1.unit_code AS unit_code,
|
||||||
|
T1.status_enum AS status_enum,
|
||||||
|
T1.method_code AS method_code,
|
||||||
|
T1.rate_code AS rate_code,
|
||||||
|
T1.dose AS dose,
|
||||||
|
T1.dose_unit_code AS dose_unit_code,
|
||||||
|
T4.id AS charge_item_id,
|
||||||
|
T4.total_price AS total_price,
|
||||||
|
T4.status_enum AS charge_status,
|
||||||
|
al.id AS position_id,
|
||||||
|
al.name AS position_name,
|
||||||
|
T1.dispense_per_duration AS dispense_per_duration,
|
||||||
|
T2.part_percent AS part_percent,
|
||||||
|
ccd.name AS condition_definition_name,
|
||||||
|
T1.therapy_enum AS therapyEnum,
|
||||||
|
T1.sort_number AS sort_number,
|
||||||
|
T1.based_on_id AS based_on_id
|
||||||
|
FROM med_medication_request AS T1
|
||||||
|
LEFT JOIN med_medication_definition AS T2 ON T2.ID = T1.medication_id
|
||||||
|
AND T2.delete_flag = '0'
|
||||||
|
LEFT JOIN med_medication AS T3 ON T3.medication_def_id = T2.ID
|
||||||
|
AND T3.delete_flag = '0'
|
||||||
|
LEFT JOIN adm_charge_item AS T4 ON T4.service_id = T1.ID AND T4.delete_flag = '0' AND
|
||||||
|
T4.service_table = 'med_medication_request'
|
||||||
|
LEFT JOIN adm_location AS al ON al.ID = T1.perform_location AND al.delete_flag = '0'
|
||||||
|
LEFT JOIN cli_condition AS cc ON cc.id = T1.condition_id AND cc.delete_flag = '0'
|
||||||
|
LEFT JOIN cli_condition_definition AS ccd ON ccd.id = cc.definition_id
|
||||||
|
WHERE T1.delete_flag = '0' AND T1.tcm_flag = 0 AND T1.generate_source_enum = 1
|
||||||
|
AND T1.encounter_id = %s
|
||||||
|
AND T1.refund_medicine_id IS NULL)
|
||||||
|
UNION ALL
|
||||||
|
(SELECT 2 AS advice_type,
|
||||||
|
T1.id AS request_id,
|
||||||
|
T1.id || '-2' AS unique_key,
|
||||||
|
T1.requester_id AS requester_id,
|
||||||
|
T1.create_time AS request_time,
|
||||||
|
CASE WHEN T1.requester_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
|
||||||
|
T1.content_json AS content_json,
|
||||||
|
null AS skin_test_flag,
|
||||||
|
null AS inject_flag,
|
||||||
|
null AS group_id,
|
||||||
|
T2.NAME AS advice_name,
|
||||||
|
T2.SIZE AS volume,
|
||||||
|
T1.lot_number AS lot_number,
|
||||||
|
T1.quantity AS quantity,
|
||||||
|
T1.unit_code AS unit_code,
|
||||||
|
T1.status_enum AS status_enum,
|
||||||
|
'' AS method_code,
|
||||||
|
T1.rate_code AS rate_code,
|
||||||
|
NULL AS dose,
|
||||||
|
'' AS dose_unit_code,
|
||||||
|
T3.id AS charge_item_id,
|
||||||
|
T3.total_price AS total_price,
|
||||||
|
T3.status_enum AS charge_status,
|
||||||
|
al.id AS position_id,
|
||||||
|
al.name AS position_name,
|
||||||
|
null AS dispense_per_duration,
|
||||||
|
T2.part_percent AS part_percent,
|
||||||
|
'' AS condition_definition_name,
|
||||||
|
2 AS therapyEnum,
|
||||||
|
99 AS sort_number,
|
||||||
|
T1.based_on_id AS based_on_id
|
||||||
|
FROM wor_device_request AS T1
|
||||||
|
LEFT JOIN adm_device_definition AS T2 ON T2.ID = T1.device_def_id
|
||||||
|
AND T2.delete_flag = '0'
|
||||||
|
LEFT JOIN adm_charge_item AS T3
|
||||||
|
ON T3.service_id = T1.ID AND T3.delete_flag = '0' AND
|
||||||
|
T3.service_table = 'wor_device_request'
|
||||||
|
LEFT JOIN adm_location AS al ON al.ID = T1.perform_location AND al.delete_flag = '0'
|
||||||
|
WHERE T1.delete_flag = '0' AND T1.generate_source_enum = 1
|
||||||
|
AND T1.encounter_id = %s
|
||||||
|
AND T1.refund_device_id IS NULL)
|
||||||
|
UNION ALL
|
||||||
|
(SELECT 3 AS advice_type,
|
||||||
|
T1.id AS request_id,
|
||||||
|
T1.id || '-3' AS unique_key,
|
||||||
|
T1.requester_id AS requester_id,
|
||||||
|
T1.create_time AS request_time,
|
||||||
|
CASE WHEN T1.requester_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
|
||||||
|
T1.content_json AS content_json,
|
||||||
|
null AS skin_test_flag,
|
||||||
|
null AS inject_flag,
|
||||||
|
null AS group_id,
|
||||||
|
COALESCE(T2.NAME, T1.content_json::jsonb->>'surgeryName') AS advice_name,
|
||||||
|
'' AS volume,
|
||||||
|
'' AS lot_number,
|
||||||
|
T1.quantity AS quantity,
|
||||||
|
T1.unit_code AS unit_code,
|
||||||
|
T1.status_enum AS status_enum,
|
||||||
|
'' AS method_code,
|
||||||
|
'' AS rate_code,
|
||||||
|
NULL AS dose,
|
||||||
|
'' AS dose_unit_code,
|
||||||
|
T3.id AS charge_item_id,
|
||||||
|
T3.total_price AS total_price,
|
||||||
|
T3.status_enum AS charge_status,
|
||||||
|
ao.id AS position_id,
|
||||||
|
ao.name AS position_name,
|
||||||
|
null AS dispense_per_duration,
|
||||||
|
1 AS part_percent,
|
||||||
|
'' AS condition_definition_name,
|
||||||
|
T1.therapy_enum AS therapyEnum,
|
||||||
|
99 AS sort_number,
|
||||||
|
T1.based_on_id AS based_on_id
|
||||||
|
FROM wor_service_request AS T1
|
||||||
|
LEFT JOIN wor_activity_definition AS T2
|
||||||
|
ON T2.ID = T1.activity_id
|
||||||
|
AND T2.delete_flag = '0'
|
||||||
|
LEFT JOIN adm_charge_item AS T3 ON T3.service_id = T1.ID AND T3.delete_flag = '0' AND
|
||||||
|
T3.service_table = 'wor_service_request'
|
||||||
|
LEFT JOIN adm_organization AS ao ON ao.ID = T1.org_id AND ao.delete_flag = '0'
|
||||||
|
WHERE T1.delete_flag = '0' AND T1.generate_source_enum = 1
|
||||||
|
AND T1.parent_id IS NULL
|
||||||
|
AND T1.encounter_id = %s)
|
||||||
|
ORDER BY status_enum
|
||||||
|
""",
|
||||||
|
(
|
||||||
|
practitioner_id,
|
||||||
|
encounter_id,
|
||||||
|
practitioner_id,
|
||||||
|
encounter_id,
|
||||||
|
practitioner_id,
|
||||||
|
encounter_id,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
print(f"查询到 {len(rows)} 条记录")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 模拟前端过滤
|
||||||
|
print("模拟前端过滤逻辑:")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 前端过滤条件
|
||||||
|
therapy_enum_filter = "" # 不过滤
|
||||||
|
order_class_code_filter = "" # 不过滤(全部)
|
||||||
|
order_status_filter = "" # 不过滤
|
||||||
|
|
||||||
|
filtered_count = 0
|
||||||
|
|
||||||
|
for i, row in enumerate(rows):
|
||||||
|
advice_type = row[0] # SQL中的 advice_type
|
||||||
|
request_id = row[1]
|
||||||
|
unique_key = row[2]
|
||||||
|
advice_name = row[10]
|
||||||
|
therapy_enum = row[25]
|
||||||
|
status_enum = row[14]
|
||||||
|
|
||||||
|
# 模拟前端的 adviceType 赋值
|
||||||
|
# 从前端代码看,adviceType 应该等于 SQL 的 advice_type
|
||||||
|
item_advice_type = advice_type # 1=药品, 2=耗材, 3=项目
|
||||||
|
|
||||||
|
# 模拟过滤
|
||||||
|
therapy_match = not therapy_enum_filter or str(therapy_enum_filter) == str(
|
||||||
|
therapy_enum
|
||||||
|
)
|
||||||
|
class_match = not order_class_code_filter or str(order_class_code_filter) == str(
|
||||||
|
item_advice_type
|
||||||
|
)
|
||||||
|
status_match = not order_status_filter or (
|
||||||
|
str(order_status_filter) == str(status_enum) and request_id
|
||||||
|
)
|
||||||
|
|
||||||
|
if therapy_match and class_match and status_match:
|
||||||
|
filtered_count += 1
|
||||||
|
type_names = {1: "药品", 2: "耗材", 3: "诊疗/手术"}
|
||||||
|
type_name = type_names.get(advice_type, f"类型{advice_type}")
|
||||||
|
print(
|
||||||
|
f"✓ 第{i + 1}条通过过滤: advice_type={advice_type}({type_name}), advice_name={advice_name}, therapyEnum={therapy_enum}, status={status_enum}"
|
||||||
|
)
|
||||||
|
|
||||||
|
print()
|
||||||
|
print(f"过滤后剩余: {filtered_count} 条")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 检查手术医嘱
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
category_enum,
|
||||||
|
COALESCE(
|
||||||
|
(SELECT name FROM wor_activity_definition WHERE id = sr.activity_id AND delete_flag = '0'),
|
||||||
|
sr.content_json::jsonb->>'surgeryName'
|
||||||
|
) as advice_name,
|
||||||
|
therapy_enum,
|
||||||
|
status_enum
|
||||||
|
FROM wor_service_request sr
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
AND encounter_id = %s
|
||||||
|
""",
|
||||||
|
(encounter_id,),
|
||||||
|
)
|
||||||
|
|
||||||
|
print("手术医嘱详情:")
|
||||||
|
for row in cursor.fetchall():
|
||||||
|
print(
|
||||||
|
f" ID: {row[0]}, category_enum: {row[1]}(手术), advice_name: {row[2]}, therapy_enum: {row[3]}, status: {row[4]}"
|
||||||
|
)
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
113
scripts/check_new_records.py
Normal file
113
scripts/check_new_records.py
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
import psycopg2
|
||||||
|
import json
|
||||||
|
|
||||||
|
DB_CONFIG = {
|
||||||
|
"host": "192.168.110.252",
|
||||||
|
"port": 15432,
|
||||||
|
"database": "postgresql",
|
||||||
|
"user": "postgresql",
|
||||||
|
"password": "Jchl1528",
|
||||||
|
"options": "-c search_path=hisdev",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def check_new_records():
|
||||||
|
conn = None
|
||||||
|
try:
|
||||||
|
print("Connecting to database...")
|
||||||
|
conn = psycopg2.connect(**DB_CONFIG)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
print("Connected!\n")
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
print("New Surgery Records Check")
|
||||||
|
print("=" * 80)
|
||||||
|
|
||||||
|
# Check specific IDs
|
||||||
|
ids = ["2039583488323280897", "2039583488231006210"]
|
||||||
|
for id in ids:
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
SELECT
|
||||||
|
wsr.id,
|
||||||
|
wsr.category_enum,
|
||||||
|
wsr.activity_id,
|
||||||
|
wsr.content_json::jsonb->>'surgeryName' as surgery_name,
|
||||||
|
wsr.content_json::jsonb->>'surgeryCode' as surgery_code,
|
||||||
|
wsr.content_json as full_json,
|
||||||
|
wsr.create_time,
|
||||||
|
cs.surgery_name as cli_surgery_name,
|
||||||
|
cs.surgery_code as cli_surgery_code
|
||||||
|
FROM wor_service_request wsr
|
||||||
|
LEFT JOIN cli_surgery cs ON cs.id = wsr.activity_id
|
||||||
|
WHERE wsr.id = %s
|
||||||
|
""",
|
||||||
|
(id,),
|
||||||
|
)
|
||||||
|
|
||||||
|
row = cursor.fetchone()
|
||||||
|
if row:
|
||||||
|
print(f"\nRecord ID: {row[0]}")
|
||||||
|
print(f" category_enum: {row[1]}")
|
||||||
|
print(f" activity_id: {row[2]}")
|
||||||
|
print(
|
||||||
|
f" surgeryName from content_json: {row[3] if row[3] else 'EMPTY'}"
|
||||||
|
)
|
||||||
|
print(
|
||||||
|
f" surgeryCode from content_json: {row[4] if row[4] else 'EMPTY'}"
|
||||||
|
)
|
||||||
|
print(f" cli_surgery_name: {row[7] if row[7] else 'N/A'}")
|
||||||
|
print(f" create_time: {row[6]}")
|
||||||
|
if row[5]:
|
||||||
|
try:
|
||||||
|
content = json.loads(row[5])
|
||||||
|
print(f" Full content_json keys: {list(content.keys())}")
|
||||||
|
except:
|
||||||
|
print(f" Raw content_json: {row[5][:100]}")
|
||||||
|
else:
|
||||||
|
print(f"\nRecord {id} not found!")
|
||||||
|
|
||||||
|
# Check most recent 3 surgery records
|
||||||
|
print("\n" + "=" * 80)
|
||||||
|
print("Most Recent 3 Surgery Records")
|
||||||
|
print("=" * 80)
|
||||||
|
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
wsr.id,
|
||||||
|
wsr.category_enum,
|
||||||
|
wsr.activity_id,
|
||||||
|
wsr.content_json::jsonb->>'surgeryName' as surgery_name,
|
||||||
|
wsr.content_json::jsonb->>'surgeryCode' as surgery_code,
|
||||||
|
wsr.create_time,
|
||||||
|
cs.surgery_name as cli_surgery_name
|
||||||
|
FROM wor_service_request wsr
|
||||||
|
LEFT JOIN cli_surgery cs ON cs.id = wsr.activity_id
|
||||||
|
WHERE wsr.category_enum = 4
|
||||||
|
AND wsr.delete_flag = '0'
|
||||||
|
ORDER BY wsr.create_time DESC
|
||||||
|
LIMIT 3
|
||||||
|
""")
|
||||||
|
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
for row in rows:
|
||||||
|
print(f"\nID: {row[0]}")
|
||||||
|
print(f" surgeryName: {row[3] if row[3] else 'EMPTY'}")
|
||||||
|
print(f" surgeryCode: {row[4] if row[4] else 'EMPTY'}")
|
||||||
|
print(f" cli_surgery_name: {row[6] if row[6] else 'N/A'}")
|
||||||
|
print(f" create_time: {row[5]}")
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error: {e}")
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
traceback.print_exc()
|
||||||
|
finally:
|
||||||
|
if conn:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
check_new_records()
|
||||||
105
scripts/check_service_request.py
Normal file
105
scripts/check_service_request.py
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
import psycopg2
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.stdout.reconfigure(encoding="utf-8")
|
||||||
|
|
||||||
|
conn = psycopg2.connect(
|
||||||
|
host="192.168.110.252",
|
||||||
|
port=15432,
|
||||||
|
database="postgresql",
|
||||||
|
user="postgresql",
|
||||||
|
password="Jchl1528",
|
||||||
|
)
|
||||||
|
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("SET search_path TO hisdev, public")
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
print("直接检查 ServiceRequest 数据")
|
||||||
|
print("=" * 80)
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 直接查询表数据
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
category_enum,
|
||||||
|
content_json,
|
||||||
|
activity_id
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE encounter_id = 2038823905749327873
|
||||||
|
AND delete_flag = '0'
|
||||||
|
AND parent_id IS NULL
|
||||||
|
""")
|
||||||
|
|
||||||
|
print("原始数据:")
|
||||||
|
for row in cursor.fetchall():
|
||||||
|
print(f" ID: {row[0]}")
|
||||||
|
print(f" category_enum: {row[1]}")
|
||||||
|
print(f" activity_id: {row[3]}")
|
||||||
|
if row[2]:
|
||||||
|
import json
|
||||||
|
|
||||||
|
try:
|
||||||
|
content = json.loads(row[2]) if isinstance(row[2], str) else row[2]
|
||||||
|
print(f" content_json.surgeryName: {content.get('surgeryName', 'N/A')}")
|
||||||
|
except:
|
||||||
|
print(f" content_json: {row[2][:100]}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("=" * 80)
|
||||||
|
print("测试 COALESCE 语法")
|
||||||
|
print("=" * 80)
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 测试 COALESCE 语法
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
COALESCE(category_enum, 3) as advice_type,
|
||||||
|
COALESCE(content_json::jsonb->>'surgeryName', '默认值') as surgery_name
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
LIMIT 1
|
||||||
|
""")
|
||||||
|
|
||||||
|
row = cursor.fetchone()
|
||||||
|
if row:
|
||||||
|
print(f"COALESCE 测试:")
|
||||||
|
print(f" ID: {row[0]}")
|
||||||
|
print(f" advice_type: {row[1]}")
|
||||||
|
print(f" surgery_name: {row[2]}")
|
||||||
|
else:
|
||||||
|
print("未找到记录")
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("=" * 80)
|
||||||
|
print("检查 activity_definition 关联")
|
||||||
|
print("=" * 80)
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 检查 activity_definition
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
sr.id,
|
||||||
|
sr.activity_id,
|
||||||
|
ad.name as activity_name,
|
||||||
|
COALESCE(ad.name, sr.content_json::jsonb->>'surgeryName') as coalesce_name
|
||||||
|
FROM wor_service_request sr
|
||||||
|
LEFT JOIN wor_activity_definition ad ON ad.id = sr.activity_id AND ad.delete_flag = '0'
|
||||||
|
WHERE sr.category_enum = 4
|
||||||
|
AND sr.delete_flag = '0'
|
||||||
|
AND sr.encounter_id = 2038823905749327873
|
||||||
|
""")
|
||||||
|
|
||||||
|
for row in cursor.fetchall():
|
||||||
|
print(f" ServiceRequest ID: {row[0]}")
|
||||||
|
print(f" activity_id: {row[1]}")
|
||||||
|
print(f" activity_name: {row[2]}")
|
||||||
|
print(f" coalesce_name: {row[3]}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
160
scripts/check_surgery_advice.py
Normal file
160
scripts/check_surgery_advice.py
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
诊断脚本:检查手术医嘱是否正确保存和显示
|
||||||
|
"""
|
||||||
|
|
||||||
|
import psycopg2
|
||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
# 数据库配置
|
||||||
|
DB_CONFIG = {
|
||||||
|
"host": "localhost",
|
||||||
|
"port": 5432,
|
||||||
|
"database": "his",
|
||||||
|
"user": "postgres",
|
||||||
|
"password": "postgres",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def check_surgery_advice():
|
||||||
|
"""检查最近保存的手术医嘱"""
|
||||||
|
try:
|
||||||
|
conn = psycopg2.connect(**DB_CONFIG)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
print("手术医嘱诊断报告")
|
||||||
|
print("=" * 80)
|
||||||
|
print(f"查询时间: {datetime.now()}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 1. 查询最近的手术医嘱(category_enum = 4)
|
||||||
|
print("1. 查询最近保存的手术医嘱:")
|
||||||
|
print("-" * 80)
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
category_enum,
|
||||||
|
activity_id,
|
||||||
|
content_json,
|
||||||
|
patient_id,
|
||||||
|
encounter_id,
|
||||||
|
create_time
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
LIMIT 5
|
||||||
|
""")
|
||||||
|
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
if not rows:
|
||||||
|
print("⚠️ 没有找到手术医嘱记录(category_enum = 4)")
|
||||||
|
else:
|
||||||
|
for row in rows:
|
||||||
|
print(f"\n手术医嘱 ID: {row[0]}")
|
||||||
|
print(f" category_enum: {row[1]}")
|
||||||
|
print(f" activity_id: {row[2]}")
|
||||||
|
print(f" patient_id: {row[4]}")
|
||||||
|
print(f" encounter_id: {row[5]}")
|
||||||
|
print(f" create_time: {row[6]}")
|
||||||
|
|
||||||
|
# 解析 content_json
|
||||||
|
try:
|
||||||
|
content = json.loads(row[3]) if row[3] else {}
|
||||||
|
surgery_name = content.get("surgeryName", "NOT FOUND")
|
||||||
|
surgery_code = content.get("surgeryCode", "NOT FOUND")
|
||||||
|
print(f" content_json.surgeryName: {surgery_name}")
|
||||||
|
print(f" content_json.surgeryCode: {surgery_code}")
|
||||||
|
|
||||||
|
if surgery_name == "NOT FOUND" or not surgery_name:
|
||||||
|
print(" ❌ 警告: content_json 中没有 surgeryName!")
|
||||||
|
else:
|
||||||
|
print(" ✅ surgeryName 已正确保存")
|
||||||
|
except Exception as e:
|
||||||
|
print(f" ❌ 解析 content_json 失败: {e}")
|
||||||
|
print(f" 原始内容: {row[3]}")
|
||||||
|
|
||||||
|
print("\n" + "=" * 80)
|
||||||
|
|
||||||
|
# 2. 测试 SQL 查询是否能正确获取 advice_name
|
||||||
|
print("\n2. 测试 SQL 查询是否能正确获取手术名称:")
|
||||||
|
print("-" * 80)
|
||||||
|
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
wsr.id,
|
||||||
|
COALESCE(wad.NAME, wsr.content_json::jsonb->>'surgeryName', wsr.content_json::jsonb->>'adviceName') AS advice_name,
|
||||||
|
wsr.content_json::jsonb->>'surgeryName' AS surgery_name_from_json,
|
||||||
|
wad.NAME AS activity_name,
|
||||||
|
wsr.category_enum
|
||||||
|
FROM wor_service_request wsr
|
||||||
|
LEFT JOIN wor_activity_definition wad ON wad.ID = wsr.activity_id AND wad.delete_flag = '0'
|
||||||
|
WHERE wsr.category_enum = 4
|
||||||
|
AND wsr.delete_flag = '0'
|
||||||
|
ORDER BY wsr.create_time DESC
|
||||||
|
LIMIT 5
|
||||||
|
""")
|
||||||
|
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
if not rows:
|
||||||
|
print("⚠️ 没有找到手术医嘱记录")
|
||||||
|
else:
|
||||||
|
for row in rows:
|
||||||
|
print(f"\n手术医嘱 ID: {row[0]}")
|
||||||
|
print(f" COALESCE advice_name: {row[1]}")
|
||||||
|
print(f" surgeryName from JSON: {row[2]}")
|
||||||
|
print(f" activity_definition name: {row[3]}")
|
||||||
|
print(f" category_enum: {row[4]}")
|
||||||
|
|
||||||
|
if not row[1]:
|
||||||
|
print(" ❌ 警告: advice_name 为空!")
|
||||||
|
else:
|
||||||
|
print(" ✅ advice_name 可以正确获取")
|
||||||
|
|
||||||
|
print("\n" + "=" * 80)
|
||||||
|
|
||||||
|
# 3. 检查是否存在 activity_id 对应的 wor_activity_definition
|
||||||
|
print("\n3. 检查手术医嘱的 activity_id 关联:")
|
||||||
|
print("-" * 80)
|
||||||
|
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
wsr.id,
|
||||||
|
wsr.activity_id,
|
||||||
|
wad.id AS def_id,
|
||||||
|
wad.name AS def_name,
|
||||||
|
CASE WHEN wad.id IS NULL THEN 'MISSING' ELSE 'OK' END AS status
|
||||||
|
FROM wor_service_request wsr
|
||||||
|
LEFT JOIN wor_activity_definition wad ON wad.ID = wsr.activity_id
|
||||||
|
WHERE wsr.category_enum = 4
|
||||||
|
AND wsr.delete_flag = '0'
|
||||||
|
ORDER BY wsr.create_time DESC
|
||||||
|
LIMIT 5
|
||||||
|
""")
|
||||||
|
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
for row in rows:
|
||||||
|
status_icon = "✅" if row[4] == "OK" else "❌"
|
||||||
|
print(
|
||||||
|
f"{status_icon} service_request.id={row[0]}, activity_id={row[1]}, definition={row[3] or 'NULL'}"
|
||||||
|
)
|
||||||
|
|
||||||
|
print("\n" + "=" * 80)
|
||||||
|
print("诊断完成")
|
||||||
|
print("=" * 80)
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ 诊断失败: {e}")
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
check_surgery_advice()
|
||||||
117
scripts/check_surgery_db.py
Normal file
117
scripts/check_surgery_db.py
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import psycopg2
|
||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
DB_CONFIG = {
|
||||||
|
"host": "192.168.110.252",
|
||||||
|
"port": 15432,
|
||||||
|
"database": "postgresql",
|
||||||
|
"user": "postgresql",
|
||||||
|
"password": "Jchl1528",
|
||||||
|
"options": "-c search_path=hisdev",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def check_surgery_advice():
|
||||||
|
conn = None
|
||||||
|
try:
|
||||||
|
print("Connecting to database...")
|
||||||
|
conn = psycopg2.connect(**DB_CONFIG)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
print("Connected!\n")
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
print("Surgery Advice Diagnostic Report")
|
||||||
|
print("=" * 80)
|
||||||
|
print(f"Time: {datetime.now()}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 1. Query recent surgery advice
|
||||||
|
print("1. Recent surgery advice records:")
|
||||||
|
print("-" * 80)
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
category_enum,
|
||||||
|
activity_id,
|
||||||
|
content_json::jsonb->>'surgeryName' as surgery_name,
|
||||||
|
content_json::jsonb->>'surgeryCode' as surgery_code,
|
||||||
|
create_time
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
LIMIT 5
|
||||||
|
""")
|
||||||
|
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
if not rows:
|
||||||
|
print("No surgery advice found (category_enum = 4)")
|
||||||
|
else:
|
||||||
|
for row in rows:
|
||||||
|
print(f"\nID: {row[0]}")
|
||||||
|
print(f" category_enum: {row[1]}")
|
||||||
|
print(f" activity_id: {row[2]}")
|
||||||
|
print(f" surgeryName from JSON: {row[3]}")
|
||||||
|
print(f" surgeryCode from JSON: {row[4]}")
|
||||||
|
print(f" create_time: {row[5]}")
|
||||||
|
|
||||||
|
if not row[3]:
|
||||||
|
print(" WARNING: surgeryName is EMPTY!")
|
||||||
|
else:
|
||||||
|
print(" OK: surgeryName exists")
|
||||||
|
|
||||||
|
print("\n" + "=" * 80)
|
||||||
|
|
||||||
|
# 2. Test SQL COALESCE query
|
||||||
|
print("\n2. Testing SQL COALESCE query:")
|
||||||
|
print("-" * 80)
|
||||||
|
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
wsr.id,
|
||||||
|
COALESCE(wad.NAME, wsr.content_json::jsonb->>'surgeryName', wsr.content_json::jsonb->>'adviceName') AS advice_name,
|
||||||
|
wsr.content_json::jsonb->>'surgeryName' AS surgery_name_from_json,
|
||||||
|
wad.NAME AS activity_name,
|
||||||
|
wsr.activity_id
|
||||||
|
FROM wor_service_request wsr
|
||||||
|
LEFT JOIN wor_activity_definition wad ON wad.ID = wsr.activity_id AND wad.delete_flag = '0'
|
||||||
|
WHERE wsr.category_enum = 4
|
||||||
|
AND wsr.delete_flag = '0'
|
||||||
|
ORDER BY wsr.create_time DESC
|
||||||
|
LIMIT 5
|
||||||
|
""")
|
||||||
|
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
for row in rows:
|
||||||
|
print(f"\nID: {row[0]}")
|
||||||
|
print(f" COALESCE advice_name: {row[1]}")
|
||||||
|
print(f" surgeryName from JSON: {row[2]}")
|
||||||
|
print(f" activity_definition name: {row[3]}")
|
||||||
|
print(f" activity_id: {row[4]}")
|
||||||
|
|
||||||
|
if not row[1]:
|
||||||
|
print(" WARNING: advice_name is EMPTY!")
|
||||||
|
else:
|
||||||
|
print(" OK: advice_name exists")
|
||||||
|
|
||||||
|
print("\n" + "=" * 80)
|
||||||
|
print("Diagnostic complete")
|
||||||
|
print("=" * 80)
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"ERROR: {e}")
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
traceback.print_exc()
|
||||||
|
finally:
|
||||||
|
if conn:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
check_surgery_advice()
|
||||||
83
scripts/check_surgery_detail.py
Normal file
83
scripts/check_surgery_detail.py
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
import psycopg2
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.stdout.reconfigure(encoding="utf-8")
|
||||||
|
|
||||||
|
conn = psycopg2.connect(
|
||||||
|
host="192.168.110.252",
|
||||||
|
port=15432,
|
||||||
|
database="postgresql",
|
||||||
|
user="postgresql",
|
||||||
|
password="Jchl1528",
|
||||||
|
)
|
||||||
|
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("SET search_path TO hisdev, public")
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
print("检查手术医嘱的详细信息")
|
||||||
|
print("=" * 80)
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 查询手术医嘱的详细信息
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
prescription_no,
|
||||||
|
category_enum,
|
||||||
|
status_enum,
|
||||||
|
patient_id,
|
||||||
|
encounter_id,
|
||||||
|
activity_id,
|
||||||
|
generate_source_enum,
|
||||||
|
content_json,
|
||||||
|
create_time
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE prescription_no = 'OP202603311433'
|
||||||
|
AND delete_flag = '0'
|
||||||
|
""")
|
||||||
|
|
||||||
|
row = cursor.fetchone()
|
||||||
|
if row:
|
||||||
|
print("手术医嘱详细信息:")
|
||||||
|
print(f" ID: {row[0]}")
|
||||||
|
print(f" 单号: {row[1]}")
|
||||||
|
print(f" category_enum: {row[2]} (4=手术)")
|
||||||
|
print(f" status_enum: {row[3]} (1=待签发)")
|
||||||
|
print(f" patient_id: {row[4]}")
|
||||||
|
print(f" encounter_id: {row[5]}")
|
||||||
|
print(f" activity_id: {row[6]}")
|
||||||
|
print(f" generate_source_enum: {row[7]} (1=医生处方)")
|
||||||
|
print(f" content_json: {row[8]}")
|
||||||
|
print(f" create_time: {row[9]}")
|
||||||
|
else:
|
||||||
|
print("未找到手术医嘱")
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("=" * 80)
|
||||||
|
|
||||||
|
# 查询该就诊的所有医嘱
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
prescription_no,
|
||||||
|
category_enum,
|
||||||
|
status_enum,
|
||||||
|
activity_id
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE encounter_id = 2038823905749327873
|
||||||
|
AND delete_flag = '0'
|
||||||
|
ORDER BY category_enum, create_time DESC
|
||||||
|
""")
|
||||||
|
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
print(f"就诊ID 2038823905749327873 的所有医嘱(共{len(rows)}条):")
|
||||||
|
for row in rows:
|
||||||
|
cat_names = {1: "西药", 2: "耗材", 3: "诊疗", 4: "手术"}
|
||||||
|
cat_name = cat_names.get(row[2], f"类型{row[2]}")
|
||||||
|
print(
|
||||||
|
f" ID: {row[0]}, 单号: {row[1]}, 类型: {cat_name}({row[2]}), 状态: {row[3]}, activity_id: {row[4]}"
|
||||||
|
)
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
53
scripts/check_therapy_columns.py
Normal file
53
scripts/check_therapy_columns.py
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import psycopg2
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.stdout.reconfigure(encoding="utf-8")
|
||||||
|
|
||||||
|
conn = psycopg2.connect(
|
||||||
|
host="192.168.110.252",
|
||||||
|
port=15432,
|
||||||
|
database="postgresql",
|
||||||
|
user="postgresql",
|
||||||
|
password="Jchl1528",
|
||||||
|
)
|
||||||
|
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("SET search_path TO hisdev, public")
|
||||||
|
|
||||||
|
print("wor_service_request therapy相关列:")
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT column_name
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_schema = 'hisdev'
|
||||||
|
AND table_name = 'wor_service_request'
|
||||||
|
AND column_name LIKE '%therapy%'
|
||||||
|
""")
|
||||||
|
for row in cursor.fetchall():
|
||||||
|
print(f" {row[0]}")
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("med_medication_request therapy相关列:")
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT column_name
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_schema = 'hisdev'
|
||||||
|
AND table_name = 'med_medication_request'
|
||||||
|
AND column_name LIKE '%therapy%'
|
||||||
|
""")
|
||||||
|
for row in cursor.fetchall():
|
||||||
|
print(f" {row[0]}")
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("wor_device_request therapy相关列:")
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT column_name
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_schema = 'hisdev'
|
||||||
|
AND table_name = 'wor_device_request'
|
||||||
|
AND column_name LIKE '%therapy%'
|
||||||
|
""")
|
||||||
|
for row in cursor.fetchall():
|
||||||
|
print(f" {row[0]}")
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
111
scripts/diagnose_surgery_flow.py
Normal file
111
scripts/diagnose_surgery_flow.py
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
import psycopg2
|
||||||
|
import json
|
||||||
|
|
||||||
|
DB_CONFIG = {
|
||||||
|
"host": "192.168.110.252",
|
||||||
|
"port": 15432,
|
||||||
|
"database": "postgresql",
|
||||||
|
"user": "postgresql",
|
||||||
|
"password": "Jchl1528",
|
||||||
|
"options": "-c search_path=hisdev",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def diagnose():
|
||||||
|
conn = None
|
||||||
|
try:
|
||||||
|
conn = psycopg2.connect(**DB_CONFIG)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
print("Diagnosis: Surgery Data Flow")
|
||||||
|
print("=" * 80)
|
||||||
|
|
||||||
|
# 1. Find latest cli_surgery records
|
||||||
|
print("\n1. Latest cli_surgery records:")
|
||||||
|
print("-" * 80)
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT id, surgery_name, surgery_code, surgery_no, create_time
|
||||||
|
FROM cli_surgery
|
||||||
|
WHERE delete_flag = '0'
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
LIMIT 3
|
||||||
|
""")
|
||||||
|
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
for row in rows:
|
||||||
|
print(f"ID: {row[0]}")
|
||||||
|
print(f" surgery_name: {'[HAS VALUE]' if row[1] else '[NULL/EMPTY]'}")
|
||||||
|
print(f" surgery_code: {'[HAS VALUE]' if row[2] else '[NULL/EMPTY]'}")
|
||||||
|
|
||||||
|
# 2. Check corresponding wor_service_request
|
||||||
|
print("\n2. Check wor_service_request:")
|
||||||
|
print("-" * 80)
|
||||||
|
|
||||||
|
for cli_id, cli_name, cli_code, cli_no, cli_time in rows:
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
SELECT
|
||||||
|
wsr.id,
|
||||||
|
wsr.content_json::jsonb->>'surgeryName' as surgery_name_json,
|
||||||
|
wsr.content_json::jsonb->>'surgeryCode' as surgery_code_json,
|
||||||
|
wsr.create_time
|
||||||
|
FROM wor_service_request wsr
|
||||||
|
WHERE wsr.activity_id = %s
|
||||||
|
AND wsr.category_enum = 4
|
||||||
|
AND wsr.delete_flag = '0'
|
||||||
|
""",
|
||||||
|
(cli_id,),
|
||||||
|
)
|
||||||
|
|
||||||
|
wsr_row = cursor.fetchone()
|
||||||
|
if wsr_row:
|
||||||
|
print(f"cli_surgery ID: {cli_id}")
|
||||||
|
print(
|
||||||
|
f" cli_surgery surgery_name: {'[HAS VALUE]' if cli_name else '[NULL]'}"
|
||||||
|
)
|
||||||
|
print(
|
||||||
|
f" cli_surgery surgery_code: {'[HAS VALUE]' if cli_code else '[NULL]'}"
|
||||||
|
)
|
||||||
|
print(f" wor_service_request ID: {wsr_row[0]}")
|
||||||
|
print(
|
||||||
|
f" wor_service_request surgeryName: {'[HAS VALUE]' if wsr_row[1] else '[NULL/EMPTY]'}"
|
||||||
|
)
|
||||||
|
print(
|
||||||
|
f" wor_service_request surgeryCode: {'[HAS VALUE]' if wsr_row[2] else '[NULL/EMPTY]'}"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not wsr_row[1] and cli_name:
|
||||||
|
print(
|
||||||
|
f" *** PROBLEM: cli_surgery has name but wor_service_request does NOT! ***"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
print(
|
||||||
|
f"cli_surgery ID: {cli_id} - No matching wor_service_request found!"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 3. Statistics
|
||||||
|
print("\n3. Statistics:")
|
||||||
|
print("-" * 80)
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
AND (content_json::jsonb->>'surgeryName' IS NULL OR content_json::jsonb->>'surgeryName' = '')
|
||||||
|
""")
|
||||||
|
|
||||||
|
count = cursor.fetchone()[0]
|
||||||
|
print(f" Surgery advice without surgeryName: {count}")
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error: {e}")
|
||||||
|
finally:
|
||||||
|
if conn:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
diagnose()
|
||||||
182
scripts/execute_repair.py
Normal file
182
scripts/execute_repair.py
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
import psycopg2
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# 设置UTF-8编码
|
||||||
|
sys.stdout.reconfigure(encoding="utf-8")
|
||||||
|
|
||||||
|
# 数据库连接
|
||||||
|
conn = psycopg2.connect(
|
||||||
|
host="192.168.110.252",
|
||||||
|
port=15432,
|
||||||
|
database="postgresql",
|
||||||
|
user="postgresql",
|
||||||
|
password="Jchl1528",
|
||||||
|
)
|
||||||
|
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
# 设置schema
|
||||||
|
cursor.execute("SET search_path TO hisdev, public")
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
# 1. 查询需要修复的记录数
|
||||||
|
print("=" * 60)
|
||||||
|
print("Bug #318 历史数据修复")
|
||||||
|
print("=" * 60)
|
||||||
|
print()
|
||||||
|
|
||||||
|
print("步骤1: 查询需要修复的手术申请单...")
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM doc_request_form rf
|
||||||
|
LEFT JOIN wor_service_request sr ON sr.prescription_no = rf.prescription_no
|
||||||
|
AND sr.delete_flag = '0'
|
||||||
|
WHERE rf.type_code = 'PROCEDURE'
|
||||||
|
AND rf.delete_flag = '0'
|
||||||
|
AND sr.id IS NULL
|
||||||
|
""")
|
||||||
|
count = cursor.fetchone()[0]
|
||||||
|
print(f"✓ 发现 {count} 条需要修复的手术申请单")
|
||||||
|
print()
|
||||||
|
|
||||||
|
if count == 0:
|
||||||
|
print("没有需要修复的数据")
|
||||||
|
else:
|
||||||
|
# 2. 查看部分记录详情
|
||||||
|
print("步骤2: 查看部分记录详情...")
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT rf.id, rf.prescription_no, rf.encounter_id, rf.patient_id, rf.create_time
|
||||||
|
FROM doc_request_form rf
|
||||||
|
LEFT JOIN wor_service_request sr ON sr.prescription_no = rf.prescription_no
|
||||||
|
AND sr.delete_flag = '0'
|
||||||
|
WHERE rf.type_code = 'PROCEDURE'
|
||||||
|
AND rf.delete_flag = '0'
|
||||||
|
AND sr.id IS NULL
|
||||||
|
ORDER BY rf.create_time DESC
|
||||||
|
LIMIT 5
|
||||||
|
""")
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
for row in rows:
|
||||||
|
print(
|
||||||
|
f" ID: {row[0]}, 单号: {row[1]}, 就诊: {row[2]}, 患者: {row[3]}, 时间: {row[4]}"
|
||||||
|
)
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 3. 执行修复 - 生成ServiceRequest
|
||||||
|
print("步骤3: 生成手术医嘱(ServiceRequest)...")
|
||||||
|
cursor.execute("""
|
||||||
|
INSERT INTO wor_service_request (
|
||||||
|
bus_no, prescription_no, status_enum, generate_source_enum,
|
||||||
|
therapy_enum, quantity, unit_code, category_enum,
|
||||||
|
patient_id, requester_id, encounter_id, authored_time,
|
||||||
|
org_id, content_json, delete_flag, create_time, create_by, tenant_id
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
LPAD(FLOOR(RANDOM() * 10000)::TEXT, 4, '0'),
|
||||||
|
rf.prescription_no,
|
||||||
|
1, 1, 2, 1, '次', 4,
|
||||||
|
rf.patient_id, rf.requester_id, rf.encounter_id, rf.create_time,
|
||||||
|
rf.org_id, rf.desc_json, '0', rf.create_time, rf.requester_id, 1
|
||||||
|
FROM doc_request_form rf
|
||||||
|
LEFT JOIN wor_service_request sr ON sr.prescription_no = rf.prescription_no
|
||||||
|
AND sr.delete_flag = '0'
|
||||||
|
WHERE rf.type_code = 'PROCEDURE'
|
||||||
|
AND rf.delete_flag = '0'
|
||||||
|
AND sr.id IS NULL
|
||||||
|
RETURNING id, prescription_no
|
||||||
|
""")
|
||||||
|
new_requests = cursor.fetchall()
|
||||||
|
print(f"✓ 成功生成 {len(new_requests)} 条手术医嘱")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 4. 生成ChargeItem
|
||||||
|
print("步骤4: 生成收费项目(ChargeItem)...")
|
||||||
|
|
||||||
|
# 获取刚插入的ServiceRequest
|
||||||
|
prescription_nos = [r[1] for r in new_requests]
|
||||||
|
if prescription_nos:
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
INSERT INTO adm_charge_item (
|
||||||
|
bus_no, status_enum, generate_source_enum, patient_id,
|
||||||
|
context_enum, encounter_id, enterer_id, entered_date,
|
||||||
|
service_table, service_id, product_table, requesting_org_id,
|
||||||
|
quantity_value, quantity_unit, unit_price, total_price,
|
||||||
|
delete_flag, create_time, create_by, tenant_id
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
'CI' || sr.bus_no, 1, 1, sr.patient_id, 3, sr.encounter_id,
|
||||||
|
sr.requester_id, sr.create_time, 'wor_service_request', sr.id,
|
||||||
|
'wor_activity_definition', sr.org_id, 1, '次',
|
||||||
|
COALESCE((sr.content_json::jsonb->>'surgeryFee')::numeric, 0),
|
||||||
|
COALESCE((sr.content_json::jsonb->>'surgeryFee')::numeric, 0),
|
||||||
|
'0', sr.create_time, sr.requester_id, 1
|
||||||
|
FROM wor_service_request sr
|
||||||
|
WHERE sr.prescription_no = ANY(%s)
|
||||||
|
AND sr.category_enum = 4
|
||||||
|
AND sr.delete_flag = '0'
|
||||||
|
""",
|
||||||
|
(prescription_nos,),
|
||||||
|
)
|
||||||
|
|
||||||
|
# 麻醉费用
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
INSERT INTO adm_charge_item (
|
||||||
|
bus_no, status_enum, generate_source_enum, patient_id,
|
||||||
|
context_enum, encounter_id, enterer_id, entered_date,
|
||||||
|
service_table, service_id, product_table, requesting_org_id,
|
||||||
|
quantity_value, quantity_unit, unit_price, total_price,
|
||||||
|
delete_flag, create_time, create_by, tenant_id
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
'CI' || sr.bus_no || '_A', 1, 1, sr.patient_id, 3, sr.encounter_id,
|
||||||
|
sr.requester_id, sr.create_time, 'wor_service_request', sr.id,
|
||||||
|
'wor_activity_definition', sr.org_id, 1, '次',
|
||||||
|
(sr.content_json::jsonb->>'anesthesiaFee')::numeric,
|
||||||
|
(sr.content_json::jsonb->>'anesthesiaFee')::numeric,
|
||||||
|
'0', sr.create_time, sr.requester_id, 1
|
||||||
|
FROM wor_service_request sr
|
||||||
|
WHERE sr.prescription_no = ANY(%s)
|
||||||
|
AND sr.category_enum = 4
|
||||||
|
AND sr.delete_flag = '0'
|
||||||
|
AND sr.content_json::jsonb->>'anesthesiaFee' IS NOT NULL
|
||||||
|
AND (sr.content_json::jsonb->>'anesthesiaFee')::numeric > 0
|
||||||
|
""",
|
||||||
|
(prescription_nos,),
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"✓ 成功生成收费项目")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 5. 验证结果
|
||||||
|
print("步骤5: 验证修复结果...")
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT COUNT(*) FROM wor_service_request
|
||||||
|
WHERE category_enum = 4 AND delete_flag = '0'
|
||||||
|
""")
|
||||||
|
service_count = cursor.fetchone()[0]
|
||||||
|
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT COUNT(*) FROM adm_charge_item ci
|
||||||
|
WHERE ci.service_table = 'wor_service_request'
|
||||||
|
AND EXISTS (
|
||||||
|
SELECT 1 FROM wor_service_request sr
|
||||||
|
WHERE sr.id = ci.service_id AND sr.category_enum = 4
|
||||||
|
)
|
||||||
|
""")
|
||||||
|
charge_count = cursor.fetchone()[0]
|
||||||
|
|
||||||
|
print(f"✓ 手术医嘱总数: {service_count}")
|
||||||
|
print(f"✓ 手术收费项目总数: {charge_count}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 提交事务
|
||||||
|
conn.commit()
|
||||||
|
print("=" * 60)
|
||||||
|
print("✓ 修复完成!")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
271
scripts/final_check.py
Normal file
271
scripts/final_check.py
Normal file
@@ -0,0 +1,271 @@
|
|||||||
|
import psycopg2
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.stdout.reconfigure(encoding="utf-8")
|
||||||
|
|
||||||
|
conn = psycopg2.connect(
|
||||||
|
host="192.168.110.252",
|
||||||
|
port=15432,
|
||||||
|
database="postgresql",
|
||||||
|
user="postgresql",
|
||||||
|
password="Jchl1528",
|
||||||
|
)
|
||||||
|
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("SET search_path TO hisdev, public")
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
print("检查手术医嘱的完整数据")
|
||||||
|
print("=" * 80)
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 检查手术医嘱的所有字段
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
sr.id,
|
||||||
|
sr.prescription_no,
|
||||||
|
sr.category_enum,
|
||||||
|
sr.status_enum,
|
||||||
|
sr.therapy_enum,
|
||||||
|
sr.patient_id,
|
||||||
|
sr.encounter_id,
|
||||||
|
sr.requester_id,
|
||||||
|
sr.activity_id,
|
||||||
|
sr.quantity,
|
||||||
|
sr.unit_code,
|
||||||
|
sr.content_json,
|
||||||
|
sr.generate_source_enum,
|
||||||
|
sr.delete_flag,
|
||||||
|
sr.parent_id,
|
||||||
|
sr.create_time
|
||||||
|
FROM wor_service_request sr
|
||||||
|
WHERE sr.category_enum = 4
|
||||||
|
AND sr.delete_flag = '0'
|
||||||
|
AND sr.encounter_id = 2038823905749327873
|
||||||
|
""")
|
||||||
|
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
print(f"手术医嘱数量: {len(rows)}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
for row in rows:
|
||||||
|
print(f"ID: {row[0]}")
|
||||||
|
print(f"单号: {row[1]}")
|
||||||
|
print(f"category_enum: {row[2]} (4=手术)")
|
||||||
|
print(f"status_enum: {row[3]} (1=待签发)")
|
||||||
|
print(f"therapy_enum: {row[4]}")
|
||||||
|
print(f"patient_id: {row[5]}")
|
||||||
|
print(f"encounter_id: {row[6]}")
|
||||||
|
print(f"requester_id: {row[7]}")
|
||||||
|
print(f"activity_id: {row[8]}")
|
||||||
|
print(f"quantity: {row[9]}")
|
||||||
|
print(f"unit_code: {row[10]}")
|
||||||
|
print(f"content_json: {row[11][:100] if row[11] else 'None'}...")
|
||||||
|
print(f"generate_source_enum: {row[12]}")
|
||||||
|
print(f"delete_flag: {row[13]}")
|
||||||
|
print(f"parent_id: {row[14]}")
|
||||||
|
print(f"create_time: {row[15]}")
|
||||||
|
print("-" * 80)
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 检查是否有parent_id不为null的记录(子医嘱)
|
||||||
|
print("检查是否有子医嘱(parent_id不为null):")
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM wor_service_request sr
|
||||||
|
WHERE sr.encounter_id = 2038823905749327873
|
||||||
|
AND sr.parent_id IS NOT NULL
|
||||||
|
AND sr.delete_flag = '0'
|
||||||
|
""")
|
||||||
|
parent_count = cursor.fetchone()[0]
|
||||||
|
print(f"子医嘱数量: {parent_count}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 检查SQL查询返回的完整数据(模拟getRegRequestBaseInfo)
|
||||||
|
print("=" * 80)
|
||||||
|
print("模拟完整的API查询(包含所有UNION)")
|
||||||
|
print("=" * 80)
|
||||||
|
print()
|
||||||
|
|
||||||
|
practitioner_id = 1980296166230962178
|
||||||
|
encounter_id = 2038823905749327873
|
||||||
|
|
||||||
|
# 使用完整的SQL查询(包含COALESCE修复)
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
(SELECT 1 AS advice_type,
|
||||||
|
T1.id AS request_id,
|
||||||
|
T1.id || '-1' AS unique_key,
|
||||||
|
T1.practitioner_id AS requester_id,
|
||||||
|
T1.create_time AS request_time,
|
||||||
|
CASE WHEN T1.practitioner_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
|
||||||
|
T1.content_json AS content_json,
|
||||||
|
T1.skin_test_flag AS skin_test_flag,
|
||||||
|
T1.infusion_flag AS inject_flag,
|
||||||
|
T1.group_id AS group_id,
|
||||||
|
T2.NAME AS advice_name,
|
||||||
|
T3.total_volume AS volume,
|
||||||
|
T1.lot_number AS lot_number,
|
||||||
|
T1.quantity AS quantity,
|
||||||
|
T1.unit_code AS unit_code,
|
||||||
|
T1.status_enum AS status_enum,
|
||||||
|
T1.method_code AS method_code,
|
||||||
|
T1.rate_code AS rate_code,
|
||||||
|
T1.dose AS dose,
|
||||||
|
T1.dose_unit_code AS dose_unit_code,
|
||||||
|
T4.id AS charge_item_id,
|
||||||
|
T4.total_price AS total_price,
|
||||||
|
T4.status_enum AS charge_status,
|
||||||
|
al.id AS position_id,
|
||||||
|
al.name AS position_name,
|
||||||
|
T1.dispense_per_duration AS dispense_per_duration,
|
||||||
|
T2.part_percent AS part_percent,
|
||||||
|
ccd.name AS condition_definition_name,
|
||||||
|
COALESCE(T1.therapy_enum, 1) AS therapyEnum,
|
||||||
|
T1.sort_number AS sort_number,
|
||||||
|
T1.based_on_id AS based_on_id
|
||||||
|
FROM med_medication_request AS T1
|
||||||
|
LEFT JOIN med_medication_definition AS T2 ON T2.ID = T1.medication_id
|
||||||
|
AND T2.delete_flag = '0'
|
||||||
|
LEFT JOIN med_medication AS T3 ON T3.medication_def_id = T2.ID
|
||||||
|
AND T3.delete_flag = '0'
|
||||||
|
LEFT JOIN adm_charge_item AS T4 ON T4.service_id = T1.ID AND T4.delete_flag = '0' AND
|
||||||
|
T4.service_table = 'med_medication_request'
|
||||||
|
LEFT JOIN adm_location AS al ON al.ID = T1.perform_location AND al.delete_flag = '0'
|
||||||
|
LEFT JOIN cli_condition AS cc ON cc.id = T1.condition_id AND cc.delete_flag = '0'
|
||||||
|
LEFT JOIN cli_condition_definition AS ccd ON ccd.id = cc.definition_id
|
||||||
|
WHERE T1.delete_flag = '0' AND T1.tcm_flag = 0 AND T1.generate_source_enum = 1
|
||||||
|
AND T1.encounter_id = %s
|
||||||
|
AND T1.refund_medicine_id IS NULL)
|
||||||
|
UNION ALL
|
||||||
|
(SELECT 2 AS advice_type,
|
||||||
|
T1.id AS request_id,
|
||||||
|
T1.id || '-2' AS unique_key,
|
||||||
|
T1.requester_id AS requester_id,
|
||||||
|
T1.create_time AS request_time,
|
||||||
|
CASE WHEN T1.requester_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
|
||||||
|
T1.content_json AS content_json,
|
||||||
|
null AS skin_test_flag,
|
||||||
|
null AS inject_flag,
|
||||||
|
null AS group_id,
|
||||||
|
T2.NAME AS advice_name,
|
||||||
|
T2.SIZE AS volume,
|
||||||
|
T1.lot_number AS lot_number,
|
||||||
|
T1.quantity AS quantity,
|
||||||
|
T1.unit_code AS unit_code,
|
||||||
|
T1.status_enum AS status_enum,
|
||||||
|
'' AS method_code,
|
||||||
|
T1.rate_code AS rate_code,
|
||||||
|
NULL AS dose,
|
||||||
|
'' AS dose_unit_code,
|
||||||
|
T3.id AS charge_item_id,
|
||||||
|
T3.total_price AS total_price,
|
||||||
|
T3.status_enum AS charge_status,
|
||||||
|
al.id AS position_id,
|
||||||
|
al.name AS position_name,
|
||||||
|
null AS dispense_per_duration,
|
||||||
|
T2.part_percent AS part_percent,
|
||||||
|
'' AS condition_definition_name,
|
||||||
|
COALESCE(T1.therapy_enum, 2) AS therapyEnum,
|
||||||
|
99 AS sort_number,
|
||||||
|
T1.based_on_id AS based_on_id
|
||||||
|
FROM wor_device_request AS T1
|
||||||
|
LEFT JOIN adm_device_definition AS T2 ON T2.ID = T1.device_def_id
|
||||||
|
AND T2.delete_flag = '0'
|
||||||
|
LEFT JOIN adm_charge_item AS T3
|
||||||
|
ON T3.service_id = T1.ID AND T3.delete_flag = '0' AND
|
||||||
|
T3.service_table = 'wor_device_request'
|
||||||
|
LEFT JOIN adm_location AS al ON al.ID = T1.perform_location AND al.delete_flag = '0'
|
||||||
|
WHERE T1.delete_flag = '0' AND T1.generate_source_enum = 1
|
||||||
|
AND T1.encounter_id = %s
|
||||||
|
AND T1.refund_device_id IS NULL)
|
||||||
|
UNION ALL
|
||||||
|
(SELECT 3 AS advice_type,
|
||||||
|
T1.id AS request_id,
|
||||||
|
T1.id || '-3' AS unique_key,
|
||||||
|
T1.requester_id AS requester_id,
|
||||||
|
T1.create_time AS request_time,
|
||||||
|
CASE WHEN T1.requester_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
|
||||||
|
T1.content_json AS content_json,
|
||||||
|
null AS skin_test_flag,
|
||||||
|
null AS inject_flag,
|
||||||
|
null AS group_id,
|
||||||
|
COALESCE(T2.NAME, T1.content_json::jsonb->>'surgeryName') AS advice_name,
|
||||||
|
'' AS volume,
|
||||||
|
'' AS lot_number,
|
||||||
|
T1.quantity AS quantity,
|
||||||
|
T1.unit_code AS unit_code,
|
||||||
|
T1.status_enum AS status_enum,
|
||||||
|
'' AS method_code,
|
||||||
|
'' AS rate_code,
|
||||||
|
NULL AS dose,
|
||||||
|
'' AS dose_unit_code,
|
||||||
|
T3.id AS charge_item_id,
|
||||||
|
T3.total_price AS total_price,
|
||||||
|
T3.status_enum AS charge_status,
|
||||||
|
ao.id AS position_id,
|
||||||
|
ao.name AS position_name,
|
||||||
|
null AS dispense_per_duration,
|
||||||
|
1 AS part_percent,
|
||||||
|
'' AS condition_definition_name,
|
||||||
|
COALESCE(T1.therapy_enum, 2) AS therapyEnum,
|
||||||
|
99 AS sort_number,
|
||||||
|
T1.based_on_id AS based_on_id
|
||||||
|
FROM wor_service_request AS T1
|
||||||
|
LEFT JOIN wor_activity_definition AS T2
|
||||||
|
ON T2.ID = T1.activity_id
|
||||||
|
AND T2.delete_flag = '0'
|
||||||
|
LEFT JOIN adm_charge_item AS T3 ON T3.service_id = T1.ID AND T3.delete_flag = '0' AND
|
||||||
|
T3.service_table = 'wor_service_request'
|
||||||
|
LEFT JOIN adm_organization AS ao ON ao.ID = T1.org_id AND ao.delete_flag = '0'
|
||||||
|
WHERE T1.delete_flag = '0' AND T1.generate_source_enum = 1
|
||||||
|
AND T1.parent_id IS NULL
|
||||||
|
AND T1.encounter_id = %s)
|
||||||
|
ORDER BY status_enum
|
||||||
|
""",
|
||||||
|
(
|
||||||
|
practitioner_id,
|
||||||
|
encounter_id,
|
||||||
|
practitioner_id,
|
||||||
|
encounter_id,
|
||||||
|
practitioner_id,
|
||||||
|
encounter_id,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
api_rows = cursor.fetchall()
|
||||||
|
print(f"API返回数据总数: {len(api_rows)}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 检查手术医嘱(advice_type=3)
|
||||||
|
surgery_rows = [r for r in api_rows if r[0] == 3]
|
||||||
|
print(f"手术医嘱(advice_type=3)数量: {len(surgery_rows)}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
for row in surgery_rows:
|
||||||
|
advice_name = row[10]
|
||||||
|
therapy_enum = row[25]
|
||||||
|
status = row[14]
|
||||||
|
print(f" advice_name: {advice_name}")
|
||||||
|
print(f" therapyEnum: {therapy_enum} (2=临时)")
|
||||||
|
print(f" status_enum: {status}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
print("结论:")
|
||||||
|
if len(surgery_rows) > 0:
|
||||||
|
print(f"✓ API查询返回了 {len(surgery_rows)} 条手术医嘱")
|
||||||
|
print("✓ advice_name 已正确返回")
|
||||||
|
print("✓ therapyEnum 默认为 2 (临时)")
|
||||||
|
print()
|
||||||
|
print("如果前端仍不显示,问题可能:")
|
||||||
|
print(" 1. 前端缓存 - 请清除浏览器缓存")
|
||||||
|
print(" 2. 代码未正确部署 - 请检查实际运行的代码版本")
|
||||||
|
print(" 3. 前端过滤逻辑 - 请检查浏览器控制台网络请求返回的数据")
|
||||||
|
else:
|
||||||
|
print("✗ API查询未返回手术医嘱")
|
||||||
|
print(" 请检查数据库数据或SQL条件")
|
||||||
126
scripts/fix_content_json.py
Normal file
126
scripts/fix_content_json.py
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
import psycopg2
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.stdout.reconfigure(encoding="utf-8")
|
||||||
|
|
||||||
|
conn = psycopg2.connect(
|
||||||
|
host="192.168.110.252",
|
||||||
|
port=15432,
|
||||||
|
database="postgresql",
|
||||||
|
user="postgresql",
|
||||||
|
password="Jchl1528",
|
||||||
|
)
|
||||||
|
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("SET search_path TO hisdev, public")
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
print("修复手术医嘱 content_json 为 null 的问题")
|
||||||
|
print("=" * 80)
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 1. 查询所有 content_json 为 null 的手术医嘱
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
prescription_no,
|
||||||
|
content_json
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
AND content_json IS NULL
|
||||||
|
""")
|
||||||
|
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
print(f"发现 {len(rows)} 条 content_json 为 null 的手术医嘱")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 2. 从对应的手术申请单获取 desc_json 并更新
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
sr.id,
|
||||||
|
sr.prescription_no,
|
||||||
|
rf.desc_json
|
||||||
|
FROM wor_service_request sr
|
||||||
|
JOIN doc_request_form rf ON rf.prescription_no = sr.prescription_no
|
||||||
|
WHERE sr.category_enum = 4
|
||||||
|
AND sr.delete_flag = '0'
|
||||||
|
AND sr.content_json IS NULL
|
||||||
|
AND rf.delete_flag = '0'
|
||||||
|
""")
|
||||||
|
|
||||||
|
fix_rows = cursor.fetchall()
|
||||||
|
print(f"找到 {len(fix_rows)} 条可以修复的记录")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 3. 更新 content_json
|
||||||
|
update_count = 0
|
||||||
|
for row in fix_rows:
|
||||||
|
service_id = row[0]
|
||||||
|
prescription_no = row[1]
|
||||||
|
desc_json = row[2]
|
||||||
|
|
||||||
|
if desc_json:
|
||||||
|
try:
|
||||||
|
# 解析 desc_json
|
||||||
|
if isinstance(desc_json, str):
|
||||||
|
desc_data = json.loads(desc_json)
|
||||||
|
else:
|
||||||
|
desc_data = desc_json
|
||||||
|
|
||||||
|
# 构建 content_json
|
||||||
|
content_data = {
|
||||||
|
"surgeryName": desc_data.get("surgeryName", ""),
|
||||||
|
"surgeryCode": desc_data.get("surgeryCode", ""),
|
||||||
|
"surgeryFee": desc_data.get("surgeryFee", "0"),
|
||||||
|
"anesthesiaFee": desc_data.get("anesthesiaFee", "0"),
|
||||||
|
"plannedTime": desc_data.get("plannedTime", ""),
|
||||||
|
"surgeryIndication": desc_data.get("surgeryIndication", ""),
|
||||||
|
"preoperativeDiagnosis": desc_data.get("preoperativeDiagnosis", ""),
|
||||||
|
}
|
||||||
|
|
||||||
|
content_json = json.dumps(content_data, ensure_ascii=False)
|
||||||
|
|
||||||
|
# 更新数据库
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
UPDATE wor_service_request
|
||||||
|
SET content_json = %s
|
||||||
|
WHERE id = %s
|
||||||
|
""",
|
||||||
|
(content_json, service_id),
|
||||||
|
)
|
||||||
|
|
||||||
|
update_count += 1
|
||||||
|
print(f"✓ 更新 ID={service_id}, 单号={prescription_no}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"✗ 更新失败 ID={service_id}: {e}")
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
print()
|
||||||
|
print(f"✓ 成功修复 {update_count} 条记录")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 4. 验证修复结果
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
prescription_no,
|
||||||
|
content_json
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
AND content_json IS NULL
|
||||||
|
""")
|
||||||
|
|
||||||
|
remaining = cursor.fetchall()
|
||||||
|
print(f"剩余 {len(remaining)} 条 content_json 为 null 的记录")
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("=" * 80)
|
||||||
|
print("修复完成!请刷新医嘱列表页面查看效果。")
|
||||||
|
print("=" * 80)
|
||||||
90
scripts/fix_remaining.py
Normal file
90
scripts/fix_remaining.py
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import psycopg2
|
||||||
|
|
||||||
|
DB_CONFIG = {
|
||||||
|
"host": "192.168.110.252",
|
||||||
|
"port": 15432,
|
||||||
|
"database": "postgresql",
|
||||||
|
"user": "postgresql",
|
||||||
|
"password": "Jchl1528",
|
||||||
|
"options": "-c search_path=hisdev",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def fix():
|
||||||
|
conn = None
|
||||||
|
try:
|
||||||
|
conn = psycopg2.connect(**DB_CONFIG)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
print("Fixing remaining surgery records")
|
||||||
|
print("=" * 80)
|
||||||
|
|
||||||
|
# Count before
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
AND (content_json::jsonb->>'surgeryName' IS NULL OR content_json::jsonb->>'surgeryName' = '')
|
||||||
|
""")
|
||||||
|
before = cursor.fetchone()[0]
|
||||||
|
print(f"\nBefore fix: {before} records without surgeryName")
|
||||||
|
|
||||||
|
# Execute fix
|
||||||
|
cursor.execute("""
|
||||||
|
UPDATE wor_service_request wsr
|
||||||
|
SET content_json =
|
||||||
|
COALESCE(
|
||||||
|
(wsr.content_json::jsonb || jsonb_build_object(
|
||||||
|
'surgeryName', cs.surgery_name,
|
||||||
|
'surgeryCode', COALESCE(cs.surgery_code, '')
|
||||||
|
))::text,
|
||||||
|
jsonb_build_object(
|
||||||
|
'surgeryName', cs.surgery_name,
|
||||||
|
'surgeryCode', COALESCE(cs.surgery_code, '')
|
||||||
|
)::text
|
||||||
|
)
|
||||||
|
FROM cli_surgery cs
|
||||||
|
WHERE wsr.category_enum = 4
|
||||||
|
AND wsr.delete_flag = '0'
|
||||||
|
AND (wsr.content_json::jsonb->>'surgeryName' IS NULL OR wsr.content_json::jsonb->>'surgeryName' = '')
|
||||||
|
AND cs.id = wsr.activity_id
|
||||||
|
AND cs.surgery_name IS NOT NULL
|
||||||
|
AND cs.delete_flag = '0'
|
||||||
|
""")
|
||||||
|
|
||||||
|
fixed = cursor.rowcount
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
print(f"Fixed: {fixed} records")
|
||||||
|
|
||||||
|
# Count after
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
AND (content_json::jsonb->>'surgeryName' IS NULL OR content_json::jsonb->>'surgeryName' = '')
|
||||||
|
""")
|
||||||
|
after = cursor.fetchone()[0]
|
||||||
|
print(f"After fix: {after} records without surgeryName")
|
||||||
|
|
||||||
|
if after == 0:
|
||||||
|
print("\n*** ALL RECORDS FIXED! ***")
|
||||||
|
else:
|
||||||
|
print(f"\n*** {after} records still need attention ***")
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error: {e}")
|
||||||
|
if conn:
|
||||||
|
conn.rollback()
|
||||||
|
finally:
|
||||||
|
if conn:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
fix()
|
||||||
206
scripts/query_patient_data.py
Normal file
206
scripts/query_patient_data.py
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
import psycopg2
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.stdout.reconfigure(encoding="utf-8")
|
||||||
|
|
||||||
|
# 数据库连接
|
||||||
|
conn = psycopg2.connect(
|
||||||
|
host="192.168.110.252",
|
||||||
|
port=15432,
|
||||||
|
database="postgresql",
|
||||||
|
user="postgresql",
|
||||||
|
password="Jchl1528",
|
||||||
|
)
|
||||||
|
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("SET search_path TO hisdev, public")
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
print("查询患者:王俊彭 (病历号: PN0000000038)")
|
||||||
|
print("=" * 80)
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 1. 查询患者基本信息和就诊ID
|
||||||
|
print("步骤1: 查询患者基本信息...")
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
p.id as patient_id,
|
||||||
|
p.name as patient_name,
|
||||||
|
e.id as encounter_id,
|
||||||
|
e.create_time as encounter_time
|
||||||
|
FROM adm_patient p
|
||||||
|
LEFT JOIN adm_encounter e ON e.patient_id = p.id
|
||||||
|
WHERE p.name = '王俊彭'
|
||||||
|
ORDER BY e.create_time DESC
|
||||||
|
LIMIT 5
|
||||||
|
""")
|
||||||
|
patient_rows = cursor.fetchall()
|
||||||
|
|
||||||
|
if not patient_rows:
|
||||||
|
print("✗ 未找到患者信息")
|
||||||
|
else:
|
||||||
|
for row in patient_rows:
|
||||||
|
print(
|
||||||
|
f" 患者ID: {row[0]}, 姓名: {row[1]}, 就诊ID: {row[2]}, 就诊时间: {row[3]}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 获取最新的就诊ID
|
||||||
|
encounter_id = patient_rows[0][2]
|
||||||
|
patient_id = patient_rows[0][0]
|
||||||
|
print(f"\n使用就诊ID: {encounter_id}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 2. 查询手术申请单
|
||||||
|
print("步骤2: 查询手术申请单...")
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
prescription_no,
|
||||||
|
type_code,
|
||||||
|
name,
|
||||||
|
create_time,
|
||||||
|
desc_json
|
||||||
|
FROM doc_request_form
|
||||||
|
WHERE encounter_id = %s
|
||||||
|
AND type_code = 'PROCEDURE'
|
||||||
|
AND delete_flag = '0'
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
""",
|
||||||
|
(encounter_id,),
|
||||||
|
)
|
||||||
|
|
||||||
|
request_forms = cursor.fetchall()
|
||||||
|
if not request_forms:
|
||||||
|
print("✗ 未找到手术申请单")
|
||||||
|
else:
|
||||||
|
print(f"✓ 找到 {len(request_forms)} 条手术申请单:")
|
||||||
|
for rf in request_forms:
|
||||||
|
print(
|
||||||
|
f" 申请单ID: {rf[0]}, 单号: {rf[1]}, 类型: {rf[2]}, 名称: {rf[3]}, 时间: {rf[4]}"
|
||||||
|
)
|
||||||
|
if rf[5]:
|
||||||
|
try:
|
||||||
|
import json
|
||||||
|
|
||||||
|
desc = json.loads(rf[5])
|
||||||
|
surgery_name = desc.get("surgeryName", "N/A")
|
||||||
|
surgery_fee = desc.get("surgeryFee", "N/A")
|
||||||
|
print(f" -> 手术名称: {surgery_name}, 手术费用: {surgery_fee}")
|
||||||
|
except:
|
||||||
|
print(f" -> 手术详情: {rf[5][:100]}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 3. 查询手术医嘱(ServiceRequest)
|
||||||
|
print("步骤3: 查询手术医嘱(ServiceRequest)...")
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
prescription_no,
|
||||||
|
status_enum,
|
||||||
|
category_enum,
|
||||||
|
patient_id,
|
||||||
|
encounter_id,
|
||||||
|
create_time,
|
||||||
|
content_json
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE patient_id = %s
|
||||||
|
AND category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
""",
|
||||||
|
(patient_id,),
|
||||||
|
)
|
||||||
|
|
||||||
|
service_requests = cursor.fetchall()
|
||||||
|
if not service_requests:
|
||||||
|
print("✗ 未找到手术医嘱")
|
||||||
|
print("\n⚠️ 问题确认:有手术申请单但没有对应的手术医嘱!")
|
||||||
|
else:
|
||||||
|
print(f"✓ 找到 {len(service_requests)} 条手术医嘱:")
|
||||||
|
for sr in service_requests:
|
||||||
|
status_text = {1: "待签发", 2: "已签发", 3: "已执行"}.get(
|
||||||
|
sr[2], f"状态{sr[2]}"
|
||||||
|
)
|
||||||
|
print(
|
||||||
|
f" 医嘱ID: {sr[0]}, 单号: {sr[1]}, 状态: {status_text}, 就诊ID: {sr[5]}, 时间: {sr[6]}"
|
||||||
|
)
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 4. 查询收费项目
|
||||||
|
print("步骤4: 查询收费项目(ChargeItem)...")
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
bus_no,
|
||||||
|
status_enum,
|
||||||
|
total_price,
|
||||||
|
service_id
|
||||||
|
FROM adm_charge_item
|
||||||
|
WHERE patient_id = %s
|
||||||
|
AND service_table = 'wor_service_request'
|
||||||
|
AND delete_flag = '0'
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
""",
|
||||||
|
(patient_id,),
|
||||||
|
)
|
||||||
|
|
||||||
|
charge_items = cursor.fetchall()
|
||||||
|
if not charge_items:
|
||||||
|
print("✗ 未找到收费项目")
|
||||||
|
else:
|
||||||
|
print(f"✓ 找到 {len(charge_items)} 条收费项目:")
|
||||||
|
for ci in charge_items:
|
||||||
|
print(f" 收费ID: {ci[0]}, 单号: {ci[1]}, 金额: {ci[3]}, 关联医嘱: {ci[4]}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 5. 查询医嘱列表(用于对比)
|
||||||
|
print("步骤5: 查询该患者的所有医嘱...")
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
SELECT
|
||||||
|
category_enum,
|
||||||
|
status_enum,
|
||||||
|
count(*) as count
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE patient_id = %s
|
||||||
|
AND delete_flag = '0'
|
||||||
|
GROUP BY category_enum, status_enum
|
||||||
|
ORDER BY category_enum
|
||||||
|
""",
|
||||||
|
(patient_id,),
|
||||||
|
)
|
||||||
|
|
||||||
|
categories = cursor.fetchall()
|
||||||
|
if categories:
|
||||||
|
print("✓ 医嘱统计:")
|
||||||
|
cat_names = {1: "西药", 2: "耗材", 3: "诊疗", 4: "手术"}
|
||||||
|
stat_names = {1: "待签发", 2: "已签发", 3: "已执行"}
|
||||||
|
for cat in categories:
|
||||||
|
cat_name = cat_names.get(cat[0], f"类型{cat[0]}")
|
||||||
|
stat_name = stat_names.get(cat[1], f"状态{cat[1]}")
|
||||||
|
print(f" {cat_name} - {stat_name}: {cat[2]}条")
|
||||||
|
print()
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
|
||||||
|
# 问题诊断
|
||||||
|
if request_forms and not service_requests:
|
||||||
|
print("\n🔴 问题确认:")
|
||||||
|
print(" ✓ 手术申请单存在(doc_request_form)")
|
||||||
|
print(" ✗ 手术医嘱不存在(wor_service_request)")
|
||||||
|
print("\n 结论:保存手术申请单时未生成手术医嘱")
|
||||||
|
print(" 原因:代码修复可能未生效或未部署到生产环境")
|
||||||
|
elif service_requests:
|
||||||
|
print("\n✅ 数据正常:")
|
||||||
|
print(" ✓ 手术申请单存在")
|
||||||
|
print(" ✓ 手术医嘱存在")
|
||||||
|
print("\n 请在医嘱TAB页面查看是否能显示")
|
||||||
|
|
||||||
|
print()
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
39
scripts/rebuild-backend-memory.bat
Normal file
39
scripts/rebuild-backend-memory.bat
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ============================================
|
||||||
|
# OpenHIS 后端编译脚本(增加内存)
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
cd /d D:\his\openhis-server-new
|
||||||
|
|
||||||
|
echo "============================================"
|
||||||
|
echo "开始编译 OpenHIS 后端"
|
||||||
|
echo "============================================"
|
||||||
|
echo.
|
||||||
|
|
||||||
|
:: 设置更大的堆内存给 Maven
|
||||||
|
echo "[1/3] 清理旧的编译文件..."
|
||||||
|
set MAVEN_OPTS=-Xmx4g -XX:MaxMetaspaceSize=512m
|
||||||
|
call mvn clean -q
|
||||||
|
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo 清理失败!
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
echo "[2/3] 编译打包(跳过测试)..."
|
||||||
|
set MAVEN_OPTS=-Xmx4g -XX:MaxMetaspaceSize=512m -XX:+UseG1GC
|
||||||
|
call mvn package -DskipTests -q
|
||||||
|
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo 编译失败!
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
echo "[3/3] 编译完成!"
|
||||||
|
echo.
|
||||||
|
echo "============================================"
|
||||||
|
echo 请手动重启后端服务
|
||||||
|
echo ============================================
|
||||||
|
pause
|
||||||
31
scripts/rebuild-backend.bat
Normal file
31
scripts/rebuild-backend.bat
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
@echo off
|
||||||
|
chcp 65001 >nul
|
||||||
|
echo ============================================
|
||||||
|
echo 重新编译部署 OpenHIS 后端
|
||||||
|
echo ============================================
|
||||||
|
echo.
|
||||||
|
|
||||||
|
cd /d D:\his\openhis-server-new
|
||||||
|
|
||||||
|
echo [1/3] 清理旧的编译文件...
|
||||||
|
call mvn clean -q
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo 清理失败!
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
echo [2/3] 编译打包(跳过测试)...
|
||||||
|
call mvn package -DskipTests -q
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo 编译失败!
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
echo [3/3] 编译完成!
|
||||||
|
echo.
|
||||||
|
echo ============================================
|
||||||
|
echo 请手动重启后端服务
|
||||||
|
echo ============================================
|
||||||
|
pause
|
||||||
102
scripts/test-device-api.js
Normal file
102
scripts/test-device-api.js
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
const { chromium } = require('playwright');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
async function testDeviceApi() {
|
||||||
|
const browser = await chromium.launch({
|
||||||
|
headless: true,
|
||||||
|
args: ['--no-sandbox', '--disable-setuid-sandbox']
|
||||||
|
});
|
||||||
|
|
||||||
|
const context = await browser.newContext({
|
||||||
|
viewport: { width: 1920, height: 2000 }
|
||||||
|
});
|
||||||
|
|
||||||
|
const page = await context.newPage();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const baseUrl = 'http://localhost:18080';
|
||||||
|
|
||||||
|
// Step 1: 登录获取token
|
||||||
|
console.log('[Step 1] 登录获取token...');
|
||||||
|
const loginRes = await page.evaluate(async (baseUrl) => {
|
||||||
|
const res = await fetch(`${baseUrl}/login`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ username: 'admin', password: 'admin123' })
|
||||||
|
});
|
||||||
|
return res.json();
|
||||||
|
}, baseUrl);
|
||||||
|
|
||||||
|
console.log('[Step 1] 登录结果:', loginRes.code === 200 ? '成功' : '失败');
|
||||||
|
|
||||||
|
if (loginRes.code !== 200) {
|
||||||
|
console.error('[Error] 登录失败:', loginRes.msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2: 调用getDeviceList API
|
||||||
|
console.log('[Step 2] 调用耗材列表API...');
|
||||||
|
const apiRes = await page.evaluate(async (baseUrl) => {
|
||||||
|
const res = await fetch(`${baseUrl}/data-dictionary/device/information-page?pageNo=1&pageSize=100&searchKey=&statusEnum=2`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': 'Bearer ' + localStorage.getItem('token')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return res.json();
|
||||||
|
}, baseUrl);
|
||||||
|
|
||||||
|
console.log('[Step 2] API响应状态:', apiRes.code);
|
||||||
|
|
||||||
|
if (apiRes.code === 200 && apiRes.data && apiRes.data.records) {
|
||||||
|
console.log(`\n[Step 3] 获取到 ${apiRes.data.records.length} 条耗材记录`);
|
||||||
|
|
||||||
|
// 保存完整数据到文件
|
||||||
|
fs.writeFileSync('device_api_response.json', JSON.stringify(apiRes.data, null, 2));
|
||||||
|
console.log('[Step 3] 完整数据已保存到 device_api_response.json');
|
||||||
|
|
||||||
|
// 分析前5条记录
|
||||||
|
console.log('\n[Step 4] 分析前5条记录的价格字段:');
|
||||||
|
apiRes.data.records.slice(0, 5).forEach((item, index) => {
|
||||||
|
console.log(`\n记录 ${index + 1}:`);
|
||||||
|
console.log(' - name:', item.name);
|
||||||
|
console.log(' - busNo:', item.busNo);
|
||||||
|
console.log(' - price:', item.price);
|
||||||
|
console.log(' - retailPrice:', item.retailPrice);
|
||||||
|
console.log(' - purchasePrice:', item.purchasePrice);
|
||||||
|
console.log(' - maximumRetailPrice:', item.maximumRetailPrice);
|
||||||
|
|
||||||
|
// 检查所有包含price的字段
|
||||||
|
const priceFields = Object.keys(item).filter(k =>
|
||||||
|
k.toLowerCase().includes('price') || k.toLowerCase().includes('amount')
|
||||||
|
);
|
||||||
|
console.log(' - 所有价格相关字段:', priceFields);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 统计有多少条记录有价格
|
||||||
|
const withRetailPrice = apiRes.data.records.filter(item =>
|
||||||
|
item.retailPrice !== undefined && item.retailPrice !== null && item.retailPrice !== ''
|
||||||
|
).length;
|
||||||
|
const withPrice = apiRes.data.records.filter(item =>
|
||||||
|
item.price !== undefined && item.price !== null && item.price !== ''
|
||||||
|
).length;
|
||||||
|
|
||||||
|
console.log(`\n[Step 5] 数据统计:`);
|
||||||
|
console.log(` - 总记录数: ${apiRes.data.records.length}`);
|
||||||
|
console.log(` - 有retailPrice的记录: ${withRetailPrice}`);
|
||||||
|
console.log(` - 有price的记录: ${withPrice}`);
|
||||||
|
console.log(` - 无任何价格的记录: ${apiRes.data.records.length - Math.max(withRetailPrice, withPrice)}`);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
console.error('[Error] API调用失败:', apiRes.msg || '未知错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[Error]', error.message);
|
||||||
|
} finally {
|
||||||
|
await browser.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testDeviceApi();
|
||||||
116
scripts/test_doctorstation_sql.py
Normal file
116
scripts/test_doctorstation_sql.py
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
import psycopg2
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.stdout.reconfigure(encoding="utf-8")
|
||||||
|
|
||||||
|
conn = psycopg2.connect(
|
||||||
|
host="192.168.110.252",
|
||||||
|
port=15432,
|
||||||
|
database="postgresql",
|
||||||
|
user="postgresql",
|
||||||
|
password="Jchl1528",
|
||||||
|
)
|
||||||
|
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("SET search_path TO hisdev, public")
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
print("测试 DoctorStation SQL (模拟 doctor-station API)")
|
||||||
|
print("=" * 80)
|
||||||
|
print()
|
||||||
|
|
||||||
|
encounter_id = 2038823905749327873
|
||||||
|
practitioner_id = 1980296166230962178
|
||||||
|
|
||||||
|
# 使用修改后的 SQL 查询(第三部分 - ServiceRequest)
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
SELECT
|
||||||
|
COALESCE(T1.category_enum, 3) AS advice_type,
|
||||||
|
T1.id AS request_id,
|
||||||
|
T1.id || '-3' AS unique_key,
|
||||||
|
'' AS prescription_no,
|
||||||
|
T1.requester_id AS requester_id,
|
||||||
|
T1.create_time AS request_time,
|
||||||
|
CASE WHEN T1.requester_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
|
||||||
|
T1.content_json AS content_json,
|
||||||
|
null AS skin_test_flag,
|
||||||
|
null AS inject_flag,
|
||||||
|
null AS group_id,
|
||||||
|
COALESCE(T2.NAME, T1.content_json::jsonb->>'surgeryName', T1.content_json::jsonb->>'adviceName') AS advice_name,
|
||||||
|
'' AS volume,
|
||||||
|
'' AS lot_number,
|
||||||
|
T1.quantity AS quantity,
|
||||||
|
T1.unit_code AS unit_code,
|
||||||
|
T1.status_enum AS status_enum,
|
||||||
|
'' AS method_code,
|
||||||
|
'' AS rate_code,
|
||||||
|
NULL AS dose,
|
||||||
|
'' AS dose_unit_code,
|
||||||
|
T3.id AS charge_item_id,
|
||||||
|
T3.total_price AS total_price,
|
||||||
|
T3.status_enum AS charge_status,
|
||||||
|
ao.id AS position_id,
|
||||||
|
ao.name AS position_name,
|
||||||
|
null AS dispense_per_duration,
|
||||||
|
1 AS part_percent,
|
||||||
|
'' AS condition_definition_name,
|
||||||
|
99 AS sort_number,
|
||||||
|
T1.based_on_id AS based_on_id,
|
||||||
|
T1.category_enum AS category_enum
|
||||||
|
FROM wor_service_request AS T1
|
||||||
|
LEFT JOIN wor_activity_definition AS T2
|
||||||
|
ON T2.ID = T1.activity_id
|
||||||
|
AND T2.delete_flag = '0'
|
||||||
|
LEFT JOIN adm_charge_item AS T3 ON T3.service_id = T1.ID AND T3.delete_flag = '0' AND
|
||||||
|
T3.service_table = 'wor_service_request'
|
||||||
|
LEFT JOIN adm_organization AS ao ON ao.ID = T1.org_id AND ao.delete_flag = '0'
|
||||||
|
WHERE T1.delete_flag = '0' AND T1.generate_source_enum = 1
|
||||||
|
AND T1.parent_id IS NULL
|
||||||
|
AND T1.encounter_id = %s
|
||||||
|
ORDER BY T1.status_enum
|
||||||
|
""",
|
||||||
|
(practitioner_id, encounter_id),
|
||||||
|
)
|
||||||
|
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
print(f"查询到 {len(rows)} 条 ServiceRequest 记录")
|
||||||
|
print()
|
||||||
|
|
||||||
|
for row in rows:
|
||||||
|
advice_type = row[0]
|
||||||
|
request_id = row[1]
|
||||||
|
advice_name = row[10]
|
||||||
|
category_enum = row[25]
|
||||||
|
|
||||||
|
print(f"request_id: {request_id}")
|
||||||
|
print(f" advice_type: {advice_type} (应该=4)")
|
||||||
|
print(f" category_enum: {category_enum}")
|
||||||
|
print(f" advice_name: {advice_name}")
|
||||||
|
print(f" advice_name是否为空: {advice_name is None or advice_name == ''}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 特别检查手术医嘱
|
||||||
|
surgery_rows = [r for r in rows if r[24] == 4] # category_enum = 4
|
||||||
|
print(f"手术医嘱 (category_enum=4) 数量: {len(surgery_rows)}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
if surgery_rows:
|
||||||
|
for row in surgery_rows:
|
||||||
|
print(f"✓ 手术医嘱:")
|
||||||
|
print(f" request_id: {row[1]}")
|
||||||
|
print(f" advice_type: {row[0]} (应该=4)")
|
||||||
|
print(f" advice_name: {row[10]}")
|
||||||
|
print(
|
||||||
|
f" 是否通过前端过滤: {'否 (adviceName为空)' if not row[10] or row[10].strip() == '' else '是'}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
print("✗ 未找到手术医嘱")
|
||||||
|
print()
|
||||||
|
print("可能原因:")
|
||||||
|
print(" 1. SQL COALESCE 语法错误")
|
||||||
|
print(" 2. content_json 中没有 surgeryName 字段")
|
||||||
|
print(" 3. 数据未正确保存")
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
214
scripts/test_frontend_processing.py
Normal file
214
scripts/test_frontend_processing.py
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
import psycopg2
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.stdout.reconfigure(encoding="utf-8")
|
||||||
|
|
||||||
|
conn = psycopg2.connect(
|
||||||
|
host="192.168.110.252",
|
||||||
|
port=15432,
|
||||||
|
database="postgresql",
|
||||||
|
user="postgresql",
|
||||||
|
password="Jchl1528",
|
||||||
|
)
|
||||||
|
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("SET search_path TO hisdev, public")
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
print("模拟前端处理逻辑,检查是否会报错")
|
||||||
|
print("=" * 80)
|
||||||
|
print()
|
||||||
|
|
||||||
|
encounter_id = 2038823905749327873
|
||||||
|
practitioner_id = 1980296166230962178
|
||||||
|
|
||||||
|
# 查询所有数据(UNION ALL 三部分)
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
(SELECT 1 AS advice_type,
|
||||||
|
T1.id AS request_id,
|
||||||
|
T1.id || '-1' AS unique_key,
|
||||||
|
T1.practitioner_id AS requester_id,
|
||||||
|
T1.create_time AS request_time,
|
||||||
|
CASE WHEN T1.practitioner_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
|
||||||
|
T1.content_json AS content_json,
|
||||||
|
T1.skin_test_flag AS skin_test_flag,
|
||||||
|
T1.infusion_flag AS inject_flag,
|
||||||
|
T1.group_id AS group_id,
|
||||||
|
T2.NAME AS advice_name,
|
||||||
|
T3.total_volume AS volume,
|
||||||
|
T1.lot_number AS lot_number,
|
||||||
|
T1.quantity AS quantity,
|
||||||
|
T1.unit_code AS unit_code,
|
||||||
|
T1.status_enum AS status_enum,
|
||||||
|
T1.method_code AS method_code,
|
||||||
|
T1.rate_code AS rate_code,
|
||||||
|
T1.dose AS dose,
|
||||||
|
T1.dose_unit_code AS dose_unit_code,
|
||||||
|
T4.id AS charge_item_id,
|
||||||
|
T4.total_price AS total_price,
|
||||||
|
T4.status_enum AS charge_status,
|
||||||
|
al.id AS position_id,
|
||||||
|
al.name AS position_name,
|
||||||
|
T1.dispense_per_duration AS dispense_per_duration,
|
||||||
|
T2.part_percent AS part_percent,
|
||||||
|
ccd.name AS condition_definition_name,
|
||||||
|
T1.therapy_enum AS therapyEnum,
|
||||||
|
T1.sort_number AS sort_number,
|
||||||
|
T1.based_on_id AS based_on_id
|
||||||
|
FROM med_medication_request AS T1
|
||||||
|
LEFT JOIN med_medication_definition AS T2 ON T2.ID = T1.medication_id
|
||||||
|
AND T2.delete_flag = '0'
|
||||||
|
LEFT JOIN med_medication AS T3 ON T3.medication_def_id = T2.ID
|
||||||
|
AND T3.delete_flag = '0'
|
||||||
|
LEFT JOIN adm_charge_item AS T4 ON T4.service_id = T1.ID AND T4.delete_flag = '0' AND
|
||||||
|
T4.service_table = 'med_medication_request'
|
||||||
|
LEFT JOIN adm_location AS al ON al.ID = T1.perform_location AND al.delete_flag = '0'
|
||||||
|
LEFT JOIN cli_condition AS cc ON cc.id = T1.condition_id AND cc.delete_flag = '0'
|
||||||
|
LEFT JOIN cli_condition_definition AS ccd ON ccd.id = cc.definition_id
|
||||||
|
WHERE T1.delete_flag = '0' AND T1.tcm_flag = 0 AND T1.generate_source_enum = 1
|
||||||
|
AND T1.encounter_id = %s
|
||||||
|
AND T1.refund_medicine_id IS NULL)
|
||||||
|
UNION ALL
|
||||||
|
(SELECT 2 AS advice_type,
|
||||||
|
T1.id AS request_id,
|
||||||
|
T1.id || '-2' AS unique_key,
|
||||||
|
T1.requester_id AS requester_id,
|
||||||
|
T1.create_time AS request_time,
|
||||||
|
CASE WHEN T1.requester_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
|
||||||
|
T1.content_json AS content_json,
|
||||||
|
null AS skin_test_flag,
|
||||||
|
null AS inject_flag,
|
||||||
|
null AS group_id,
|
||||||
|
T2.NAME AS advice_name,
|
||||||
|
T2.SIZE AS volume,
|
||||||
|
T1.lot_number AS lot_number,
|
||||||
|
T1.quantity AS quantity,
|
||||||
|
T1.unit_code AS unit_code,
|
||||||
|
T1.status_enum AS status_enum,
|
||||||
|
'' AS method_code,
|
||||||
|
T1.rate_code AS rate_code,
|
||||||
|
NULL AS dose,
|
||||||
|
'' AS dose_unit_code,
|
||||||
|
T3.id AS charge_item_id,
|
||||||
|
T3.total_price AS total_price,
|
||||||
|
T3.status_enum AS charge_status,
|
||||||
|
al.id AS position_id,
|
||||||
|
al.name AS position_name,
|
||||||
|
null AS dispense_per_duration,
|
||||||
|
T2.part_percent AS part_percent,
|
||||||
|
'' AS condition_definition_name,
|
||||||
|
2 AS therapyEnum,
|
||||||
|
99 AS sort_number,
|
||||||
|
T1.based_on_id AS based_on_id
|
||||||
|
FROM wor_device_request AS T1
|
||||||
|
LEFT JOIN adm_device_definition AS T2 ON T2.ID = T1.device_def_id
|
||||||
|
AND T2.delete_flag = '0'
|
||||||
|
LEFT JOIN adm_charge_item AS T3
|
||||||
|
ON T3.service_id = T1.ID AND T3.delete_flag = '0' AND
|
||||||
|
T3.service_table = 'wor_device_request'
|
||||||
|
LEFT JOIN adm_location AS al ON al.ID = T1.perform_location AND al.delete_flag = '0'
|
||||||
|
WHERE T1.delete_flag = '0' AND T1.generate_source_enum = 1
|
||||||
|
AND T1.encounter_id = %s
|
||||||
|
AND T1.refund_device_id IS NULL)
|
||||||
|
UNION ALL
|
||||||
|
(SELECT 3 AS advice_type,
|
||||||
|
T1.id AS request_id,
|
||||||
|
T1.id || '-3' AS unique_key,
|
||||||
|
T1.requester_id AS requester_id,
|
||||||
|
T1.create_time AS request_time,
|
||||||
|
CASE WHEN T1.requester_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
|
||||||
|
T1.content_json AS content_json,
|
||||||
|
null AS skin_test_flag,
|
||||||
|
null AS inject_flag,
|
||||||
|
null AS group_id,
|
||||||
|
COALESCE(T2.NAME, T1.content_json::jsonb->>'surgeryName') AS advice_name,
|
||||||
|
'' AS volume,
|
||||||
|
'' AS lot_number,
|
||||||
|
T1.quantity AS quantity,
|
||||||
|
T1.unit_code AS unit_code,
|
||||||
|
T1.status_enum AS status_enum,
|
||||||
|
'' AS method_code,
|
||||||
|
'' AS rate_code,
|
||||||
|
NULL AS dose,
|
||||||
|
'' AS dose_unit_code,
|
||||||
|
T3.id AS charge_item_id,
|
||||||
|
T3.total_price AS total_price,
|
||||||
|
T3.status_enum AS charge_status,
|
||||||
|
ao.id AS position_id,
|
||||||
|
ao.name AS position_name,
|
||||||
|
null AS dispense_per_duration,
|
||||||
|
1 AS part_percent,
|
||||||
|
'' AS condition_definition_name,
|
||||||
|
T1.therapy_enum AS therapyEnum,
|
||||||
|
99 AS sort_number,
|
||||||
|
T1.based_on_id AS based_on_id
|
||||||
|
FROM wor_service_request AS T1
|
||||||
|
LEFT JOIN wor_activity_definition AS T2
|
||||||
|
ON T2.ID = T1.activity_id
|
||||||
|
AND T2.delete_flag = '0'
|
||||||
|
LEFT JOIN adm_charge_item AS T3 ON T3.service_id = T1.ID AND T3.delete_flag = '0' AND
|
||||||
|
T3.service_table = 'wor_service_request'
|
||||||
|
LEFT JOIN adm_organization AS ao ON ao.ID = T1.org_id AND ao.delete_flag = '0'
|
||||||
|
WHERE T1.delete_flag = '0' AND T1.generate_source_enum = 1
|
||||||
|
AND T1.parent_id IS NULL
|
||||||
|
AND T1.encounter_id = %s)
|
||||||
|
ORDER BY status_enum
|
||||||
|
""",
|
||||||
|
(
|
||||||
|
practitioner_id,
|
||||||
|
encounter_id,
|
||||||
|
practitioner_id,
|
||||||
|
encounter_id,
|
||||||
|
practitioner_id,
|
||||||
|
encounter_id,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
print(f"查询到 {len(rows)} 条记录")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 模拟前端处理
|
||||||
|
error_count = 0
|
||||||
|
success_count = 0
|
||||||
|
|
||||||
|
for i, row in enumerate(rows):
|
||||||
|
request_id = row[1]
|
||||||
|
unique_key = row[2]
|
||||||
|
advice_name = row[10]
|
||||||
|
content_json = row[6]
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 模拟前端:JSON.parse(item.contentJson)
|
||||||
|
if content_json is None or content_json == "":
|
||||||
|
parsed_content = {}
|
||||||
|
else:
|
||||||
|
parsed_content = (
|
||||||
|
json.loads(content_json)
|
||||||
|
if isinstance(content_json, str)
|
||||||
|
else content_json
|
||||||
|
)
|
||||||
|
|
||||||
|
success_count += 1
|
||||||
|
|
||||||
|
# 检查手术医嘱
|
||||||
|
if unique_key.endswith("-3") and advice_name:
|
||||||
|
print(f"✓ 第{i + 1}条: advice_type=3 (ServiceRequest)")
|
||||||
|
print(f" request_id: {request_id}")
|
||||||
|
print(f" advice_name: {advice_name}")
|
||||||
|
print(f" content_json解析成功")
|
||||||
|
print()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
error_count += 1
|
||||||
|
print(f"✗ 第{i + 1}条报错: {e}")
|
||||||
|
print(f" request_id: {request_id}")
|
||||||
|
print(f" content_json: {content_json}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
print(f"成功: {success_count}, 失败: {error_count}")
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
106
scripts/test_sql.py
Normal file
106
scripts/test_sql.py
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
import psycopg2
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.stdout.reconfigure(encoding="utf-8")
|
||||||
|
|
||||||
|
conn = psycopg2.connect(
|
||||||
|
host="192.168.110.252",
|
||||||
|
port=15432,
|
||||||
|
database="postgresql",
|
||||||
|
user="postgresql",
|
||||||
|
password="Jchl1528",
|
||||||
|
)
|
||||||
|
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("SET search_path TO hisdev, public")
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
print("使用实际部署的SQL查询数据")
|
||||||
|
print("=" * 80)
|
||||||
|
print()
|
||||||
|
|
||||||
|
practitioner_id = 1980296166230962178
|
||||||
|
encounter_id = 2038823905749327873
|
||||||
|
|
||||||
|
# 只查询第三部分(ServiceRequest)使用COALESCE
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
SELECT
|
||||||
|
3 AS advice_type,
|
||||||
|
T1.id AS request_id,
|
||||||
|
T1.id || '-3' AS unique_key,
|
||||||
|
T1.requester_id AS requester_id,
|
||||||
|
T1.create_time AS request_time,
|
||||||
|
CASE WHEN T1.requester_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
|
||||||
|
T1.content_json AS content_json,
|
||||||
|
null AS skin_test_flag,
|
||||||
|
null AS inject_flag,
|
||||||
|
null AS group_id,
|
||||||
|
COALESCE(T2.NAME, T1.content_json::jsonb->>'surgeryName') AS advice_name,
|
||||||
|
'' AS volume,
|
||||||
|
'' AS lot_number,
|
||||||
|
T1.quantity AS quantity,
|
||||||
|
T1.unit_code AS unit_code,
|
||||||
|
T1.status_enum AS status_enum,
|
||||||
|
'' AS method_code,
|
||||||
|
'' AS rate_code,
|
||||||
|
NULL AS dose,
|
||||||
|
'' AS dose_unit_code,
|
||||||
|
T3.id AS charge_item_id,
|
||||||
|
T3.total_price AS total_price,
|
||||||
|
T3.status_enum AS charge_status,
|
||||||
|
ao.id AS position_id,
|
||||||
|
ao.name AS position_name,
|
||||||
|
null AS dispense_per_duration,
|
||||||
|
1 AS part_percent,
|
||||||
|
'' AS condition_definition_name,
|
||||||
|
COALESCE(T1.therapy_enum, 2) AS therapyEnum,
|
||||||
|
99 AS sort_number,
|
||||||
|
T1.based_on_id AS based_on_id
|
||||||
|
FROM wor_service_request AS T1
|
||||||
|
LEFT JOIN wor_activity_definition AS T2
|
||||||
|
ON T2.ID = T1.activity_id
|
||||||
|
AND T2.delete_flag = '0'
|
||||||
|
LEFT JOIN adm_charge_item AS T3 ON T3.service_id = T1.ID AND T3.delete_flag = '0' AND
|
||||||
|
T3.service_table = 'wor_service_request'
|
||||||
|
LEFT JOIN adm_organization AS ao ON ao.ID = T1.org_id AND ao.delete_flag = '0'
|
||||||
|
WHERE T1.delete_flag = '0' AND T1.generate_source_enum = 1
|
||||||
|
AND T1.parent_id IS NULL
|
||||||
|
AND T1.encounter_id = %s
|
||||||
|
ORDER BY T1.status_enum
|
||||||
|
""",
|
||||||
|
(practitioner_id, encounter_id),
|
||||||
|
)
|
||||||
|
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
print(f"查询到 {len(rows)} 条 ServiceRequest 记录")
|
||||||
|
print()
|
||||||
|
|
||||||
|
for row in rows:
|
||||||
|
advice_name = row[10]
|
||||||
|
therapy_enum = row[25]
|
||||||
|
status = row[14]
|
||||||
|
content_json = row[6]
|
||||||
|
|
||||||
|
print(f"advice_name: {advice_name}")
|
||||||
|
print(f"therapyEnum: {therapy_enum} (类型: {type(therapy_enum)})")
|
||||||
|
print(f"status_enum: {status}")
|
||||||
|
print(f"content_json: {content_json[:80] if content_json else 'None'}...")
|
||||||
|
print("-" * 80)
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("结论:")
|
||||||
|
if len(rows) > 0 and rows[0][10] and rows[0][25] is not None:
|
||||||
|
print("✓ SQL查询正常,数据完整")
|
||||||
|
print(" - advice_name 已正确返回")
|
||||||
|
print(" - therapyEnum 已正确返回")
|
||||||
|
print()
|
||||||
|
print("如果前端仍不显示,请检查:")
|
||||||
|
print(" 1. 浏览器控制台的网络请求返回值")
|
||||||
|
print(" 2. 前端代码是否正确处理了数据")
|
||||||
|
else:
|
||||||
|
print("✗ SQL查询有问题")
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
115
scripts/verify_fix.py
Normal file
115
scripts/verify_fix.py
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
import psycopg2
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.stdout.reconfigure(encoding="utf-8")
|
||||||
|
|
||||||
|
conn = psycopg2.connect(
|
||||||
|
host="192.168.110.252",
|
||||||
|
port=15432,
|
||||||
|
database="postgresql",
|
||||||
|
user="postgresql",
|
||||||
|
password="Jchl1528",
|
||||||
|
)
|
||||||
|
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("SET search_path TO hisdev, public")
|
||||||
|
|
||||||
|
print("=" * 80)
|
||||||
|
print("验证修复后的数据(模拟新SQL查询)")
|
||||||
|
print("=" * 80)
|
||||||
|
print()
|
||||||
|
|
||||||
|
encounter_id = 2038823905749327873
|
||||||
|
practitioner_id = 1980296166230962178
|
||||||
|
|
||||||
|
# 使用修改后的SQL逻辑
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
SELECT
|
||||||
|
3 AS advice_type,
|
||||||
|
T1.id AS request_id,
|
||||||
|
T1.id || '-3' AS unique_key,
|
||||||
|
T1.requester_id AS requester_id,
|
||||||
|
T1.create_time AS request_time,
|
||||||
|
CASE WHEN T1.requester_id = %s THEN '1' ELSE '0' END AS biz_request_flag,
|
||||||
|
T1.content_json AS content_json,
|
||||||
|
null AS skin_test_flag,
|
||||||
|
null AS inject_flag,
|
||||||
|
null AS group_id,
|
||||||
|
COALESCE(T2.NAME, T1.content_json::jsonb->>'surgeryName') AS advice_name,
|
||||||
|
'' AS volume,
|
||||||
|
'' AS lot_number,
|
||||||
|
T1.quantity AS quantity,
|
||||||
|
T1.unit_code AS unit_code,
|
||||||
|
T1.status_enum AS status_enum,
|
||||||
|
'' AS method_code,
|
||||||
|
'' AS rate_code,
|
||||||
|
NULL AS dose,
|
||||||
|
'' AS dose_unit_code,
|
||||||
|
T3.id AS charge_item_id,
|
||||||
|
T3.total_price AS total_price,
|
||||||
|
T3.status_enum AS charge_status,
|
||||||
|
ao.id AS position_id,
|
||||||
|
ao.name AS position_name,
|
||||||
|
null AS dispense_per_duration,
|
||||||
|
1 AS part_percent,
|
||||||
|
'' AS condition_definition_name,
|
||||||
|
T1.therapy_enum AS therapyEnum,
|
||||||
|
99 AS sort_number,
|
||||||
|
T1.based_on_id AS based_on_id
|
||||||
|
FROM wor_service_request AS T1
|
||||||
|
LEFT JOIN wor_activity_definition AS T2
|
||||||
|
ON T2.ID = T1.activity_id
|
||||||
|
AND T2.delete_flag = '0'
|
||||||
|
LEFT JOIN adm_charge_item AS T3 ON T3.service_id = T1.ID AND T3.delete_flag = '0' AND
|
||||||
|
T3.service_table = 'wor_service_request'
|
||||||
|
LEFT JOIN adm_organization AS ao ON ao.ID = T1.org_id AND ao.delete_flag = '0'
|
||||||
|
WHERE T1.delete_flag = '0' AND T1.generate_source_enum = 1
|
||||||
|
AND T1.parent_id IS NULL
|
||||||
|
AND T1.encounter_id = %s
|
||||||
|
ORDER BY T1.status_enum
|
||||||
|
""",
|
||||||
|
(practitioner_id, encounter_id),
|
||||||
|
)
|
||||||
|
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
print(f"查询到 {len(rows)} 条记录:")
|
||||||
|
print()
|
||||||
|
|
||||||
|
for row in rows:
|
||||||
|
print(f"advice_type: {row[0]}")
|
||||||
|
print(f"request_id: {row[1]}")
|
||||||
|
print(f"unique_key: {row[2]}")
|
||||||
|
print(f"advice_name: {row[10]} ← 关键字段") # advice_name是第11个字段(索引10)
|
||||||
|
print(f"content_json: {row[6][:80] if row[6] else None}...")
|
||||||
|
print(f"status_enum: {row[14]}")
|
||||||
|
print(f"therapyEnum: {row[25]}")
|
||||||
|
print("-" * 80)
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 检查手术医嘱
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
prescription_no,
|
||||||
|
COALESCE(
|
||||||
|
(SELECT name FROM wor_activity_definition WHERE id = sr.activity_id AND delete_flag = '0'),
|
||||||
|
sr.content_json::jsonb->>'surgeryName'
|
||||||
|
) as advice_name,
|
||||||
|
status_enum,
|
||||||
|
content_json::jsonb->>'surgeryName' as surgery_name
|
||||||
|
FROM wor_service_request sr
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
AND encounter_id = %s
|
||||||
|
""",
|
||||||
|
(encounter_id,),
|
||||||
|
)
|
||||||
|
|
||||||
|
print("直接查询手术医嘱:")
|
||||||
|
for row in cursor.fetchall():
|
||||||
|
print(f" ID: {row[0]}, 单号: {row[1]}, advice_name: {row[2]}, 状态: {row[3]}")
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
19
scripts/手动编译步骤.bat
Normal file
19
scripts/手动编译步骤.bat
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
@echo off
|
||||||
|
echo ============================================
|
||||||
|
echo 手动编译 OpenHIS 后端
|
||||||
|
echo ============================================
|
||||||
|
echo.
|
||||||
|
echo 请在命令行中依次执行以下命令:
|
||||||
|
echo.
|
||||||
|
echo 1. 进入项目目录
|
||||||
|
echo cd /d D:\his\openhis-server-new
|
||||||
|
echo.
|
||||||
|
echo 2. 清理并编译
|
||||||
|
echo mvn clean package -DskipTests
|
||||||
|
echo.
|
||||||
|
echo 3. 等待编译完成(约5-10分钟)
|
||||||
|
echo.
|
||||||
|
echo 4. 重启后端服务
|
||||||
|
echo.
|
||||||
|
echo ============================================
|
||||||
|
pause
|
||||||
45
sql/fix_apply_dept_name_null.sql
Normal file
45
sql/fix_apply_dept_name_null.sql
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
-- 修复手术安排中申请科室名称为空的数据
|
||||||
|
-- 执行时间:2026-03-31
|
||||||
|
-- 说明:填充 cli_surgery 表中 apply_dept_name 为空的记录
|
||||||
|
|
||||||
|
-- 1. 查看当前申请科室名称的填充情况
|
||||||
|
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 null_count
|
||||||
|
FROM public.cli_surgery
|
||||||
|
WHERE delete_flag = '0';
|
||||||
|
|
||||||
|
-- 2. 修复申请科室名称(关联 adm_organization 表)
|
||||||
|
UPDATE public.cli_surgery s
|
||||||
|
SET apply_dept_name = o.name
|
||||||
|
FROM public.adm_organization o
|
||||||
|
WHERE s.apply_dept_id = o.id
|
||||||
|
AND s.apply_dept_name IS NULL
|
||||||
|
AND s.delete_flag = '0';
|
||||||
|
|
||||||
|
-- 3. 对于 apply_dept_id 为空的记录,尝试从其他来源获取
|
||||||
|
-- 例如从就诊记录中查找科室信息
|
||||||
|
UPDATE public.cli_surgery s
|
||||||
|
SET apply_dept_name = d.dept_name
|
||||||
|
FROM public.adm_encounter e
|
||||||
|
JOIN public.adm_department d ON e.dept_id = d.id
|
||||||
|
WHERE s.encounter_id = e.id
|
||||||
|
AND s.apply_dept_name IS NULL
|
||||||
|
AND s.apply_dept_id IS NULL
|
||||||
|
AND s.delete_flag = '0';
|
||||||
|
|
||||||
|
-- 4. 再次查询,验证修复结果
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
surgery_no,
|
||||||
|
patient_name,
|
||||||
|
apply_dept_id,
|
||||||
|
apply_dept_name,
|
||||||
|
create_time
|
||||||
|
FROM public.cli_surgery
|
||||||
|
WHERE delete_flag = '0'
|
||||||
|
AND (apply_dept_name IS NULL OR apply_dept_name = '')
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
LIMIT 20;
|
||||||
48
sql/fix_remaining_surgery.sql
Normal file
48
sql/fix_remaining_surgery.sql
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
-- ============================================
|
||||||
|
-- 修复遗漏的手术医嘱数据
|
||||||
|
-- ============================================
|
||||||
|
|
||||||
|
-- 查看需要修复的记录
|
||||||
|
SELECT
|
||||||
|
wsr.id,
|
||||||
|
wsr.activity_id,
|
||||||
|
cs.surgery_name,
|
||||||
|
cs.surgery_code,
|
||||||
|
wsr.create_time
|
||||||
|
FROM wor_service_request wsr
|
||||||
|
LEFT JOIN cli_surgery cs ON cs.id = wsr.activity_id
|
||||||
|
WHERE wsr.category_enum = 4
|
||||||
|
AND wsr.delete_flag = '0'
|
||||||
|
AND (wsr.content_json::jsonb->>'surgeryName' IS NULL OR wsr.content_json::jsonb->>'surgeryName' = '')
|
||||||
|
AND cs.surgery_name IS NOT NULL
|
||||||
|
ORDER BY wsr.create_time DESC;
|
||||||
|
|
||||||
|
-- 执行修复
|
||||||
|
UPDATE wor_service_request wsr
|
||||||
|
SET content_json =
|
||||||
|
COALESCE(
|
||||||
|
(wsr.content_json::jsonb || jsonb_build_object(
|
||||||
|
'surgeryName', cs.surgery_name,
|
||||||
|
'surgeryCode', COALESCE(cs.surgery_code, '')
|
||||||
|
))::text,
|
||||||
|
jsonb_build_object(
|
||||||
|
'surgeryName', cs.surgery_name,
|
||||||
|
'surgeryCode', COALESCE(cs.surgery_code, '')
|
||||||
|
)::text
|
||||||
|
)
|
||||||
|
FROM cli_surgery cs
|
||||||
|
WHERE wsr.category_enum = 4
|
||||||
|
AND wsr.delete_flag = '0'
|
||||||
|
AND (wsr.content_json::jsonb->>'surgeryName' IS NULL OR wsr.content_json::jsonb->>'surgeryName' = '')
|
||||||
|
AND cs.id = wsr.activity_id
|
||||||
|
AND cs.surgery_name IS NOT NULL
|
||||||
|
AND cs.delete_flag = '0';
|
||||||
|
|
||||||
|
-- 验证修复结果
|
||||||
|
SELECT
|
||||||
|
'Remaining empty records' as status,
|
||||||
|
COUNT(*) as count
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
AND (content_json::jsonb->>'surgeryName' IS NULL OR content_json::jsonb->>'surgeryName' = '');
|
||||||
56
sql/fix_surgery_missing_names.sql
Normal file
56
sql/fix_surgery_missing_names.sql
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
-- 修复手术申请表中申请科室和主刀医生姓名为空的问题
|
||||||
|
-- 执行时间:2026-03-31
|
||||||
|
-- 说明:填充 cli_surgery 表中 apply_dept_name 和 main_surgeon_name 为空的记录
|
||||||
|
|
||||||
|
-- 1. 查看当前字段的填充情况
|
||||||
|
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 public.cli_surgery
|
||||||
|
WHERE delete_flag = '0';
|
||||||
|
|
||||||
|
-- 2. 修复申请科室名称(根据 apply_dept_id 关联 adm_organization 表)
|
||||||
|
UPDATE public.cli_surgery s
|
||||||
|
SET apply_dept_name = o.name
|
||||||
|
FROM public.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';
|
||||||
|
|
||||||
|
-- 3. 修复主刀医生姓名(根据 main_surgeon_id 关联 sys_user 表)
|
||||||
|
UPDATE public.cli_surgery s
|
||||||
|
SET main_surgeon_name = u.nick_name
|
||||||
|
FROM public.sys_user u
|
||||||
|
WHERE s.main_surgeon_id = u.user_id
|
||||||
|
AND (s.main_surgeon_name IS NULL OR s.main_surgeon_name = '')
|
||||||
|
AND s.delete_flag = '0';
|
||||||
|
|
||||||
|
-- 4. 对于 apply_dept_id 为空但有 org_id 的记录,使用 org_name 作为申请科室
|
||||||
|
UPDATE public.cli_surgery s
|
||||||
|
SET apply_dept_name = o.name,
|
||||||
|
apply_dept_id = s.org_id
|
||||||
|
FROM public.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';
|
||||||
|
|
||||||
|
-- 5. 验证修复结果 - 查看仍有空值的记录
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
surgery_no,
|
||||||
|
patient_name,
|
||||||
|
apply_dept_id,
|
||||||
|
apply_dept_name,
|
||||||
|
main_surgeon_id,
|
||||||
|
main_surgeon_name,
|
||||||
|
create_time
|
||||||
|
FROM public.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 20;
|
||||||
90
sql/修复历史手术医嘱数据.sql
Normal file
90
sql/修复历史手术医嘱数据.sql
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
-- ============================================
|
||||||
|
-- Bug #318 历史手术医嘱数据修复脚本
|
||||||
|
-- 修复 content_json 中缺失的 surgeryName
|
||||||
|
-- ============================================
|
||||||
|
|
||||||
|
-- 1. 查看需要修复的数据
|
||||||
|
SELECT
|
||||||
|
'Before Fix - Count' as status,
|
||||||
|
COUNT(*) as total_count
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
AND (content_json::jsonb->>'surgeryName' IS NULL OR content_json::jsonb->>'surgeryName' = '');
|
||||||
|
|
||||||
|
-- 2. 查看需要修复的详细记录
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
activity_id,
|
||||||
|
content_json::jsonb->>'surgeryName' as current_surgery_name,
|
||||||
|
content_json as full_content_json,
|
||||||
|
create_time
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
AND (content_json::jsonb->>'surgeryName' IS NULL OR content_json::jsonb->>'surgeryName' = '')
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
LIMIT 10;
|
||||||
|
|
||||||
|
-- 3. 【执行修复】从 cli_surgery 表获取手术名称并更新
|
||||||
|
-- 注意:此操作会修改历史数据,请先备份
|
||||||
|
UPDATE wor_service_request wsr
|
||||||
|
SET content_json =
|
||||||
|
CASE
|
||||||
|
WHEN wsr.content_json IS NULL OR wsr.content_json = '' THEN
|
||||||
|
jsonb_build_object(
|
||||||
|
'surgeryName', cs.surgery_name,
|
||||||
|
'surgeryCode', cs.surgery_code
|
||||||
|
)::text
|
||||||
|
ELSE
|
||||||
|
(wsr.content_json::jsonb || jsonb_build_object(
|
||||||
|
'surgeryName', cs.surgery_name,
|
||||||
|
'surgeryCode', cs.surgery_code
|
||||||
|
))::text
|
||||||
|
END
|
||||||
|
FROM cli_surgery cs
|
||||||
|
WHERE wsr.category_enum = 4
|
||||||
|
AND wsr.delete_flag = '0'
|
||||||
|
AND (wsr.content_json::jsonb->>'surgeryName' IS NULL OR wsr.content_json::jsonb->>'surgeryName' = '')
|
||||||
|
AND cs.id = wsr.activity_id;
|
||||||
|
|
||||||
|
-- 4. 【备选修复】如果没有关联的 cli_surgery 记录,尝试从 activity_id 获取名称
|
||||||
|
UPDATE wor_service_request wsr
|
||||||
|
SET content_json =
|
||||||
|
CASE
|
||||||
|
WHEN wsr.content_json IS NULL OR wsr.content_json = '' THEN
|
||||||
|
jsonb_build_object(
|
||||||
|
'surgeryName', '手术项目-' || wsr.activity_id,
|
||||||
|
'surgeryCode', ''
|
||||||
|
)::text
|
||||||
|
ELSE
|
||||||
|
(wsr.content_json::jsonb || jsonb_build_object(
|
||||||
|
'surgeryName', '手术项目-' || wsr.activity_id,
|
||||||
|
'surgeryCode', ''
|
||||||
|
))::text
|
||||||
|
END
|
||||||
|
WHERE wsr.category_enum = 4
|
||||||
|
AND wsr.delete_flag = '0'
|
||||||
|
AND (wsr.content_json::jsonb->>'surgeryName' IS NULL OR wsr.content_json::jsonb->>'surgeryName' = '')
|
||||||
|
AND wsr.activity_id IS NOT NULL;
|
||||||
|
|
||||||
|
-- 5. 查看修复后的结果
|
||||||
|
SELECT
|
||||||
|
'After Fix - Count' as status,
|
||||||
|
COUNT(*) as remaining_count
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
AND (content_json::jsonb->>'surgeryName' IS NULL OR content_json::jsonb->>'surgeryName' = '');
|
||||||
|
|
||||||
|
-- 6. 验证修复成功
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
content_json::jsonb->>'surgeryName' as surgery_name,
|
||||||
|
content_json::jsonb->>'surgeryCode' as surgery_code,
|
||||||
|
create_time
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
LIMIT 5;
|
||||||
84
sql/修复历史手术医嘱数据_执行.sql
Normal file
84
sql/修复历史手术医嘱数据_执行.sql
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
-- ============================================
|
||||||
|
-- Bug #318 历史手术医嘱数据修复(执行版本)
|
||||||
|
-- ============================================
|
||||||
|
|
||||||
|
-- 步骤1:先查看有多少条记录需要修复
|
||||||
|
SELECT
|
||||||
|
'需要修复的记录数' as description,
|
||||||
|
COUNT(*) as count
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
AND (content_json::jsonb->>'surgeryName' IS NULL OR content_json::jsonb->>'surgeryName' = '');
|
||||||
|
|
||||||
|
-- 步骤2:【执行此语句进行修复】
|
||||||
|
-- 从 cli_surgery 表关联获取手术名称
|
||||||
|
UPDATE wor_service_request wsr
|
||||||
|
SET content_json = COALESCE(
|
||||||
|
(wsr.content_json::jsonb || jsonb_build_object(
|
||||||
|
'surgeryName', cs.surgery_name,
|
||||||
|
'surgeryCode', cs.surgery_code
|
||||||
|
))::text,
|
||||||
|
jsonb_build_object(
|
||||||
|
'surgeryName', COALESCE(cs.surgery_name, '手术项目'),
|
||||||
|
'surgeryCode', COALESCE(cs.surgery_code, '')
|
||||||
|
)::text
|
||||||
|
)
|
||||||
|
FROM cli_surgery cs
|
||||||
|
WHERE wsr.category_enum = 4
|
||||||
|
AND wsr.delete_flag = '0'
|
||||||
|
AND (wsr.content_json::jsonb->>'surgeryName' IS NULL OR wsr.content_json::jsonb->>'surgeryName' = '')
|
||||||
|
AND cs.id = wsr.activity_id
|
||||||
|
AND cs.delete_flag = '0';
|
||||||
|
|
||||||
|
-- 步骤3:【备选修复】对于没有关联 cli_surgery 的记录,使用默认值
|
||||||
|
UPDATE wor_service_request
|
||||||
|
SET content_json = COALESCE(
|
||||||
|
(content_json::jsonb || jsonb_build_object(
|
||||||
|
'surgeryName', '手术项目',
|
||||||
|
'surgeryCode', ''
|
||||||
|
))::text,
|
||||||
|
jsonb_build_object(
|
||||||
|
'surgeryName', '手术项目',
|
||||||
|
'surgeryCode', ''
|
||||||
|
)::text
|
||||||
|
)
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
AND (content_json::jsonb->>'surgeryName' IS NULL OR content_json::jsonb->>'surgeryName' = '');
|
||||||
|
|
||||||
|
-- 步骤4:验证修复结果
|
||||||
|
SELECT
|
||||||
|
'修复后剩余空记录数' as description,
|
||||||
|
COUNT(*) as count
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
AND (content_json::jsonb->>'surgeryName' IS NULL OR content_json::jsonb->>'surgeryName' = '');
|
||||||
|
|
||||||
|
-- 步骤5:查看修复后的示例数据
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
activity_id,
|
||||||
|
content_json::jsonb->>'surgeryName' as surgery_name,
|
||||||
|
content_json::jsonb->>'surgeryCode' as surgery_code,
|
||||||
|
create_time
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
LIMIT 5;
|
||||||
|
|
||||||
|
|
||||||
|
-- 查看今天新插入的手术医嘱
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
content_json::jsonb->>'surgeryName' as surgery_name,
|
||||||
|
content_json::jsonb->>'surgeryCode' as surgery_code,
|
||||||
|
create_time
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
AND create_time >= CURRENT_DATE
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
LIMIT 3;
|
||||||
44
sql/迁移记录-DB变更记录/20260401_update_surgery_advice_type.sql
Normal file
44
sql/迁移记录-DB变更记录/20260401_update_surgery_advice_type.sql
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
-- ============================================
|
||||||
|
-- Bug #318 数据迁移脚本
|
||||||
|
-- 更新历史手术医嘱的 advice_type 从 4 改为 6
|
||||||
|
-- 避免与耗材类型冲突
|
||||||
|
-- ============================================
|
||||||
|
|
||||||
|
-- 1. 查看当前手术医嘱数据(category_enum=4)
|
||||||
|
SELECT
|
||||||
|
'更新前统计' as step,
|
||||||
|
COUNT(*) as total_count,
|
||||||
|
COUNT(CASE WHEN category_enum = 4 THEN 1 END) as surgery_count
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE delete_flag = '0'
|
||||||
|
AND generate_source_enum = 1;
|
||||||
|
|
||||||
|
-- 2. 查看手术医嘱详情(用于验证)
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
bus_no,
|
||||||
|
category_enum,
|
||||||
|
content_json::jsonb->>'surgeryName' as surgery_name,
|
||||||
|
create_time
|
||||||
|
FROM wor_service_request
|
||||||
|
WHERE category_enum = 4
|
||||||
|
AND delete_flag = '0'
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
LIMIT 10;
|
||||||
|
|
||||||
|
-- 3. 【执行更新】将手术医嘱的 category_enum 从 4 改为 6
|
||||||
|
-- 注意:此操作不可逆,请先备份数据
|
||||||
|
-- UPDATE wor_service_request
|
||||||
|
-- SET category_enum = 6
|
||||||
|
-- WHERE category_enum = 4
|
||||||
|
-- AND delete_flag = '0';
|
||||||
|
|
||||||
|
-- 4. 验证更新结果
|
||||||
|
-- SELECT
|
||||||
|
-- '更新后统计' as step,
|
||||||
|
-- COUNT(*) as total_count,
|
||||||
|
-- COUNT(CASE WHEN category_enum = 4 THEN 1 END) as category_4_count,
|
||||||
|
-- COUNT(CASE WHEN category_enum = 6 THEN 1 END) as category_6_count
|
||||||
|
-- FROM wor_service_request
|
||||||
|
-- WHERE delete_flag = '0'
|
||||||
|
-- AND generate_source_enum = 1;
|
||||||
252
surgery_charge_issue_analysis.md
Normal file
252
surgery_charge_issue_analysis.md
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
# 门诊医生站手术申请未生成预收费明细记录问题深度分析报告
|
||||||
|
|
||||||
|
## 一、问题概述
|
||||||
|
|
||||||
|
门诊医生站手术申请保存后,门诊收费系统无法查询到对应的预收费明细记录。
|
||||||
|
|
||||||
|
## 二、已做的修复
|
||||||
|
|
||||||
|
已将 `SurgeryAppServiceImpl.java` 中的 `ChargeItem` 状态从 `DRAFT` 改为 `PLANNED`:
|
||||||
|
```java
|
||||||
|
// 第350行
|
||||||
|
chargeItem.setStatusEnum(ChargeItemStatus.PLANNED.getValue()); // 收费状态:待收费
|
||||||
|
```
|
||||||
|
|
||||||
|
## 三、深入分析发现的问题
|
||||||
|
|
||||||
|
### 3.1 前端提交数据检查
|
||||||
|
|
||||||
|
**文件**: `openhis-ui-vue3/src/views/doctorstation/components/surgery/surgeryApplication.vue`
|
||||||
|
|
||||||
|
前端表单包含费用字段:
|
||||||
|
- `surgeryFee` - 手术费用(第419行)
|
||||||
|
- `anesthesiaFee` - 麻醉费用(第426行)
|
||||||
|
- `totalFee` - 总费用(通过计算属性 `totalCalculatedFee` 自动计算并同步到表单,第564-583行)
|
||||||
|
|
||||||
|
提交时调用 API:
|
||||||
|
- 新增:`addSurgery(form.value)`(第1050行)
|
||||||
|
- 修改:`updateSurgery(form.value)`(第1066行)
|
||||||
|
|
||||||
|
**结论**: 前端正确传递了费用字段,问题不在前端。
|
||||||
|
|
||||||
|
### 3.2 后端收费生成逻辑分析
|
||||||
|
|
||||||
|
**文件**: `openhis-server-new/openhis-application/src/main/java/com/openhis/web/clinicalmanage/appservice/impl/SurgeryAppServiceImpl.java`
|
||||||
|
|
||||||
|
手术申请生成 ChargeItem 的代码(第348-369行):
|
||||||
|
|
||||||
|
```java
|
||||||
|
ChargeItem chargeItem = new ChargeItem();
|
||||||
|
chargeItem.setStatusEnum(ChargeItemStatus.PLANNED.getValue()); // 收费状态:待收费
|
||||||
|
chargeItem.setBusNo("CI" + serviceRequest.getBusNo());
|
||||||
|
chargeItem.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue());
|
||||||
|
chargeItem.setPatientId(surgeryDto.getPatientId());
|
||||||
|
chargeItem.setContextEnum(3); // 类型:3-诊疗
|
||||||
|
chargeItem.setEncounterId(surgeryDto.getEncounterId());
|
||||||
|
chargeItem.setAccountId(accountId);
|
||||||
|
chargeItem.setDefinitionId(surgeryId);
|
||||||
|
chargeItem.setEntererId(practitionerId);
|
||||||
|
chargeItem.setEnteredDate(curDate);
|
||||||
|
chargeItem.setServiceTable(CommonConstants.TableName.WOR_SERVICE_REQUEST);
|
||||||
|
chargeItem.setServiceId(serviceRequest.getId());
|
||||||
|
chargeItem.setProductTable("cli_surgery"); // 【问题1】产品表是手术表
|
||||||
|
chargeItem.setProductId(surgeryId); // 【问题2】产品ID是手术ID
|
||||||
|
chargeItem.setRequestingOrgId(orgId);
|
||||||
|
chargeItem.setQuantityValue(BigDecimal.valueOf(1));
|
||||||
|
chargeItem.setQuantityUnit("次");
|
||||||
|
chargeItem.setUnitPrice(surgeryDto.getSurgeryFee() != null ? surgeryDto.getSurgeryFee() : new BigDecimal("0.0"));
|
||||||
|
chargeItem.setTotalPrice(surgeryDto.getTotalFee() != null ? surgeryDto.getTotalFee() : new BigDecimal("0.0"));
|
||||||
|
chargeItemService.save(chargeItem);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 门诊收费查询逻辑分析
|
||||||
|
|
||||||
|
**文件**: `openhis-server-new/openhis-application/src/main/resources/mapper/chargemanage/OutpatientChargeAppMapper.xml`
|
||||||
|
|
||||||
|
关键 SQL 查询(第67-148行):
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT T1.encounter_id, T1.id, T1.patient_id, T1.context_enum, T1.status_enum, ...
|
||||||
|
CASE
|
||||||
|
WHEN T1.context_enum = #{activity} THEN T2."name"
|
||||||
|
WHEN T1.context_enum = #{medication} THEN T3."name"
|
||||||
|
WHEN T1.context_enum = #{device} THEN T4."name"
|
||||||
|
END AS item_name,
|
||||||
|
FROM adm_charge_item AS T1
|
||||||
|
LEFT JOIN wor_activity_definition AS T2
|
||||||
|
ON T1.context_enum = #{activity}
|
||||||
|
AND T1.product_id = T2.id
|
||||||
|
LEFT JOIN med_medication_definition AS T3
|
||||||
|
ON T1.context_enum = #{medication}
|
||||||
|
AND T1.product_id = T3.id
|
||||||
|
LEFT JOIN adm_device_definition AS T4
|
||||||
|
ON T1.context_enum = #{device}
|
||||||
|
AND T1.product_id = T4.id
|
||||||
|
-- ... 其他条件
|
||||||
|
WHERE T1.encounter_id = #{encounterId}
|
||||||
|
AND T1.status_enum IN (#{planned}, #{billable}, #{billed}, #{refunding}, #{refunded}, #{partRefund})
|
||||||
|
AND T1.context_enum != #{register}
|
||||||
|
AND T1.delete_flag = '0'
|
||||||
|
```
|
||||||
|
|
||||||
|
**参数值**:
|
||||||
|
- `activity` = 3 (ChargeItemContext.ACTIVITY.getValue())
|
||||||
|
- `planned` = 1 (ChargeItemStatus.PLANNED.getValue())
|
||||||
|
|
||||||
|
### 3.4 核心问题定位
|
||||||
|
|
||||||
|
#### 问题1:ChargeItemContext 枚举定义
|
||||||
|
|
||||||
|
**文件**: `openhis-common/src/main/java/com/openhis/common/enums/ChargeItemContext.java`
|
||||||
|
|
||||||
|
```java
|
||||||
|
public enum ChargeItemContext implements HisEnumInterface {
|
||||||
|
MEDICATION(1, "1", "药品"),
|
||||||
|
DEVICE(2, "2", "耗材"),
|
||||||
|
ACTIVITY(3, "3", "项目"), // 诊疗项目
|
||||||
|
REGISTER(4, "4", "挂号");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 问题2:数据关联不匹配(根本原因)
|
||||||
|
|
||||||
|
手术申请生成的 ChargeItem:
|
||||||
|
| 字段 | 值 | 说明 |
|
||||||
|
|------|-----|------|
|
||||||
|
| contextEnum | 3 | ACTIVITY(项目) |
|
||||||
|
| productTable | "cli_surgery" | 手术表 |
|
||||||
|
| productId | surgeryId | 手术ID |
|
||||||
|
|
||||||
|
门诊收费 SQL 查询逻辑:
|
||||||
|
- 当 `context_enum = 3 (ACTIVITY)` 时,关联 `wor_activity_definition` 表
|
||||||
|
- SQL: `LEFT JOIN wor_activity_definition AS T2 ON T1.context_enum = #{activity} AND T1.product_id = T2.id`
|
||||||
|
|
||||||
|
**核心问题**:
|
||||||
|
1. 手术申请保存的 `product_id` 是手术ID(cli_surgery表的ID)
|
||||||
|
2. 但 SQL 查询时关联的是 `wor_activity_definition` 表
|
||||||
|
3. 手术ID在 `wor_activity_definition` 表中不存在
|
||||||
|
4. 导致 LEFT JOIN 返回 NULL,手术收费记录无法显示
|
||||||
|
|
||||||
|
### 3.5 对比其他申请类型的收费生成
|
||||||
|
|
||||||
|
#### 检查申请(ExamApplyController.java)
|
||||||
|
```java
|
||||||
|
chargeItem.setContextEnum(2); // 类型:2=耗材(不是诊疗!)
|
||||||
|
chargeItem.setProductTable(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION);
|
||||||
|
chargeItem.setProductId(0L);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 住院申请单(RequestFormManageAppServiceImpl.java)
|
||||||
|
```java
|
||||||
|
surgeryChargeItem.setContextEnum(3); // 3-诊疗
|
||||||
|
surgeryChargeItem.setProductTable(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION);
|
||||||
|
surgeryChargeItem.setProductId(activityList.get(0).getAdviceDefinitionId()); // 诊疗定义ID
|
||||||
|
```
|
||||||
|
|
||||||
|
**差异总结**:
|
||||||
|
| 申请类型 | contextEnum | productTable | productId |
|
||||||
|
|----------|-------------|--------------|-----------|
|
||||||
|
| 手术申请(门诊) | 3 (ACTIVITY) | cli_surgery | surgeryId |
|
||||||
|
| 检查申请 | 2 (DEVICE) | wor_activity_definition | 0L |
|
||||||
|
| 住院申请单 | 3 (ACTIVITY) | wor_activity_definition | adviceDefinitionId |
|
||||||
|
|
||||||
|
## 四、解决方案
|
||||||
|
|
||||||
|
### 方案1:修改手术申请的 productTable 和 productId(推荐)
|
||||||
|
|
||||||
|
修改 `SurgeryAppServiceImpl.java` 第362-363行:
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 修改前
|
||||||
|
chargeItem.setProductTable("cli_surgery");
|
||||||
|
chargeItem.setProductId(surgeryId);
|
||||||
|
|
||||||
|
// 修改后
|
||||||
|
chargeItem.setProductTable(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION);
|
||||||
|
// 需要获取手术对应的诊疗项目定义ID
|
||||||
|
chargeItem.setProductId(surgeryDefinitionId); // 从手术项目定义表中获取
|
||||||
|
```
|
||||||
|
|
||||||
|
**注意**:此方案需要手术项目与诊疗项目定义有对应关系。
|
||||||
|
|
||||||
|
### 方案2:修改门诊收费查询 SQL
|
||||||
|
|
||||||
|
修改 `OutpatientChargeAppMapper.xml`,增加对 `cli_surgery` 表的关联:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<select id="selectEncounterPatientPrescription" ...>
|
||||||
|
SELECT T1.encounter_id, ...,
|
||||||
|
CASE
|
||||||
|
WHEN T1.context_enum = #{activity} THEN T2."name"
|
||||||
|
WHEN T1.context_enum = #{medication} THEN T3."name"
|
||||||
|
WHEN T1.context_enum = #{device} THEN T4."name"
|
||||||
|
END AS item_name,
|
||||||
|
-- 增加:从手术表获取名称
|
||||||
|
T5.name AS surgery_name
|
||||||
|
FROM adm_charge_item AS T1
|
||||||
|
LEFT JOIN wor_activity_definition AS T2 ...
|
||||||
|
LEFT JOIN med_medication_definition AS T3 ...
|
||||||
|
LEFT JOIN adm_device_definition AS T4 ...
|
||||||
|
-- 增加手术表关联
|
||||||
|
LEFT JOIN cli_surgery AS T5
|
||||||
|
ON T1.product_table = 'cli_surgery'
|
||||||
|
AND T1.product_id = T5.id
|
||||||
|
WHERE ...
|
||||||
|
</select>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方案3:修改 ChargeItem 保存逻辑(临时方案)
|
||||||
|
|
||||||
|
如果手术项目暂时没有对应的诊疗项目定义,可以:
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 设置 productTable 为 wor_activity_definition,但 productId 设为 0
|
||||||
|
chargeItem.setProductTable(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION);
|
||||||
|
chargeItem.setProductId(0L);
|
||||||
|
// 在 item_name 或其他字段中保存手术名称
|
||||||
|
```
|
||||||
|
|
||||||
|
## 五、额外发现的问题
|
||||||
|
|
||||||
|
### 5.1 检查申请的 contextEnum 设置错误
|
||||||
|
|
||||||
|
在 `ExamApplyController.java` 第249行:
|
||||||
|
```java
|
||||||
|
chargeItem.setContextEnum(2); // 类型:2=诊疗
|
||||||
|
```
|
||||||
|
|
||||||
|
但实际上 `2` 对应的是 `ChargeItemContext.DEVICE`(耗材),不是诊疗。正确的应该是:
|
||||||
|
```java
|
||||||
|
chargeItem.setContextEnum(ChargeItemContext.ACTIVITY.getValue()); // 3
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 手术申请缺少处方号
|
||||||
|
|
||||||
|
对比检查申请,手术申请的 ChargeItem 没有设置 `prescriptionNo` 字段,可能导致收费查询时无法关联到处方信息。
|
||||||
|
|
||||||
|
## 六、修复建议优先级
|
||||||
|
|
||||||
|
1. **高优先级**:修改手术申请的 `productTable` 和 `productId`,使其与门诊收费 SQL 查询兼容
|
||||||
|
2. **中优先级**:增加手术申请 ChargeItem 的 `prescriptionNo` 字段设置
|
||||||
|
3. **低优先级**:修复检查申请的 `contextEnum` 设置错误
|
||||||
|
|
||||||
|
## 七、验证步骤
|
||||||
|
|
||||||
|
1. 修改代码后,重新编译部署
|
||||||
|
2. 在门诊医生站创建新的手术申请
|
||||||
|
3. 检查 `adm_charge_item` 表,确认记录已生成且字段正确
|
||||||
|
4. 在门诊收费系统查询该患者的收费明细,确认手术费用能正常显示
|
||||||
|
5. 测试收费、结算流程是否正常
|
||||||
|
|
||||||
|
## 八、相关文件清单
|
||||||
|
|
||||||
|
| 文件路径 | 说明 |
|
||||||
|
|----------|------|
|
||||||
|
| `openhis-ui-vue3/src/views/doctorstation/components/surgery/surgeryApplication.vue` | 前端手术申请组件 |
|
||||||
|
| `openhis-server-new/openhis-application/src/main/java/com/openhis/web/clinicalmanage/appservice/impl/SurgeryAppServiceImpl.java` | 手术申请服务实现 |
|
||||||
|
| `openhis-server-new/openhis-application/src/main/resources/mapper/chargemanage/OutpatientChargeAppMapper.xml` | 门诊收费查询Mapper |
|
||||||
|
| `openhis-server-new/openhis-application/src/main/java/com/openhis/web/chargemanage/appservice/impl/OutpatientChargeAppServiceImpl.java` | 门诊收费服务实现 |
|
||||||
|
| `openhis-server-new/openhis-common/src/main/java/com/openhis/common/enums/ChargeItemContext.java` | 收费项目类型枚举 |
|
||||||
|
| `openhis-server-new/openhis-domain/src/main/java/com/openhis/administration/domain/ChargeItem.java` | 收费项实体类 |
|
||||||
|
| `openhis-server-new/openhis-application/src/main/java/com/openhis/web/check/controller/ExamApplyController.java` | 检查申请控制器(对比参考) |
|
||||||
|
| `openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/appservice/impl/RequestFormManageAppServiceImpl.java` | 住院申请单服务(对比参考) |
|
||||||
71
test_fix.js
Normal file
71
test_fix.js
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
const { Pool } = require('pg');
|
||||||
|
const pool = new Pool({
|
||||||
|
host: '47.116.196.11',
|
||||||
|
port: 15432,
|
||||||
|
database: 'postgresql',
|
||||||
|
user: 'postgresql',
|
||||||
|
password: 'Jchl1528'
|
||||||
|
});
|
||||||
|
|
||||||
|
async function testFix() {
|
||||||
|
try {
|
||||||
|
console.log('=== 测试手术安排关联修复 ===\n');
|
||||||
|
|
||||||
|
// 1. 测试新的 JOIN 条件
|
||||||
|
const result = await pool.query(`
|
||||||
|
SELECT
|
||||||
|
os.schedule_id,
|
||||||
|
os.oper_code,
|
||||||
|
os.apply_id,
|
||||||
|
cs.id as surgery_id,
|
||||||
|
cs.surgery_no,
|
||||||
|
cs.apply_dept_name,
|
||||||
|
cs.main_surgeon_name,
|
||||||
|
CASE
|
||||||
|
WHEN cs.id IS NOT NULL THEN '✅ 关联成功'
|
||||||
|
ELSE '❌ 未找到关联'
|
||||||
|
END as status
|
||||||
|
FROM hisdev.op_schedule os
|
||||||
|
LEFT JOIN hisdev.cli_surgery cs
|
||||||
|
ON os.oper_code = cs.surgery_no AND cs.delete_flag = '0'
|
||||||
|
WHERE os.delete_flag = '0'
|
||||||
|
ORDER BY os.create_time DESC
|
||||||
|
LIMIT 10
|
||||||
|
`);
|
||||||
|
|
||||||
|
console.log('手术安排与手术申请关联情况(使用 oper_code = surgery_no):');
|
||||||
|
console.table(result.rows);
|
||||||
|
|
||||||
|
// 2. 统计关联成功率
|
||||||
|
const stats = await pool.query(`
|
||||||
|
SELECT
|
||||||
|
COUNT(*) as total,
|
||||||
|
COUNT(CASE WHEN cs.id IS NOT NULL THEN 1 END) as matched,
|
||||||
|
COUNT(CASE WHEN cs.id IS NULL THEN 1 END) as unmatched,
|
||||||
|
ROUND(COUNT(CASE WHEN cs.id IS NOT NULL THEN 1 END) * 100.0 / COUNT(*), 2) as match_rate
|
||||||
|
FROM hisdev.op_schedule os
|
||||||
|
LEFT JOIN hisdev.cli_surgery cs
|
||||||
|
ON os.oper_code = cs.surgery_no AND cs.delete_flag = '0'
|
||||||
|
WHERE os.delete_flag = '0'
|
||||||
|
`);
|
||||||
|
|
||||||
|
console.log('\n=== 关联统计 ===');
|
||||||
|
console.log(`总计: ${stats.rows[0].total}`);
|
||||||
|
console.log(`关联成功: ${stats.rows[0].matched}`);
|
||||||
|
console.log(`未找到关联: ${stats.rows[0].unmatched}`);
|
||||||
|
console.log(`关联成功率: ${stats.rows[0].match_rate}%`);
|
||||||
|
|
||||||
|
if (parseInt(stats.rows[0].matched) > 0) {
|
||||||
|
console.log('\n✅ 修复成功!手术安排现在能正确关联到手术申请,申请科室和主刀医生可以正常显示。');
|
||||||
|
} else {
|
||||||
|
console.log('\n⚠️ 没有关联成功的记录,请检查数据。');
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error('测试失败:', err.message);
|
||||||
|
} finally {
|
||||||
|
pool.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testFix();
|
||||||
BIN
zentao_bug_266.png
Normal file
BIN
zentao_bug_266.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 193 KiB |
BIN
zentao_bug_306.png
Normal file
BIN
zentao_bug_306.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 123 KiB |
BIN
zentao_bug_307.png
Normal file
BIN
zentao_bug_307.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 111 KiB |
BIN
zentao_bug_320.png
Normal file
BIN
zentao_bug_320.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 154 KiB |
15
zentao_bug_320_parsed.json
Normal file
15
zentao_bug_320_parsed.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"title": "",
|
||||||
|
"description": "",
|
||||||
|
"steps": "图1:门诊手术安排:手术申请查询选中手术申请记录点击【确认】\n\n图2:新增手术安排界面的就诊卡号取值错误\n\n1、如上图1、2所示:手术管理-》门诊手术安排:新增手术安排界面的就诊卡号取值错误。",
|
||||||
|
"expected": "1、如上图1、2所示:手术管理-》门诊手术安排:新增手术安排界面的就诊卡号取值于患者档案的就诊卡号字段的值,adm_patient.id = adm_patient_identifier.patient_id;adm_patient_identifier.identifier_no 字段就是就诊卡号,如下图3所示\n\n图3",
|
||||||
|
"actual": "1、手术管理-》门诊手术安排:新增手术安排界面的就诊卡号取值错误。",
|
||||||
|
"priority": "",
|
||||||
|
"status": "",
|
||||||
|
"module": "",
|
||||||
|
"assignedTo": "",
|
||||||
|
"openedBy": "",
|
||||||
|
"bugType": "",
|
||||||
|
"severity": "",
|
||||||
|
"allText": "测试\n开源HIS改造落地\n仪表盘\nBug\n用例\n套件\n测试单\n测试报告\n用例库\n自动化\n9\nA\n返回\n320\n手术管理-》门诊手术安排:新增手术安排界面的就诊卡号取值错误\n提Bug\n重现步骤\n\n[步骤]\n\n图1:门诊手术安排:手术申请查询选中手术申请记录点击【确认】\n\n图2:新增手术安排界面的就诊卡号取值错误\n\n1、如上图1、2所示:手术管理-》门诊手术安排:新增手术安排界面的就诊卡号取值错误。\n\n[结果]\n\n1、手术管理-》门诊手术安排:新增手术安排界面的就诊卡号取值错误。\n\n[期望]\n\n1、如上图1、2所示:手术管理-》门诊手术安排:新增手术安排界面的就诊卡号取值于患者档案的就诊卡号字段的值,adm_patient.id = adm_patient_identifier.patient_id;adm_patient_identifier.identifier_no 字段就是就诊卡号,如下图3所示\n\n图3\n\n历史记录\n添加备注\n1\n2026-03-31 22:53:45, 由 陈显精 创建。\n2\n2026-03-31 22:53:49, 由 陈显精 指派给 王怡哲。\n返回\n确认\n指派\n解决\n转研发需求\n转任务\n创建用例\n基本信息\nBug的一生\n所属模块\n手术麻醉管理\n所属计划\n来源用例\nBug类型\n代码错误\n严重程度\n优先级\n3\nBug状态\n激活\n激活次数\n激活时间\n是否确认\n未确认\n指派给\n王怡哲 于 2026-03-31 22:53:45\n截止日期\n反馈者\n通知邮箱\n操作系统\n浏览器\n关键词\n抄送给\n项目/迭代/研发需求/任务\n其他相关\n所属项目\n开源HIS改造落地\n所属执行\n相关需求\n相关任务"
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user