Compare commits
173 Commits
c7f85ff20d
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
| 1a67581314 | |||
| 398b6a2d5b | |||
| fb07a957ff | |||
| 8ed2590b1b | |||
| 8e1a693547 | |||
| 92ef1280b8 | |||
| 89b4f29eb7 | |||
| 0fdf09f9bc | |||
| 7119fc3b7f | |||
| 5f3cf9c4d2 | |||
| 62531c8560 | |||
| 6a107cad18 | |||
| 804f9fc219 | |||
| e9c5efceaa | |||
| a587848df6 | |||
| 546e6a3f79 | |||
| 1d316c2f14 | |||
| 86325dd79a | |||
| d0ec708646 | |||
| d6c72e435a | |||
| 4acada98e1 | |||
| 151cca357d | |||
| 881c110bb2 | |||
| 93f45d7c03 | |||
| c542e2b499 | |||
| b8ea9fd950 | |||
| a727059e64 | |||
| c8a26b55bb | |||
| d85d6f4b96 | |||
| 340c7ef4d4 | |||
| ab567f3f98 | |||
| b485b5de8e | |||
| 3fc9a36449 | |||
| c2154a29c5 | |||
| 8a66db3cd8 | |||
| 14a6234178 | |||
| 1c18ef5859 | |||
| c31991dbdd | |||
| e5bf042043 | |||
| beae756526 | |||
| acb892266c | |||
| aa8a9c5865 | |||
| 86c9e7b007 | |||
| ec1e3deb0f | |||
| 4795496a6b | |||
| e6368aa9c9 | |||
| ff1658cd42 | |||
| de3d8ad567 | |||
| 3cfa8d53e3 | |||
| 516d2ef2a6 | |||
| f05b205663 | |||
| a721060894 | |||
| 7dc54278ed | |||
| b0a91b78e5 | |||
| 5efd0b51fa | |||
| 275f8addd0 | |||
| 4b2b1b4d14 | |||
| 0e2ada26dd | |||
| 81ecfc0688 | |||
| dc3729d76a | |||
| f06950ba0f | |||
| e21cc32634 | |||
| 0db4dc726f | |||
| 2e82071cca | |||
| 7b52063dc4 | |||
| 42c86c08b8 | |||
| c66c5db187 | |||
| 93f836b2c6 | |||
| 353bec2a3c | |||
| 4e8a9ece41 | |||
| f83f48238e | |||
| 7eb4c8d30a | |||
| d5c80b20df | |||
| 825172de2a | |||
| 590df8a58b | |||
| c0fbed9169 | |||
| 017ed885d9 | |||
| e20d9fbf7d | |||
| d7a32eb8c5 | |||
| d515c47e89 | |||
| 200b4853db | |||
| 4229196574 | |||
| 4ff58b3f2e | |||
| ab3431c53d | |||
| bb20d8308e | |||
| db84f4b2bd | |||
| 0a2978bc0a | |||
| 4e9c1a9716 | |||
| 2aa8b88b3a | |||
| 1a51508e78 | |||
| cd523cced0 | |||
| 4b3663c7d7 | |||
|
|
5e594e7c25 | ||
| a18143ef41 | |||
| 4f3b1dff8f | |||
| a45b6e7955 | |||
| cec2f47a1f | |||
| a350095ced | |||
| 3f52a98a32 | |||
| d60b579dcd | |||
| d413a4cd60 | |||
| 93447b0e46 | |||
| 2921d4535a | |||
| b71354d3b6 | |||
| 57a33e0baa | |||
| 759f10d9d0 | |||
| d8e2c485a4 | |||
| 69e24ba2b4 | |||
| 81f5001601 | |||
| 96087d8dac | |||
| 9331dc7525 | |||
| 6372e3c80f | |||
| 615be87c71 | |||
| c0ab80bd4d | |||
| 772119e320 | |||
| 256791348c | |||
|
|
a08808b41d | ||
|
|
f407a2a886 | ||
| babd8d0c04 | |||
| 1f738c969a | |||
| 3f67753344 | |||
| 3e650dd041 | |||
| 773a485114 | |||
| 9675106d4b | |||
|
|
f655f06871 | ||
| 2c2dbd7542 | |||
| 8b47a8ab55 | |||
| 5ebe6c6333 | |||
| 65a52e9742 | |||
|
|
d04be6062b | ||
|
|
defab36cca | ||
| 681107ca64 | |||
| f75133369a | |||
| ca812421d2 | |||
| ae12cb2135 | |||
| d2a1cd6f29 | |||
| d9d2b83c5b | |||
| e9a8f6eedc | |||
| fd83ac9621 | |||
| 704a1105cf | |||
| 20af7351a0 | |||
| e4fe900618 | |||
| a963ad8fdc | |||
|
|
bbf4c8441b | ||
| e9d09e69c9 | |||
| e5fb8a3350 | |||
| b55fa84b85 | |||
| 5f00dab7ad | |||
| 8c42cf11b5 | |||
| ada67eb9c0 | |||
| 7b1777a91e | |||
| af6fdbf7d6 | |||
| 6c80673427 | |||
|
|
cbb3f618be | ||
| babf62083a | |||
| 68cfa48820 | |||
|
|
d47c83eec5 | ||
|
|
2915915881 | ||
| 68b92dfe31 | |||
| c9e8729d07 | |||
| 207640f4ef | |||
| 566ce61293 | |||
|
|
a04fa368b1 | ||
| f940078208 | |||
| 06363ec191 | |||
|
|
3c8d5e94a3 | ||
|
|
6f7f6dc9f5 | ||
|
|
376ddd46ff | ||
| e1ab9fba23 | |||
| f458835183 | |||
|
|
57f591e1c0 | ||
|
|
a98a03e00a | ||
| fddf1c2d03 |
18
.gitignore
vendored
18
.gitignore
vendored
@@ -416,3 +416,21 @@
|
||||
/node_modules/proxy-from-env/package.json
|
||||
/node_modules/proxy-from-env/README.md
|
||||
/node_modules/.package-lock.json
|
||||
/.idea/shelf/在进行更新之前于_2026_6_5_16_37_取消提交了更改_[更改]/shelved.patch
|
||||
/.idea/shelf/在进行更新之前于_2026_6_6_07_53_取消提交了更改_[更改]/shelved.patch
|
||||
/.idea/shelf/在进行更新之前于_2026_6_6_07_58_取消提交了更改_[更改]/shelved.patch
|
||||
/.idea/shelf/在进行更新之前于_2026_6_6_09_03_取消提交了更改_[更改]/shelved.patch
|
||||
/.idea/shelf/在进行更新之前于_2026_6_6_09_07_取消提交了更改_[更改]/shelved.patch
|
||||
/.idea/shelf/在进行更新之前于_2026_6_6_09_17_取消提交了更改_[更改]/shelved.patch
|
||||
/.idea/shelf/_2026_6_5_16_37____.xml
|
||||
/.idea/shelf/_2026_6_6_07_53____.xml
|
||||
/.idea/shelf/_2026_6_6_07_58____.xml
|
||||
/.idea/shelf/_2026_6_6_09_03____.xml
|
||||
/.idea/shelf/_2026_6_6_09_07____.xml
|
||||
/.idea/shelf/_2026_6_6_09_17____.xml
|
||||
/.idea/shelf/在进行更新之前于_2026_6_5_16_37_取消提交了更改_[更改]/shelved.patch
|
||||
/.idea/shelf/在进行更新之前于_2026_6_6_07_53_取消提交了更改_[更改]/shelved.patch
|
||||
/.idea/shelf/在进行更新之前于_2026_6_6_07_58_取消提交了更改_[更改]/shelved.patch
|
||||
/.idea/shelf/在进行更新之前于_2026_6_6_09_03_取消提交了更改_[更改]/shelved.patch
|
||||
/.idea/shelf/在进行更新之前于_2026_6_6_09_07_取消提交了更改_[更改]/shelved.patch
|
||||
/.idea/shelf/在进行更新之前于_2026_6_6_09_17_取消提交了更改_[更改]/shelved.patch
|
||||
|
||||
566
.idea/shelf/在进行更新之前于_2026_6_5_16_37_取消提交了更改_[更改]/shelved.patch
generated
Normal file
566
.idea/shelf/在进行更新之前于_2026_6_5_16_37_取消提交了更改_[更改]/shelved.patch
generated
Normal file
File diff suppressed because one or more lines are too long
566
.idea/shelf/在进行更新之前于_2026_6_6_07_53_取消提交了更改_[更改]/shelved.patch
generated
Normal file
566
.idea/shelf/在进行更新之前于_2026_6_6_07_53_取消提交了更改_[更改]/shelved.patch
generated
Normal file
File diff suppressed because one or more lines are too long
566
.idea/shelf/在进行更新之前于_2026_6_6_07_58_取消提交了更改_[更改]/shelved.patch
generated
Normal file
566
.idea/shelf/在进行更新之前于_2026_6_6_07_58_取消提交了更改_[更改]/shelved.patch
generated
Normal file
File diff suppressed because one or more lines are too long
566
.idea/shelf/在进行更新之前于_2026_6_6_09_03_取消提交了更改_[更改]/shelved.patch
generated
Normal file
566
.idea/shelf/在进行更新之前于_2026_6_6_09_03_取消提交了更改_[更改]/shelved.patch
generated
Normal file
File diff suppressed because one or more lines are too long
566
.idea/shelf/在进行更新之前于_2026_6_6_09_07_取消提交了更改_[更改]/shelved.patch
generated
Normal file
566
.idea/shelf/在进行更新之前于_2026_6_6_09_07_取消提交了更改_[更改]/shelved.patch
generated
Normal file
File diff suppressed because one or more lines are too long
566
.idea/shelf/在进行更新之前于_2026_6_6_09_17_取消提交了更改_[更改]/shelved.patch
generated
Normal file
566
.idea/shelf/在进行更新之前于_2026_6_6_09_17_取消提交了更改_[更改]/shelved.patch
generated
Normal file
File diff suppressed because one or more lines are too long
570
AGENTS.md
570
AGENTS.md
@@ -106,6 +106,576 @@
|
||||
- 每次修改后必须 `mvn clean compile -DskipTests` 验证
|
||||
- **违规判定**: 因修改导致原有代码编译失败或运行报错,视为违反铁律18,必须立即回滚修复
|
||||
|
||||
|
||||
**铁律19: 编译错误不区分来源(Bug #698 教训)**
|
||||
- `mvn compile`、`vite build`、`vue-tsc` 等构建命令报错 = 不过关,**不管是自己引入的还是历史遗留的**
|
||||
- 禁止说"这是预存问题""不是我改的""原有bug"——构建通不过就不能宣称完成
|
||||
- 正确做法:定位错误 → 修复 → 重新构建确认通过 → 然后才能继续
|
||||
- **违规判定**: 构建命令有 ERROR 但未修复就报告"编译通过",视为违反铁律
|
||||
|
||||
**铁律20: 数据来源必须验证(Bug #698 教训)**
|
||||
- 涉及数据查询/提取时,必须先确认数据实际存储位置,不能假设
|
||||
- 案例:从 `raw_steps_html` 提取 fileID,而不是从 `steps`(纯文本,已被 strip)
|
||||
- 修复前必须:打印/检查原始数据结构 → 确认字段存在 → 再写提取逻辑
|
||||
- 禁止:凭代码推断数据位置、假设"应该在这里"
|
||||
|
||||
**铁律21: 外部配置值必须实测验证(Bug #698 教训)**
|
||||
- 使用外部服务(API、模型、数据库)的配置值,必须实际调用验证,不能仅凭记忆或推测
|
||||
- 案例:模型名 `mino-v2.5` 应为 `mimo-v2.5`,拼写错误导致 400
|
||||
- 配置变更后必须:发起一次真实请求 → 确认返回 200 → 再宣称配置正确
|
||||
- 禁止:改完配置不测试、假设"应该能用"
|
||||
|
||||
**铁律22: 端到端验证必须有实际输出证据(Bug #698 教训)**
|
||||
- 声称功能生效前,必须有实际的端到端输出证据
|
||||
- 不能仅凭代码路径推断"应该走了 vision"——必须看到实际返回内容
|
||||
- 验证方式:运行命令 → 检查输出中包含预期关键词(如 vision 分析结果、图片识别文字)
|
||||
- 禁止:只检查代码路径可达就算"验证通
|
||||
**铁律23: 文件读写强制 UTF-8 编码(必遵守)**
|
||||
- **禁止**使用 Get-Content -Raw(不带 -Encoding UTF8)读取源文件
|
||||
- **禁止**使用 Out-File -Encoding utf8(会写 BOM)
|
||||
- **正确写法**:
|
||||
- 读取:[System.IO.File]::ReadAllText(, [System.Text.Encoding]::UTF8)
|
||||
- 写入:[System.IO.File]::WriteAllText(, # HealthLink-HIS — AI 开发规范
|
||||
|
||||
> 🤖 本文件由 Codex CLI、Claude Code 等工具自动读取。
|
||||
> 工具进入项目目录时会自动加载此文件作为开发规范上下文。
|
||||
|
||||
---
|
||||
|
||||
# HealthLink-HIS — AI 开发规范(自动加载)
|
||||
|
||||
> 🤖 **本文件供所有 AI 编码工具自动读取**。进入本项目后必须遵守以下规范。
|
||||
>
|
||||
> **模型决定上限,Harness 决定底线。**
|
||||
|
||||
---
|
||||
|
||||
## 一、项目概览
|
||||
|
||||
| 属性 | 值 |
|
||||
|------|------|
|
||||
| 项目名 | HealthLink-HIS(医院信息系统) |
|
||||
| 后端路径 | `healthlink-his-server/` |
|
||||
| 前端路径 | `healthlink-his-ui/` |
|
||||
| 文档路径 | `MD/` |
|
||||
| JDK | 25 (OpenJDK) |
|
||||
| Spring Boot | 4.0.6 |
|
||||
| MyBatis-Plus | 3.5.16 |
|
||||
| Vue | 3.x + Vite + Element Plus |
|
||||
| 数据库 | PostgreSQL 15+ |
|
||||
| 包名 | `com.healthlink.his` |
|
||||
| 后端端口 | 18082 |
|
||||
| 前端端口 | 81 |
|
||||
|
||||
---
|
||||
|
||||
## 二、铁律(必须遵守,违反即失败)
|
||||
|
||||
### 🔴 P0 铁律 — 不可违反
|
||||
|
||||
**铁律1: 修改完必须测试**
|
||||
```
|
||||
后端: mvn clean compile -DskipTests → mvn install -DskipTests → mvn test
|
||||
前端: npm run build:dev → npm run lint
|
||||
```
|
||||
- 白盒:编译通过,无 ERROR
|
||||
- 黑盒:关键接口返回 `{code:200, data:...}`,验证业务逻辑
|
||||
- 冒烟:应用正常启动,核心流程通畅
|
||||
|
||||
**铁律2: Flyway 数据库迁移**
|
||||
- 凡是新建表、新增字段,必须创建 Flyway 迁移脚本
|
||||
- 路径:`healthlink-his-domain/src/main/resources/db/migration/`
|
||||
- 命名:`V{版本号}__{描述}.sql`(双下划线)
|
||||
|
||||
**铁律3: 测试通过后才提交**
|
||||
- 编译 + 测试全部通过后才能 git commit
|
||||
- 不提交未完成的功能、调试代码、临时文件
|
||||
|
||||
**铁律4: 前后端API路径对齐**
|
||||
- 后端前缀:`/healthlink-his/api/v1/`
|
||||
- 前端 `request.js` 的 baseURL 必须与后端匹配
|
||||
|
||||
**铁律5: 状态值一致性(Bug #574 教训)**
|
||||
- 修改任何状态值前,必须先列出完整的状态流转链路
|
||||
- 检查项:枚举定义 → Service 设置 → 查询映射 → 前端 STATUS_CLASS_MAP → 前端 v-if → 统计SQL
|
||||
- 禁止:只改一端不检查其他端
|
||||
|
||||
**铁律6: 禁止删除源文件(Bug #574 教训)**
|
||||
- 绝对禁止删除项目中已有的 Java/Vue/SQL 源文件
|
||||
- 编译错误 → 修复错误;重复文件 → 重构合并
|
||||
- 唯一例外:明确由人类确认删除的文件
|
||||
|
||||
**铁律7: 禁止修改已有公开方法签名**
|
||||
- 不能删除/重命名已有的 public 方法,不能修改参数列表
|
||||
- 需要新功能 → 添加重载方法;需要改行为 → 修改内部实现
|
||||
|
||||
**铁律8: 验证后才宣称完成(Verification Before Completion)**
|
||||
- **没有跑过验证命令,就不能说"完成了""通过了""没问题"**
|
||||
- 禁止使用"应该可以""大概没问题""看起来正确"
|
||||
- 必须:运行命令 → 读取输出 → 确认结果 → 才能宣称
|
||||
- 这是诚实原则,不是效率问题
|
||||
|
||||
|
||||
**铁律9: 开发前必须审核原有代码(P0 — 铁律)**
|
||||
- **任何新功能开发前,必须先搜索项目中是否已有相关代码**
|
||||
- 搜索路径:Controller / AppService / Service / Mapper / Entity / 前端页面 / API接口
|
||||
- 如果已有部分功能 → 在原有代码基础上**升级优化完善**,禁止另起炉灶
|
||||
- 如果已有接口但前端缺失 → 只补前端,不重复建后端
|
||||
- 如果已有前端但后端缺失 → 只补后端,不重写前端
|
||||
- 搜索命令:`rg -l "关键词" healthlink-his-server/ healthlink-his-ui/src/`
|
||||
- 禁止:不看代码就新建模块、重复实现已有功能、废弃原有代码另写一套
|
||||
|
||||
|
||||
**铁律12: 设计文档确认后自主开发(铁律)**
|
||||
- 设计文档(如 `MD/architecture/GRADE3A_GAP_ANALYSIS_AND_DESIGN.md`)一旦确认,后续开发**必须按文档自主执行**
|
||||
- **禁止反复询问"是否继续""下一步做什么""是否开始"**——直接按计划推进
|
||||
- 每完成一个 Sprint,自动提交推送,然后立即开始下一个 Sprint
|
||||
- 只在遇到**无法解决的阻塞**(如技术选型冲突、需求不明确、第三方依赖不可用)时才暂停询问
|
||||
- 设计文档是"**已签合同**",不是"参考意见"。铁律执行优先级:设计文档 > 人类临时指令 > AI 自行判断
|
||||
|
||||
**铁律18: 禁止破坏原有功能(P0绝对铁律)**
|
||||
- **完善增加功能和流程时,绝对不能破坏或者让原有功能不能用**
|
||||
- 修改已有实体前必须对比原始文件(`git show HEAD~N:./file.java`),保留所有原有字段和方法
|
||||
- 新增字段只能追加,不能删除或重命名已有字段
|
||||
- SQL迁移只允许 `ALTER TABLE ADD COLUMN`,不允许 `DROP COLUMN` 或 `RENAME COLUMN`
|
||||
- Controller新端点不能修改已有端点的路径或参数
|
||||
- 前端新页面不能修改已有页面的组件结构
|
||||
- 每次修改后必须 `mvn clean compile -DskipTests` 验证
|
||||
- **违规判定**: 因修改导致原有代码编译失败或运行报错,视为违反铁律18,必须立即回滚修复
|
||||
|
||||
|
||||
**铁律19: 编译错误不区分来源(Bug #698 教训)**
|
||||
- `mvn compile`、`vite build`、`vue-tsc` 等构建命令报错 = 不过关,**不管是自己引入的还是历史遗留的**
|
||||
- 禁止说"这是预存问题""不是我改的""原有bug"——构建通不过就不能宣称完成
|
||||
- 正确做法:定位错误 → 修复 → 重新构建确认通过 → 然后才能继续
|
||||
- **违规判定**: 构建命令有 ERROR 但未修复就报告"编译通过",视为违反铁律
|
||||
|
||||
**铁律20: 数据来源必须验证(Bug #698 教训)**
|
||||
- 涉及数据查询/提取时,必须先确认数据实际存储位置,不能假设
|
||||
- 案例:从 `raw_steps_html` 提取 fileID,而不是从 `steps`(纯文本,已被 strip)
|
||||
- 修复前必须:打印/检查原始数据结构 → 确认字段存在 → 再写提取逻辑
|
||||
- 禁止:凭代码推断数据位置、假设"应该在这里"
|
||||
|
||||
**铁律21: 外部配置值必须实测验证(Bug #698 教训)**
|
||||
- 使用外部服务(API、模型、数据库)的配置值,必须实际调用验证,不能仅凭记忆或推测
|
||||
- 案例:模型名 `mino-v2.5` 应为 `mimo-v2.5`,拼写错误导致 400
|
||||
- 配置变更后必须:发起一次真实请求 → 确认返回 200 → 再宣称配置正确
|
||||
- 禁止:改完配置不测试、假设"应该能用"
|
||||
|
||||
**铁律22: 端到端验证必须有实际输出证据(Bug #698 教训)**
|
||||
- 声称功能生效前,必须有实际的端到端输出证据
|
||||
- 不能仅凭代码路径推断"应该走了 vision"——必须看到实际返回内容
|
||||
- 验证方式:运行命令 → 检查输出中包含预期关键词(如 vision 分析结果、图片识别文字)
|
||||
- 禁止:只检查代码路径可达就算"验证通过"
|
||||
|
||||
|
||||
### 🟡 P1 铁律 — 强烈建议
|
||||
|
||||
**铁律9: 先分解再行动**
|
||||
- 修改超过3个文件、涉及多模块、数据库变更,必须先制定计划
|
||||
|
||||
**铁律10: 验证后信**
|
||||
- 每次修改后必须验证编译通过,不信记忆
|
||||
|
||||
**铁律13: 文档统一管理**
|
||||
- 所有文档存储在 `MD/` 目录
|
||||
- 文件名:大写英文+下划线(如 `BACKEND_CHECKLIST.md`)
|
||||
- 文档头部必须包含元数据块(文档类型、版本、日期)
|
||||
|
||||
---
|
||||
|
||||
|
||||
**铁律14: 设计文档必须包含UI设计和调用流程**
|
||||
- 所有新模块/页面的设计文档必须包含:UI布局描述、交互效果清单、前后端调用流程
|
||||
- 没有明确UI设计的模块,禁止直接编码
|
||||
- 详见
|
||||
- 设计文档必须写清楚:系统调用关系、方法函数调用关系、完整业务流程
|
||||
- 设计文档中每个用户操作必须对应:前端事件 → API调用 → 后端处理链路 → 返回数据 → UI渲染
|
||||
|
||||
---
|
||||
|
||||
## 三、Karpathy 编码准则
|
||||
|
||||
> 减少 LLM 常见编码错误。偏向谨慎而非速度。
|
||||
|
||||
### 3.1 先想再写
|
||||
- 明确陈述假设,不确定就问
|
||||
- 多种解读时都列出来,不要默默选一种
|
||||
- 有更简单的方案就说出来,该推回就推回
|
||||
- 不清楚的地方停下来,说清楚哪里不清楚
|
||||
|
||||
### 3.2 简洁优先
|
||||
- 不做没要求的功能,不做一次性代码的抽象
|
||||
- 不加没要求的"灵活性"和"可配置性"
|
||||
- 200 行能 50 行搞定就重写
|
||||
- 自问:"高级工程师会不会觉得这过度设计?"
|
||||
|
||||
### 3.3 精准修改
|
||||
- 只改必须改的,不"顺手改进"相邻代码
|
||||
- 匹配现有代码风格,即使你有不同的偏好
|
||||
- 每行改动都能追溯到用户的请求
|
||||
- 只清理你自己改动产生的无用代码
|
||||
|
||||
### 3.4 目标驱动
|
||||
- 把任务转化为可验证目标
|
||||
- 多步任务声明计划:`[步骤] → 验证: [检查]`
|
||||
- 强验收标准让 Agent 能独立循环,弱标准需要持续澄清
|
||||
|
||||
---
|
||||
|
||||
## 四、全链路 6 环分析
|
||||
|
||||
> ⚠️ **涉及数据库字段的 Bug / 需求,必须走完整链路。**
|
||||
|
||||
```
|
||||
前端/页面 → Controller → Service → Mapper → DB/SQL → 关联模块
|
||||
①录入 ②验证 ③业务 ④持久化 ⑤存储 ⑥联动
|
||||
```
|
||||
|
||||
| 环 | 检查内容 |
|
||||
|----|---------|
|
||||
| ① 录入 | 前端有无输入入口(弹窗、表格行编辑、表单) |
|
||||
| ② 验证 | Controller 参数校验、@Valid、权限控制 |
|
||||
| ③ 业务 | Service 业务逻辑、事务边界、多个 Service 实现类入口 |
|
||||
| ④ 持久化 | Mapper XML、DTO 字段映射、类型转换 |
|
||||
| ⑤ 存储 | 数据库表结构、索引、NOT NULL 约束 |
|
||||
| ⑥ 联动 | 上游(医嘱→护士站)、下游(打印、计费、报表)是否同步 |
|
||||
|
||||
**修复后的验证顺序**:
|
||||
1. 数据库:确认状态值已正确写入
|
||||
2. 后端接口:确认返回的状态映射正确
|
||||
3. 前端显示:确认页面显示正确状态文本
|
||||
4. 前端交互:确认按钮/操作基于正确状态启用/禁用
|
||||
5. 统计数据:确认池/报表统计包含新状态
|
||||
|
||||
---
|
||||
|
||||
## 五、Harness Engineering 方法论
|
||||
|
||||
> Harness = 约束 + 反馈 + 控制平面 + 持久执行
|
||||
|
||||
### 5.1 四层约束金字塔
|
||||
|
||||
| 层级 | 内容 | 落地方式 |
|
||||
|------|------|---------|
|
||||
| **L1 架构约束** | 接口合约、包结构、命名规范、禁止模式 | 本文件铁律 |
|
||||
| **L2 代码质量** | 圈复杂度、代码风格、类型提示 | 编译门禁 + ESLint |
|
||||
| **L3 安全约束** | 敏感信息检测、权限检查、输入验证 | 配置不可硬编码 |
|
||||
| **L4 业务规则** | 领域逻辑、数据一致性、事务边界 | 全链路 6 环验证 |
|
||||
|
||||
**约束设计原则**:
|
||||
- **可验证**:每条约束必须能被自动化检查("覆盖率>90%"✅ "质量要高"❌)
|
||||
- **无歧义**:"每函数不超过50行"✅ "函数不要太长"❌
|
||||
- **优先级**:安全(1) > 架构(2) > 业务(3) > 质量(4) > 性能(5)
|
||||
- **渐进增强**:L1编译通过 → L2+命名规范 → L3+测试覆盖 → L4+安全扫描
|
||||
|
||||
### 5.2 三层反馈系统
|
||||
|
||||
| 层级 | 速度 | 覆盖范围 | 失败处理 |
|
||||
|------|------|---------|---------|
|
||||
| **L1 编译检查** | <30秒 | 语法、类型、签名 | 立即阻断,自行修复 |
|
||||
| **L2 数据流验证** | <5分钟 | 全链路字段、Mapper XML、DTO | 修复后上报 |
|
||||
| **L3 人工审查** | 10-30分钟 | 架构、设计、业务正确性 | 驳回/指导/批准 |
|
||||
|
||||
**反馈铁律**:
|
||||
- 反馈必须可行动(文件 + 行号 + 错误类型 + 修复方向)
|
||||
- 失败后先回滚到最近检查点,再重试
|
||||
- 持续失败3次 → 上报人类
|
||||
|
||||
### 5.3 控制平面
|
||||
|
||||
```
|
||||
战略层(人类) → 设定目标、审批决策、异常升级
|
||||
战术层(Agent) → 任务分解、update_plan、依赖协调、检查点保存
|
||||
执行层(Agent) → 代码生成、测试执行、错误恢复、幂等重试
|
||||
```
|
||||
|
||||
### 5.4 持久执行
|
||||
|
||||
- 每个关键步骤保存检查点(`update_plan` 进度)
|
||||
- 失败后从最新检查点恢复,不从头开始
|
||||
- 幂等设计:同一操作重复执行结果一致
|
||||
- **三层状态管理**:系统层(工作流ID/超时/重试) → 执行层(当前活动/进度) → 业务层(已完成工作/中间产物)
|
||||
|
||||
---
|
||||
|
||||
## 六、五层质量门禁
|
||||
|
||||
| 门禁 | 时间 | 范围 | 失败处理 |
|
||||
|------|------|------|---------|
|
||||
| **L1 编译检查** | <30秒 | 语法、类型、导入 | Agent 自行修复 |
|
||||
| **L2 静态分析** | <2分钟 | 代码风格、复杂度、安全 | Agent 修复 |
|
||||
| **L3 单元测试** | <5分钟 | 功能正确性、边界条件 | 自动修复或上报 |
|
||||
| **L4 集成测试** | <15分钟 | 模块间交互、数据流 | 上报人工 |
|
||||
| **L5 生产验证** | 持续 | 监控、告警、性能 | 自动回滚 |
|
||||
|
||||
**提交铁律**:L1-L2 必须通过才能 commit,L3(如有DB变更)必须通过才能 push
|
||||
|
||||
---
|
||||
|
||||
## 七、系统化调试(Systematic Debugging)
|
||||
|
||||
> **铁律:没有根因调查,不能提出修复方案。**
|
||||
|
||||
### 四阶段流程
|
||||
|
||||
**阶段1:根因调查**(修复前必须完成)
|
||||
1. 仔细阅读错误信息(堆栈、行号、错误码)
|
||||
2. 稳定复现(能否可靠触发?步骤?每次?)
|
||||
3. 检查最近变更(git diff、新依赖、配置变更)
|
||||
4. 多组件系统:在每个组件边界加诊断日志,定位哪一层断裂
|
||||
5. 追踪数据流:坏值从哪里来?谁调用的?一直追溯到源头
|
||||
|
||||
**阶段2:模式分析**
|
||||
- 找到同代码库中类似的正常工作代码
|
||||
- 逐项对比差异
|
||||
- 理解依赖关系
|
||||
|
||||
**阶段3:假设与测试**
|
||||
- 形成单一假设:"我认为X是根因,因为Y"
|
||||
- 做最小改动测试
|
||||
- 有效 → 阶段4;无效 → 新假设
|
||||
|
||||
**阶段4:实施**
|
||||
- 创建失败测试用例
|
||||
- 修复根因(不是症状)
|
||||
- 验证修复
|
||||
|
||||
---
|
||||
|
||||
## 八、后端开发规范
|
||||
|
||||
### 分层架构
|
||||
```
|
||||
Controller → AppService → Service → Mapper → Entity
|
||||
```
|
||||
|
||||
### 命名规范
|
||||
| 类型 | 规则 | 示例 |
|
||||
|------|------|------|
|
||||
| Controller | `XxxController` | `RegistrationController` |
|
||||
| AppService | `IXxxAppService` / `XxxAppServiceImpl` | `IRegistrationAppService` |
|
||||
| Service | `IXxxService` / `XxxServiceImpl` | `IRegistrationService` |
|
||||
| Mapper | `XxxMapper` | `RegistrationMapper` |
|
||||
| Entity | `Xxx` | `Registration` |
|
||||
| DTO | `XxxDto` / `XxxQueryDto` | `RegistrationDto` |
|
||||
|
||||
### 包结构
|
||||
```
|
||||
com.healthlink.his.web.{module}.controller
|
||||
com.healthlink.his.web.{module}.appservice
|
||||
com.healthlink.his.web.{module}.service
|
||||
com.healthlink.his.web.{module}.mapper
|
||||
com.healthlink.his.web.{module}.dto
|
||||
com.healthlink.his.domain.{module}
|
||||
com.healthlink.his.common.enums
|
||||
```
|
||||
|
||||
### 关键约束
|
||||
- 所有查询使用 `LambdaQueryWrapper`,禁止字符串拼接 SQL
|
||||
- `@Transactional(rollbackFor = Exception.class)` 管理事务
|
||||
- 所有接口标注 `@PreAuthorize` 权限控制
|
||||
- 患者敏感信息在日志中脱敏
|
||||
- **扩展功能不修改原有函数签名**
|
||||
|
||||
---
|
||||
|
||||
## 九、前端开发规范
|
||||
|
||||
### 技术栈
|
||||
- Vue 3 + Vite + Element Plus + Pinia + Axios(基于 RuoYi-Vue3)
|
||||
|
||||
### 目录结构
|
||||
```
|
||||
src/api/{module}/ # API接口
|
||||
src/views/{module}/ # 页面组件
|
||||
src/store/modules/ # Pinia状态管理
|
||||
src/components/ # 公共组件
|
||||
```
|
||||
|
||||
### 关键约束
|
||||
- API前缀:`/healthlink-his/api/v1/`
|
||||
- 路由懒加载:`() => import('@/views/xxx/index.vue')`
|
||||
- 页面使用 `<script setup>` 语法
|
||||
- 按钮权限使用 `v-hasPermi` 指令
|
||||
- `onMounted` 中注册的事件在 `onUnmounted` 中移除
|
||||
|
||||
---
|
||||
|
||||
## 十、Agent 体系
|
||||
|
||||
### 角色与路由
|
||||
|
||||
| 代号 | 名称 | 角色 | 路由关键词 |
|
||||
|------|------|------|-----------|
|
||||
| liubei | 刘备 | 项目经理 | 协调、分派、异常升级 |
|
||||
| zhugeliang | 诸葛亮 | 架构师 | 分析、路由、设计 |
|
||||
| guanyu | 关羽 | 后端开发 | java, api, spring, service, controller |
|
||||
| zhaoyun | 赵云 | 前端开发 | vue, 界面, 显示, 弹窗, 按钮 |
|
||||
| xunyu | 荀彧 | DBA | 数据库, sql, 迁移, mapper xml |
|
||||
| zhangfei | 张飞 | 测试 | 测试, QA, 回归 |
|
||||
| huatuo | 华佗 | 验收 | 需求验收、质量确认 |
|
||||
| chenlin | 陈琳 | 文档 | 文档、归档、Git提交 |
|
||||
|
||||
### 协作流水线
|
||||
|
||||
```
|
||||
刘备(协调) → 诸葛亮(分析路由) → {关羽|赵云}(修复) → 荀彧(DB审查) → 张飞(测试) → 华佗(验收) → 陈琳(归档)
|
||||
```
|
||||
|
||||
### Bug 修复完整管线(BDT 方法论)
|
||||
|
||||
```
|
||||
获取Bug → 设计测试用例 → 基线测试(应失败) → 全链路修复 → 回归测试(应通过) → 扩展测试(无回归) → 提交
|
||||
```
|
||||
|
||||
### Bug 状态管理铁律
|
||||
- 人类提的 Bug:只加备注,不改状态,不改分配
|
||||
- 智能体提的 Bug:可以改分配和加备注
|
||||
- 已关闭/已解决的 Bug 不再处理
|
||||
|
||||
---
|
||||
|
||||
## 十一、审查与审计
|
||||
|
||||
### 三层审查体系
|
||||
|
||||
| 层级 | 内容 | 时机 |
|
||||
|------|------|------|
|
||||
| **L1 自审** | Agent 对照约束逐条检查 | 每次提交前 |
|
||||
| **L2 配对审查** | Agent 生成变更摘要,人类终审 | PR/提交时 |
|
||||
| **L3 合规审查** | 审计追踪,记录所有 AI 操作 | 持续 |
|
||||
|
||||
### L1 自审清单
|
||||
```yaml
|
||||
self_review:
|
||||
- "所有修改能通过编译?"
|
||||
- "遵守命名规范?"
|
||||
- "测试覆盖达标?"
|
||||
- "没有遗漏的 TODO / DEBUG?"
|
||||
- "变更范围没超出任务边界?"
|
||||
```
|
||||
|
||||
### 评审评分维度
|
||||
| 维度 | 问题 |
|
||||
|------|------|
|
||||
| 正确性 | 行为是否符合目标功能? |
|
||||
| 验证 | 检查是否真的跑过并留下证据? |
|
||||
| 范围纪律 | 是否保持在选定功能范围内? |
|
||||
| 可靠性 | 结果能否在重启后继续工作? |
|
||||
| 可维护性 | 代码和文档是否清楚到可交接? |
|
||||
|
||||
---
|
||||
|
||||
## 十二、标准工作循环
|
||||
|
||||
```
|
||||
开始会话
|
||||
├→ 1. Init — 读 AGENTS.md + PROGRESS.md + git log
|
||||
├→ 2. Select — 只选一个未完成功能
|
||||
├→ 3. Implement — 一次只做一个,不扩大范围
|
||||
├→ 4. Verify — 运行验证命令,有证据才标记完成
|
||||
└→ 5. Cleanup — 更新进度 + clean-state-checklist + git commit
|
||||
```
|
||||
|
||||
### 会话结束前必须运行 Clean State Checklist
|
||||
```
|
||||
□ 标准启动路径仍然可用
|
||||
□ 标准验证路径仍然可运行
|
||||
□ 当前进度已记录到进度日志
|
||||
□ 无半成品步骤处于未记录状态
|
||||
□ 下一轮会话无需人工修复即可继续
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 十三、开发流程
|
||||
|
||||
```
|
||||
收到任务
|
||||
├→ ① 分析需求 → 读相关文档(MD/)、读全链路6环
|
||||
├→ ② 制定计划 → update_plan (3-6个阶段)
|
||||
├→ ③ 后端开发 → Controller → AppService → Service → Mapper → Entity → Flyway
|
||||
├→ ④ 后端测试 → mvn test → 接口测试(业务逻辑验证)
|
||||
├→ ⑤ 前端开发 → API接口 → 页面组件 → 路由配置
|
||||
├→ ⑥ 前端测试 → npm run build:dev → 功能验证
|
||||
├→ ⑦ 质量门禁 → L1编译 → L2测试 → L3DB审查 → L4验收 → L5归档
|
||||
└→ ⑧ 提交代码 → git commit(规范格式) → git push → 文档更新
|
||||
```
|
||||
|
||||
### Git Commit 格式
|
||||
```
|
||||
<type>(<scope>): <subject>
|
||||
|
||||
type: feat|fix|docs|refactor|test|chore
|
||||
scope: 模块名(如 registration, billing, pharmacy)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 十四、快速参考命令
|
||||
|
||||
```bash
|
||||
# === 后端 ===
|
||||
export JAVA_HOME=/opt/jdk-25
|
||||
mvn clean compile -DskipTests # 编译
|
||||
mvn install -DskipTests # 构建
|
||||
mvn test -pl healthlink-his-application -Dtest="XxxTest" -Dsurefire.failIfNoSpecifiedTests=false
|
||||
|
||||
# === 前端 ===
|
||||
cd healthlink-his-ui
|
||||
npm run dev && npm run build:dev && npm run lint && npm run test:run
|
||||
|
||||
# === Git ===
|
||||
git status && git add -A && git commit -m "feat(module): desc" && git push origin develop
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 十五、详细规范文档索引
|
||||
|
||||
| 文档 | 路径 | 用途 |
|
||||
|------|------|------|
|
||||
| 执行铁律 | `MD/specs/IRON_RULES.md` | 铁律完整版 |
|
||||
| 后端规范 | `MD/specs/BACKEND_DEVELOPMENT_STANDARD.md` | 后端编码标准 |
|
||||
| 前端规范 | `MD/specs/FRONTEND_DEVELOPMENT_STANDARD.md` | 前端编码标准 |
|
||||
| Harness方法论 | `MD/specs/HARNESS_ENGINEERING.md` | 完整Harness+Agent方法论 |
|
||||
| 文档规范 | `MD/DOCUMENTATION_STANDARD.md` | 文档管理标准 |
|
||||
| 后端清单 | `MD/specs/BACKEND_CHECKLIST.md` | 发布前检查 |
|
||||
| 前端清单 | `MD/specs/FRONTEND_CHECKLIST.md` | 发布前检查 |
|
||||
| 三甲标准 | `MD/standards/GRADE3A_HIS_STANDARD.md` | 三甲医院达标标准 |
|
||||
| Flyway指南 | `MD/guides/FLYWAY_USAGE_GUIDE.md` | 数据库迁移指南 |
|
||||
|
||||
---
|
||||
|
||||
## 十六、过往教训
|
||||
|
||||
| 教训 | 内容 |
|
||||
|------|------|
|
||||
| 状态链路断裂 | Bug#574: 签到设 BOOKED(1) 而非 CHECKED_IN(3),前端映射缺失 → 必须走完整状态链路 |
|
||||
| 盲删源文件 | AI 看到编译错误直接删文件,没检查 baseline → 必须先确认文件来源 |
|
||||
| 修复方向偏差 | 多次 fallback 改的是错误的 Service → 必须用 rg 搜索所有相关代码路径 |
|
||||
| bug_reports 缺列 | INSERT 静默失败 → 必须检查表结构 |
|
||||
| 禅道 comment API | API 不存在,用 resolve+activate workaround |
|
||||
| SQLite WAL 并发 | 多进程并发写需要 checkpoint |
|
||||
| UTF-8 切片 | 多字节字符不能用 byte index 切片 |
|
||||
| 上下文焦虑 | Agent 感觉上下文快满时会匆忙结束,跳过验证 → 注意 context 40% 阈值 |
|
||||
| 过早宣告胜利 | 自评≠验证,分开"干活"和"检查" |
|
||||
| 覆盖率幻觉 | 覆盖率达标但逻辑没测 → 引入变异测试 |
|
||||
|
||||
---
|
||||
|
||||
> ⚠️ 本文件是 AI 开发规范的唯一信源。各工具配置文件由 `bash scripts/sync-ai-rules.sh` 同步。
|
||||
|
||||
---
|
||||
|
||||
> 📅 最后同步: 2026-06-06 15:09 | 源文件: RULES.md | 重新同步: `bash scripts/sync-ai-rules.sh`
|
||||
, [System.Text.UTF8Encoding]::new(False))
|
||||
- git提取:先 Out-File -Encoding utf8 保存到临时文件,再用 [System.IO.File]::ReadAllText() 读取
|
||||
- **根因**:PowerShell 管道会丢失换行符,git show | Out-File 会将多行文件压缩为一行
|
||||
过"
|
||||
|
||||
|
||||
### 🟡 P1 铁律 — 强烈建议
|
||||
|
||||
**铁律9: 先分解再行动**
|
||||
|
||||
424
MD/MODULE_INDEX.md
Normal file
424
MD/MODULE_INDEX.md
Normal file
@@ -0,0 +1,424 @@
|
||||
# HealthLink-HIS 代码模块索引
|
||||
|
||||
> 供 LLM 快速定位代码。每个模块列出 Controller → Service → Mapper 关键文件。
|
||||
|
||||
## 关键词 → 模块速查
|
||||
|
||||
| 关键词 | 后端模块 | 前端目录 |
|
||||
|---|---|---|
|
||||
| 门诊医生站/门诊医嘱/门诊处方/诊断/检查申请 | `doctorstation` | `doctorstation` |
|
||||
| 住院医生站/住院医嘱/临床医嘱/签发/停嘱 | `regdoctorstation` | `inpatientDoctor` |
|
||||
| 住院护士站/医嘱校对/医嘱执行/护理/换床 | `inhospitalnursestation` | `inpatientNurse` |
|
||||
| 挂号/门诊收费/门诊结算 | `chargemanage` | `charge` |
|
||||
| 住院收费/住院结算/预交金 | `inhospitalcharge` | `inHospitalManagement` |
|
||||
| 收费管理/计费/退费 | `paymentmanage` | `outpatientFinance` |
|
||||
| 药品/药房/药库/发药/取药 | `pharmacymanage` | `pharmacymanagement` |
|
||||
| 药房发药/门诊发药 | `pharmacyDispensarymanage` | `drug` |
|
||||
| 药库管理/库存 | `pharmacyWarehousemanage` | `medicineStorage` |
|
||||
| 库存管理/盘点/出入库 | `inventorymanage` | `medicineStorage` |
|
||||
| 物资管理/耗材 | `materialmanage` | `` |
|
||||
| 字典/数据字典/诊疗目录/基础数据 | `datadictionary` | `datadictionary` |
|
||||
| 部门/科室管理 | `departmentmanage` | `system` |
|
||||
| 卡管理/就诊卡 | `cardmanagement` | `cardmanagement` |
|
||||
| 检验/化验/标本 | `lab` | `inspection` |
|
||||
| 检查/影像/放射 | `Inspection` | `inspection` |
|
||||
| 手术/手术安排/手术申请 | `surgicalschedule` | `surgerymanage` |
|
||||
| 病历/电子病历/EMR | `emr` | `emr` |
|
||||
| 护理记录/护理评估 | `nursing` | `nursing` |
|
||||
| 分诊/排队/叫号 | `triageandqueuemanage` | `triageandqueuemanage` |
|
||||
| 医保/医保对码/医保目录 | `ybmanage` | `ybmanagement` |
|
||||
| 会诊/会诊申请 | `consultation` | `consultationmanagement` |
|
||||
| 院感/感染上报 | `infection` | `infection` |
|
||||
| 合理用药/处方审核 | `rationaldrug` | `rationaldrug` |
|
||||
| 中医/中医处方 | `tcm` | `tcm` |
|
||||
| 患者管理/患者信息 | `patientmanage` | `patientmanagement` |
|
||||
| 预约/挂号预约 | `appointmentmanage` | `appoinmentmanage` |
|
||||
| 报告/报告管理 | `reportmanage` | `` |
|
||||
| 质控/质量 | `quality` | `quality` |
|
||||
| 系统管理/用户/角色/权限 | `basicmanage` | `system` |
|
||||
| 门诊管理/门诊工作站 | `outpatientmanage` | `doctorstation` |
|
||||
| 前置手术/术前管理 | `preopmanage` | `preopmanage` |
|
||||
| 危急值 | `criticalvalue` | `criticalvalue` |
|
||||
| 抗菌药 | `antibiotic` | `antibiotic` |
|
||||
| 随访 | `followup` | `followup` |
|
||||
| request.js/请求拦截/响应拦截 | `common` | `crossmodule` |
|
||||
|
||||
## 后端模块详情
|
||||
|
||||
### `Inspection` (40 files)
|
||||
- **Controller**: `Inspection/controller/SampleCollectController.java` `Inspection/controller/ObservationDefController.java` `Inspection/controller/LabReferenceRangeController.java`
|
||||
- **AppService**: `Inspection/appservice/ISampleCollectAppManageAppService.java` `Inspection/appservice/ILisConfigManageAppService.java` `Inspection/appservice/IInstrumentManageAppService.java`
|
||||
- **ServiceImpl**: `Inspection/appservice/impl/LisConfigManageAppServiceImpl.java` `Inspection/appservice/impl/ObservationManageAppServiceImpl.java` `Inspection/appservice/impl/SpecimenManageAppServiceImpl.java`
|
||||
- **Mapper**: `Inspection/mapper/SampleCollectMapper.java` `Inspection/mapper/LisReportMapper.java` `Inspection/mapper/GroupRecMapper.java`
|
||||
- **DTO**: `Inspection/dto/SampleCollectManageDto.java` `Inspection/dto/SpecimenDefManageDto.java` `Inspection/dto/InstrumentManageDto.java` `Inspection/dto/LisConfigManageDto.java` `Inspection/dto/InstrumentSelParam.java`
|
||||
|
||||
### `adjustprice` (10 files)
|
||||
- **Controller**: `adjustprice/controller/ChangePriceController.java` `adjustprice/controller/ChangePriceDataListPageController.java`
|
||||
- **ServiceImpl**: `adjustprice/appservice/impl/AdjustPriceServiceImpl.java`
|
||||
- **Mapper**: `adjustprice/mapper/AdjustPriceMapper.java`
|
||||
- **DTO**: `adjustprice/dto/ChangePriceDataDto.java` `adjustprice/dto/AdjustPriceManagerSearchParam.java` `adjustprice/dto/ChangePricePageDto.java`
|
||||
|
||||
### `anesthesia` (4 files)
|
||||
- **Controller**: `anesthesia/controller/AnesthesiaController.java` `anesthesia/controller/AnesthesiaEnhancedController.java`
|
||||
- **AppService**: `anesthesia/appservice/IAnesthesiaAppService.java`
|
||||
- **ServiceImpl**: `anesthesia/appservice/impl/AnesthesiaAppServiceImpl.java`
|
||||
|
||||
### `antibiotic` (3 files)
|
||||
- **Controller**: `antibiotic/controller/AntibioticController.java`
|
||||
- **AppService**: `antibiotic/appservice/IAntibioticAppService.java`
|
||||
- **ServiceImpl**: `antibiotic/appservice/impl/AntibioticAppServiceImpl.java`
|
||||
|
||||
### `appointmentmanage` (29 files)
|
||||
- **Controller**: `appointmentmanage/controller/ScheduleSlotController.java` `appointmentmanage/controller/DeptAppthoursController.java` `appointmentmanage/controller/SchedulePoolController.java`
|
||||
- **AppService**: `appointmentmanage/appservice/IDeptAppService.java` `appointmentmanage/appservice/IDoctorScheduleAppService.java` `appointmentmanage/appservice/IClinicRoomAppService.java`
|
||||
- **ServiceImpl**: `appointmentmanage/appservice/impl/DoctorScheduleAppServiceImpl.java` `appointmentmanage/appservice/impl/DeptAppointmentHoursAppServiceImpl.java` `appointmentmanage/appservice/impl/TicketAppServiceImpl.java`
|
||||
- **Mapper**: `appointmentmanage/mapper/DoctorScheduleAppMapper.java` `appointmentmanage/mapper/SchedulePoolAppMapper.java` `appointmentmanage/mapper/DeptAppMapper.java`
|
||||
- **DTO**: `appointmentmanage/dto/TicketDto.java` `appointmentmanage/dto/SchedulePoolDto.java`
|
||||
|
||||
### `basedatamanage` (44 files)
|
||||
- **Controller**: `basedatamanage/controller/OrganizationLocationController.java` `basedatamanage/controller/BodyStructureController.java` `basedatamanage/controller/OperatingRoomController.java`
|
||||
- **AppService**: `basedatamanage/appservice/IOrganizationAppService.java` `basedatamanage/appservice/IBodyStructureAppService.java` `basedatamanage/appservice/ILocationAppService.java`
|
||||
- **ServiceImpl**: `basedatamanage/appservice/impl/PractitionerAppServiceImpl.java` `basedatamanage/appservice/impl/BodyStructureAppServiceImpl.java` `basedatamanage/appservice/impl/OrganizationAppServiceImpl.java`
|
||||
- **Mapper**: `basedatamanage/mapper/PractitionerAppAppMapper.java`
|
||||
- **DTO**: `basedatamanage/dto/SelectableOrgDto.java` `basedatamanage/dto/PractitionerOrgAndLocationDto.java` `basedatamanage/dto/OrganizationInitDto.java` `basedatamanage/dto/OperatingRoomDto.java` `basedatamanage/dto/LocationInitDto.java`
|
||||
|
||||
### `basicmanage` (5 files)
|
||||
- **Controller**: `basicmanage/controller/BedController.java` `basicmanage/controller/InvoiceController.java` `basicmanage/controller/InvoiceSegmentController.java`
|
||||
|
||||
### `basicservice` (7 files)
|
||||
- **Controller**: `basicservice/controller/HealthcareServiceController.java`
|
||||
- **Mapper**: `basicservice/mapper/HealthcareServiceBizMapper.java`
|
||||
- **DTO**: `basicservice/dto/HealthcareServiceAddOrUpdateParam.java` `basicservice/dto/HealthcareServiceDto.java` `basicservice/dto/HealthcareServiceInitDto.java`
|
||||
|
||||
### `ca` (3 files)
|
||||
- **Controller**: `ca/controller/CaSignatureController.java`
|
||||
- **AppService**: `ca/appservice/ICaSignatureAppService.java`
|
||||
- **ServiceImpl**: `ca/appservice/impl/CaSignatureAppServiceImpl.java`
|
||||
|
||||
### `cardmanagement` (17 files)
|
||||
- **Controller**: `cardmanagement/controller/CardManageController.java`
|
||||
- **AppService**: `cardmanagement/appservice/ICardManageAppService.java`
|
||||
- **ServiceImpl**: `cardmanagement/appservice/impl/CardManageAppServiceImpl.java`
|
||||
- **Mapper**: `cardmanagement/mapper/InfectiousAuditMapper.java` `cardmanagement/mapper/InfectiousCardMapper.java`
|
||||
- **DTO**: `cardmanagement/dto/InfectiousCardDto.java` `cardmanagement/dto/DoctorCardQueryDto.java` `cardmanagement/dto/DoctorCardListDto.java` `cardmanagement/dto/SingleReturnDto.java` `cardmanagement/dto/CardStatisticsDto.java`
|
||||
|
||||
### `catalogmanage` (4 files)
|
||||
- **Controller**: `catalogmanage/controller/CatalogController.java`
|
||||
- **ServiceImpl**: `catalogmanage/appservice/impl/CatalogServiceImpl.java`
|
||||
- **Mapper**: `catalogmanage/mapper/CatalogMapper.java`
|
||||
|
||||
### `charge` (4 files)
|
||||
- **Controller**: `charge/patientcardrenewal/PatientCardRenewalController.java`
|
||||
- **ServiceImpl**: `charge/patientcardrenewal/PatientCardRenewalServiceImpl.java`
|
||||
|
||||
### `chargemanage` (46 files)
|
||||
- **Controller**: `chargemanage/controller/OutpatientRegistrationController.java` `chargemanage/controller/OutpatientPricingController.java` `chargemanage/controller/InpatientChargeController.java`
|
||||
- **AppService**: `chargemanage/appservice/IInpatientChargeAppService.java` `chargemanage/appservice/IOutpatientRegistrationAppService.java` `chargemanage/appservice/IOutpatientRefundAppService.java`
|
||||
- **ServiceImpl**: `chargemanage/appservice/impl/OutpatientChargeAppServiceImpl.java` `chargemanage/appservice/impl/InpatientChargeAppServiceImpl.java` `chargemanage/appservice/impl/OutpatientRefundAppServiceImpl.java`
|
||||
- **Mapper**: `chargemanage/mapper/OutpatientRefundAppMapper.java` `chargemanage/mapper/OutpatientRegistrationAppMapper.java` `chargemanage/mapper/OutpatientChargeAppMapper.java`
|
||||
- **DTO**: `chargemanage/dto/ReprintRegistrationDto.java` `chargemanage/dto/EncounterPatientRefundDto.java` `chargemanage/dto/OutpatientPricingPriceDto.java` `chargemanage/dto/OutpatientPricingInventoryDto.java` `chargemanage/dto/RefundItemParam.java`
|
||||
|
||||
### `check` (27 files)
|
||||
- **Controller**: `check/controller/CheckMethodController.java` `check/controller/SpecimenBarcodeController.java` `check/controller/RadiologyEnhancedController.java`
|
||||
- **AppService**: `check/appservice/ILisGroupInfoAppService.java` `check/appservice/ICheckPartAppService.java` `check/appservice/ICheckMethodAppService.java`
|
||||
- **ServiceImpl**: `check/appservice/impl/CheckMethodAppServiceImpl.java` `check/appservice/impl/CheckPartAppServiceImpl.java` `check/appservice/impl/CheckPackageAppServiceImpl.java`
|
||||
- **Mapper**: `check/mapper/LisGroupInfoAppMapper.java` `check/mapper/CheckMethodAppMapper.java` `check/mapper/CheckPartAppMapper.java`
|
||||
- **DTO**: `check/dto/CheckPackageDetailDto.java` `check/dto/ExamApplyDto.java` `check/dto/ExamApplyItemDto.java` `check/dto/CheckPackageDto.java` `check/dto/CheckMethodDto.java`
|
||||
|
||||
### `clinical` (2 files)
|
||||
- **Controller**: `clinical/controller/KnowledgeBaseController.java` `clinical/controller/ClinicalPathwayController.java`
|
||||
|
||||
### `clinicalmanage` (11 files)
|
||||
- **Controller**: `clinicalmanage/controller/SurgicalScheduleController.java` `clinicalmanage/controller/SurgeryController.java`
|
||||
- **AppService**: `clinicalmanage/appservice/ISurgicalScheduleAppService.java` `clinicalmanage/appservice/ISurgeryAppService.java`
|
||||
- **ServiceImpl**: `clinicalmanage/appservice/impl/SurgicalScheduleAppServiceImpl.java` `clinicalmanage/appservice/impl/SurgeryAppServiceImpl.java`
|
||||
- **Mapper**: `clinicalmanage/mapper/SurgicalScheduleAppMapper.java` `clinicalmanage/mapper/SurgeryAppMapper.java`
|
||||
- **DTO**: `clinicalmanage/dto/SurgeryDto.java` `clinicalmanage/dto/OpScheduleDto.java` `clinicalmanage/dto/OpCreateScheduleDto.java`
|
||||
|
||||
### `common` (17 files)
|
||||
- **Controller**: `common/controller/CommonAppController.java`
|
||||
- **ServiceImpl**: `common/appservice/impl/CommonServiceImpl.java`
|
||||
- **Mapper**: `common/mapper/CommonAppMapper.java`
|
||||
- **DTO**: `common/dto/ActivityDefinitionDto.java` `common/dto/PerformInfoDto.java` `common/dto/PractitionerInfoDto.java` `common/dto/LocationInventoryDto.java` `common/dto/PerformRecordDto.java`
|
||||
|
||||
### `consultation` (19 files)
|
||||
- **Controller**: `consultation/controller/ConsultationController.java`
|
||||
- **AppService**: `consultation/appservice/IConsultationAppService.java`
|
||||
- **ServiceImpl**: `consultation/appservice/impl/ConsultationAppServiceImpl.java`
|
||||
- **Mapper**: `consultation/mapper/ConsultationInvitedMapper.java` `consultation/mapper/ConsultationConfirmationMapper.java` `consultation/mapper/ConsultationRequestMapper.java`
|
||||
- **DTO**: `consultation/dto/PhysicianNodeDto.java` `consultation/dto/InvitedObjectDto.java` `consultation/dto/ConsultationActivityDto.java` `consultation/dto/DepartmentTreeDto.java` `consultation/dto/ConsultationRequestDto.java`
|
||||
|
||||
### `controller` (2 files)
|
||||
- **Controller**: `controller/WorkflowController.java` `controller/HomeStatisticsController.java`
|
||||
|
||||
### `criticalvalue` (3 files)
|
||||
- **Controller**: `criticalvalue/controller/CriticalValueController.java`
|
||||
- **AppService**: `criticalvalue/appservice/ICriticalValueAppService.java`
|
||||
- **ServiceImpl**: `criticalvalue/appservice/impl/CriticalValueAppServiceImpl.java`
|
||||
|
||||
### `crossmodule` (3 files)
|
||||
- **Controller**: `crossmodule/controller/CrossModuleController.java` `crossmodule/controller/EnhancementController.java` `crossmodule/controller/IntegrationController.java`
|
||||
|
||||
### `datadictionary` (65 files)
|
||||
- **Controller**: `datadictionary/controller/DiagnosisTreatmentController.java` `datadictionary/controller/MedicationManageController.java` `datadictionary/controller/DiseaseManageController.java`
|
||||
- **AppService**: `datadictionary/appservice/IDeviceManageAppService.java` `datadictionary/appservice/IDiagTreatMAppService.java` `datadictionary/appservice/ItemDefinitionAppService.java`
|
||||
- **ServiceImpl**: `datadictionary/appservice/impl/DiagTreatMAppServiceImpl.java` `datadictionary/appservice/impl/SupplierManagementAppServiceImpl.java` `datadictionary/appservice/impl/ItemDefinitionAppServiceImpl.java`
|
||||
- **Mapper**: `datadictionary/mapper/MedicationManageSearchMapper.java` `datadictionary/mapper/ICDCodeMapper.java` `datadictionary/mapper/ActivityDefinitionManageMapper.java`
|
||||
- **DTO**: `datadictionary/dto/DeviceManageUpDto.java` `datadictionary/dto/ChargeItemOptionDto.java` `datadictionary/dto/SupplierDto.java` `datadictionary/dto/DiagnosisTreatmentInitDto.java` `datadictionary/dto/DiagnosisTreatmentSelParam.java`
|
||||
|
||||
### `departmentmanage` (42 files)
|
||||
- **Controller**: `departmentmanage/controller/DepartmentTransferOutOrderController.java` `departmentmanage/controller/DepartmentReturnToWarehouseOrderController.java` `departmentmanage/controller/DepartmentStocktakingOrderController.java`
|
||||
- **ServiceImpl**: `departmentmanage/appservice/impl/DepartmentReceiptApprovalServiceImpl.java` `departmentmanage/appservice/impl/DepartmentStockInOrderServiceImpl.java` `departmentmanage/appservice/impl/DepartmentCommonServiceImpl.java`
|
||||
- **Mapper**: `departmentmanage/mapper/DepartmentTransferInOrderMapper.java` `departmentmanage/mapper/DepartmentStocktakingOrderMapper.java` `departmentmanage/mapper/DepartmentTransferOutOrderMapper.java`
|
||||
- **DTO**: `departmentmanage/dto/DepartmentDeviceInfoDto.java` `departmentmanage/dto/DepartmentDetailDto.java` `departmentmanage/dto/DepartmentInitDto.java` `departmentmanage/dto/DepartmentSearchParam.java` `departmentmanage/dto/DepartmentDto.java`
|
||||
|
||||
### `doctorstation` (91 files)
|
||||
- **Controller**: `doctorstation/controller/DoctorStationDiagnosisController.java` `doctorstation/controller/DoctorStationInspectionLabApplyController.java` `doctorstation/controller/DoctorStationChineseMedicalController.java`
|
||||
- **AppService**: `doctorstation/appservice/IDoctorPhraseAppService.java` `doctorstation/appservice/IDoctorStationEmrAppService.java` `doctorstation/appservice/IDoctorStationMainAppService.java`
|
||||
- **ServiceImpl**: `doctorstation/appservice/impl/DoctorStationPtDetailsAppServiceImpl.java` `doctorstation/appservice/impl/DoctorStationElepPrescriptionServiceImpl.java` `doctorstation/appservice/impl/DoctorPhraseAppServiceImpl.java`
|
||||
- **Mapper**: `doctorstation/mapper/DoctorStationAdviceAppMapper.java` `doctorstation/mapper/DoctorStationEmrAppMapper.java` `doctorstation/mapper/DoctorStationDiagnosisAppMapper.java`
|
||||
- **DTO**: `doctorstation/dto/EncounterContractDto.java` `doctorstation/dto/AdviceInventoryDto.java` `doctorstation/dto/ActivityChildrenJsonParams.java` `doctorstation/dto/DoctorStationLabApplyItemDto.java` `doctorstation/dto/DoctorStationInitDto.java`
|
||||
|
||||
### `document` (47 files)
|
||||
- **Controller**: `document/controller/DocRecordController.java` `document/controller/DocDefinitionController.java` `document/controller/InformedConsentController.java`
|
||||
- **AppService**: `document/appservice/IDocStatisticsAppService.java` `document/appservice/IDocRecordAppService.java` `document/appservice/IDocTemplateAppService.java`
|
||||
- **ServiceImpl**: `document/appservice/impl/DocStatisticsDefinitionAppServiceImpl.java` `document/appservice/impl/DocRecordAppServiceImpl.java` `document/appservice/impl/DocStatisticsAppServiceImpl.java`
|
||||
- **Mapper**: `document/mapper/DocRecordAppMapper.java` `document/mapper/DocStatisticsDefinitionAppMapper.java` `document/mapper/DocDefinitionAppMapper.java`
|
||||
- **DTO**: `document/dto/DocStatisticsDefinitionDto.java` `document/dto/DocRecordPatientQueryParam.java` `document/dto/DocDefinitionOrganizationDto.java` `document/dto/DocRecordDto.java` `document/dto/DocTemplateDto.java`
|
||||
|
||||
### `empi` (5 files)
|
||||
- **Controller**: `empi/controller/EmpiController.java` `empi/controller/EmpiIdVerificationController.java` `empi/controller/EmpiEnhancedController.java`
|
||||
- **AppService**: `empi/appservice/IEmpiAppService.java`
|
||||
- **ServiceImpl**: `empi/appservice/impl/EmpiAppServiceImpl.java`
|
||||
|
||||
### `emr` (6 files)
|
||||
- **Controller**: `emr/controller/EmrArchiveController.java` `emr/controller/StructuredEmrController.java` `emr/controller/EmrRevisionController.java`
|
||||
- **AppService**: `emr/appservice/IStructuredEmrAppService.java`
|
||||
- **ServiceImpl**: `emr/appservice/impl/StructuredEmrAppServiceImpl.java`
|
||||
|
||||
### `epidemic` (3 files)
|
||||
- **Controller**: `epidemic/controller/EpidemicController.java`
|
||||
- **AppService**: `epidemic/appservice/IEpidemicAppService.java`
|
||||
- **ServiceImpl**: `epidemic/appservice/impl/EpidemicAppServiceImpl.java`
|
||||
|
||||
### `esbmanage` (4 files)
|
||||
- **Controller**: `esbmanage/controller/EsbReliabilityController.java` `esbmanage/controller/EsbMessageController.java` `esbmanage/controller/EsbServiceRegistryController.java`
|
||||
|
||||
### `externalintegration` (18 files)
|
||||
- **Controller**: `externalintegration/controller/FoodborneAcquisitionAppController.java`
|
||||
- **AppService**: `externalintegration/appservice/IBankPosCloudAppService.java` `externalintegration/appservice/IFoodborneAcquisitionAppService.java`
|
||||
- **ServiceImpl**: `externalintegration/appservice/impl/FoodborneAcquisitionAppServiceImpl.java` `externalintegration/appservice/impl/BankPosCloudAppServiceImpl.java`
|
||||
- **Mapper**: `externalintegration/mapper/FoodborneAcquisitionAppMapper.java`
|
||||
- **DTO**: `externalintegration/dto/BpcTransactionResponseDto.java` `externalintegration/dto/BpcPaymentScanNotifyDto.java` `externalintegration/dto/FaSimplediseaseAddNopwParam.java` `externalintegration/dto/BpcTransactionRequestDto.java` `externalintegration/dto/BpcDataElementDto.java`
|
||||
|
||||
### `infection` (4 files)
|
||||
- **Controller**: `infection/controller/InfectionEnhancedController.java` `infection/controller/InfectionController.java`
|
||||
- **AppService**: `infection/appservice/IInfectionAppService.java`
|
||||
- **ServiceImpl**: `infection/appservice/impl/InfectionAppServiceImpl.java`
|
||||
|
||||
### `inhospitalcharge` (17 files)
|
||||
- **Controller**: `inhospitalcharge/controller/AdvancePaymentManageController.java` `inhospitalcharge/controller/InHospitalRegisterController.java`
|
||||
- **AppService**: `inhospitalcharge/appservice/IInHospitalRegisterAppService.java` `inhospitalcharge/appservice/IAdvancePaymentManageAppService.java`
|
||||
- **ServiceImpl**: `inhospitalcharge/appservice/impl/AdvancePaymentManageAppServiceImpl.java` `inhospitalcharge/appservice/impl/InHospitalRegisterAppServiceImpl.java`
|
||||
- **Mapper**: `inhospitalcharge/mapper/InHospitalRegisterAppMapper.java` `inhospitalcharge/mapper/AdvancePaymentManageAppMapper.java`
|
||||
- **DTO**: `inhospitalcharge/dto/AdvancePaymentInAndOutDto.java` `inhospitalcharge/dto/PatientUpdateDto.java` `inhospitalcharge/dto/NoFilesRegisterDto.java` `inhospitalcharge/dto/InHospitalPatientInfoDto.java` `inhospitalcharge/dto/InHospitalRegisterQueryDto.java`
|
||||
|
||||
### `inhospitalnursestation` (52 files)
|
||||
- **Controller**: `inhospitalnursestation/controller/AdviceProcessController.java` `inhospitalnursestation/controller/NurseBillingController.java` `inhospitalnursestation/controller/EncounterAutoRollAppController.java`
|
||||
- **AppService**: `inhospitalnursestation/appservice/IOrgDeviceStockTakeAppService.java` `inhospitalnursestation/appservice/IAdviceProcessAppService.java` `inhospitalnursestation/appservice/INurseBillingAppService.java`
|
||||
- **ServiceImpl**: `inhospitalnursestation/appservice/impl/OrgDeviceStockTakeAppServiceImpl.java` `inhospitalnursestation/appservice/impl/ATDManageAppServiceImpl.java` `inhospitalnursestation/appservice/impl/EncounterAutoRollAppServiceImpl.java`
|
||||
- **Mapper**: `inhospitalnursestation/mapper/ATDManageAppMapper.java` `inhospitalnursestation/mapper/EncounterAutoRollAppMapper.java` `inhospitalnursestation/mapper/MedicineSummaryAppMapper.java`
|
||||
- **DTO**: `inhospitalnursestation/dto/AdmissionBedPageDto.java` `inhospitalnursestation/dto/AdviceExecuteParam.java` `inhospitalnursestation/dto/InpatientAdviceParam.java` `inhospitalnursestation/dto/DispenseFormSearchParam.java` `inhospitalnursestation/dto/AutoRollNursingDto.java`
|
||||
|
||||
### `inpatientmanage` (40 files)
|
||||
- **Controller**: `inpatientmanage/controller/NursingVitalSignsChartController.java` `inpatientmanage/controller/VitalSignsController.java` `inpatientmanage/controller/PatientHomeController.java`
|
||||
- **AppService**: `inpatientmanage/appservice/IPatientHomeAppService.java` `inpatientmanage/appservice/IDepositAppService.java` `inpatientmanage/appservice/INursingRecordAppService.java`
|
||||
- **ServiceImpl**: `inpatientmanage/appservice/impl/DepositAppServiceImpl.java` `inpatientmanage/appservice/impl/NursingRecordAppServiceImpl.java` `inpatientmanage/appservice/impl/PatientHomeAppServiceImpl.java`
|
||||
- **Mapper**: `inpatientmanage/mapper/VitalSignsAppMapper.java` `inpatientmanage/mapper/DepositMapper.java` `inpatientmanage/mapper/NursingRecordAppMapper.java`
|
||||
- **DTO**: `inpatientmanage/dto/DepositDetailDto.java` `inpatientmanage/dto/VitalSignsChartSmallDto.java` `inpatientmanage/dto/VitalSignsSaveDto.java` `inpatientmanage/dto/PatientHomeSearchParam.java` `inpatientmanage/dto/PatientHomeEmptyBedDto.java`
|
||||
|
||||
### `inventorymanage` (107 files)
|
||||
- **Controller**: `inventorymanage/controller/PurchaseReturnController.java` `inventorymanage/controller/InventorySettlementController.java` `inventorymanage/controller/ReturnIssueController.java`
|
||||
- **AppService**: `inventorymanage/appservice/IProductStocktakingAppService.java` `inventorymanage/appservice/IInventoryDetailsAppService.java` `inventorymanage/appservice/IReturnIssueAppService.java`
|
||||
- **ServiceImpl**: `inventorymanage/appservice/impl/InventoryDetailsAppServiceImpl.java` `inventorymanage/appservice/impl/ProductTransferAppServiceImpl.java` `inventorymanage/appservice/impl/ReceiptApprovalAppServiceImpl.java`
|
||||
- **Mapper**: `inventorymanage/mapper/ProductDetailAppMapper.java` `inventorymanage/mapper/RequisitionIssueMapper.java` `inventorymanage/mapper/PurchaseReturnMapper.java`
|
||||
- **DTO**: `inventorymanage/dto/ProductTransferPageDto.java` `inventorymanage/dto/PurchaseInventoryDto.java` `inventorymanage/dto/ReceiptDetailDto.java` `inventorymanage/dto/RequisitionOutDetailDto.java` `inventorymanage/dto/InventoryReceiptDetailDto.java`
|
||||
|
||||
### `jlau` (5 files)
|
||||
- **Controller**: `jlau/controller/ReviewPrescriptionRecordsController.java`
|
||||
- **AppService**: `jlau/appservice/IReviewPrescriptionRecordsAppService.java`
|
||||
- **ServiceImpl**: `jlau/appservice/impl/ReviewPrescriptionRecordsAppServiceImpl.java`
|
||||
- **Mapper**: `jlau/mapper/ReviewPrescriptionRecordsAppMapper.java`
|
||||
- **DTO**: `jlau/dto/ReviewPrescriptionRecordsDto.java`
|
||||
|
||||
### `lab` (7 files)
|
||||
- **Controller**: `lab/controller/LabActivityDefinitionController.java` `lab/controller/LabHistoryController.java` `lab/controller/LabEnhancedController.java`
|
||||
- **AppService**: `lab/appservice/ILabActivityDefinitionAppService.java`
|
||||
- **ServiceImpl**: `lab/appservice/impl/LabActivityDefinitionAppServiceImpl.java`
|
||||
|
||||
### `materialmanage` (46 files)
|
||||
- **Controller**: `materialmanage/controller/MaterialReturnOrderController.java` `materialmanage/controller/MaterialTransferInOrderController.java` `materialmanage/controller/MaterialTransferOutOrderController.java`
|
||||
- **ServiceImpl**: `materialmanage/appservice/impl/MaterialPurchaseOrderServiceImpl.java` `materialmanage/appservice/impl/MaterialTransferOutOrderServiceImpl.java` `materialmanage/appservice/impl/MaterialReturnToWarehouseOrderServiceImpl.java`
|
||||
- **Mapper**: `materialmanage/mapper/MaterialCommonMapper.java` `materialmanage/mapper/MaterialProfitLossOrderMapper.java` `materialmanage/mapper/MaterialTransferOutOrderMapper.java`
|
||||
- **DTO**: `materialmanage/dto/MaterialInitDto.java` `materialmanage/dto/MaterialSearchParam.java` `materialmanage/dto/MaterialDto.java` `materialmanage/dto/MaterialDetailDto.java` `materialmanage/dto/MaterialDeviceInfoDto.java`
|
||||
|
||||
### `mrhomepage` (6 files)
|
||||
- **Controller**: `mrhomepage/controller/DrgAnalysisController.java` `mrhomepage/controller/MrManagementController.java` `mrhomepage/controller/MrHomepageController.java`
|
||||
- **AppService**: `mrhomepage/appservice/IMrHomepageAppService.java`
|
||||
- **ServiceImpl**: `mrhomepage/appservice/impl/MrHomepageAppServiceImpl.java`
|
||||
|
||||
### `nenu` (22 files)
|
||||
- **Controller**: `nenu/controller/GfRatioApplicationRecordController.java` `nenu/controller/GfStudentListController.java` `nenu/controller/GfRatioManageController.java`
|
||||
- **AppService**: `nenu/appservice/IGfRatioManageAppService.java` `nenu/appservice/IGfRatioApplicationRecordAppService.java` `nenu/appservice/IGfStudentListAppService.java`
|
||||
- **ServiceImpl**: `nenu/appservice/impl/GfRatioApplicationRecordAppServiceImpl.java` `nenu/appservice/impl/GfRatioManageAppServiceImpl.java` `nenu/appservice/impl/GfStudentListAppServiceImpl.java`
|
||||
- **Mapper**: `nenu/mapper/GfStudentListAppMapper.java` `nenu/mapper/GfRatioManageAppMapper.java` `nenu/mapper/GfRatioApplicationRecordAppMapper.java`
|
||||
- **DTO**: `nenu/dto/GfIndividualRatioDto.java` `nenu/dto/GfRatioApplicationRecordDto.java` `nenu/dto/GfStudentListImportDto.java` `nenu/dto/GfRatioApplicationProcessDto.java` `nenu/dto/GfStudentPeisDto.java`
|
||||
|
||||
### `nursing` (8 files)
|
||||
- **Controller**: `nursing/controller/NursingExecutionController.java` `nursing/controller/NursingAssessmentEnhancedController.java` `nursing/controller/NursingEnhancedController.java`
|
||||
- **AppService**: `nursing/appservice/INursingAppService.java`
|
||||
- **ServiceImpl**: `nursing/appservice/impl/NursingAppServiceImpl.java`
|
||||
|
||||
### `orderclosedloop` (3 files)
|
||||
- **Controller**: `orderclosedloop/controller/OrderClosedLoopController.java`
|
||||
- **AppService**: `orderclosedloop/appservice/IOrderClosedLoopAppService.java`
|
||||
- **ServiceImpl**: `orderclosedloop/appservice/impl/OrderClosedLoopAppServiceImpl.java`
|
||||
|
||||
### `outpatientmanage` (22 files)
|
||||
- **Controller**: `outpatientmanage/controller/OutpatientTreatmentController.java` `outpatientmanage/controller/OutpatientSkinTestAppController.java` `outpatientmanage/controller/OutpatientInfusionController.java`
|
||||
- **AppService**: `outpatientmanage/appservice/IOutpatientTreatmentAppService.java` `outpatientmanage/appservice/IOutpatientInfusionAppService.java` `outpatientmanage/appservice/IOutpatientSkinTestAppService.java`
|
||||
- **ServiceImpl**: `outpatientmanage/appservice/impl/OutpatientTreatmentAppServiceImpl.java` `outpatientmanage/appservice/impl/OutpatientSkinTestAppServiceImpl.java` `outpatientmanage/appservice/impl/OutpatientInfusionAppServiceImpl.java`
|
||||
- **Mapper**: `outpatientmanage/mapper/OutpatientTreatmentAppMapper.java` `outpatientmanage/mapper/OutpatientInfusionAppMapper.java` `outpatientmanage/mapper/OutpatientSkinTestAppMapper.java`
|
||||
- **DTO**: `outpatientmanage/dto/SkinTestMedLotNumberDto.java` `outpatientmanage/dto/OutpatientInfusionRecordDto.java` `outpatientmanage/dto/SkinTestSaveDto.java` `outpatientmanage/dto/OutpatientTreatmentInfoDto.java` `outpatientmanage/dto/OutpatientStationInitDto.java`
|
||||
|
||||
### `patientmanage` (13 files)
|
||||
- **Controller**: `patientmanage/controller/PatientInformationController.java` `patientmanage/controller/OutpatientRecordController.java`
|
||||
- **ServiceImpl**: `patientmanage/appservice/impl/OutpatientRecordServiceImpl.java` `patientmanage/appservice/impl/PatientInformationServiceImpl.java`
|
||||
- **Mapper**: `patientmanage/mapper/PatientManageMapper.java`
|
||||
- **DTO**: `patientmanage/dto/PatientInfoInitDto.java` `patientmanage/dto/PatientIdInfoDto.java` `patientmanage/dto/OutpatientRecordSearchParam.java` `patientmanage/dto/PatientBaseInfoDto.java` `patientmanage/dto/OutpatientRecordDto.java`
|
||||
|
||||
### `paymentmanage` (57 files)
|
||||
- **Controller**: `paymentmanage/controller/EleInvoiceController.java` `paymentmanage/controller/ChargeBillController.java` `paymentmanage/controller/PaymentContractController.java`
|
||||
- **ServiceImpl**: `paymentmanage/appservice/impl/PaymentRecServiceImpl.java` `paymentmanage/appservice/impl/IChargeBillServiceImpl.java` `paymentmanage/appservice/impl/EleInvoiceServiceImpl.java`
|
||||
- **Mapper**: `paymentmanage/mapper/EleInvoiceMapper.java` `paymentmanage/mapper/ThreePartPayMapper.java` `paymentmanage/mapper/ChangePriceMapper.java`
|
||||
- **DTO**: `paymentmanage/dto/NenuBpcPayDto.java` `paymentmanage/dto/EleInvoiceResultDto.java` `paymentmanage/dto/ChargeSummaryDto.java` `paymentmanage/dto/EleInvoicePaymentInfoDto.java` `paymentmanage/dto/Clinic2207OrderResultInfoDto.java`
|
||||
|
||||
### `personalization` (22 files)
|
||||
- **Controller**: `personalization/controller/ActivityDeviceController.java` `personalization/controller/OrdersGroupPackageController.java` `personalization/controller/OrderGroupController.java`
|
||||
- **AppService**: `personalization/appservice/IOrderGroupAppService.java` `personalization/appservice/IOrdersGroupPackageAppService.java` `personalization/appservice/IActivityDeviceAppService.java`
|
||||
- **ServiceImpl**: `personalization/appservice/impl/OrdersGroupPackageAppServiceImpl.java` `personalization/appservice/impl/ActivityDeviceAppServiceImpl.java` `personalization/appservice/impl/IOrderGroupAppServiceImpl.java`
|
||||
- **Mapper**: `personalization/mapper/OrdersGroupPackageAppMapper.java` `personalization/mapper/OrderGroupAppMapper.java` `personalization/mapper/ActivityDeviceAppMapper.java`
|
||||
- **DTO**: `personalization/dto/OrdersGroupPackageDetailSaveDto.java` `personalization/dto/OrderGroupDto.java` `personalization/dto/OrdersGroupPackageDto.java` `personalization/dto/OrderGroupInitDto.java` `personalization/dto/OrdersGroupPackageDetailQueryDto.java`
|
||||
|
||||
### `pharmacyDispensarymanage` (42 files)
|
||||
- **Controller**: `pharmacyDispensarymanage/controller/PharmacyDispensaryTransferOutOrderController.java` `pharmacyDispensarymanage/controller/PharmacyDispensaryDispensingOrderController.java` `pharmacyDispensarymanage/controller/PharmacyDispensaryStocktakingOrderController.java`
|
||||
- **ServiceImpl**: `pharmacyDispensarymanage/appservice/impl/PharmacyDispensaryStocktakingOrderServiceImpl.java` `pharmacyDispensarymanage/appservice/impl/PharmacyDispensaryTransferInOrderServiceImpl.java` `pharmacyDispensarymanage/appservice/impl/PharmacyDispensaryStockInOrderServiceImpl.java`
|
||||
- **Mapper**: `pharmacyDispensarymanage/mapper/PharmacyDispensaryReturnToWarehouseOrderMapper.java` `pharmacyDispensarymanage/mapper/PharmacyDispensaryTransferOutOrderMapper.java` `pharmacyDispensarymanage/mapper/PharmacyDispensaryRequisitionOrderMapper.java`
|
||||
- **DTO**: `pharmacyDispensarymanage/dto/PharmacyDispensaryDto.java` `pharmacyDispensarymanage/dto/PharmacyDispensaryDetailDto.java` `pharmacyDispensarymanage/dto/PharmacyDispensarySearchParam.java` `pharmacyDispensarymanage/dto/PharmacyDispensaryMedicationInfoDto.java` `pharmacyDispensarymanage/dto/PharmacyDispensaryInitDto.java`
|
||||
|
||||
### `pharmacyWarehousemanage` (42 files)
|
||||
- **Controller**: `pharmacyWarehousemanage/controller/PharmacyWarehouseProfitLossOrderController.java` `pharmacyWarehousemanage/controller/PharmacyWarehouseReturnToWarehouseOrderController.java` `pharmacyWarehousemanage/controller/PharmacyWarehouseStockOutOrderController.java`
|
||||
- **ServiceImpl**: `pharmacyWarehousemanage/appservice/impl/PharmacyWarehousePurchaseOrderServiceImpl.java` `pharmacyWarehousemanage/appservice/impl/PharmacyWarehouseDocumentManagementServiceImpl.java` `pharmacyWarehousemanage/appservice/impl/PharmacyWarehouseProfitLossOrderServiceImpl.java`
|
||||
- **Mapper**: `pharmacyWarehousemanage/mapper/PharmacyWarehousePurchaseOrderMapper.java` `pharmacyWarehousemanage/mapper/PharmacyWarehouseDocumentManagementMapper.java` `pharmacyWarehousemanage/mapper/PharmacyWarehouseStockInOrderMapper.java`
|
||||
- **DTO**: `pharmacyWarehousemanage/dto/PharmacyWarehouseDto.java` `pharmacyWarehousemanage/dto/PharmacyWarehouseDetailDto.java` `pharmacyWarehousemanage/dto/PharmacyWarehouseMedicationInfoDto.java` `pharmacyWarehousemanage/dto/PharmacyWarehouseInitDto.java` `pharmacyWarehousemanage/dto/PharmacyWarehouseSearchParam.java`
|
||||
|
||||
### `pharmacymanage` (53 files)
|
||||
- **Controller**: `pharmacymanage/controller/InHospitalReturnMedicineController.java` `pharmacymanage/controller/PharmacyStockAlertController.java` `pharmacymanage/controller/MedicationDetailsController.java`
|
||||
- **AppService**: `pharmacymanage/appservice/ISummaryDispenseMedicineAppService.java` `pharmacymanage/appservice/IPendingMedicationDetailsAppService.java` `pharmacymanage/appservice/IInHospitalReturnMedicineAppService.java`
|
||||
- **ServiceImpl**: `pharmacymanage/appservice/impl/ReturnMedicineAppServiceImpl.java` `pharmacymanage/appservice/impl/MedicationDetailsAppServiceImpl.java` `pharmacymanage/appservice/impl/WesternMedicineDispenseAppServiceImpl.java`
|
||||
- **Mapper**: `pharmacymanage/mapper/PendingMedicationDetailsMapper.java` `pharmacymanage/mapper/MedicalDeviceDispenseMapper.java` `pharmacymanage/mapper/SummaryDispenseMedicineMapper.java`
|
||||
- **DTO**: `pharmacymanage/dto/MedDetailsInitDto.java` `pharmacymanage/dto/EncounterInfoSearchParam.java` `pharmacymanage/dto/ItemDispenseOrderDto.java` `pharmacymanage/dto/MedicineSummaryDto.java` `pharmacymanage/dto/MedicineSummarySearchParam.java`
|
||||
|
||||
### `quality` (5 files)
|
||||
- **Controller**: `quality/controller/BusinessAnalyticsController.java` `quality/controller/QualityEnhancedController.java` `quality/controller/EmrQualityController.java`
|
||||
- **AppService**: `quality/appservice/IEmrQualityAppService.java`
|
||||
- **ServiceImpl**: `quality/appservice/impl/EmrQualityAppServiceImpl.java`
|
||||
|
||||
### `rationaldrug` (3 files)
|
||||
- **Controller**: `rationaldrug/controller/RationalDrugController.java`
|
||||
- **AppService**: `rationaldrug/appservice/IRationalDrugAppService.java`
|
||||
- **ServiceImpl**: `rationaldrug/appservice/impl/RationalDrugAppServiceImpl.java`
|
||||
|
||||
### `regdoctorstation` (38 files)
|
||||
- **Controller**: `regdoctorstation/controller/NurseManageController.java` `regdoctorstation/controller/AdviceManageController.java` `regdoctorstation/controller/SpecialAdviceController.java`
|
||||
- **AppService**: `regdoctorstation/appservice/IAdviceManageAppService.java` `regdoctorstation/appservice/IRequestFormManageAppService.java` `regdoctorstation/appservice/ISpecialAdviceAppService.java`
|
||||
- **ServiceImpl**: `regdoctorstation/appservice/impl/SpecialAdviceAppServiceImpl.java` `regdoctorstation/appservice/impl/RequestFormManageAppServiceImpl.java` `regdoctorstation/appservice/impl/NurseManageServiceImpl.java`
|
||||
- **Mapper**: `regdoctorstation/mapper/RequestFormManageAppMapper.java` `regdoctorstation/mapper/AdviceManageAppMapper.java` `regdoctorstation/mapper/SpecialAdviceAppMapper.java`
|
||||
- **DTO**: `regdoctorstation/dto/RegPatientMainInfoDto.java` `regdoctorstation/dto/NursingOrdersDetailDto.java` `regdoctorstation/dto/LeaveHospitalParam.java` `regdoctorstation/dto/NursingOrdersSaveDto.java` `regdoctorstation/dto/NursingOrdersEncounterDto.java`
|
||||
|
||||
### `reportManagement` (11 files)
|
||||
- **Controller**: `reportManagement/controller/reportManagementController.java`
|
||||
- **AppService**: `reportManagement/appservice/IInfectiousCardAppService.java`
|
||||
- **ServiceImpl**: `reportManagement/appservice/impl/InfectiousCardAppServiceImpl.java`
|
||||
- **Mapper**: `reportManagement/mapper/ReportManageCardMapper.java`
|
||||
- **DTO**: `reportManagement/dto/InfectiousCardDto.java` `reportManagement/dto/InfectiousCardParam.java`
|
||||
|
||||
### `reportmanage` (164 files)
|
||||
- **Controller**: `reportmanage/controller/AmbAdviceStatisticsAppController.java` `reportmanage/controller/MonthlySettlementController.java` `reportmanage/controller/PurchaseReturnReportController.java`
|
||||
- **AppService**: `reportmanage/appservice/PurchaseReturnReportAppService.java` `reportmanage/appservice/IDrugDosageSettlementAppService.java` `reportmanage/appservice/IDepartmentRevenueStatisticsAppService.java`
|
||||
- **ServiceImpl**: `reportmanage/appservice/impl/InboundReportAppServiceImpl.java` `reportmanage/appservice/impl/MedicationInboundReportAppServiceImpl.java` `reportmanage/appservice/impl/ReportStatisticsAppServiceImpl.java`
|
||||
- **Mapper**: `reportmanage/mapper/PrintReportMapper.java` `reportmanage/mapper/ReportStatisticsMapper.java` `reportmanage/mapper/LossReportMapper.java`
|
||||
- **DTO**: `reportmanage/dto/ReportDiseaseDetailsDto.java` `reportmanage/dto/InboundReportSearchParam.java` `reportmanage/dto/InpatientMedicalRecordHomePageCollectionDto.java` `reportmanage/dto/ZyCostDetailParam.java` `reportmanage/dto/BottleLabelDto.java`
|
||||
|
||||
### `review` (3 files)
|
||||
- **Controller**: `review/controller/ReviewController.java`
|
||||
- **AppService**: `review/appservice/IReviewAppService.java`
|
||||
- **ServiceImpl**: `review/appservice/impl/ReviewAppServiceImpl.java`
|
||||
|
||||
### `service` (2 files)
|
||||
- **ServiceImpl**: `service/impl/HomeStatisticsServiceImpl.java`
|
||||
|
||||
### `system` (5 files)
|
||||
- **Controller**: `system/controller/ApiAuthController.java` `system/controller/DashboardController.java` `system/controller/SysAuditLogController.java`
|
||||
|
||||
### `tcm` (3 files)
|
||||
- **Controller**: `tcm/controller/TcmController.java`
|
||||
- **AppService**: `tcm/appservice/ITcmAppService.java`
|
||||
- **ServiceImpl**: `tcm/appservice/impl/TcmAppServiceImpl.java`
|
||||
|
||||
### `tencentJH` (13 files)
|
||||
- **Controller**: `tencentJH/controller/TencentController.java`
|
||||
- **AppService**: `tencentJH/appservice/ITencentAppService.java`
|
||||
- **ServiceImpl**: `tencentJH/appservice/impl/TencentAppServiceImpl.java`
|
||||
- **Mapper**: `tencentJH/mapper/TencentAppMapper.java`
|
||||
- **DTO**: `tencentJH/dto/PatientInfoTencentDto.java` `tencentJH/dto/CurrentDayEncounterTencentDto.java`
|
||||
|
||||
### `triageandqueuemanage` (13 files)
|
||||
- **Controller**: `triageandqueuemanage/controller/CallNumberVoiceConfigController.java` `triageandqueuemanage/controller/TriageQueueController.java`
|
||||
- **AppService**: `triageandqueuemanage/appservice/CallNumberVoiceConfigAppService.java` `triageandqueuemanage/appservice/TriageQueueAppService.java`
|
||||
- **ServiceImpl**: `triageandqueuemanage/appservice/impl/CallNumberVoiceConfigAppServiceImpl.java` `triageandqueuemanage/appservice/impl/TriageQueueAppServiceImpl.java`
|
||||
- **Mapper**: `triageandqueuemanage/mapper/CallNumberVoiceConfigAppMapper.java`
|
||||
|
||||
### `ybmanage` (55 files)
|
||||
- **Controller**: `ybmanage/controller/YbInpatientController.java` `ybmanage/controller/YbElepController.java` `ybmanage/controller/YbController.java`
|
||||
- **ServiceImpl**: `ybmanage/service/impl/YbEleHttpServiceImpl.java` `ybmanage/service/impl/YbServiceImpl.java` `ybmanage/service/impl/YbElepBaseServiceImpl.java`
|
||||
- **Mapper**: `ybmanage/mapper/YbElepMapper.java` `ybmanage/mapper/YbMapper.java`
|
||||
- **DTO**: `ybmanage/dto/FinancialHand3203AWebParam.java` `ybmanage/dto/FinancialHand3201WebParam.java` `ybmanage/dto/Financial13203WebParam.java` `ybmanage/dto/VeriPrescriptionInfoDto.java` `ybmanage/dto/YbInHospitalRegisterQueryDto.java`
|
||||
|
||||
## 前端关键文件
|
||||
|
||||
| 目录 | 说明 |
|
||||
|---|---|
|
||||
| `src/utils/request.js` | Axios 请求/响应拦截器 |
|
||||
| `src/api/` | API 接口定义 |
|
||||
| `src/components/` | 公共组件 |
|
||||
| `src/views/doctorstation/` | 门诊医生站 |
|
||||
| `src/views/inpatientDoctor/` | 住院医生站 |
|
||||
| `src/views/inpatientNurse/` | 住院护士站 |
|
||||
| `src/views/charge/` | 收费工作站 |
|
||||
| `src/views/datadictionary/` | 数据字典 |
|
||||
| `src/views/system/` | 系统管理 |
|
||||
|
||||
## 公共/通用文件
|
||||
|
||||
- `com.core.common.core.domain.R` — 统一响应封装
|
||||
- `com.core.common.core.domain.entity.SysDictData` — 字典数据实体
|
||||
- `com.core.common.utils.SecurityUtils` — 安全工具(获取当前用户)
|
||||
- `com.core.common.enums.*` — 枚举定义
|
||||
- `com.healthlink.his.common.constant.CommonConstants` — 公共常量
|
||||
- `com.healthlink.his.common.utils.HisQueryUtils` — 查询工具
|
||||
- `com.healthlink.his.common.utils.HisPageUtils` — 分页工具
|
||||
- `com.healthlink.his.web.doctorstation.utils.AdviceUtils` — 医嘱工具类
|
||||
|
||||
|
||||
=== 已生成 421 行索引 ===
|
||||
34
MD/bugs/BUG_648_ANALYSIS.md
Normal file
34
MD/bugs/BUG_648_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #648 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:56:11
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 648
|
||||
- **标题**: 【住院医生工作站】临床医嘱下的手术按钮点击,不会出现报卡
|
||||
- **模块**: 住院医生工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd67-df3d-7c71-bf6d-30f90a80ea57"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_651_ANALYSIS.md
Normal file
34
MD/bugs/BUG_651_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #651 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:54:57
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 651
|
||||
- **标题**: [住院医生站-手术申请] 无法检索出已启用的手术项目(如:“血管闭合切割刀”)
|
||||
- **模块**: 住院医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd66-bbbc-7e51-baa6-21fce84ded9d"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_653_ANALYSIS.md
Normal file
34
MD/bugs/BUG_653_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #653 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:53:31
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 653
|
||||
- **标题**: [住院医生站-临床医嘱] 医嘱录入界面“给药途径”下拉列表及显示值包含冗余数字编码
|
||||
- **模块**: 住院医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd65-58c3-79b2-a2ee-dbce445061dc"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_655_ANALYSIS.md
Normal file
34
MD/bugs/BUG_655_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #655 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:52:03
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 655
|
||||
- **标题**: [门诊医生站-检查开单] 检查申请保存后总金额结算异常,未累加“检查方法”附加金额
|
||||
- **模块**: 门诊医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd64-16c7-7581-9c6d-677e3ea9d50e"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_656_ANALYSIS.md
Normal file
34
MD/bugs/BUG_656_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #656 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:50:34
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 656
|
||||
- **标题**: [门诊医生站-检查申请] 单击已保存记录回显异常:自动跳转页签错误且“检查方法”数据未回显
|
||||
- **模块**: 门诊医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd62-b87a-7a20-9007-a4f7f3d0221f"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_657_ANALYSIS.md
Normal file
34
MD/bugs/BUG_657_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #657 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:48:58
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 657
|
||||
- **标题**: [门诊医生站-检查申请] “检查明细”页签数据展示异常:检查方法未回显且单价/金额计算错误
|
||||
- **模块**: 门诊医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd61-420f-7202-a12d-5658faf3a782"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_659_ANALYSIS.md
Normal file
34
MD/bugs/BUG_659_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #659 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:47:35
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 659
|
||||
- **标题**: 【住院管理-住院护士站】选择了患者还提示叫你选择患者
|
||||
- **模块**: 病区护士工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd5f-ee1b-7cf3-a1e1-02052bc2e994"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_660_ANALYSIS.md
Normal file
34
MD/bugs/BUG_660_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #660 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:46:08
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 660
|
||||
- **标题**: 【分诊排队管理-智能分诊排队管理】加入队列失败
|
||||
- **模块**: 分诊排队管理
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd5e-9721-70a3-840f-c408e2899450"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_661_ANALYSIS.md
Normal file
34
MD/bugs/BUG_661_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #661 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:45:14
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 661
|
||||
- **标题**: 【住院管理-住院护士站】选择一名患者进行换床会出现报卡且报错
|
||||
- **模块**: 病区护士工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd5d-c771-78a0-ab9a-d6761a97bfbc"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_662_ANALYSIS.md
Normal file
34
MD/bugs/BUG_662_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #662 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:44:13
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 662
|
||||
- **标题**: 【住院管理-住院护士站】在医嘱校对中的已停止字段没有对应的已停止按钮
|
||||
- **模块**: 病区护士工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd5c-d876-7242-9774-ec5a26b7610c"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_664_ANALYSIS.md
Normal file
34
MD/bugs/BUG_664_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #664 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:43:05
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 664
|
||||
- **标题**: 【住院管理-住院护士站】医嘱执行中的取消执行无法点击
|
||||
- **模块**: 病区护士工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd5b-cf04-7930-9cbf-a075148435d6"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_665_ANALYSIS.md
Normal file
34
MD/bugs/BUG_665_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #665 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:41:42
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 665
|
||||
- **标题**: 【收费工作站-门诊挂号】当日已挂号,界面加载卡死
|
||||
- **模块**: 收费工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd5a-999f-7131-9cff-376ffdbca994"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_666_ANALYSIS.md
Normal file
34
MD/bugs/BUG_666_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #666 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:40:37
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 666
|
||||
- **标题**: [门诊-发药管理] 药品已完成收费但“门诊发药”模块无法检索到患者信息,导致无法实现发药逻辑
|
||||
- **模块**: 门诊药房管理
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd59-9d9a-7033-860f-1f9bb39e8335"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_667_ANALYSIS.md
Normal file
34
MD/bugs/BUG_667_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #667 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:39:11
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 667
|
||||
- **标题**: [门诊收费-业务流程] 医嘱未挂钩【完诊】状态,医生未终结门诊即可提前在收费端结算,存在漏开/错开费用风险
|
||||
- **模块**: 门诊收费管理
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd58-3b49-78a0-bc30-4aa9e6a0867c"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_668_ANALYSIS.md
Normal file
34
MD/bugs/BUG_668_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #668 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:37:37
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 668
|
||||
- **标题**: [门诊医生站-中医处方] 点击【签发】按钮系统崩溃,提示“element cannot be mapped to a null key”
|
||||
- **模块**: 门诊医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd56-cdbd-7993-b9ec-de7f1c2cf84b"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_669_ANALYSIS.md
Normal file
34
MD/bugs/BUG_669_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #669 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:36:00
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 669
|
||||
- **标题**: [门诊医生站-中医处方] 中医处方头信息(费用性质、频次、天数、付数等)在保存并重新进入后回显为空
|
||||
- **模块**: 门诊医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd55-51d4-7a52-bc60-168bba962fff"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_670_ANALYSIS.md
Normal file
34
MD/bugs/BUG_670_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #670 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:34:28
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 670
|
||||
- **标题**: [门诊医生站-中医处方] “煎药方式”与“特殊煎法”下拉框数据为空,未能调用字典管理数据
|
||||
- **模块**: 门诊医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd53-fbb0-7cb1-a270-c561f87c0d0a"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_671_ANALYSIS.md
Normal file
34
MD/bugs/BUG_671_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #671 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:32:13
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 671
|
||||
- **标题**: [门诊医生站-医嘱] 列表字段定义错误:“退回原因”应变更为“备注”并正确回显录入内容
|
||||
- **模块**: 门诊医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd51-db08-7f40-9733-ba8443073467"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_672_ANALYSIS.md
Normal file
34
MD/bugs/BUG_672_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #672 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:30:04
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 672
|
||||
- **标题**: [门诊医生站-诊断] 新增中医诊断保存后,列表中“发病日期”、“诊断日期”和“医生”字段显示为空
|
||||
- **模块**: 门诊医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd4f-e1ab-7c50-9afd-f9606ce9d862"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_673_ANALYSIS.md
Normal file
34
MD/bugs/BUG_673_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #673 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:28:21
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 673
|
||||
- **标题**: 【收费工作站-门诊挂号】挂号列表排版错乱
|
||||
- **模块**: 收费工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd4e-6113-73a0-804e-fe1a2937d45f"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_674_ANALYSIS.md
Normal file
34
MD/bugs/BUG_674_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #674 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:27:13
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 674
|
||||
- **标题**: 【住院管理-住院医生工作站】在临床医嘱的签发失效
|
||||
- **模块**: 住院医生工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd4d-58dc-7ac0-8588-e329ed1d71e3"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_675_ANALYSIS.md
Normal file
34
MD/bugs/BUG_675_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #675 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:25:50
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 675
|
||||
- **标题**: [门诊医生站-检查申请] “检查方法”字段缺少必填标识却执行了强校验逻辑
|
||||
- **模块**: 门诊医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd4c-154d-7fc3-bfe2-8d1c1233ae5c"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_676_ANALYSIS.md
Normal file
34
MD/bugs/BUG_676_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #676 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:24:48
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 676
|
||||
- **标题**: [住院医生站-临床医嘱] 勾选“待签发”临时医嘱后,点击【签发】按钮无响应
|
||||
- **模块**: 住院医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd4b-0f4d-7073-8f70-c6d403872519"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_678_ANALYSIS.md
Normal file
34
MD/bugs/BUG_678_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #678 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:23:07
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 678
|
||||
- **标题**: 【住院医生工作站】诊断录入中的诊断类别无法选择数据
|
||||
- **模块**: 住院医生工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd49-8574-7243-a5a0-60adcf729dcf"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_679_ANALYSIS.md
Normal file
34
MD/bugs/BUG_679_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #679 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:21:52
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 679
|
||||
- **标题**: [住院医生站-临床医嘱] 新增项目点击“确定”后编辑面板不自动收起,且“取消”按钮失效
|
||||
- **模块**: 住院医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd48-7364-7fe1-8c03-5c6411c0ba39"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_680_ANALYSIS.md
Normal file
34
MD/bugs/BUG_680_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #680 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:20:02
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 680
|
||||
- **标题**: [住院医生站-临床医嘱] 勾选“待签发”临时医嘱后点击【删除】按钮无响应
|
||||
- **模块**: 住院医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd46-b544-7ab3-b1e9-18fa9b9bf8f5"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_681_ANALYSIS.md
Normal file
34
MD/bugs/BUG_681_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #681 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:18:56
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 681
|
||||
- **标题**: [门诊收费] 点击“已收费”列表患者报错“encounterId 为 undefined”,导致无法查看收费详情
|
||||
- **模块**: 门诊收费管理
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd45-c39e-7cd3-9c4c-704b5dd61808"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_682_ANALYSIS.md
Normal file
34
MD/bugs/BUG_682_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #682 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:17:56
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 682
|
||||
- **标题**: 【住院医生工作站】历史医嘱的报卡的布局有些字段被覆盖
|
||||
- **模块**: 住院医生工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd44-ccf6-7e70-bf1e-d8b34b3047b2"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_683_ANALYSIS.md
Normal file
34
MD/bugs/BUG_683_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #683 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:16:25
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 683
|
||||
- **标题**: 【门诊医生工作站】无法选择医嘱项目
|
||||
- **模块**: 门诊医生工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd43-6142-7222-bb99-c29ab0ce42de"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_684_ANALYSIS.md
Normal file
34
MD/bugs/BUG_684_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #684 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:14:54
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 684
|
||||
- **标题**: 【手术管理】手术状态下拉框有重复
|
||||
- **模块**: 手术麻醉管理
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd42-029a-7491-9473-ef085ac9e5b6"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_685_ANALYSIS.md
Normal file
34
MD/bugs/BUG_685_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #685 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:13:19
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 685
|
||||
- **标题**: 【住院护士站】住院护士站报错404页面打不开
|
||||
- **模块**: 病区护士工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd40-8cfb-7290-bcb6-d7550ebb4239"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_686_ANALYSIS.md
Normal file
34
MD/bugs/BUG_686_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #686 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:12:25
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 686
|
||||
- **标题**: 【门诊管理-门诊划价】项目的排版错乱字段重叠
|
||||
- **模块**: 门诊收费管理
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd3f-b780-7ed0-8698-4e67181f0d55"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_687_ANALYSIS.md
Normal file
34
MD/bugs/BUG_687_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #687 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:10:24
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 687
|
||||
- **标题**: 【库房管理-统计管理】库房明细记录的操作列表下停供报错
|
||||
- **模块**: 库房管理
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd3d-e4f7-7723-8b8f-ef72d5b3805b"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_688_ANALYSIS.md
Normal file
34
MD/bugs/BUG_688_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #688 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:09:19
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 688
|
||||
- **标题**: [住院发退药-发药明细单] 患者列表布局挤压导致内容显示不全,且多条件组合检索(患者信息/发药状态/药品分类)失效
|
||||
- **模块**: 住院药房管理
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd3c-f5ef-7fe3-b95b-7e2f0355ea42"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_689_ANALYSIS.md
Normal file
34
MD/bugs/BUG_689_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #689 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:08:01
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 689
|
||||
- **标题**: [住院管理-住院发退药] 发药汇总单界面布局被挤压、发放状态文案不符及右侧详情联动无数据
|
||||
- **模块**: 住院药房管理
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd3b-b577-7670-945c-a995871568c1"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_691_ANALYSIS.md
Normal file
34
MD/bugs/BUG_691_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #691 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:06:34
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 691
|
||||
- **标题**: [门诊挂号-预约签到] 确认弹窗患者姓名显示为undefined,且提交签到报错缺失organizationId参数
|
||||
- **模块**: 建档挂号管理
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd3a-5d3f-7bf2-9279-a062ef4ff8fc"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_693_ANALYSIS.md
Normal file
34
MD/bugs/BUG_693_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #693 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:05:00
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 693
|
||||
- **标题**: [门诊医生站-诊断录入] 诊断选择弹窗中点击诊断后,界面无法回填且未赋值
|
||||
- **模块**: 门诊医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd38-ecfe-7432-b7e0-040657841dc1"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_694_ANALYSIS.md
Normal file
34
MD/bugs/BUG_694_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #694 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:02:47
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 694
|
||||
- **标题**: 【住院医生工作站】不同的权限登录之前的标签后面的权限也可以打开
|
||||
- **模块**: 住院医生工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd36-e742-7c22-a18d-c5c27bc2a7f7"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_695_ANALYSIS.md
Normal file
34
MD/bugs/BUG_695_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #695 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:01:29
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 695
|
||||
- **标题**: 【住院医生工作站】将一条已签发的医嘱进行停嘱,显示成功但是状态还是已签发
|
||||
- **模块**: 住院医生工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd35-b960-7cf2-858d-ed17672599d7"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
34
MD/bugs/BUG_696_ANALYSIS.md
Normal file
34
MD/bugs/BUG_696_ANALYSIS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #696 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 03:00:12
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 696
|
||||
- **标题**: [收费工作站-住院登记] 优化姓名搜索框,增设“身份证号”与“申请时间段”检索条件,及列表字段补充显示
|
||||
- **模块**: 住院登记管理
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
{"type":"thread.started","thread_id":"019ebd34-8727-7480-b6b5-c61fdeb2c987"}
|
||||
{"type":"turn.started"}
|
||||
{"type":"error","message":"Reconnecting... 1/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 2/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 3/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 4/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"Reconnecting... 5/5 (stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses))"}
|
||||
{"type":"error","message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}
|
||||
{"type":"turn.failed","error":{"message":"stream disconnected before completion: error sending request for url (http://127.0.0.1:8788/v1/responses)"}}
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
194
MD/bugs/BUG_697_ANALYSIS.md
Normal file
194
MD/bugs/BUG_697_ANALYSIS.md
Normal file
@@ -0,0 +1,194 @@
|
||||
# Bug #697 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 02:58:52
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 697
|
||||
- **标题**: [门诊管理-门诊挂号] 检索并选择患者后,信息未回填赋值至挂号表单,导致挂号阻断
|
||||
- **模块**: 建档挂号管理
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
Now I have a comprehensive understanding of the bug. Let me produce my analysis.
|
||||
|
||||
---
|
||||
|
||||
## 一、Bug 理解
|
||||
|
||||
### 禅道原文引用
|
||||
|
||||
**Bug 标题**:[门诊管理-门诊挂号] 检索并选择患者后,信息未回填赋值至挂号表单,导致挂号阻断
|
||||
|
||||
**重现步骤**:
|
||||
> 【步骤】登录账号 admin/admin123,进入【门诊管理】→【门诊挂号】。在"患者身份信息"输入框中输入关键字"随子赫"(或就诊卡号 2123123)。系统自动弹出模糊匹配的待选患者悬浮列表。用鼠标左键双击或单击选中列表中的患者"随子赫"这一行数据。观察挂号主界面各患者信息输入框(姓名、性别、年龄、就诊卡号、证件号、电话等)的接收状态。
|
||||
|
||||
**期望结果**:
|
||||
> 选中列表中的患者后,该患者的所有基本信息(包括但不限于:姓名、性别、年龄、就诊卡号、证件号、电话等)应自动回填并正确渲染显示在挂号主界面的对应表单中。
|
||||
|
||||
**实际结果**:
|
||||
> 选中下拉列表后该列表消失,但主界面的姓名、性别、年龄、就诊卡号、证件号、电话等所有患者基本信息字段依然为空,未回显任何数据,导致整个挂号业务无法继续保存。
|
||||
|
||||
### 附图分析关键信息
|
||||
- 截图中红色标注:**"点击选中患者,患者信息未实现赋值至主界面,实现不了挂号业务"**
|
||||
- 截图中红色标注:**"未赋值"**(第二个截图中整个挂号表单区域为空白)
|
||||
- 患者下拉列表正常显示,数据完整(姓名、就诊卡号、性别、证件号、联系电话、年龄),但选中后主表单所有字段为空
|
||||
|
||||
### 综合总结
|
||||
用户在门诊挂号页面搜索患者后,下拉列表能正常弹出并显示匹配结果。但点击选中某一行后,**列表关闭了,主表单的姓名、性别、年龄、就诊卡号、证件号、电话等字段全部为空**,挂号流程被完全阻断。这是一个典型的**前端数据回填事件链断裂**问题——选中事件触发了列表关闭,但回填逻辑未成功执行。
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
### 根因:el-popover `trigger="manual"` + input `@blur` 导致事件链断裂
|
||||
|
||||
**完整事件链分析:**
|
||||
|
||||
1. 用户在搜索输入框输入关键字 → `handleFocus()` 显示 popover → `patientList` 组件通过 watcher 触发 `getList()` → API 返回患者列表正常 ✅
|
||||
2. 用户**点击** popover 中的某一行 →
|
||||
3. **关键断裂点**:点击 popover 内部内容时,浏览器先处理 input 的 **blur 事件** → `handleBlur()` 立即执行 `showPopover.value = false`
|
||||
4. Element Plus 的 `el-popover` 使用 `trigger="manual"` 模式,当 `:visible` 变为 `false` 时,**popover 内容从 DOM 中移除/隐藏**
|
||||
5. 由于 popover 内容被移除,vxe-table 的 `@cell-click="clickRow"` 事件**来不及触发**或触发时 DOM 已不可用
|
||||
6. `clickRow` → `emit("selsectPatient", params.row)` **未被触发**
|
||||
7. 父组件的 `selsectPatient(row)` **未被调用** → 表单字段未赋值
|
||||
|
||||
**事件时序图:**
|
||||
```
|
||||
mousedown (table row)
|
||||
→ input blur fires (handleBlur)
|
||||
→ showPopover = false
|
||||
→ popover content removed from DOM
|
||||
→ cell-click fires on vxe-table (TOO LATE, DOM gone)
|
||||
```
|
||||
|
||||
**涉及文件:**
|
||||
|
||||
| 文件 | 作用 | 问题点 |
|
||||
|------|------|--------|
|
||||
| `healthlink-his-ui/src/views/charge/outpatientregistration/index.vue` (L116-137) | el-popover + input 模板 | `@blur="handleBlur"` 立即关闭 popover |
|
||||
| `healthlink-his-ui/src/views/charge/outpatientregistration/index.vue` (L1996-1998) | `handleBlur` 函数 | 无延迟,立即 `showPopover = false` |
|
||||
| `healthlink-his-ui/src/views/charge/outpatientregistration/index.vue` (L2228-2241) | `selsectPatient` 函数 | 逻辑正确但未被触发 |
|
||||
| `healthlink-his-ui/src/views/charge/outpatientregistration/components/patientList.vue` (L96) | `@cell-click="clickRow"` | click 事件未能触发 |
|
||||
| `healthlink-his-ui/src/views/charge/outpatientregistration/components/patientList.vue` (L54) | `@mousedown.prevent` | 绑在组件上,未阻止 input blur |
|
||||
|
||||
**为什么 `@mousedown.prevent` 没有阻止 blur?**
|
||||
|
||||
`@mousedown.prevent` 是 Vue 事件修饰符,绑定在 `<patientList>` 组件上,会附加到组件的根元素 `<div>` 上。但 `mousedown` 事件的传播方向是**从目标元素向上冒泡**:
|
||||
- 表格单元格 `mousedown` → 表格 `mousedown` → `<div>` 的 Vue mousedown(`preventDefault` 执行)
|
||||
- 但 input 的 `blur` 是由浏览器的**焦点管理机制**触发的,不受 `preventDefault` 的完全控制
|
||||
- 特别是当 el-popover 使用 Teleport 将内容渲染到 `document.body` 时,popover 内容的 mousedown 事件可能不会冒泡到触发元素的父容器
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
### 修复策略:在 popover 内容区域拦截 mousedown,阻止 input 失焦
|
||||
|
||||
**修改文件**:`healthlink-his-ui/src/views/charge/outpatientregistration/index.vue`
|
||||
|
||||
**修改内容**:
|
||||
|
||||
#### 修改 1:在 popover 内容区域添加 mousedown 阻止事件(约 L116-137)
|
||||
|
||||
将模板中的 popover 内容区域修改为:
|
||||
|
||||
```vue
|
||||
<!-- 修改前 -->
|
||||
<el-popover
|
||||
:popper-style="{ padding: '0' }"
|
||||
placement="bottom-start"
|
||||
:visible="showPopover"
|
||||
trigger="manual"
|
||||
:width="1200"
|
||||
>
|
||||
<patientList
|
||||
:searchkey="patientSearchKey"
|
||||
@selsect-patient="selsectPatient"
|
||||
@mousedown.prevent
|
||||
/>
|
||||
...
|
||||
</el-popover>
|
||||
|
||||
<!-- 修改后 -->
|
||||
<el-popover
|
||||
:popper-style="{ padding: '0' }"
|
||||
placement="bottom-start"
|
||||
:visible="showPopover"
|
||||
trigger="manual"
|
||||
:width="1200"
|
||||
>
|
||||
<div @mousedown.prevent>
|
||||
<patientList
|
||||
:searchkey="patientSearchKey"
|
||||
@selsect-patient="selsectPatient"
|
||||
/>
|
||||
</div>
|
||||
...
|
||||
</el-popover>
|
||||
```
|
||||
|
||||
关键变化:
|
||||
- `@mousedown.prevent` 从 `<patientList>` 组件标签移到**包裹 popover 内容的 `<div>`** 上
|
||||
- 确保 popover 内任何位置的 mousedown 都会被阻止默认行为,从而**阻止 input 失焦**
|
||||
- input 不失焦 → popover 不关闭 → `cell-click` 正常触发 → `selsectPatient` 正常执行 → 表单正确赋值
|
||||
|
||||
#### 修改 2:添加防御性保障 — 优化 `handleBlur`(约 L1996-1998)
|
||||
|
||||
```javascript
|
||||
// 修改前
|
||||
function handleBlur() {
|
||||
showPopover.value = false;
|
||||
}
|
||||
|
||||
// 修改后
|
||||
function handleBlur() {
|
||||
setTimeout(() => {
|
||||
showPopover.value = false;
|
||||
}, 200);
|
||||
}
|
||||
```
|
||||
|
||||
双重保障:即使 `@mousedown.prevent` 在某些边界情况下未完全生效,200ms 延迟也足以让 `cell-click` 事件完成、`selsectPatient` 执行,之后再关闭 popover。
|
||||
|
||||
#### 修改 3:(可选)增加键盘关闭支持
|
||||
|
||||
由于 `@mousedown.prevent` 阻止了焦点转移,用户需要其他方式关闭 popover:
|
||||
|
||||
```javascript
|
||||
// 在 onMounted 中添加
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape' && showPopover.value) {
|
||||
showPopover.value = false;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 修改清单
|
||||
|
||||
| # | 文件 | 行号(约) | 修改内容 |
|
||||
|---|------|-----------|---------|
|
||||
| 1 | `outpatientregistration/index.vue` | L116-137 | popover 内容包裹 `<div @mousedown.prevent>` |
|
||||
| 2 | `outpatientregistration/index.vue` | L1996-1998 | `handleBlur` 增加 200ms setTimeout |
|
||||
| 3 | `outpatientregistration/index.vue` | L2228-2241 | `selsectPatient` 函数逻辑无需修改(已正确) |
|
||||
|
||||
---
|
||||
|
||||
## 四、路由决策
|
||||
|
||||
**FIXER**: zhaoyun
|
||||
|
||||
**REASON**: 纯前端 Bug——el-popover 事件链断裂导致患者信息回填失败,涉及 Vue 模板事件绑定和 el-popover 组件交互逻辑,属于前端 UI 修复范畴,无需数据库变更,不需要后端参与。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
25
MD/bugs/BUG_698_ANALYSIS.md
Normal file
25
MD/bugs/BUG_698_ANALYSIS.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Bug #698 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-11 16:51:39
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 698
|
||||
- **标题**: [收费工作站-住院登记-已登记入院] 检索维度单一,且关键归档信息缺失(需增设检索条件与补充列表字段展示)
|
||||
- **模块**: 住院登记管理
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
(LLM 失败,关键词分析)
|
||||
Bug: [收费工作站-住院登记-已登记入院] 检索维度单一,且关键归档信息缺失(需增设检索条件与补充列表字段展示)
|
||||
模块: 住院登记管理
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **修复 Agent**: zhaoyun
|
||||
- **原因**: 关键词: 前端
|
||||
139
MD/bugs/BUG_712_ANALYSIS.md
Normal file
139
MD/bugs/BUG_712_ANALYSIS.md
Normal file
@@ -0,0 +1,139 @@
|
||||
# Bug #712 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 02:46:37
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 712
|
||||
- **标题**: 【收费工作站-预交金管理】“预交金管理”页面缺失展示“支付方式”列及患者“床号”、“费用类型”
|
||||
- **模块**: 住院登记管理
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
分析完成。以下是完整的 Bug #712 分析报告。
|
||||
|
||||
---
|
||||
|
||||
## 一、Bug 理解
|
||||
|
||||
**Bug 标题**:【收费工作站-预交金管理】"预交金管理"页面缺失展示"支付方式"列及患者"床号"、"费用类型"
|
||||
|
||||
**重现步骤**:
|
||||
1. 登录系统,进入"收费工作站" → "预交金管理"页面
|
||||
2. 输入住院号查询关联患者(如"三太子")
|
||||
3. 检查患者基本信息卡片及下方收支明细列表
|
||||
|
||||
**期望结果**:
|
||||
1. 患者卡片区增加展示"床号"(如:012床)与"费用类型"(医保类型,如:职工医保)
|
||||
2. 明细列表区在"票据类型"与"收款时间"之间新增"支付方式"字段列
|
||||
|
||||
**附图分析关键信息**:
|
||||
- 图2492/2493 显示患者卡片区域"在院科室/病区: 呼吸内科病房/呼吸内科一区",**没有独立展示床号和费用类型**
|
||||
- 收支明细列表列头为:序号、收据号、金额、票据类型、收款时间、收款员 —— **缺少"支付方式"列**
|
||||
- 截图中有红色标注:"增加患者床号和费用类型"、"增加支付方式字段列"
|
||||
|
||||
**综合总结**:用户在预交金管理页面查询住院患者后,患者信息卡片只显示了科室/病区,无法看到该患者的具体床号和医保费用类型;下方流水明细列表缺少支付方式列,无法知道每笔交易的支付渠道(现金/支付宝等)。这两个信息对打印收据和财务核对都是必需的。
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
经过全链路 6 环分析,问题分布在前端和后端两个层面:
|
||||
|
||||
### 缺陷 1:费用类型(费用类型/医保类型)缺失
|
||||
|
||||
**前端** `index.vue:88-110`:患者信息卡片区域没有展示"费用类型"字段。
|
||||
**后端** `AdvancePaymentInfoDto.java`:DTO 缺少 `ybClassText`(医保类别文本)字段。
|
||||
**后端** `AdvancePaymentManageAppMapper.xml`:`getAdvancePaymentInfo` SQL 查询未 SELECT `ae.yb_class_text`。
|
||||
**数据库**:`adm_encounter` 表已有 `yb_class_text` 字段(保险类型文本,如"职工医保")。
|
||||
|
||||
### 缺陷 2:床号显示不突出
|
||||
|
||||
**后端** SQL 已查询 `alb.name AS bed_name`,DTO 已有 `bedName` 字段。
|
||||
**前端** `index.vue:115-120`:床号被拼在"在院科室/病区"字符串中(`wardName + houseName + bedName`),没有独立展示为"床号:012床"。
|
||||
|
||||
### 缺陷 3:支付方式列缺失
|
||||
|
||||
**前端** `index.vue:147`:`<vxe-column field="payWay" title="支付方式" />` 被注释掉了。
|
||||
**后端** `AdvancePaymentFlowRecordDto.java`:DTO 缺少支付方式字段(`payEnum` / `payWay`)。
|
||||
**后端** `AdvancePaymentManageAppMapper.xml:90-99`:`getAdvancePaymentFlowRecordList` SQL 只查了 `fin_payment_reconciliation` 主表,**未 JOIN** `fin_payment_rec_detail` 子表(`pay_enum` 字段在子表中)。
|
||||
**数据库**:`fin_payment_rec_detail` 表有 `pay_enum`(支付类型编码,如现金/支付宝/微信)。
|
||||
|
||||
**涉及文件清单**:
|
||||
|
||||
| 文件 | 修改内容 |
|
||||
|------|---------|
|
||||
| `AdvancePaymentInfoDto.java` | 新增 `ybClassText` 字段 |
|
||||
| `AdvancePaymentManageAppMapper.xml` | `getAdvancePaymentInfo` SQL 加 `ae.yb_class_text` |
|
||||
| `AdvancePaymentFlowRecordDto.java` | 新增 `payEnum` + `payWay` 字段 |
|
||||
| `AdvancePaymentManageAppMapper.xml` | `getAdvancePaymentFlowRecordList` SQL JOIN `fin_payment_rec_detail`,取 `pay_enum` |
|
||||
| `AdvancePaymentManageAppServiceImpl.java` | 流水记录返回后增加 `payWay` 枚举映射 |
|
||||
| `index.vue` | 卡片区域新增"床号"和"费用类型"展示;取消注释支付方式列 |
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
### Step 1:后端 — DTO 新增字段
|
||||
|
||||
**`AdvancePaymentInfoDto.java`**:新增字段
|
||||
```java
|
||||
/** 费用类型(医保类型文本,如:职工医保) */
|
||||
private String ybClassText;
|
||||
```
|
||||
|
||||
**`AdvancePaymentFlowRecordDto.java`**:新增字段
|
||||
```java
|
||||
/** 支付方式编码 */
|
||||
private Integer payEnum;
|
||||
/** 支付方式文本(如:现金、支付宝) */
|
||||
private String payWay;
|
||||
```
|
||||
|
||||
### Step 2:后端 — Mapper XML 修改
|
||||
|
||||
**`AdvancePaymentManageAppMapper.xml`**:
|
||||
|
||||
1. `getAdvancePaymentInfo` 子查询中加 `ae.yb_class_text AS yb_class_text`
|
||||
2. `getAdvancePaymentFlowRecordList` SQL 加 JOIN `fin_payment_rec_detail`,取 `prd.pay_enum`
|
||||
|
||||
### Step 3:后端 — ServiceImpl 枚举映射
|
||||
|
||||
**`AdvancePaymentManageAppServiceImpl.java`**:
|
||||
|
||||
在 `getAdvancePaymentFlowRecord` 方法中增加支付方式枚举映射:
|
||||
```java
|
||||
e.setPayWay(EnumUtils.getInfoByValue(YbPayment.class, e.getPayEnum()));
|
||||
```
|
||||
|
||||
### Step 4:前端 — 页面字段补充
|
||||
|
||||
**`index.vue`**:
|
||||
1. 在"在院科室/病区"行下方(或同行),新增展示:
|
||||
- `床号: {{ patientInfo.bedName }}`(独立标签)
|
||||
- `费用类型: {{ patientInfo.ybClassText }}`
|
||||
2. 取消注释支付方式列,改为:
|
||||
```html
|
||||
<vxe-column field="payWay" title="支付方式" align="center" min-width="100" />
|
||||
```
|
||||
3. 插入位置:在 `paymentEnum_enumText`(票据类型)列之后、`operateTime`(收款时间)列之前
|
||||
|
||||
---
|
||||
|
||||
## 四、路由决策
|
||||
|
||||
**FIXER**: zhaoyun(赵云 — 前端开发)
|
||||
**REASON**: 本次修复核心在于前端页面展示(卡片字段补充 + 表格列取消注释),后端改动量较小(DTO 加 2 字段、SQL 加 2 列、Service 加 1 行映射),属于前后端联动的 UI 展示修复,赵云可一并处理前端和后端轻量改动。无需 DBA 审查(无建表/加字段迁移)。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
127
MD/bugs/BUG_714_ANALYSIS.md
Normal file
127
MD/bugs/BUG_714_ANALYSIS.md
Normal file
@@ -0,0 +1,127 @@
|
||||
# Bug #714 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 02:42:58
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 714
|
||||
- **标题**: 【住院护士站-医嘱校对】住院护士站-医嘱核对界面:缺少“截止时间”过滤条件且默认单选未选中“全部”
|
||||
- **模块**: 病区护士工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
分析完毕。以下是完整输出。
|
||||
|
||||
---
|
||||
|
||||
## 一、Bug 理解
|
||||
|
||||
**Bug 标题**:【住院护士站-医嘱校对】住院护士站-医嘱核对界面:缺少"截止时间"过滤条件且默认单选未选中"全部"
|
||||
|
||||
**重现步骤**:
|
||||
1. 登录系统,进入"住院护士站"菜单
|
||||
2. 点击进入"医嘱核对"页面,选中左侧"在科"列表中的某位患者
|
||||
3. 观察右侧查询条件区域(包含"未校对/已校对/已停止/已退回"四个标签页)
|
||||
|
||||
**结果**:
|
||||
1. 过滤条件中缺少"截止时间"时间控件,无法限制截止时间进行医嘱筛选
|
||||
2. 医嘱分类单选框默认未自动选中"全部"
|
||||
3. 切换到"已校对/已停止/已退回"标签页时,同样缺失截止时间字段
|
||||
|
||||
**期望**:
|
||||
1. 四个标签页均应增加"截止时间"查询条件
|
||||
2. "截止时间"默认显示为系统当前时间,且支持手动编辑/选择
|
||||
3. 页面初始化默认选中"全部"单项
|
||||
|
||||
**附图关键信息**:截图清晰显示查询条件区域仅有"医嘱分类"(全部/长期/临时)单选框和"查询"按钮,无截止时间DatePicker控件;且"全部"选项未处于选中状态。
|
||||
|
||||
**综合总结**:用户在住院护士站医嘱核对界面无法按时间节点批量筛选医嘱,因为查询区域缺少截止时间过滤条件。同时初始化时医嘱分类默认未选中"全部",不利于日常操作。这是一个典型的设计缺陷——查询条件不完整影响护士工作效率。
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
经代码全链路追踪,Bug 涉及前端组件 + 后端 DTO + Service + Mapper 四层:
|
||||
|
||||
**前端层**(`medicalOrderProofread/components/prescriptionList.vue`):
|
||||
1. `<el-radio-group>` 中"全部"选项的 `:value` 原为 `null`(commit `376ddd46f` 中添加),导致 `type` 初始值为 `null`,UI 上无选项被选中
|
||||
2. 组件中完全没有 `<el-date-picker>` 日期选择控件,无法选择截止时间
|
||||
3. `handleGetPrescription()` 构造请求参数时未传递 `deadline` 字段
|
||||
|
||||
**后端 DTO 层**(`InpatientAdviceParam.java`):
|
||||
- `deadline` 字段已存在(在初始重构中引入),但此前未被 Service 层实际使用
|
||||
|
||||
**Service 层**(`AdviceProcessAppServiceImpl.java` → `getInpatientAdvicePage()`):
|
||||
- 未提取 `deadline` 参数,未在 `QueryWrapper` 中拼接时间范围条件
|
||||
|
||||
**Mapper 层**(`AdviceProcessAppMapper.xml`):
|
||||
- SQL 使用 `${ew.customSqlSegment}` 拼接条件,Service 未设置条件则 SQL 无截止时间过滤
|
||||
|
||||
**根因总结**:前端查询组件设计时遗漏了截止时间控件,且默认值设置不当;后端虽然 DTO 有字段但 Service 层未处理该参数,导致整条链路断裂。
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案(⚠️ 已在 `ca812421d` 中修复)
|
||||
|
||||
> **注意**:经过 git 历史追踪,此 Bug 的修复已作为 Bug #665 的附带修复在 commit `ca812421d` 中完成。以下是修复内容详解:
|
||||
|
||||
### 3.1 前端修复(`prescriptionList.vue`)
|
||||
|
||||
| 修改点 | 修改前 | 修改后 |
|
||||
|--------|--------|--------|
|
||||
| Radio 默认值 | `:value="null"` | `:value="0"` |
|
||||
| type 初始值 | `ref(null)` | `ref(0)` |
|
||||
| 截止时间控件 | 无 | 新增 `<el-date-picker>` (datetime类型) |
|
||||
| deadline 初始值 | 无 | `ref(formatDateStr(new Date(), 'YYYY-MM-DD') + ' 23:59:59')` |
|
||||
| 查询参数 | 无 deadline | `...(deadline.value ? { deadline: deadline.value } : {})` |
|
||||
| therapyEnum 条件 | `type.value != null` | `type.value !== 0`(仅非"全部"时传递) |
|
||||
|
||||
### 3.2 后端修复(`AdviceProcessAppServiceImpl.java` → `getInpatientAdvicePage()`)
|
||||
|
||||
新增代码逻辑:
|
||||
```java
|
||||
// 提取 deadline 手动处理
|
||||
String deadline = inpatientAdviceParam.getDeadline();
|
||||
inpatientAdviceParam.setDeadline(null);
|
||||
// ...
|
||||
// 手动拼接 deadline 条件,按医嘱截止时间筛选
|
||||
if (deadline != null && !deadline.isEmpty()) {
|
||||
LocalDateTime deadlineTime = LocalDateTime.parse(deadline,
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
queryWrapper.le("end_time", deadlineTime); // ≤ 截止时间
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 四标签页覆盖机制
|
||||
|
||||
`index.vue` 中四个 tab 各创建独立的 `PrescriptionList` 实例,每个实例维护独立的 `type` 和 `deadline` ref。切换 tab 时通过 `provide/inject` + `ref` 调用目标 tab 组件的 `handleGetPrescription()`,四标签页均能独立使用截止时间过滤。
|
||||
|
||||
### 3.4 验证检查项
|
||||
|
||||
- [ ] 前端编译通过(`npm run build:dev`)
|
||||
- [ ] 后端编译通过(`mvn clean compile -DskipTests`)
|
||||
- [ ] "未校对" tab:截止时间默认为当日 23:59:59,可编辑
|
||||
- [ ] "全部" radio 默认选中,查询结果包含长期+临时
|
||||
- [ ] "已校对/已停止/已退回" tab 同样有截止时间控件
|
||||
- [ ] 修改截止时间后点"查询",结果正确过滤
|
||||
|
||||
---
|
||||
|
||||
## 四、路由决策
|
||||
|
||||
**FIXER**: zhaoyun(前端为主)+ guanyu(后端 Service 层配合)
|
||||
|
||||
**REASON**: Bug 涉及前端 UI 组件(DatePicker 控件新增 + Radio 默认值修正)占主要工作量,交赵云处理;后端 Service 层 deadline 条件拼接需关羽配合验证 SQL 正确性。**但此 Bug 已在 `ca812421d` commit 中修复完成**,若禅道状态仍为 active,建议直接关闭并更新禅道状态为"已解决"。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
235
MD/bugs/BUG_715_ANALYSIS.md
Normal file
235
MD/bugs/BUG_715_ANALYSIS.md
Normal file
@@ -0,0 +1,235 @@
|
||||
# Bug #715 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 02:38:26
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 715
|
||||
- **标题**: 【住院护士站-医嘱校对】医生已签发的“临时耗材医嘱”未同步至护士站“医嘱校对”界面
|
||||
- **模块**: 病区护士工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
Now I have all the information needed. Let me write the comprehensive analysis.
|
||||
|
||||
---
|
||||
|
||||
## 一、Bug 理解
|
||||
|
||||
**禅道 Bug 标题**:【住院护士站-医嘱校对】医生已签发的"临时耗材医嘱"未同步至护士站"医嘱校对"界面
|
||||
|
||||
**重现步骤**:
|
||||
1. 医生端:进入"住院医生工作站",为患者刘潇凡开具并手动点击【签发】一条"临时"医嘱(如:一次性使用导尿包)
|
||||
2. 护士端:进入"住院护士站" > "医嘱校对"界面
|
||||
3. 在"未校对"标签页中,选中患者,点击【查询】
|
||||
|
||||
**期望结果**:系统应正确加载并显示已签发的临时耗材医嘱,以便护士进行核对操作。
|
||||
|
||||
**实际结果**:医嘱核对页面显示空白,提示"点击查询获取患者医嘱信息",无法查到已签发的临时耗材医嘱。
|
||||
|
||||
**附图关键信息**:
|
||||
- 截图1(医生端):显示患者刘潇凡有一条状态为"**已签发**"的临时医嘱"一次性使用导尿包",类别为"耗材",金额 38.00 元
|
||||
- 截图2(护士端):"医嘱校对 → 未校对"页面,患者已选中但右侧**内容区域完全空白**,仅显示"点击查询获取患者医嘱信息"
|
||||
|
||||
**综合总结**:医生签发的耗材医嘱(存储在 `wor_device_request` 表)在护士站医嘱校对页面无法查询到,因为该页面的 SQL 查询只包含了药品请求(`med_medication_request`)和服务请求(`wor_service_request`)两个 UNION 子查询,**完全缺失了耗材请求(`wor_device_request`)的第三个 UNION 子查询**。
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
### 根因定位
|
||||
|
||||
**核心缺陷文件**:`healthlink-his-server/healthlink-his-application/src/main/resources/mapper/inhospitalnursestation/AdviceProcessAppMapper.xml`
|
||||
|
||||
`selectInpatientAdvicePage` 查询使用 UNION 组合三种医嘱类型,但只写了两个子查询:
|
||||
|
||||
| 序号 | 表名 | 医嘱类型 | 状态 |
|
||||
|------|------|---------|------|
|
||||
| ✅ 1 | `med_medication_request` | 药品医嘱 | 有 |
|
||||
| ✅ 2 | `wor_service_request` | 诊疗服务医嘱 | 有 |
|
||||
| ❌ 3 | `wor_device_request` | **耗材/器材医嘱** | **缺失** |
|
||||
|
||||
**对比证据**:住院医生站的 `DoctorStationAdviceAppMapper.xml`(行 674-732)和住院医生工作站的 `AdviceManageAppMapper.xml`(行 247-305)都正确包含了 `wor_device_request` 的 UNION 子查询,证明耗材医嘱是系统支持的医嘱类型。
|
||||
|
||||
### 签发流程差异
|
||||
|
||||
从 `AdviceManageAppServiceImpl.java`(行 842-845)可确认:
|
||||
- 药品/服务医嘱签发:状态保持 `DRAFT(1)` + 设置 `performer_check_id`
|
||||
- **耗材医嘱签发**:状态直接设为 `ACTIVE(2)`(不使用 `performer_check_id`)
|
||||
|
||||
### 涉及文件
|
||||
|
||||
| 文件 | 作用 |
|
||||
|------|------|
|
||||
| `AdviceProcessAppMapper.xml` | **需修改** — 缺少 `wor_device_request` UNION 子查询 |
|
||||
| `AdviceProcessAppServiceImpl.java` | **可能需微调** — `therapyEnum` 条件处理(设备医嘱的 `therapy_enum` 为 NULL) |
|
||||
| `InpatientAdviceDto.java` | DTO,已包含 `adviceTable` 字段,可区分医嘱来源表 |
|
||||
| `DeviceRequest.java` | 基础实体,注意:**没有** `performerCheckId` 字段 |
|
||||
| `CommonConstants.java:150` | 常量 `WOR_DEVICE_REQUEST = "wor_device_request"` 已定义 |
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
### Step 1: 在 `AdviceProcessAppMapper.xml` 中添加第三个 UNION 子查询
|
||||
|
||||
在现有的 `wor_service_request` UNION 之后、`ORDER BY T1.status_enum )` 之前,添加 `wor_device_request` 的 UNION 子查询。需映射到 `InpatientAdviceDto` 的所有字段:
|
||||
|
||||
```xml
|
||||
UNION
|
||||
( SELECT DISTINCT T1.encounter_id,
|
||||
T1.tenant_id,
|
||||
#{worDeviceRequest} AS advice_table,
|
||||
T1.id AS request_id,
|
||||
T1.use_start_time AS start_time,
|
||||
T1.use_end_time AS end_time,
|
||||
T1.requester_id AS requester_id,
|
||||
T1.create_time AS request_time,
|
||||
NULL::integer AS skin_test_flag,
|
||||
NULL::integer AS inject_flag,
|
||||
NULL::bigint AS group_id,
|
||||
NULL::bigint AS performer_check_id,
|
||||
T2."name" AS advice_name,
|
||||
T2.id AS item_id,
|
||||
NULL::varchar AS volume,
|
||||
T1.lot_number AS lot_number,
|
||||
T1.quantity AS quantity,
|
||||
T1.unit_code AS unit_code,
|
||||
T1.status_enum AS request_status,
|
||||
NULL::varchar AS method_code,
|
||||
T1.rate_code AS rate_code,
|
||||
NULL::numeric AS dose,
|
||||
NULL::varchar AS dose_unit_code,
|
||||
al1.id AS position_id,
|
||||
al1."name" AS position_name,
|
||||
NULL::integer AS dispense_per_duration,
|
||||
T2.part_percent AS part_percent,
|
||||
NULL::varchar AS condition_definition_name,
|
||||
NULL::integer AS therapy_enum,
|
||||
NULL::integer AS sort_number,
|
||||
NULL::integer AS execute_num,
|
||||
af.day_times,
|
||||
ae.bus_no,
|
||||
ap."name" AS patient_name,
|
||||
al2."name" AS bed_name,
|
||||
ap.gender_enum,
|
||||
ap.birth_date,
|
||||
ap.id AS patient_id,
|
||||
fc.contract_name,
|
||||
diagnosis.condition_names,
|
||||
pra."name" AS admitting_doctor_name,
|
||||
personal_account.balance_amount,
|
||||
personal_account.id AS account_id,
|
||||
NULL::varchar AS category_code,
|
||||
NULL::integer AS dispense_status,
|
||||
NULL::numeric AS unit_price,
|
||||
NULL::numeric AS total_price,
|
||||
NULL::bigint AS stopper_id,
|
||||
T1.update_by AS stopper_name
|
||||
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_location AS al1
|
||||
ON al1.id = T1.perform_location AND al1.delete_flag = '0'
|
||||
LEFT JOIN adm_encounter ae
|
||||
ON ae.id = T1.encounter_id AND ae.class_enum = #{imp} AND ae.delete_flag = '0'
|
||||
LEFT JOIN adm_patient ap ON ae.patient_id = ap.id AND ap.delete_flag = '0'
|
||||
LEFT JOIN adm_encounter_location ael
|
||||
ON ae.id = ael.encounter_id AND ael.delete_flag = '0'
|
||||
AND ael.status_enum = #{active} AND ael.form_enum = #{bed}
|
||||
LEFT JOIN adm_location al2 ON ael.location_id = al2.id AND al2.delete_flag = '0'
|
||||
LEFT JOIN adm_account aa
|
||||
ON ae.id = aa.encounter_id AND aa.encounter_flag = 1 AND aa.delete_flag = '0'
|
||||
LEFT JOIN fin_contract fc ON aa.contract_no = fc.bus_no AND fc.delete_flag = '0'
|
||||
LEFT JOIN (
|
||||
SELECT aed.encounter_id, STRING_AGG(ccd.name, ', ') AS condition_names
|
||||
FROM adm_encounter_diagnosis aed
|
||||
INNER JOIN cli_condition cc ON cc.id = aed.condition_id AND cc.delete_flag = '0'
|
||||
INNER JOIN cli_condition_definition ccd ON ccd.id = cc.definition_id AND ccd.delete_flag = '0'
|
||||
WHERE aed.delete_flag = '0'
|
||||
GROUP BY aed.encounter_id
|
||||
) AS diagnosis ON ae.id = diagnosis.encounter_id
|
||||
LEFT JOIN adm_encounter_participant aep
|
||||
ON ae.id = aep.encounter_id AND aep.delete_flag = '0'
|
||||
AND aep.status_enum = #{active} AND aep.type_code = #{admittingDoctor}
|
||||
LEFT JOIN adm_practitioner pra ON aep.practitioner_id = pra.id AND pra.delete_flag = '0'
|
||||
LEFT JOIN (
|
||||
SELECT aa.id, aa.encounter_id,
|
||||
(aa.balance_amount -
|
||||
COALESCE(SUM(CASE WHEN aci.status_enum IN (#{billed}, #{billable})
|
||||
THEN aci.total_price ELSE 0 END), 0) +
|
||||
COALESCE(SUM(CASE WHEN aci.status_enum = #{refunded}
|
||||
THEN aci.total_price ELSE 0 END), 0)) AS balance_amount
|
||||
FROM adm_account aa
|
||||
LEFT JOIN adm_charge_item aci ON aa.encounter_id = aci.encounter_id AND aa.delete_flag = '0'
|
||||
WHERE aa.type_code = #{personalCashAccount} AND aa.delete_flag = '0'
|
||||
GROUP BY aa.id, aa.encounter_id, aa.balance_amount
|
||||
) AS personal_account ON personal_account.encounter_id = ae.id
|
||||
LEFT JOIN adm_frequency af ON af.rate_code = T1.rate_code AND af.delete_flag = '0'
|
||||
WHERE T1.delete_flag = '0'
|
||||
AND T1.generate_source_enum = #{doctorPrescription}
|
||||
AND T1.refund_device_id IS NULL
|
||||
AND (T1.based_on_id IS NULL OR T1.based_on_table IS NULL)
|
||||
ORDER BY T1.status_enum )
|
||||
```
|
||||
|
||||
**关键差异注意**:
|
||||
1. `performer_check_id` — 设为 `NULL::bigint`,因为 `wor_device_request` 没有此字段,耗材签发时直接将 `statusEnum` 设为 `ACTIVE(2)`
|
||||
2. `therapy_enum` — 设为 `NULL::integer`,因为耗材医嘱没有治疗类型分类
|
||||
3. `advice_table` — 使用新的参数 `#{worDeviceRequest}`
|
||||
4. WHERE 条件中不需要 `performer_check_id IS NOT NULL` 检查,因为耗材签发后直接为 `ACTIVE(2)` 状态
|
||||
5. 需要排除基于其他医嘱生成的执行记录:`AND (T1.based_on_id IS NULL OR T1.based_on_table IS NULL)`
|
||||
|
||||
### Step 2: 修改 `AdviceProcessAppMapper.java` — 添加参数
|
||||
|
||||
在 `selectInpatientAdvicePage` 方法签名中添加 `worDeviceRequest` 参数:
|
||||
|
||||
```java
|
||||
Page<InpatientAdviceDto> selectInpatientAdvicePage(
|
||||
@Param("page") Page<InpatientAdviceDto> page,
|
||||
@Param(Constants.WRAPPER) QueryWrapper<InpatientAdviceParam> queryWrapper,
|
||||
@Param("medMedicationRequest") String medMedicationRequest,
|
||||
@Param("worServiceRequest") String worServiceRequest,
|
||||
@Param("worDeviceRequest") String worDeviceRequest, // 新增
|
||||
// ... 其余参数不变
|
||||
);
|
||||
```
|
||||
|
||||
### Step 3: 修改 `AdviceProcessAppServiceImpl.java` — 传递新参数
|
||||
|
||||
在 `getInpatientAdvicePage` 方法中,调用 mapper 时添加 `CommonConstants.TableName.WOR_DEVICE_REQUEST`:
|
||||
|
||||
```java
|
||||
Page<InpatientAdviceDto> inpatientAdvicePage
|
||||
= adviceProcessAppMapper.selectInpatientAdvicePage(
|
||||
new Page<>(pageNo, pageSize), queryWrapper,
|
||||
CommonConstants.TableName.MED_MEDICATION_REQUEST,
|
||||
CommonConstants.TableName.WOR_SERVICE_REQUEST,
|
||||
CommonConstants.TableName.WOR_DEVICE_REQUEST, // 新增
|
||||
RequestStatus.DRAFT.getValue(), ...);
|
||||
```
|
||||
|
||||
### Step 4: 确保 `therapyEnum` 条件兼容
|
||||
|
||||
当前代码已修复(行 `queryWrapper.and(w -> w.eq("therapy_enum", therapyEnum).or().isNull("therapy_enum"))`),允许 NULL 的 `therapy_enum` 通过。耗材医嘱的 `therapy_enum` 为 NULL,会匹配 "全部" 和 "临时" 两个筛选条件,这是正确的行为。
|
||||
|
||||
---
|
||||
|
||||
## 四、路由决策
|
||||
|
||||
**FIXER**: `guanyu`(后端开发)
|
||||
|
||||
**REASON**: 此 Bug 为纯后端 SQL 查询缺陷——Mapper XML 中 UNION 缺少 `wor_device_request` 子查询,需修改 XML、Mapper 接口、ServiceImpl 调用三处。前端无需改动,属于后端数据查询层的修复,交给后端开发最合适。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
214
MD/bugs/BUG_716_ANALYSIS.md
Normal file
214
MD/bugs/BUG_716_ANALYSIS.md
Normal file
@@ -0,0 +1,214 @@
|
||||
# Bug #716 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 02:33:10
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 716
|
||||
- **标题**: 【住院医生站-临床医嘱】住院医嘱录入界面:医嘱类型/耗材仓库显示不符合业务逻辑,且开嘱医生列无回写值
|
||||
- **模块**: 住院医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
I have enough evidence now. Let me provide the comprehensive analysis.
|
||||
|
||||
---
|
||||
|
||||
## Bug #716 分析报告
|
||||
|
||||
### 一、Bug 理解
|
||||
|
||||
**原文引用 — 禅道 Bug 标题:**
|
||||
> 【住院医生站-临床医嘱】住院医嘱录入界面:医嘱类型/耗材仓库显示不符合业务逻辑,且开嘱医生列无回写值
|
||||
|
||||
**重现步骤:**
|
||||
1. 登录账号 `doctor1`,在"住院医生工作站"选中患者,点击【新增】医嘱
|
||||
2. 点击【医嘱类型】下拉框,观察显示内容
|
||||
3. 在添加含耗材的医嘱时,观察【耗材仓库】字段选择列表的显示内容
|
||||
4. 保存并签发该医嘱,查看医嘱列表明细中【开嘱医生】列的显示
|
||||
|
||||
**结果:**
|
||||
1. 医嘱类型显示为数字(如"2")
|
||||
2. 耗材仓库选择框显示的是批号(如"4444444")
|
||||
3. 已保存/签发的医嘱,【开嘱医生】列显示为"-"
|
||||
|
||||
**期望:**
|
||||
1. 医嘱类型下拉应展示业务名称(如"耗材"),而非数字
|
||||
2. 耗材仓库选择列表应展示"仓库名称",而非批号
|
||||
3. 【开嘱医生】应显示当前操作医生的姓名
|
||||
|
||||
**附图关键信息:**
|
||||
- 图2506:红色箭头标注"显示数字",指向医嘱类型区域显示"2"
|
||||
- 图2507:红色箭头标注"应该显示耗材仓库 不是批号",耗材仓库下拉选中值为"4444444"
|
||||
- 图2508:红色箭头标注"未回写",新保存的耗材医嘱【开嘱医生】列显示"-"
|
||||
|
||||
**综合总结:** 用户在住院医生工作站新增耗材类医嘱时,遇到三个显示/数据问题:(1) 医嘱类型下拉框的 el-select 显示原始数字编码而非业务名称;(2) 耗材仓库下拉框显示的是 inventoryId/批号而非仓库名称标签;(3) 新保存的耗材医嘱在列表中开嘱医生列显示"-",说明 requesterId 的字典翻译或数据回写链路断裂。
|
||||
|
||||
---
|
||||
|
||||
### 二、根因分析
|
||||
|
||||
#### 问题1:医嘱类型显示数字
|
||||
|
||||
**目标文件:**
|
||||
- `healthlink-his-ui/src/views/inpatientDoctor/home/components/order/index.vue` (行 312-357)
|
||||
|
||||
**根因:** 内联编辑行的医嘱类型 el-select 使用 `:model-value="getRowSelectValue(scope.row)"` 单向绑定。`@change` 处理器直接修改 `filterPrescriptionList[scope.rowIndex].adviceType`,但 `filterPrescriptionList` 是 computed 属性,其返回的数组是 `prescriptionList.value.filter(...)` 的结果。虽然修改的是同一个对象引用,但 Vue 的 computed 缓存机制可能导致 el-select 未及时重新评估 `model-value`,从而显示原始值而非匹配的 label。
|
||||
|
||||
此外,`getRowSelectValue` 返回 `row.adviceType`(数字),而选项的 `value` 也是数字 `2`。如果 `adviceType` 在某处被转为字符串 `"2"`(例如从 `contentJson` 反序列化时),则 `model-value="2"` (string) 与 `value: 2` (number) 不匹配,el-select 会显示原始值。
|
||||
|
||||
**关键代码:**
|
||||
```javascript
|
||||
// index.vue:1202
|
||||
function getRowSelectValue(row) {
|
||||
if (row.adviceType == 1 && row.categoryCode) {
|
||||
return '1-' + row.categoryCode;
|
||||
}
|
||||
if (row.adviceType == 7) {
|
||||
return 7;
|
||||
}
|
||||
return row.adviceType; // ← 可能是 string "2" 而非 number 2
|
||||
}
|
||||
```
|
||||
|
||||
**影响范围:** `index.vue:316` 的 el-select `:model-value` 绑定
|
||||
|
||||
---
|
||||
|
||||
#### 问题2:耗材仓库显示批号
|
||||
|
||||
**目标文件:**
|
||||
- `healthlink-his-ui/src/views/inpatientDoctor/home/components/order/OrderForm.vue` (行 479-498)
|
||||
|
||||
**根因:** 耗材(adviceType==2)的药房/仓库下拉框使用 `v-model="row.inventoryId"`,el-option 的 `:value="item.inventoryId"`。当 `row.inventoryId` 与 stockList 中的 `item.inventoryId` 类型不一致时(一个是 string,一个是 number),el-select 无法匹配选项,回退显示原始 `inventoryId` 值。
|
||||
|
||||
后端 `AdviceInventoryDto.inventoryId` 使用了 `@JsonSerialize(using = ToStringSerializer.class)`,Jackson 会将其序列化为字符串。但在 `setValue` 函数中,`inventoryId` 从 `selectedStock?.inventoryId` 赋值,而 `selectedStock` 来自 `mergedStockList`(合并了 `inventoryList` 和 `priceList`)。如果 `priceList` 中也有 `inventoryId` 字段且为 number 类型,`{ ...item, ...priceList[index] }` 的 spread 会覆盖为 number,导致类型不一致。
|
||||
|
||||
**关键代码:**
|
||||
```javascript
|
||||
// index.vue:2206
|
||||
mergedStockList = row.inventoryList.map((item, index) => {
|
||||
return { ...item, ...priceList[index] }; // priceList 可能覆盖 inventoryId 类型
|
||||
});
|
||||
|
||||
// OrderForm.vue:480
|
||||
<el-select v-model="row.inventoryId" ...>
|
||||
<el-option :value="item.inventoryId" :label="`${item.locationName} 批次号: ...`" />
|
||||
</el-select>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 问题3:开嘱医生显示"-"
|
||||
|
||||
**目标文件:**
|
||||
- 后端:`AdviceManageAppServiceImpl.java` (行 817-910, `handDevice` 方法)
|
||||
- 前端:`index.vue` (行 1030-1033, 数据转换)
|
||||
|
||||
**根因:** 后端 `AdviceSaveDto` 构造函数设置了 `this.practitionerId = SecurityUtils.getLoginUser().getPractitionerId()`。但 `handDevice` 方法中,`requesterId` 只在 `if (is_save)` 分支内设置:
|
||||
```java
|
||||
if (is_save) {
|
||||
deviceRequest.setRequesterId(regAdviceSaveDto.getPractitionerId());
|
||||
}
|
||||
```
|
||||
|
||||
当用户直接签发(`adviceOpType=SIGN_ADVICE`)时,`is_save=false`,`requesterId` 不会被设置到 `DeviceRequest` 对象上。虽然 MyBatis-Plus 的 `saveOrUpdate` 默认跳过 null 字段(不会覆盖已有的 `requester_id`),但如果这是**首次签发**(未先保存),则 `requester_id` 在数据库中为 NULL。
|
||||
|
||||
更重要的是,SQL 查询的列别名 `requester_id_dict_text`(下划线命名)与 DTO 字段 `requesterId_dictText`(混合命名)不匹配。MyBatis 的 `mapUnderscoreToCamelCase` 会将 `requester_id_dict_text` 映射为 `requesterIdDictText`,而非 `requesterId_dictText`。虽然 `@Dict` 注解理论上会补填,但如果 `requesterId` 本身为 NULL,则字典查询也返回 NULL,最终前端回退到 `'-'`。
|
||||
|
||||
---
|
||||
|
||||
### 三、修复方案
|
||||
|
||||
#### 修复1:医嘱类型 el-select 显示数字
|
||||
|
||||
**文件:** `healthlink-his-ui/src/views/inpatientDoctor/home/components/order/index.vue`
|
||||
|
||||
**修改内容:**
|
||||
1. 在 `getRowSelectValue` 函数中,确保返回值类型与选项 `value` 类型一致(统一为 number)
|
||||
2. 在 `@change` 处理器中,使用 `prescriptionList.value[index]` 直接操作源数据,而非通过 computed 属性
|
||||
|
||||
```javascript
|
||||
// 修复 getRowSelectValue,确保返回 number
|
||||
function getRowSelectValue(row) {
|
||||
const adviceType = Number(row.adviceType);
|
||||
if (adviceType === 1 && row.categoryCode) {
|
||||
return '1-' + row.categoryCode;
|
||||
}
|
||||
if (adviceType === 7) {
|
||||
return 7;
|
||||
}
|
||||
return isNaN(adviceType) ? undefined : adviceType;
|
||||
}
|
||||
```
|
||||
|
||||
#### 修复2:耗材仓库显示批号
|
||||
|
||||
**文件:** `healthlink-his-ui/src/views/inpatientDoctor/home/components/order/OrderForm.vue`
|
||||
|
||||
**修改内容:**
|
||||
1. 在耗材(adviceType==2)的 el-select 中,使用 `:value="String(item.inventoryId)"` 和 `v-model` 统一为 string 类型
|
||||
2. 或者在 `setValue` 函数中确保 `inventoryId` 类型一致
|
||||
|
||||
```javascript
|
||||
// OrderForm.vue 中耗材部分,统一 inventoryId 为 string
|
||||
<el-option
|
||||
v-for="item in row.stockList"
|
||||
:key="item.inventoryId"
|
||||
:value="String(item.inventoryId)"
|
||||
:label="`${item.locationName} 批次号: ${item.lotNumber ?? '-'} 库存:${...}`"
|
||||
/>
|
||||
```
|
||||
|
||||
同时在 `index.vue` 的 `setValue` 中:
|
||||
```javascript
|
||||
inventoryId: selectedStock?.inventoryId ? String(selectedStock.inventoryId) : undefined,
|
||||
```
|
||||
|
||||
#### 修复3:开嘱医生显示"-"
|
||||
|
||||
**文件:** `healthlink-his-server/.../AdviceManageAppServiceImpl.java`
|
||||
|
||||
**修改内容:**
|
||||
在 `handDevice` 方法中,将 `requesterId` 的设置移到 `if (is_save)` 块外面,确保签发操作也设置 `requesterId`:
|
||||
|
||||
```java
|
||||
// handDevice 方法中,longInsertOrUpdateList 和 tempInsertOrUpdateList 的循环内
|
||||
// 将 requesterId 设置移到 if (is_save) 块外
|
||||
deviceRequest.setRequesterId(regAdviceSaveDto.getPractitionerId()); // ← 移到这里
|
||||
if (is_save) {
|
||||
deviceRequest.setBusNo(...);
|
||||
deviceRequest.setGenerateSourceEnum(...);
|
||||
// ... 其他仅保存时设置的字段
|
||||
}
|
||||
```
|
||||
|
||||
同样在 `handMedication` 和 `handService` 方法中检查是否存在相同问题。
|
||||
|
||||
**附加修复(保险措施):** 在前端数据转换中,确保 `requesterId_dictText` 的回退逻辑更健壮:
|
||||
```javascript
|
||||
requesterId_dictText: item.requesterId_dictText
|
||||
|| (item.requesterId ? (String(item.requesterId) === String(userStore.practitionerId) ? userStore.name : '') : '')
|
||||
|| '-',
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 四、路由决策
|
||||
|
||||
**FIXER:** `zhaoyun`(前端开发)+ `guanyu`(后端开发)
|
||||
|
||||
**REASON:** 问题1和问题2是纯前端 el-select 绑定/类型问题,由赵云修复;问题3涉及后端 `handDevice` 方法中 `requesterId` 设置位置不当,需要关羽修改后端 Java 代码。两个角色各负责独立的修复范围,无冲突,可并行工作。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: ** 问题1和问题2是纯前端 el-select 绑定/类型问题,由赵云修复;问题3涉及后端 `handDevice` 方法中 `requesterId` 设置位置不当,需要关羽修改后端 Java 代码。两个角色各负责独立的修复范围,无冲突,可并行工作。
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
169
MD/bugs/BUG_718_ANALYSIS.md
Normal file
169
MD/bugs/BUG_718_ANALYSIS.md
Normal file
@@ -0,0 +1,169 @@
|
||||
# Bug #718 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 02:19:56
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 718
|
||||
- **标题**: 【业务逻辑缺陷】医生端点击“停嘱”后医嘱直接变更为“已停止”,未流转至护士端进行停止核对
|
||||
- **模块**: 病区护士工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
Now I have a thorough understanding of the entire flow. Let me compile my analysis.
|
||||
|
||||
---
|
||||
|
||||
## 一、Bug 理解
|
||||
|
||||
### 原文引用
|
||||
|
||||
**Bug 标题**:【业务逻辑缺陷】医生端点击"停嘱"后医嘱直接变更为"已停止",未流转至护士端进行停止核对
|
||||
|
||||
**重现步骤**:
|
||||
1. 登录"住院医生工作站",选择在科患者(如:刘潇凡)
|
||||
2. 找到一条已校对且正在执行的长期医嘱(如:注射用头孢哌酮舒巴坦钠)
|
||||
3. 选中该医嘱,点击界面上方的【停嘱】按钮
|
||||
4. 观察医生端该医嘱的状态变化
|
||||
5. 登录"住院护士站",进入"医嘱核对"页面
|
||||
6. 依次查看【未校对】和【已停止】标签页
|
||||
|
||||
**期望结果**:
|
||||
1. 医生端点击"停嘱"后,医嘱状态应变更为【已停嘱】(中间状态),不能一步到位直接变成终态【停止】
|
||||
2. 该医嘱应流转并显示在护士端的【未校对】标签页内,供护士进行停嘱确认
|
||||
3. 只有当护士在"未校对"下选中该停嘱医嘱并点击【核对通过】后,医嘱状态才变更为【已停止】,并最终流转显示在【已停止】标签页中
|
||||
|
||||
**附图关键信息**:
|
||||
- 图1(医生端):红色标注指出"停嘱成功的医嘱状态应该是'已停嘱'待核对,需要重新定义一个医嘱状态'已停嘱'记录已停嘱的医嘱";列表中停嘱后医嘱状态显示为"停止"
|
||||
- 图2(护士端):红色标注指出"已停嘱的医嘱应该显示在未校对标签页 待护士核对,核对后状态变成已停止";未校对标签页中无停嘱待核对记录
|
||||
|
||||
### 综合总结
|
||||
|
||||
医生点击停嘱后,医嘱状态直接跳变为终态"停止"(或至少在显示上呈现为停止),护士端的【未校对】标签页未收到该停嘱待核对记录,护士无法执行核对确认。期望的流程是:医生停嘱→状态变为中间态"已停嘱"→流转至护士端未校对→护士核对通过→状态变为终态"停止"。
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
通过代码审查,我追踪了完整的停嘱数据流链路:
|
||||
|
||||
### 后端代码(看似正确但存在显示链路断裂)
|
||||
|
||||
1. **医生停嘱接口** `AdviceManageAppServiceImpl.stopRegAdvice()`(第1100行):将状态设为 `RequestStatus.PENDING_STOP(13, "已停嘱")` ✅
|
||||
2. **护士站查询** `AdviceProcessAppServiceImpl.getInpatientAdvicePage()`(第204-213行):查询 ACTIVE(2) 时同时包含 PENDING_STOP(13) ✅
|
||||
3. **护士核对** `AdviceProcessAppServiceImpl.adviceVerify()`(第433-450行):将 PENDING_STOP(13) 转为 STOPPED(6) ✅
|
||||
4. **枚举定义** `RequestStatus.java`:`PENDING_STOP(13, "pending_stop", "已停嘱")` ✅
|
||||
|
||||
### 根本问题:护士站前端状态显示映射缺失
|
||||
|
||||
`prescriptionList.vue` 中的 `REQUEST_STATUS_DISPLAY` 映射表**缺少 PENDING_STOP(13) 条目**:
|
||||
|
||||
```javascript
|
||||
// 第356-361行
|
||||
const REQUEST_STATUS_DISPLAY = {
|
||||
[RequestStatus.DRAFT]: '待签发', // 1 → '待签发'
|
||||
[RequestStatus.ACTIVE]: '已签发', // 2 → '已签发'
|
||||
[RequestStatus.COMPLETED]: '已校对', // 3 → '已校对'
|
||||
[RequestStatus.STOPPED]: '已停止', // 6 → '已停止'
|
||||
// ⚠️ 缺少 PENDING_STOP(13) 条目!
|
||||
};
|
||||
```
|
||||
|
||||
`getStatusDisplayText()` 的回退逻辑虽然最终能通过 `LEGACY_STATUS_TEXT` 或 `requestStatus_enumText` 返回正确的文本"已停嘱",但**存在一个更严重的问题**:
|
||||
|
||||
对于药品医嘱,`getStatusDisplayText()` **优先使用 `dispenseStatus`**(发药状态)。如果停嘱前已存在发药记录(如 dispenseStatus=4 → "已发药"),则 PENDING_STOP 的停嘱状态会被发药状态**遮蔽**,护士看不到"已停嘱"状态。
|
||||
|
||||
### 涉及的关键文件
|
||||
|
||||
| 文件 | 问题 |
|
||||
|------|------|
|
||||
| `healthlink-his-ui/src/views/inpatientNurse/medicalOrderProofread/components/prescriptionList.vue` | `REQUEST_STATUS_DISPLAY` 缺少 PENDING_STOP 映射;`getStatusDisplayText` 对 PENDING_STOP 的优先级逻辑不当 |
|
||||
| `healthlink-his-ui/src/views/inpatientDoctor/home/components/order/index.vue` | 医生端模板已有 statusEnum==13→"已停嘱" 映射,**看似正确** |
|
||||
| `healthlink-his-server/.../AdviceManageAppServiceImpl.java` | 后端停嘱逻辑已正确设置 PENDING_STOP,**无需修改** |
|
||||
| `healthlink-his-server/.../AdviceProcessAppServiceImpl.java` | 护士站查询已包含 PENDING_STOP,核对逻辑已正确处理,**无需修改** |
|
||||
| `healthlink-his-server/healthlink-his-common/.../RequestStatus.java` | 枚举定义正确,PENDING_STOP(13) 已存在,**无需修改** |
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
### 修复1:护士站前端状态显示映射(核心修复)
|
||||
|
||||
**文件**:`healthlink-his-ui/src/views/inpatientNurse/medicalOrderProofread/components/prescriptionList.vue`
|
||||
|
||||
**修改1a**:在 `REQUEST_STATUS_DISPLAY` 中添加 PENDING_STOP 映射
|
||||
|
||||
```javascript
|
||||
// 第356行后添加
|
||||
const REQUEST_STATUS_DISPLAY = {
|
||||
[RequestStatus.DRAFT]: '待签发',
|
||||
[RequestStatus.ACTIVE]: '已签发',
|
||||
[RequestStatus.COMPLETED]: '已校对',
|
||||
[RequestStatus.STOPPED]: '已停止',
|
||||
[RequestStatus.PENDING_STOP]: '已停嘱', // ← 新增
|
||||
};
|
||||
```
|
||||
|
||||
**修改1b**:修改 `getStatusDisplayText` 逻辑,确保 PENDING_STOP 优先级高于 dispenseStatus
|
||||
|
||||
PENDING_STOP 是停嘱的中间状态,应优先显示,不受旧的发药状态遮蔽:
|
||||
|
||||
```javascript
|
||||
const getStatusDisplayText = (row) => {
|
||||
// 0. 已停嘱(13)优先显示 —— 停嘱中间态必须醒目,不被旧发药状态遮蔽
|
||||
const requestCode = Number(row?.requestStatus);
|
||||
if (requestCode === RequestStatus.PENDING_STOP) {
|
||||
return '已停嘱';
|
||||
}
|
||||
// 1. 优先使用发药状态
|
||||
const dispenseCode = Number(row?.dispenseStatus);
|
||||
if (DISPENSE_STATUS_DISPLAY[dispenseCode]) {
|
||||
return DISPENSE_STATUS_DISPLAY[dispenseCode];
|
||||
}
|
||||
// 2. 使用行级别请求状态
|
||||
if (REQUEST_STATUS_DISPLAY[requestCode]) {
|
||||
return REQUEST_STATUS_DISPLAY[requestCode];
|
||||
}
|
||||
// 3. 兼容旧后端枚举文本
|
||||
return LEGACY_STATUS_TEXT[row?.requestStatus_enumText] || row?.requestStatus_enumText || '';
|
||||
};
|
||||
```
|
||||
|
||||
### 修复2:医生端 SQL 查询补充 stop_time/stop_user_name(优化)
|
||||
|
||||
**文件**:`healthlink-his-server/.../mapper/regdoctorstation/AdviceManageAppMapper.xml`
|
||||
|
||||
当前 SQL 中 stop_time 和 stop_user_name 仅在 `status_enum = 6`(STOPPED)时返回,PENDING_STOP(13) 时不返回,导致医生端停嘱时间/停嘱医生列为空。需将条件改为 `status_enum IN (6, 13)`:
|
||||
|
||||
```xml
|
||||
<!-- 修改前 -->
|
||||
CASE WHEN T1.status_enum = 6 THEN T1.effective_dose_end ELSE NULL END AS stop_time,
|
||||
CASE WHEN T1.status_enum = 6 THEN T1.update_by ELSE NULL END AS stop_user_name
|
||||
|
||||
<!-- 修改后 -->
|
||||
CASE WHEN T1.status_enum IN (6, 13) THEN T1.effective_dose_end ELSE NULL END AS stop_time,
|
||||
CASE WHEN T1.status_enum IN (6, 13) THEN T1.update_by ELSE NULL END AS stop_user_name
|
||||
```
|
||||
|
||||
(对 ServiceRequest 和 DeviceRequest 的 UNION 部分同样修改)
|
||||
|
||||
---
|
||||
|
||||
## 四、路由决策
|
||||
|
||||
**FIXER**: `guanyu`(后端开发)+ `zhaoyun`(前端开发)
|
||||
|
||||
**REASON**: 本 Bug 涉及前后端两个层面。核心修复在前端护士站的状态显示映射(`prescriptionList.vue` 的 `REQUEST_STATUS_DISPLAY` 和 `getStatusDisplayText`),属于 `zhaoyun` 的职责范围。次要修复在后端 Mapper XML 的 SQL 条件补充(`AdviceManageAppMapper.xml`),属于 `guanyu` 的职责范围。后端核心停嘱逻辑(`stopRegAdvice` 和 `adviceVerify`)**已正确实现**,无需修改。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
147
MD/bugs/BUG_719_ANALYSIS.md
Normal file
147
MD/bugs/BUG_719_ANALYSIS.md
Normal file
@@ -0,0 +1,147 @@
|
||||
# Bug #719 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 02:11:11
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 719
|
||||
- **标题**: 【护士站-医嘱校对】已停止列表:频次/用法及停嘱医生字段未回写显示
|
||||
- **模块**: 病区护士工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
Now I have a complete understanding of the bug. Let me provide the analysis.
|
||||
|
||||
---
|
||||
|
||||
## 一、Bug 理解
|
||||
|
||||
### 禅道 Bug 原文
|
||||
|
||||
**标题**: 【护士站-医嘱校对】已停止列表:频次/用法及停嘱医生字段未回写显示
|
||||
|
||||
**重现步骤**:
|
||||
1. 医生端已对某医嘱进行"停嘱"操作(如:注射用头孢哌酮舒巴坦钠)
|
||||
2. 登录护士端进入"住院护士站" > "医嘱校对"
|
||||
3. 在查询页签中点击"已停止"标签
|
||||
4. 查看对应医嘱记录的"频次/用法"及"停嘱医生"两列
|
||||
|
||||
**结果**: 列表中"频次/用法"及"停嘱医生"列内容为空,未显示任何数据。
|
||||
|
||||
**期望**: 列表对应的"频次/用法"及"停嘱医生"列应正确显示数据,且与临床医生端显示内容一致(如:每日一次 静脉滴注、内科医生1)。
|
||||
|
||||
### 附图关键信息
|
||||
- **图2513**(护士站"已停止"标签页):两条已停医嘱记录中,"频次/用法"列和"停嘱医生"列均为空白。图中用红色标注"频次/用法 和停嘱医生未回写"。
|
||||
- **图2512**(医生站视图):同一医嘱显示"频次/用法"为"每日一次 静脉滴注","停嘱医生"为"内科医生1"。
|
||||
|
||||
### 综合总结
|
||||
护士在医嘱校对的"已停止"列表中查看已停医嘱时,"频次/用法"和"停嘱医生"两个字段显示为空。这两个字段在医生端正常显示。问题出在护士站查询已停止医嘱时,数据源(SQL查询或Java处理)未能正确返回这两个字段的值。
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
### 根因1:停嘱医生字段 —— `stopper_name` 映射到 `update_by` 被覆盖
|
||||
|
||||
**核心问题链路**:
|
||||
|
||||
1. **医生停嘱** (`AdviceManageAppServiceImpl.stopRegAdvice`): 设置 `update_by = SecurityUtils.getNickName()`(医生昵称)
|
||||
- 此时 `update_by = "内科医生1"` ✓
|
||||
- **但未设置 `stopper_id`**(虽然 V41 迁移已添加此列)
|
||||
|
||||
2. **护士校对** (`AdviceProcessAppServiceImpl.adviceVerify`): 设置 `update_by = SecurityUtils.getNickName()`(护士昵称)
|
||||
- 此时 `update_by` 被覆盖为护士名
|
||||
- 如果护士昵称为空/NULL → `update_by = NULL`
|
||||
|
||||
3. **SQL 查询** (`AdviceProcessAppMapper.xml`):
|
||||
```sql
|
||||
NULL::bigint AS stopper_id, -- 硬编码 NULL!
|
||||
T1.update_by AS stopper_name -- 使用 update_by,已被覆盖
|
||||
```
|
||||
|
||||
4. **Java 处理**:
|
||||
```java
|
||||
e.setStopperName(e.getStopperName()); // 这是空操作!
|
||||
```
|
||||
|
||||
**结论**: `stopper_name` 取自 `update_by`,而 `update_by` 被护士校对操作覆盖。若护士昵称为空,该字段为 NULL。V41 迁移添加了 `stopper_id` 列但 Java 实体和查询均未使用。
|
||||
|
||||
**涉及文件**:
|
||||
- `AdviceProcessAppMapper.xml` (L209-210, L355-356): `NULL::bigint AS stopper_id` + `T1.update_by AS stopper_name`
|
||||
- `AdviceProcessAppServiceImpl.java` (L318): `e.setStopperName(e.getStopperName())` — 空操作
|
||||
- `AdviceManageAppServiceImpl.java` (L1127): `.set(MedicationRequest::getUpdateBy, stopUserName)` — 未设 `stopper_id`
|
||||
- `MedicationRequest.java`: 缺少 `stopperId` 字段
|
||||
- `ServiceRequest.java`: 缺少 `stopperId` 字段
|
||||
|
||||
### 根因2:频次/用法字段 —— 需要进一步排查
|
||||
|
||||
SQL 查询正确选取了 `T1.rate_code` 和 `T1.method_code`,Java 代码也正确计算了 `frequencyUsage`。但两个停嘱医嘱都为空,可能是:
|
||||
- 数据库中这两条医嘱的 `rate_code`/`method_code` 为 NULL(创建时未设置)
|
||||
- 或 `DictUtils.getDictLabel` 返回空字符串
|
||||
|
||||
**需验证**: 检查 `med_medication_request` 表中对应记录的 `rate_code` 和 `method_code` 值。
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
### 修复1:停嘱医生字段(核心修复)
|
||||
|
||||
**Step 1**: 给 `MedicationRequest` 和 `ServiceRequest` 实体添加 `stopperId` 字段
|
||||
|
||||
**Step 2**: 更新医生站停嘱逻辑,设置 `stopper_id`
|
||||
|
||||
```java
|
||||
// AdviceManageAppServiceImpl.stopRegAdvice
|
||||
// 获取停嘱医生的 practitionerId
|
||||
Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
|
||||
// 药品
|
||||
.set(MedicationRequest::getStopperId, practitionerId)
|
||||
.set(MedicationRequest::getUpdateBy, stopUserName)
|
||||
// 诊疗
|
||||
.set(ServiceRequest::getStopperId, practitionerId)
|
||||
.set(ServiceRequest::getUpdateBy, stopUserName)
|
||||
```
|
||||
|
||||
**Step 3**: 更新护士站 SQL 查询,用 `stopper_id` 关联 `adm_practitioner` 获取医生姓名
|
||||
|
||||
```sql
|
||||
-- AdviceProcessAppMapper.xml 中 MedicationRequest UNION:
|
||||
-- 修改前:
|
||||
NULL::bigint AS stopper_id,
|
||||
T1.update_by AS stopper_name
|
||||
-- 修改后:
|
||||
T1.stopper_id AS stopper_id,
|
||||
COALESCE(practitioner_stop.name, T1.update_by) AS stopper_name
|
||||
-- 并增加 LEFT JOIN:
|
||||
LEFT JOIN adm_practitioner practitioner_stop ON T1.stopper_id = practitioner_stop.id AND practitioner_stop.delete_flag = '0'
|
||||
```
|
||||
|
||||
对 ServiceRequest UNION 同理修改。
|
||||
|
||||
**Step 4**: 更新护士站校对逻辑,停嘱单校对时不应覆盖 `update_by`(或同时保留 stopper 信息)
|
||||
|
||||
### 修复2:频次/用法字段
|
||||
|
||||
先验证数据:检查 `med_medication_request` 表中 `rate_code` 和 `method_code` 是否为 NULL。如果为 NULL,需检查订单创建流程是否正确设置了这两个字段。
|
||||
|
||||
---
|
||||
|
||||
## 四、路由决策
|
||||
|
||||
**FIXER: guanyu(后端开发)+ zhaoyun(前端开发)**
|
||||
|
||||
**REASON**: 根因在后端(SQL 查询 `stopper_name` 映射错误 + 实体缺少 `stopperId` + 停嘱逻辑未设 `stopper_id`),需 guanyu 修复实体类、Mapper XML、Service 层。频次/用法需排查数据库数据,也属后端。前端可能需确认"频次/用法"为空时的展示逻辑,属 zhaoyun 范围。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
228
MD/bugs/BUG_720_ANALYSIS.md
Normal file
228
MD/bugs/BUG_720_ANALYSIS.md
Normal file
@@ -0,0 +1,228 @@
|
||||
# Bug #720 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 01:53:34
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 720
|
||||
- **标题**: 【住院医生工作站】只要打开了一个模块所有的的权限的都可以打开存在安全隐患
|
||||
- **模块**: 住院医生工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
I now have a complete understanding of the bug. Here is my analysis:
|
||||
|
||||
---
|
||||
|
||||
## 一、Bug 理解
|
||||
|
||||
**禅道 Bug #720 标题**:【住院医生工作站】只要打开了一个模块所有的权限的都可以打开存在安全隐患
|
||||
|
||||
**重现步骤**:随便登录一个账号(例:wx,密码:123456),随便打开一个模块,随便切换一个账号(例:doctor1,密码:123456),可以打开 wx 账号的卡片模块。
|
||||
|
||||
**期望结果**:什么权限下的模块就在什么权限下出现,不应该在别的权限下打开。
|
||||
|
||||
**附图分析**:
|
||||
- 截图1(用户"韦雪"):在「医保管理」→「电子处方管理」中查看处方列表
|
||||
- 截图2(用户"内科医生1"):登录后左侧导航中「门诊医生工作站」展开但**无「电子处方管理」子菜单**,然而主界面却**依然停留在「电子处方管理」页面**,且数据完全一致
|
||||
- 两张截图中,不同角色看到了相同的业务数据和操作按钮,且无任何"无权限"提示
|
||||
|
||||
**综合总结**:用户 A(护士/药师角色)登录后打开某模块,退出后切换为用户 B(医生角色),用户 B 能直接访问 A 的页面。根因是切换账号后旧路由未被清除、新守卫校验不充分,导致路由级权限绕过。
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
### 核心问题:Vue Router `addRoute()` 是永久性的,切换账号后旧路由从未被移除
|
||||
|
||||
**完整触发链路**:
|
||||
|
||||
```
|
||||
用户A登录 → getInfo()获取A的权限 → generateRoutes() → router.addRoute(A的路由) [永久注册]
|
||||
↓
|
||||
用户A退出 → logOut() → 清除token/roles/permissions/标签页 → 跳转/login
|
||||
[⚠️ 未清除: permission store状态、router中已注册的路由]
|
||||
↓
|
||||
用户B登录 → setToken(B的token) → 跳转/
|
||||
↓
|
||||
router.beforeEach → roles.length===0 → getInfo()获取B的权限 → generateRoutes()
|
||||
→ router.addRoute(B的路由) [B的路由被追加,A的路由依然存在]
|
||||
↓
|
||||
用户B访问/ePrescribing → router.resolve(to).matched.length > 0 ✅(A的路由还在)
|
||||
→ 守卫放行 → 越权访问成功 ❌
|
||||
```
|
||||
|
||||
**三处代码缺陷**:
|
||||
|
||||
| 缺陷 | 文件 | 问题 |
|
||||
|------|------|------|
|
||||
| **缺陷1** | `store/modules/permission.js` `generateRoutes()` | 只追加新路由,从不移除旧路由。没有记录已添加的动态路由名 |
|
||||
| **缺陷2** | `store/modules/user.js` `logOut()` | 只清除 token/roles/permissions/tagsView,**未重置 permission store**(routes/sidebarRouters等)|
|
||||
| **缺陷3** | `permission.js` 路由守卫 | 最终校验只检查 `router.resolve(to).matched.length === 0`(路由是否注册),**不检查当前用户是否有权访问该路由** |
|
||||
|
||||
**注意**:路由守卫中已有注释"铁律: 路由权限校验 — 防止切换账户后通过旧标签或直接输入URL访问无权限页面",说明开发者**意识到了这个问题但修复不彻底**——因为旧路由从未被清除,所以 `matched.length` 永远 > 0,校验形同虚设。
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
### 方案:三层防御(清除旧路由 + 重置状态 + 守卫增强)
|
||||
|
||||
#### 修改1:`healthlink-his-ui/src/store/modules/permission.js` — 记录并清除旧路由
|
||||
|
||||
```javascript
|
||||
// 新增 state
|
||||
state: () => ({
|
||||
routes: [],
|
||||
addRoutes: [],
|
||||
defaultRoutes: [],
|
||||
topbarRouters: [],
|
||||
sidebarRouters: [],
|
||||
// 新增:记录所有动态添加的路由名,用于清理
|
||||
addedRouteNames: []
|
||||
}),
|
||||
|
||||
// 新增 action:清除所有动态路由
|
||||
actions: {
|
||||
removeAddedRoutes() {
|
||||
this.addedRouteNames.forEach(name => {
|
||||
try { router.removeRoute(name) } catch(e) {}
|
||||
})
|
||||
this.addedRouteNames = []
|
||||
},
|
||||
|
||||
generateRoutes(roles) {
|
||||
return new Promise(resolve => {
|
||||
// 【修复】生成新路由前,先清除所有旧的动态路由
|
||||
this.removeAddedRoutes()
|
||||
|
||||
getRouters().then(res => {
|
||||
const sdata = JSON.parse(JSON.stringify(res.data))
|
||||
const rdata = JSON.parse(JSON.stringify(res.data))
|
||||
const defaultData = JSON.parse(JSON.stringify(res.data))
|
||||
const sidebarRoutes = filterAsyncRouter(sdata)
|
||||
const rewriteRoutes = filterAsyncRouter(rdata, false, true)
|
||||
const defaultRoutes = filterAsyncRouter(defaultData)
|
||||
const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
|
||||
|
||||
// 记录并添加路由
|
||||
const addedNames = []
|
||||
asyncRoutes.forEach(route => {
|
||||
router.addRoute(route)
|
||||
if (route.name) addedNames.push(route.name)
|
||||
})
|
||||
addNotFoundRoute()
|
||||
|
||||
// 记录后端动态路由名
|
||||
this.trackAddedRoutes(rewriteRoutes, addedNames)
|
||||
|
||||
this.setRoutes(rewriteRoutes)
|
||||
this.setSidebarRouters(constantRoutes.concat(sidebarRoutes))
|
||||
this.setDefaultRoutes(sidebarRoutes)
|
||||
this.setTopbarRoutes(defaultRoutes)
|
||||
resolve(rewriteRoutes)
|
||||
}).catch(err => {
|
||||
console.error('获取路由失败:', err)
|
||||
addNotFoundRoute()
|
||||
this.setRoutes([])
|
||||
resolve([])
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 新增:递归追踪所有动态添加的路由名
|
||||
trackAddedRoutes(routes, names) {
|
||||
routes.forEach(route => {
|
||||
if (route.name) names.push(route.name)
|
||||
if (route.children) this.trackAddedRoutes(route.children, names)
|
||||
})
|
||||
this.addedRouteNames = [...new Set(names)]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 修改2:`healthlink-his-ui/src/store/modules/user.js` — logOut 时重置权限状态
|
||||
|
||||
```javascript
|
||||
import usePermissionStore from '@/store/modules/permission'
|
||||
|
||||
// 在 logOut action 中增加:
|
||||
logOut() {
|
||||
return new Promise((resolve, reject) => {
|
||||
logout(this.token).then(() => {
|
||||
this.token = ''
|
||||
this.roles = []
|
||||
this.permissions = []
|
||||
this.tenantId = ''
|
||||
removeToken()
|
||||
try { useTagsViewStore().delAllViews() } catch(e) {}
|
||||
// 【修复】清除所有动态路由,防止旧用户路由残留
|
||||
try { usePermissionStore().removeAddedRoutes() } catch(e) {}
|
||||
try { usePermissionStore().$reset() } catch(e) {}
|
||||
resolve()
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
#### 修改3:`healthlink-his-ui/src/permission.js` — 增强路由守卫权限校验
|
||||
|
||||
在现有的 `resolved.matched.length` 检查之后,增加基于用户权限的二次校验:
|
||||
|
||||
```javascript
|
||||
// 在 "return true" 之前,增加权限校验
|
||||
// 获取目标路由对应的菜单路径
|
||||
const targetPath = to.path
|
||||
const sidebarRoutes = usePermissionStore().sidebarRouters
|
||||
const allPaths = collectAllPaths(sidebarRoutes) // 递归收集所有已授权路径
|
||||
if (allPaths.size > 0 && !allPaths.has(targetPath) && !isConstantPath(targetPath)) {
|
||||
ElMessage.warning('无权访问该页面')
|
||||
return { path: '/' }
|
||||
}
|
||||
return true
|
||||
```
|
||||
|
||||
其中辅助函数:
|
||||
```javascript
|
||||
// 常量路由(始终允许访问)不需要权限校验
|
||||
function isConstantPath(path) {
|
||||
const constantPaths = ['/', '/index', '/login', '/register', '/401', '/lock', '/user/profile', '/redirect']
|
||||
return constantPaths.some(p => path === p || path.startsWith(p + '/'))
|
||||
}
|
||||
|
||||
// 递归收集 sidebarRouters 中所有路由路径
|
||||
function collectAllPaths(routes) {
|
||||
const paths = new Set()
|
||||
function walk(items) {
|
||||
items.forEach(r => {
|
||||
if (r.path) paths.add(r.path.startsWith('/') ? r.path : '/' + r.path)
|
||||
if (r.children) walk(r.children)
|
||||
})
|
||||
}
|
||||
walk(routes)
|
||||
return paths
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、路由决策
|
||||
|
||||
**FIXER**: guanyu(后端开发 + 通用修复)
|
||||
|
||||
**REASON**: 此 Bug 的修复**全部在前端**(`permission.js` 路由守卫、`permission.js` store、`user.js` store),涉及 Vue Router 路由生命周期管理和 Pinia store 状态管理,属于前端核心逻辑修改。虽然分类为"后端开发"的关羽,但此任务本质是前端路由/权限架构修复,**更应交给 zhaoyun(前端开发)**。因为需要修改 3 个前端核心文件(`permission.js` store、`user.js` store、路由守卫 `permission.js`),涉及 Vue Router 4 的 `addRoute/removeRoute` 生命周期、Pinia store 重置、路由守卫权限校验等前端专属知识。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
101
MD/bugs/BUG_721_ANALYSIS.md
Normal file
101
MD/bugs/BUG_721_ANALYSIS.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# Bug #721 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 01:44:34
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 721
|
||||
- **标题**: 【影像管理】点击新增检查出现sql语句报错
|
||||
- **模块**: 住院医生工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
已定位根因,分析完成。
|
||||
|
||||
---
|
||||
|
||||
### 一、Bug 理解
|
||||
|
||||
**禅道原文:**
|
||||
> **Bug #721**:【影像管理】点击新增检查出现sql语句报错
|
||||
>
|
||||
> **重现步骤**:登录内科医生1的账号:doctor1 密码:123456进入影像管理→点击新增检查→填写新增影像检查记录→确认 → 出现报错
|
||||
>
|
||||
> **期望结果**:能够正常的新增成功不会出现报错
|
||||
|
||||
**附图关键信息:**
|
||||
- 错误信息:`ERROR: null value in column "patient_id" of relation "radiology_image_comparison" violates not-null constraint`
|
||||
- 失败的 INSERT SQL:`INSERT INTO radiology_image_comparison (id, examination_type, examination_name, body_part, finding_text, conclusion_text, doctor_name, create_by, create_time, tenant_id)` — 注意 **`patient_id` 列根本不在 INSERT 语句中**,说明实体的 `patientId` 字段始终为 null
|
||||
- 表单弹窗里**没有患者ID字段**,只有检查类型、检查名称、检查部位等字段
|
||||
|
||||
**综合总结:** 用户在影像对比页面点击"新增检查"时,弹窗表单没有 `patientId` 字段,提交后后端实体的 `patientId` 为 null,而数据库表 `radiology_image_comparison.patient_id` 有 NOT NULL 约束,导致插入失败。
|
||||
|
||||
---
|
||||
|
||||
### 二、根因分析
|
||||
|
||||
**根因:前后端均缺失 `patientId` 传递**
|
||||
|
||||
| 层级 | 问题 |
|
||||
|------|------|
|
||||
| **前端 `index.vue`** | `formData` 初始值无 `patientId`,弹窗表单无患者ID输入,`submitForm()` 直接提交 `formData.value`,不含 `patientId` |
|
||||
| **后端 Controller** | `addRecord(@RequestBody RadiologyImageComparison record)` 直接 `save()`,既不校验 `patientId` 是否为空,也不从页面查询区的 `patientId` 中获取 |
|
||||
| **数据库** | `radiology_image_comparison.patient_id` 列有 NOT NULL 约束,插入空值失败 |
|
||||
|
||||
**涉及文件:**
|
||||
- `healthlink-his-ui/src/views/radiologycomparison/index.vue` — formData 缺少 patientId
|
||||
- `healthlink-his-server/.../RadiologyComparisonController.java` — addRecord 未校验/设置 patientId
|
||||
|
||||
---
|
||||
|
||||
### 三、修复方案
|
||||
|
||||
**修改 1:前端 `index.vue`** — `submitForm()` 中补充 `patientId`
|
||||
|
||||
```js
|
||||
async function submitForm() {
|
||||
// 补充患者ID(来自页面查询区)
|
||||
formData.value.patientId = patientId.value ? Number(patientId.value) : null
|
||||
await addRecord(formData.value)
|
||||
ElMessage.success('新增成功')
|
||||
showAdd.value = false
|
||||
loadData()
|
||||
}
|
||||
```
|
||||
|
||||
**修改 2:后端 `RadiologyComparisonController.java`** — `addRecord` 增加参数校验
|
||||
|
||||
```java
|
||||
@PostMapping("/add")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> addRecord(@RequestBody RadiologyImageComparison record) {
|
||||
if (record.getPatientId() == null) {
|
||||
return R.fail("患者ID不能为空");
|
||||
}
|
||||
record.setCreateTime(new Date());
|
||||
comparisonService.save(record);
|
||||
return R.ok(record);
|
||||
}
|
||||
```
|
||||
|
||||
**修改范围:** 2个文件,改动量极小,不破坏现有功能。
|
||||
|
||||
---
|
||||
|
||||
### 四、路由决策
|
||||
|
||||
**FIXER: guanyu**
|
||||
**REASON: 后端 Controller 缺少参数校验是核心根因(后端权重更高),前端 formData 传递也需要同步修复,优先由 guanyu 处理后端校验 + 前端联动调整。**
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: 后端 Controller 缺少参数校验是核心根因(后端权重更高),前端 formData 传递也需要同步修复,优先由 guanyu 处理后端校验 + 前端联动调整。**
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
168
MD/bugs/BUG_722_ANALYSIS.md
Normal file
168
MD/bugs/BUG_722_ANALYSIS.md
Normal file
@@ -0,0 +1,168 @@
|
||||
# Bug #722 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 01:41:53
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 722
|
||||
- **标题**: 【住院医生工作站】住院病历的页面打不开
|
||||
- **模块**: 住院医生工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
Based on my thorough analysis, here's the complete Bug #722 analysis:
|
||||
|
||||
---
|
||||
|
||||
### 一、Bug 理解
|
||||
|
||||
**Bug 标题**: 【住院医生工作站】住院病历的页面打不开
|
||||
|
||||
**重现步骤**: 登录内科医生1账号 doctor1/123456 → 进入住院管理 → 住院医生增强 → 住院病历
|
||||
|
||||
**期望结果**: 能够正常打开住院病历
|
||||
|
||||
**实际结果**: 页面标签 "住院病历" 已打开,但主内容区域完全空白,无任何表单、列表、患者信息或操作界面加载。无错误提示。
|
||||
|
||||
**附图关键信息**:
|
||||
- 左侧导航菜单"住院病历"已高亮(蓝色)
|
||||
- 顶部已打开"住院病历 ×"标签页
|
||||
- 主内容区域**完全空白**,无任何UI元素
|
||||
- 无弹出错误提示框
|
||||
|
||||
**综合总结**: 用户通过侧边栏菜单点击"住院病历",标签页成功创建,但页面主体内容区域渲染为空白,无任何数据或组件显示。问题可能源于前端路由配置、组件加载失败或数据获取异常。
|
||||
|
||||
---
|
||||
|
||||
### 二、根因分析
|
||||
|
||||
通过代码链路追踪,定位到以下技术问题链:
|
||||
|
||||
#### 根因1(最可能):菜单路由的 `component` 字段路径与实际组件路径不匹配
|
||||
|
||||
**关键代码链路**:
|
||||
- 路由动态加载:`src/store/modules/permission.js` → `loadView()` 函数通过 `import.meta.glob` 匹配组件路径
|
||||
- 匹配逻辑:`dir === view`,其中 `dir = path.split('views/')[1].split('.vue')[0]`
|
||||
- 实际文件:`inpatientDoctor/home/index.vue` → 路径 `inpatientDoctor/home/index`
|
||||
- 如果数据库菜单 `component` 字段为 `inpatientDoctor/home/emr/index`(EMR子组件),则**脱离了 home 页面的患者列表和标签页容器**,EMR 组件独立渲染但无法获取患者上下文
|
||||
|
||||
**验证方法**: 查询数据库 `sys_menu` 表中"住院病历"菜单项的 `component` 字段值
|
||||
|
||||
#### 根因2(补充):EMR 组件无患者上下文时渲染空白
|
||||
|
||||
**关键代码** (`inpatientDoctor/home/emr/index.vue`):
|
||||
```javascript
|
||||
// line 172 - 组件使用 localPatientInfo
|
||||
import {localPatientInfo as patientInfo} from '../store/localPatient.js';
|
||||
|
||||
// line 903 - onMounted 中依赖 patientInfo
|
||||
onMounted(async () => {
|
||||
await queryTemplateTree();
|
||||
if (patientInfo.value && patientInfo.value.patientId && ...) {
|
||||
nextTick(() => { selectDefaultTemplate(); });
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
当 EMR 作为独立路由组件加载时:
|
||||
1. `localPatientInfo` 为空(未通过 home 页面的患者列表选择患者)
|
||||
2. `queryTemplateTree()` 执行后模板树为空(可能因 `primaryMenuEnum=1` 无匹配文书定义)
|
||||
3. `currentComponent` 保持为空字符串,`<component :is="currentComponent" />` 不渲染任何内容
|
||||
4. 整页空白
|
||||
|
||||
#### 根因3(次要):PatientList 组件 API 调用缺少状态过滤
|
||||
|
||||
**关键代码** (`inpatientDoctor/home/index.vue`):
|
||||
```javascript
|
||||
// line 90 - getList 使用 status: 5
|
||||
getPatientList({ status: 5, searchKey: searchData.keyword })
|
||||
```
|
||||
|
||||
**但** `PatientList/patient-list.vue` 内部**独立调用** `getPatientList` **不传 status 参数**,导致返回所有患者(可能为空或不正确)。
|
||||
|
||||
---
|
||||
|
||||
### 三、修复方案
|
||||
|
||||
#### 修复1(核心):确认并修正菜单路由 component 字段
|
||||
|
||||
**检查步骤**:
|
||||
```sql
|
||||
SELECT menu_id, menu_name, component, path
|
||||
FROM sys_menu
|
||||
WHERE menu_name LIKE '%住院病历%';
|
||||
```
|
||||
|
||||
**预期问题**: component 字段值为 `inpatientDoctor/home/emr/index`
|
||||
|
||||
**修复**:
|
||||
```sql
|
||||
UPDATE sys_menu
|
||||
SET component = 'inpatientDoctor/home/index'
|
||||
WHERE menu_name = '住院病历' AND parent_id = (
|
||||
SELECT menu_id FROM sys_menu WHERE menu_name = '住院医生增强'
|
||||
);
|
||||
```
|
||||
|
||||
#### 修复2(防御性):EMR 组件增加患者未选择提示
|
||||
|
||||
**文件**: `healthlink-his-ui/src/views/inpatientDoctor/home/emr/index.vue`
|
||||
|
||||
在 `onMounted` 的 `queryTemplateTree()` 之后增加患者状态检查:
|
||||
|
||||
```javascript
|
||||
onMounted(async () => {
|
||||
await queryTemplateTree();
|
||||
if (
|
||||
patientInfo.value &&
|
||||
patientInfo.value.patientId &&
|
||||
Object.keys(patientInfo.value).length > 0
|
||||
) {
|
||||
nextTick(() => {
|
||||
selectDefaultTemplate();
|
||||
});
|
||||
} else {
|
||||
// 增加:无患者时显示提示而非空白
|
||||
ElMessage.info('请先在左侧选择患者');
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### 修复3(可选):PatientList 组件传递 status 参数
|
||||
|
||||
**文件**: `healthlink-his-ui/src/components/PatientList/patient-list.vue`
|
||||
|
||||
确保 `getPatientList` 调用时传入 `status` prop:
|
||||
|
||||
```javascript
|
||||
const getList = () => {
|
||||
queryloading.value = true;
|
||||
getPatientList({
|
||||
status: props.status || 5,
|
||||
searchKey: searchData.keyword
|
||||
}).then(res => {
|
||||
// ...
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 四、路由决策
|
||||
|
||||
**FIXER**: `zhaoyun`(前端开发)
|
||||
|
||||
**REASON**: 本 Bug 核心是前端路由配置(菜单 component 字段映射)和 EMR 组件渲染问题,涉及前端路由动态加载机制、Vue 组件容器结构、以及患者上下文状态管理,属于纯前端问题链。需要 zhaoyun 验证数据库菜单 component 路径、修复路由映射,并增强 EMR 组件的容错提示。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
98
MD/bugs/BUG_723_ANALYSIS.md
Normal file
98
MD/bugs/BUG_723_ANALYSIS.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# Bug #723 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 01:31:01
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 723
|
||||
- **标题**: 【住院医生工作站】有两个住院医生增强
|
||||
- **模块**: 门诊医生工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
Now I have enough context to provide the analysis. Let me compile the findings.
|
||||
|
||||
---
|
||||
|
||||
## 一、Bug 理解
|
||||
|
||||
**禅道原文引用:**
|
||||
|
||||
- **标题**:【住院医生工作站】有两个住院医生增强
|
||||
- **重现步骤**:登录内科医生1账号:doctor1 密码:123456 打开住院管理有两个住院增强
|
||||
- **结果**:出现重复了
|
||||
- **期望**:不会出现重复的模块卡片,显得很冗余
|
||||
|
||||
**附图关键信息:**
|
||||
|
||||
截图显示左侧导航菜单栏,展开"住院管理"一级菜单后,二级菜单列表中出现了**两个完全相同的"住院医生增强"**条目(图标、文字均一致),紧邻排列。
|
||||
|
||||
**综合总结:** 用户登录 doctor1 账号后,在"住院管理"导航菜单下看到两个一模一样的"住院医生增强"菜单入口,造成界面冗余和用户困惑。这是一个**菜单数据重复问题**,需要删除其中一条重复的 `sys_menu` 记录。
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
**根因:`sys_menu` 数据库表中存在两条 `menu_name = '住院医生增强'` 且 `parent_id` 相同的记录。**
|
||||
|
||||
在 RuoYi 架构中,导航菜单由后端 `sys_menu` 表动态提供,前端根据 API 返回的菜单树渲染侧边栏。具体数据链路:
|
||||
|
||||
```
|
||||
sys_menu 表 → SysMenuMapper.xml (selectMenuList/selectMenuTreeByMenuIds)
|
||||
→ SysMenuService → SysMenuController (/system/menu/list)
|
||||
→ 前端 usePermissionStore → Sidebar 渲染
|
||||
```
|
||||
|
||||
最可能的产生原因:某次 Flyway 迁移或手动数据库操作中,对"住院医生增强"菜单执行了**两次 INSERT**,导致 `sys_menu` 表中出现两条同名、同父节点的菜单记录。前端渲染时会忠实地展示所有有效菜单,因此出现重复。
|
||||
|
||||
**涉及的关键文件:**
|
||||
- `core-system/src/main/resources/mapper/system/SysMenuMapper.xml` — 菜单查询 SQL
|
||||
- `sys_menu` 表 — 存储菜单数据(`menu_id`, `menu_name`, `parent_id`, `path`, `component`)
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
**方案:创建 Flyway 迁移脚本,删除 `sys_menu` 表中 `menu_name = '住院医生增强'` 的重复记录(保留 `menu_id` 最小的一条)。**
|
||||
|
||||
**步骤:**
|
||||
|
||||
1. **创建 Flyway 迁移文件** `V45__fix_duplicate_menu_doctor_enhanced.sql`:
|
||||
|
||||
```sql
|
||||
-- V45: 修复 Bug#723 — 删除 sys_menu 中重复的"住院医生增强"菜单条目
|
||||
-- 保留 menu_id 最小的那条,删除其余重复记录
|
||||
DELETE FROM sys_menu
|
||||
WHERE menu_name = '住院医生增强'
|
||||
AND menu_id NOT IN (
|
||||
SELECT MIN(menu_id)
|
||||
FROM sys_menu
|
||||
WHERE menu_name = '住院医生增强'
|
||||
);
|
||||
```
|
||||
|
||||
**注意事项:**
|
||||
- Flyway 迁移一旦执行不可回滚,所以此 SQL 使用了子查询保留最小 `menu_id` 的策略,确保只删重复
|
||||
- 需要确认"住院医生增强"对应的 `path` 和 `component` 是否也一致(如果不一致,说明两个菜单指向不同功能,需要人工判断保留哪个)
|
||||
- 修复后需要**重新登录** doctor1 账号验证侧边栏不再重复
|
||||
|
||||
---
|
||||
|
||||
## 四、路由决策
|
||||
|
||||
**FIXER**: `xunyu`(荀彧 / DBA)
|
||||
|
||||
**REASON**: 这是纯数据库数据问题(`sys_menu` 表重复记录),不涉及 Java 代码或前端代码修改,只需要创建一条 Flyway 迁移 SQL 删除重复菜单记录,属于数据库变更范畴,由 DBA 角色处理最合适。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
178
MD/bugs/BUG_724_ANALYSIS.md
Normal file
178
MD/bugs/BUG_724_ANALYSIS.md
Normal file
@@ -0,0 +1,178 @@
|
||||
# Bug #724 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 01:24:08
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 724
|
||||
- **标题**: 【合理用药】模块下的功能卡片打开都会出现报错
|
||||
- **模块**: 手术麻醉管理
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
Now I have a clear picture. Let me trace the full request flow and output my analysis.
|
||||
|
||||
---
|
||||
|
||||
## 一、Bug 理解
|
||||
|
||||
### 禅道原文引用
|
||||
|
||||
**Bug 标题**: 【合理用药】模块下的功能卡片打开都会出现报错
|
||||
|
||||
**重现步骤**: 登录内科医生1的账号 doctor1 / 123456 → 打开合理用药 → 点击合理用药下面的模块
|
||||
|
||||
**期望结果**: 不会出现报错,能够正常进入该模块下的页面
|
||||
|
||||
### 附图关键信息
|
||||
|
||||
截图中红色错误横幅:
|
||||
```
|
||||
No static resource healthlink-his/api/v1/antibiotic/statistics for request '/healthlink-his/healthlink-his/api/v1/antibiotic/statistics'.
|
||||
```
|
||||
|
||||
左侧导航栏"合理用药"展开,包含四个子模块:抗菌药物规则、药物相互作用、审核日志、合理用药统计。四个统计卡片全部为 0,表格显示"暂无数据"。所有模块页面都会出现相同报错。
|
||||
|
||||
### 综合总结
|
||||
|
||||
用户登录医生账号后,打开"合理用药"模块下的所有子页面(抗菌药物规则、药物相互作用、审核日志、合理用药统计),页面顶部均出现红色错误提示。错误信息显示请求路径中 `/healthlink-his` 出现了两次,导致 Spring Boot 无法匹配到任何 Controller 端点,所有合理用药相关 API 请求全部失败。
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
### 错误路径解剖
|
||||
|
||||
```
|
||||
浏览器请求: /healthlink-his/healthlink-his/api/v1/antibiotic/statistics
|
||||
↑ 第一次 ↑ Spring Boot context-path
|
||||
```
|
||||
|
||||
Spring Boot 收到请求后:
|
||||
1. 去除 context-path `/healthlink-his` → 剩余路径:`/healthlink-his/api/v1/antibiotic/statistics`
|
||||
2. 匹配 Controller:`AntibioticController` 的 `@RequestMapping("/api/v1/antibiotic")` → **无法匹配**(路径多了一层 `/healthlink-his`)
|
||||
3. Spring Boot 退化为静态资源查找 → 找不到 → 返回 404 错误
|
||||
|
||||
### 请求链路追踪
|
||||
|
||||
```
|
||||
前端 API 调用:
|
||||
request.js → baseURL = import.meta.env.VITE_APP_BASE_API
|
||||
api/antibiotic/index.js → url = '/api/v1/antibiotic/statistics'
|
||||
最终 URL = ${VITE_APP_BASE_API}/api/v1/antibiotic/statistics
|
||||
|
||||
错误路径 = /healthlink-his/healthlink-his/api/v1/antibiotic/statistics
|
||||
```
|
||||
|
||||
**反推得出**:`VITE_APP_BASE_API` 在实际部署环境中被设置为 `/healthlink-his`(或类似的包含 context-path 的值),而非代码仓库中定义的 `/prd-api` 或 `/dev-api`。
|
||||
|
||||
### 根因结论
|
||||
|
||||
**上下文路径 `/healthlink-his` 被重复叠加了两次。** 可能的触发场景:
|
||||
|
||||
| 层 | 配置 | 效果 |
|
||||
|---|---|---|
|
||||
| `VITE_APP_BASE_API`(实际部署值) | `/healthlink-his`(异常值,代码仓库中为 `/prd-api`) | 前端发送 `/healthlink-his/api/v1/...` |
|
||||
| Nginx 代理 | `location /healthlink-his/ { proxy_pass http://backend/healthlink-his/; }` | 转发后路径变为 `/healthlink-his/api/v1/...` |
|
||||
| Spring Boot context-path | `context-path: /healthlink-his` | 去除一次后剩余 `/healthlink-his/api/v1/...` → 无法匹配 |
|
||||
|
||||
**核心矛盾**:前端 API 路径 `/api/v1/...` 是正确的相对路径,但 `VITE_APP_BASE_API` 环境变量在部署时被设置为了 `/healthlink-his`,与 Spring Boot 的 `context-path` 冲突,导致路径叠加。
|
||||
|
||||
### 涉及文件
|
||||
|
||||
| 文件 | 作用 | 是否需要修改 |
|
||||
|---|---|---|
|
||||
| `healthlink-his-ui/src/utils/request.js:56` | `baseURL: import.meta.env.VITE_APP_BASE_API` | ✅ 需确认部署时的值 |
|
||||
| `healthlink-his-ui/src/api/antibiotic/index.js` | 抗菌药物 API 定义(`/api/v1/antibiotic/...`) | ❌ 路径正确 |
|
||||
| `healthlink-his-ui/src/api/rationaldrug.js` | 合理用药 API 定义(`/api/v1/rational-drug/...`) | ❌ 路径正确 |
|
||||
| `healthlink-his-server/.../application.yml:20` | `context-path: /healthlink-his` | ❌ 后端正确 |
|
||||
| `deploy/nginx-healthlink-his.conf` | Nginx 代理配置 | ✅ 需确认实际部署版本 |
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
### 方案 1:修复部署环境的 `VITE_APP_BASE_API`(推荐,最小改动)
|
||||
|
||||
**问题本质**:部署环境使用了错误的 `VITE_APP_BASE_API` 值。
|
||||
|
||||
**修复**:确保部署时使用正确的环境文件:
|
||||
|
||||
```bash
|
||||
# 生产环境部署命令
|
||||
cd healthlink-his-ui
|
||||
npm run build -- --mode prod
|
||||
```
|
||||
|
||||
确保 `.env.prod` 中的值为:
|
||||
```
|
||||
VITE_APP_BASE_API = '/prd-api'
|
||||
```
|
||||
|
||||
对应的 Nginx 配置(`deploy/nginx-healthlink-his.conf`):
|
||||
```nginx
|
||||
location /prd-api/ {
|
||||
proxy_pass http://127.0.0.1:18082/healthlink-his/;
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### 方案 2:如果部署环境必须使用 `/healthlink-his` 作为前端路径
|
||||
|
||||
如果实际部署环境中前端通过 `http://server/healthlink-his/` 访问,Nginx 也需要相应调整:
|
||||
|
||||
```nginx
|
||||
# 方案 A:Nginx 不在 proxy_pass 中添加 context-path(让 Spring Boot 处理)
|
||||
location /healthlink-his/api/ {
|
||||
proxy_pass http://127.0.0.1:18082; # 注意:无尾部路径
|
||||
...
|
||||
}
|
||||
|
||||
# 方案 B:前端 API 路径不包含 context-path
|
||||
# VITE_APP_BASE_API = ''(空字符串),前端请求 /api/v1/...
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:18082/healthlink-his;
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### 方案 3:代码层面的防御性修复(可选)
|
||||
|
||||
在 `request.js` 中添加 URL 校验,防止 context-path 重复:
|
||||
|
||||
```javascript
|
||||
// request.js 中 axios 实例创建后
|
||||
service.interceptors.request.use(config => {
|
||||
// 防止 baseURL 包含后端 context-path 导致重复
|
||||
if (config.baseURL && config.baseURL.includes('/healthlink-his')) {
|
||||
console.warn('[WARN] VITE_APP_BASE_API 包含 /healthlink-his,可能导致路径重复!')
|
||||
}
|
||||
// ...existing code
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、路由决策
|
||||
|
||||
**FIXER: guanyu(后端)+ zhaoyun(前端)联合排查,优先 zhaoyun**
|
||||
|
||||
**REASON**: 本 Bug 的根因是**部署配置问题**而非代码缺陷。需要:
|
||||
1. **zhaoyun** 确认实际部署环境的 `VITE_APP_BASE_API` 值,检查前端 `.env` 文件和构建命令是否正确
|
||||
2. **guanyu** 确认后端 Spring Boot `context-path` 与 Nginx 代理规则的匹配关系
|
||||
3. 修复的核心是**对齐前端 baseURL 与 Nginx 代理规则**,确保 `/healthlink-his` 不被叠加两次
|
||||
|
||||
**优先级**:zhaoyun 先检查 `.env.prod` 和实际构建配置 → guanyu 验证 Nginx 配置 → 联合确认修复
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
121
MD/bugs/BUG_725_ANALYSIS.md
Normal file
121
MD/bugs/BUG_725_ANALYSIS.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# Bug #725 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 01:14:15
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 725
|
||||
- **标题**: 【急诊管理】绿色通道的激活出现报错
|
||||
- **模块**: 会诊管理
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
I have all the information needed. Let me now output the analysis.
|
||||
|
||||
---
|
||||
|
||||
## 一、Bug 理解
|
||||
|
||||
**禅道 Bug #725**:【急诊管理】绿色通道的激活出现报错
|
||||
|
||||
**重现步骤**:
|
||||
> 登录内科医生1账号:doctor1 密码:123456 → 打开急诊管理 → 进入绿色通道激活
|
||||
|
||||
**期望结果**:能够正常激活绿色通道
|
||||
|
||||
**错误信息**:
|
||||
```
|
||||
Error updating database. Cause: PSQLException: ERROR: null value in column "patient_id"
|
||||
of relation "emergency_green_channel" violates not-null constraint
|
||||
```
|
||||
|
||||
**附图分析**:
|
||||
- 弹窗表单中「患者ID」字段为空(`el-input-number` 未输入值),但用户点击了「激活」按钮
|
||||
- 数据库 INSERT SQL:`INSERT INTO emergency_green_channel (id, disease_type, target_time, doctor, activate_time, create_by, create_time, tenant_id)` — **`patient_id` 完全不在 INSERT 列表中**
|
||||
- 表单规则 `addFormRules.patientId` 声明了 required,但实际未阻止提交
|
||||
|
||||
**综合总结**:用户点击「激活绿色通道」时,弹窗表单中「患者ID」为空就直接提交,后端 MyBatis-Plus 生成的 INSERT 语句完全跳过了 `patient_id` 字段(null 值被 MyBatis 默认策略忽略),导致违反数据库 `NOT NULL` 约束。前端表单的 required 校验规则未生效,后端校验也未拦住请求。
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
**根因链路(全链路 6 环)**:
|
||||
|
||||
| 环 | 问题 |
|
||||
|---|---|
|
||||
| ① 录入(前端) | `addFormRules.patientId` 的 `required` 规则触发条件是 `trigger:'blur'`,但 `el-input-number` 的 blur 事件对 null 值不触发校验;`submitAdd` 中的 `validate()` 可能静默通过 |
|
||||
| ② 验证(后端) | `EmergencyController.activateGreenChannel()` 有 `if (gc.getPatientId() == null)` 检查,但 **前端根本没发起带正确错误码的请求** — MyBatis-Plus 异常被全局异常处理器捕获,前端收到的是原始错误堆栈文本而非结构化 R.fail |
|
||||
| ③ 业务 | `EmergencyGreenChannelServiceImpl` 无额外校验,直接继承 MyBatis-Plus `save()` |
|
||||
| ④ 持久化 | MyBatis-Plus 默认 `FieldStrategy.INSERT_NOT_NULL`:null 字段不写入 INSERT → `patient_id` 缺失 |
|
||||
| ⑤ 存储 | `emergency_green_channel` 表定义 `patient_id BIGINT NOT NULL` → 报错 |
|
||||
|
||||
**涉及文件**:
|
||||
- `healthlink-his-server/.../web/emergency/controller/EmergencyController.java` — 后端校验逻辑(已有但被跳过)
|
||||
- `healthlink-his-ui/src/views/emergency/greentrack/index.vue` — 前端表单校验失效
|
||||
- `healthlink-his-ui/src/views/emergency/greentrack/api.js` — API 调用
|
||||
- `healthlink-his-server/.../emergency/domain/EmergencyGreenChannel.java` — 实体定义
|
||||
- `V32__followup_pathology_emergency.sql` — DB 表结构(`NOT NULL` 约束)
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
### 修复点 1:前端表单校验(`greentrack/index.vue`)
|
||||
|
||||
**问题**:`submitAdd` 中 `validate()` 逻辑有隐患 — `el-input-number` 组件在未输入时 v-model 为 `null`,但 required 校验的 `trigger:'blur'` 对此场景不可靠。更关键的是,**validate 的 try-catch 写法在某些情况下可能跳过校验**。
|
||||
|
||||
**修改**:改为标准 async/await 写法,并将 trigger 改为 `change`:
|
||||
|
||||
```js
|
||||
// 修改 addFormRules
|
||||
const addFormRules = {
|
||||
patientId: [{required: true, message: '请输入患者ID', trigger: 'change'}]
|
||||
}
|
||||
|
||||
// 修改 submitAdd — 移除 try-catch,使用标准 await
|
||||
const submitAdd = async () => {
|
||||
if (addFormRef.value) {
|
||||
const valid = await addFormRef.value.validate().catch(() => false)
|
||||
if (!valid) return
|
||||
}
|
||||
await activate(addForm.value)
|
||||
ElMessage.success('绿色通道已激活')
|
||||
addVisible.value = false
|
||||
loadData()
|
||||
refreshStats()
|
||||
}
|
||||
```
|
||||
|
||||
### 修复点 2:后端校验(`EmergencyController.java`)
|
||||
|
||||
后端已有 `gc.getPatientId() == null` 检查,但需确认 `R.fail()` 返回格式被前端正确识别。当前后端代码已正确,无需修改后端(校验逻辑存在且会返回错误)。如果前端仍能穿透,则需要检查全局异常处理器是否正确包装了 `MethodArgumentNotValidException`。
|
||||
|
||||
### 修复点 3(可选优化):增加后端 `@Valid` 注解
|
||||
|
||||
在 `activateGreenChannel` 方法参数上增加 `@Valid` 并在实体 `patientId` 字段加 `@NotNull`,作为双保险:
|
||||
|
||||
```java
|
||||
public R<?> activateGreenChannel(@RequestBody @Valid EmergencyGreenChannel gc) {
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、路由决策
|
||||
|
||||
**FIXER**: **zhaoyun**(前端开发)
|
||||
|
||||
**REASON**: 根因在前端表单校验失效 — `addFormRules` 的 trigger 选择不当 + `submitAdd` 中 validate 的错误处理逻辑有缺陷。后端校验逻辑已存在且正确,核心修复是前端表单校验。修改范围仅限 1 个前端文件 `greentrack/index.vue`。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
134
MD/bugs/BUG_726_ANALYSIS.md
Normal file
134
MD/bugs/BUG_726_ANALYSIS.md
Normal file
@@ -0,0 +1,134 @@
|
||||
# Bug #726 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 01:12:01
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 726
|
||||
- **标题**: 【病理管理】开病历医嘱出现报错
|
||||
- **模块**: 疾病报告管理
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
Now I have all the information needed for a complete analysis. Let me compile the findings.
|
||||
|
||||
---
|
||||
|
||||
### 一、Bug 理解
|
||||
|
||||
**禅道 Bug #726:【病理管理】开病历医嘱出现报错**
|
||||
|
||||
- **重现步骤**: 登录内科医生1账号(doctor1/123456),进入病理管理→病理医嘱→点击"开病理医嘱"报卡→点击确定
|
||||
- **结果**: 出现报错 `ERROR: null value in column "patient_id" of relation "pathology_order" violates not-null constraint`
|
||||
- **期望**: 能够正常进行该项操作
|
||||
|
||||
**附图关键信息**:
|
||||
- 弹窗表单中"患者ID"、"患者姓名"、"就诊ID"三个字段均为空
|
||||
- `el-input-number` 控件未填入值,`patientId` 为 `null`
|
||||
- 后端执行的 INSERT SQL 中**完全没有 `patient_id` 列**,说明 MyBatis-Plus 对 null 值字段执行了跳过策略
|
||||
|
||||
**综合总结**: 用户在"开病理医嘱"弹窗中未填写患者ID(或系统未自动填充),导致提交时 `patientId=null`。MyBatis-Plus 的默认 insert 策略跳过了 null 字段(INSERT SQL 中无 `patient_id` 列),而数据库 `pathology_order.patient_id` 列有 `NOT NULL` 约束,导致插入失败。
|
||||
|
||||
---
|
||||
|
||||
### 二、根因分析
|
||||
|
||||
**直接原因**: 前端表单提交了 `patientId: null`,后端 Controller `addOrder()` 未做任何校验直接调用 `orderService.save(order)`,MyBatis-Plus 生成的 INSERT 不包含 `patient_id` 列,触发 PostgreSQL NOT NULL 约束。
|
||||
|
||||
**根因链条**:
|
||||
1. **前端** `healthlink-his-ui/src/views/pathology/order/index.vue`: `el-input-number` 的 `v-model="form.patientId"` 初始值为 `null`,用户未手动输入时保持 `null`
|
||||
2. **前端** `submitForm()`: 无任何校验逻辑,直接调用 `add(form.value)`
|
||||
3. **后端** `PathologyController.addOrder()`: 无参数校验(无 `@Valid`、无手动检查),直接 `orderService.save(order)`
|
||||
4. **DB**: `pathology_order.patient_id BIGINT NOT NULL`(V32 迁移脚本定义)
|
||||
|
||||
**涉及文件**:
|
||||
| 文件 | 问题 |
|
||||
|------|------|
|
||||
| `healthlink-his-ui/src/views/pathology/order/index.vue` | 表单无校验,`patientId` 可为 null |
|
||||
| `healthlink-his-server/.../web/pathology/controller/PathologyController.java` | `addOrder()` 无参数校验 |
|
||||
| `healthlink-his-domain/.../pathology/domain/PathologyOrder.java` | Entity 无 `@NotNull` 注解 |
|
||||
|
||||
---
|
||||
|
||||
### 三、修复方案
|
||||
|
||||
**方案:前后端双重校验 + 自动获取患者信息**
|
||||
|
||||
#### 1. 后端:Controller 加校验(1 个文件)
|
||||
|
||||
**文件**: `PathologyController.java` 的 `addOrder()` 方法
|
||||
|
||||
**修改内容**: 在保存前校验必填字段 `patientId` 和 `patientName`:
|
||||
|
||||
```java
|
||||
@PostMapping("/order/add")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> addOrder(@RequestBody PathologyOrder order) {
|
||||
if (order.getPatientId() == null) {
|
||||
return R.fail("患者ID不能为空");
|
||||
}
|
||||
if (!StringUtils.hasText(order.getPatientName())) {
|
||||
return R.fail("患者姓名不能为空");
|
||||
}
|
||||
if (!StringUtils.hasText(order.getOrderStatus())) {
|
||||
order.setOrderStatus("PENDING");
|
||||
}
|
||||
order.setApplyTime(new Date());
|
||||
order.setCreateTime(new Date());
|
||||
orderService.save(order);
|
||||
return R.ok(order);
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 前端:表单提交前校验(1 个文件)
|
||||
|
||||
**文件**: `healthlink-his-ui/src/views/pathology/order/index.vue`
|
||||
|
||||
**修改内容**: 在 `submitForm()` 中增加校验逻辑:
|
||||
|
||||
```javascript
|
||||
const submitForm = async () => {
|
||||
if (!form.value.patientId) { ElMessage.warning('请选择患者'); return }
|
||||
if (!form.value.patientName) { ElMessage.warning('请填写患者姓名'); return }
|
||||
if (isEdit.value) {
|
||||
await update(form.value)
|
||||
} else {
|
||||
await add(form.value)
|
||||
}
|
||||
ElMessage.success('操作成功')
|
||||
dlgVisible.value = false
|
||||
loadData()
|
||||
}
|
||||
```
|
||||
|
||||
**修改总结**:
|
||||
|
||||
| 文件 | 修改内容 | 影响范围 |
|
||||
|------|---------|---------|
|
||||
| `PathologyController.java:~addOrder()` | 增加 `patientId` 和 `patientName` 非空校验 | 仅影响新增病理医嘱接口 |
|
||||
| `pathology/order/index.vue:submitForm()` | 增加前端提交前校验 | 仅影响病理医嘱表单 |
|
||||
|
||||
**验证步骤**:
|
||||
1. `mvn clean compile -DskipTests` → 编译通过
|
||||
2. 不填 patientId 点确定 → 前端提示"请选择患者"
|
||||
3. 填入 patientId 后提交 → 后端正常保存,INSERT 包含 `patient_id` 列
|
||||
|
||||
---
|
||||
|
||||
### 四、路由决策
|
||||
|
||||
- **FIXER**: `guanyu`(后端修复 Controller 校验)+ `zhaoyun`(前端修复表单校验)
|
||||
- **REASON**: 此 Bug 涉及后端 Controller 缺少参数校验和前端表单缺少提交前校验两个独立修改点,后端修复归属关羽,前端修复归属赵云,可并行处理。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
125
MD/bugs/BUG_727_ANALYSIS.md
Normal file
125
MD/bugs/BUG_727_ANALYSIS.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# Bug #727 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 01:08:49
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 727
|
||||
- **标题**: 【住院护士站-入出转管理】转出页面待转科患者医嘱列表缺失“医嘱状态”列且“执行科室”未获取值回显
|
||||
- **模块**: 病区护士工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
I now have a complete understanding of the bug. Let me provide the analysis.
|
||||
|
||||
---
|
||||
|
||||
## 一、Bug 理解
|
||||
|
||||
**禅道 Bug 标题**:【住院护士站-入出转管理】转出页面待转科患者医嘱列表缺失"医嘱状态"列且"执行科室"未获取值回显
|
||||
|
||||
**重现步骤**:
|
||||
1. 登录"住院医生工作站",为患者开立医嘱(如:荆防颗粒),确保已校对(状态为:已校对,药房/科室为:中心药房)
|
||||
2. 登录"住院护士站",进入【入出转管理】下的【转出】标签页,选择该患者
|
||||
3. 观察右侧下方医嘱列表
|
||||
|
||||
**期望结果**:
|
||||
1. 医嘱列表应有"医嘱状态"列,正确回显"已校对"
|
||||
2. "执行科室"列应显示"中心药房",不能显示"-"
|
||||
|
||||
**附图关键信息**:
|
||||
- 图2524(护士站转出页):医嘱列表缺少"医嘱状态"列,"执行科室"显示"-"
|
||||
- 图2525(医生站对比页):同一医嘱"荆防颗粒",状态显示"已校对",药房/科室显示"中心药房"
|
||||
|
||||
**综合总结**:护士站在转出页面查看待转科患者的医嘱时,列表缺少"医嘱状态"列且"执行科室"未回显药房名称。而同一医嘱在医生站正常显示"已校对"和"中心药房"。这是一个前后端数据展示不一致的问题。
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
### 问题1:医嘱状态列缺失
|
||||
|
||||
**已修复**。Commit `babd8d0c0`(2026-06-11)已添加了"医嘱状态"列到 `transferOut.vue` 模板,且后端 `ATDManageAppServiceImpl.getInPatientPendingList()` 已正确设置 `requestStatus_enumText`。
|
||||
|
||||
### 问题2:执行科室显示"-"
|
||||
|
||||
**根因**:后端保存药品医嘱时,`perform_location` 字段未正确赋值。
|
||||
|
||||
**完整数据链路分析**:
|
||||
|
||||
| 环 | 状态 | 说明 |
|
||||
|---|---|---|
|
||||
| ① 前端录入 | ✅ 正常 | 医生站选药房后,`orgId` 字段存有药房 ID |
|
||||
| ② DTO 传输 | ❌ 断裂 | 前端发送 `orgId` → DTO 反序列化到 `orgId` 字段 |
|
||||
| ③ Service 保存 | ❌ 断裂 | `DoctorStationAdviceAppServiceImpl:1172` 读取 `adviceSaveDto.getLocationId()` 而非 `getOrgId()`,导致 `performLocation` 为 null |
|
||||
| ④ 数据库存储 | ❌ 数据缺失 | `med_medication_request.perform_location` 为 NULL |
|
||||
| ⑤ 护士站查询 | ✅ SQL 正确 | `ATDManageAppMapper.xml` 正确 JOIN `adm_location`,但因 `perform_location` 为 NULL,`position_name` 为 NULL |
|
||||
| ⑥ 前端展示 | ✅ 逻辑正确 | `positionName \|\| orgName` 均为 null,显示"-" |
|
||||
|
||||
**关键代码定位**:
|
||||
|
||||
`DoctorStationAdviceAppServiceImpl.java:1172`:
|
||||
```java
|
||||
// 发放药房
|
||||
medicationRequest.setPerformLocation(adviceSaveDto.getLocationId());
|
||||
```
|
||||
|
||||
`AdviceSaveDto.java` 中:
|
||||
- `positionId`(line 65):前端字段名 `orgId`,对应数据库 `perform_location`
|
||||
- `orgId`(line 78):前端传来字段名 `orgId`,对应数据库 `org_id`
|
||||
- `locationId`(line 166):独立字段,前端可能未发送此字段
|
||||
|
||||
**Bug #238 修复引入的问题**:`AdviceSaveDto` 添加了 `orgId` 字段(Bug #238 修复),但 `DoctorStationAdviceAppServiceImpl` 仍然从 `getLocationId()` 读取药房 ID,而前端实际发送的是 `orgId`。`locationId` 未被前端赋值,导致 `performLocation` 始终为 null。
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
### 方案:修复后端赋值逻辑
|
||||
|
||||
**修改文件**:`DoctorStationAdviceAppServiceImpl.java`
|
||||
|
||||
**修改位置**:第 1172 行
|
||||
|
||||
**修改内容**:
|
||||
```java
|
||||
// 修改前
|
||||
medicationRequest.setPerformLocation(adviceSaveDto.getLocationId());
|
||||
|
||||
// 修改后 — 优先使用 getPerformLocation(),其次 getOrgId(),最后 getLocationId()
|
||||
medicationRequest.setPerformLocation(
|
||||
adviceSaveDto.getPerformLocation() != null ? adviceSaveDto.getPerformLocation()
|
||||
: adviceSaveDto.getOrgId() != null ? adviceSaveDto.getOrgId()
|
||||
: adviceSaveDto.getLocationId()
|
||||
);
|
||||
```
|
||||
|
||||
**同时检查**(同类问题):
|
||||
1. `DoctorStationChineseMedicalAppServiceImpl.java:551` — 中药处方可能有相同问题
|
||||
2. 现有数据修复 — 对 `perform_location` 为 NULL 的已保存医嘱,需要从 `content_json` 中提取 `orgId` 回填
|
||||
|
||||
**验证步骤**:
|
||||
1. `mvn clean compile -DskipTests` — 编译通过
|
||||
2. 医生站开药 → 选"中心药房" → 签发
|
||||
3. 护士站转出页 → 选该患者 → 医嘱列表"执行科室"应显示"中心药房"
|
||||
|
||||
---
|
||||
|
||||
## 四、路由决策
|
||||
|
||||
**FIXER**: guanyu(后端开发)
|
||||
|
||||
**REASON**: 核心 Bug 在后端 `DoctorStationAdviceAppServiceImpl` 的字段赋值逻辑,需要修改 Java 代码中 `setPerformLocation` 的取值来源。前端模板和 SQL 查询均已正确,无需前端修改。可能还需同步修复 `DoctorStationChineseMedicalAppServiceImpl` 中的同类问题。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
147
MD/bugs/BUG_728_ANALYSIS.md
Normal file
147
MD/bugs/BUG_728_ANALYSIS.md
Normal file
@@ -0,0 +1,147 @@
|
||||
# Bug #728 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 01:00:18
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 728
|
||||
- **标题**: 【住院护士站-医嘱校对】转科医嘱核对通过后原床位被提前释放,导致转科前待处理事项无法执行
|
||||
- **模块**: 病区护士工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
分析完成。以下是完整的 Bug 分析报告:
|
||||
|
||||
---
|
||||
|
||||
## 一、Bug 理解
|
||||
|
||||
**禅道标题:** 【住院护士站-医嘱校对】转科医嘱核对通过后原床位被提前释放,导致转科前待处理事项无法执行
|
||||
|
||||
**重现步骤:**
|
||||
1. 医生端为患者(002床 不知道)开立转科预嘱并签发
|
||||
2. 登录住院护士站,在【医嘱校对】页面"未校对-临时医嘱"中找到该患者的"转科"医嘱
|
||||
3. 选中该医嘱,点击【核对通过】,提示"校对成功"
|
||||
4. 切换至其他菜单(医嘱执行、汇总领药等)
|
||||
|
||||
**结果:**
|
||||
- 护士核对通过转科医嘱后,系统**立即释放并清退了该患者的原床位**(床号显示为 `-:-`,非在科状态)
|
||||
- 患者从左侧在科患者列表中**消失**,护士无法在【医嘱执行】【汇总领药】等界面选中该患者
|
||||
- 转科前尚未完成的带药、治疗等医嘱无法执行
|
||||
|
||||
**期望:**
|
||||
1. 核对通过转科医嘱后,应**保留原床位占用**和在科状态
|
||||
2. 允许护士继续处理转科前所有待执行医嘱
|
||||
3. **只有**护士在【入出转管理】页面确认执行【转科】或【清床】操作后,才正式释放床位
|
||||
|
||||
**附图关键信息:**
|
||||
- 图2527:校对页面,红框标注"核对通过"按钮和转科医嘱
|
||||
- 图2526/2529:入出转管理页面,床号显示 `-:-`,患者已标记"待转科",仍显示"待取药/待退药"和"待处理执行单"
|
||||
- 图2528:校对页面,患者"不知道"已从左侧列表消失,红框注释"转科医嘱护士校对通过后 待转科的患者床位应该保留"
|
||||
|
||||
**综合总结:** 护士在医嘱校对页面核对通过转科医嘱后,系统过早触发了床位释放和在科状态变更,导致患者从在科列表中消失,护士无法继续执行转科前遗留的待办医嘱。正确行为应是核对通过仅更新医嘱状态,保留床位和在科状态,待护士在入出转管理页面手动执行转科时才释放资源。
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
**核心问题代码:** `AdviceProcessAppServiceImpl.adviceVerify()` 方法(第 465-472 行)
|
||||
|
||||
```java
|
||||
// 处理转科/出院等特殊医嘱
|
||||
for (ServiceRequest serviceRequest : normalRequests) {
|
||||
if (ActivityDefCategory.TRANSFER.getValue().equals(serviceRequest.getCategoryEnum())) {
|
||||
encounterService.updateEncounterStatus(serviceRequest.getEncounterId(),
|
||||
EncounterZyStatus.PENDING_TRANSFER.getValue()); // ← BUG:校对时立即改变患者状态
|
||||
} else if (ActivityDefCategory.DISCHARGE.getValue().equals(serviceRequest.getCategoryEnum())) {
|
||||
encounterService.updateEncounterStatus(serviceRequest.getEncounterId(),
|
||||
EncounterZyStatus.AWAITING_DISCHARGE.getValue());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**根因链条:**
|
||||
1. **`adviceVerify`(校对通过)** 在处理转科医嘱时,直接调用 `encounterService.updateEncounterStatus()` 将患者 encounter 状态改为 `PENDING_TRANSFER`(6)
|
||||
2. 同时,转科医嘱的 ServiceRequest 状态被设为 `COMPLETED`(3)
|
||||
3. 这触发了系统级联反应——患者状态变更导致床位信息被释放(`encounter_location` 中 BED 类型的记录状态被联动修改),患者从在科患者列表中消失
|
||||
4. **实际的转科操作** 由 `ATDManageAppServiceImpl.transferDepartment()` 执行,这才是应该执行床位释放、状态变更的地方
|
||||
|
||||
**正确的时序设计:**
|
||||
- **校对通过** → 仅更新医嘱状态(转科医嘱→COMPLETED),**不改变**患者 encounter 状态
|
||||
- **入出转管理→转科** → 执行床位释放、状态变更、新病区分配
|
||||
|
||||
**涉及文件:**
|
||||
- `AdviceProcessAppServiceImpl.java` — `adviceVerify()` 方法,第 465-472 行
|
||||
- `ATDManageAppServiceImpl.java` — `transferDepartment()` 方法(正确的转科执行逻辑)
|
||||
- `EncounterLocationServiceImpl.java` — `updateEncounterLocationStatus()` 方法(床位状态更新)
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
### 修复步骤
|
||||
|
||||
**步骤 1:修改 `AdviceProcessAppServiceImpl.adviceVerify()` 方法**
|
||||
|
||||
**文件:** `healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/inhospitalnursestation/appservice/impl/AdviceProcessAppServiceImpl.java`
|
||||
|
||||
**修改内容:** 删除校对通过时对转科医嘱的 encounter 状态更新
|
||||
|
||||
将第 463-472 行:
|
||||
```java
|
||||
// 处理转科/出院等特殊医嘱
|
||||
for (ServiceRequest serviceRequest : normalRequests) {
|
||||
if (ActivityDefCategory.TRANSFER.getValue().equals(serviceRequest.getCategoryEnum())) {
|
||||
encounterService.updateEncounterStatus(serviceRequest.getEncounterId(),
|
||||
EncounterZyStatus.PENDING_TRANSFER.getValue());
|
||||
} else if (ActivityDefCategory.DISCHARGE.getValue().equals(serviceRequest.getCategoryEnum())) {
|
||||
encounterService.updateEncounterStatus(serviceRequest.getEncounterId(),
|
||||
EncounterZyStatus.AWAITING_DISCHARGE.getValue());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
改为:
|
||||
```java
|
||||
// 转科/出院医嘱核对通过时,不立即改变患者 encounter 状态
|
||||
// 状态变更推迟到入出转管理页面执行转科/出院操作时触发(ATDManageAppServiceImpl.transferDepartment)
|
||||
// 校对通过仅更新医嘱状态(已在上方 COMPLETED 处理),保留原床位和在科状态
|
||||
```
|
||||
|
||||
**说明:**
|
||||
- 转科医嘱的 `ServiceRequest` 状态已在上方通过 `updateCompleteRequestStatus` 设为 COMPLETED(3),这是正确的
|
||||
- 删除的是 encounter 状态的联动更新,不影响医嘱本身的校对完成
|
||||
- 出院医嘱同理删除(AWAITING_DISCHARGE 状态应推迟到出院操作时设置)
|
||||
|
||||
**步骤 2:编译验证**
|
||||
```bash
|
||||
mvn clean compile -DskipTests -pl healthlink-his-server/healthlink-his-application
|
||||
mvn test -pl healthlink-his-server/healthlink-his-application -Dtest="NurseStationTest" -Dsurefire.failIfNoSpecifiedTests=false
|
||||
```
|
||||
|
||||
**步骤 3:前端确认(无需修改)**
|
||||
|
||||
前端【医嘱校对】页面无需修改,因为:
|
||||
- 医嘱校对接口返回"校对成功"后,前端刷新医嘱列表,转科医嘱状态正确更新为"已完成"
|
||||
- 患者在科列表的刷新由后端 `selectInpatientPage` 查询驱动,患者 encounter 状态不变 → 列表中继续显示
|
||||
|
||||
---
|
||||
|
||||
## 四、路由决策
|
||||
|
||||
**FIXER:** guanyu(关羽 — 后端开发)
|
||||
|
||||
**REASON:** 修复涉及 Java 后端 Service 层逻辑修改(`AdviceProcessAppServiceImpl.adviceVerify` 方法),属于纯后端业务逻辑调整,无前端改动,由后端开发 Agent 执行最合适。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: ** 修复涉及 Java 后端 Service 层逻辑修改(`AdviceProcessAppServiceImpl.adviceVerify` 方法),属于纯后端业务逻辑调整,无前端改动,由后端开发 Agent 执行最合适。
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
139
MD/bugs/BUG_729_ANALYSIS.md
Normal file
139
MD/bugs/BUG_729_ANALYSIS.md
Normal file
@@ -0,0 +1,139 @@
|
||||
# Bug #729 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 00:53:38
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 729
|
||||
- **标题**: 【住院护士站-入出转管理】待转科列表“入院病区/入院病房”下拉筛选项无数据,未正确读取转科申请数据
|
||||
- **模块**: 病区护士工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
Now I have a complete understanding of the issue. Let me finalize my analysis.
|
||||
|
||||
### 一、Bug 理解
|
||||
|
||||
**禅道 Bug #729 原文:**
|
||||
- **标题**:【住院护士站-入出转管理】待转科列表"入院病区/入院病房"下拉筛选项无数据,未正确读取转科申请数据
|
||||
- **重现步骤**:1. 临床医生端为患者提交转科申请(转入科室:临床心理科,转入病区:第二病区);2. 登录住院护士站,进入入出转管理的"转出"页面;3. 点击"入院病区"或"入院病房"下拉框
|
||||
- **期望结果**:「入院病区」应去重读取所有"待转科"患者的【转科申请-转入病区】字段值;「入院病房」应去重读取所有"待转科"患者的【转科申请-转入科室/病房】字段值
|
||||
|
||||
**图片关键信息**:图2中"入院病区"和"入院病房"下拉框展开后为空白,无任何选项数据,红色文字明确标注"应该取值当前有待转科患者的转入科室和转入病区的数据供护士筛选用"。
|
||||
|
||||
**综合总结**:护士在"转出"页面使用下拉框筛选待转科患者时,下拉框为空。原因是当前代码调用 `getPractitionerWard()` 获取的是当前登录护士被分配的病区列表,而不是从 `doc_order_process` 表中读取待转科患者的转入病区/转入科室数据。正确的数据源应该是所有 encounter_status=6(待转科)的患者的转科申请中的 targetLocationId 和 targetOrganizationId。
|
||||
|
||||
---
|
||||
|
||||
### 二、根因分析
|
||||
|
||||
**核心问题**:前端 `transferOut.vue` 的 `initData()` 函数调用 `getPractitionerWard()`(接口 `/app-common/practitioner-ward`)获取下拉数据,这个接口返回的是当前护士被分配的病区列表,与"待转科患者的转入病区/转入科室"无关。
|
||||
|
||||
**数据链路分析**:
|
||||
1. 医生提交转科申请时,`SpecialAdviceAppServiceImpl.saveTransferOrders()` 创建 `doc_order_process` 记录,其中:
|
||||
- `target_location_id` = 转入病区(对应 `adm_location` 表)
|
||||
- `target_organization_id` = 转入科室(对应 `adm_organization` 表)
|
||||
- `encounter_id` = 关联就诊记录
|
||||
2. 患者的 `adm_encounter.status_enum = 6`(PENDING_TRANSFER)
|
||||
3. 当前前端下拉框应该查询:`doc_order_process` JOIN `adm_encounter`(status=6),分别获取 DISTINCT `target_location_id` 和 `target_organization_id` 对应的名称
|
||||
|
||||
**涉及文件**:
|
||||
- `healthlink-his-ui/src/views/inpatientNurse/inOut/components/transferOut.vue` — `initData()` 函数调用了错误的 API
|
||||
- `healthlink-his-server/.../inhospitalnursestation/controller/ATDManageController.java` — 需要新增端点
|
||||
- `healthlink-his-server/.../inhospitalnursestation/appservice/impl/ATDManageAppServiceImpl.java` — 需要新增方法
|
||||
- `healthlink-his-server/.../inhospitalnursestation/mapper/ATDManageAppMapper.java` — 需要新增查询
|
||||
- `healthlink-his-server/.../resources/mapper/inhospitalnursestation/ATDManageAppMapper.xml` — 需要新增 SQL
|
||||
|
||||
---
|
||||
|
||||
### 三、修复方案
|
||||
|
||||
**后端(3个文件修改 + 1个新增查询):**
|
||||
|
||||
1. **`ATDManageAppMapper.java`** — 新增方法:
|
||||
```java
|
||||
List<Map<String, Object>> selectTransferWardOptions(Long currentUserOrgId);
|
||||
List<Map<String, Object>> selectTransferOrganizationOptions(Long currentUserOrgId);
|
||||
```
|
||||
或合并为一个方法返回两个列表。
|
||||
|
||||
2. **`ATDManageAppMapper.xml`** — 新增 SQL:
|
||||
```sql
|
||||
<!-- 获取待转科患者的转入病区去重列表 -->
|
||||
<select id="selectTransferWardOptions" resultType="map">
|
||||
SELECT DISTINCT al.id AS id, al.name AS name
|
||||
FROM doc_order_process dop
|
||||
JOIN adm_encounter ae ON ae.id = dop.encounter_id AND ae.delete_flag = '0'
|
||||
JOIN adm_location al ON al.id = dop.target_location_id AND al.delete_flag = '0'
|
||||
WHERE ae.status_enum = 6
|
||||
AND ae.class_enum = 1 -- 住院
|
||||
AND ae.organization_id = #{currentUserOrgId}
|
||||
AND ae.delete_flag = '0'
|
||||
AND dop.delete_flag = '0'
|
||||
</select>
|
||||
|
||||
<!-- 获取待转科患者的转入科室去重列表 -->
|
||||
<select id="selectTransferOrganizationOptions" resultType="map">
|
||||
SELECT DISTINCT ao.id AS id, ao.name AS name
|
||||
FROM doc_order_process dop
|
||||
JOIN adm_encounter ae ON ae.id = dop.encounter_id AND ae.delete_flag = '0'
|
||||
JOIN adm_organization ao ON ao.id = dop.target_organization_id AND ao.delete_flag = '0'
|
||||
WHERE ae.status_enum = 6
|
||||
AND ae.class_enum = 1
|
||||
AND ae.organization_id = #{currentUserOrgId}
|
||||
AND ae.delete_flag = '0'
|
||||
AND dop.delete_flag = '0'
|
||||
</select>
|
||||
```
|
||||
|
||||
3. **`IATDManageAppService.java` / `ATDManageAppServiceImpl.java`** — 新增方法:
|
||||
```java
|
||||
R<?> getTransferFilterOptions();
|
||||
```
|
||||
实现中调用 mapper 获取两个去重列表,返回 `{ wardList: [...], organizationList: [...] }`。
|
||||
|
||||
4. **`ATDManageController.java`** — 新增端点:
|
||||
```java
|
||||
@GetMapping("/transfer-filter-options")
|
||||
public R<?> getTransferFilterOptions() {
|
||||
return atdManageAppService.getTransferFilterOptions();
|
||||
}
|
||||
```
|
||||
|
||||
**前端(2个文件修改):**
|
||||
|
||||
5. **`api.js`** — 新增 API:
|
||||
```javascript
|
||||
export function getTransferFilterOptions() {
|
||||
return request({
|
||||
url: '/nurse-station/atd-manage/transfer-filter-options',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
6. **`transferOut.vue`** — 修改 `initData()` 函数:
|
||||
- 将 `getPractitionerWard()` 替换为 `getTransferFilterOptions()`
|
||||
- 用返回的 `wardList` 填充 `initInfoOptions.value.wardListOptions`
|
||||
- 用返回的 `organizationList` 填充 `wardLocationList`(或新建变量 `organizationListOptions`)
|
||||
- 当选择"入院病区"时,应根据选择的 wardId 过滤对应的转入科室(可选优化,也可独立显示两个下拉框)
|
||||
|
||||
---
|
||||
|
||||
### 四、路由决策
|
||||
|
||||
**FIXER: zhaoyun**
|
||||
**REASON**: 这是一个纯前端+后端接口对接问题,涉及下拉框数据源替换。前端 `transferOut.vue` 是主体修改点(替换 API 调用和数据绑定),后端只需新增一个查询端点。赵云负责前端开发,且修改涉及 Vue 组件交互逻辑,由赵云主导、配合荀彧(新增 mapper SQL)最为合适。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: zhaoyun
|
||||
- **修复 Agent**: zhaoyun(前端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
179
MD/bugs/BUG_731_ANALYSIS.md
Normal file
179
MD/bugs/BUG_731_ANALYSIS.md
Normal file
@@ -0,0 +1,179 @@
|
||||
# Bug #731 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 00:39:06
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 731
|
||||
- **标题**: 【临床医嘱-转科】转科申请成功后主界面未自动刷新,且生成的医嘱名称与科室数据错误
|
||||
- **模块**: 住院医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
Now I have a complete picture. Here's my analysis:
|
||||
|
||||
---
|
||||
|
||||
## Bug #731 分析报告
|
||||
|
||||
### 一、Bug 理解
|
||||
|
||||
**禅道标题**:【临床医嘱-转科】转科申请成功后主界面未自动刷新,且生成的医嘱名称与科室数据错误
|
||||
|
||||
**重现步骤**:
|
||||
1. 登录住院医生工作站,选择在科患者(如:002,当前科室:呼吸内科病房)
|
||||
2. 进入"临床医嘱"页面,点击【转科】唤起申请弹窗
|
||||
3. 选择"转入科室"为【临床心理科】,"转入病区"为【第二病区】,填写原因后点击【确认】
|
||||
4. 弹窗关闭且提示"转科申请已提交"后,观察医嘱列表状态
|
||||
5. 手动点击【刷新数据】按钮后,核对自动生成的转科医嘱
|
||||
|
||||
**期望结果**:
|
||||
1. 提交成功后自动刷新医嘱列表
|
||||
2. 医嘱名称应为"转科-临床心理科"
|
||||
3. 药房/科室应为患者当前科室"呼吸内科病房"
|
||||
|
||||
**实际结果**:
|
||||
1. 未自动刷新,需手动点击"刷新数据"按钮
|
||||
2. 医嘱名称仅为"转科",缺少转入科室名
|
||||
3. 药房/科室显示为"信息科"(系统管理科室),完全错误
|
||||
|
||||
---
|
||||
|
||||
### 二、根因分析
|
||||
|
||||
本 Bug 包含 **3 个独立问题**,根因分布在前端和后端:
|
||||
|
||||
#### 问题1:未自动刷新
|
||||
|
||||
**根因**:前端 `transferOrganizationDialog.vue` 在成功提交后没有 `emit('success')`,且父组件 `order/index.vue` 没有给该对话框绑定 `@success` 处理函数。
|
||||
|
||||
对比已正常工作的出院对话框 `leaveHospitalDialog.vue`:
|
||||
- 出院对话框有 `emit('success')` 调用
|
||||
- 父组件有 `@success="handleLeaveHospitalSuccess"` → `getListInfo(false)` 刷新列表
|
||||
- 转科对话框两处都缺失
|
||||
|
||||
**涉及文件**:
|
||||
- `healthlink-his-ui/src/views/inpatientDoctor/home/components/order/applicationForm/transferOrganizationDialog.vue`(第149行附近 `submitApplicationForm`)
|
||||
- `healthlink-his-ui/src/views/inpatientDoctor/home/components/order/index.vue`(第673行 `<TransferOrganizationDialog>`)
|
||||
|
||||
#### 问题2:医嘱名称仅为"转科"
|
||||
|
||||
**根因**:后端 `SpecialAdviceAppServiceImpl.saveTransferOrganizationOrders()` 中,`ServiceRequest` 的名称使用了诊疗目录定义的默认名称"转科"(来自 `CommonConstants.BusinessName.TRANSFER_ORGANIZATION = "转科"`),没有拼接转入科室名称。
|
||||
|
||||
**涉及文件**:
|
||||
- `healthlink-his-server/.../regdoctorstation/appservice/impl/SpecialAdviceAppServiceImpl.java`(`saveTransferOrganizationOrders` 方法,约第300行)
|
||||
|
||||
#### 问题3:药房/科室显示为"信息科"
|
||||
|
||||
**根因**:后端 `saveTransferOrganizationOrders()` 中设置了 `serviceRequest.setOrgId(activityAdviceBaseDto.getPositionId())`,其中 `activityAdviceBaseDto` 是从诊疗目录(activity definition)获取的默认数据,其 `positionId` 对应的科室是"信息科"(转科医嘱定义的默认归属科室),而非患者当前所在科室。
|
||||
|
||||
对比出院医嘱 `saveLeaveHospitalOrders()` 使用了 `activityAdviceBaseDto.getPositionId()` 但出院医嘱没有这个问题(因为出院后不需要药房/科室归属)。转科医嘱需要显示的是**患者当前所在的科室**(转出科室)。
|
||||
|
||||
前端 `patientInfo` store 中有 `inHospitalOrgId`(入科科室ID),但后端 `TransferOrganizationParam` 没有传入原科室参数。
|
||||
|
||||
**涉及文件**:
|
||||
- `healthlink-his-server/.../regdoctorstation/appservice/impl/SpecialAdviceAppServiceImpl.java`(`saveTransferOrganizationOrders` 方法)
|
||||
- `healthlink-his-server/.../regdoctorstation/dto/TransferOrganizationParam.java`(缺少 `originalOrganizationId` 字段)
|
||||
- `healthlink-his-ui/.../order/applicationForm/transferOrganizationDialog.vue`(未传入原科室参数)
|
||||
|
||||
---
|
||||
|
||||
### 三、修复方案
|
||||
|
||||
#### 修复1:自动刷新
|
||||
|
||||
**文件**:`transferOrganizationDialog.vue`
|
||||
```diff
|
||||
// 在 <script setup> 中添加 emit 定义
|
||||
+ const emit = defineEmits(['success']);
|
||||
|
||||
// submitApplicationForm 中成功后 emit
|
||||
transferOrganization(form).then((res) => {
|
||||
if (res.code == 200) {
|
||||
proxy.$modal.msgSuccess('转科申请已提交');
|
||||
dialogVisible.value = false;
|
||||
+ emit('success');
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
**文件**:`order/index.vue`
|
||||
```diff
|
||||
<TransferOrganizationDialog
|
||||
ref="transferOrganizationRef"
|
||||
+ @success="handleTransferOrgSuccess"
|
||||
/>
|
||||
|
||||
// 添加回调函数(在 handleTransferOrg 函数附近)
|
||||
+ function handleTransferOrgSuccess() {
|
||||
+ getListInfo(false);
|
||||
+ }
|
||||
```
|
||||
|
||||
#### 修复2:医嘱名称拼接科室
|
||||
|
||||
**文件**:`SpecialAdviceAppServiceImpl.java`(`saveTransferOrganizationOrders` 方法)
|
||||
|
||||
在创建 `ServiceRequest` 后、`save` 前,根据 `targetOrganizationId` 查询转入科室名称并拼接到请求名称中:
|
||||
|
||||
```diff
|
||||
serviceRequest.setRequesterId(practitionerId); // 开方医生
|
||||
serviceRequest.setEncounterId(encounterId); // 就诊id
|
||||
- serviceRequest.setOrgId(activityAdviceBaseDto.getPositionId()); // 执行科室(见修复3)
|
||||
+ // 查询转入科室名称,拼接到医嘱名称
|
||||
+ // 原名称"转科" → "转科-转入的科室名称"
|
||||
serviceRequest.setConditionId(conditionId); // 诊断id
|
||||
serviceRequest.setEncounterDiagnosisId(encounterDiagnosisId); // 就诊诊断id
|
||||
```
|
||||
|
||||
需要在 `ServiceRequest` 上设置名称。具体做法:在 `AdviceManageAppMapper` 或 `SpecialAdviceAppMapper` 中添加查询方法,根据 `targetOrganizationId` 查询科室名称,然后:
|
||||
```java
|
||||
// 设置医嘱显示名称为 "转科-转入科室名"
|
||||
```
|
||||
|
||||
#### 修复3:药房/科室使用患者当前科室
|
||||
|
||||
**文件**:`TransferOrganizationParam.java`
|
||||
```diff
|
||||
+ /** 原科室(患者当前所在科室) */
|
||||
+ @JsonSerialize(using = ToStringSerializer.class)
|
||||
+ private Long originalOrganizationId;
|
||||
```
|
||||
|
||||
**文件**:`transferOrganizationDialog.vue`
|
||||
```diff
|
||||
form.encounterId = patientInfo.value.encounterId
|
||||
form.patientId = patientInfo.value.patientId
|
||||
+ form.originalOrganizationId = patientInfo.value.inHospitalOrgId
|
||||
```
|
||||
|
||||
**文件**:`SpecialAdviceAppServiceImpl.java`
|
||||
```diff
|
||||
- serviceRequest.setOrgId(activityAdviceBaseDto.getPositionId()); // 执行科室(诊疗定义默认)
|
||||
+ serviceRequest.setOrgId(transferOrganizationParam.getOriginalOrganizationId()); // 执行科室(患者当前科室)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 四、路由决策
|
||||
|
||||
**FIXER**: **zhaoyun** + **guanyu**(联合修复)
|
||||
|
||||
**REASON**:
|
||||
- **zhaoyun(赵云/前端)** 负责修复1(自动刷新):修改 `transferOrganizationDialog.vue` 添加 `emit('success')`,修改 `order/index.vue` 添加 `@success` 回调——纯前端改动
|
||||
- **guanyu(关羽/后端)** 负责修复2和修复3(医嘱名称+科室ID):修改 `TransferOrganizationParam.java` 添加 `originalOrganizationId` 字段,修改 `SpecialAdviceAppServiceImpl.java` 的 `saveTransferOrganizationOrders` 方法——纯后端改动
|
||||
|
||||
两个修复互不依赖,可以并行实施。但由于修复3(后端接收 `originalOrganizationId`)需要前端配合传参,**建议由 zhaoyun 先改前端(修复1+修复3前端部分),guanyu 同时改后端(修复2+修复3后端部分),最后联调验证**。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
195
MD/bugs/BUG_732_ANALYSIS.md
Normal file
195
MD/bugs/BUG_732_ANALYSIS.md
Normal file
@@ -0,0 +1,195 @@
|
||||
# Bug #732 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 00:30:55
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 732
|
||||
- **标题**: 【医嘱闭环-闭环统计】科室的闭环和未闭环医嘱预警加载卡死
|
||||
- **模块**: 系统管理
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
Based on my analysis, I now have a clear picture of the root cause. Let me output the structured analysis.
|
||||
|
||||
---
|
||||
|
||||
### 一、Bug 理解
|
||||
|
||||
**禅道原文引用:**
|
||||
- **标题**:【医嘱闭环-闭环统计】科室的闭环和未闭环医嘱预警加载卡死
|
||||
- **重现步骤**:登录内科医生1的账号:doctor1 密码:123456进入医嘱闭环打开闭环统计查看界面
|
||||
- **结果**:出现报错:`main.js:84 TypeError: Cannot convert object to primitive value`
|
||||
- **期望**:能够正常显示报卡的信息和操作界面
|
||||
|
||||
**附图分析关键信息:**
|
||||
- 页面标题"科室/医生闭环统计",右侧有"按科室"下拉和"刷新"按钮
|
||||
- 两个数据区域(科室/医生闭环统计表格、未闭环医嘱预警表格)均为空白,仅有蓝色加载动画圆圈(loading spinner)
|
||||
- 右上角红色标签"X 条待处理"但数字被遮挡
|
||||
- **核心异常**:控制台 `TypeError: Cannot convert object to primitive value`,导致两个表格数据加载卡死
|
||||
|
||||
**综合总结**:用户登录 doctor1 账号进入医嘱闭环统计页面,页面框架正常渲染但两个核心数据表格(科室/医生闭环统计、未闭环医嘱预警)均卡在 loading 状态无法加载数据。控制台报 `TypeError: Cannot convert object to primitive value`,表明前端在渲染过程中遇到了一个对象值被当作原始值使用的场景。
|
||||
|
||||
---
|
||||
|
||||
### 二、根因分析
|
||||
|
||||
经过全链路追踪(前端 Vue 组件 → API → Controller → AppService → Mapper SQL),根因是**多层问题叠加**:
|
||||
|
||||
#### 根因 1(直接触发 TypeError):PostgreSQL 列别名大小写折叠 + 前端 prop 不匹配
|
||||
|
||||
`OrderExecuteRecordMapper.java` 中的 4 个 SQL 查询使用了 camelCase 列别名:
|
||||
```sql
|
||||
-- selectGroupByDepartment
|
||||
SELECT COALESCE(m.department_name, '未知') AS department, COUNT(*) AS totalOrders, ...
|
||||
|
||||
-- selectGroupByDoctor
|
||||
SELECT COALESCE(m.doctor_name, '未知') AS doctorName, COUNT(*) AS totalOrders, ...
|
||||
|
||||
-- selectUnclosedWarnings
|
||||
SELECT e.order_no AS orderNo, e.patient_name AS patientName, ...
|
||||
```
|
||||
|
||||
**PostgreSQL 会将未加引号的标识符折叠为小写**。因此 JDBC ResultSet 返回的 Map key 全部是小写:
|
||||
- `totalOrders` → `totalorders`
|
||||
- `closedCount` → `closedcount`
|
||||
- `orderNo` → `orderno`
|
||||
- `patientName` → `patientname`
|
||||
- `orderType` → `ordertype`
|
||||
- `currentStep` → `currentstep`
|
||||
- `orderTime` → `ordertime`
|
||||
|
||||
Java 的 `getLong()`/`getString()` helper 有 `key.toLowerCase()` fallback,所以 Java 层计算正确。但 **`getGroupStats()` 返回的 Map 中同时存在**:
|
||||
- 小写 key(来自 SQL):`totalorders`, `closedcount`
|
||||
- camelCase key(Java 代码 put):`unclosedCount`, `closedRate`
|
||||
|
||||
前端模板使用 `prop="totalOrders"` 无法匹配 `totalorders`,导致表格列值为 `undefined`。
|
||||
|
||||
#### 根因 2(直接触发 TypeError):`el-progress` 接收到非 number 类型的 `percentage`
|
||||
|
||||
在 `<el-progress :percentage="scope.row.closedRate || 0">` 中:
|
||||
- `scope.row.closedRate` 是 Java 计算后 put 进 map 的 `double`,序列化为 JSON number → 正常
|
||||
- 但 `scope.row.closedRate` 如果因上游数据异常为非数字对象,`||` 不会拦截(对象是 truthy),`el-progress` 内部尝试数值转换时抛出 `TypeError: Cannot convert object to primitive value`
|
||||
|
||||
#### 根因 3(数据问题):`getUnclosedWarnings()` 未用 helper 处理 `orderTime`
|
||||
|
||||
```java
|
||||
// 第 143 行
|
||||
Object orderTimeObj = row.get("orderTime"); // ← PostgreSQL 返回的是 "ordertime",永远 null
|
||||
```
|
||||
|
||||
导致所有未闭环医嘱的 `overdueDuration` 都显示"未知",`orderTime` 都显示空字符串。
|
||||
|
||||
#### 根因 4(缺失数据源):`order_execute_record` 表与 `order_main` 表无关联数据
|
||||
|
||||
`selectGroupByDepartment` 等 SQL 做了 `LEFT JOIN order_main m ON e.order_no = m.order_no`,但 `order_execute_record` 是闭环追踪表,其中的 `order_no` 可能与 `order_main`(门诊挂号单表)中的 `order_no` **语义不同**——`order_main` 是门诊挂号/预约表,不是医嘱表。即使 JOIN 成功,`department_name` 和 `doctor_name` 也可能全为 NULL。
|
||||
|
||||
**涉及的关键文件:**
|
||||
|
||||
| 层 | 文件 | 行号 |
|
||||
|---|---|---|
|
||||
| Mapper SQL | `OrderExecuteRecordMapper.java` | 全部 4 个 `@Select` 方法 |
|
||||
| AppService | `OrderClosedLoopAppServiceImpl.java` | `getGroupStats()` L131-143, `getUnclosedWarnings()` L146-168 |
|
||||
| 前端组件 | `statistics/index.vue` | L74 `el-progress`, L84-88 `el-table-column`, L99-102 `el-progress` |
|
||||
| 前端 API | `orderclosedloop.js` | `getClosedLoopStatistics()` |
|
||||
|
||||
---
|
||||
|
||||
### 三、修复方案
|
||||
|
||||
#### 修复 1:SQL 列别名加双引号保留大小写(根本修复)
|
||||
|
||||
修改 `OrderExecuteRecordMapper.java`,所有 SQL 别名加 PostgreSQL 双引号:
|
||||
|
||||
```sql
|
||||
-- selectOverviewByType
|
||||
SELECT e.order_type AS "orderType",
|
||||
COUNT(*) AS "totalOrders",
|
||||
COUNT(CASE WHEN e.execute_status = 'completed' THEN 1 END) AS "closedCount"
|
||||
|
||||
-- selectGroupByDepartment
|
||||
SELECT COALESCE(m.department_name, '未知') AS "department",
|
||||
COUNT(*) AS "totalOrders",
|
||||
COUNT(CASE WHEN e.execute_status = 'completed' THEN 1 END) AS "closedCount"
|
||||
|
||||
-- selectGroupByDoctor
|
||||
SELECT COALESCE(m.doctor_name, '未知') AS "doctorName",
|
||||
COUNT(*) AS "totalOrders",
|
||||
COUNT(CASE WHEN e.execute_status = 'completed' THEN 1 END) AS "closedCount"
|
||||
|
||||
-- selectUnclosedWarnings
|
||||
SELECT e.order_no AS "orderNo",
|
||||
e.patient_name AS "patientName",
|
||||
e.order_type AS "orderType",
|
||||
COALESCE(m.department_name, '未知') AS "department",
|
||||
COALESCE(m.doctor_name, '未知') AS "doctorName",
|
||||
e.current_step AS "currentStep",
|
||||
e.create_time AS "orderTime"
|
||||
```
|
||||
|
||||
这样 JDBC 返回的 Map key 就是精确的 camelCase,前端 `prop` 能正确匹配。
|
||||
|
||||
#### 修复 2:`getUnclosedWarnings()` 使用 helper 处理 `orderTime`
|
||||
|
||||
将 `row.get("orderTime")` 改为使用 `getString()` helper 或直接用小写 key:
|
||||
|
||||
```java
|
||||
// 修改前
|
||||
Object orderTimeObj = row.get("orderTime");
|
||||
|
||||
// 修改后(兼容大小写)
|
||||
Object orderTimeObj = row.get("orderTime");
|
||||
if (orderTimeObj == null) {
|
||||
orderTimeObj = row.get("ordertime");
|
||||
}
|
||||
```
|
||||
|
||||
或者更彻底地,在修复 1(SQL 加引号)之后,`row.get("orderTime")` 就能正确获取值。
|
||||
|
||||
#### 修复 3:前端 `el-progress` 添加防御性数值转换
|
||||
|
||||
在 `statistics/index.vue` 中,确保传给 `el-progress` 的 `percentage` 始终为 number:
|
||||
|
||||
```html
|
||||
<!-- 修复前 -->
|
||||
<el-progress :percentage="statistics.drugClosedRate || 0" :stroke-width="8" />
|
||||
|
||||
<!-- 修复后 -->
|
||||
<el-progress :percentage="Number(statistics.drugClosedRate) || 0" :stroke-width="8" />
|
||||
```
|
||||
|
||||
同理修复 `closedRate` 的绑定:
|
||||
```html
|
||||
<el-progress :percentage="Number(scope.row.closedRate) || 0" :stroke-width="12" />
|
||||
```
|
||||
|
||||
#### 修复 4:`getGroupStats()` 确保 key 一致性
|
||||
|
||||
在 `OrderClosedLoopAppServiceImpl.getGroupStats()` 中,显式 put camelCase key(即使修复 1 后 SQL 已正确,这是防御性编码):
|
||||
|
||||
```java
|
||||
// 在 item.put("unclosedCount", ...) 之前加:
|
||||
item.put("totalOrders", totalOrders);
|
||||
item.put("closedCount", closedCount);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 四、路由决策
|
||||
|
||||
**FIXER: zhaoyun(赵云 — 前端开发)**
|
||||
|
||||
**REASON**: 此 Bug 的直接表现是前端 TypeError 导致页面卡死,核心修复在前端模板的防御性编码(修复 3)和后端 Mapper SQL 的列别名引号处理(修复 1/2/4)。赵云负责前端修复(`statistics/index.vue` 中 `el-progress` 的数值转换),同时需要协调荀彧协助后端 Mapper SQL 修改(`OrderExecuteRecordMapper.java`)。前端权重更高(页面卡死的直接原因是前端渲染),由赵云主导。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: zhaoyun
|
||||
- **修复 Agent**: zhaoyun(前端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
89
MD/bugs/BUG_733_ANALYSIS.md
Normal file
89
MD/bugs/BUG_733_ANALYSIS.md
Normal file
@@ -0,0 +1,89 @@
|
||||
# Bug #733 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 00:22:15
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 733
|
||||
- **标题**: 【目录管理-诊疗目录】点击“编辑”按钮报错,且无法弹出编辑窗口进行数据修改
|
||||
- **模块**: 系统管理
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
根因完全定位。分析结果如下:
|
||||
|
||||
---
|
||||
|
||||
## 一、Bug 理解
|
||||
|
||||
**禅道 Bug #733**:【目录管理-诊疗目录】点击"编辑"按钮报错,且无法弹出编辑窗口进行数据修改
|
||||
|
||||
- **重现步骤**:登录系统 → 系统管理 > 目录管理 > 诊疗目录 → 选择任意行 → 点击【编辑】
|
||||
- **结果**:页面无响应,顶部红色报错:`No static resource data-dictionary/diagnosis-treatment/information-one for request '/healthlink-his/data-dictionary/diagnosis-treatment/information-one/'.`
|
||||
- **期望**:弹出"编辑诊疗项目"窗口,正确回显数据供修改
|
||||
|
||||
**综合**:用户在诊疗目录列表点击编辑时,前端请求后端获取详情接口失败,报 404 静态资源错误,编辑弹窗无法打开。根因是前端 API URL 写法有误。
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
**根因:`getDiagnosisTreatmentOne` 函数的 URL 末尾多了一个 `/`(trailing slash)**
|
||||
|
||||
对比代码:
|
||||
|
||||
| 文件 | 行 | URL | 状态 |
|
||||
|---|---|---|---|
|
||||
| `diagnosistreatment.js:15` | 编辑用 | `'/data-dictionary/diagnosis-treatment/information-one/'` | ❌ 多了 `/` |
|
||||
| `implementDepartment.js:65` | 同功能 | `'/data-dictionary/diagnosis-treatment/information-one?id=' + id` | ✅ 正确 |
|
||||
| `disease.js:15` | 类似目录 | `'/data-dictionary/disease/information-one'` | ✅ 正确 |
|
||||
| `device.js:15` | 类似目录 | `'/data-dictionary/device/information-one'` | ✅ 正确 |
|
||||
|
||||
**后端 Controller** (`DiagnosisTreatmentController.java`) 定义:
|
||||
```java
|
||||
@GetMapping("/information-one")
|
||||
public R<?> getDiseaseTreatmentOne(@RequestParam Long id)
|
||||
```
|
||||
|
||||
**请求链路**:
|
||||
1. `getDiagnosisTreatmentOne(row.id)` → Axios 拼接 URL
|
||||
2. Axios 将 `params: {id}` 作为 query string 追加
|
||||
3. 因 URL 以 `/` 结尾,实际请求变成:`/healthlink-his/data-dictionary/diagnosis-treatment/information-one/?id=xxx`
|
||||
4. Spring Boot 将 `/information-one/` 解析为**目录路径**,查找静态资源,返回 404 `No static resource`
|
||||
|
||||
**涉及文件**(仅 1 个文件需修改):
|
||||
- `healthlink-his-ui/src/views/catalog/diagnosistreatment/components/diagnosistreatment.js:15`
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
**修改 `diagnosistreatment.js` 第 15 行,去掉 URL 末尾的 `/`:**
|
||||
|
||||
```diff
|
||||
- url: '/data-dictionary/diagnosis-treatment/information-one/',
|
||||
+ url: '/data-dictionary/diagnosis-treatment/information-one',
|
||||
```
|
||||
|
||||
仅此一处修改,前后端代码风格一致,后端无需任何改动。
|
||||
|
||||
---
|
||||
|
||||
## 四、路由决策
|
||||
|
||||
**FIXER: zhaoyun(赵云)**
|
||||
|
||||
**REASON**: 纯前端 API URL 拼写错误,后端接口正常(`/information-one` 映射正确),只需前端修复一个字符,赵云负责前端开发最合适。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: zhaoyun
|
||||
- **修复 Agent**: zhaoyun(前端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
128
MD/bugs/BUG_734_ANALYSIS.md
Normal file
128
MD/bugs/BUG_734_ANALYSIS.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# Bug #734 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 00:19:48
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 734
|
||||
- **标题**: 【住院医生站-临床医嘱】医嘱开具时,录入框右侧缺少最小单位与剂量单位的动态换算公式说明(如:2袋 = 30 g)
|
||||
- **模块**: 住院医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
Now I have a complete picture. Let me output the analysis.
|
||||
|
||||
---
|
||||
|
||||
## Bug #734 分析报告
|
||||
|
||||
### 一、Bug 理解
|
||||
|
||||
**禅道标题:** 【住院医生站-临床医嘱】医嘱开具时,录入框右侧缺少最小单位与剂量单位的动态换算公式说明(如:2袋 = 30 g)
|
||||
|
||||
**重现步骤:**
|
||||
1. 登录"住院医生工作站",进入"临床医嘱"页面
|
||||
2. 点击【新增】录入一条医嘱,在药品搜索栏输入并选择"荆防颗粒"
|
||||
3. 在"单次用量"输入框中输入:2,单位:袋
|
||||
4. 观察"单次用量"单位下拉框右侧的公式显示区域
|
||||
|
||||
**期望结果:** 系统应自动读取该药品的计量换算值(15)与剂量单位(g),在单次用量右侧动态显示换算等式:`2袋 = 30 g (2×15g)`
|
||||
|
||||
**附图关键信息:**
|
||||
- 图片2539/2540:临床医嘱录入表单中,单次用量输入框(值=2)和单位下拉框(值=袋)右侧的红框区域**为空白**
|
||||
- 图片2541(药品目录):荆防颗粒的配置数据 — 计量换算=15,剂量单位=g,最小单位=袋
|
||||
- 临时医嘱同样缺失此公式显示
|
||||
|
||||
**总结:** 医生在开具临床医嘱时,输入单次用量后无法看到最小单位与剂量单位之间的换算公式说明。系统已有换算比例数据(`unitConversionRatio=15`),但前端未将其渲染为可视化的换算公式文本。
|
||||
|
||||
---
|
||||
|
||||
### 二、根因分析
|
||||
|
||||
**根因:前端模板缺少换算公式的渲染逻辑**
|
||||
|
||||
数据流追踪(全链路6环):
|
||||
|
||||
| 环 | 状态 | 说明 |
|
||||
|---|---|---|
|
||||
| ⑤ 存储 | ✅ | `medication_detail` 表有 `unit_conversion_ratio` 字段,值为15 |
|
||||
| ④ 持久化 | ✅ | `DoctorStationAdviceAppMapper.xml` 第14行 `abi.unit_conversion_ratio` 已查询 |
|
||||
| ③ 业务 | ✅ | `AdviceBaseDto.unitConversionRatio` 字段已定义,数据正常返回 |
|
||||
| ② 验证 | ✅ | API正常返回 `unitConversionRatio: 15` |
|
||||
| ① 录入 | ❌ | `OrderForm.vue` 中**没有**换算公式的显示区域 |
|
||||
|
||||
**具体分析:**
|
||||
|
||||
1. **后端数据完整**:`AdviceBaseDto` 有 `unitConversionRatio`(BigDecimal),Mapper SQL 已查询该字段
|
||||
2. **前端数据可达**:`setValue(row)` 中通过 `...baseRow` 展开,`row.unitConversionRatio` 在行数据上可用
|
||||
3. **已有换算逻辑**:`index.vue:2973` 的 `convertValues()` 函数已使用 `row.unitConversionRatio` 进行数值转换
|
||||
4. **缺失UI展示**:`OrderForm.vue` 在"单次用量" + "单位"下拉框之后,**没有任何显示换算公式的元素**
|
||||
|
||||
**涉及文件:**
|
||||
- `OrderForm.vue:109-126` — 长期医嘱表单,单位下拉框后缺少公式显示
|
||||
- `OrderForm.vue:352-362` — 临时医嘱表单,单位下拉框后缺少公式显示
|
||||
- `useOrder.js` — 已有 `convertValue` 逻辑(数值计算),无需修改
|
||||
|
||||
---
|
||||
|
||||
### 三、修复方案
|
||||
|
||||
**修改文件:** `healthlink-his-ui/src/views/inpatientDoctor/home/components/order/OrderForm.vue`
|
||||
|
||||
**修改内容:** 在两处单位下拉框(`minUnitCode` select)之后,添加换算公式显示元素。
|
||||
|
||||
#### 修改点1:长期医嘱表单(约第125行后)
|
||||
|
||||
在 `</el-select>`(minUnitCode)和 `</div>`(form-group关闭)之间,添加:
|
||||
|
||||
```html
|
||||
<span
|
||||
v-if="row.unitConversionRatio && row.doseQuantity"
|
||||
style="font-size: 13px; color: #409eff; margin-left: 4px; white-space: nowrap"
|
||||
>
|
||||
{{
|
||||
row.doseQuantity
|
||||
+ ' '
|
||||
+ (row.unitCodeList?.find(i => i.value === row.minUnitCode && i.type === 'minUnit')?.label || '')
|
||||
+ ' = '
|
||||
+ (row.doseQuantity * row.unitConversionRatio)
|
||||
+ ' '
|
||||
+ (row.unitCodeList?.find(i => i.type === config.unitMap['dose'])?.label || '')
|
||||
+ ' ('
|
||||
+ row.doseQuantity + '×' + row.unitConversionRatio
|
||||
+ ')'
|
||||
}}
|
||||
</span>
|
||||
```
|
||||
|
||||
#### 修改点2:临时医嘱表单(约第356行后)
|
||||
|
||||
同样在 minUnitCode 的 `</el-select>` 之后,添加相同的换算公式显示元素。
|
||||
|
||||
**公式渲染逻辑:**
|
||||
- 条件:`row.unitConversionRatio` 存在且 `row.doseQuantity` 有值时才显示
|
||||
- 格式:`{剂量}{最小单位} = {剂量×换算比} {剂量单位} ({剂量}×{换算比})`
|
||||
- 示例:`2袋 = 30 g (2×15g)`
|
||||
- 样式:蓝色小字(`#409eff`),不换行(`white-space: nowrap`)
|
||||
|
||||
**不需要修改后端**:数据链路完整,`unitConversionRatio` 已正确返回。
|
||||
|
||||
---
|
||||
|
||||
### 四、路由决策
|
||||
|
||||
**FIXER: zhaoyun**
|
||||
**REASON:** 纯前端模板修改,只需在 `OrderForm.vue` 两处添加换算公式显示元素,属于UI展示层修复,无后端改动。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: zhaoyun
|
||||
- **修复 Agent**: zhaoyun(前端)
|
||||
- **原因**: ** 纯前端模板修改,只需在 `OrderForm.vue` 两处添加换算公式显示元素,属于UI展示层修复,无后端改动。
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
26
MD/bugs/BUG_735_ANALYSIS.md
Normal file
26
MD/bugs/BUG_735_ANALYSIS.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Bug #735 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-13 00:12:22
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 735
|
||||
- **标题**: 【住院医生工作站-临床医嘱】数据逻辑缺陷:新医嘱点击“签发”后,“停嘱医生”字段错误生成数据
|
||||
- **模块**: 住院医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
Now I need to understand the full picture. Let me look at what happens during save for a new order — specifically how `contentJson` is constructed:
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
132
MD/bugs/BUG_738_ANALYSIS.md
Normal file
132
MD/bugs/BUG_738_ANALYSIS.md
Normal file
@@ -0,0 +1,132 @@
|
||||
# Bug #738 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-12 23:44:59
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 738
|
||||
- **标题**: 【住院医生工作站-临床医嘱】模块底部“检验、检查、输血、手术”功能按钮置灰,无法触发开单业务
|
||||
- **模块**: 住院医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
Analysis complete. Here's the full output:
|
||||
|
||||
---
|
||||
|
||||
## Bug #738 分析报告
|
||||
|
||||
---
|
||||
|
||||
### 一、Bug 理解
|
||||
|
||||
**禅道 Bug 标题**:【住院医生工作站-临床医嘱】模块底部"检验、检查、输血、手术"功能按钮置灰,无法触发开单业务
|
||||
|
||||
**重现步骤**:
|
||||
1. 登录账号:doctor1 密码:123456,登录"住院医生工作站"
|
||||
2. 在左侧列表中选中一名已入院患者
|
||||
3. 点击上方【临床医嘱】页签
|
||||
4. 观察页面底部"检验"、"检查"、"输血"、"手术"功能按钮状态
|
||||
|
||||
**期望结果**:在"临床医嘱"界面下,底部的"检验"、"检查"、"输血"、"手术"按钮应当处于可用(激活)状态,点击后应能正常弹出对应的申请单编辑界面。
|
||||
|
||||
**实际结果**:四个功能按钮处于置灰(禁用)状态,点击无任何响应。
|
||||
|
||||
**附图关键信息**:截图中红框标注了底部四个按钮(检验、检查、输血、手术)均为灰色不可点击状态,旁边标注"按钮变灰色无法触发开单"。其余页面功能(医嘱列表、操作按钮)均正常。
|
||||
|
||||
**综合总结**:在住院医生工作站的临床医嘱页签中,选中患者后底部四个申请单入口按钮(检验/检查/输血/手术)始终禁用,导致医生无法发起任何医疗申请。页面其他功能(新增、保存、签发等医嘱操作)均正常,问题仅限于这四个底部按钮的 disabled 状态判定。
|
||||
|
||||
---
|
||||
|
||||
### 二、根因分析
|
||||
|
||||
**直接原因**:
|
||||
|
||||
文件 `applicationFormBottomBtn.vue` (line 12, 19, 26, 33) 中,四个按钮的禁用条件为:
|
||||
```html
|
||||
:disabled="!props.patientInfo?.inHospitalOrgId"
|
||||
```
|
||||
|
||||
**数据流断裂链路**:
|
||||
|
||||
```
|
||||
home/index.vue (Advice 渲染)
|
||||
└→ <Advice ref="adviceRef" /> ← ❌ 未传递 patientInfo prop
|
||||
└→ order/index.vue (Advice 组件)
|
||||
└→ props.patientInfo = {} ← 默认空对象
|
||||
└→ <application-form-bottom-btn :patient-info="patientInfo" />
|
||||
└→ applicationFormBottomBtn.vue
|
||||
└→ props.patientInfo?.inHospitalOrgId → undefined
|
||||
└→ !undefined = true → 按钮全部禁用 ✗
|
||||
```
|
||||
|
||||
**核心断裂点**:`home/index.vue` 第 33-35 行:
|
||||
```html
|
||||
<el-tab-pane label="临床医嘱" name="prescription">
|
||||
<Advice ref="adviceRef" /> <!-- ← 没有传 :patient-info="currentPatientInfo" -->
|
||||
</el-tab-pane>
|
||||
```
|
||||
|
||||
而同页的"诊断录入"tab 正确传递了:
|
||||
```html
|
||||
<el-tab-pane label="诊断录入" name="diagnosis">
|
||||
<Diagnose ref="diagnosisRef" :patient-info="currentPatientInfo" />
|
||||
</el-tab-pane>
|
||||
```
|
||||
|
||||
**患者数据实际存在**:当患者被选中时,`handleItemClick` 正确调用了 `updateLocalPatientInfo(node)` 和 `updatePatientInfo(node)`,数据在 store 中是正确的。但 `applicationFormBottomBtn.vue` 没有从 store 读取,而是依赖从未被传递的 prop。
|
||||
|
||||
---
|
||||
|
||||
### 三、修复方案
|
||||
|
||||
**修改文件**:`healthlink-his-ui/src/views/inpatientDoctor/home/components/order/applicationForm/applicationFormBottomBtn.vue`
|
||||
|
||||
**修改内容**:让按钮的禁用条件从 store 中读取患者信息,而非依赖未被传递的 prop。
|
||||
|
||||
具体改动:
|
||||
1. 从 `../../store/localPatient.js` 导入 `localPatientInfo`
|
||||
2. 用 `computed` 属性从 store 获取 `inHospitalOrgId`
|
||||
3. 将四个按钮的 `:disabled` 条件改为使用该 computed 属性
|
||||
|
||||
```js
|
||||
// 新增 import
|
||||
import { localPatientInfo } from '../../../../store/localPatient.js'
|
||||
|
||||
// 新增 computed
|
||||
const effectivePatientInfo = computed(() => props.patientInfo || localPatientInfo.value)
|
||||
```
|
||||
|
||||
```html
|
||||
<!-- 修改四个按钮的 disabled 条件 -->
|
||||
:disabled="!effectivePatientInfo?.inHospitalOrgId"
|
||||
```
|
||||
|
||||
**铁律检查**:
|
||||
- 铁律6 ✓:不删除任何文件
|
||||
- 铁律7 ✓:不修改任何已有方法签名
|
||||
- 铁律18 ✓:不破坏已有功能,仅追加 store 读取逻辑
|
||||
- 铁律9 ✓:搜索确认无重复代码
|
||||
|
||||
**验证**:修改后 `npm run build:dev` 编译通过 → `npm run lint` 无 ERROR → 页面选中患者后按钮可点击。
|
||||
|
||||
---
|
||||
|
||||
### 四、路由决策
|
||||
|
||||
**FIXER**: **赵云 (zhaoyun)**
|
||||
|
||||
**REASON**: 纯前端问题 — `applicationFormBottomBtn.vue` 模板中 disabled 条件依赖的 `patientInfo` prop 从未被父组件传递,需修改前端 Vue 组件逻辑,属于赵云的前端/界面/按钮职责范围。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
84
MD/bugs/BUG_741_ANALYSIS.md
Normal file
84
MD/bugs/BUG_741_ANALYSIS.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# Bug #741 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-12 11:46:17
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 741
|
||||
- **标题**: 【住院医生工作站】打开门诊医生工作站会有代码列表报错
|
||||
- **模块**: 住院医生工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
### 一、Bug 理解
|
||||
|
||||
用户登录 doctor1 账号进入**住院医生工作站**页面时,页面加载过程中某个 API 请求返回了 500 错误,错误信息为 `class java.util.ArrayList cannot be cast to class com.fasterxml.jackson.databind.JsonNode`。这个 Java ClassCastException 被前端 `request.js` 拦截器捕获并弹出错误提示,导致页面功能异常。期望是页面能正常加载,患者列表和各 Tab 页正常工作。
|
||||
|
||||
### 二、根因分析
|
||||
|
||||
**直接原因**:后端某个 API 接口在处理请求或序列化响应时,抛出了 `ClassCastException: ArrayList cannot be cast to JsonNode`。异常被 `GlobalExceptionHandler` 捕获后返回 `{code:500, msg:"class java.util.ArrayList cannot be cast to class com.fasterxml.jackson.databind.JsonNode"}`。
|
||||
|
||||
**根因定位**:commit `68cfa4882` 修改了 `ApplicationConfig`,将 `Jackson2ObjectMapperBuilderCustomizer` 替换为直接创建 `new ObjectMapper()` 的 `@Bean`。
|
||||
|
||||
```java
|
||||
// 旧代码 — 定制 Spring Boot 自动配置的 ObjectMapper
|
||||
@Bean
|
||||
public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
|
||||
return builder -> { ... };
|
||||
}
|
||||
|
||||
// 新代码 — 直接覆盖 Spring Boot 自动配置的 ObjectMapper
|
||||
@Bean
|
||||
public ObjectMapper objectMapper() {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
**问题机制**:
|
||||
1. 定义 `@Bean ObjectMapper` 会**替换** Spring Boot 自动配置的 `ObjectMapper`,丢失大量自动配置(模块注册、类型解析器、序列化注解处理等)
|
||||
2. Spring Boot 4.x 的 `MappingJackson2HttpMessageConverter` 使用此 Bean 做响应序列化
|
||||
3. 当 `DictAspect`(拦截所有 `@GetMapping`/`@PostMapping`)处理 `R<IPage<RegPatientMainInfoDto>>` 响应时,`IPage` 的泛型信息在新 `ObjectMapper` 下无法正确解析
|
||||
4. Jackson 内部在序列化过程中尝试将 `ArrayList`(`IPage` 内部的 records 列表)强转为 `JsonNode`,导致 `ClassCastException`
|
||||
|
||||
**涉及文件**:
|
||||
- `core-framework/.../ApplicationConfig.java` — **根因所在**,ObjectMapper Bean 配置不当
|
||||
- `healthlink-his-common/.../DictAspect.java` — 拦截所有 Controller 方法,触发序列化链路
|
||||
- `regdoctorstation/.../AdviceManageController.java` — `/reg-patient-zk` 端点
|
||||
- `regdoctorstation/.../AdviceManageAppServiceImpl.java` — `getRegPatientMainInfo()` 返回 `IPage`
|
||||
- `utils/request.js` — 前端拦截器,line 186 抛出 Promise reject
|
||||
|
||||
### 三、修复方案
|
||||
|
||||
**修改文件**:`core-framework/src/main/java/com/core/framework/config/ApplicationConfig.java`
|
||||
|
||||
**修复方式**:将 `@Bean ObjectMapper` 回退为 `Jackson2ObjectMapperBuilderCustomizer`,这样 Spring Boot 自动配置的 ObjectMapper 保持不变,只在其基础上追加自定义配置:
|
||||
|
||||
```java
|
||||
@Bean
|
||||
public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
|
||||
return builder -> {
|
||||
builder.timeZone(TimeZone.getDefault());
|
||||
builder.simpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
JavaTimeModule javaTimeModule = new JavaTimeModule();
|
||||
javaTimeModule.addDeserializer(LocalDateTime.class, LOCAL_DATE_TIME_DESERIALIZER);
|
||||
javaTimeModule.addSerializer(LocalDateTime.class,
|
||||
new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||
builder.modules(javaTimeModule);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
**验证步骤**:
|
||||
1. `mvn clean compile -DskipTests` — 编译通过
|
||||
2. 启动应用 → 以 doctor1 登录 → 进入住院医生工作站 → 确认无报错
|
||||
3. 验证患者列表正常加载、诊断/医嘱 Tab 页正常切换
|
||||
|
||||
### 四、路由决策
|
||||
|
||||
- **修复 Agent**: guanyu(后端开发)
|
||||
- **原因**: 修复点在 `ApplicationConfig.java` 的 ObjectMapper Bean 配置,属于后端 Spring 配置问题,需要回退 Jackson 序列化配置并验证编译通过。
|
||||
91
MD/bugs/BUG_742_ANALYSIS.md
Normal file
91
MD/bugs/BUG_742_ANALYSIS.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# Bug #742 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-12 23:08:48
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 742
|
||||
- **标题**: 【收费工作站-住院登记】待登记入院和已登记入院出现查找数据库的报错
|
||||
- **模块**: 收费工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
编译通过。现在我已完整理解了 Bug 的根因和修复历史。
|
||||
|
||||
---
|
||||
|
||||
### 一、Bug 理解
|
||||
|
||||
**禅道 Bug #742 原文引用:**
|
||||
|
||||
- **标题**:【收费工作站-住院登记】待登记入院和已登记入院出现查找数据库的报错
|
||||
- **严重程度**:2 (严重)
|
||||
- **重现步骤**:登录内科医生1账号 → 收费工作站 → 住院登记 → 打开"待登记入院"和"已登记入院"标签页
|
||||
- **实际结果**:两个页面均出现红色报错:`BindingException: Parameter 'startTime' not found. Available parameters are [formEnum, param5, ew, encounterStatus, param6, page, registeredFlag, param3, param4, param1, encounterClass, param2]`
|
||||
- **期望结果**:进入住院登记模块,能正常打开"待登记入院"和"已登记入院"板块并显示数据
|
||||
|
||||
**附图关键信息**:截图显示两个标签页均为空白/暂无数据,顶部红色错误提示 MyBatis `BindingException`——`startTime` 参数在 Mapper 可用参数列表中不存在。
|
||||
|
||||
**综合总结**:用户在"收费工作站→住院登记"模块中,两个核心列表页(待登记入院、已登记入院)均因后端 MyBatis 参数绑定错误而无法加载任何数据,功能完全中断。根本原因是 Mapper XML 引用了 `#{startTime}` 等参数,但 Mapper Java 接口中缺少对应的 `@Param("startTime")` 注解。
|
||||
|
||||
---
|
||||
|
||||
### 二、根因分析
|
||||
|
||||
**根因**:Mapper XML 与 Mapper Java 接口参数不匹配。
|
||||
|
||||
**时间线追溯**:
|
||||
|
||||
| 时间 | 操作 | 影响 |
|
||||
|------|------|------|
|
||||
| Jun 10 (commit `8c42cf11b`) | 华佗更新 Mapper XML,新增 `#{startTime}`、`#{endTime}`、`#{organizationId}` 的 `<if>` 条件 | ⚠️ XML 引用了 3 个新参数,但**未同步更新 Mapper Java 接口** |
|
||||
| Jun 11 01:42 UTC | 王栩坤报告 Bug #742 | 此时 Mapper Java 仍缺少 `@Param("startTime")` |
|
||||
| Jun 11 10:05 (commit `defab36cc`) | 冉芸侨添加 `@Param` 注解,但放在 `queryWrapper` 之后 | 部分修复,参数顺序与 AppService 调用不一致 |
|
||||
| Jun 11 17:30 (commit `babd8d0c0`) | 华佗重排 Mapper 参数顺序,AppService 改为从方法参数取值 | ✅ 修复完成,三层对齐 |
|
||||
|
||||
**涉及文件**:
|
||||
|
||||
| 文件 | 问题 |
|
||||
|------|------|
|
||||
| `InHospitalRegisterAppMapper.xml` | 新增 `#{startTime}` 等引用(Jun 10),但 Mapper Java 未同步 |
|
||||
| `InHospitalRegisterAppMapper.java` | 缺少 `@Param("startTime")` / `@Param("endTime")` / `@Param("organizationId")` |
|
||||
| `InHospitalRegisterAppServiceImpl.java` | 调用 Mapper 时参数顺序与 Mapper 签名不匹配 |
|
||||
|
||||
**铁律违反**:违反铁律 4(前后端 API 路径/参数对齐)和铁律 19(编译错误不区分来源)——XML 更新后必须同步更新 Mapper Java 接口。
|
||||
|
||||
---
|
||||
|
||||
### 三、修复方案
|
||||
|
||||
**当前代码状态**:经 `defab36cc` + `babd8d0c0` 两次提交,修复已完成,编译通过(已验证 `mvn clean compile -DskipTests` BUILD SUCCESS)。
|
||||
|
||||
**已修复的对齐关系**:
|
||||
|
||||
1. **Mapper Java** (`InHospitalRegisterAppMapper.java:28-33`):`@Param("startTime")`, `@Param("endTime")`, `@Param("organizationId")` 已在 `queryWrapper` 之前
|
||||
2. **AppService** (`InHospitalRegisterAppServiceImpl.java:175-193`):方法签名接收 `Date startTime, Date endTime, Long organizationId`,调用 Mapper 时按正确顺序传入
|
||||
3. **Controller** (`InHospitalRegisterController.java:56-62`):`@RequestParam("startTime")` / `@RequestParam("endTime")` / `@RequestParam("organizationId")` 正确传递到 Service
|
||||
4. **Mapper XML**:`<if test='startTime != null'>` 正确引用 `#{startTime}`
|
||||
|
||||
**结论**:代码层面的修复已完成。需要:
|
||||
- 重新部署编译后的应用(当前服务器运行的是修复前的版本)
|
||||
- 验证部署后"待登记入院"和"已登记入院"两个列表页能正常加载数据
|
||||
|
||||
---
|
||||
|
||||
### 四、路由决策
|
||||
|
||||
**FIXER**: `guanyu`(后端开发)
|
||||
**REASON**:这是纯后端 MyBatis Mapper 参数绑定问题,代码已修复但需确认部署和运行验证。如果需要额外的接口测试或边界情况验证,交由 `guanyu` 执行后端验证。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
162
MD/bugs/BUG_743_ANALYSIS.md
Normal file
162
MD/bugs/BUG_743_ANALYSIS.md
Normal file
@@ -0,0 +1,162 @@
|
||||
# Bug #743 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-12 23:02:08
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 743
|
||||
- **标题**: 【急诊管理】急诊抢救模块下的开始抢救只填分诊id会出现报错null value in column "patient_id" of relation "emergency_rescue" violates not-null constraint
|
||||
- **模块**: 会诊管理
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
Now I have a complete picture. Let me produce the analysis.
|
||||
|
||||
---
|
||||
|
||||
### 一、Bug 理解
|
||||
|
||||
**禅道 Bug #743 原文:**
|
||||
> **标题**:【急诊管理】急诊抢救模块下的开始抢救只填分诊id会出现报错 null value in column "patient_id" of relation "emergency_rescue" violates not-null constraint
|
||||
>
|
||||
> **重现步骤**:登录内科医生1的账号 doctor1/123456 → 进入急诊管理 → 急诊抢救 → 点击开始抢救 → 只填写分诊ID → 点击确认
|
||||
>
|
||||
> **结果**:报错 `PSQLException: ERROR: null value in column "patient_id" of relation "emergency_rescue" violates not-null constraint`
|
||||
>
|
||||
> **期望**:不会出现报错,能够正常实现,或者显示"患者ID的字段未填入,请填入患者ID"
|
||||
|
||||
**附图分析**:截图中表单显示"患者ID"输入框为空(无值),"分诊ID"填入了 `1`,点击确定后页面顶部弹出红色数据库报错横幅。INSERT SQL 为 `INSERT INTO emergency_rescue (id, triage_id, rescue_start, chief_doctor, rescue_team, procedures, medications, create_by, create_time, tenant_id)` —— 完全缺少 `patient_id` 字段。
|
||||
|
||||
**综合总结**:用户在"开始抢救"弹窗中只填写了分诊ID、未填患者ID就提交,后端没有做参数校验就直接调用 `rescueService.save()`,导致 MyBatis-Plus 生成的 INSERT 语句不含 `patient_id`,PostgreSQL 的 NOT NULL 约束拒绝插入,系统将底层数据库报错直接暴露给用户。正确行为应该是:后端校验 `patient_id` 必填(或从分诊记录自动关联患者ID),前端也应加必填校验。
|
||||
|
||||
---
|
||||
|
||||
### 二、根因分析
|
||||
|
||||
**根因:`addRescue` 方法零校验 + 缺少患者ID自动关联逻辑**
|
||||
|
||||
调用链路:前端 `submitForm()` → POST `/emergency/rescue/add` → `EmergencyController.addRescue()` → `rescueService.save(rescue)` → DB INSERT
|
||||
|
||||
| 问题层 | 具体问题 |
|
||||
|--------|---------|
|
||||
| **后端 Controller** | `addRescue()` 方法(第167行)直接 `rescueService.save(rescue)`,**无任何参数校验**,`patientId` 为 null 时仍然保存 |
|
||||
| **后端 Controller** | 虽然有 `triageId` → `EmergencyTriage` 的联动逻辑(第172行),但这段逻辑在 `save` **之后**,且只更新分诊状态,**没有从 triage 反填 patientId** |
|
||||
| **前端 Form** | `el-form` 无 `:rules` 校验规则,`el-form-item` 无 `required` 标记,患者ID可为空直接提交 |
|
||||
| **数据库** | `emergency_rescue.patient_id` 有 NOT NULL 约束,MyBatis-Plus 对 null 字段不生成 INSERT 列,导致约束违反 |
|
||||
|
||||
**涉及文件**:
|
||||
- `healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/emergency/controller/EmergencyController.java` — 第165-180行 `addRescue` 方法
|
||||
- `healthlink-his-ui/src/views/emergency/rescue/index.vue` — 表单模板 + `submitForm` 函数
|
||||
- `healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/emergency/domain/EmergencyTriage.java` — `patientId` 字段(用于反填)
|
||||
|
||||
---
|
||||
|
||||
### 三、修复方案
|
||||
|
||||
#### 修复1:后端 Controller — 增加校验 + 从分诊记录自动关联 patientId
|
||||
|
||||
**文件**: `EmergencyController.java` 第165-180行
|
||||
|
||||
**修改内容**:在 `save` 前增加校验和自动填充逻辑:
|
||||
|
||||
```java
|
||||
@PostMapping("/rescue/add")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> addRescue(@RequestBody EmergencyRescue rescue) {
|
||||
// 从分诊记录自动关联患者ID(如果前端未传 patientId)
|
||||
if (rescue.getPatientId() == null && rescue.getTriageId() != null) {
|
||||
EmergencyTriage triage = triageService.getById(rescue.getTriageId());
|
||||
if (triage == null) {
|
||||
return R.fail("分诊记录不存在,请检查分诊ID");
|
||||
}
|
||||
if (triage.getPatientId() == null) {
|
||||
return R.fail("关联的分诊记录中患者ID为空,无法创建抢救记录");
|
||||
}
|
||||
rescue.setPatientId(triage.getPatientId());
|
||||
}
|
||||
// 最终校验 patientId 必填
|
||||
if (rescue.getPatientId() == null) {
|
||||
return R.fail("患者ID不能为空,请填写患者ID或提供有效的分诊ID");
|
||||
}
|
||||
rescue.setRescueStart(new Date());
|
||||
rescue.setCreateTime(new Date());
|
||||
rescueService.save(rescue);
|
||||
// 联动更新分诊状态
|
||||
if (rescue.getTriageId() != null) {
|
||||
EmergencyTriage triage = triageService.getById(rescue.getTriageId());
|
||||
if (triage != null) {
|
||||
triage.setStatus("IN_TREATMENT");
|
||||
triageService.updateById(triage);
|
||||
}
|
||||
}
|
||||
return R.ok(rescue);
|
||||
}
|
||||
```
|
||||
|
||||
**核心逻辑**:
|
||||
1. 如果前端没传 `patientId` 但传了 `triageId`,从 `EmergencyTriage` 记录中自动取 `patientId` 填入
|
||||
2. 如果两个都没有 → 返回友好错误信息 `R.fail("患者ID不能为空...")`
|
||||
3. 确保 `patientId` 在 `save` 前必定有值
|
||||
|
||||
#### 修复2:前端表单 — 增加必填校验规则
|
||||
|
||||
**文件**: `healthlink-his-ui/src/views/emergency/rescue/index.vue`
|
||||
|
||||
**修改内容**:
|
||||
|
||||
```vue
|
||||
<!-- 1. el-form 加 :rules -->
|
||||
<el-form :model="form" label-width="100px" :rules="formRules" ref="formRef">
|
||||
|
||||
<!-- 2. 患者ID 加 prop -->
|
||||
<el-form-item label="患者ID" prop="patientId">
|
||||
|
||||
<!-- 3. 分诊ID 加 prop -->
|
||||
<el-form-item label="分诊ID" prop="triageId">
|
||||
```
|
||||
|
||||
```js
|
||||
// 4. 在 script setup 中添加:
|
||||
import {ref, reactive, onMounted} from 'vue'
|
||||
const formRef = ref(null)
|
||||
const formRules = reactive({
|
||||
patientId: [{ required: true, message: '请输入患者ID', trigger: 'blur' }],
|
||||
triageId: [{ required: true, message: '请输入分诊ID', trigger: 'blur' }]
|
||||
})
|
||||
|
||||
// 5. 修改 submitForm 加表单校验:
|
||||
const submitForm = async () => {
|
||||
await formRef.value.validate()
|
||||
if (isEdit.value) {
|
||||
await (await import('./api')).update(form.value || {})
|
||||
} else {
|
||||
await add(form.value)
|
||||
}
|
||||
ElMessage.success('操作成功')
|
||||
dlgVisible.value = false
|
||||
loadData()
|
||||
}
|
||||
```
|
||||
|
||||
**注意**:由于后端已做了"只填分诊ID自动反填患者ID"的逻辑,前端可以将 `patientId` 改为非必填(允许用户只填分诊ID即可),但建议至少保留 `triageId` 必填。如果希望更严格,则两个都必填。
|
||||
|
||||
---
|
||||
|
||||
### 四、路由决策
|
||||
|
||||
**FIXER**: `guanyu`(后端)+ `zhaoyun`(前端)
|
||||
|
||||
**REASON**: 核心修复在后端 `EmergencyController.addRescue()` 方法——增加参数校验和从分诊记录自动关联 `patientId`,这是 bug 的根因所在,由 **guanyu** 负责。前端 `rescue/index.vue` 的表单校验规则增强为辅助防御层,由 **zhaoyun** 负责。两个修改互相独立,可并行进行。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
109
MD/bugs/BUG_744_ANALYSIS.md
Normal file
109
MD/bugs/BUG_744_ANALYSIS.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# Bug #744 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-12 22:59:18
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 744
|
||||
- **标题**: 【病案管理】申请借阅的报卡出现报错Error updating database. Cause: org.postgresql.util.PSQLException
|
||||
- **模块**: 疾病报告管理
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
分析完成。以下是完整的 Bug 分析报告。
|
||||
|
||||
---
|
||||
|
||||
### 一、Bug 理解
|
||||
|
||||
**禅道 Bug #744 原文:**
|
||||
- **标题**:【病案管理】申请借阅的报卡出现报错Error updating database
|
||||
- **重现步骤**:登录内科医生1的账号:doctor1 密码:123456 → 进入病案管理 → 打开申请借阅
|
||||
- **结果**:出现报错 `ERROR: null value in column "medical_record_id" of relation "mr_borrowing" violates not-null constraint`
|
||||
- **期望**:能够正常操作申请借阅功能,不会出现爆红报错
|
||||
|
||||
**附图关键信息:**
|
||||
- 页面标题"申请借阅",弹窗表单有字段:病案号(`111`)、患者(空)、借阅人(`1111`)、借阅科室(`111`)、借阅原因(`1111`)
|
||||
- 红色错误条显示 `INSERT INTO mr_borrowing (id, patient_name, mr_number, borrower_name, borrower_dept, borrow_reason, ...)` — **注意 INSERT 语句中根本没有 `medical_record_id` 字段**
|
||||
- `Failing row contains (2064902426836570114, null, , 111, 1111, ...)` — `medical_record_id` 位置为 null
|
||||
|
||||
**综合总结:** 用户在"病案管理 → 申请借阅"页面填写表单并提交时,系统向 `mr_borrowing` 表插入记录失败,因为 `medical_record_id` 字段(NOT NULL 约束)未被赋值。这是一个前后端都遗漏了该字段的缺陷——前端表单没有这个输入项,后端 Controller 也没有自动填充。
|
||||
|
||||
---
|
||||
|
||||
### 二、根因分析
|
||||
|
||||
**直接原因:** `mr_borrowing` 表的 `medical_record_id` 列有 `NOT NULL` 约束,但 INSERT 语句中该字段为 null。
|
||||
|
||||
**代码层面根因(两处缺失):**
|
||||
|
||||
| 层 | 文件 | 问题 |
|
||||
|---|---|---|
|
||||
| **前端** | `healthlink-his-ui/src/views/mrmanagement/index.vue` | `borrowForm` 只有 `mrNumber, patientName, borrowerName, borrowerDept, borrowReason`,**没有 `medicalRecordId` 字段**。表单提交时不会携带此值 |
|
||||
| **后端** | `healthlink-his-application/.../MrManagementController.java` | `applyBorrowing()` 方法直接将前端传来的 `MrBorrowing` 对象 save,**没有校验或设置 `medicalRecordId`** |
|
||||
|
||||
**数据库约束确认:** `V18__emr_mr_nursing_fhir.sql` 中建表语句 `medical_record_id BIGINT NOT NULL`。
|
||||
|
||||
**`medicalRecordId` 的含义:** 它是 `mr_homepage` 表的 `id`(病案首页记录的主键),是 `mr_borrowing` 表的外键,用于关联具体哪份病案被借阅。
|
||||
|
||||
---
|
||||
|
||||
### 三、修复方案
|
||||
|
||||
#### 修复点 1:前端表单补充 `medicalRecordId` 字段(主要修复)
|
||||
|
||||
**文件**:`healthlink-his-ui/src/views/mrmanagement/index.vue`
|
||||
|
||||
1. `borrowForm` reactive 增加 `medicalRecordId: null`
|
||||
2. 借阅弹窗表单中增加 `medicalRecordId` 的输入方式:
|
||||
- **方案 A(推荐,最简)**:在"病案号"输入旁增加一个"病案首页ID"输入框(或改为下拉选择,从病案首页列表中选取),绑定 `borrowForm.medicalRecordId`
|
||||
- **方案 B(更好体验)**:将"病案号"改为远程搜索下拉(`el-select` + `remote-method`),用户输入病案号后自动查询 `mr_homepage`,选中后自动填充 `medicalRecordId` 和 `patientName`
|
||||
|
||||
#### 修复点 2:后端 Controller 增加校验(防御性编程)
|
||||
|
||||
**文件**:`healthlink-his-application/.../MrManagementController.java`
|
||||
|
||||
在 `applyBorrowing()` 方法中增加校验:
|
||||
|
||||
```java
|
||||
@PostMapping("/borrowing/apply")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> applyBorrowing(@RequestBody MrBorrowing borrowing) {
|
||||
// 新增:校验必填字段
|
||||
if (borrowing.getMedicalRecordId() == null) {
|
||||
return R.fail("病案首页ID不能为空");
|
||||
}
|
||||
borrowing.setStatus(0);
|
||||
borrowing.setBorrowDate(new Date());
|
||||
borrowing.setCreateTime(new Date());
|
||||
borrowingService.save(borrowing);
|
||||
return R.ok(borrowing);
|
||||
}
|
||||
```
|
||||
|
||||
#### 修复点 3(可选增强):后端提供根据病案号查询的接口
|
||||
|
||||
如果前端要实现"输入病案号自动查询填充",需要后端提供根据 `mr_number` 查询 `mr_homepage` 的接口,返回 `id` 和 `patientName`。
|
||||
|
||||
---
|
||||
|
||||
### 四、路由决策
|
||||
|
||||
**FIXER**: `guanyu`(后端)+ `zhaoyun`(前端)
|
||||
|
||||
**REASON**: 此 Bug 需要前后端同时修改——后端 Controller 需增加 `medicalRecordId` 校验,前端表单需补充该字段的输入和提交。属于典型的前后端联合修复场景,建议 `guanyu` 修后端校验 + `zhaoyun` 修前端表单,两人并行。
|
||||
|
||||
**优先级**:前端修复是关键路径(没有该字段提交永远失败),后端校验是防御性补充。如果只能一个 Agent,优先 `zhaoyun`。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
122
MD/bugs/BUG_745_ANALYSIS.md
Normal file
122
MD/bugs/BUG_745_ANALYSIS.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# Bug #745 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-12 22:54:49
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 745
|
||||
- **标题**: 【病案管理】申请封存的报卡出现报错Error updating database. Cause: org.postgresql.util.PSQLException
|
||||
- **模块**: 会诊管理
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
分析完毕,根因非常清晰。
|
||||
|
||||
---
|
||||
|
||||
## 一、Bug 理解
|
||||
|
||||
**禅道 Bug #745:【病案管理】申请封存的报卡出现报错Error updating database. Cause: org.postgresql.util.PSQLException**
|
||||
|
||||
- **重现步骤**:登录内科医生1账号(doctor1/123456),进入病案管理,打开病案封存标签页,点击"申请封存",填写表单后点"确认封存"
|
||||
- **结果**:出现红色错误提示:`null value in column "medical_record_id" of relation "mr_sealing" violates not-null constraint`
|
||||
- **期望**:能正常操作申请封存功能,不出现报错
|
||||
|
||||
**附图分析**:
|
||||
- 弹窗中填写了:病案号`12`、患者`12`、封存类型`主动封存`、封存原因`12`、封存人`12`
|
||||
- 错误 SQL 的 INSERT 列表为 `(id, patient_name, mr_number, seal_reason, seal_type, seal_date, seal_by, status, create_by, create_time, tenant_id)` —— **完全缺少 `medical_record_id` 列**
|
||||
- Failing row 的第二个值为 `null`,确认该字段未被赋值
|
||||
|
||||
**综合总结**:用户在"病案封存"页面填写封存信息并提交时,由于前端表单未传递 `medicalRecordId` 字段,后端也未对该字段做赋值或校验,导致向数据库 `mr_sealing` 表 INSERT 时 `medical_record_id` 列为空值,违反了 NOT NULL 约束,操作失败。
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
根因是**前后端均未处理 `medicalRecordId` 字段**:
|
||||
|
||||
| 层 | 问题 |
|
||||
|---|---|
|
||||
| **数据库** | `mr_sealing` 表定义了 `medical_record_id BIGINT NOT NULL`(`V18__emr_mr_nursing_fhir.sql`) |
|
||||
| **Entity** | `MrSealing.java` 有 `medicalRecordId` 字段,但前端不传时为 null |
|
||||
| **Controller** | `MrManagementController.sealRecord()` 直接 `sealingService.save(sealing)`,无任何校验 |
|
||||
| **Frontend** | `sealForm` 定义为 `{mrNumber:'',patientName:'',sealType:1,sealReason:'',sealBy:''}`,**无 `medicalRecordId`** |
|
||||
| **Frontend Dialog** | 表单只有5个字段:病案号、患者、封存类型、封存原因、封存人,**无 `medicalRecordId` 输入项** |
|
||||
|
||||
MyBatis-Plus 的 `save()` 方法会跳过 null 字段,所以 INSERT SQL 中不含 `medical_record_id`,违反 NOT NULL 约束。
|
||||
|
||||
**涉及文件**:
|
||||
- `healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/mrhomepage/domain/MrSealing.java:14` — Entity 有该字段
|
||||
- `healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/mrhomepage/controller/MrManagementController.java:80-86` — sealRecord 方法
|
||||
- `healthlink-his-ui/src/views/mrmanagement/index.vue:157` — sealForm 缺少 medicalRecordId
|
||||
- `healthlink-his-ui/src/views/mrmanagement/index.vue:127-141` — 封存弹窗缺少该字段
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
### 修改 1:前端 `index.vue` — sealForm 添加 medicalRecordId
|
||||
|
||||
**文件**: `healthlink-his-ui/src/views/mrmanagement/index.vue`
|
||||
|
||||
**第157行**,`sealForm` 添加 `medicalRecordId`:
|
||||
```js
|
||||
// 修改前
|
||||
const sealForm=reactive({mrNumber:'',patientName:'',sealType:1,sealReason:'',sealBy:''})
|
||||
// 修改后
|
||||
const sealForm=reactive({medicalRecordId:null,mrNumber:'',patientName:'',sealType:1,sealReason:'',sealBy:''})
|
||||
```
|
||||
|
||||
**第128-137行**,封存弹窗的 el-form 中添加 `medicalRecordId` 输入项(放在"病案号"之前):
|
||||
```vue
|
||||
<el-form-item label="病案ID"><el-input-number v-model="sealForm.medicalRecordId" :min="1" style="width:100%"/></el-form-item>
|
||||
```
|
||||
|
||||
### 修改 2:后端 Controller — 添加校验
|
||||
|
||||
**文件**: `healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/mrhomepage/controller/MrManagementController.java`
|
||||
|
||||
**第80-86行** `sealRecord()` 方法,在 `save()` 前添加校验:
|
||||
```java
|
||||
@PostMapping("/sealing/seal")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> sealRecord(@RequestBody MrSealing sealing) {
|
||||
if (sealing.getMedicalRecordId() == null) {
|
||||
return R.fail("医疗记录ID不能为空");
|
||||
}
|
||||
sealing.setStatus(0);
|
||||
sealing.setSealDate(new Date());
|
||||
sealing.setCreateTime(new Date());
|
||||
sealingService.save(sealing);
|
||||
return R.ok(sealing);
|
||||
}
|
||||
```
|
||||
|
||||
### 修改 3(同理修复借阅,预防性修复)
|
||||
|
||||
`mr_borrowing` 表同样有 `medical_record_id BIGINT NOT NULL`,`borrowForm` 也缺少该字段。建议同时修复:
|
||||
|
||||
**前端**:`borrowForm` 添加 `medicalRecordId`,借阅弹窗添加对应输入项
|
||||
|
||||
**后端**:`applyBorrowing()` 添加同样的 null 校验
|
||||
|
||||
---
|
||||
|
||||
## 四、路由决策
|
||||
|
||||
**FIXER**: **guanyu** + **zhaoyun**
|
||||
|
||||
**REASON**: 需要同时修改后端 Controller(guanyu 负责)和前端 Vue 表单(zhaoyun 负责),涉及前后端联调,两个 Agent 协作完成。修复量小(3处改动),属于典型前后端对齐 Bug。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: '',patientName:'',sealType:1,sealReason:'',sealBy:''}`,**无 `medicalRecordId`** |
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
85
MD/bugs/BUG_746_ANALYSIS.md
Normal file
85
MD/bugs/BUG_746_ANALYSIS.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# Bug #746 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-12 22:51:12
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 746
|
||||
- **标题**: 【电子病历管理】病历时效加载卡死会有报错了“No static resource emr-archive/overdue/list for request '/healthlink-his/emr-archive/overdue/list'.”
|
||||
- **模块**: 会诊管理
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
Now I have all the information needed. Here's my analysis:
|
||||
|
||||
---
|
||||
|
||||
## 一、Bug 理解
|
||||
|
||||
**禅道 Bug #746**:
|
||||
- **标题**:【电子病历管理】病历时效加载卡死会有报错了"No static resource emr-archive/overdue/list for request '/healthlink-his/emr-archive/overdue/list'."
|
||||
- **重现步骤**:登录内科医生1账号 → 打开电子病历管理 → 打开病历时效 → 出现报错
|
||||
- **期望结果**:能够正常进入病历时效,卡死界面能够正常显示
|
||||
- **附图关键信息**:页面顶部红色错误条 `No static resource emr-archive/overdue/list for request '/healthlink-his/emr-archive/overdue/list'`;四个统计卡片全部为 0;数据列表空白并显示加载中旋转图标
|
||||
|
||||
**总结**:用户在病历时效页面加载时,前端请求了错误的 API 路径 `/emr-archive/overdue/list`,该路径在后端无对应 Controller 端点,导致数据加载失败、页面卡死。
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
**问题链条**:
|
||||
|
||||
| 层级 | 文件 | 问题 |
|
||||
|------|------|------|
|
||||
| 前端 API | `src/api/emr.js` | `getOverdueList` 定义了错误 URL `/emr-archive/overdue/list` |
|
||||
| 前端 API | `src/api/emr/index.js` | `getOverdueList` 定义了正确 URL `/api/v1/emr/timeliness/overdue` |
|
||||
| 前端页面 | `src/views/emr/timeliness/index.vue:40` | `import ... from '@/api/emr'` → 解析到 `emr.js` 而非 `emr/index.js` |
|
||||
| 后端 | `EmrArchiveController` (`/emr-archive`) | 只有 `/page`, `/print`, `/archive`, `/reprint`, `/stats`,无 `/overdue/list` |
|
||||
| 后端 | `StructuredEmrController` (`/api/v1/emr`) | 已有 `/timeliness/overdue` 端点 ✅ |
|
||||
|
||||
**根因**:Vite 的 `@` 别名解析规则是「文件优先于目录索引」。`@/api/emr` 先匹配到 `src/api/emr.js`(文件),不会进入 `src/api/emr/index.js`(目录索引)。`src/api/emr.js` 中的 `getOverdueList` 使用了不存在的后端路径 `/emr-archive/overdue/list`。
|
||||
|
||||
`src/api/emr.js` 中的另外两个函数也有同样问题:
|
||||
- `getTimelinessByEncounter` → `/emr-revision/timeliness/...`(不存在)
|
||||
- `getTimelinessStatistics` → `/emr-revision/statistics`(不存在)
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
**方案:修复 `src/api/emr.js` 中的错误 URL,对齐到 `StructuredEmrController` 的正确端点**
|
||||
|
||||
需修改 **1 个文件**:
|
||||
|
||||
### `healthlink-his-ui/src/api/emr.js`
|
||||
|
||||
将三个函数的 URL 修改为后端 `StructuredEmrController` 的正确路径:
|
||||
|
||||
| 函数 | 错误 URL | 正确 URL |
|
||||
|------|---------|---------|
|
||||
| `getTimelinessByEncounter` | `/emr-revision/timeliness/{id}` | `/api/v1/emr/timeliness/encounter/{id}` |
|
||||
| `getTimelinessStatistics` | `/emr-revision/statistics` | `/api/v1/emr/timeliness/statistics` |
|
||||
| `getOverdueList` | `/emr-archive/overdue/list` | `/api/v1/emr/timeliness/overdue` |
|
||||
|
||||
同时 `getPendingEmrCount` 指向 `/emr-archive/pending-count`,后端 `EmrArchiveController` 也没有该端点,也需要同步处理(可暂改为调用 `/emr-archive/stats` 或在后端补充端点)。
|
||||
|
||||
---
|
||||
|
||||
## 四、路由决策
|
||||
|
||||
**FIXER**: guanyu
|
||||
**REASON**: 修复仅涉及前端 API URL 对齐后端已有端点,属于简单的接口路径修正,后端端点已存在无需改动,交给后端/全栈开发关羽处理即可。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
97
MD/bugs/BUG_748_ANALYSIS.md
Normal file
97
MD/bugs/BUG_748_ANALYSIS.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# Bug #748 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-12 22:48:02
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 748
|
||||
- **标题**: 【临床路径】临床路径管理下的操作按钮报错:Error updating database. Cause: org.postgresql.util.PSQLException:
|
||||
- **模块**: 系统管理
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
Analysis complete. Here's my full report:
|
||||
|
||||
---
|
||||
|
||||
### 一、Bug 理解
|
||||
|
||||
**禅道 Bug #748:【临床路径】临床路径管理下的操作按钮报错**
|
||||
|
||||
> **重现步骤**:登录内科医生1的账号(doctor1/123456)→ 进入临床路径 → 点击操作下的按钮(入径/完成/变异)
|
||||
>
|
||||
> **期望结果**:能够正常响应这几个按钮的操作,不会出现报错
|
||||
|
||||
**附图关键信息**:页面顶部显示红色错误提示框:
|
||||
```
|
||||
ERROR: column "create_by" of relation "clinical_pathway_execution" does not exist
|
||||
SQL: INSERT INTO clinical_pathway_execution (id, pathway_id, enter_date, status, create_by, create_time, tenant_id) VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
```
|
||||
页面列表正常显示了临床路径数据(J18.9 肺炎 / 社区获得性肺炎临床路径),但点击操作按钮即报错。
|
||||
|
||||
**综合总结**:用户在临床路径管理页面点击"入径"等操作按钮时,系统尝试向 `clinical_pathway_execution` 表插入记录,但 SQL 中包含了表里不存在的 `create_by` 列,导致 PostgreSQL 抛出 PSQLException。这是 Entity 继承 HisBaseEntity 后引入的字段与数据库表结构不匹配的问题。
|
||||
|
||||
---
|
||||
|
||||
### 二、根因分析
|
||||
|
||||
**完整因果链**:
|
||||
|
||||
1. **Entity 层**:`ClinicalPathwayExecution extends HisBaseEntity`(`healthlink-his-domain/.../clinical/domain/ClinicalPathwayExecution.java`)
|
||||
2. **HisBaseEntity** 定义了 6 个字段:`createBy`、`createTime`、`updateBy`、`updateTime`、`tenantId`、`deleteFlag`
|
||||
3. **MyBatis-Plus** 自动映射为列名:`create_by`、`create_time`、`update_by`、`update_time`、`tenant_id`、`delete_flag`
|
||||
4. **V30 迁移脚本**建表时只包含:`create_time`、`tenant_id`、`delete_flag`(3/6 匹配)
|
||||
5. **缺失列**:`create_by`、`update_by`、`update_time`(3 个字段缺失)
|
||||
6. **V43 迁移脚本**(`V43__add_hisbase_columns_to_clinical_pathway_execution.sql`)已存在,意图修复此问题,但**该迁移在目标数据库上未成功执行**
|
||||
7. INSERT 时 MyBatis-Plus 生成了包含 `create_by` 的 SQL → **PSQLException: column does not exist**
|
||||
|
||||
**涉及文件**:
|
||||
- `healthlink-his-domain/.../clinical/domain/ClinicalPathwayExecution.java` — Entity 继承 HisBaseEntity
|
||||
- `core-common/.../domain/HisBaseEntity.java` — 基类定义 createBy 等字段
|
||||
- `V30__remaining_capabilities.sql` — 原始建表(缺 3 列)
|
||||
- `V43__add_hisbase_columns_to_clinical_pathway_execution.sql` — 修复迁移(未生效)
|
||||
|
||||
---
|
||||
|
||||
### 三、修复方案
|
||||
|
||||
**方案:创建新的 Flyway 迁移脚本**,确保 `clinical_pathway_execution` 表包含 HisBaseEntity 所需的全部列。
|
||||
|
||||
**修改文件**:新建 `V2026_0612__fix_clinical_pathway_execution_hisbase_columns.sql`
|
||||
|
||||
```sql
|
||||
-- Fix Bug #748: clinical_pathway_execution 缺少 HisBaseEntity 列
|
||||
-- V43 迁移未在目标数据库执行,此处重新添加缺失列
|
||||
ALTER TABLE clinical_pathway_execution ADD COLUMN IF NOT EXISTS create_by VARCHAR(64) DEFAULT '';
|
||||
ALTER TABLE clinical_pathway_execution ADD COLUMN IF NOT EXISTS update_by VARCHAR(64) DEFAULT '';
|
||||
ALTER TABLE clinical_pathway_execution ADD COLUMN IF NOT EXISTS update_time TIMESTAMP;
|
||||
```
|
||||
|
||||
**要点**:
|
||||
- 只添加 V30 缺失的 3 列(`create_by`、`update_by`、`update_time`),不碰已有列
|
||||
- 使用 `ADD COLUMN IF NOT EXISTS` 保证幂等性
|
||||
- `create_time`、`tenant_id`、`delete_flag` 已在 V30 中存在,不需要重复添加
|
||||
- 新版本号 `V2026_0612` 高于所有现有迁移,确保被执行
|
||||
|
||||
**无需修改 Java 代码**——Entity 和 Mapper 都是正确的,问题纯粹是数据库迁移未执行。
|
||||
|
||||
---
|
||||
|
||||
### 四、路由决策
|
||||
|
||||
**FIXER: xunyu(荀彧 / DBA)**
|
||||
|
||||
**REASON**: 本 Bug 是纯粹的数据库迁移缺失问题——V43 迁移未在目标环境执行,需要 DBA 确认新迁移脚本的创建和验证。不涉及 Java 代码或前端修改,属于数据库结构对齐范畴。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: xunyu
|
||||
- **修复 Agent**: xunyu(数据库)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
137
MD/bugs/BUG_749_ANALYSIS.md
Normal file
137
MD/bugs/BUG_749_ANALYSIS.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# Bug #749 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-12 22:44:54
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 749
|
||||
- **标题**: 【门诊医生工作站】门诊医生工作站无法对患者进行保存医嘱的
|
||||
- **模块**: 门诊医生工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
Now I have enough understanding of the code flow. Let me compile my analysis.
|
||||
|
||||
---
|
||||
|
||||
## 一、Bug 理解
|
||||
|
||||
**原文引用 — 禅道 Bug #749:**
|
||||
|
||||
> **标题**:【门诊医生工作站】门诊医生工作站无法对患者进行保存医嘱的
|
||||
>
|
||||
> **重现步骤**:登录内科医生1的账号:doctor1 密码:123456 进入门诊医生工作站 → 保存一个诊断 → 进入医嘱 → 新增一条医嘱 → [结果] 点击了保存,无法保存成功,点击保存按钮无法响应
|
||||
>
|
||||
> **期望结果**:能够将医嘱保存成功,状态有待保存,变成待签发的状态
|
||||
|
||||
**附图关键信息:**
|
||||
- 医嘱Tab页已打开,列表中有 3 条已保存医嘱(已签发×2、已收费×1)
|
||||
- 顶部有一条**"待保存"状态的新行**:医嘱类型显示"选择..."(未选择)、项目未输入、药房/科室"请选择药房"(未选择)
|
||||
- **保存按钮**(蓝色)可见,但用户反映点击后无法响应
|
||||
|
||||
**综合总结**:用户在门诊医生工作站的医嘱Tab页新增了一条医嘱行,尝试点击"保存"按钮将医嘱从"待保存"变为"待签发",但按钮点击后没有任何响应,保存未生效。根据截图中"待保存"行关键字段(医嘱类型、项目、药房)均为空的状态,判断该行的**展开编辑区域(expand row)仍然处于打开状态**,导致 `handleSaveBatch()` 中的前置校验拦截了保存操作。
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
**核心问题:** `handleSaveBatch()` 函数在 line 3738-3741 检查了展开行状态:
|
||||
|
||||
```javascript
|
||||
// line 3738-3741 prescriptionlist.vue
|
||||
const prescriptionExpandOrder = prescription.expandOrder || [];
|
||||
if (prescriptionExpandOrder.length > 0) {
|
||||
proxy.$modal.msgWarning('请先点击确定确认当前医嘱');
|
||||
return; // ← 保存被拦截
|
||||
}
|
||||
```
|
||||
|
||||
**关键发现:** 这里的检查目标是 `prescription.expandOrder`(处方对象的属性),**不是**组件的 `expandOrder.value`(控制实际展开行的响应式变量)。`prescription.expandOrder` 在 `createNewPrescription()` 中被初始化为 `[]`,此后**从未被修改**,所以此检查永远为 false — 这是一段**无效的死代码**。
|
||||
|
||||
**真正的拦截点**在更上游的几个校验。结合截图分析,用户点击"保存"时:
|
||||
|
||||
1. **展开编辑行仍然打开**:用户新增医嘱行后(`handleAddPrescription`),如果选了项目但没点展开行中的"确定"按钮确认,行仍处于 `isEdit: true` 状态
|
||||
2. **`handleSaveBatch` 中 `saveList` 构建问题**:`saveList` 过滤条件中检查 `item.prescriptionId === targetPrescriptionId`,但从 `getListInfo` 加载的历史医嘱**没有 `prescriptionId` 字段**(因为 `prescriptionId` 是前端本地生成的处方ID),导致只有通过 `handleAddPrescription` 新增的行才有正确的 `prescriptionId` 匹配
|
||||
3. **`handleSaveSign` 对新医嘱不调 API**:当用户点击展开行中的"确定"按钮时,`handleSaveSign` 对没有 `requestId` 的新医嘱只做前端状态更新(`isEdit = false`),**不调用后端保存接口**,真正的保存依赖后续点击"保存"按钮
|
||||
|
||||
**最可能的失败场景:**
|
||||
|
||||
- 用户新增行 → 未完全填写展开行 → 直接点击"保存" → 前置校验(如 `expandOrder.value.length > 0`、或 `accountId` 校验)拦截 → 弹出警告但用户可能忽略
|
||||
- 或者用户填写了展开行但未点击"确定"就点击"保存" → 保存被 `expandOrder` 拦截
|
||||
|
||||
**涉及文件:**
|
||||
- `healthlink-his-ui/src/views/doctorstation/components/prescription/prescriptionlist.vue` — `handleSaveBatch()` (line 3693)、`handleSaveSign()` (line 3500)、`handleAddPrescription()` (line 2370)
|
||||
- `healthlink-his-ui/src/views/doctorstation/components/api.js` — `savePrescription()` (line 295)
|
||||
- `healthlink-his-server/.../DoctorStationAdviceController.java` — `saveAdvice()` (line 560)
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
### 方案 A:UX 修复 — 让保存按钮对"未确认"的行也能正常保存
|
||||
|
||||
**核心思路**:用户点击"保存"时,自动完成未确认行的关闭操作,而不是拦截并弹出警告。
|
||||
|
||||
**修改文件:** `prescriptionlist.vue`
|
||||
|
||||
**修改 1:** 在 `handleSaveBatch()` 中,移除无效的 `prescription.expandOrder` 检查(line 3738-3741),改为检查组件级 `expandOrder.value`,并在有展开行时**自动关闭**而非拦截:
|
||||
|
||||
```javascript
|
||||
// 替换 line 3738-3741
|
||||
// 删除旧的无效检查:
|
||||
// const prescriptionExpandOrder = prescription.expandOrder || [];
|
||||
// if (prescriptionExpandOrder.length > 0) { ... }
|
||||
|
||||
// 改为:如果有展开行,自动关闭展开行
|
||||
if (expandOrder.value.length > 0) {
|
||||
updateExpandOrder([]);
|
||||
}
|
||||
```
|
||||
|
||||
**修改 2:** 在 `handleSaveBatch()` 的 `saveList` 过滤中,移除 `prescriptionId` 匹配条件(因为历史医嘱没有此字段),改为对所有 `statusEnum == 1 && !isSaved` 的行都能保存:
|
||||
|
||||
```javascript
|
||||
// 修改 saveList 过滤条件(约 line 3823)
|
||||
.filter((item) => {
|
||||
return item.statusEnum == 1 && !item.isSaved;
|
||||
// 删除:&& (item.prescriptionId === targetPrescriptionId || !item.prescriptionId)
|
||||
})
|
||||
```
|
||||
|
||||
**修改 3:** 给"保存"按钮增加明确的校验提示(当存在未填写完整的新行时):
|
||||
|
||||
```javascript
|
||||
// 在 saveList 过滤后,检查是否有未填完关键字段的行
|
||||
const incompleteItems = saveList.filter(item =>
|
||||
!item.adviceType || !item.adviceName || !item.encounterId
|
||||
);
|
||||
if (incompleteItems.length > 0 && saveList.length === incompleteItems.length) {
|
||||
proxy.$modal.msgWarning('请先选择医嘱类型和项目,填写完整后再保存');
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
### 方案 B(如果方案 A 改动太大):仅确保按钮可见反馈
|
||||
|
||||
在 `handleSaveBatch` 的每个 `return` 前,确保有明确的 `proxy.$modal.msgWarning()` 提示,让用户知道为什么保存失败。
|
||||
|
||||
---
|
||||
|
||||
## 四、路由决策
|
||||
|
||||
**FIXER: zhaoyun(赵云)**
|
||||
|
||||
**REASON:** 该 Bug 主要涉及前端 `prescriptionlist.vue` 的 UX 和数据流问题(保存按钮点击无响应、展开行状态管理、保存过滤条件),属于前端交互和界面逻辑修复范畴,由前端开发 Agent 赵云负责。无需数据库迁移或后端接口修改。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: zhaoyun
|
||||
- **修复 Agent**: zhaoyun(前端)
|
||||
- **原因**: ** 该 Bug 主要涉及前端 `prescriptionlist.vue` 的 UX 和数据流问题(保存按钮点击无响应、展开行状态管理、保存过滤条件),属于前端交互和界面逻辑修复范畴,由前端开发 Agent 赵云负责。无需数据库迁移或后端接口修改。
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
129
MD/bugs/BUG_750_ANALYSIS.md
Normal file
129
MD/bugs/BUG_750_ANALYSIS.md
Normal file
@@ -0,0 +1,129 @@
|
||||
# Bug #750 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-12 22:27:51
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 750
|
||||
- **标题**: 【收费工作站-住院登记】修改患者登记信息(如费用性质)并保存后,系统未更新原记录而是新增了一条重复记录
|
||||
- **模块**: 住院登记管理
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
Now I have enough information to provide the analysis. Let me compile the full diagnosis.
|
||||
|
||||
---
|
||||
|
||||
## 一、Bug 理解
|
||||
|
||||
**禅道 Bug 标题**:【收费工作站-住院登记】修改患者登记信息(如费用性质)并保存后,系统未更新原记录而是新增了一条重复记录
|
||||
|
||||
**重现步骤**:
|
||||
1. 登录系统,进入 [收费工作站] → [住院登记]
|
||||
2. 切换到 [已登记入院] 页签,找到一条已存在的登记记录(如:序号9,测试患者戊,费用性质为"全自费")
|
||||
3. 点击操作列下的 [修改] 按钮,打开"修改登记"弹窗
|
||||
4. 将"费用性质"从"全自费"修改为"职工基本医疗保险"
|
||||
5. 点击 [保存],系统提示"住院登记操作成功"
|
||||
|
||||
**期望结果**:修改保存后,系统只保留一行该患者的记录,且费用性质成功更新。
|
||||
|
||||
**附图关键信息**:
|
||||
- 弹窗中"费用性质"被红框标注为"职工基本医疗保险"(修改后值),"保存"按钮被红框圈出
|
||||
- 列表中序号8(旧数据"全自费")和序号9(新数据"职工基本医疗保险")同时存在,红字标注"生成了两条重复的数据"
|
||||
- 两条记录的登记时间完全相同(`2026-06-07 21:42:13`),说明不是两次独立操作
|
||||
|
||||
**综合总结**:用户在"已登记入院"列表点击修改并保存后,系统本应在原记录上更新费用性质,但实际行为是保留了原记录并新增了一条相同记录,导致同一患者出现两条住院登记。保存操作被错误地执行为"新增"而非"更新"。
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
**核心问题**:`InHospitalRegisterAppServiceImpl.updateRegistration()` 方法中,使用 `iEncounterService.saveOrUpdate(encounter)` 保存修改后的 encounter 时,MyBatis-Plus 将其执行为 **INSERT** 而非 **UPDATE**,导致生成新记录。
|
||||
|
||||
**技术根因链路**:
|
||||
|
||||
1. **配置冲突**:`HisBaseEntity.deleteFlag` 字段标注了 `@TableLogic(value = "0", delval = "1")`,但全局配置 `application.yml` 中设置 `logic-delete-value: 0`(应为1)和 `logic-not-delete-value: 1`(应为0),二者矛盾。虽然注解优先于全局配置,但这种不一致可能导致 `saveOrUpdate` 内部的存在性检查逻辑产生非预期行为。
|
||||
|
||||
2. **`saveOrUpdate` 的二义性**:该方法依赖 entity 的 `id` 是否为 null 来判断 INSERT/UPDATE。虽然 `getById` 理论上返回了正确的 entity(含 id),但 `saveOrUpdate` 在多租户拦截器(`TenantLineInnerInterceptor`)+ 逻辑删除注解(`@TableLogic`)的叠加作用下,其内部的 `selectById` 查询可能返回 null(例如 `tenant_id` 过滤条件不匹配),从而触发 INSERT 分支。
|
||||
|
||||
3. **`@TableLogic` 与全局配置冲突**(`application.yml`):
|
||||
```yaml
|
||||
mybatis-plus:
|
||||
global-config:
|
||||
db-config:
|
||||
logic-delete-field: validFlag # 全局指定 validFlag(但实体用的是 deleteFlag)
|
||||
logic-delete-value: 0 # 0=已删除(注解是 0=未删除)
|
||||
logic-not-delete-value: 1 # 1=未删除(注解是 1=已删除)
|
||||
```
|
||||
|
||||
**涉及文件**:
|
||||
|
||||
| 文件 | 角色 |
|
||||
|------|------|
|
||||
| `InHospitalRegisterAppServiceImpl.java:377-475` | `updateRegistration()` 方法 — 问题入口 |
|
||||
| `HisBaseEntity.java` | `@TableLogic(value="0", delval="1")` 注解 — 配置冲突 |
|
||||
| `MybatisPlusConfig.java` | 多租户 + 乐观锁 + 逻辑删除拦截器链 |
|
||||
| `application.yml:93-100` | MyBatis-Plus 全局配置 — 与注解矛盾 |
|
||||
| `accomplishList.vue:286-302` / `patientRegister.vue:455-475` | 前端调用链 |
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
### 方案:将 `saveOrUpdate` 改为显式 `updateById`
|
||||
|
||||
最安全、最精确的修复是:在 `updateRegistration` 中已通过 `getById` 确认记录存在并获取了完整 entity(含 id),因此无需使用具有二义性的 `saveOrUpdate`,直接使用 `updateById` 确保执行 UPDATE。
|
||||
|
||||
**修改文件**:`InHospitalRegisterAppServiceImpl.java`
|
||||
|
||||
```java
|
||||
// 第406行附近,修改前:
|
||||
iEncounterService.saveOrUpdate(encounter);
|
||||
|
||||
// 修改为:
|
||||
iEncounterService.updateById(encounter);
|
||||
```
|
||||
|
||||
同样,病区信息和账户信息的 `saveOrUpdate` 也应替换为显式更新:
|
||||
|
||||
**病区更新**(约第419行):
|
||||
```java
|
||||
// 修改前:
|
||||
iEncounterLocationService.saveOrUpdate(encounterLocationReg);
|
||||
|
||||
// 修改为:
|
||||
iEncounterLocationService.updateById(encounterLocationReg);
|
||||
```
|
||||
|
||||
**账户更新**(约第429-470行中所有 `saveOrUpdate` 调用):
|
||||
```java
|
||||
// 修改前:
|
||||
iAccountService.saveOrUpdate(cashAccount);
|
||||
// 修改为:
|
||||
iAccountService.updateById(cashAccount);
|
||||
|
||||
// 同理修改所有 iAccountService.saveOrUpdate(...) 调用
|
||||
```
|
||||
|
||||
> **注意**:账户的"else"分支(账户不存在时创建新账户)保持使用 `iAccountService.save(newAccount)` 不变。
|
||||
|
||||
---
|
||||
|
||||
## 四、路由决策
|
||||
|
||||
**FIXER**: guanyu
|
||||
|
||||
**REASON**: 根因在后端 `InHospitalRegisterAppServiceImpl.updateRegistration()` 的 MyBatis-Plus `saveOrUpdate` 调用需改为 `updateById`,纯后端 Java 修复,属于 guanyu(后端开发)的职责范围。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
26
MD/bugs/BUG_752_ANALYSIS.md
Normal file
26
MD/bugs/BUG_752_ANALYSIS.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Bug #752 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-12 22:09:00
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 752
|
||||
- **标题**: 【门诊医生站-检查项目】保存检查申请单时报JSON解析错误
|
||||
- **模块**: 门诊医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
分析完成。根因明确、修复方案清晰,建议直接分派给赵云执行修复。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
174
MD/bugs/BUG_753_ANALYSIS.md
Normal file
174
MD/bugs/BUG_753_ANALYSIS.md
Normal file
@@ -0,0 +1,174 @@
|
||||
# Bug #753 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-12 22:03:57
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 753
|
||||
- **标题**: 【收费工作站-住院登记】“待登记入院”与“已登记入院”页签下页面容器高度异常,系统自动无限下扩产生大量空白区
|
||||
- **模块**: 住院登记管理
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## 一、Bug 理解
|
||||
|
||||
**原文引用:**
|
||||
|
||||
> **标题**:【收费工作站-住院登记】"待登记入院"与"已登记入院"页签下页面容器高度异常,系统自动无限下扩产生大量空白区
|
||||
>
|
||||
> **重现步骤**:
|
||||
> 1. 登录医院信息管理系统账号。
|
||||
> 2. 在左侧主菜单栏中依次点击:「收费工作站」->「住院登记」。
|
||||
> 3. 在右侧主工作区中,首先查看默认的「待登记入院」页签,往下滑动页面或观察底部数据区域。
|
||||
> 4. 接着点击切换至「已登记入院」页签,同样向下滑动并观察底部。
|
||||
>
|
||||
> **结果**:表格与尾底部分页控件(写有"共 59 条 10条/页..."的控制条)之间存在异常巨大的空白间隔。页面右侧纵向滚动条极长,系统自动无限往下拉高窗口,给用户视觉呈瞬间呈现"断层/留白过长"现象。(注:在"待登记入院"和"已登记入院"两个子标签下均存在该问题。)
|
||||
>
|
||||
> **期望**:页面各组件高度计算正确,自适应浏览器窗口大小。分页控件行应紧跟紧随在表格区域底部显示,或者将表格区固定在一定高度内(超出出现局部滚动条),不能出现无限制的页面底部空白区和全局滚动条。
|
||||
|
||||
**附图分析**:
|
||||
- 已登记入院页签:10行数据的表格下方出现大面积空白区域,分页控件被推到页面最底部,右侧纵向滚动条极长。
|
||||
- 待登记入院页签:表格显示"暂无数据",但页面同样存在高度异常。
|
||||
- 两个标签页下均有"系统自动无限往下扩高窗口"的标注。
|
||||
|
||||
**综合总结**:用户在住院登记页面的两个页签(待登记/已登记)中,表格下方出现大面积异常空白,分页控件与表格严重脱节,页面滚动条极长。这是一个纯前端布局问题,由 CSS 高度约束缺失导致 vxe-table 在无约束父容器中无限撑开高度。
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
**直接原因**:两个组件(`accomplishList.vue` 和 `awaitList.vue`)的 `.table-container` 缺少高度约束和溢出控制。
|
||||
|
||||
**详细技术分析**:
|
||||
|
||||
布局链条高度约束断裂:
|
||||
|
||||
```
|
||||
.app-container (min-height: calc(100vh - 84px), 无固定height, 无overflow)
|
||||
└─ el-tabs (auto height)
|
||||
└─ .awaitList-container (height: 100%, 但父元素无固定高度 → 实际等于 auto)
|
||||
├─ .operate (height: 40px, 固定)
|
||||
└─ .table-container (无高度约束, 仅 padding)
|
||||
├─ vxe-table (height="100%", 父容器auto → 无法正确约束)
|
||||
└─ pagination
|
||||
```
|
||||
|
||||
关键问题:
|
||||
1. **`.awaitList-container` 使用 `height: 100%`,但其父元素(el-tabs content)无固定高度**——导致 `100%` 实际解析为 auto,无法约束子元素。
|
||||
2. **`.table-container` 无 `overflow` 约束、无 flex 布局**——内容可以无限撑高。
|
||||
3. **`vxe-table` 的 `height="100%"` 属性**——在无固定高度的父容器中无法创建滚动区域,表格内容直接撑开容器。
|
||||
|
||||
**涉及文件**(均为纯前端 CSS 问题):
|
||||
- `healthlink-his-ui/src/views/inHospitalManagement/charge/register/components/accomplishList.vue` — 已登记入院列表
|
||||
- `healthlink-his-ui/src/views/inHospitalManagement/charge/register/components/awaitList.vue` — 待登记入院列表
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
**核心思路**:用 flexbox 将 `.awaitList-container` 改为纵向弹性布局,让 `.table-container` 自动填充剩余空间并限制溢出,使 vxe-table 的 `height="100%"` 能正确约束在固定高度内。
|
||||
|
||||
### 修改文件 1:`accomplishList.vue`
|
||||
|
||||
```scss
|
||||
<!-- 修改前 -->
|
||||
<style lang="scss" scoped>
|
||||
.awaitList-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.operate {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 40px;
|
||||
padding: 0 16px;
|
||||
align-items: center;
|
||||
}
|
||||
.table-container {
|
||||
padding: 8px 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- 修改后 -->
|
||||
<style lang="scss" scoped>
|
||||
.awaitList-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.operate {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 40px;
|
||||
padding: 0 16px;
|
||||
align-items: center;
|
||||
}
|
||||
.table-container {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
padding: 8px 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
### 修改文件 2:`awaitList.vue`
|
||||
|
||||
同样的 CSS 修改(两个文件的 style 完全一致):
|
||||
|
||||
```scss
|
||||
<!-- 修改后 -->
|
||||
<style lang="scss" scoped>
|
||||
.awaitList-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.operate {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 40px;
|
||||
padding: 0 16px;
|
||||
align-items: center;
|
||||
}
|
||||
.table-container {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
padding: 8px 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
**修改要点**(3处 CSS 变更,两文件相同):
|
||||
1. `.awaitList-container` 加 `display: flex; flex-direction: column;` — 建立纵向弹性布局
|
||||
2. `.operate` 加 `flex-shrink: 0;` — 防止搜索栏被压缩
|
||||
3. `.table-container` 加 `flex: 1; min-height: 0; overflow: hidden;` — **关键修复**:自动填充剩余空间 + 禁止溢出撑高 + `min-height: 0` 确保 flex 子元素可缩小
|
||||
|
||||
这样 vxe-table 的 `height="100%"` 就能在固定的 `.table-container` 内正确创建滚动区域,表格内容超出时在表格内部滚动,分页控件紧随表格下方,不再撑开整个页面。
|
||||
|
||||
---
|
||||
|
||||
## 四、路由决策
|
||||
|
||||
**FIXER**: zhaoyun
|
||||
**REASON**: 这是纯前端 CSS 布局问题,只涉及两个 Vue 组件的 `<style>` 块修改,无后端变更、无数据库变更,由前端开发修复最合适。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: guanyu
|
||||
- **修复 Agent**: guanyu(后端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
164
MD/bugs/BUG_757_ANALYSIS.md
Normal file
164
MD/bugs/BUG_757_ANALYSIS.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# Bug #757 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-12 14:58:17
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 757
|
||||
- **标题**: 【门诊医生工作站】中医诊断中没有相同的诊断和症候,但就无法新增中医诊断
|
||||
- **模块**: 门诊医生工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
I have enough information now to produce the analysis. Let me compile the findings.
|
||||
|
||||
---
|
||||
|
||||
## 一、Bug 理解
|
||||
|
||||
用户在门诊医生站打开"中医诊断"对话框,选择中医诊断和中医证候后点击确定,**无法成功保存**。同时,已经保存过的中医诊断也无法正确回显诊断详情。期望:能正常选择诊断和证候、保存成功,并回显诊断详情数据。
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
核心问题在 `tcmdiagnosisDialog.vue` 的 `submit()` 函数,它向后端发送的字段名与后端 DTO 完全不匹配:
|
||||
|
||||
**前端发送的数据结构:**
|
||||
```js
|
||||
const diagnosisChildList = [{
|
||||
conditionCode: condition.value, // ← 字段名错误
|
||||
syndromeCode: syndrome.value, // ← 字段名错误
|
||||
}];
|
||||
```
|
||||
|
||||
**后端 `SaveDiagnosisChildParam` 期望的数据结构:**
|
||||
- `definitionId` (Long) — 诊断定义 ID
|
||||
- `ybNo` (String) — 医保编码
|
||||
- `syndromeGroupNo` (String) — 中医证候组号(用于关联病和证)
|
||||
- `maindiseFlag` (Integer) — 主诊断标记
|
||||
- `diagSrtNo` (Integer) — 排序号
|
||||
|
||||
**具体根因列表:**
|
||||
|
||||
| # | 问题 | 位置 | 影响 |
|
||||
|---|------|------|------|
|
||||
| 1 | `submit()` 发送 `conditionCode`/`syndromeCode`,后端接收不到 `definitionId` 和 `ybNo` | `tcmdiagnosisDialog.vue:submit()` | 保存时 Condition 记录的 `definitionId` 为 null,保存失败或数据损坏 |
|
||||
| 2 | 没有传 `syndromeGroupNo` 来关联"病"和"证" | `tcmdiagnosisDialog.vue:submit()` | 后端无法将诊断和证候配对成一组 |
|
||||
| 3 | `openDialog()` 获取下拉选项时用 `item.ybNo` 作为 value,但没有保存 `definitionId` | `tcmdiagnosisDialog.vue:openDialog()` | 丢失了关键的 `definitionId` |
|
||||
| 4 | 没有传 `patientInfo` prop(dialog 用 `defineProps` 声明了但父组件可能未传) | `tcmdiagnosisDialog.vue` | `saveTcmDiagnosis` 请求中 `patientId`/`encounterId` 为 null |
|
||||
|
||||
**可能涉及的文件:**
|
||||
- `healthlink-his-ui/src/views/doctorstation/components/tcm/tcmdiagnosisDialog.vue` — 主要 Bug 所在
|
||||
- `healthlink-his-ui/src/views/doctorstation/components/api.js` — API 定义(无误)
|
||||
- `healthlink-his-server/.../appservice/impl/DoctorStationChineseMedicalAppServiceImpl.java` — 后端 `saveTcmDiagnosis` 方法
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
### 修复 1:`tcmdiagnosisDialog.vue` — `openDialog()` 方法
|
||||
|
||||
将下拉选项的 value 从 `ybNo` 改为同时保存 `definitionId`:
|
||||
|
||||
```js
|
||||
// 修改前
|
||||
conditionOptions.value = res.data.records.map((item) => ({
|
||||
value: item.ybNo,
|
||||
label: item.name,
|
||||
}));
|
||||
|
||||
// 修改后
|
||||
conditionOptions.value = res.data.records.map((item) => ({
|
||||
value: item.id, // 用 definition ID 作为 value
|
||||
ybNo: item.ybNo, // 保留医保编码
|
||||
label: item.name,
|
||||
}));
|
||||
syndromeOptions.value = res.data.records.map((item) => ({
|
||||
value: item.id,
|
||||
ybNo: item.ybNo,
|
||||
label: item.name,
|
||||
}));
|
||||
```
|
||||
|
||||
### 修复 2:`tcmdiagnosisDialog.vue` — `submit()` 方法
|
||||
|
||||
重写提交逻辑,匹配后端 `SaveDiagnosisChildParam` 的字段名:
|
||||
|
||||
```js
|
||||
function submit() {
|
||||
if (!condition.value || !syndrome.value) {
|
||||
proxy.$modal.msgWarning('请选择诊断和证候');
|
||||
return;
|
||||
}
|
||||
|
||||
// 找到选中的诊断和证候的完整信息
|
||||
const selectedCondition = conditionOptions.value.find(item => item.value === condition.value);
|
||||
const selectedSyndrome = syndromeOptions.value.find(item => item.value === syndrome.value);
|
||||
|
||||
// 生成证候组号(时间戳)
|
||||
const syndromeGroupNo = 'TCM' + Date.now();
|
||||
|
||||
const diagnosisChildList = [
|
||||
{
|
||||
definitionId: condition.value, // 中医诊断 definition ID
|
||||
ybNo: selectedCondition?.ybNo, // 中医诊断医保编码
|
||||
syndromeGroupNo: syndromeGroupNo,
|
||||
maindiseFlag: 1, // 主诊断标记
|
||||
diagSrtNo: 1, // 排序号(病)
|
||||
},
|
||||
{
|
||||
definitionId: syndrome.value, // 中医证候 definition ID
|
||||
ybNo: selectedSyndrome?.ybNo, // 中医证候医保编码
|
||||
syndromeGroupNo: syndromeGroupNo, // 同一组号
|
||||
maindiseFlag: 0,
|
||||
diagSrtNo: 2, // 排序号(证)
|
||||
},
|
||||
];
|
||||
|
||||
saveTcmDiagnosis({
|
||||
patientId: props.patientInfo.patientId,
|
||||
encounterId: props.patientInfo.encounterId,
|
||||
diagnosisChildList: diagnosisChildList,
|
||||
}).then((res) => {
|
||||
if (res.code === 200) {
|
||||
proxy.$modal.msgSuccess('保存成功');
|
||||
emit('flush');
|
||||
close();
|
||||
} else {
|
||||
proxy.$modal.msgError(res.msg || '保存失败');
|
||||
}
|
||||
}).catch((error) => {
|
||||
console.error('保存中医诊断失败:', error);
|
||||
proxy.$modal.msgError('保存失败,请重试');
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### 修复 3:确保父组件传递 `patientInfo` prop
|
||||
|
||||
检查父组件(`tcmAdvice.vue` 或使用 `tcmdiagnosisDialog` 的页面)是否正确传递了 `patientInfo` prop。`tcmAdvice.vue` 已有 `patientInfo` prop 定义,所以如果是从 `tcmAdvice` 中使用该 dialog,需要通过 `:patientInfo="patientInfo"` 传递。
|
||||
|
||||
### 修复 4(可选):后端防御性处理
|
||||
|
||||
后端 `saveTcmDiagnosis` 方法可以增加对 `definitionId` 为空的校验,避免写入脏数据:
|
||||
|
||||
```java
|
||||
// 在 saveTcmDiagnosis 方法开头增加
|
||||
for (SaveDiagnosisChildParam param : diagnosisChildList) {
|
||||
if (param.getDefinitionId() == null) {
|
||||
return R.fail("诊断定义ID不能为空,请重新选择诊断");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 四、路由决策
|
||||
|
||||
**FIXER: zhaoyun**(前端开发)
|
||||
**REASON:** Bug 根因在前端对话框组件 `tcmdiagnosisDialog.vue` 的字段映射错误和提交逻辑缺陷,需要修改 Vue 前端代码(openDialog 数据映射 + submit 参数构建 + 父组件 prop 传递),属于前端界面和 API 调用层修复。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **修复 Agent**: zhaoyun
|
||||
- **原因**: ** Bug 根因在前端对话框组件 `tcmdiagnosisDialog.vue` 的字段映射错误和提交逻辑缺陷,需要修改 Vue 前端代码(openDialog 数据映射 + submit 参数构建 + 父组件 prop 传递),属于前端界面和 API 调用层修复。
|
||||
122
MD/bugs/BUG_758_ANALYSIS.md
Normal file
122
MD/bugs/BUG_758_ANALYSIS.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# Bug #758 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-12 15:34:50
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 758
|
||||
- **标题**: 【门诊医生工作站-检验】检验信息下的新增的字段按钮点击会出现报错Cannot deserialize value of type `com.core.common.core.domain.entity.SysDictData` from Array value
|
||||
- **模块**: 门诊医生工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
I now have a complete understanding of the root cause. Let me provide the analysis.
|
||||
|
||||
---
|
||||
|
||||
### 一、Bug 理解
|
||||
|
||||
用户在门诊医生工作站的"检验信息"区域点击"新增"按钮时,页面弹出 Jackson 反序列化错误 `Cannot deserialize value of type SysDictData from Array value`,无法正常新增检验信息。期望点击新增后能正常清空表单、准备录入新检验申请单。
|
||||
|
||||
### 二、根因分析
|
||||
|
||||
**错误触发链路:**
|
||||
|
||||
```
|
||||
用户点击"新增"
|
||||
→ handleNewApplication()
|
||||
→ resetForm()
|
||||
→ getEncounterDiagnosis(encounterId) [API 调用]
|
||||
→ 后端返回 R<List<DiagnosisQueryDto>>
|
||||
→ DictAspect 拦截 @GetMapping 响应
|
||||
→ processDict() 发现 DiagnosisQueryDto.medTypeCode 有 @Dict(dictCode = "med_type")
|
||||
→ DictUtils.getDictLabel("med_type", value)
|
||||
→ DictUtils.getDictCache("med_type")
|
||||
→ mapper.convertValue(cached, TypeReference<List<SysDictData>>) ← 💥 这里抛异常
|
||||
→ DictAspect 无 try-catch,异常直接传播到前端
|
||||
```
|
||||
|
||||
**根因:`DictUtils.getDictCache()` 缺少异常处理**
|
||||
|
||||
- 文件:`core-common/src/main/java/com/core/common/utils/DictUtils.java:38-62`
|
||||
- Redis 中的字典缓存数据结构异常(可能是旧 Fastjson 序列化格式遗留、嵌套数组等)
|
||||
- Jackson `ObjectMapper.convertValue()` 无法将异常结构转为 `List<SysDictData>`,抛出 `JsonMappingException`
|
||||
- 该异常未被 `DictUtils` 或 `DictAspect` 捕获,直接传播为 HTTP 500 错误
|
||||
|
||||
**涉及的关键文件:**
|
||||
1. `core-common/src/main/java/com/core/common/utils/DictUtils.java` — `getDictCache()` 方法(核心问题)
|
||||
2. `healthlink-his-common/src/main/java/com/healthlink/his/common/aspectj/DictAspect.java` — `processDict()` 方法(缺少异常保护)
|
||||
3. `healthlink-his-application/src/main/java/com/healthlink/his/web/doctorstation/controller/DoctorStationDiagnosisController.java` — 被 DictAspect 拦截的控制器
|
||||
4. `healthlink-his-application/src/main/java/com/healthlink/his/web/doctorstation/dto/DiagnosisQueryDto.java` — 含 `@Dict` 注解的 DTO
|
||||
|
||||
**与历史 Bug 的关联:** 此前 commit `babd8d0c0` 修复了类似问题(Jackson 配置从 ObjectMapper bean 改回 Jackson2ObjectMapperBuilderCustomizer),但 `DictUtils.getDictCache()` 的 `convertValue` 仍缺少防御性异常处理。
|
||||
|
||||
### 三、修复方案
|
||||
|
||||
**修改 1:`DictUtils.getDictCache()` 添加 try-catch 防御**(核心修复)
|
||||
|
||||
文件:`core-common/src/main/java/com/core/common/utils/DictUtils.java`
|
||||
|
||||
在 `getDictCache()` 方法中,为 `mapper.convertValue()` 添加 try-catch,失败时清理损坏缓存并返回 null:
|
||||
|
||||
```java
|
||||
public static List<SysDictData> getDictCache(String key) {
|
||||
Object cached = SpringUtils.getBean(RedisCache.class).getCacheObject(getCacheKey(key));
|
||||
if (StringUtils.isNull(cached)) {
|
||||
return null;
|
||||
}
|
||||
if (cached instanceof List && ((List<?>) cached).stream().allMatch(e -> e instanceof SysDictData)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<SysDictData> result = (List<SysDictData>) cached;
|
||||
return result;
|
||||
}
|
||||
try {
|
||||
com.fasterxml.jackson.core.type.TypeReference<List<SysDictData>> typeRef =
|
||||
new com.fasterxml.jackson.core.type.TypeReference<List<SysDictData>>() {};
|
||||
ObjectMapper mapper = new ObjectMapper()
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
if (cached instanceof JsonNode jsonNode) {
|
||||
return mapper.convertValue(jsonNode, typeRef);
|
||||
}
|
||||
return mapper.convertValue(cached, typeRef);
|
||||
} catch (Exception e) {
|
||||
// 缓存数据格式异常,清理损坏缓存,下次重新加载
|
||||
org.slf4j.LoggerFactory.getLogger(DictUtils.class)
|
||||
.warn("字典缓存转换失败(key={}),已清理: {}", key, e.getMessage());
|
||||
removeDictCache(key);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**修改 2:`DictAspect.processDict()` 添加 try-catch 防御**(防止字典翻译失败影响 API 响应)
|
||||
|
||||
文件:`healthlink-his-common/src/main/java/com/healthlink/his/common/aspectj/DictAspect.java`
|
||||
|
||||
在 `processDict()` 方法中,对字典查询部分包裹 try-catch:
|
||||
|
||||
```java
|
||||
} else if (field.isAnnotationPresent(Dict.class)) {
|
||||
try {
|
||||
// ... 原有字典翻译逻辑 ...
|
||||
} catch (Exception e) {
|
||||
log.debug("字段 {} 字典翻译失败,跳过: {}", field.getName(), e.getMessage());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 四、路由决策
|
||||
|
||||
**FIXER: guanyu(后端开发)**
|
||||
|
||||
**REASON:** 修复涉及 `DictUtils`(core-common 模块)和 `DictAspect`(healthlink-his-common 模块)两个后端 Java 文件的异常处理逻辑,纯后端修复,无需前端改动。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **修复 Agent**: guanyu
|
||||
- **原因**: ** 修复涉及 `DictUtils`(core-common 模块)和 `DictAspect`(healthlink-his-common 模块)两个后端 Java 文件的异常处理逻辑,纯后端修复,无需前端改动。
|
||||
104
MD/bugs/BUG_759_ANALYSIS.md
Normal file
104
MD/bugs/BUG_759_ANALYSIS.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# Bug #759 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-12 21:51:43
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 759
|
||||
- **标题**: 【门诊医生工作站】电子处方点击新增处方,报卡在100%卡出屏幕且诊断等下拉框无数据回显
|
||||
- **模块**: 门诊医生工作站
|
||||
- **提出人**: 王栩坤
|
||||
|
||||
---
|
||||
|
||||
I now have a complete understanding. Here is my analysis:
|
||||
|
||||
---
|
||||
|
||||
## 一、Bug 理解
|
||||
|
||||
**禅道 Bug #759 原文:**
|
||||
|
||||
- **标题**:【门诊医生工作站】电子处方点击新增处方,报卡在100%卡出屏幕且诊断等下拉框无数据回显
|
||||
- **重现步骤**:登录内科医生1账号(doctor1/123456)→ 进入门诊医生工作站 → 选择一名患者 → 点击处方 → 点击新增处方
|
||||
- **实际结果**:报卡界面边距超出,下拉框无数据回显
|
||||
- **期望结果**:能够在100%视图下,新增处方的报卡能够完全展示出来;诊断和慢性诊断的下拉框有数据回显
|
||||
|
||||
**附图关键信息**:
|
||||
- 截图显示"新增处方"弹窗右侧被截断,"服药时间(结束)"和"途径"列不可见,右下角"删除"按钮被裁剪
|
||||
- "诊断"下拉框显示占位文本"诊断","慢病诊断"下拉框点击后显示"无数据"
|
||||
|
||||
**综合总结**:用户在门诊医生工作站新增处方时,弹窗宽度固定为 `1840px`,在 100% 缩放下超出屏幕可视区域导致内容溢出;同时"诊断"和"慢病诊断"两个下拉框均无数据可选,无法正常使用处方开具功能。
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
**涉及唯一文件**:`healthlink-his-ui/src/views/doctorstation/components/eprescriptiondialog.vue`
|
||||
|
||||
### 问题1:弹窗宽度溢出
|
||||
|
||||
- **根因**:`el-dialog` 第5行设置 `width="1840px"` 为固定像素值。标准 1920px 屏幕减去浏览器 UI 和滚动条后可用宽度不足 1840px,导致右侧内容被截断。此外第240行药品搜索弹出框 `popover` 设置 `width="1200"`,也加剧了溢出。
|
||||
- **证据**:第5行 `width="1840px"`,第240行 `:width="1200"`
|
||||
|
||||
### 问题2:诊断下拉框无数据
|
||||
|
||||
- **根因**:"诊断"下拉框使用 `remote-method="getInit"`(第134行),这是一个远程搜索模式 —— **只有用户输入关键字时才会触发 `getInit` 函数调用 API**。弹窗打开时 `open()` 函数调用了 `getDiagnosisInfo()`,其中 `getEncounterDiagnosis()` 获取的诊断数据存入了 `diagnosisList`(第764行),但 **没有同步填充 `diagnosisListOption`**(下拉框 v-for 绑定的数据源,第138行)。因此弹窗打开时下拉框列表为空。
|
||||
- **代码证据**:`getDiagnosisInfo()` 第764行 `diagnosisList.value = res.data`,但 `diagnosisListOption` 仅在 `getInit` 的 remote 回调中被赋值(第716行)
|
||||
|
||||
### 问题3:慢病诊断下拉框无数据
|
||||
|
||||
- **根因**:`getChronicDisease` 调用医保接口 `/yb-request/getConditionDefinition`(第779行)。如果医保服务未连接或返回空数据,catch 中静默处理并设为空数组(第786行)。这可能是医保环境未配置的预期行为,但即使医保已连接,如果 `encounterId` 传参有问题也会导致返回空。
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
### 修复1:弹窗宽度改为响应式
|
||||
|
||||
**文件**:`eprescriptiondialog.vue` 第5行
|
||||
|
||||
```diff
|
||||
- width="1840px"
|
||||
+ width="90vw"
|
||||
+ style="max-width: 1840px"
|
||||
```
|
||||
|
||||
同时将第240行药品搜索 popover 宽度从 `1200` 缩减为 `min(1200px, 80vw)` 或直接改为 `"100%"`。
|
||||
|
||||
### 修复2:诊断下拉框打开时加载初始数据
|
||||
|
||||
**文件**:`eprescriptiondialog.vue` `getDiagnosisInfo()` 函数(约第763行)
|
||||
|
||||
在 `getEncounterDiagnosis` 成功回调中,增加 `diagnosisListOption` 的赋值:
|
||||
|
||||
```diff
|
||||
getEncounterDiagnosis(props.patient.encounterId).then((res) => {
|
||||
diagnosisList.value = res.data;
|
||||
+ diagnosisListOption.value = res.data || [];
|
||||
let diagnosisInfo = diagnosisList.value.filter((item) => {
|
||||
```
|
||||
|
||||
### 修复3:慢病诊断 — 确认 API 返回
|
||||
|
||||
此问题取决于医保服务是否可用。如果医保服务已连接但仍无数据,需检查后端 `/yb-request/getConditionDefinition` 接口的返回值。如果是医保未配置环境,则属于已知限制,可考虑在下拉框上增加"医保未连接"的提示文案。
|
||||
|
||||
---
|
||||
|
||||
## 四、路由决策
|
||||
|
||||
**FIXER: zhaoyun(赵云 — 前端开发)**
|
||||
|
||||
**REASON**:两个问题的根因全部在前端 `eprescriptiondialog.vue` 的样式和数据初始化逻辑中,不需要后端改动,属于纯前端修复任务。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: zhaoyun
|
||||
- **修复 Agent**: zhaoyun(前端)
|
||||
- **原因**: LLM 分析决策
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
114
MD/bugs/BUG_760_ANALYSIS.md
Normal file
114
MD/bugs/BUG_760_ANALYSIS.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# Bug #760 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-12 21:48:44
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 760
|
||||
- **标题**: [住院护士站-护理记录] 选中患者时系统报错
|
||||
- **模块**: 病区护士工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
Analysis complete. Here's the full report.
|
||||
|
||||
---
|
||||
|
||||
### 一、Bug 理解
|
||||
|
||||
**禅道 Bug #760:[住院护士站-护理记录] 选中患者时系统报错**
|
||||
|
||||
**重现步骤:**
|
||||
1. 登录账号:wx,密码:123456,登录系统,进入【住院护士站】
|
||||
2. 点击【护理记录】页签
|
||||
3. 在左侧列表中选中任意已入院的患者
|
||||
|
||||
**期望结果:**
|
||||
1. 选中患者后,系统正常响应,无报错弹窗
|
||||
2. 成功加载并展示该患者对应的护理记录表单及历史数据
|
||||
|
||||
**实际结果:**
|
||||
- 页面弹出红色报错:`No static resource nursing/statistics/summary/list for request '/healthlink-his/nursing/statistics/summary/list'`
|
||||
- 右侧护理记录列表显示"暂无数据"
|
||||
|
||||
**截图确认:** 顶部红色报错横幅清晰可见,错误 URL 为 `/healthlink-his/nursing/statistics/summary/list`,选中患者"陈显精"后右侧表格为空。
|
||||
|
||||
**总结:** 用户在住院护士站的「护理记录」页签选中患者时,前端发起了一个后端不存在的 API 请求 `/nursing/statistics/summary/list`,导致 404 报错,护理记录数据无法加载。
|
||||
|
||||
---
|
||||
|
||||
### 二、根因分析
|
||||
|
||||
**根因:Tab 组件映射错误 — "护理记录"页签加载了错误的组件。**
|
||||
|
||||
在 `healthlink-his-ui/src/views/inpatientNurse/inpatientNurseStation/index.vue` 中:
|
||||
|
||||
```html
|
||||
<!-- 第72-76行 -->
|
||||
<el-tab-pane label="护理记录" name="NursingRecord">
|
||||
<Criticalrecord v-if="activeTabName === 'NursingRecord'" />
|
||||
</el-tab-pane>
|
||||
```
|
||||
|
||||
这里渲染的是 `Criticalrecord` 组件,而不是 `NursingRecord` 组件。
|
||||
|
||||
**关键文件对比:**
|
||||
|
||||
| 文件 | API 路径 | 后端是否有对应 Controller |
|
||||
|------|----------|--------------------------|
|
||||
| `nursingstatistics/criticalrecord.vue` → `nursingstatistics/api.js` | `/nursing/statistics/summary/list` | ❌ **不存在** |
|
||||
| `nursingRecord/index.vue` → `nursingRecord/components/api.js` | `/nursing-record/nursing-patient-page` 等 | ✅ `NursingRecordController` |
|
||||
|
||||
- `inpatientNurseStation/index.js` 中已经同时导入了两个组件:
|
||||
- `NursingRecord` from `@/views/inpatientNurse/nursingRecord/index.vue`
|
||||
- `Criticalrecord` from `@/views/inpatientNurse/nursingstatistics/criticalrecord.vue`
|
||||
- 但 `index.vue` 的模板中**用错了组件名**:`<Criticalrecord>` 应该是 `<NursingRecord>`
|
||||
- 后端 `NursingRecordController` 映射在 `/nursing-record`,有完整的 patient-page、nursing-patient-page、save-nursing、delete-nursing 等端点
|
||||
|
||||
**涉及的文件:**
|
||||
- `healthlink-his-ui/src/views/inpatientNurse/inpatientNurseStation/index.vue` — 模板中 Tab 渲染了错误组件
|
||||
|
||||
---
|
||||
|
||||
### 三、修复方案
|
||||
|
||||
**修改 1 个文件,1 处改动:**
|
||||
|
||||
**文件:** `healthlink-his-ui/src/views/inpatientNurse/inpatientNurseStation/index.vue`
|
||||
|
||||
**改动:** 将第 74 行的 `<Criticalrecord>` 替换为 `<NursingRecord>`
|
||||
|
||||
```diff
|
||||
- <el-tab-pane label="护理记录" name="NursingRecord">
|
||||
- <Criticalrecord v-if="activeTabName === 'NursingRecord'" />
|
||||
+ <el-tab-pane label="护理记录" name="NursingRecord">
|
||||
+ <NursingRecord v-if="activeTabName === 'NursingRecord'" />
|
||||
</el-tab-pane>
|
||||
```
|
||||
|
||||
`NursingRecord` 已在同文件的 `index.js` 中导入(第3行),无需额外添加 import。
|
||||
|
||||
**验证:**
|
||||
1. `cd healthlink-his-ui && npm run build:dev` — 编译通过
|
||||
2. 登录后进入住院护士站 → 护理记录 → 选中患者 → 应加载出患者护理记录列表,无红色报错
|
||||
|
||||
---
|
||||
|
||||
### 四、路由决策
|
||||
|
||||
**FIXER: zhaoyun**
|
||||
|
||||
**REASON:** 纯前端组件映射修复,仅改动 1 个 Vue 文件中的 1 行模板标签(`Criticalrecord` → `NursingRecord`),属于前端界面/组件层级的问题。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **FIXER_ID**: zhaoyun
|
||||
- **修复 Agent**: zhaoyun(前端)
|
||||
- **原因**: ** 纯前端组件映射修复,仅改动 1 个 Vue 文件中的 1 行模板标签(`Criticalrecord` → `NursingRecord`),属于前端界面/组件层级的问题。
|
||||
|
||||
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。
|
||||
132
MD/bugs/BUG_761_ANALYSIS.md
Normal file
132
MD/bugs/BUG_761_ANALYSIS.md
Normal file
@@ -0,0 +1,132 @@
|
||||
# Bug #761 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-12 16:31:36
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 761
|
||||
- **标题**: [住院护士站-汇总领药]领药明细列表,“领药时间”显示逻辑异常且早于医嘱开立时间
|
||||
- **模块**: 病区护士工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
I now have a complete understanding of the bug. Let me produce the analysis.
|
||||
|
||||
---
|
||||
|
||||
### 一、Bug 理解
|
||||
|
||||
用户在"住院护士站 → 汇总领药"页面看到"领药时间"列显示了错误的日期("06-09"),早于医嘱开立时间(06-10 05:18:44)和实际执行时间(06-10 05:18)。期望:①列名改为"执行时间";②时间值应与医嘱执行界面的执行时间一致;③未发药/未汇总前不应展示"领药时间"。
|
||||
|
||||
### 二、根因分析
|
||||
|
||||
**全链路追踪:**
|
||||
|
||||
```
|
||||
前端 prescriptionList.vue → API: getPrescriptionList
|
||||
→ 后端 MedicineSummaryController.getMedicineDispenseFormPage
|
||||
→ MedicineSummaryAppServiceImpl.getMedicineDispenseFormPage
|
||||
→ MedicineSummaryAppMapper.selectMedicineDispenseFormPage (SQL)
|
||||
→ 返回 MedicineDispenseFormDto.medicineSummaryParamList
|
||||
→ 其中 dispenseTime 来自 med_medication_dispense.planned_dispense_time
|
||||
```
|
||||
|
||||
**核心问题(2处):**
|
||||
|
||||
**问题1:数据源错误 — `planned_dispense_time` ≠ 执行时间**
|
||||
|
||||
- Mapper XML 第39行:`<result property="dispenseTime" column="planned_dispense_time"/>`,将 `med_medication_dispense.planned_dispense_time` 映射为 `dispenseTime`
|
||||
- `planned_dispense_time` 是在 `AdviceProcessAppServiceImpl` 调用 `generateMedicationDispense()` 时通过 `parseExecuteTime(executeTime)` 设置的,来自前端传入的执行时间字符串
|
||||
- 实际执行时间存储在 `cli_procedure.occurrence_time`(`Procedure.java` 第54行),这才是医嘱执行界面显示的"执行时间"
|
||||
- `planned_dispense_time` 的值可能因时区转换、字符串解析精度等原因与 `occurrence_time` 不一致(差一天即 "06-09" vs "06-10")
|
||||
|
||||
**问题2:列名语义错误 — "领药时间"应为"执行时间"**
|
||||
|
||||
- `prescriptionList.vue` 第164行:`title="领药时间"`,此列展示的是每条医嘱的执行时间点,不是"领药时间"
|
||||
- 在未生成汇总领药单之前,不存在"领药"动作,显示"领药时间"不符合业务逻辑
|
||||
|
||||
**涉及文件:**
|
||||
|
||||
| 文件 | 行号 | 问题 |
|
||||
|------|------|------|
|
||||
| `prescriptionList.vue` | 164 | 列名 "领药时间" 应改为 "执行时间" |
|
||||
| `MedicineSummaryAppMapper.xml` | 39, 78, ~125, 203 | `planned_dispense_time` 应改为 `cli_procedure.occurrence_time` |
|
||||
| `MedicineSummaryParam.java` | 22 | 字段名 `dispenseTime` 可保持不变(仅改数据源) |
|
||||
|
||||
### 三、修复方案
|
||||
|
||||
#### 修改1:后端 Mapper XML — 改用执行时间
|
||||
|
||||
**文件**: `healthlink-his-server/healthlink-his-application/src/main/resources/mapper/inhospitalnursestation/MedicineSummaryAppMapper.xml`
|
||||
|
||||
**改动A**:resultMap collection 映射,将 `dispenseTime` 的数据源从 `planned_dispense_time` 改为 `occurrence_time`(来自 `cli_procedure` 表):
|
||||
|
||||
```xml
|
||||
<!-- 第36-41行,collection 改为: -->
|
||||
<collection property="medicineSummaryParamList" ofType="com.healthlink.his.web.inhospitalnursestation.dto.MedicineSummaryParam">
|
||||
<result property="procedureId" column="procedure_id"/>
|
||||
<result property="dispenseId" column="dispense_id"/>
|
||||
<result property="dispenseTime" column="execution_time"/>
|
||||
<result property="dispenseStatus" column="dispense_status"/>
|
||||
</collection>
|
||||
```
|
||||
|
||||
**改动B**:内层 SQL 增加 `cli_procedure` JOIN 并选取 `occurrence_time`:
|
||||
|
||||
在内层 SELECT(约第98行 `mmd.status_enum AS dispense_status` 之后)添加:
|
||||
```sql
|
||||
cp.occurrence_time AS execution_time,
|
||||
```
|
||||
|
||||
在 FROM 子句中 `med_medication_dispense AS mmd` 之后添加 LEFT JOIN:
|
||||
```sql
|
||||
LEFT JOIN cli_procedure cp
|
||||
ON cp.id = mmd.procedure_id
|
||||
AND cp.delete_flag = '0'
|
||||
```
|
||||
|
||||
**改动C**:外层 SELECT(第78行)将 `ii.planned_dispense_time` 改为 `ii.execution_time`:
|
||||
|
||||
```sql
|
||||
ii.execution_time,
|
||||
```
|
||||
|
||||
**改动D**:ORDER BY(第203行)将 `mmd.planned_dispense_time` 改为 `cp.occurrence_time`:
|
||||
|
||||
```sql
|
||||
ORDER BY cp.occurrence_time )) AS ii
|
||||
```
|
||||
|
||||
#### 修改2:前端列名 — "领药时间" → "执行时间"
|
||||
|
||||
**文件**: `healthlink-his-ui/src/views/inpatientNurse/drugDistribution/components/prescriptionList.vue`
|
||||
|
||||
第164行:
|
||||
```vue
|
||||
<!-- 修改前 -->
|
||||
<vxe-column title="领药时间" field="times">
|
||||
|
||||
<!-- 修改后 -->
|
||||
<vxe-column title="执行时间" field="times">
|
||||
```
|
||||
|
||||
#### 无需修改的部分
|
||||
- `MedicineSummaryParam.java` — 字段名 `dispenseTime` 保持不变,仅后端数据源改变
|
||||
- `MedicineSummaryAppServiceImpl.java` — 无变化(`medicineSummary()` 方法提交时自行用 `new Date()` 覆盖)
|
||||
- 前端时间格式化逻辑 — `item.dispenseTime?.substring(5, 10)` 从 "yyyy-MM-dd HH:mm:ss" 截取 "MM-dd",格式兼容
|
||||
|
||||
### 四、路由决策
|
||||
|
||||
**FIXER: guanyu(后端开发)**
|
||||
|
||||
**REASON**: 修复核心在 Mapper XML SQL 改写(JOIN `cli_procedure` 取 `occurrence_time` 替代 `planned_dispense_time`),属于后端数据查询层改动。前端仅改一个列名文本,可一并处理但主要工作量在后端 SQL。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **修复 Agent**: guanyu
|
||||
- **原因**: LLM 分析决策
|
||||
102
MD/bugs/BUG_762_ANALYSIS.md
Normal file
102
MD/bugs/BUG_762_ANALYSIS.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# Bug #762 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-12 16:21:51
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 762
|
||||
- **标题**: [住院护士站-领药汇总]“汇总领药”界面的筛选标签文字丢失且功能失效
|
||||
- **模块**: 病区护士工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
Now I have the complete picture. Here's my analysis:
|
||||
|
||||
---
|
||||
|
||||
### 一、Bug 理解
|
||||
|
||||
住院护士站的「汇总领药」页面(`drugDistribution/index.vue`)顶部筛选栏有 4 个按钮——"西药""中药""明细""汇总",但目前这 4 个按钮**仅显示空白**,用户看不到文字标签,也无法通过点击"西药/中药"进行药物类别筛选。期望按钮正常显示中文标签,且点击可触发对应的数据筛选。
|
||||
|
||||
### 二、根因分析
|
||||
|
||||
**根因完全在前端**,`healthlink-his-ui/src/views/inpatientNurse/drugDistribution/index.vue` 存在两个问题:
|
||||
|
||||
**问题1:`el-radio-button` 缺少标签文字**
|
||||
|
||||
```html
|
||||
<!-- 第50~64行,当前代码 -->
|
||||
<el-radio-group v-model="drugType" class="ml10">
|
||||
<el-radio-button value="1" /> <!-- ← 缺少标签文字 -->
|
||||
<el-radio-button value="2" /> <!-- ← 缺少标签文字 -->
|
||||
</el-radio-group>
|
||||
<el-radio-group v-model="isDetails" class="ml20" @change="handleRadioChange">
|
||||
<el-radio-button value="1" /> <!-- ← 缺少标签文字 -->
|
||||
<el-radio-button value="2" /> <!-- ← 缺少标签文字 -->
|
||||
</el-radio-group>
|
||||
```
|
||||
|
||||
Element Plus 的 `el-radio-button` 需要通过默认 slot 或 `label` 属性显示文字,仅设 `value` 不会渲染任何可见文本。
|
||||
|
||||
**问题2:`drugType` 未传递给子组件,筛选功能失效**
|
||||
|
||||
- `drugType` 在 `index.vue:178` 定义(`ref('1')`),但 `PrescriptionList` 和 `SummaryMedicineList` 组件在模板中**未接收此 prop**:
|
||||
```html
|
||||
<PrescriptionList v-if="isDetails == 1" ref="prescriptionRefs"
|
||||
:exe-status="exeStatus" :request-status="requestStatus"
|
||||
:deadline="deadline" :therapy-enum="therapyEnum" />
|
||||
<!-- 缺少 :drug-type="drugType" -->
|
||||
```
|
||||
- `prescriptionList.vue` 和 `summaryMedicineList.vue` 的 `defineProps` 中均未定义 `drugType`
|
||||
- API 调用时也未传 `tcmFlag` 参数
|
||||
|
||||
**后端已具备筛选能力**:`DispenseFormSearchParam` 已有 `tcmFlag` 字段(第34行),`HisQueryUtils.buildQueryWrapper` 会自动生成 WHERE 条件,Mapper XML 使用 `${ew.customSqlSegment}` 动态拼接。前端只需传参即可。
|
||||
|
||||
### 三、修复方案
|
||||
|
||||
纯前端修复,涉及 3 个文件,后端无需改动。
|
||||
|
||||
**文件1:`healthlink-his-ui/src/views/inpatientNurse/drugDistribution/index.vue`**
|
||||
|
||||
| 修改点 | 内容 |
|
||||
|--------|------|
|
||||
| 第53行 `el-radio-button value="1"` | 改为 `<el-radio-button value="1">西药</el-radio-button>` |
|
||||
| 第56行 `el-radio-button value="2"` | 改为 `<el-radio-button value="2">中药</el-radio-button>` |
|
||||
| 第62行 `el-radio-button value="1"` | 改为 `<el-radio-button value="1">明细</el-radio-button>` |
|
||||
| 第65行 `el-radio-button value="2"` | 改为 `<el-radio-button value="2">汇总</el-radio-button>` |
|
||||
| `PrescriptionList` 组件标签 | 添加 `:drug-type="drugType"` prop |
|
||||
| `SummaryMedicineList` 组件标签 | 添加 `:drug-type="drugType"` prop |
|
||||
|
||||
**文件2:`healthlink-his-ui/src/views/inpatientNurse/drugDistribution/components/prescriptionList.vue`**
|
||||
|
||||
| 修改点 | 内容 |
|
||||
|--------|------|
|
||||
| `defineProps` 块(第259行) | 新增 `drugType: { type: String, default: '1' }` |
|
||||
| `handleGetPrescription` 函数(第281行) | API 调用参数中添加 `tcmFlag: props.drugType === '1' ? 0 : 1`(西药=0,中药=1) |
|
||||
|
||||
**文件3:`healthlink-his-ui/src/views/inpatientNurse/drugDistribution/components/summaryMedicineList.vue`**
|
||||
|
||||
| 修改点 | 内容 |
|
||||
|--------|------|
|
||||
| `defineProps` 块(第168行) | 新增 `drugType: { type: String, default: '1' }` |
|
||||
| `handleGetPrescription` 函数(第186行) | API 调用参数中添加 `tcmFlag: props.drugType === '1' ? 0 : 1` |
|
||||
|
||||
**验证方式:**
|
||||
1. `cd healthlink-his-ui && npm run build:dev` 编译通过
|
||||
2. `npm run lint` 无报错
|
||||
3. 手动验证:进入汇总领药页,4 个按钮显示"西药""中药""明细""汇总"文字;点击切换正常
|
||||
|
||||
### 四、路由决策
|
||||
|
||||
**FIXER: zhaoyun**(前端开发)
|
||||
**REASON:** 此 Bug 纯前端问题,涉及 3 个 Vue 组件的模板和 props 修复,属于前端 UI/交互层面,无需后端改动,最适合由赵云处理。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **修复 Agent**: zhaoyun
|
||||
- **原因**: ** 此 Bug 纯前端问题,涉及 3 个 Vue 组件的模板和 props 修复,属于前端 UI/交互层面,无需后端改动,最适合由赵云处理。
|
||||
90
MD/bugs/BUG_763_ANALYSIS.md
Normal file
90
MD/bugs/BUG_763_ANALYSIS.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# Bug #763 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-12 16:18:00
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 763
|
||||
- **标题**: [住院护士站-医嘱校对]医生工作站已签发的临时医嘱在护士站“医嘱校对”中无法查询
|
||||
- **模块**: 病区护士工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
This confirms `effectiveDoseEnd` is only set in outpatient prescriptions, NOT in inpatient order signing. Now I have the complete root cause.
|
||||
|
||||
---
|
||||
|
||||
### 一、Bug 理解
|
||||
|
||||
护士在"医嘱校对"界面选择患者并点击查询时,医生已签发的临时医嘱(药品类,如注射用头孢)无法显示,列表为空。期望行为:已签发的临时医嘱应出现在"未校对"列表中,供护士校对。
|
||||
|
||||
### 二、根因分析
|
||||
|
||||
**根因:Bug #665 修复引入的 `deadline` 过滤条件未处理 `NULL` 值。**
|
||||
|
||||
完整数据链路追踪:
|
||||
|
||||
1. **医生签发临时医嘱** → `AdviceManageAppServiceImpl.handMedication()` → `tempMedicationRequest.setStatusEnum(ACTIVE=2)` → 调用 `saveOrUpdate()` → 写入 `med_medication_request` 表
|
||||
2. **关键遗漏**:`effectiveDoseEnd`(服药结束时间)在整个签发流程中**从未被设置**(`setEffectiveDoseEnd` 仅在门诊处方 `DoctorStationElepPrescriptionServiceImpl` 中调用,住院医嘱路径不涉及),因此数据库中 `effective_dose_end = NULL`
|
||||
3. **护士站查询** → 前端 `prescriptionList.vue` 默认发送 `deadline = "2026-06-12 23:59:59"` → 后端 `AdviceProcessAppServiceImpl.getInpatientAdvicePage()` 拼接条件:
|
||||
```java
|
||||
queryWrapper.le("end_time", deadlineTime); // Bug #665 引入
|
||||
```
|
||||
生成 SQL:`end_time <= '2026-06-12 23:59:59'`
|
||||
4. **NULL 比较失败**:PostgreSQL 中 `NULL <= anything` 结果为 `NULL`(等价于 `FALSE`),WHERE 子句排除该行 → 查询结果为空
|
||||
|
||||
**涉及文件:**
|
||||
- `AdviceProcessAppServiceImpl.java`(第 235-243 行)— deadline 条件拼接
|
||||
- `AdviceProcessAppMapper.xml` — UNION 查询,`T1.effective_dose_end AS end_time`
|
||||
|
||||
### 三、修复方案
|
||||
|
||||
**修改文件**:`healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/inhospitalnursestation/appservice/impl/AdviceProcessAppServiceImpl.java`
|
||||
|
||||
**修改内容**:将 deadline 过滤条件从 `le` 改为 NULL 安全的写法:
|
||||
|
||||
```java
|
||||
// 修改前(Bug #665 代码):
|
||||
if (deadline != null && !deadline.isEmpty()) {
|
||||
try {
|
||||
LocalDateTime deadlineTime = LocalDateTime.parse(deadline,
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
queryWrapper.le("end_time", deadlineTime);
|
||||
} catch (DateTimeParseException e) {
|
||||
// 忽略无效的日期格式
|
||||
}
|
||||
}
|
||||
|
||||
// 修改后:
|
||||
if (deadline != null && !deadline.isEmpty()) {
|
||||
try {
|
||||
LocalDateTime deadlineTime = LocalDateTime.parse(deadline,
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
queryWrapper.and(w -> w.le("end_time", deadlineTime).or().isNull("end_time"));
|
||||
} catch (DateTimeParseException e) {
|
||||
// 忽略无效的日期格式
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**原理**:`end_time <= deadline OR end_time IS NULL`,确保 `effective_dose_end` 为 NULL 的新签发医嘱也能被查询到。
|
||||
|
||||
**验证**:
|
||||
1. `mvn clean compile -DskipTests` → 编译通过
|
||||
2. 签发临时医嘱 → 护士站查询 → 应能查到
|
||||
3. 长期医嘱、有截止时间的医嘱 → deadline 筛选仍然生效
|
||||
|
||||
### 四、路由决策
|
||||
|
||||
**FIXER**: guanyu
|
||||
**REASON**: 修复范围仅涉及后端 Java Service 层一处 SQL 条件修改,属于纯后端逻辑修复,由后端开发关羽执行。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **修复 Agent**: guanyu
|
||||
- **原因**: LLM 分析决策
|
||||
121
MD/bugs/BUG_764_ANALYSIS.md
Normal file
121
MD/bugs/BUG_764_ANALYSIS.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# Bug #764 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-12 16:05:34
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 764
|
||||
- **标题**: [门诊医生工作站-检验] 已维护诊疗项目的检验项目“肾功能5项”在开立保存时报错“未找到对应的诊疗定义”
|
||||
- **模块**: 门诊医生工作站
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
Now I have a complete understanding of the bug. Let me output the analysis.
|
||||
|
||||
---
|
||||
|
||||
### 一、Bug 理解
|
||||
|
||||
用户在门诊医生工作站选择检验项目"肾功能5项"并点击保存时,系统报错"未找到检验项目 '肾功能5项' 对应的诊疗定义"。该检验项目已在后台正确维护,期望保存成功并自动联动生成门诊医嘱记录。
|
||||
|
||||
### 二、根因分析
|
||||
|
||||
**根因**:`DoctorStationLabApplyServiceImpl.java` 的检验申请保存方法包含两个阶段:
|
||||
|
||||
1. **阶段一(保存申请单明细)**:正确使用 `labActivityDefinitionService.getById(activityId)` 从 `lab_activity_definition` 表查询检验项目定义(第182行)。
|
||||
2. **阶段二(自动创建门诊医嘱)**:**错误地**调用 `activityDefinitionService.getAppointActivityDefinitionId(itemName)`,该方法按名称精确匹配 `wor_activity_definition` 表(SQL: `WHERE NAME = #{activityName}`)。
|
||||
|
||||
**关键问题**:检验项目(如"肾功能5项")存储在独立的 `lab_activity_definition` 表中,**不存在于** `wor_activity_definition` 表中。按名称查询 `wor_activity_definition` 必然返回 null,触发 RuntimeException。
|
||||
|
||||
**对比参考**:`ExamApplyController`(检查申请)已正确处理类似情况——使用 `activityId = 0L` 占位,不依赖 `wor_activity_definition`(第224行注释:"检查申请不走诊疗定义,设置为0占位")。
|
||||
|
||||
**涉及文件**:
|
||||
- `DoctorStationLabApplyServiceImpl.java:254-259` — 查询逻辑错误(根因)
|
||||
- `ActivityDefinitionMapper.xml:7-13` — SQL 查询 `wor_activity_definition` by name
|
||||
- `ActivityDefinitionServiceImpl.java:76-77` — `getAppointActivityDefinitionId` 方法
|
||||
|
||||
### 三、修复方案
|
||||
|
||||
修改 `DoctorStationLabApplyServiceImpl.java` 中阶段二(门诊医嘱创建循环),将从 `wor_activity_definition` 按名称查询改为使用 `lab_activity_definition` 的 `activityId` 直接查询:
|
||||
|
||||
**修改文件**:`healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/doctorstation/appservice/impl/DoctorStationLabApplyServiceImpl.java`
|
||||
|
||||
**具体改动**:
|
||||
|
||||
将第254-370行附近的代码从:
|
||||
|
||||
```java
|
||||
// 1. 根据检验项目名称查询诊疗定义(检验项目)
|
||||
String itemName = labApplyItemDto.getItemName();
|
||||
Long activityDefinitionId = activityDefinitionService.getAppointActivityDefinitionId(itemName);
|
||||
if (activityDefinitionId == null) {
|
||||
throw new RuntimeException("未找到检验项目 '" + itemName + "' 对应的诊疗定义");
|
||||
}
|
||||
// 2. 获取诊疗定义详情
|
||||
ActivityDefinition activityDefinition = activityDefinitionService.getById(activityDefinitionId);
|
||||
if (activityDefinition == null) {
|
||||
throw new RuntimeException("诊疗定义不存在");
|
||||
}
|
||||
...
|
||||
adviceSaveDto.setAdviceDefinitionId(activityDefinitionId);
|
||||
adviceSaveDto.setDefinitionId(activityDefinitionId);
|
||||
adviceSaveDto.setCategoryCode(activityDefinition.getCategoryCode());
|
||||
adviceSaveDto.setActivityId(activityDefinitionId);
|
||||
adviceSaveDto.setAdviceTableName("wor_activity_definition");
|
||||
...
|
||||
adviceSaveDto.setUnitCode(activityDefinition.getPermittedUnitCode());
|
||||
Long feePackageId = activityDefinition.getFeePackageId();
|
||||
```
|
||||
|
||||
改为:
|
||||
|
||||
```java
|
||||
// 1. 获取检验项目定义(从 lab_activity_definition 表,不走 wor_activity_definition)
|
||||
String itemName = labApplyItemDto.getItemName();
|
||||
Long labActivityId = labApplyItemDto.getActivityId();
|
||||
if (labActivityId == null) {
|
||||
throw new RuntimeException("检验项目 '" + itemName + "' 未传入 activityId,请重新选择检验项目");
|
||||
}
|
||||
LabActivityDefinition labActivityDef = labActivityDefinitionService.getById(labActivityId);
|
||||
if (labActivityDef == null) {
|
||||
throw new RuntimeException("检验项目定义不存在,activityId=" + labActivityId);
|
||||
}
|
||||
...
|
||||
// 医嘱定义 ID:使用 lab_activity_definition 的 ID
|
||||
adviceSaveDto.setAdviceDefinitionId(labActivityId);
|
||||
// 费用定价 ID:检验项目不走 wor_activity_definition 定价体系,用 0 占位(与 ExamApplyController 一致)
|
||||
adviceSaveDto.setDefinitionId(0L);
|
||||
adviceSaveDto.setCategoryCode(labActivityDef.getCategoryCode());
|
||||
adviceSaveDto.setActivityId(labActivityId);
|
||||
adviceSaveDto.setAdviceTableName("lab_activity_definition");
|
||||
...
|
||||
adviceSaveDto.setUnitCode(labActivityDef.getPermittedUnitCode());
|
||||
Long feePackageId = labActivityDef.getFeePackageId();
|
||||
```
|
||||
|
||||
**核心改动点**:
|
||||
| 字段 | 原值 | 新值 | 原因 |
|
||||
|------|------|------|------|
|
||||
| 数据源 | `wor_activity_definition` (by name) | `lab_activity_definition` (by ID) | 检验项目独立存储 |
|
||||
| `adviceDefinitionId` | `wor_activity_definition.id` | `lab_activity_definition.id` | 正确引用产品表 |
|
||||
| `definitionId` | `wor_activity_definition.id` | `0L` 占位 | 检验项目不走诊疗定价体系 |
|
||||
| `adviceTableName` | `"wor_activity_definition"` | `"lab_activity_definition"` | 正确指向产品来源表 |
|
||||
| `categoryCode` | `ActivityDefinition.categoryCode` | `LabActivityDefinition.categoryCode` | 同名字段,来源切换 |
|
||||
| `unitCode` | `ActivityDefinition.permittedUnitCode` | `LabActivityDefinition.permittedUnitCode` | 同名字段,来源切换 |
|
||||
| `feePackageId` | `ActivityDefinition.feePackageId` | `LabActivityDefinition.feePackageId` | 同名字段,来源切换 |
|
||||
|
||||
### 四、路由决策
|
||||
|
||||
**FIXER**: `guanyu`(后端开发)
|
||||
|
||||
**REASON**: 此 Bug 仅涉及后端 Java 代码修改(`DoctorStationLabApplyServiceImpl.java` 一个文件),核心是修正检验项目的数据源查询逻辑——从 `wor_activity_definition` 切换到 `lab_activity_definition`。不需要前端改动(前端已正确传递 `activityId`),不需要数据库变更。属于后端 Service 层逻辑修复,由关羽执行最合适。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **修复 Agent**: guanyu
|
||||
- **原因**: LLM 分析决策
|
||||
74
MD/bugs/BUG_765_ANALYSIS.md
Normal file
74
MD/bugs/BUG_765_ANALYSIS.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# Bug #765 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-12 15:58:59
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **Bug #**: 765
|
||||
- **标题**: [收费工作站-门诊挂号] 在“患者身份信息”框中选中检索的患者后,患者列表浮窗未自动隐藏
|
||||
- **模块**: 建档挂号管理
|
||||
- **提出人**: 陈显精
|
||||
|
||||
---
|
||||
|
||||
Now I have the complete picture. Here's my analysis:
|
||||
|
||||
---
|
||||
|
||||
### 一、Bug 理解
|
||||
|
||||
在门诊挂号页面的"患者身份信息"输入框中,用户输入关键字后弹出患者列表浮窗(`el-popover`),点击选中某行患者后,表单信息已正确回填,但浮窗没有自动关闭,继续遮挡下方录入项。用户期望选中后浮窗自动收起。
|
||||
|
||||
### 二、根因分析
|
||||
|
||||
问题出在 `outpatientregistration/index.vue` 中的 **popover 可见性控制逻辑**。
|
||||
|
||||
**关键代码链路:**
|
||||
|
||||
| 位置 | 代码 | 作用 |
|
||||
|------|------|------|
|
||||
| `index.vue:118` | `:visible="showPopover"` | popover 显隐由 `showPopover` 控制 |
|
||||
| `index.vue:125` | `@mousedown.prevent` | 阻止 mousedown 冒泡到 input,防止点击列表时 input 失焦 |
|
||||
| `index.vue:1990` | `handleFocus() → showPopover = true` | input 获焦显示浮窗 |
|
||||
| `index.vue:1996` | `handleBlur() → showPopover = false` | input 失焦隐藏浮窗 |
|
||||
| `index.vue:2228` | `selsectPatient(row)` — **只回填表单,未关闭浮窗** | ⬅️ 根因 |
|
||||
|
||||
**根因**:`selsectPatient` 函数只做了 `Object.assign(form.value, row)` 等字段回填,**没有设置 `showPopover.value = false`**。由于 `@mousedown.prevent` 阻止了点击列表时 input 的 blur 事件,`handleBlur` 不会被触发,浮窗就一直保持显示。
|
||||
|
||||
### 三、修复方案
|
||||
|
||||
**修改文件**:`healthlink-his-ui/src/views/charge/outpatientregistration/index.vue`
|
||||
|
||||
**修改内容**:在 `selsectPatient` 函数末尾添加一行,关闭 popover:
|
||||
|
||||
```javascript
|
||||
function selsectPatient(row) {
|
||||
Object.assign(form.value, row);
|
||||
form.value.patientId = row.id;
|
||||
form.value.searchKey = row.name;
|
||||
form.value.name = row.name;
|
||||
form.value.idCard = row.idCard;
|
||||
form.value.genderEnum_enumText = row.genderEnum_enumText;
|
||||
form.value.phone = row.phone;
|
||||
form.value.firstEnum_enumText = row.firstEnum_enumText;
|
||||
form.value.age = row.age;
|
||||
form.value.identifierNo = row.identifierNo;
|
||||
showPopover.value = false; // ← 新增:选中患者后关闭浮窗
|
||||
}
|
||||
```
|
||||
|
||||
**影响范围**:仅一处,不涉及后端、不涉及数据库、不涉及其他组件。
|
||||
|
||||
### 四、路由决策
|
||||
|
||||
**FIXER**: `zhaoyun`(前端开发)
|
||||
**REASON**: 纯前端 Vue 组件修复,只需在 `index.vue` 的 `selsectPatient` 函数中增加一行 `showPopover.value = false;`,属于 Element Plus popover 交互问题,赵云负责前端界面修复。
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **修复 Agent**: guanyu
|
||||
- **原因**: LLM 分析决策
|
||||
43
MD/bugs/BUG_诊疗目录_SYSDESDICT_ANALYSIS.md
Normal file
43
MD/bugs/BUG_诊疗目录_SYSDESDICT_ANALYSIS.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# 诊疗目录 SysDictData 反序列化错误 诸葛亮分析报告
|
||||
|
||||
> **文档类型**: Bug分析
|
||||
> **分析时间**: 2026-06-11
|
||||
> **分析模型**: mimo-v2.5 (LLM深度分析)
|
||||
|
||||
---
|
||||
|
||||
## 基本信息
|
||||
- **标题**: 诊疗目录 /system/catalog/diagnosistreatment 进入报错
|
||||
- **错误**: Cannot deserialize value of type SysDictData from Array value
|
||||
- **模块**: 诊疗目录管理
|
||||
|
||||
---
|
||||
|
||||
## 根因分析
|
||||
|
||||
**根本原因**: commit `68cfa4882` 将 Jackson 配置从 `Jackson2ObjectMapperBuilderCustomizer` 改为直接定义 `ObjectMapper` bean。
|
||||
|
||||
直接定义 `ObjectMapper` bean 会导致 Spring Boot 的 Jackson 自动配置完全失效:
|
||||
1. Spring Boot 默认的 Jackson 模块(如 `jackson-datatype-jdk8`、`jackson-datatype-jsr310`)不会自动注册
|
||||
2. 默认的序列化/反序列化特性设置丢失
|
||||
3. `ObjectMapper` 的默认可见性设置可能不同
|
||||
|
||||
当 `DictAspect` 处理 `@Dict` 注解的 DTO 时,Jackson 在序列化/反序列化过程中遇到 `SysDictData` 类型,由于缺少正确的模块配置,无法正确处理嵌套的数组/对象结构。
|
||||
|
||||
## 修复方案
|
||||
|
||||
将 `ApplicationConfig.java` 中的 `ObjectMapper` bean 改回 `Jackson2ObjectMapperBuilderCustomizer`,让 Spring Boot 自动配置保持生效。
|
||||
|
||||
### 修改文件
|
||||
- `core-framework/src/main/java/com/core/framework/config/ApplicationConfig.java`
|
||||
|
||||
### 修改内容
|
||||
- `public ObjectMapper objectMapper()` → `public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization()`
|
||||
- 移除手动创建的 `ObjectMapper` 实例
|
||||
- 使用 builder 模式配置,保留 Spring Boot 默认设置
|
||||
|
||||
---
|
||||
|
||||
## 路由决策
|
||||
- **修复 Agent**: guanyu (后端)
|
||||
- **原因**: Jackson 配置问题,纯后端修改
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
# 前端发布前检查清单
|
||||
|
||||
> **文档类型**: 技术规范
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"test_time": "2026-06-08T09:11:33.934379",
|
||||
"test_time": "2026-06-08T11:20:49.248056",
|
||||
"environment": "http://localhost:18082/healthlink-his",
|
||||
"total": 125,
|
||||
"passed": 125,
|
||||
@@ -167,7 +167,7 @@
|
||||
"id": "OP-PHARM",
|
||||
"name": "待发药列表",
|
||||
"ok": true,
|
||||
"detail": "待发药=534"
|
||||
"detail": "待发药=532"
|
||||
},
|
||||
{
|
||||
"id": "OP-WEST",
|
||||
@@ -377,13 +377,13 @@
|
||||
"id": "INS-3D",
|
||||
"name": "3D重建任务",
|
||||
"ok": true,
|
||||
"detail": "任务=0"
|
||||
"detail": "任务=14"
|
||||
},
|
||||
{
|
||||
"id": "INS-3D-RPT",
|
||||
"name": "3D重建报告",
|
||||
"ok": true,
|
||||
"detail": "报告=0"
|
||||
"detail": "报告=11"
|
||||
},
|
||||
{
|
||||
"id": "INS-RAD-RPT",
|
||||
@@ -695,7 +695,7 @@
|
||||
"id": "MR-05-PHARM",
|
||||
"name": "药师→待发药",
|
||||
"ok": true,
|
||||
"detail": "待发药=534"
|
||||
"detail": "待发药=532"
|
||||
},
|
||||
{
|
||||
"id": "MR-06-CHARGE",
|
||||
|
||||
34
docs/bug-fixes/bug-761.md
Normal file
34
docs/bug-fixes/bug-761.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #761 修复报告
|
||||
|
||||
## 基本信息
|
||||
- **标题**: Bug #761 测试完成,请验收。提出人: chenxj。
|
||||
- **提出人**: chenxj
|
||||
- **修复时间**: 17:05:05 ~ 17:31:09
|
||||
- **修复耗时**: 1465.3s
|
||||
- **Commit**: `008ae24b4`
|
||||
- **测试结果**: ❌ FAIL
|
||||
|
||||
## 根因分析
|
||||
---
|
||||
|
||||
## Bug #761 修复完成
|
||||
|
||||
**根因**:
|
||||
- `MedicineSummaryAppMapper.xml` 中 `dispenseTime` 字段映射自 `med_medication_dispense.planned_dispense_time`(计划发药时间),而非实际执行时间。`planned_dispense_time` 在 `AdviceProcessAppServi | 文件变更: 无变更 | 阶段: generator:PASS reviewer:PASS qa:PASS verifier:PASS
|
||||
|
||||
## 修复文件
|
||||
.../impl/DoctorStationLabApplyServiceImpl.java | 32 ++++++++++------------
|
||||
|
||||
## 流程时间线
|
||||
| 时间 | 智能体 | 事件 | 状态 | 耗时 |
|
||||
|------|--------|------|------|------|
|
||||
| 14:24:44 | zhugeliang | pre_analyze_done | ✅ | 0.0s |
|
||||
| 15:06:07 | zhugeliang | pre_analyze_done | ✅ | 0.0s |
|
||||
| 15:53:07 | zhugeliang | pre_analyze_done | ✅ | 0.0s |
|
||||
| 17:05:05 | guanyu | fix_start | ⏳ | 0.0s |
|
||||
| 17:31:09 | guanyu | fix_done | ✅ | 1465.3s |
|
||||
| 17:31:21 | zhugeliang | analyze_done | ✅ | 0.0s |
|
||||
| 21:33:09 | chenlin | doc_done | ✅ | <1s |
|
||||
|
||||
## 全流程
|
||||
诸葛亮分析 → guanyu 修复 → 张飞测试 → 华佗验收 → 陈琳归档
|
||||
35
docs/bug-fixes/bug-763.md
Normal file
35
docs/bug-fixes/bug-763.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Bug #763 修复报告
|
||||
|
||||
## 基本信息
|
||||
- **标题**: Bug #763 测试完成,请验收。提出人: chenxj。
|
||||
- **提出人**: chenxj
|
||||
- **修复时间**: 17:31:18 ~ 18:13:03
|
||||
- **修复耗时**: 1310.2s
|
||||
- **Commit**: `008ae24b4`
|
||||
- **测试结果**: ❌ FAIL
|
||||
|
||||
## 根因分析
|
||||
**编译验证通过 ✅ BUILD SUCCESS**
|
||||
|
||||
## Bug #763 修复验证结果
|
||||
|
||||
**根因确认(诸葛亮分析正确)**:
|
||||
- Bug #665 引入的 `queryWrapper.le("end_time", deadlineTime)` 对 NULL 值处理不当
|
||||
- 住院临时医嘱签发时 `effectiveDoseEnd` 未赋值 → DB 中 `effective_dose_end | 文件变更: 无变更 | 阶段: generator:PASS reviewer:PASS qa:PASS verifier:PASS
|
||||
|
||||
## 修复文件
|
||||
.../impl/DoctorStationLabApplyServiceImpl.java | 32 ++++++++++------------
|
||||
|
||||
## 流程时间线
|
||||
| 时间 | 智能体 | 事件 | 状态 | 耗时 |
|
||||
|------|--------|------|------|------|
|
||||
| 14:06:51 | guanyu | fix_start | ⏳ | 0.0s |
|
||||
| 16:18:32 | zhugeliang | pre_analyze_done | ✅ | 0.0s |
|
||||
| 17:31:18 | guanyu | fix_start | ⏳ | 0.0s |
|
||||
| 17:48:37 | guanyu | fix_retry | ❓ | 0.0s |
|
||||
| 18:13:03 | guanyu | fix_done | ✅ | 1310.2s |
|
||||
| 18:13:16 | zhugeliang | analyze_done | ✅ | 0.0s |
|
||||
| 21:33:23 | chenlin | doc_done | ✅ | <1s |
|
||||
|
||||
## 全流程
|
||||
诸葛亮分析 → guanyu 修复 → 张飞测试 → 华佗验收 → 陈琳归档
|
||||
32
docs/bug-fixes/bug-764.md
Normal file
32
docs/bug-fixes/bug-764.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Bug #764 修复报告
|
||||
|
||||
## 基本信息
|
||||
- **标题**: Bug #764 测试完成,请验收。提出人: chenxj。
|
||||
- **提出人**: chenxj
|
||||
- **修复时间**: 18:13:10 ~ 18:36:37
|
||||
- **修复耗时**: 1285.2s
|
||||
- **Commit**: `008ae24b4`
|
||||
- **测试结果**: ❌ FAIL
|
||||
|
||||
## 根因分析
|
||||
**修复完成** ✅
|
||||
|
||||
修改文件:`healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/doctorstation/appservice/impl/DoctorStationLabApplyServiceImpl.java`
|
||||
|
||||
核心改动:将门诊医嘱创建阶段的检验项目定义查询从 ` | 文件变更: 无变更 | 阶段: generator:PASS reviewer:PASS qa:PASS verifier:PASS
|
||||
|
||||
## 修复文件
|
||||
.../impl/DoctorStationLabApplyServiceImpl.java | 32 ++++++++++------------
|
||||
|
||||
## 流程时间线
|
||||
| 时间 | 智能体 | 事件 | 状态 | 耗时 |
|
||||
|------|--------|------|------|------|
|
||||
| 16:05:49 | zhugeliang | pre_analyze_done | ✅ | 0.0s |
|
||||
| 18:13:10 | guanyu | fix_start | ⏳ | 0.0s |
|
||||
| 18:36:37 | guanyu | fix_done | ✅ | 1285.2s |
|
||||
| 18:36:49 | zhugeliang | analyze_done | ✅ | 0.0s |
|
||||
| 21:33:06 | xunyu | db_review_done | ✅ | 0.0s |
|
||||
| 21:33:52 | chenlin | doc_done | ✅ | <1s |
|
||||
|
||||
## 全流程
|
||||
诸葛亮分析 → guanyu 修复 → 张飞测试 → 华佗验收 → 陈琳归档
|
||||
34
docs/bug-fixes/bug-765.md
Normal file
34
docs/bug-fixes/bug-765.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Bug #765 修复报告
|
||||
|
||||
## 基本信息
|
||||
- **标题**: Bug #765 测试完成,请验收。提出人: chenxj。
|
||||
- **提出人**: chenxj
|
||||
- **修复时间**: 18:36:43 ~ 19:01:34
|
||||
- **修复耗时**: 1410.2s
|
||||
- **Commit**: `008ae24b4`
|
||||
- **测试结果**: ✅ PASS
|
||||
|
||||
## 根因分析
|
||||
✅ **编译成功**,`✓ built in 1m 55s`,0 错误。
|
||||
|
||||
---
|
||||
|
||||
## 修复摘要
|
||||
|
||||
**根因**:`selsectPatient` 函数(第 2228 行)只做了患者信息回填(`Object.assign` + 逐字段赋值),没有关闭 `showPopover`。由于 `@mousedown.prevent` 阻止了 input 失焦,`handleBlur` 中的 `show | 文件变更: 无变更 | 阶段: generator:PASS reviewer:PASS qa:PASS verifier:PASS
|
||||
|
||||
## 修复文件
|
||||
.../impl/DoctorStationLabApplyServiceImpl.java | 32 ++++++++++------------
|
||||
|
||||
## 流程时间线
|
||||
| 时间 | 智能体 | 事件 | 状态 | 耗时 |
|
||||
|------|--------|------|------|------|
|
||||
| 15:59:27 | zhugeliang | pre_analyze_done | ✅ | 0.0s |
|
||||
| 18:36:43 | guanyu | fix_start | ⏳ | 0.0s |
|
||||
| 19:01:34 | guanyu | fix_done | ✅ | 1410.2s |
|
||||
| 19:01:44 | zhugeliang | analyze_done | ✅ | 0.0s |
|
||||
| 21:33:38 | zhangfei | test_done | ✅ | 0.0s |
|
||||
| 21:33:38 | chenlin | doc_done | ✅ | <1s |
|
||||
|
||||
## 全流程
|
||||
诸葛亮分析 → guanyu 修复 → 张飞测试 → 华佗验收 → 陈琳归档
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user