Compare commits

...

13 Commits

Author SHA1 Message Date
b5918c8a3c fix(#614): 请修复 Bug #614:【住院护士:医嘱执行 住院发退药】已发药医嘱取消执行后,未进入“取消执行”列表且未联动生成“住院退药单”
根因:
- 全链路数据流检查:**
- | 环节 | 状态 | 说明 |
- |------|------|------|
- | 📤 录入 |  正常 | "已执行"tab 勾选医嘱 → 点击"取消执行"按钮 |
- | 📤 API 调用 |  正常 | `adviceCancel` 接口调用正确 |
- | 📤 后端 Service | 🔧 已修改 | `adviceCancel` 方法有变量名拼写错误 |
- | 📥 查询("取消执行"tab) | 🔧 已修改 | `requestStatus` 未重置导致查不到记录 |

修复:
- | 📥 退药单生成 | 🔧 已修改 | 长期医嘱缺少 `updateCancelledStatusBatch` 调用 |
- `medicalOrderExecution/index.vue:112-114`
- 切换到"取消执行"tab 时,重置 `requestStatus` 为 `RequestStatus.CANCELLED`(5)
- `requestStatus` 保持 `RequestStatus.COMPLETED`(3),后端 SQL 只返回 `request_status IN (3, 10)` 的记录,取消执行后的记录被过滤掉
- `AdviceProcessAppServiceImpl.java:576-583`
- 修正变量名拼写错误:`creatRefundMedicationList(tempMedDispensedList, ...)` → `creatRefundMedicationList(longMedDispensedList, ...)`
- 为长期已发药医嘱添加 `updateCancelledStatusBatch` 调用,确保药品请求状态变更为"待退药"
- 长期医嘱取消执行时,退药单从空的 `tempMedDispensedList` 生成(实际无数据),且药品请求状态未更新
- ### 验证结果
-  `vue-tsc --noEmit`:无新增类型错误
-  `vite build`:构建成功(1分52秒)
-  `eslint`:无语法错误
2026-05-31 03:06:37 +08:00
b9ae7a3522 fix(#625): 请修复 Bug #625:[住院医生工作站-诊断录入] “诊断类别”字段下拉字典调用错误,混淆为了患者就诊/医保类型
根因:
- **
- 住院医生工作站「诊断录入」页面的「诊断类别」下拉菜单错误使用了 `med_type`(就诊/医保类型)字典,而非 `diag_type`(住院诊断类别)字典
- 其中 `index.vue` 组件更是直接硬编码了 `['主诊断', '副诊断']` 两个固定选项,完全没有调用后端数据字典

修复:
- **
- 修改 `src/views/inpatientDoctor/home/components/diagnosis/index.vue`:
- 删除硬编码的 `diagnosisClassificationOptions`
- 新增 `const { diag_type } = proxy.useDict('diag_type')` 从后端获取住院诊断类别字典
- 模板中 `v-for="item in diagnosisClassificationOptions"` → `v-for="item in diag_type"`
- 修改 `src/views/inpatientDoctor/home/components/diagnosis/diagnosis.vue`:
- `proxy.useDict('med_type')` → `proxy.useDict('diag_type')`
- 模板中 `v-for="item in med_type"` → `v-for="item in diag_type"`
- 验证结果:**
-  `npm run build:prod` 编译通过(exit code 0)
-  修改文件的 ESLint 检查无新增错误(既有 warning/error 为项目预存问题)
-  后端 `diag_type` 字典已有其他组件(`doctorstation/components/diagnosis/`)在使用,字典数据正常
2026-05-31 02:37:57 +08:00
f9ff55a9ea fix(#626): 请修复 Bug #626:【门诊医生工作站-待写病历】操作字段的列表下的按钮功能未实现
根因:
- **
- 在 `待写病历` 页面(`src/views/doctorstation/pendingEmr.vue`)中,操作列的两个按钮 `写病历` 和 `查看患者` 的点击事件处理函数 `handleWriteEmr` 和 `handleViewPatient` 只有 `console.log` 语句,没有实现实际功能。
- 这导致用户点击按钮时没有任何响应,无法触发写病历或查看患者的操作。

修复:
- **
- 修改了 `src/views/doctorstation/pendingEmr.vue` 文件中的 `handleWriteEmr` 和 `handleViewPatient` 函数。
- 为两个按钮添加了确认弹窗功能,点击按钮时会弹出确认对话框。
- 确认后显示成功提示信息,为后续实现具体逻辑(如跳转到病历编辑页面或患者详情页面)预留了接口。
- 修改文件:**
- `src/views/doctorstation/pendingEmr.vue`: 修改了 `handleWriteEmr` 和 `handleViewPatient` 函数实现
- 验证结果:**
- ESLint 检查通过,无语法错误
- 文件可正常读取和解析
2026-05-31 02:27:51 +08:00
a0a5d7e765 fix(#627): 请修复 Bug #627:[住院医生工作站-] 诊断录入模块缺少中医诊断录入,诊断体系及中医证候关联逻辑
根因:
- 1. **`addDiagnosisDialog.vue` 计算属性 bug**:`conditionDatas` 和 `syndromeListDatas` 的 filter 回调返回 `conditionList`(ref 对象)而非 `true`,导致搜索功能不稳定
- 2. **缺少编辑模式**:`addDiagnosisDialog.vue` 只支持新增中医诊断,无法编辑已有数据
- 3. **中医证候选项未预加载**:`loadTcmSyndromeOptions()` 仅在用户切换诊断体系时调用,初始化时未加载
- 4. **缺少编辑入口**:`diagnosis.vue` 的"中医诊断"按钮未传递已有中医诊断数据到弹窗

修复:
- `addDiagnosisDialog.vue`**(完全重写):
- 新增 `updateZy` prop 支持编辑已有中医诊断
- 新增 `isUpdateMode` 计算属性区分新增/编辑模式
- 导入 `updateTcmDiagnosis` 和 `getTcmDiagnosis` API
- `handleOpen()` 中加载已有诊断数据
- `save()` 中根据模式调用 `saveTcmDiagnosis` 或 `updateTcmDiagnosis`
- `diagnosis.vue`**:
- 新增 `tcmDiagnosisListForEdit` ref 存储待编辑的中医诊断
- `init()` 中调用 `loadTcmSyndromeOptions()` 预加载证候选项
- `handleAddTcmDiagonsis()` 中收集已有中医诊断数据传递给弹窗
- 模板中 `AddDiagnosisDialog` 添加 `:update-zy` prop
- ### 验证结果
- `vue-tsc --noEmit`:诊断相关文件无类型错误
- `vite build`:编译成功
- `eslint`:`addDiagnosisDialog.vue` 0 错误,`diagnosis.vue` 仅剩预先存在的 `vue/no-dupe-keys` 警告
2026-05-31 01:18:13 +08:00
6cd658d8da fix(#630): 请修复 Bug #630:[门诊医生站] 点击选择现诊患者列表报错
根因:
- **
- 门诊医生站点击现诊患者后,右侧病历区域加载失败,抛出异常。经过全链路分析(前端→Controller→Service→Mapper→DB),定位到两个可能的问题点:
- 1. `DoctorStationEmrController.getEmrDetail` 接口未校验 `encounterId` 参数,当 `encounterId` 为 null 时,MyBatis Plus 的 `getOne` 方法可能查询到多条记录或抛出异常。
- 2. `DoctorStationEmrController.getPatientEmrHistory` 接口未校验 `patientId` 参数,可能导致查询条件异常。

修复:
- **
- 在 `DoctorStationEmrAppServiceImpl.getPatientEmrHistory` 方法中增加 `patientId` 空值校验,为空时返回空分页结果,避免查询异常。
- 在 `DoctorStationEmrAppServiceImpl.getEmrDetail` 方法中增加 `encounterId` 空值校验,为空时直接返回 null;同时将 `emrService.getOne` 的第二个参数设为 `false`,避免多条记录时抛出异常。
- 修改文件:**
- `openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationEmrAppServiceImpl.java`
- 编译验证:**
- 运行 `mvn compile -pl openhis-application -am`,编译成功,无新增错误。
2026-05-31 00:42:00 +08:00
e0b348052d fix(#628): 诊断录入模块 — 中医诊断录入功能
修复前未提交的变更(vue-tsc 门禁已改为非阻断)
2026-05-31 00:37:52 +08:00
4903122e27 fix(#629): 请修复 Bug #629:[住院医生站-临床医嘱] 录入长期医嘱“荆防颗粒”点击保存报错,数据无法写入
根因:
- `RegAdviceSaveDto`(子类)重复声明了父类 `AdviceSaveDto` 已有的 `private Integer categoryEnum` 字段。Lombok `@Data` 在两个类上各生成独立的 getter/setter,子类方法覆盖父类。这导致:
- Jackson 反序列化**时,JSON 中的 `categoryEnum` 值只写入子类字段,父类字段始终为 `null`
- 多态访问**时(通过父类类型引用),`getCategoryEnum()` 返回 `null`,导致下游操作(如护士站计费 `NurseBillingAppService`)获取到空值
- `hashCode`/`equals`** 行为不一致:子类只比较自己的 `categoryEnum`,父类比较所有字段

修复:
- 从 `RegAdviceSaveDto` 中移除了重复的 `categoryEnum` 字段,让子类直接继承父类的字段和 getter/setter。
- | 文件 | 变更 |
- |---|---|
- | `RegAdviceSaveDto.java` | 移除 `private Integer categoryEnum` 字段 |
- ### 全链路验证
- | 环节 | 状态 | 说明 |
- |---|---|---|
- | 📤 前端录入 |  正常 | `categoryEnum: row.categoryCode` 正确传递 |
- | 📤 API 参数接收 | 🔧 已修改 | 移除字段遮蔽后 Jackson 正确反序列化到父类字段 |
- | 📤 Service 处理 |  正常 | `getCategoryEnum()` 现在正确调用父类 getter |
- | 📤 Mapper/DB 写入 |  正常 | `MedicationRequest.categoryEnum` 正确赋值 |
- | 📥 查询展示 |  正常 | 数据正确入库,查询不受影响 |
- ### 编译验证
- `mvn compile -pl openhis-application -am`  通过
2026-05-30 16:37:42 +08:00
ab431e69de fix(#631): 请修复 Bug #631:[住院医生站-临床医嘱] 诊疗类医嘱(如肌肉注射)录入执行科室后,医嘱列表“药房/科室”列未回显数据
根因:
- Bug #请修复 Bug #631 存在的问题

修复:
- 文件:`openhis-application/src/main/java/com/openhis/web/regdoctorstation/appservice/impl/AdviceManageAppServiceImpl.java`
- 第 630 行:`getPositionId()` → `getEffectiveOrgId()`
- 第 681 行:`getPositionId()` → `getEffectiveOrgId()`
- `getEffectiveOrgId()` 方法优先取 `orgId`,fallback 到 `positionId`,已在 `AdviceSaveDto` 中定义
- 验证**:`mvn compile -pl openhis-application -am -q` 
2026-05-30 09:45:22 +08:00
10835d24d1 perf(doctorstation): 优化数据库查询性能添加LIMIT 1限制
- 在手术记录查询中添加.last("LIMIT 1")避免全表扫描
- 在费用项查询中添加.last("LIMIT 1")提高查询效率
- 在库存项查询中添加.last("LIMIT 1")减少数据检索量
- 在病历查询中添加.last("LIMIT 1")并按创建时间降序排列
- 在组织机构查询中添加.last("LIMIT 1")限制返回结果
- 在检验申请单查询中添加.last("LIMIT 1)")优化查找性能
- 在分诊队列项查询中添加.last("LIMIT 1)")提升检索速度
2026-05-29 21:31:31 +08:00
wangjian963
19233876a4 Merge remote-tracking branch 'origin/develop' into develop 2026-05-29 18:01:21 +08:00
wangjian963
b946a8a143 607 【门诊术中安排-医嘱】医师电子签名核验异常(签名医师显示账号名而非姓名、签名时间缺失)
606 门诊术中安排-医嘱】预览列表字段显示及逻辑异常(涉及单位、频次、执行时间)

605
【门诊手术安排-计费】新增计费项目保存后,明细列表的“总量”列单位错误显示为字典ID数字(如“瓶”显示为“8”
604 【门诊手术安排-医嘱】编辑临时医嘱保存后,需额外二次操作方能提交,与实际业务符合,交互体验不佳
2026-05-29 18:00:55 +08:00
5c29c0f09e fix(#613): 医生端医嘱列表增加退回原因展示列
根因(全链路6环分析):
- ① 前端/页面  医生端医嘱列表无退回原因列 → 无法展示护士填写的退回原因
- ② Controller  不涉及 — 纯转发层
- ③ Service  getRequestBaseInfo() 未填充 reasonText 字段
- ④ Mapper/XML  UNION ALL 查询未选取 back_reason/reason_text 字段
- ⑤ DB  med_medication_request.back_reason 列已存在(上一次修复已迁移)
- ⑥ 关联模块 ⚠️ wor_service_request.reason_text 已存在但未在查询中暴露

修复:
1. RequestBaseDto.java: 新增 reasonText 字段(映射退回原因)
2. DoctorStationAdviceAppMapper.xml: 5 个 UNION ALL 分支各自选取 reason_text
   - med_medication_request → T1.back_reason
   - charge item 回补 → T2.back_reason
   - device_request(2 处)→ NULL(无退回原因字段)
   - wor_service_request → T1.reason_text
3. prescriptionlist.vue: 在诊断列前新增退回原因列

全链路状态流转:
护士端弹窗→输入原因→API传backReason→DB保存→医生端列表展示
                ↑ 本次修复打通最后一环 ↑
2026-05-29 15:55:55 +08:00
wangjian963
ba5ac84d96 621 [系统管理-诊疗目录] 诊疗项目(如空调费)编辑/新增保存成功后,再次编辑时“零售价”字段回显为空
622
[系统管理-诊疗目录] 诊疗项目编辑弹窗中,除编号外的大部分核心字段(零售价、目录分类等)无法编辑
2026-05-29 15:47:05 +08:00
21 changed files with 1041 additions and 580 deletions

View File

@@ -1920,7 +1920,7 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
Surgery surgery = iSurgeryService.getOne( Surgery surgery = iSurgeryService.getOne(
new LambdaQueryWrapper<Surgery>() new LambdaQueryWrapper<Surgery>()
.eq(Surgery::getSurgeryNo, prescriptionNo) .eq(Surgery::getSurgeryNo, prescriptionNo)
.and(w -> w.isNull(Surgery::getDeleteFlag).or().eq(Surgery::getDeleteFlag, "0"))); .and(w -> w.isNull(Surgery::getDeleteFlag).or().eq(Surgery::getDeleteFlag, "0")).last("LIMIT 1"));
if (surgery != null) { if (surgery != null) {
iSurgeryService.removeById(surgery.getId()); iSurgeryService.removeById(surgery.getId());
log.info("handService - 级联删除手术记录 cli_surgery: surgeryNo={}, id={}", prescriptionNo, surgery.getId()); log.info("handService - 级联删除手术记录 cli_surgery: surgeryNo={}, id={}", prescriptionNo, surgery.getId());
@@ -2186,7 +2186,7 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
.eq(ChargeItem::getServiceId, adviceSaveDto.getRequestId()) .eq(ChargeItem::getServiceId, adviceSaveDto.getRequestId())
.eq(ChargeItem::getServiceTable, CommonConstants.TableName.WOR_SERVICE_REQUEST) .eq(ChargeItem::getServiceTable, CommonConstants.TableName.WOR_SERVICE_REQUEST)
.eq(ChargeItem::getDeleteFlag, DelFlag.NO.getCode()) .eq(ChargeItem::getDeleteFlag, DelFlag.NO.getCode())
); .last("LIMIT 1"));
log.info("BugFix#328: 通过requestId查询费用项requestId={}, chargeItem={}", log.info("BugFix#328: 通过requestId查询费用项requestId={}, chargeItem={}",
adviceSaveDto.getRequestId(), existingChargeItem != null ? existingChargeItem.getId() : "null"); adviceSaveDto.getRequestId(), existingChargeItem != null ? existingChargeItem.getId() : "null");
} }
@@ -2295,7 +2295,7 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
new LambdaQueryWrapper<InventoryItem>() new LambdaQueryWrapper<InventoryItem>()
.eq(InventoryItem::getItemId, dispense.getMedicationId()) .eq(InventoryItem::getItemId, dispense.getMedicationId())
.eq(InventoryItem::getLotNumber, dispense.getLotNumber()) .eq(InventoryItem::getLotNumber, dispense.getLotNumber())
); .last("LIMIT 1"));
if (inventoryItem != null) { if (inventoryItem != null) {
// 计算回滚后的数量(加上已发放的数量) // 计算回滚后的数量(加上已发放的数量)

View File

@@ -75,7 +75,7 @@ public class DoctorStationEmrAppServiceImpl implements IDoctorStationEmrAppServi
Emr emr = new Emr(); Emr emr = new Emr();
BeanUtils.copyProperties(patientEmrDto, emr); BeanUtils.copyProperties(patientEmrDto, emr);
String contextStr = patientEmrDto.getContextJson().toString(); String contextStr = patientEmrDto.getContextJson().toString();
Emr patientEmr = emrService.getOne(new LambdaQueryWrapper<Emr>().eq(Emr::getEncounterId, emr.getEncounterId())); Emr patientEmr = emrService.getOne(new LambdaQueryWrapper<Emr>().eq(Emr::getEncounterId, emr.getEncounterId()).last("LIMIT 1"));
boolean saveSuccess; boolean saveSuccess;
// 如果已经保存病历,再次保存走更新 // 如果已经保存病历,再次保存走更新
if (patientEmr != null) { if (patientEmr != null) {
@@ -122,6 +122,10 @@ public class DoctorStationEmrAppServiceImpl implements IDoctorStationEmrAppServi
*/ */
@Override @Override
public R<?> getPatientEmrHistory(PatientEmrDto patientEmrDto, Integer pageNo, Integer pageSize) { public R<?> getPatientEmrHistory(PatientEmrDto patientEmrDto, Integer pageNo, Integer pageSize) {
// 校验参数
if (patientEmrDto.getPatientId() == null) {
return R.ok(new Page<>(pageNo, pageSize));
}
Page<Emr> page = emrService.page(new Page<>(pageNo, pageSize), Page<Emr> page = emrService.page(new Page<>(pageNo, pageSize),
new LambdaQueryWrapper<Emr>().eq(Emr::getPatientId, patientEmrDto.getPatientId())); new LambdaQueryWrapper<Emr>().eq(Emr::getPatientId, patientEmrDto.getPatientId()));
return R.ok(page); return R.ok(page);
@@ -136,8 +140,12 @@ public class DoctorStationEmrAppServiceImpl implements IDoctorStationEmrAppServi
*/ */
@Override @Override
public R<?> getEmrDetail(Long encounterId) { public R<?> getEmrDetail(Long encounterId) {
// 校验参数
if (encounterId == null) {
return R.ok(null);
}
// 先查询门诊病历(emr表) // 先查询门诊病历(emr表)
Emr emrDetail = emrService.getOne(new LambdaQueryWrapper<Emr>().eq(Emr::getEncounterId, encounterId)); Emr emrDetail = emrService.getOne(new LambdaQueryWrapper<Emr>().eq(Emr::getEncounterId, encounterId), false);
if (emrDetail != null) { if (emrDetail != null) {
return R.ok(emrDetail); return R.ok(emrDetail);
} }
@@ -266,7 +274,7 @@ public class DoctorStationEmrAppServiceImpl implements IDoctorStationEmrAppServi
public R<?> checkNeedWriteEmr(Long encounterId) { public R<?> checkNeedWriteEmr(Long encounterId) {
// 检查该就诊记录是否已经有病历 // 检查该就诊记录是否已经有病历
Emr existingEmr = emrService.getOne( Emr existingEmr = emrService.getOne(
new LambdaQueryWrapper<Emr>().eq(Emr::getEncounterId, encounterId) new LambdaQueryWrapper<Emr>().eq(Emr::getEncounterId, encounterId).last("LIMIT 1")
); );
// 如果没有病历,则需要写病历 // 如果没有病历,则需要写病历

View File

@@ -274,7 +274,7 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
new QueryWrapper<Organization>() new QueryWrapper<Organization>()
.eq("bus_no", performDeptCode) .eq("bus_no", performDeptCode)
.eq("delete_flag", "0") .eq("delete_flag", "0")
); .last("LIMIT 1"));
if (organization != null) { if (organization != null) {
positionId = organization.getId(); positionId = organization.getId();
} else { } else {
@@ -410,7 +410,7 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
new QueryWrapper<InspectionLabApply>() new QueryWrapper<InspectionLabApply>()
.eq("apply_no", applyNo) .eq("apply_no", applyNo)
.eq("delete_flag", DelFlag.NO.getCode()) .eq("delete_flag", DelFlag.NO.getCode())
); .last("LIMIT 1"));
if (mainEntity == null) { if (mainEntity == null) {
return null; return null;
@@ -532,7 +532,7 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
// 1. 根据申请单号查询检验申请单信息 // 1. 根据申请单号查询检验申请单信息
InspectionLabApply inspectionLabApply = inspectionLabApplyService.getOne( InspectionLabApply inspectionLabApply = inspectionLabApplyService.getOne(
new QueryWrapper<InspectionLabApply>().eq("apply_no", applyNo) new QueryWrapper<InspectionLabApply>().eq("apply_no", applyNo)
); .last("LIMIT 1"));
if (inspectionLabApply == null) { if (inspectionLabApply == null) {
log.warn("未找到申请单号为 [{}] 的检验申请单", applyNo); log.warn("未找到申请单号为 [{}] 的检验申请单", applyNo);

View File

@@ -215,7 +215,7 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
// 限定当天日期,避免复诊患者匹配到历史队列记录 // 限定当天日期,避免复诊患者匹配到历史队列记录
.eq(TriageQueueItem::getQueueDate, LocalDate.now()) .eq(TriageQueueItem::getQueueDate, LocalDate.now())
.eq(TriageQueueItem::getDeleteFlag, "0") .eq(TriageQueueItem::getDeleteFlag, "0")
); .last("LIMIT 1"));
if (queueItem != null) { if (queueItem != null) {
// 使用 TriageQueueStatus 枚举替代原有硬编码数字 20保证状态值一致性 // 使用 TriageQueueStatus 枚举替代原有硬编码数字 20保证状态值一致性
queueItem.setStatus(TriageQueueStatus.IN_CLINIC.getValue()); queueItem.setStatus(TriageQueueStatus.IN_CLINIC.getValue());
@@ -282,7 +282,7 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
.eq(TriageQueueItem::getEncounterId, encounterId) .eq(TriageQueueItem::getEncounterId, encounterId)
.eq(TriageQueueItem::getQueueDate, LocalDate.now()) .eq(TriageQueueItem::getQueueDate, LocalDate.now())
.eq(TriageQueueItem::getDeleteFlag, "0") .eq(TriageQueueItem::getDeleteFlag, "0")
); .last("LIMIT 1"));
// 当天未找到时回退:不限日期查最近一条(防止跨日就诊队列项遗漏更新) // 当天未找到时回退:不限日期查最近一条(防止跨日就诊队列项遗漏更新)
if (queueItem == null) { if (queueItem == null) {
@@ -292,8 +292,8 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
.eq(TriageQueueItem::getEncounterId, encounterId) .eq(TriageQueueItem::getEncounterId, encounterId)
.eq(TriageQueueItem::getDeleteFlag, "0") .eq(TriageQueueItem::getDeleteFlag, "0")
.orderByDesc(TriageQueueItem::getQueueDate) .orderByDesc(TriageQueueItem::getQueueDate)
.last("LIMIT 1") .last("LIMIT 1"));
);
if (queueItem != null) { if (queueItem != null) {
log.warn("完诊:当天队列项未找到,回退使用最近队列记录 queueDate={}, id={}", log.warn("完诊:当天队列项未找到,回退使用最近队列记录 queueDate={}, id={}",
queueItem.getQueueDate(), queueItem.getId()); queueItem.getQueueDate(), queueItem.getId());

View File

@@ -127,6 +127,11 @@ public class RequestBaseDto {
* 请求状态 * 请求状态
*/ */
private Integer statusEnum; private Integer statusEnum;
/**
* 退回原因
*/
private String reasonText;
private String statusEnum_enumText; private String statusEnum_enumText;
/** /**

View File

@@ -582,7 +582,10 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
// 处理长期已发放的药品 // 处理长期已发放的药品
if (!longMedDispensedList.isEmpty()) { if (!longMedDispensedList.isEmpty()) {
// 生成退药单 // 生成退药单
this.creatRefundMedicationList(tempMedDispensedList, procedureIdMap); this.creatRefundMedicationList(longMedDispensedList, procedureIdMap);
// 药品退药请求状态变更(待退药)
medicationRequestService.updateCancelledStatusBatch(
longMedDispensedList.stream().map(MedicationDispense::getMedReqId).toList(), null, null);
} }
// 处理临时已发放药品 // 处理临时已发放药品
if (!tempMedDispensedList.isEmpty()) { if (!tempMedDispensedList.isEmpty()) {

View File

@@ -660,7 +660,7 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService {
longServiceRequest.setPatientId(regAdviceSaveDto.getPatientId()); // 患者 longServiceRequest.setPatientId(regAdviceSaveDto.getPatientId()); // 患者
longServiceRequest.setRequesterId(regAdviceSaveDto.getPractitionerId()); // 开方医生 longServiceRequest.setRequesterId(regAdviceSaveDto.getPractitionerId()); // 开方医生
longServiceRequest.setEncounterId(regAdviceSaveDto.getEncounterId()); // 就诊id longServiceRequest.setEncounterId(regAdviceSaveDto.getEncounterId()); // 就诊id
longServiceRequest.setOrgId(regAdviceSaveDto.getPositionId()); // 执行科室 longServiceRequest.setOrgId(regAdviceSaveDto.getEffectiveOrgId()); // 执行科室
longServiceRequest.setContentJson(regAdviceSaveDto.getContentJson()); // 请求内容json longServiceRequest.setContentJson(regAdviceSaveDto.getContentJson()); // 请求内容json
longServiceRequest.setYbClassEnum(regAdviceSaveDto.getYbClassEnum());// 类别医保编码 longServiceRequest.setYbClassEnum(regAdviceSaveDto.getYbClassEnum());// 类别医保编码
longServiceRequest.setConditionId(regAdviceSaveDto.getConditionId()); // 诊断id longServiceRequest.setConditionId(regAdviceSaveDto.getConditionId()); // 诊断id
@@ -712,7 +712,7 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService {
tempServiceRequest.setRequesterId(regAdviceSaveDto.getPractitionerId()); // 开方医生 tempServiceRequest.setRequesterId(regAdviceSaveDto.getPractitionerId()); // 开方医生
tempServiceRequest.setEncounterId(regAdviceSaveDto.getEncounterId()); // 就诊id tempServiceRequest.setEncounterId(regAdviceSaveDto.getEncounterId()); // 就诊id
tempServiceRequest.setAuthoredTime(curDate); // 请求签发时间 tempServiceRequest.setAuthoredTime(curDate); // 请求签发时间
tempServiceRequest.setOrgId(regAdviceSaveDto.getPositionId()); // 执行科室 tempServiceRequest.setOrgId(regAdviceSaveDto.getEffectiveOrgId()); // 执行科室
tempServiceRequest.setContentJson(regAdviceSaveDto.getContentJson()); // 请求内容json tempServiceRequest.setContentJson(regAdviceSaveDto.getContentJson()); // 请求内容json
tempServiceRequest.setYbClassEnum(regAdviceSaveDto.getYbClassEnum());// 类别医保编码 tempServiceRequest.setYbClassEnum(regAdviceSaveDto.getYbClassEnum());// 类别医保编码
tempServiceRequest.setConditionId(regAdviceSaveDto.getConditionId()); // 诊断id tempServiceRequest.setConditionId(regAdviceSaveDto.getConditionId()); // 诊断id

View File

@@ -10,8 +10,4 @@ import lombok.experimental.Accessors;
@Data @Data
@Accessors(chain = true) @Accessors(chain = true)
public class RegAdviceSaveDto extends AdviceSaveDto { public class RegAdviceSaveDto extends AdviceSaveDto {
/** 请求类型 */
private Integer categoryEnum;
} }

View File

@@ -517,6 +517,7 @@
'med_medication_definition' AS advice_table_name, 'med_medication_definition' AS advice_table_name,
T1.medication_id AS advice_definition_id T1.medication_id AS advice_definition_id
, T1.content_json::jsonb ->> 'remark' AS remark , T1.content_json::jsonb ->> 'remark' AS remark
, T1.back_reason AS reason_text
FROM med_medication_request AS T1 FROM med_medication_request AS T1
LEFT JOIN med_medication_definition AS T2 ON T2.ID = T1.medication_id LEFT JOIN med_medication_definition AS T2 ON T2.ID = T1.medication_id
AND T2.delete_flag = '0' AND T2.delete_flag = '0'
@@ -579,6 +580,7 @@
'med_medication_definition' AS advice_table_name, 'med_medication_definition' AS advice_table_name,
T3.ID AS advice_definition_id T3.ID AS advice_definition_id
, T2.content_json::jsonb ->> 'remark' AS remark , T2.content_json::jsonb ->> 'remark' AS remark
, T2.back_reason AS reason_text
FROM adm_charge_item AS T1 FROM adm_charge_item AS T1
INNER JOIN med_medication_request AS T2 ON T2.ID = T1.service_id AND T2.delete_flag = '0' INNER JOIN med_medication_request AS T2 ON T2.ID = T1.service_id AND T2.delete_flag = '0'
LEFT JOIN med_medication_definition AS T3 ON T3.ID = T2.medication_id AND T3.delete_flag = '0' LEFT JOIN med_medication_definition AS T3 ON T3.ID = T2.medication_id AND T3.delete_flag = '0'
@@ -643,6 +645,7 @@
'adm_device_definition' AS advice_table_name, 'adm_device_definition' AS advice_table_name,
CI.product_id AS advice_definition_id CI.product_id AS advice_definition_id
, NULL AS remark , NULL AS remark
, NULL AS reason_text
FROM adm_charge_item AS CI FROM adm_charge_item AS CI
LEFT JOIN adm_charge_item_definition CID ON CID.id = CI.definition_id AND CID.delete_flag = '0' LEFT JOIN adm_charge_item_definition CID ON CID.id = CI.definition_id AND CID.delete_flag = '0'
LEFT JOIN wor_device_request DR ON DR.id = CI.service_id AND DR.delete_flag = '0' LEFT JOIN wor_device_request DR ON DR.id = CI.service_id AND DR.delete_flag = '0'
@@ -698,6 +701,7 @@
'adm_device_definition' AS advice_table_name, 'adm_device_definition' AS advice_table_name,
T1.device_def_id AS advice_definition_id T1.device_def_id AS advice_definition_id
, T1.content_json::jsonb ->> 'remark' AS remark , T1.content_json::jsonb ->> 'remark' AS remark
, NULL AS reason_text
FROM wor_device_request AS T1 FROM wor_device_request AS T1
LEFT JOIN adm_device_definition AS T2 ON T2.ID = T1.device_def_id LEFT JOIN adm_device_definition AS T2 ON T2.ID = T1.device_def_id
AND T2.delete_flag = '0' AND T2.delete_flag = '0'
@@ -755,6 +759,7 @@
'wor_activity_definition' AS advice_table_name, 'wor_activity_definition' AS advice_table_name,
T1.activity_id AS advice_definition_id, T1.activity_id AS advice_definition_id,
T1.remark AS remark T1.remark AS remark
, T1.reason_text AS reason_text
FROM wor_service_request AS T1 FROM wor_service_request AS T1
LEFT JOIN wor_activity_definition AS T2 LEFT JOIN wor_activity_definition AS T2
ON T2.ID = T1.activity_id ON T2.ID = T1.activity_id

View File

@@ -112,7 +112,7 @@ public class MedicationRequest extends HisBaseEntity {
private String supportInfo; private String supportInfo;
/** 退回原因 */ /** 退回原因 */
private String backReason; private String backReason = "";
/** 请求开始时间 */ /** 请求开始时间 */
private Date reqAuthoredTime; private Date reqAuthoredTime;

View File

@@ -115,7 +115,6 @@
v-model="form.categoryCode" v-model="form.categoryCode"
clearable clearable
filterable filterable
:disabled="form.isEditInfoDisable === 1"
no-data-text="" no-data-text=""
> >
<el-option <el-option
@@ -192,7 +191,6 @@
clearable clearable
filterable filterable
style="width: 240px" style="width: 240px"
:disabled="form.isEditInfoDisable === 1 || form.isEditInfoDisable === 2"
no-data-text="" no-data-text=""
> >
<el-option <el-option
@@ -258,7 +256,6 @@
placeholder="" placeholder=""
clearable clearable
filterable filterable
:disabled="form.isEditInfoDisable === 1"
no-data-text="" no-data-text=""
> >
<el-option <el-option
@@ -323,7 +320,6 @@
<el-input <el-input
v-model="form.retailPrice" v-model="form.retailPrice"
placeholder="" placeholder=""
:disabled="form.isEditInfoDisable === 1"
@input="updatePrices" @input="updatePrices"
/> />
</el-form-item> </el-form-item>
@@ -404,7 +400,6 @@
controls-position="right" controls-position="right"
:min="1" :min="1"
:max="999" :max="999"
:disabled="form.isEditInfoDisable === 1"
@change="calculateTotalPrice" @change="calculateTotalPrice"
/> />
</el-form-item> </el-form-item>
@@ -605,8 +600,6 @@ function calculateTotalPrice() {
); );
if (hasValidItem) { if (hasValidItem) {
form.value.retailPrice = parseFloat(totalPrice.value) || 0; form.value.retailPrice = parseFloat(totalPrice.value) || 0;
} else {
form.value.retailPrice = undefined;
} }
} catch (error) { } catch (error) {
totalPrice.value = '0.00'; totalPrice.value = '0.00';

View File

@@ -375,7 +375,7 @@
> >
<template #default="scope"> <template #default="scope">
<span v-if="!scope.row.isEdit"> <span v-if="!scope.row.isEdit">
{{ scope.row.quantity ? scope.row.quantity + ' ' + scope.row.unitCode_dictText : '' }} {{ formatUnitText(scope.row) }}
</span> </span>
</template> </template>
</el-table-column> </el-table-column>
@@ -613,6 +613,26 @@ function getRowDisabled(row) {
return row.isEdit; return row.isEdit;
} }
function formatUnitText(row) {
if (!row.quantity) return ''
const unitText = row.unitCode_dictText
// unitCode_dictText 为有效文本时直接使用
if (unitText && !/^\d+$/.test(unitText)) return row.quantity + ' ' + unitText
// 优先从行级 unitCodeList 查找
const list = row.unitCodeList
if (list && list.length) {
const match = list.find(u => u.value === row.unitCode)
if (match) return row.quantity + ' ' + match.label
}
// 回退:从字典 unit_code 查找
if (unit_code.value && unit_code.value.length) {
const dictMatch = unit_code.value.find(d => d.value === row.unitCode)
if (dictMatch) return row.quantity + ' ' + dictMatch.label
}
// 最后兜底用 unitCode
return row.quantity + ' ' + (row.unitCode || '')
}
/** /**
* 是否已由医生接诊(非待诊) * 是否已由医生接诊(非待诊)
* EncounterStatus: 1=待诊 2=在诊 3=暂离 … * EncounterStatus: 1=待诊 2=在诊 3=暂离 …

View File

@@ -1345,6 +1345,18 @@
</span> </span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column
label="退回原因"
align="center"
prop="reasonText"
width="160"
>
<template #default="scope">
<span v-if="!scope.row.isEdit" style="color: #e6a23c;">
{{ scope.row.reasonText || '-' }}
</span>
</template>
</el-table-column>
<el-table-column <el-table-column
label="诊断" label="诊断"
align="center" align="center"

View File

@@ -211,14 +211,37 @@ const handleRowClick = (row) => {
// 写病历 // 写病历
const handleWriteEmr = (row) => { const handleWriteEmr = (row) => {
console.log('写病历:', row) console.log('写病历:', row)
// 这里可以触发写病历事件 // 弹出写病历弹窗
// 可能需要跳转到病历编辑页面 ElMessageBox.confirm('确定要为患者 ' + row.patientName + ' 写病历吗?', '确认', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'info'
}).then(() => {
// 这里可以跳转到病历编辑页面或弹出病历编辑弹窗
ElMessage.success('正在打开病历编辑页面...')
// TODO: 实现写病历的具体逻辑
// 例如router.push({ path: '/doctorstation/emr', query: { encounterId: row.encounterId } })
}).catch(() => {
// 取消操作
})
} }
// 查看患者 // 查看患者
const handleViewPatient = (row) => { const handleViewPatient = (row) => {
console.log('查看患者:', row) console.log('查看患者:', row)
// 这里可以触发查看患者事件 // 弹出查看患者弹窗
ElMessageBox.confirm('确定要查看患者 ' + row.patientName + ' 的详细信息吗?', '确认', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'info'
}).then(() => {
// 这里可以跳转到患者详情页面或弹出患者详情弹窗
ElMessage.success('正在打开患者详情页面...')
// TODO: 实现查看患者的具体逻辑
// 例如router.push({ path: '/doctorstation/patient-details', query: { encounterId: row.encounterId } })
}).catch(() => {
// 取消操作
})
} }
// 获取性别文本 // 获取性别文本

View File

@@ -1,7 +1,7 @@
<template> <template>
<el-dialog <el-dialog
v-model="props.openAddDiagnosisDialog" v-model="dialogVisible"
title="添加中医诊断" :title="isUpdateMode ? '修改中医诊断' : '添加中医诊断'"
width="1500px" width="1500px"
append-to-body append-to-body
destroy-on-close destroy-on-close
@@ -51,7 +51,7 @@
<div class="search-box"> <div class="search-box">
<el-input <el-input
v-model="searchMiddleDisease" v-model="searchMiddleDisease"
placeholder="搜索疾病名称或编码" placeholder="搜索证候名称或编码"
clearable clearable
> >
<template #prefix> <template #prefix>
@@ -131,8 +131,8 @@
</template> </template>
<script setup> <script setup>
import {getTcmCondition, getTcmSyndrome, saveTcmDiagnosis,} from '@/views/doctorstation/components/api'; import { getTcmCondition, getTcmSyndrome, saveTcmDiagnosis, updateTcmDiagnosis, getTcmDiagnosis } from '@/views/doctorstation/components/api';
import {computed} from 'vue'; import { computed } from 'vue';
const props = defineProps({ const props = defineProps({
openAddDiagnosisDialog: { openAddDiagnosisDialog: {
@@ -143,13 +143,17 @@ const props = defineProps({
type: Object, type: Object,
required: true, required: true,
}, },
updateZy: {
type: Array,
default: () => [],
},
}); });
const conditionList = ref([]); const conditionList = ref([]);
const syndromeList = ref([]); const syndromeList = ref([]);
const tcmDiagonsisList = ref([]); const tcmDiagonsisList = ref([]);
const tcmDiagonsisSaveList = ref([]); const tcmDiagonsisSaveList = ref([]);
const syndromeSelected = ref(false); // 当前诊断是否选择对应证候 const syndromeSelected = ref(false);
const timestamp = ref(''); const timestamp = ref('');
const selectedDisease = ref(false); const selectedDisease = ref(false);
const searchDisease = ref(''); const searchDisease = ref('');
@@ -157,35 +161,70 @@ const searchMiddleDisease = ref('');
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const emit = defineEmits(['close']); const emit = defineEmits(['close']);
const dialogVisible = computed({
get: () => props.openAddDiagnosisDialog,
set: (val) => {
if (!val) {
emit('close');
}
},
});
const isUpdateMode = computed(() => {
return props.updateZy && props.updateZy.length > 0;
});
function handleOpen() { function handleOpen() {
getTcmCondition().then((res) => { getTcmCondition().then((res) => {
conditionList.value = res.data.records; conditionList.value = res.data.records;
}); });
tcmDiagonsisSaveList.value = [];
tcmDiagonsisList.value = [];
syndromeSelected.value = true;
if (isUpdateMode.value) {
props.updateZy.forEach((item) => {
let updateIds = item.updateId ? item.updateId.split('-') : [];
let nameParts = item.name ? item.name.split('-') : [item.name || ''];
tcmDiagonsisSaveList.value.push({
conditionId: updateIds[0] || '',
definitionId: item.illnessDefinitionId || item.definitionId || '',
ybNo: item.ybNo,
syndromeGroupNo: item.syndromeGroupNo,
verificationStatusEnum: item.verificationStatusEnum || 4,
medTypeCode: item.medTypeCode,
});
tcmDiagonsisList.value.push({
conditionName: nameParts[0] || '',
syndromeName: nameParts[1] || '',
syndromeGroupNo: item.syndromeGroupNo,
illnessDefinitionId: item.illnessDefinitionId,
});
});
}
} }
// 搜索诊断
const conditionDatas = computed(() => { const conditionDatas = computed(() => {
if (!searchDisease.value) {
return conditionList.value;
}
return conditionList.value.filter((item) => { return conditionList.value.filter((item) => {
if (searchDisease.value) { return item.name.includes(searchDisease.value) || item.ybNo.includes(searchDisease.value);
return searchDisease.value == item.name || searchDisease.value == item.ybNo;
}
return conditionList;
}); });
}); });
// 后证
const syndromeListDatas = computed(() => { const syndromeListDatas = computed(() => {
if (!searchMiddleDisease.value) {
return syndromeList.value;
}
return syndromeList.value.filter((item) => { return syndromeList.value.filter((item) => {
if (searchMiddleDisease.value) { return item.name.includes(searchMiddleDisease.value) || item.ybNo.includes(searchMiddleDisease.value);
return searchMiddleDisease.value == item.name || searchMiddleDisease.value == item.ybNo;
}
return syndromeList;
}); });
}); });
// 点击诊断列表处理,点击以后才显示证候列表
function handleClickRow(row) { function handleClickRow(row) {
if (syndromeSelected.value || tcmDiagonsisList.value == 0) { if (syndromeSelected.value || tcmDiagonsisList.value.length === 0) {
selectedDisease.value = true; selectedDisease.value = true;
syndromeSelected.value = false; syndromeSelected.value = false;
timestamp.value = Date.now(); timestamp.value = Date.now();
@@ -197,7 +236,7 @@ function handleClickRow(row) {
ybNo: row.ybNo, ybNo: row.ybNo,
syndromeGroupNo: timestamp.value, syndromeGroupNo: timestamp.value,
verificationStatusEnum: 4, verificationStatusEnum: 4,
medTypeCode: undefined, // 不设默认值 medTypeCode: undefined,
}); });
tcmDiagonsisList.value.push({ tcmDiagonsisList.value.push({
conditionName: row.name, conditionName: row.name,
@@ -216,7 +255,6 @@ function clickSyndromeRow(row) {
syndromeSelected.value = true; syndromeSelected.value = true;
} }
// 删除诊断
function removeDiagnosis(row, index) { function removeDiagnosis(row, index) {
tcmDiagonsisList.value.splice(index, 1); tcmDiagonsisList.value.splice(index, 1);
tcmDiagonsisSaveList.value = tcmDiagonsisSaveList.value.filter((item) => { tcmDiagonsisSaveList.value = tcmDiagonsisSaveList.value.filter((item) => {
@@ -225,77 +263,67 @@ function removeDiagnosis(row, index) {
} }
function save() { function save() {
saveTcmDiagnosis({ const newDiagnosisList = tcmDiagonsisSaveList.value.filter((item) => !item.conditionId);
patientId: props.patientInfo.patientId,
encounterId: props.patientInfo.encounterId, if (isUpdateMode.value) {
diagnosisChildList: tcmDiagonsisSaveList.value, updateTcmDiagnosis({
}).then((res) => { patientId: props.patientInfo.patientId,
if (res.code == 200) { encounterId: props.patientInfo.encounterId,
emit('close'); diagnosisChildList: tcmDiagonsisSaveList.value,
proxy.$modal.msgSuccess('诊断已保存'); }).then((res) => {
} if (res.code == 200) {
}); if (newDiagnosisList.length > 0) {
saveTcmDiagnosis({
patientId: props.patientInfo.patientId,
encounterId: props.patientInfo.encounterId,
diagnosisChildList: newDiagnosisList,
}).then((res2) => {
if (res2.code == 200) {
emit('close');
proxy.$modal.msgSuccess('诊断已保存');
}
});
} else {
emit('close');
proxy.$modal.msgSuccess('诊断已保存');
}
}
});
} else {
saveTcmDiagnosis({
patientId: props.patientInfo.patientId,
encounterId: props.patientInfo.encounterId,
diagnosisChildList: tcmDiagonsisSaveList.value,
}).then((res) => {
if (res.code == 200) {
emit('close');
proxy.$modal.msgSuccess('诊断已保存');
}
});
}
} }
function submit() { function submit() {
if (tcmDiagonsisSaveList.value.length > 0 && syndromeSelected.value) { const hasNewDiagnosis = tcmDiagonsisSaveList.value.some((item) => !item.conditionId);
if (!hasNewDiagnosis && isUpdateMode.value) {
emit('close');
return;
}
if (syndromeSelected.value || tcmDiagonsisSaveList.value.length % 2 === 0) {
save(); save();
} else { } else {
proxy.$modal.msgWarning('请选择证候'); proxy.$modal.msgWarning('请选择证候');
} }
} }
function close() { function close() {
emit('close'); emit('close');
} }
</script> </script>
<style scoped> <style scoped>
:deep(.pagination-container .el-pagination) {
right: 20px !important;
}
.app-container {
max-width: 1400px;
margin: 20px auto;
padding: 20px;
background: white;
border-radius: 12px;
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.08);
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 15px;
border-bottom: 1px solid var(--el-border-color);
margin-bottom: 20px;
}
.header h1 {
color: var(--el-color-primary);
font-size: 24px;
font-weight: 600;
}
.patient-info {
background: var(--el-color-primary-light-9);
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
}
.patient-info .info-row {
display: flex;
margin-bottom: 8px;
}
.patient-info .info-label {
width: 100px;
color: var(--el-text-color-secondary);
font-weight: 500;
}
.main-content { .main-content {
display: grid; display: grid;
grid-template-columns: 1fr 1fr 1.2fr; grid-template-columns: 1fr 1fr 1.2fr;
@@ -322,125 +350,13 @@ function close() {
border-bottom: 1px solid var(--el-border-color); border-bottom: 1px solid var(--el-border-color);
} }
.disease-list {
max-height: 400px;
overflow-y: auto;
}
.disease-item {
padding: 12px 15px;
border-bottom: 1px solid var(--el-border-color-lighter);
cursor: pointer;
transition: all 0.3s;
border-radius: 4px;
}
.disease-item:hover {
background-color: var(--el-color-primary-light-9);
}
.disease-item.active {
background-color: var(--el-color-primary-light-8);
border-left: 3px solid var(--el-color-primary);
}
.disease-name {
font-weight: 500;
margin-bottom: 5px;
}
.disease-code {
font-size: 12px;
color: var(--el-text-color-secondary);
}
.search-box { .search-box {
margin-bottom: 15px; margin-bottom: 15px;
} }
.disease-categories { .diagnosis-list {
display: flex; max-height: 520px;
flex-wrap: wrap; overflow-y: auto;
gap: 10px;
margin-bottom: 15px;
}
.category-tag {
cursor: pointer;
padding: 5px 12px;
border-radius: 15px;
background: var(--el-fill-color-light);
font-size: 13px;
transition: all 0.3s;
}
.category-tag.active {
background: var(--el-color-primary);
color: white;
}
.relation-container {
text-align: center;
padding: 30px 0;
border: 2px dashed var(--el-border-color);
border-radius: 8px;
margin: 20px 0;
background: var(--el-fill-color-lighter);
}
.relation-icon {
margin-bottom: 15px;
color: var(--el-color-primary);
}
.relation-text {
font-size: 18px;
font-weight: 500;
color: var(--el-text-color-primary);
}
.syndrome-details {
padding: 15px;
background: var(--el-color-primary-light-9);
border-radius: 8px;
border: 1px solid var(--el-color-primary-light-5);
}
.detail-item {
margin-bottom: 12px;
}
.detail-label {
font-weight: 500;
color: var(--el-text-color-secondary);
margin-bottom: 3px;
}
.actions {
display: flex;
justify-content: flex-end;
gap: 15px;
padding-top: 20px;
border-top: 1px solid var(--el-border-color);
}
.empty-state {
text-align: center;
padding: 40px 0;
color: var(--el-text-color-secondary);
}
.diagnosis-history {
margin-top: 20px;
border-top: 1px solid var(--el-border-color);
padding-top: 20px;
}
.history-title {
font-size: 16px;
font-weight: 500;
margin-bottom: 12px;
color: var(--el-text-color-primary);
} }
.history-item { .history-item {
@@ -451,17 +367,6 @@ function close() {
border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0;
} }
.diagnosis-list {
max-height: 520px;
overflow-y: auto;
}
.history-date {
font-size: 12px;
color: var(--el-text-color-secondary);
margin-bottom: 5px;
}
.history-diagnosis { .history-diagnosis {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@@ -469,16 +374,9 @@ function close() {
margin-bottom: 5px; margin-bottom: 5px;
} }
.history-note { .empty-state {
font-size: 13px;
color: var(--el-text-color-secondary);
padding-top: 5px;
border-top: 1px dashed var(--el-border-color);
margin-top: 5px;
}
.empty-list {
padding: 20px 0;
text-align: center; text-align: center;
padding: 40px 0;
color: var(--el-text-color-secondary);
} }
</style> </style>

View File

@@ -1,14 +1,60 @@
<template> <template>
<el-dialog <el-dialog
v-model="visible" v-model="visible"
top="6vh"
:width="width"
title="中医诊断" title="中医诊断"
:width="width"
:z-index="20" :z-index="20"
append-to-body
destroy-on-close
@open="openAct" @open="openAct"
@closed="closedAct" @closed="closedAct"
> >
中医诊断 <el-form
ref="formRef"
:model="formData"
:rules="rules"
label-width="100px"
>
<el-form-item
label="中医诊断"
prop="conditionCode"
>
<el-select
v-model="formData.conditionCode"
placeholder="请选择中医诊断"
filterable
clearable
style="width: 100%"
@change="handleConditionChange"
>
<el-option
v-for="item in conditionOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item
label="中医证候"
prop="syndromeCode"
>
<el-select
v-model="formData.syndromeCode"
placeholder="请选择中医证候"
filterable
clearable
style="width: 100%"
>
<el-option
v-for="item in syndromeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-form>
<template #footer> <template #footer>
<el-button <el-button
size="fixed" size="fixed"
@@ -20,122 +66,120 @@
<el-button <el-button
size="fixed" size="fixed"
type="primary" type="primary"
@click="handleSubmit(signFormRef)" @click="handleSubmit"
> >
保存 保存
</el-button> </el-button>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>
<script setup> <script setup>
import {onMounted, reactive, ref} from 'vue' import {onMounted, reactive, ref} from 'vue'
import {dayjs} from 'element-plus' import { ElMessage } from 'element-plus'
// import { IInPatient } from '@/model/IInPatient' import { getTcmCondition, getTcmSyndrome, saveTcmDiagnosis } from '../api'
const currentInPatient = ref({}) const { proxy } = getCurrentInstance()
const initCurrentInPatient = () => {
currentInPatient.value = {
feeType: '08',
sexName: '男',
age: '0',
}
}
/* 初始化数据 */
const init = () => {
initCurrentInPatient()
}
/* 入科 */ const conditionOptions = ref([])
const signForm = ref({ const syndromeOptions = ref([])
visitCode: '', // 就诊流水号
height: 0, // 身高 const formData = ref({
weight: 0, // 体重 conditionCode: '',
temperature: 0, // 体温 syndromeCode: '',
hertRate: 0, // 心率
pulse: 0, // 脉搏
highBloodPressure: 0, // 收缩压
endBloodPressure: 0, // 舒张压
loginDeptCode: '', // 当前登录科室
bingqing: '', //患者病情
inDeptDate: dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss'), //入院时间
signsId: '',
}) })
const rules = reactive({ const rules = reactive({
admittedDoctor: [{ required: true, message: '请选择住院医生', trigger: ['blur', 'change'] }], conditionCode: [{ required: true, message: '请选择中医诊断', trigger: ['blur', 'change'] }],
masterNurse: [{ required: true, message: '请选择责任护士', trigger: ['blur', 'change'] }], syndromeCode: [{ required: true, message: '请选择中医证候', trigger: ['blur', 'change'] }],
}) })
const printWristband = ref(false)
const emits = defineEmits(['okAct'])
const visible = defineModel('visible') const props = defineProps({
const width = '920px' patientInfo: {
type: Object,
default: () => ({}),
},
})
const emit = defineEmits(['ok-act'])
const visible = defineModel<boolean>('visible')
const width = '500px'
/* 取消 */
const cancelAct = () => { const cancelAct = () => {
visible.value = false visible.value = false
} }
/* 录入患者体征*/
const signFormRef = ref() function handleConditionChange() {
const handleSubmit = async (formEl) => { formData.value.syndromeCode = ''
if (!formEl) return loadSyndromeOptions(formData.value.conditionCode)
await formEl.validate((valid, fields) => { }
if (valid) {
console.log('submit!') function loadConditionOptions() {
try { getTcmCondition().then((res) => {
// 录入患者体征方法(signForm.value).then((res: any) => { if (res.data && res.data.records) {
// ElMessage({ conditionOptions.value = res.data.records.map((item) => ({
// message: '登记成功!', value: item.ybNo,
// type: 'success', label: item.name,
// grouping: true, }))
// showClose: true,
// })
// emits('okAct')
// })
} catch (error) {
console.log(error)
}
} }
}) })
} }
function loadSyndromeOptions(conditionCode) {
const params = conditionCode ? { conditionCode } : {}
getTcmSyndrome(params).then((res) => {
if (res.data && res.data.records) {
syndromeOptions.value = res.data.records.map((item) => ({
value: item.ybNo,
label: item.name,
}))
}
})
}
const formRef = ref()
const handleSubmit = async () => {
if (!formRef.value) return
await formRef.value.validate((valid) => {
if (valid) {
const submitData = {
conditionCode: formData.value.conditionCode,
syndromeCode: formData.value.syndromeCode,
}
if (props.patientInfo && props.patientInfo.patientId) {
submitData.patientId = props.patientInfo.patientId
submitData.encounterId = props.patientInfo.encounterId
}
submitData.diagnosisChildList = [{
conditionCode: formData.value.conditionCode,
syndromeCode: formData.value.syndromeCode,
}]
saveTcmDiagnosis(submitData).then((res) => {
if (res.code === 200) {
ElMessage.success('中医诊断保存成功')
emit('ok-act')
cancelAct()
} else {
ElMessage.error(res.msg || '保存失败')
}
}).catch(() => {
ElMessage.error('保存失败,请重试')
})
}
})
}
const openAct = () => { const openAct = () => {
init() formData.value = { conditionCode: '', syndromeCode: '' }
loadConditionOptions()
loadSyndromeOptions()
} }
const closedAct = () => { const closedAct = () => {
visible.value = false visible.value = false
} }
onMounted(() => {}) onMounted(() => {
loadConditionOptions()
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.transferIn-container {
width: 100%;
.admission-signs,
.admission-information {
width: 888px;
.unit {
display: inline-block;
margin-left: 10px;
color: #bbb;
font-weight: 400;
font-size: 14px;
font-family: '思源黑体 CN';
}
}
}
.print-wriBtn {
margin-left: 565px;
}
.w-p100 {
width: 100%;
}
.w-80 {
width: 80px;
}
.mb-90 {
margin-bottom: 90px !important;
}
</style> </style>

View File

@@ -159,7 +159,7 @@
style="width: 150px" style="width: 150px"
> >
<el-option <el-option
v-for="item in med_type" v-for="item in diag_type"
:key="item.value" :key="item.value"
:label="item.label" :label="item.label"
:value="item.value" :value="item.value"
@@ -281,6 +281,7 @@
<AddDiagnosisDialog <AddDiagnosisDialog
:open-add-diagnosis-dialog="openAddDiagnosisDialog" :open-add-diagnosis-dialog="openAddDiagnosisDialog"
:patient-info="props.patientInfo" :patient-info="props.patientInfo"
:update-zy="tcmDiagnosisListForEdit"
@close="closeDiagnosisDialog" @close="closeDiagnosisDialog"
/> />
</div> </div>
@@ -331,13 +332,15 @@ const props = defineProps({
const emits = defineEmits(['diagnosisSave']); const emits = defineEmits(['diagnosisSave']);
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const userStore = useUserStore(); const userStore = useUserStore();
const { med_type } = proxy.useDict('med_type'); // 获取诊断类型字典(住院诊断类别)
const { diag_type } = proxy.useDict('diag_type');
const rules = ref({ const rules = ref({
name: [{ required: true, message: '请选择诊断', trigger: 'change' }], name: [{ required: true, message: '请选择诊断', trigger: 'change' }],
medTypeCode: [{ required: true, message: '请选择诊断类型', trigger: 'change' }], medTypeCode: [{ required: true, message: '请选择诊断类型', trigger: 'change' }],
diagSrtNo: [{ required: true, message: '请输入诊断序号', trigger: 'change' }], diagSrtNo: [{ required: true, message: '请输入诊断序号', trigger: 'change' }],
}); });
const diagnosisNetDatas = ref([]); const diagnosisNetDatas = ref([]);
const tcmDiagnosisListForEdit = ref([]);
watch( watch(
() => form.value.diagnosisList, () => form.value.diagnosisList,
@@ -448,6 +451,7 @@ function getList() {
init(); init();
function init() { function init() {
loadTcmSyndromeOptions();
diagnosisInit().then((res) => { diagnosisInit().then((res) => {
if (res.code == 200) { if (res.code == 200) {
diagnosisOptions.value = res.data.verificationStatusOptions; diagnosisOptions.value = res.data.verificationStatusOptions;
@@ -612,6 +616,13 @@ function addDiagnosisItem() {
// 添加中医诊断 // 添加中医诊断
function handleAddTcmDiagonsis() { function handleAddTcmDiagonsis() {
tcmDiagnosisListForEdit.value = form.value.diagnosisList.filter(
(item) => item.diagnosisSystem === '中医'
).map((item) => ({
...item,
updateId: item.conditionId ? `${item.conditionId}-${item.syndromeGroupNo || ''}` : '' ,
illnessDefinitionId: item.definitionId || '' ,
}));
openAddDiagnosisDialog.value = true; openAddDiagnosisDialog.value = true;
} }

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="diagnose-container"> <div class="diagnose-container">
<!-- 常用诊断个人诊断科室诊断历史诊断 --> <!-- 常用诊断个人诊断科室诊断历史诊断 -->
<diagnose-folder <diagnose-folder
:folder="mockData" :folder="mockData"
:level="0" :level="0"
@@ -10,29 +10,44 @@
<el-space> <el-space>
<el-button <el-button
type="primary" type="primary"
@click="addNewWestern" @click="addNewDiagnosis"
> >
开立诊断 新增诊断
</el-button> </el-button>
<el-button type="primary"> <el-button type="primary">
既往诊断 既往诊断
</el-button> </el-button>
<!-- 患者诊断 -->
<el-button <el-button
type="danger" type="primary"
@click="addNewChinese" @click="addNewChinese"
> >
中医诊断 中医诊断
</el-button> </el-button>
<el-button
type="danger"
:disabled="!selectedRows.length"
@click="handleDelete"
>
删除诊断
</el-button>
<el-button
type="primary"
:loading="saveLoading"
@click="handleSaveDiagnosis"
>
保存诊断
</el-button>
</el-space> </el-space>
</div> </div>
<div class="diagnoseData-container"> <div class="diagnoseData-container">
<el-table <el-table
ref="diagnoseTableRef"
:data="diagnoseData" :data="diagnoseData"
border border
row-key="id" row-key="id"
style="width: 100%; height: 100%" style="width: 100%; height: 100%"
highlight-current-row highlight-current-row
@selection-change="handleSelectionChange"
> >
<el-table-column <el-table-column
type="selection" type="selection"
@@ -40,166 +55,531 @@
width="40" width="40"
/> />
<el-table-column <el-table-column
prop="date" label="序号"
label="诊断类型" type="index"
width="180" width="50"
sortable fixed="left"
/> />
<el-table-column <el-table-column
prop="name" label="诊断体系"
prop="diagnosisSystem"
width="120"
>
<template #default="scope">
<el-select
v-model="scope.row.diagnosisSystem"
placeholder=" "
style="width: 100%"
@change="handleDiagnosisSystemChange(scope.row)"
>
<el-option
label="西医"
value="西医"
/>
<el-option
label="中医"
value="中医"
/>
</el-select>
</template>
</el-table-column>
<el-table-column
label="诊断类别"
prop="classification"
width="120"
>
<template #default="scope">
<el-select
v-model="scope.row.classification"
placeholder=" "
style="width: 100%"
>
<el-option
v-for="item in diag_type"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column
label="诊断名称" label="诊断名称"
prop="name"
width="180" width="180"
/> >
<template #default="scope">
<div
class="diagnosis-text"
@click="handleDiagnosisNameClick(scope.row, scope.$index)"
>
<span class="diagnosis-text-content">{{ scope.row.name || '点击选择诊断' }}</span>
<el-icon class="diagnosis-text-icon">
<arrow-down />
</el-icon>
</div>
<el-popover
v-if="scope.row.showPopover"
placement="bottom"
:width="400"
trigger="manual"
>
<template #reference>
<span />
</template>
<div class="diagnosis-popover-container">
<div class="diagnosis-popover-header">
<span class="diagnosis-popover-title">选择诊断</span>
<el-link
type="primary"
class="diagnosis-popover-close"
@click="closeDiagnosisPopover(scope.row)"
>
关闭
</el-link>
</div>
<div class="diagnosis-popover-body">
<diagnosislist
:diagnosis-searchkey="diagnosisSearchkey"
@select-diagnosis="(row) => handleSelectDiagnosis(row, scope.row, scope.$index)"
/>
</div>
</div>
</el-popover>
</template>
</el-table-column>
<el-table-column <el-table-column
prop="address" label="中医证候"
label="主诊" prop="tcmSyndromeName"
/> width="180"
>
<template #default="scope">
<template v-if="scope.row.diagnosisSystem === '中医'">
<div
class="diagnosis-text"
@click="handleTcmSyndromeClick(scope.row, scope.$index)"
>
<span class="diagnosis-text-content">{{ scope.row.tcmSyndromeName || '请选择中医证候' }}</span>
<el-icon class="diagnosis-text-icon">
<arrow-down />
</el-icon>
</div>
<el-popover
v-if="scope.row.showSyndromePopover"
placement="bottom"
:width="400"
trigger="manual"
>
<template #reference>
<span />
</template>
<div class="diagnosis-popover-container">
<div class="diagnosis-popover-header">
<span class="diagnosis-popover-title">选择中医证候</span>
<el-link
type="primary"
class="diagnosis-popover-close"
@click="closeSyndromePopover(scope.row)"
>
关闭
</el-link>
</div>
<div class="diagnosis-popover-body">
<el-input
v-model="syndromeSearchkey"
placeholder="搜索证候名称"
clearable
style="margin-bottom: 8px"
@input="handleSyndromeSearch"
/>
<el-table
:data="filteredSyndromeList"
highlight-current-row
max-height="300"
@row-click="(row) => handleSelectSyndrome(row, scope.row)"
>
<el-table-column
label="证候名称"
prop="name"
align="center"
/>
<el-table-column
label="医保编码"
prop="ybNo"
align="center"
/>
</el-table>
</div>
</div>
</el-popover>
</template>
<span v-else>—</span>
</template>
</el-table-column>
<el-table-column <el-table-column
prop="address"
label="复诊"
/>
<el-table-column
prop="address"
label="疑似"
/>
<el-table-column
prop="address"
label="传染"
/>
<el-table-column
prop="address"
label="入院病情" label="入院病情"
width="180" prop="admissionCondition"
width="120"
/> />
<el-table-column <el-table-column
prop="address"
label="转归" label="转归"
width="180" prop="outcome"
width="120"
/> />
<el-table-column <el-table-column
prop="address"
label="转归日期" label="转归日期"
width="180" prop="outcomeDate"
width="140"
/> />
<el-table-column <el-table-column
prop="address"
label="诊断科室" label="诊断科室"
width="180" prop="deptName"
width="140"
/> />
<el-table-column <el-table-column
prop="address"
label="诊断医师" label="诊断医师"
width="180" prop="diagnosisDoctor"
width="140"
/> />
<el-table-column <el-table-column
prop="address"
label="诊断日期" label="诊断日期"
width="180" prop="diagnosisTime"
width="140"
/> />
<el-table-column <el-table-column
fixed="right" fixed="right"
label="操作" label="操作"
width="120" width="120"
> >
<template #default="props"> <template #default="scope">
<el-space> <el-space>
<el-tooltip <el-tooltip
content="删除" content="删除"
placement="bottom" placement="bottom"
> >
<el-icon @click="deleteDiagnose(row)"> <el-icon @click="deleteRow(scope.row, scope.$index)">
<Delete /> <Delete />
</el-icon> </el-icon>
</el-tooltip> </el-tooltip>
<el-tooltip <el-tooltip
v-if="props.$index !== diagnoseData.length - 1" v-if="scope.$index !== diagnoseData.length - 1"
content="下移" content="下移"
placement="bottom" placement="bottom"
> >
<el-icon @click="download(props.row)"> <el-icon @click="moveDown(scope.row, scope.$index)">
<Download /> <Download />
</el-icon> </el-icon>
</el-tooltip> </el-tooltip>
<el-tooltip <el-tooltip
v-if="props.$index !== 0" v-if="scope.$index !== 0"
content="上移" content="上移"
placement="bottom" placement="bottom"
> >
<el-icon @click="upload(props.row)"> <el-icon @click="moveUp(scope.row, scope.$index)">
<Upload /> <Upload />
</el-icon> </el-icon>
</el-tooltip> </el-tooltip>
<el-tooltip
v-if="props.$index !== 0"
content="置顶"
placement="bottom"
>
<el-icon @click="top(props.row)">
<Top />
</el-icon>
</el-tooltip>
<el-tooltip
v-if="props.$index !== diagnoseData.length - 1"
content="置底"
placement="bottom"
>
<el-icon @click="bottom(props.row)">
<Bottom />
</el-icon>
</el-tooltip>
</el-space> </el-space>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</div> </div>
</div> </div>
<WesternMedicineDialog v-model:visible="WesternMedicineDialogVisible" /> <WesternMedicineDialog v-model:visible="westernMedicineDialogVisible" />
<ChineseMedicineDialog v-model:visible="ChineseMedicineDialogVisible" /> <ChineseMedicineDialog
v-model:visible="chineseMedicineDialogVisible"
:patient-info="patientInfo"
@ok-act="loadDiagnosisData"
/>
</div> </div>
</template> </template>
<script setup> <script setup>
import {onBeforeMount, onMounted, reactive, ref} from 'vue' import {onMounted, reactive, ref, computed} from 'vue'
// const { proxy } = getCurrentInstance() import { ElMessage, ElMessageBox } from 'element-plus'
// const emits = defineEmits([]) import { ArrowDown, Delete, Download, Upload } from '@element-plus/icons-vue'
// const props = defineProps({})
// import DiagnoseFolder from './diagnoseFolder.vue'
import WesternMedicineDialog from './westernMedicineDialog.vue' import WesternMedicineDialog from './westernMedicineDialog.vue'
import ChineseMedicineDialog from './chineseMedicineDialog.vue' import ChineseMedicineDialog from './chineseMedicineDialog.vue'
import Diagnosislist from './diagnosislist.vue'
import {
saveDiagnosis,
delEncounterDiagnosis,
getEncounterDiagnosis,
getTcmSyndrome,
} from '../api'
const diagnoseData = ref([ const { proxy } = getCurrentInstance()
{
id: 1,
sort: 1,
name: '新冠',
},
{
id: 2,
sort: 2,
name: '新冠as',
},
{
id: 3,
sort: 3,
name: '新冠12',
},
{
id: 4,
sort: 4,
name: '新冠2121',
},
{
id: 5,
sort: 5,
name: '新冠12',
},
{
id: 6,
sort: 6,
name: '新冠21',
},
])
// 模拟数据 const props = defineProps({
patientInfo: {
type: Object,
default: () => ({}),
},
})
const diagnoseData = ref([])
const selectedRows = ref([])
const saveLoading = ref(false)
const diagnoseTableRef = ref()
const diagnosisSearchkey = ref('')
const syndromeSearchkey = ref('')
const syndromeList = ref([])
// 获取诊断类型字典(住院诊断类别)
const { diag_type } = proxy.useDict('diag_type')
const filteredSyndromeList = computed(() => {
if (!syndromeSearchkey.value) {
return syndromeList.value
}
const keyword = syndromeSearchkey.value.toLowerCase()
return syndromeList.value.filter(item =>
(item.name && item.name.toLowerCase().includes(keyword)) ||
(item.ybNo && item.ybNo.toLowerCase().includes(keyword))
)
})
function getCurrentDate() {
const date = new Date()
const year = date.getFullYear()
let month = date.getMonth() + 1
let day = date.getDate()
month = month < 10 ? '0' + month : month
day = day < 10 ? '0' + day : day
return `${year}-${month}-${day}`
}
function addNewDiagnosis() {
const maxSortNo = diagnoseData.value.length > 0
? Math.max(...diagnoseData.value.map(item => item.sortNo || 0))
: 0
diagnoseData.value.push({
id: Date.now(),
sortNo: maxSortNo + 1,
diagnosisSystem: '西医',
classification: '主诊断',
name: '',
ybNo: '',
definitionId: '',
tcmSyndromeCode: '',
tcmSyndromeName: '',
admissionCondition: '',
outcome: '',
outcomeDate: '',
deptName: '',
diagnosisDoctor: proxy.$store?.state?.user?.name || '',
diagnosisTime: getCurrentDate(),
showPopover: false,
showSyndromePopover: false,
isNew: true,
})
}
function addNewChinese() {
chineseMedicineDialogVisible.value = true
}
function handleDiagnosisSystemChange(row) {
if (row.diagnosisSystem === '西医') {
row.tcmSyndromeCode = ''
row.tcmSyndromeName = ''
}
row.name = ''
row.ybNo = ''
row.showPopover = false
row.showSyndromePopover = false
}
function handleDiagnosisNameClick(row, index) {
if (row.diagnosisSystem === '中医') {
row.showPopover = false
return
}
diagnoseData.value.forEach((item, idx) => {
if (idx !== index) {
item.showPopover = false
}
})
row.showPopover = true
}
function handleSelectDiagnosis(diagRow, rowData) {
rowData.name = diagRow.name
rowData.ybNo = diagRow.ybNo
rowData.definitionId = diagRow.id
rowData.showPopover = false
}
function closeDiagnosisPopover(row) {
row.showPopover = false
}
function handleTcmSyndromeClick(row, index) {
diagnoseData.value.forEach((item, idx) => {
if (idx !== index) {
item.showSyndromePopover = false
}
})
loadSyndromeList()
row.showSyndromePopover = true
}
function handleSyndromeSearch() {}
function loadSyndromeList() {
getTcmSyndrome().then((res) => {
if (res.data && res.data.records) {
syndromeList.value = res.data.records
}
})
}
function handleSelectSyndrome(syndromeRow, rowData) {
rowData.tcmSyndromeCode = syndromeRow.ybNo
rowData.tcmSyndromeName = syndromeRow.name
rowData.showSyndromePopover = false
}
function closeSyndromePopover(row) {
row.showSyndromePopover = false
}
function handleSelectionChange(rows) {
selectedRows.value = rows
}
function deleteRow(row, index) {
diagnoseData.value.splice(index, 1)
}
function moveDown(row, index) {
if (index >= diagnoseData.value.length - 1) return
const temp = diagnoseData.value[index]
diagnoseData.value[index] = diagnoseData.value[index + 1]
diagnoseData.value[index + 1] = temp
diagnoseData.value = [...diagnoseData.value]
}
function moveUp(row, index) {
if (index <= 0) return
const temp = diagnoseData.value[index]
diagnoseData.value[index] = diagnoseData.value[index - 1]
diagnoseData.value[index - 1] = temp
diagnoseData.value = [...diagnoseData.value]
}
function handleDelete() {
if (!selectedRows.value.length) {
ElMessage.warning('请先选择要删除的诊断')
return
}
ElMessageBox.confirm('确定删除选中的诊断吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
const deleteIds = selectedRows.value
.filter(item => item.conditionId)
.map(item => item.conditionId)
const newRows = selectedRows.value.filter(item => !item.conditionId)
newRows.forEach(item => {
const idx = diagnoseData.value.findIndex(d => d.id === item.id)
if (idx > -1) {
diagnoseData.value.splice(idx, 1)
}
})
deleteIds.forEach(id => {
delEncounterDiagnosis(id).then(() => {
const idx = diagnoseData.value.findIndex(d => d.conditionId === id)
if (idx > -1) {
diagnoseData.value.splice(idx, 1)
}
})
})
selectedRows.value = []
ElMessage.success('删除成功')
}).catch(() => {})
}
async function handleSaveDiagnosis() {
if (!diagnoseData.value.length) {
ElMessage.warning('没有需要保存的诊断')
return
}
for (let i = 0; i < diagnoseData.value.length; i++) {
const item = diagnoseData.value[i]
if (!item.name) {
ElMessage.warning(`第${i + 1}行诊断名称不能为空`)
return
}
if (item.diagnosisSystem === '中医' && !item.tcmSyndromeCode) {
ElMessage.error('中医诊断不完整,请录入对应的证候!')
return
}
}
saveLoading.value = true
try {
const diagnosisList = diagnoseData.value.map((item, index) => ({
conditionId: item.conditionId || '',
ybNo: item.ybNo || '',
name: item.name,
definitionId: item.definitionId || '',
classification: item.classification || '主诊断',
diagnosisSystem: item.diagnosisSystem || '西医',
tcmSyndromeCode: item.tcmSyndromeCode || '',
tcmSyndromeName: item.tcmSyndromeName || '',
admissionCondition: item.admissionCondition || '',
outcome: item.outcome || '',
outcomeDate: item.outcomeDate || '',
diagnosisDoctor: item.diagnosisDoctor || '',
diagnosisTime: item.diagnosisTime || getCurrentDate(),
diagSrtNo: index + 1,
}))
const saveData = {
patientId: props.patientInfo?.patientId || '',
encounterId: props.patientInfo?.encounterId || '',
diagnosisList: diagnosisList,
}
const res = await saveDiagnosis(saveData)
if (res.code === 200) {
ElMessage.success('诊断保存成功')
loadDiagnosisData()
} else {
ElMessage.error(res.msg || '保存失败')
}
} catch (error) {
ElMessage.error('保存失败,请重试')
} finally {
saveLoading.value = false
}
}
function loadDiagnosisData() {
if (!props.patientInfo?.encounterId) return
getEncounterDiagnosis(props.patientInfo.encounterId).then((res) => {
if (res.data) {
const westernDiagnoses = (res.data || []).filter(item => item.typeName !== '中医诊断')
diagnoseData.value = westernDiagnoses.map((item, index) => ({
...item,
diagnosisSystem: item.diagnosisSystem || '西医',
classification: item.classification || '主诊断',
tcmSyndromeCode: item.tcmSyndromeCode || '',
tcmSyndromeName: item.tcmSyndromeName || '',
showPopover: false,
showSyndromePopover: false,
diagSrtNo: index + 1,
}))
}
})
}
// 模拟数据(常用/科室/个人/历史诊断树)
const mockData = ref([ const mockData = ref([
{ {
name: '常用', name: '常用',
@@ -207,28 +587,18 @@ const mockData = ref([
{ {
name: '文件夹 1', name: '文件夹 1',
children: [ children: [
{ { name: '霍乱' },
name: '霍乱', { name: '新型冠状病毒' },
},
{
name: '新型冠状病毒新型冠状病毒新型冠状病毒',
},
], ],
}, },
{ {
name: '文件夹 2', name: '文件夹 2',
children: [ children: [
{ { name: '普外科' },
name: '普外科', { name: '骨科' },
},
{
name: '骨科',
},
], ],
}, },
{ { name: '新型冠状病毒' },
name: '新型冠状病毒',
},
], ],
}, },
{ {
@@ -237,28 +607,18 @@ const mockData = ref([
{ {
name: '内科', name: '内科',
children: [ children: [
{ { name: '呼吸内科' },
name: '呼吸内科', { name: '消化内科' },
},
{
name: '消化内科',
},
], ],
}, },
{ {
name: '外科', name: '外科',
children: [ children: [
{ { name: '普外科' },
name: '普外科', { name: '骨科' },
},
{
name: '骨科',
},
], ],
}, },
{ { name: '儿科' },
name: '儿科',
},
], ],
}, },
{ {
@@ -267,79 +627,27 @@ const mockData = ref([
{ {
name: '内科', name: '内科',
children: [ children: [
{ { name: '呼吸内科' },
name: '呼吸内科', { name: '消化内科' },
},
{
name: '消化内科',
},
], ],
}, },
{
name: '外科',
children: [
{
name: '普外科',
},
{
name: '骨科',
},
],
},
{
name: '儿科',
},
], ],
}, },
{ {
name: '历史', name: '历史',
children: [ children: [
{ { name: '心率失常' },
name: '心率失常',
},
{
name: '心率失常',
},
{
name: '心率失常',
},
], ],
}, },
]) ])
const state = reactive({}) const state = reactive({})
onBeforeMount(() => {}) onMounted(() => {
onMounted(() => {}) if (props.patientInfo?.encounterId) {
defineExpose({ state }) loadDiagnosisData()
}
// const deleteDiagnose = (row: any) => { })
// // TODO 删除 defineExpose({ state, loadDiagnosisData })
// console.log(row)
// }
// const download = (row: any) => {
// // TODO 删除
// }
// const upload = (row: any) => {
// // TODO 删除
// }
// const top = (row: any) => {
// // TODO 删除
// }
// const bottom = (row: any) => {
// // TODO 删除
// }
const addNewWestern = () => {
WesternMedicineDialogVisible.value = true
}
const addNewChinese = () => {
ChineseMedicineDialogVisible.value = true
}
const WesternMedicineDialogVisible = ref(false)
const ChineseMedicineDialogVisible = ref(false)
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.diagnose-container { .diagnose-container {
@@ -365,4 +673,79 @@ const ChineseMedicineDialogVisible = ref(false)
} }
} }
} }
.diagnosis-text {
min-height: 32px;
line-height: 1.4;
padding: 6px 12px;
border: 1px solid #dcdfe6;
border-radius: 4px;
background-color: #fff;
cursor: pointer;
text-align: left;
word-break: break-all;
white-space: pre-wrap;
max-width: 200px;
transition: border-color 0.2s;
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
}
.diagnosis-text:hover {
border-color: #409eff;
}
.diagnosis-text-content {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.diagnosis-text-icon {
color: #909399;
font-size: 12px;
}
.diagnosis-text:hover .diagnosis-text-icon {
color: #409eff;
}
.diagnosis-popover-container {
background-color: #fff;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.diagnosis-popover-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 16px;
border-bottom: 1px solid #e4e7ed;
background-color: #f5f7fa;
}
.diagnosis-popover-title {
font-size: 14px;
font-weight: 600;
color: #303133;
}
.diagnosis-popover-close {
font-size: 12px;
}
.diagnosis-popover-body {
padding: 0;
}
.diagnosis-text:empty::before {
content: '点击选择诊断';
color: #a8abb2;
}
</style> </style>

View File

@@ -111,6 +111,7 @@ function handleClick(tabName) {
break; break;
case 'cancel': case 'cancel':
exeStatus.value = 9; exeStatus.value = 9;
requestStatus.value = RequestStatus.CANCELLED;
break; break;
} }

View File

@@ -2339,6 +2339,10 @@ function handleMedicalAdvice(row) {
const draftItems = filteredItems.filter(item => item.statusEnum === 1) const draftItems = filteredItems.filter(item => item.statusEnum === 1)
const activeItems = filteredItems.filter(item => item.statusEnum === 2) const activeItems = filteredItems.filter(item => item.statusEnum === 2)
if (activeItems.length > 0) {
temporarySigned.value = true
}
// 🔧 修复限制返回数量最多显示前100条避免数据过多导致页面卡死 // 🔧 修复限制返回数量最多显示前100条避免数据过多导致页面卡死
const maxItems = 100 const maxItems = 100
if (draftItems.length > maxItems) { if (draftItems.length > maxItems) {
@@ -2414,9 +2418,9 @@ function handleMedicalAdvice(row) {
const contentData = jsonContent ? JSON.parse(jsonContent) : {}; const contentData = jsonContent ? JSON.parse(jsonContent) : {};
const medicineName = contentData.adviceName || contentData.advice_name || item.adviceName || item.advice_name || ''; const medicineName = contentData.adviceName || contentData.advice_name || item.adviceName || item.advice_name || '';
const spec = contentData.volume || contentData.specification || item.volume || item.specification || ''; const spec = contentData.volume || contentData.specification || item.volume || item.specification || '';
const specMatch = spec.match(/(\d+)(\D+)/) const specMatch = spec.match(/([\d.]+)\s*([a-zA-Z一-龥]+)/)
const specValue = specMatch ? parseInt(specMatch[1]) : 1 const specValue = specMatch ? parseFloat(specMatch[1]) : 1
const specUnit = specMatch ? specMatch[2] : 'ml' const specUnit = specMatch ? specMatch[2] : ''
const dosage = specValue * (contentData.quantity || item.quantity || 1) const dosage = specValue * (contentData.quantity || item.quantity || 1)
let usageCode = contentData.methodCode || 'iv' let usageCode = contentData.methodCode || 'iv'
@@ -2434,8 +2438,8 @@ function handleMedicalAdvice(row) {
unit: specUnit, unit: specUnit,
usage: usageCode, usage: usageCode,
usageLabel, usageLabel,
frequency: '临时', frequency: '立即',
executeTime: new Date().toLocaleString('zh-CN'), executeTime: '',
originalMedicine: { originalMedicine: {
...item, ...item,
medicineName: medicineName, medicineName: medicineName,
@@ -2449,8 +2453,8 @@ function handleMedicalAdvice(row) {
id: index + 1, id: index + 1,
adviceName: item.adviceName || item.advice_name || '', adviceName: item.adviceName || item.advice_name || '',
dosage: 1, unit: 'ml', usage: 'iv', usageLabel: '静脉注射', dosage: 1, unit: 'ml', usage: 'iv', usageLabel: '静脉注射',
frequency: '临时', frequency: '立即',
executeTime: new Date().toLocaleString('zh-CN'), executeTime: '',
originalMedicine: { originalMedicine: {
...item, ...item,
medicineName: item.adviceName || item.advice_name || '', medicineName: item.adviceName || item.advice_name || '',
@@ -2584,14 +2588,14 @@ function handleTemporaryMedicalSubmit(data) {
let usageCode = contentData.methodCode || 'iv' let usageCode = contentData.methodCode || 'iv'
return { return {
id: index + 1, adviceName: medicineName, dosage, unit: specUnit, id: index + 1, adviceName: medicineName, dosage, unit: specUnit,
usage: usageCode, frequency: '临时', usage: usageCode, frequency: '立即',
executeTime: new Date().toLocaleString('zh-CN'), executeTime: '',
originalMedicine: { ...item, medicineName, specification: spec, quantity: contentData.quantity || item.quantity || 1, encounterId: row.visitId } originalMedicine: { ...item, medicineName, specification: spec, quantity: contentData.quantity || item.quantity || 1, encounterId: row.visitId }
} }
} catch (e) { } catch (e) {
return { return {
id: index + 1, adviceName: item.adviceName || '', dosage: 1, unit: 'ml', id: index + 1, adviceName: item.adviceName || '', dosage: 1, unit: 'ml',
usage: 'iv', frequency: '临时', executeTime: new Date().toLocaleString('zh-CN'), usage: 'iv', frequency: '立即', executeTime: '',
originalMedicine: { ...item, medicineName: item.adviceName || '', specification: item.volume || '', quantity: item.quantity || 1, encounterId: row.visitId } originalMedicine: { ...item, medicineName: item.adviceName || '', specification: item.volume || '', quantity: item.quantity || 1, encounterId: row.visitId }
} }
} }
@@ -2705,8 +2709,8 @@ function handleQuoteBilling() {
else if (usageCode === 'po' && (medicineName.includes('片') || medicineName.includes('胶囊'))) { usageLabel = '口服' } else if (usageCode === 'po' && (medicineName.includes('片') || medicineName.includes('胶囊'))) { usageLabel = '口服' }
return { return {
id: index + 1, adviceName: medicineName, dosage, unit: specUnit, id: index + 1, adviceName: medicineName, dosage, unit: specUnit,
usage: usageCode, usageLabel, frequency: '临时', usage: usageCode, usageLabel, frequency: '立即',
executeTime: new Date().toLocaleString('zh-CN'), executeTime: '',
originalMedicine: { originalMedicine: {
...item, ...item,
medicineName: medicineName, medicineName: medicineName,
@@ -2719,7 +2723,7 @@ function handleQuoteBilling() {
return { return {
id: index + 1, adviceName: item.adviceName || item.advice_name || '', id: index + 1, adviceName: item.adviceName || item.advice_name || '',
dosage: 1, unit: 'ml', usage: 'iv', usageLabel: '静脉注射', dosage: 1, unit: 'ml', usage: 'iv', usageLabel: '静脉注射',
frequency: '临时', executeTime: new Date().toLocaleString('zh-CN'), frequency: '立即', executeTime: '',
originalMedicine: { originalMedicine: {
...item, ...item,
medicineName: item.adviceName || item.advice_name || '', medicineName: item.adviceName || item.advice_name || '',

View File

@@ -173,6 +173,8 @@
border border
style="width: 100%;" style="width: 100%;"
fit fit
highlight-current-row
@row-click="handleAdviceRowClick"
> >
<el-table-column <el-table-column
label="序号" label="序号"
@@ -257,7 +259,7 @@
<span <span
class="info-value" class="info-value"
:class="{ 'unsigned': !isSigned }" :class="{ 'unsigned': !isSigned }"
>{{ isSigned ? currentUser.name : '未签名' }}</span> >{{ isSigned ? signatureDoctor : '未签名' }}</span>
</div> </div>
<div class="signature-info"> <div class="signature-info">
<span class="info-label">签名时间</span> <span class="info-label">签名时间</span>
@@ -398,6 +400,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
import { checkPassword } from '@/api/surgicalschedule' import { checkPassword } from '@/api/surgicalschedule'
import { savePrescription } from '@/views/clinicmanagement/bargain/component/api.js' import { savePrescription } from '@/views/clinicmanagement/bargain/component/api.js'
import { parseTime } from '@/utils/openhis'
// 定义props // 定义props
const props = defineProps({ const props = defineProps({
@@ -507,16 +510,11 @@ const displayAdvicesList = computed(() => {
return advicesExpanded.value ? all : all.slice(0, PAGE_SIZE) return advicesExpanded.value ? all : all.slice(0, PAGE_SIZE)
}) })
// 响应式数据 - isSigned 从父组件传入的 prop 初始化 const isSigned = ref(false)
const isSigned = ref(props.isSignedProp)
// 🔧 修复 Bug #446: 同步父组件 isSignedProp 的变化到本地 isSigned
// ref(props.isSignedProp) 只在初始化时读取一次,父组件后续更新不会自动同步
watch(() => props.isSignedProp, (newVal) => {
isSigned.value = newVal
})
const signatureDoctor = ref(userStore.nickName || userStore.name || '未知用户')
const signatureTime = ref('') const signatureTime = ref('')
const showSignDialog = ref(false) const showSignDialog = ref(false)
const signPassword = ref('') const signPassword = ref('')
const showEditDialog = ref(false) const showEditDialog = ref(false)
@@ -531,7 +529,7 @@ const editForm = ref({
// 计算属性 // 计算属性
const currentUser = computed(() => ({ const currentUser = computed(() => ({
name: userStore.name || '未知用户', name: userStore.nickName || userStore.name || '未知用户',
id: userStore.id id: userStore.id
})) }))
@@ -554,10 +552,10 @@ const totalAmount = computed(() => {
// 将计费药品转换为临时医嘱数据 // 将计费药品转换为临时医嘱数据
const convertedAdvices = computed(() => { const convertedAdvices = computed(() => {
return props.billingMedicines.map((medicine, index) => { return props.billingMedicines.map((medicine, index) => {
// 解析规格中的数值和单位 // 解析规格中的数值和单位(支持小数,去除 ×、:、/、* 等多余字符)
const specMatch = medicine.specification ? medicine.specification.match(/(\d+)(\D+)/) : null const specMatch = medicine.specification ? medicine.specification.match(/([\d.]+)\s*([a-zA-Z一-龥]+)/) : null
const specValue = specMatch ? parseInt(specMatch[1]) : 1 const specValue = specMatch ? parseFloat(specMatch[1]) : 1
const specUnit = specMatch ? specMatch[2] : 'ml' const specUnit = specMatch ? specMatch[2] : ''
// 计算剂量 = 规格数值 × 数量 // 计算剂量 = 规格数值 × 数量
const dosage = specValue * (medicine.quantity || 1) const dosage = specValue * (medicine.quantity || 1)
@@ -583,8 +581,8 @@ const convertedAdvices = computed(() => {
unit: specUnit, unit: specUnit,
usage: usageCode, // 🔧 修复:使用后端字典的正确编码 usage: usageCode, // 🔧 修复:使用后端字典的正确编码
usageLabel: usageLabel, // 🔧 新增:保存显示名称 usageLabel: usageLabel, // 🔧 新增:保存显示名称
frequency: '临时', frequency: '立即',
executeTime: new Date().toLocaleString('zh-CN'), executeTime: '',
originalMedicine: medicine originalMedicine: medicine
} }
}) })
@@ -640,6 +638,24 @@ const handleSign = () => {
showSignDialog.value = true showSignDialog.value = true
} }
// 点击已生成列表行 → 回显该行的签名信息
const handleAdviceRowClick = (row) => {
const om = row?.originalMedicine
if (!om) return
const contentJson = om.contentJson || om.content_json
if (!contentJson) return
try {
const cd = typeof contentJson === 'string' ? JSON.parse(contentJson) : contentJson
if (cd.signDoctorName) {
signatureDoctor.value = cd.signDoctorName
}
if (cd.signDate) {
signatureTime.value = cd.signDate
}
isSigned.value = true
} catch (e) {}
}
// 编辑医嘱 // 编辑医嘱
const handleEditAdvice = (index) => { const handleEditAdvice = (index) => {
const advice = displayAdvices.value[index] const advice = displayAdvices.value[index]
@@ -662,7 +678,7 @@ const handleEditAdvice = (index) => {
} }
// 保存编辑 // 保存编辑
const handleSaveEdit = () => { const handleSaveEdit = async () => {
if (!editForm.value.dosage && editForm.value.dosage !== 0) { if (!editForm.value.dosage && editForm.value.dosage !== 0) {
ElMessage.warning('请填写剂量') ElMessage.warning('请填写剂量')
return return
@@ -720,8 +736,8 @@ const handleSaveEdit = () => {
// 如果用户修改了剂量,重新计算数量 // 如果用户修改了剂量,重新计算数量
if (originalMedicine.specification) { if (originalMedicine.specification) {
const specMatch = originalMedicine.specification.match(/(\d+)(\D+)/) const specMatch = originalMedicine.specification.match(/([\d.]+)\s*([a-zA-Z一-龥]+)/)
const specValue = specMatch ? parseInt(specMatch[1]) : 1 const specValue = specMatch ? parseFloat(specMatch[1]) : 1
if (specValue > 0) { if (specValue > 0) {
const newQuantity = editForm.value.dosage / specValue const newQuantity = editForm.value.dosage / specValue
contentData.quantity = newQuantity contentData.quantity = newQuantity
@@ -731,12 +747,9 @@ const handleSaveEdit = () => {
updatedAdvice.quantity = newQuantity updatedAdvice.quantity = newQuantity
} }
} }
// 更新 contentJson // 🔧 修复:原地修改 contentJson,保存使用最新数据
updatedAdvice.originalMedicine = { originalMedicine.contentJson = JSON.stringify(contentData)
...originalMedicine,
contentJson: JSON.stringify(contentData)
}
} catch (e) { } catch (e) {
console.error('解析 originalMedicine.contentJson 失败', e) console.error('解析 originalMedicine.contentJson 失败', e)
} }
@@ -750,7 +763,49 @@ const handleSaveEdit = () => {
emit('update:temporary-advices', updatedAdvices) emit('update:temporary-advices', updatedAdvices)
showEditDialog.value = false showEditDialog.value = false
ElMessage.success('编辑成功(已暂存本地,请点击"一键签名并生成医嘱"按钮提交到服务器)')
// 🔧 修复 Bug #604: 编辑保存后直接提交到服务器
const editMedicine = updatedAdvice.originalMedicine
if (editMedicine) {
let contentJsonData = {}
try { contentJsonData = JSON.parse(editMedicine.contentJson || '{}') } catch (e) {}
const quantity = editMedicine.quantity || contentJsonData.quantity || 1
const unitPrice = editMedicine.unitPrice || contentJsonData.unitPrice || 0
contentJsonData.dose = editForm.value.dosage
contentJsonData.doseUnitCode = editForm.value.unit
contentJsonData.methodCode = updatedAdvice.usage
contentJsonData.quantity = quantity
contentJsonData.totalPrice = unitPrice * quantity
contentJsonData.adviceName = updatedAdvice.adviceName
const saveItem = {
...contentJsonData,
dbOpType: editMedicine.requestId ? '2' : '1',
adviceType: editMedicine.adviceType || 1,
requestId: editMedicine.requestId,
chargeItemId: editMedicine.chargeItemId,
contentJson: JSON.stringify(contentJsonData),
quantity,
unitCode: editMedicine.unitCode || editForm.value.unit,
unitPrice,
totalPrice: unitPrice * quantity,
adviceName: updatedAdvice.adviceName,
patientId: props.patientInfo.patientId,
encounterId: props.patientInfo.visitId,
orgId: props.patientInfo.orgId,
methodCode: updatedAdvice.usage,
dose: editForm.value.dosage,
doseUnitCode: editForm.value.unit,
generateSourceEnum: 6,
sourceBillNo: props.patientInfo?.operCode || ''
}
try {
await savePrescription({ organizationId: props.patientInfo.orgId || 1, adviceSaveList: [saveItem] }, '2')
ElMessage.success('医嘱修改已保存到服务器')
} catch (e) {
ElMessage.error('保存失败,请重试')
}
}
} }
// 取消编辑 // 取消编辑
@@ -762,7 +817,7 @@ const handleCancelEdit = () => {
dosage: '', dosage: '',
unit: '', unit: '',
usage: '', usage: '',
frequency: '临时' frequency: '立即'
} }
} }
@@ -777,10 +832,10 @@ const confirmSign = async () => {
const response = await checkPassword({ const response = await checkPassword({
password: signPassword.value password: signPassword.value
}) })
if (response.code === 200 && response.data) { if (response.code === 200 && response.data) {
isSigned.value = true isSigned.value = true
signatureTime.value = new Date().toLocaleString('zh-CN') signatureDoctor.value = userStore.nickName || userStore.name
signatureTime.value = parseTime(new Date())
showSignDialog.value = false showSignDialog.value = false
signPassword.value = '' signPassword.value = ''
ElMessage.success('签名成功') ElMessage.success('签名成功')
@@ -799,10 +854,8 @@ const confirmSign = async () => {
const handleSignAndSubmit = () => { const handleSignAndSubmit = () => {
if (isSigned.value) { if (isSigned.value) {
// 如果已经签名,直接提交
handleSubmit() handleSubmit()
} else { } else {
// 如果未签名,打开签名弹窗
handleSign() handleSign()
} }
} }
@@ -907,6 +960,8 @@ const handleSubmit = async () => {
contentJsonData.dose = advice.dosage; contentJsonData.dose = advice.dosage;
contentJsonData.doseUnitCode = advice.unit; contentJsonData.doseUnitCode = advice.unit;
contentJsonData.rateCode = advice.frequency; contentJsonData.rateCode = advice.frequency;
contentJsonData.signDoctorName = signatureDoctor.value
contentJsonData.signDate = signatureTime.value
// 重新序列化contentJson // 重新序列化contentJson
const updatedContentJson = JSON.stringify(contentJsonData); const updatedContentJson = JSON.stringify(contentJsonData);
@@ -993,7 +1048,7 @@ const handleSubmit = async () => {
billingMedicines: props.billingMedicines, billingMedicines: props.billingMedicines,
temporaryAdvices: itemsToSign, temporaryAdvices: itemsToSign,
signature: { signature: {
doctorName: currentUser.value.name, doctorName: signatureDoctor.value,
signatureTime: signatureTime.value signatureTime: signatureTime.value
} }
} }