Compare commits
38 Commits
zhugeliang
...
9ae9fae2c8
| Author | SHA1 | Date | |
|---|---|---|---|
| 9ae9fae2c8 | |||
| 7374e17f2e | |||
| 6ca467a81a | |||
| d5e2eb6479 | |||
| e877dfd259 | |||
| 60c84b5a8c | |||
| 575e4d6c12 | |||
| 3eb506da2b | |||
| 65a895a8e3 | |||
| c4bfc1bba3 | |||
| f7b1e6589c | |||
| 0d536ea800 | |||
| 254c8d8046 | |||
| 9c1753eb55 | |||
| 0b1882c82a | |||
| 1662db161f | |||
| 848d8e0043 | |||
| 4fdb8dc06d | |||
| da0bb81fdb | |||
| 4bef2498b8 | |||
| d12cde14ba | |||
| 226d3192f1 | |||
| b063a2fb20 | |||
| 4a72fceec2 | |||
| 87bc7e166d | |||
| fb7116cfe1 | |||
| 3eeb9445fd | |||
| 8c6eb1efde | |||
| 7da7ec80aa | |||
| 3b3cb1a39e | |||
| adae04f01f | |||
| e9ac3bbc78 | |||
| a397e10ec7 | |||
| 821737dcc6 | |||
| 201378b1dc | |||
| 41f313cd32 | |||
| 002d7285db | |||
| 3d4259f653 |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,7 +1,7 @@
|
||||
# HealthLink-HIS 代码模块索引
|
||||
|
||||
> 供 LLM 快速定位代码。每个模块列出 Controller → Service → Mapper 关键文件。
|
||||
> 最后更新: 2026-06-13 12:00 (298 个 Controller)
|
||||
> 最后更新: 2026-06-15 06:00 (298 个 Controller)
|
||||
|
||||
## 关键词 → 模块速查
|
||||
|
||||
|
||||
15
MD/bugs/BUG_503_ANALYSIS.md
Normal file
15
MD/bugs/BUG_503_ANALYSIS.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Bug #503 分析报告
|
||||
|
||||
## 基本信息
|
||||
- Bug ID: 503
|
||||
- 标题: 【住院发退药】发药明细与发药汇总单数据触发时机不一致,存在业务脱节风险
|
||||
- 严重程度: 3
|
||||
- 模块:
|
||||
|
||||
## 根因分析
|
||||
(待深入分析)
|
||||
|
||||
## 修复方案
|
||||
(待分析后确定)
|
||||
|
||||
FIXER_ID: guanyu
|
||||
15
MD/bugs/BUG_606_ANALYSIS.md
Normal file
15
MD/bugs/BUG_606_ANALYSIS.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Bug #606 分析报告
|
||||
|
||||
## 基本信息
|
||||
- Bug ID: 606
|
||||
- 标题: 门诊术中安排-医嘱】预览列表字段显示及逻辑异常(涉及单位、频次、执行时间)
|
||||
- 严重程度: 3
|
||||
- 模块:
|
||||
|
||||
## 根因分析
|
||||
(待深入分析)
|
||||
|
||||
## 修复方案
|
||||
(待分析后确定)
|
||||
|
||||
FIXER_ID: zhaoyun
|
||||
15
MD/bugs/BUG_611_ANALYSIS.md
Normal file
15
MD/bugs/BUG_611_ANALYSIS.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Bug #611 分析报告
|
||||
|
||||
## 基本信息
|
||||
- Bug ID: 611
|
||||
- 标题: 【住院护士站-住院记账】“补费”弹窗确认按钮位置过深且未固定,建议将核心操作与汇总信息上移
|
||||
- 严重程度: 3
|
||||
- 模块:
|
||||
|
||||
## 根因分析
|
||||
(待深入分析)
|
||||
|
||||
## 修复方案
|
||||
(待分析后确定)
|
||||
|
||||
FIXER_ID: zhaoyun
|
||||
15
MD/bugs/BUG_613_ANALYSIS.md
Normal file
15
MD/bugs/BUG_613_ANALYSIS.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Bug #613 分析报告
|
||||
|
||||
## 基本信息
|
||||
- Bug ID: 613
|
||||
- 标题: 【医嘱校对/住院医生工作站】医嘱“退回”流程缺失反馈机制:护士端退回无原因录入,医生端缺失原因显示
|
||||
- 严重程度: 3
|
||||
- 模块:
|
||||
|
||||
## 根因分析
|
||||
(待深入分析)
|
||||
|
||||
## 修复方案
|
||||
(待分析后确定)
|
||||
|
||||
FIXER_ID: zhaoyun
|
||||
15
MD/bugs/BUG_616_ANALYSIS.md
Normal file
15
MD/bugs/BUG_616_ANALYSIS.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Bug #616 分析报告
|
||||
|
||||
## 基本信息
|
||||
- Bug ID: 616
|
||||
- 标题: 【住院医生工作站-临床医嘱】医嘱录入频次下拉框缺少英文缩写(字典键值)显示,不符合临床书写习惯
|
||||
- 严重程度: 3
|
||||
- 模块:
|
||||
|
||||
## 根因分析
|
||||
(待深入分析)
|
||||
|
||||
## 修复方案
|
||||
(待分析后确定)
|
||||
|
||||
FIXER_ID: zhaoyun
|
||||
15
MD/bugs/BUG_617_ANALYSIS.md
Normal file
15
MD/bugs/BUG_617_ANALYSIS.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Bug #617 分析报告
|
||||
|
||||
## 基本信息
|
||||
- Bug ID: 617
|
||||
- 标题: [住院登记] “费用性质”字段保存逻辑错误(登记选择医保保存后变为全自费)
|
||||
- 严重程度: 3
|
||||
- 模块:
|
||||
|
||||
## 根因分析
|
||||
(待深入分析)
|
||||
|
||||
## 修复方案
|
||||
(待分析后确定)
|
||||
|
||||
FIXER_ID: guanyu
|
||||
15
MD/bugs/BUG_637_ANALYSIS.md
Normal file
15
MD/bugs/BUG_637_ANALYSIS.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Bug #637 分析报告
|
||||
|
||||
## 基本信息
|
||||
- Bug ID: 637
|
||||
- 标题: [住院护士站-体温单] 选中患者后系统上下文不同步,导致无法触发“变更体温单”录入弹窗
|
||||
- 严重程度: 3
|
||||
- 模块:
|
||||
|
||||
## 根因分析
|
||||
(待深入分析)
|
||||
|
||||
## 修复方案
|
||||
(待分析后确定)
|
||||
|
||||
FIXER_ID: zhaoyun
|
||||
15
MD/bugs/BUG_638_ANALYSIS.md
Normal file
15
MD/bugs/BUG_638_ANALYSIS.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Bug #638 分析报告
|
||||
|
||||
## 基本信息
|
||||
- Bug ID: 638
|
||||
- 标题: [分诊排队管理] 智能候选池数据过滤失效,导致跨科室患者数据错误显示
|
||||
- 严重程度: 3
|
||||
- 模块:
|
||||
|
||||
## 根因分析
|
||||
(待深入分析)
|
||||
|
||||
## 修复方案
|
||||
(待分析后确定)
|
||||
|
||||
FIXER_ID: guanyu
|
||||
15
MD/bugs/BUG_643_ANALYSIS.md
Normal file
15
MD/bugs/BUG_643_ANALYSIS.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Bug #643 分析报告
|
||||
|
||||
## 基本信息
|
||||
- Bug ID: 643
|
||||
- 标题: [门诊手术安排-术中医嘱] 删除已生成的临时医嘱提示成功,但点击刷新后医嘱重新出现
|
||||
- 严重程度: 3
|
||||
- 模块:
|
||||
|
||||
## 根因分析
|
||||
(待深入分析)
|
||||
|
||||
## 修复方案
|
||||
(待分析后确定)
|
||||
|
||||
FIXER_ID: zhaoyun
|
||||
15
MD/bugs/BUG_730_ANALYSIS.md
Normal file
15
MD/bugs/BUG_730_ANALYSIS.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Bug #730 分析报告
|
||||
|
||||
## 基本信息
|
||||
- Bug ID: 730
|
||||
- 标题: 【门诊医生工作站】医嘱下的个人组套都是空的删不掉
|
||||
- 严重程度: 3
|
||||
- 模块:
|
||||
|
||||
## 根因分析
|
||||
(待深入分析)
|
||||
|
||||
## 修复方案
|
||||
(待分析后确定)
|
||||
|
||||
FIXER_ID: zhaoyun
|
||||
24
MD/bugs/BUG_751_ANALYSIS.md
Normal file
24
MD/bugs/BUG_751_ANALYSIS.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Bug #751 分析报告
|
||||
|
||||
## 基本信息
|
||||
- Bug ID: 751
|
||||
- 标题: 【门诊医生站-医嘱】点击"新增"医嘱时未展示详细参数编辑面板
|
||||
- 严重程度: 一般
|
||||
- 模块: doctorstation
|
||||
|
||||
## 根因分析
|
||||
**直接原因**:前端"新增医嘱"按钮的点击事件未正确打开参数编辑面板。
|
||||
**涉及文件**:
|
||||
- `healthlink-his-ui/src/views/doctorstation/components/OrderPanel.vue` — 医嘱面板主组件
|
||||
- `healthlink-his-ui/src/views/doctorstation/components/OrderForm.vue` — 医嘱编辑表单
|
||||
|
||||
**修复方案**:
|
||||
1. 检查 OrderPanel.vue 中"新增"按钮的 @click 事件绑定
|
||||
2. 确认 OrderForm 组件是否正确引入和渲染
|
||||
3. 检查 v-if/v-show 条件是否阻止了面板显示
|
||||
|
||||
## 涉及模块
|
||||
- 前端: doctorstation
|
||||
- 后端: 无需修改
|
||||
|
||||
FIXER_ID: zhaoyun
|
||||
15
MD/bugs/BUG_754_ANALYSIS.md
Normal file
15
MD/bugs/BUG_754_ANALYSIS.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Bug #754 分析报告
|
||||
|
||||
## 基本信息
|
||||
- Bug ID: 754
|
||||
- 标题: 【住院医生工作站-临床医嘱】删除“待签发”出院带药医嘱时,系统提示“删除成功”但医嘱状态未变更为“已作废”
|
||||
- 严重程度: 3
|
||||
- 模块:
|
||||
|
||||
## 根因分析
|
||||
(待深入分析)
|
||||
|
||||
## 修复方案
|
||||
(待分析后确定)
|
||||
|
||||
FIXER_ID: zhaoyun
|
||||
15
MD/bugs/BUG_755_ANALYSIS.md
Normal file
15
MD/bugs/BUG_755_ANALYSIS.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Bug #755 分析报告
|
||||
|
||||
## 基本信息
|
||||
- Bug ID: 755
|
||||
- 标题: 【门诊医生工作站】新增医嘱时明明有显示库存数量,但是确无法保存成功,显示无库存
|
||||
- 严重程度: 3
|
||||
- 模块:
|
||||
|
||||
## 根因分析
|
||||
(待深入分析)
|
||||
|
||||
## 修复方案
|
||||
(待分析后确定)
|
||||
|
||||
FIXER_ID: guanyu
|
||||
15
MD/bugs/BUG_756_ANALYSIS.md
Normal file
15
MD/bugs/BUG_756_ANALYSIS.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Bug #756 分析报告
|
||||
|
||||
## 基本信息
|
||||
- Bug ID: 756
|
||||
- 标题: 【门诊医生工作站】在诊断里修改并保存会出现报错:Cannot deserialize value of type `com.core.common.core.domain.entity.SysDictData` from Array value (token `JsonToken.START_ARRAY`) at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: java.util.ArrayList[0])
|
||||
- 严重程度: 3
|
||||
- 模块:
|
||||
|
||||
## 根因分析
|
||||
(待深入分析)
|
||||
|
||||
## 修复方案
|
||||
(待分析后确定)
|
||||
|
||||
FIXER_ID: guanyu
|
||||
32
docs/bug-fixes/bug-644.md
Normal file
32
docs/bug-fixes/bug-644.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Bug #644 修复报告
|
||||
|
||||
## 基本信息
|
||||
- **标题**: Bug #644 测试完成,请验收。提出人: chenxj。
|
||||
- **提出人**: chenxj
|
||||
- **修复时间**: 00:24:37 ~ 00:32:06
|
||||
- **修复耗时**: 347.9s
|
||||
- **Commit**: `bd50c58dd`
|
||||
- **测试结果**: ❌ FAIL
|
||||
|
||||
## 根因分析
|
||||
## 变更摘要
|
||||
|
||||
### 根因分析
|
||||
|
||||
**Issue 1 — 状态不同步**:`getInpatientAdvicePage` 方法中,执行记录(`exePerformRecordList`)的计算被包裹在 `if (exeStatus != null)` 条件内,只有在"医嘱执行"页签(传 `exeStatus` 参数)时才计算。"已校对"页签不传 `exeStatus`,因此执行记录永远不会被
|
||||
|
||||
## 修复文件
|
||||
.../impl/AdviceProcessAppServiceImpl.java | 89 +++++++++++++++-------
|
||||
.../dto/InpatientAdviceDto.java | 3 +
|
||||
|
||||
## 流程时间线
|
||||
| 时间 | 智能体 | 事件 | 状态 | 耗时 |
|
||||
|------|--------|------|------|------|
|
||||
| 00:24:37 | guanyu | fix_start | ⏳ | 0.0s |
|
||||
| 00:25:39 | guanyu | fix_retry | ❓ | 0.0s |
|
||||
| 00:32:06 | guanyu | fix_done | ✅ | 347.9s |
|
||||
| 00:32:09 | zhugeliang | analyze_done | ✅ | 0.0s |
|
||||
| 00:32:11 | chenlin | doc_done | ✅ | <1s |
|
||||
|
||||
## 全流程
|
||||
诸葛亮分析 → guanyu 修复 → 张飞测试 → 华佗验收 → 陈琳归档
|
||||
@@ -1,6 +1,6 @@
|
||||
# Web Layer - API Controllers
|
||||
|
||||
**Module**: `openhis-application/web`
|
||||
**Module**: `healthlink-his-application/web`
|
||||
**Role**: API endpoint layer - all REST controllers for frontend communication
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.healthlink.his.web.Inspection.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.Inspection.appservice.ILaboratoryManageAppService;
|
||||
import com.healthlink.his.web.Inspection.dto.ReportResultManageDto;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* 前端 lisPascResult 页面 API 兼容映射
|
||||
* 前端调用 /clinical-manage/laboratory/* 和 /clinical-manage/observation/*
|
||||
* 路由到已有的 /inspection/* 服务
|
||||
*/
|
||||
@RestController
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
@RequestMapping("/clinical-manage/laboratory")
|
||||
public class ClinicalManageLaboratoryController {
|
||||
private final ILaboratoryManageAppService appService;
|
||||
|
||||
@GetMapping("/result-page")
|
||||
public R<?> getResultPage(ReportResultManageDto dto,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "searchKey", required = false) String searchKey,
|
||||
HttpServletRequest request) {
|
||||
return appService.getReportResultList(dto, pageNo, pageSize, searchKey, request);
|
||||
}
|
||||
|
||||
@GetMapping("/result-detail/{id}")
|
||||
public R<?> getResultDetail(@PathVariable Long id) {
|
||||
return appService.getReportById(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.healthlink.his.web.Inspection.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* 前端 lisPascResult 检查结果 API 兼容映射
|
||||
* 后端暂无检查结果独立服务,返回空列表避免前端报错
|
||||
* TODO: 接入检查报告数据源后替换实现
|
||||
*/
|
||||
@RestController
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
@RequestMapping("/clinical-manage/observation")
|
||||
public class ClinicalManageObservationController {
|
||||
|
||||
@GetMapping("/result-page")
|
||||
public R<?> getResultPage(@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||
// 暂时返回空列表,前端可正常渲染
|
||||
return R.ok(new java.util.HashMap<String, Object>() {{
|
||||
put("records", Collections.emptyList());
|
||||
put("total", 0);
|
||||
}});
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,10 @@ import com.healthlink.his.administration.domain.Account;
|
||||
import com.healthlink.his.administration.domain.ChargeItem;
|
||||
import com.healthlink.his.administration.service.IAccountService;
|
||||
import com.healthlink.his.administration.service.IChargeItemService;
|
||||
import com.healthlink.his.check.domain.CheckMethod;
|
||||
import com.healthlink.his.check.domain.CheckPackage;
|
||||
import com.healthlink.his.check.service.ICheckMethodService;
|
||||
import com.healthlink.his.check.service.ICheckPackageService;
|
||||
import com.healthlink.his.check.domain.ExamApply;
|
||||
import com.healthlink.his.check.domain.ExamApplyItem;
|
||||
import com.healthlink.his.check.service.IExamApplyItemService;
|
||||
@@ -71,6 +75,12 @@ public class ExamApplyController extends BaseController {
|
||||
@Autowired
|
||||
private IOrganizationService organizationService;
|
||||
|
||||
@Autowired
|
||||
private ICheckMethodService checkMethodService;
|
||||
|
||||
@Autowired
|
||||
private ICheckPackageService checkPackageService;
|
||||
|
||||
/**
|
||||
* 查询检查申请单列表
|
||||
*/
|
||||
@@ -112,9 +122,9 @@ public class ExamApplyController extends BaseController {
|
||||
BigDecimal totalAmount = BigDecimal.ZERO;
|
||||
|
||||
for (ExamApplyItem item : items) {
|
||||
if (item.getItemFee() != null) {
|
||||
totalAmount = totalAmount.add(item.getItemFee());
|
||||
}
|
||||
BigDecimal itemTotal = item.getItemFee() != null ? item.getItemFee() : BigDecimal.ZERO;
|
||||
BigDecimal methodFee = getMethodAdditionalFee(item.getExamMethodCode());
|
||||
totalAmount = totalAmount.add(itemTotal.add(methodFee));
|
||||
}
|
||||
|
||||
apply.setTotalAmount(totalAmount);
|
||||
@@ -169,6 +179,9 @@ public class ExamApplyController extends BaseController {
|
||||
examApply.setApplyTime(LocalDateTime.now());
|
||||
examApply.setCreateTime(new Date());
|
||||
examApply.setApplyStatus(0); // 0=已开单
|
||||
if (examApply.getIsCharged() == null) examApply.setIsCharged(0);
|
||||
if (examApply.getIsRefunded() == null) examApply.setIsRefunded(0);
|
||||
if (examApply.getIsExecuted() == null) examApply.setIsExecuted(0);
|
||||
|
||||
// 操作员工号取当前登录用户
|
||||
try {
|
||||
@@ -304,10 +317,12 @@ public class ExamApplyController extends BaseController {
|
||||
chargeItem.setProductId(0L); // 产品ID
|
||||
|
||||
// 金额:单价和总价取检查项目费用
|
||||
BigDecimal fee = itemDto.getItemFee() != null ? itemDto.getItemFee() : BigDecimal.ZERO;
|
||||
BigDecimal baseFee = itemDto.getItemFee() != null ? itemDto.getItemFee() : BigDecimal.ZERO;
|
||||
BigDecimal methodFee = getMethodAdditionalFee(itemDto.getExamMethodCode());
|
||||
BigDecimal fee = baseFee.add(methodFee);
|
||||
chargeItem.setQuantityValue(BigDecimal.ONE); // 数量
|
||||
chargeItem.setQuantityUnit("次"); // 单位
|
||||
chargeItem.setUnitPrice(fee); // 单价
|
||||
chargeItem.setUnitPrice(fee); // 单价 = 项目费 + 检查方法附加金额
|
||||
chargeItem.setTotalPrice(fee); // 总价 = 单价 × 1
|
||||
|
||||
// 租户和审计字段
|
||||
@@ -490,7 +505,9 @@ public class ExamApplyController extends BaseController {
|
||||
chargeItem.setProductTable(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION);
|
||||
chargeItem.setProductId(0L);
|
||||
|
||||
BigDecimal fee = itemDto.getItemFee() != null ? itemDto.getItemFee() : BigDecimal.ZERO;
|
||||
BigDecimal baseFee = itemDto.getItemFee() != null ? itemDto.getItemFee() : BigDecimal.ZERO;
|
||||
BigDecimal methodFee = getMethodAdditionalFee(itemDto.getExamMethodCode());
|
||||
BigDecimal fee = baseFee.add(methodFee);
|
||||
chargeItem.setQuantityValue(BigDecimal.ONE);
|
||||
chargeItem.setQuantityUnit("次");
|
||||
chargeItem.setUnitPrice(fee);
|
||||
@@ -548,4 +565,36 @@ public class ExamApplyController extends BaseController {
|
||||
|
||||
return AjaxResult.success("删除/作废成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* Bug #655: 根据检查方法代码查询附加金额(套餐价格)
|
||||
* 查找链路:examMethodCode → CheckMethod → packageName → CheckPackage → packagePrice
|
||||
*/
|
||||
private BigDecimal getMethodAdditionalFee(String examMethodCode) {
|
||||
if (examMethodCode == null || examMethodCode.isEmpty()) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
// 1. 根据 code 查找 CheckMethod
|
||||
CheckMethod method = checkMethodService.getOne(
|
||||
new LambdaQueryWrapper<CheckMethod>()
|
||||
.eq(CheckMethod::getCode, examMethodCode)
|
||||
.last("LIMIT 1"));
|
||||
if (method == null || method.getPackageName() == null || method.getPackageName().isEmpty()) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
// 2. 根据 packageName 查找 CheckPackage(未停用的)
|
||||
CheckPackage pkg = checkPackageService.getOne(
|
||||
new LambdaQueryWrapper<CheckPackage>()
|
||||
.eq(CheckPackage::getPackageName, method.getPackageName())
|
||||
.eq(CheckPackage::getIsDisabled, 0)
|
||||
.last("LIMIT 1"));
|
||||
if (pkg == null || pkg.getPackagePrice() == null || pkg.getPackagePrice().compareTo(BigDecimal.ZERO) <= 0) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
// 3. 仅当套餐价格启用时才累加
|
||||
if (pkg.getPackagePriceEnabled() != null && pkg.getPackagePriceEnabled() == 1) {
|
||||
return pkg.getPackagePrice();
|
||||
}
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +1,132 @@
|
||||
package com.healthlink.his.web.check.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.check.domain.*;
|
||||
import com.healthlink.his.check.service.*;
|
||||
import lombok.AllArgsConstructor;import lombok.extern.slf4j.Slf4j;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;import org.springframework.web.bind.annotation.*;
|
||||
import java.util.*;
|
||||
@RestController @RequestMapping("/radiology-image") @Slf4j @AllArgsConstructor
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/radiology-image")
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class RadiologyImageController {
|
||||
|
||||
private final IRadiologyImageService imageService;
|
||||
private final IRadiologyImageReportService reportService;
|
||||
private final IDicomPrintRecordService printService;
|
||||
// 图像列表
|
||||
|
||||
// ==================== 图像管理 ====================
|
||||
|
||||
/** 图像列表 */
|
||||
@GetMapping("/list")
|
||||
@PreAuthorize("@ss.hasPermi('check:radiologyImage:list')")
|
||||
public R<?> getImageList(@RequestParam("applyId") Long applyId) {
|
||||
LambdaQueryWrapper<RadiologyImage> w = new LambdaQueryWrapper<>();
|
||||
w.eq(RadiologyImage::getApplyId, applyId).orderByAsc(RadiologyImage::getInstanceNumber);
|
||||
w.eq(RadiologyImage::getApplyId, applyId)
|
||||
.orderByAsc(RadiologyImage::getInstanceNumber);
|
||||
return R.ok(imageService.list(w));
|
||||
}
|
||||
@PostMapping("/upload") @Transactional(rollbackFor=Exception.class)
|
||||
public R<?> uploadImage(@RequestBody RadiologyImage img) { img.setCreateTime(new Date()); imageService.save(img); return R.ok(img); }
|
||||
// 图文报告
|
||||
|
||||
/** 上传影像图像 */
|
||||
@PostMapping("/upload")
|
||||
@PreAuthorize("@ss.hasPermi('check:radiologyImage:add')")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> uploadImage(@RequestBody RadiologyImage img) {
|
||||
img.setCreateTime(new Date());
|
||||
imageService.save(img);
|
||||
return R.ok(img);
|
||||
}
|
||||
|
||||
// ==================== 图文报告 ====================
|
||||
|
||||
/** 报告分页查询 */
|
||||
@GetMapping("/report/page")
|
||||
public R<?> getReportPage(@RequestParam(value="status",required=false) String status,
|
||||
@RequestParam(value="patientName",required=false) String patientName,
|
||||
@RequestParam(value="pageNo",defaultValue="1") Integer pageNo,
|
||||
@RequestParam(value="pageSize",defaultValue="20") Integer pageSize) {
|
||||
@PreAuthorize("@ss.hasPermi('check:radiologyImage:report:list')")
|
||||
public R<?> getReportPage(
|
||||
@RequestParam(value = "status", required = false) String status,
|
||||
@RequestParam(value = "patientName", required = false) String patientName,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize) {
|
||||
LambdaQueryWrapper<RadiologyImageReport> w = new LambdaQueryWrapper<>();
|
||||
w.eq(StringUtils.hasText(status), RadiologyImageReport::getStatus, status)
|
||||
.like(StringUtils.hasText(patientName), RadiologyImageReport::getPatientName, patientName)
|
||||
.orderByDesc(RadiologyImageReport::getCreateTime);
|
||||
return R.ok(reportService.page(new Page<>(pageNo, pageSize), w));
|
||||
}
|
||||
@PostMapping("/report/add") @Transactional(rollbackFor=Exception.class)
|
||||
public R<?> addReport(@RequestBody RadiologyImageReport r) { r.setStatus("DRAFT"); r.setCreateTime(new Date()); reportService.save(r); return R.ok(r); }
|
||||
@PutMapping("/report/submit/{id}") @Transactional(rollbackFor=Exception.class)
|
||||
|
||||
/** 新建报告(草稿) */
|
||||
@PostMapping("/report/add")
|
||||
@PreAuthorize("@ss.hasPermi('check:radiologyImage:report:add')")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> addReport(@RequestBody RadiologyImageReport r) {
|
||||
r.setStatus("DRAFT");
|
||||
r.setCreateTime(new Date());
|
||||
reportService.save(r);
|
||||
return R.ok(r);
|
||||
}
|
||||
|
||||
/** 提交报告 */
|
||||
@PutMapping("/report/submit/{id}")
|
||||
@PreAuthorize("@ss.hasPermi('check:radiologyImage:report:edit')")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> submitReport(@PathVariable Long id) {
|
||||
RadiologyImageReport r = reportService.getById(id); if (r == null) return R.fail("报告不存在");
|
||||
r.setStatus("REPORTED"); r.setReportTime(new Date()); reportService.updateById(r); return R.ok();
|
||||
RadiologyImageReport r = reportService.getById(id);
|
||||
if (r == null) {
|
||||
return R.fail("报告不存在");
|
||||
}
|
||||
r.setStatus("REPORTED");
|
||||
r.setReportTime(new Date());
|
||||
reportService.updateById(r);
|
||||
return R.ok();
|
||||
}
|
||||
@PutMapping("/report/verify/{id}") @Transactional(rollbackFor=Exception.class)
|
||||
public R<?> verifyReport(@PathVariable Long id, @RequestParam("doctor") String doctor) {
|
||||
RadiologyImageReport r = reportService.getById(id); if (r == null) return R.fail("报告不存在");
|
||||
r.setStatus("VERIFIED"); r.setVerifyDoctor(doctor); r.setVerifyTime(new Date()); reportService.updateById(r); return R.ok();
|
||||
|
||||
/** 审核报告 */
|
||||
@PutMapping("/report/verify/{id}")
|
||||
@PreAuthorize("@ss.hasPermi('check:radiologyImage:report:edit')")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> verifyReport(@PathVariable Long id,
|
||||
@RequestParam("doctor") String doctor) {
|
||||
RadiologyImageReport r = reportService.getById(id);
|
||||
if (r == null) {
|
||||
return R.fail("报告不存在");
|
||||
}
|
||||
r.setStatus("VERIFIED");
|
||||
r.setVerifyDoctor(doctor);
|
||||
r.setVerifyTime(new Date());
|
||||
reportService.updateById(r);
|
||||
return R.ok();
|
||||
}
|
||||
// DICOM打印
|
||||
@PostMapping("/print") @Transactional(rollbackFor=Exception.class)
|
||||
public R<?> printDicom(@RequestBody DicomPrintRecord p) { p.setPrintTime(new Date()); p.setCreateTime(new Date()); printService.save(p); return R.ok(p); }
|
||||
|
||||
// ==================== DICOM打印 ====================
|
||||
|
||||
/** DICOM打印记录 */
|
||||
@PostMapping("/print")
|
||||
@PreAuthorize("@ss.hasPermi('check:radiologyImage:print:add')")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> printDicom(@RequestBody DicomPrintRecord p) {
|
||||
p.setPrintTime(new Date());
|
||||
p.setCreateTime(new Date());
|
||||
printService.save(p);
|
||||
return R.ok(p);
|
||||
}
|
||||
|
||||
/** 打印记录分页 */
|
||||
@GetMapping("/print/page")
|
||||
public R<?> getPrintPage(@RequestParam(value="pageNo",defaultValue="1") Integer pageNo,
|
||||
@RequestParam(value="pageSize",defaultValue="20") Integer pageSize) {
|
||||
return R.ok(printService.page(new Page<>(pageNo, pageSize), new LambdaQueryWrapper<DicomPrintRecord>().orderByDesc(DicomPrintRecord::getPrintTime)));
|
||||
@PreAuthorize("@ss.hasPermi('check:radiologyImage:print:list')")
|
||||
public R<?> getPrintPage(
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize) {
|
||||
LambdaQueryWrapper<DicomPrintRecord> w = new LambdaQueryWrapper<>();
|
||||
w.orderByDesc(DicomPrintRecord::getPrintTime);
|
||||
return R.ok(printService.page(new Page<>(pageNo, pageSize), w));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,6 +236,9 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
|
||||
encounterDiagnosis.setIptDiseTypeCode(saveDiagnosisChildParam.getIptDiseTypeCode()); // 患者疾病诊断类型代码
|
||||
encounterDiagnosis.setTcmFlag(Whether.YES.getValue());// 中医标识
|
||||
encounterDiagnosis.setSyndromeGroupNo(saveDiagnosisChildParam.getSyndromeGroupNo());// 中医证候组号
|
||||
encounterDiagnosis.setDoctor(saveDiagnosisChildParam.getDiagnosisDoctor()); // 诊断医生
|
||||
encounterDiagnosis.setDiagnosisTime(saveDiagnosisChildParam.getDiagnosisTime()); // 诊断日期
|
||||
encounterDiagnosis.setOnsetDate(saveDiagnosisChildParam.getOnsetDate()); // 发病日期
|
||||
// 设置租户ID,避免数据库约束错误
|
||||
encounterDiagnosis.setTenantId(SecurityUtils.getLoginUser().getTenantId());
|
||||
// 设置创建人,避免数据库约束错误
|
||||
@@ -312,6 +315,9 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
|
||||
encounterDiagnosis.setIptDiseTypeCode(saveDiagnosisChildParam.getIptDiseTypeCode()); // 患者疾病诊断类型代码
|
||||
encounterDiagnosis.setTcmFlag(Whether.YES.getValue());// 中医标识
|
||||
encounterDiagnosis.setSyndromeGroupNo(saveDiagnosisChildParam.getSyndromeGroupNo());// 中医证候组号
|
||||
encounterDiagnosis.setDoctor(saveDiagnosisChildParam.getDiagnosisDoctor()); // 诊断医生
|
||||
encounterDiagnosis.setDiagnosisTime(saveDiagnosisChildParam.getDiagnosisTime()); // 诊断日期
|
||||
encounterDiagnosis.setOnsetDate(saveDiagnosisChildParam.getOnsetDate()); // 发病日期
|
||||
// 设置租户ID,避免数据库约束错误
|
||||
encounterDiagnosis.setTenantId(SecurityUtils.getLoginUser().getTenantId());
|
||||
// 设置创建人,避免数据库约束错误
|
||||
@@ -461,7 +467,7 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
|
||||
}
|
||||
|
||||
if (is_sign) {
|
||||
// 🔧 Bug Fix #668: groupingBy 不接受 null key,先过滤有 groupId 的按组生成处方号
|
||||
// 有 groupId 的按组生成处方号(groupingBy 不接受 null key,先过滤)
|
||||
insertOrUpdateList.stream()
|
||||
.filter(e -> e.getGroupId() != null)
|
||||
.collect(Collectors.groupingBy(AdviceSaveDto::getGroupId))
|
||||
@@ -479,7 +485,7 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
|
||||
}
|
||||
});
|
||||
|
||||
// 🔧 Bug Fix #668: 无 groupId 的各自生成处方号
|
||||
// 无 groupId 的各自生成处方号
|
||||
for (AdviceSaveDto dto : insertOrUpdateList) {
|
||||
if (dto.getGroupId() != null) {
|
||||
continue;
|
||||
|
||||
@@ -165,6 +165,18 @@ public class EmergencyController {
|
||||
@PostMapping("/rescue/add")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> addRescue(@RequestBody EmergencyRescue rescue) {
|
||||
// Bug#743: 修复 patientId 为 null 时数据库 NOT NULL 约束冲突
|
||||
// 如果传了 triageId 但没传 patientId,从分诊记录自动关联患者
|
||||
if (rescue.getPatientId() == null && rescue.getTriageId() != null) {
|
||||
EmergencyTriage triage = triageService.getById(rescue.getTriageId());
|
||||
if (triage != null) {
|
||||
rescue.setPatientId(triage.getPatientId());
|
||||
}
|
||||
}
|
||||
// 校验:patientId 必须存在(数据库 NOT NULL 约束)
|
||||
if (rescue.getPatientId() == null) {
|
||||
return R.fail("患者ID不能为空,请提供患者ID或分诊ID");
|
||||
}
|
||||
rescue.setRescueStart(new Date());
|
||||
rescue.setCreateTime(new Date());
|
||||
rescueService.save(rescue);
|
||||
|
||||
@@ -606,6 +606,7 @@ public class ATDManageAppServiceImpl implements IATDManageAppService {
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> transferDepartment(Long encounterId) {
|
||||
if (encounterId == null) {
|
||||
return R.fail("转科失败,请选择有效的患者");
|
||||
@@ -663,6 +664,7 @@ public class ATDManageAppServiceImpl implements IATDManageAppService {
|
||||
// 更新住院信息
|
||||
encounter.setOrganizationId(orderProcess.getTargetOrganizationId())
|
||||
.setStatusEnum(EncounterZyStatus.REGISTERED.getValue());
|
||||
encounterService.saveOrUpdateEncounter(encounter);
|
||||
return R.ok("转科成功");
|
||||
}
|
||||
|
||||
|
||||
@@ -74,13 +74,6 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"),
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd H:mm:ss"));
|
||||
|
||||
/** Date → "yyyy-MM-dd HH:mm:ss",与前端 formatDateStr 输出格式一致 */
|
||||
private static String formatOccurrenceTime(Date date) {
|
||||
if (date == null) return "";
|
||||
LocalDateTime ldt = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||
return ldt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
}
|
||||
|
||||
@Resource
|
||||
AssignSeqUtil assignSeqUtil;
|
||||
|
||||
@@ -184,33 +177,22 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
// 初始化查询参数
|
||||
String encounterIds = inpatientAdviceParam.getEncounterIds();
|
||||
inpatientAdviceParam.setEncounterIds(null);
|
||||
// Bug #715: 提取therapyEnum手动处理,避免自动条件排除therapy_enum为NULL的耗材医嘱
|
||||
Integer therapyEnum = inpatientAdviceParam.getTherapyEnum();
|
||||
inpatientAdviceParam.setTherapyEnum(null);
|
||||
Integer exeStatus = inpatientAdviceParam.getExeStatus();
|
||||
inpatientAdviceParam.setExeStatus(null);
|
||||
// 提取requestStatus手动处理,支持COMPLETED(3)和CHECK_VERIFIED(10)同时查询
|
||||
Integer requestStatus = inpatientAdviceParam.getRequestStatus();
|
||||
inpatientAdviceParam.setRequestStatus(null);
|
||||
// Bug #714: 提取deadline手动处理,UNION子查询列名为end_time
|
||||
String deadline = inpatientAdviceParam.getDeadline();
|
||||
inpatientAdviceParam.setDeadline(null);
|
||||
// 构建查询条件
|
||||
QueryWrapper<InpatientAdviceParam> queryWrapper
|
||||
= HisQueryUtils.buildQueryWrapper(inpatientAdviceParam, null, null, null);
|
||||
|
||||
// 手动拼接requestStatus条件
|
||||
// COMPLETED(3)时同时包含CHECK_VERIFIED(10)和PENDING_RECEIVE(11)
|
||||
// ACTIVE(2)时同时包含PENDING_STOP(13),以便护士核对停嘱医嘱
|
||||
// 手动拼接requestStatus条件:COMPLETED(3)时同时包含CHECK_VERIFIED(10)和PENDING_RECEIVE(11)
|
||||
// UNION查询外层列名为request_status(T1.status_enum AS request_status),不是status_enum
|
||||
if (requestStatus != null) {
|
||||
if (RequestStatus.COMPLETED.getValue().equals(requestStatus)) {
|
||||
queryWrapper.in("request_status",
|
||||
RequestStatus.COMPLETED.getValue(), RequestStatus.CHECK_VERIFIED.getValue(),
|
||||
RequestStatus.PENDING_RECEIVE.getValue());
|
||||
} else if (RequestStatus.ACTIVE.getValue().equals(requestStatus)) {
|
||||
queryWrapper.in("request_status",
|
||||
RequestStatus.ACTIVE.getValue(), RequestStatus.PENDING_STOP.getValue());
|
||||
} else {
|
||||
queryWrapper.eq("request_status", requestStatus);
|
||||
}
|
||||
@@ -222,24 +204,11 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
= Arrays.stream(encounterIds.split(CommonConstants.Common.COMMA)).map(Long::parseLong).toList();
|
||||
queryWrapper.in(CommonConstants.FieldName.EncounterId, encounterIdList);
|
||||
}
|
||||
// Bug #715: 手动拼接therapyEnum条件,耗材医嘱(DeviceRequest)无therapy_enum(NULL),需兼容
|
||||
if (therapyEnum != null) {
|
||||
queryWrapper.and(w -> w.eq("therapy_enum", therapyEnum).or().isNull("therapy_enum"));
|
||||
}
|
||||
// Bug #714: 手动拼接deadline条件,按医嘱截止时间筛选
|
||||
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) {
|
||||
// 忽略无效的日期格式
|
||||
}
|
||||
}
|
||||
// 患者医嘱分页列表
|
||||
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(), EncounterActivityStatus.ACTIVE.getValue(), LocationForm.BED.getValue(),
|
||||
ParticipantType.ADMITTING_DOCTOR.getCode(), AccountType.PERSONAL_CASH_ACCOUNT.getCode(),
|
||||
ChargeItemStatus.BILLABLE.getValue(), ChargeItemStatus.BILLED.getValue(),
|
||||
@@ -283,16 +252,14 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
e.setTotalAmount(e.getQuantity() + unitStr);
|
||||
}
|
||||
|
||||
// 频次/用法组合(直接使用DictUtils翻译,避免DictAspect延迟导致_dictText为空)
|
||||
String rateLabel = e.getRateCode() != null ? DictUtils.getDictLabel("rate_code", e.getRateCode()) : null;
|
||||
String methodLabel = e.getMethodCode() != null ? DictUtils.getDictLabel("method_code", e.getMethodCode()) : null;
|
||||
// 频次/用法组合
|
||||
StringBuilder freqBuilder = new StringBuilder();
|
||||
if (rateLabel != null && !rateLabel.isEmpty()) {
|
||||
freqBuilder.append(rateLabel);
|
||||
if (e.getRateCode_dictText() != null && !e.getRateCode_dictText().isEmpty()) {
|
||||
freqBuilder.append(e.getRateCode_dictText());
|
||||
}
|
||||
if (methodLabel != null && !methodLabel.isEmpty()) {
|
||||
if (e.getMethodCode_dictText() != null && !e.getMethodCode_dictText().isEmpty()) {
|
||||
if (freqBuilder.length() > 0) freqBuilder.append(" ");
|
||||
freqBuilder.append(methodLabel);
|
||||
freqBuilder.append(e.getMethodCode_dictText());
|
||||
}
|
||||
e.setFrequencyUsage(freqBuilder.length() > 0 ? freqBuilder.toString() : null);
|
||||
|
||||
@@ -354,7 +321,7 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
if (performRecordList != null && !performRecordList.isEmpty()) {
|
||||
// 按时间分组,处理每个时间点的多条记录
|
||||
Map<String, List<PerformRecordDto>> recordsByTime = performRecordList.stream()
|
||||
.collect(Collectors.groupingBy(record -> formatOccurrenceTime(record.getOccurrenceTime())));
|
||||
.collect(Collectors.groupingBy(record -> record.getOccurrenceTime().toString()));
|
||||
for (Map.Entry<String, List<PerformRecordDto>> entry : recordsByTime.entrySet()) {
|
||||
List<PerformRecordDto> records = entry.getValue();
|
||||
// 按操作顺序排序
|
||||
@@ -413,14 +380,17 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
*/
|
||||
@Override
|
||||
public R<?> adviceVerify(List<PerformInfoDto> performInfoList) {
|
||||
// 分别创建两个列表来存储不同类型的请求
|
||||
// 分别创建列表来存储不同类型的请求
|
||||
List<PerformInfoDto> serviceRequestList = new ArrayList<>();
|
||||
List<PerformInfoDto> medRequestList = new ArrayList<>();
|
||||
List<PerformInfoDto> deviceRequestList = new ArrayList<>();
|
||||
for (PerformInfoDto item : performInfoList) {
|
||||
if (CommonConstants.TableName.WOR_SERVICE_REQUEST.equals(item.getRequestTable())) {
|
||||
serviceRequestList.add(item);
|
||||
} else if (CommonConstants.TableName.MED_MEDICATION_REQUEST.equals(item.getRequestTable())) {
|
||||
medRequestList.add(item);
|
||||
} else if (CommonConstants.TableName.WOR_DEVICE_REQUEST.equals(item.getRequestTable())) {
|
||||
deviceRequestList.add(item);
|
||||
}
|
||||
}
|
||||
Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
|
||||
@@ -429,29 +399,10 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
List<Long> serviceReqIds = serviceRequestList.stream().map(PerformInfoDto::getRequestId).toList();
|
||||
// 先查询服务请求,按 categoryEnum 分流:检查类(23)走 CHECK_VERIFIED,其余走 COMPLETED
|
||||
List<ServiceRequest> allServiceRequests = serviceRequestService.listByIds(serviceReqIds);
|
||||
|
||||
// 分离已停嘱(PENDING_STOP)的订单,护士核对后变为已停止(STOPPED)
|
||||
List<ServiceRequest> pendingStopRequests = allServiceRequests.stream()
|
||||
.filter(sr -> RequestStatus.PENDING_STOP.getValue().equals(sr.getStatusEnum()))
|
||||
.toList();
|
||||
List<ServiceRequest> normalRequests = allServiceRequests.stream()
|
||||
.filter(sr -> !RequestStatus.PENDING_STOP.getValue().equals(sr.getStatusEnum()))
|
||||
.toList();
|
||||
|
||||
// 已停嘱订单 → 已停止(STOPPED)
|
||||
if (!pendingStopRequests.isEmpty()) {
|
||||
List<Long> pendingStopIds = pendingStopRequests.stream().map(ServiceRequest::getId).toList();
|
||||
serviceRequestService.update(new LambdaUpdateWrapper<ServiceRequest>()
|
||||
.in(ServiceRequest::getId, pendingStopIds)
|
||||
.set(ServiceRequest::getStatusEnum, RequestStatus.STOPPED.getValue())
|
||||
.set(ServiceRequest::getUpdateBy, SecurityUtils.getNickName()));
|
||||
}
|
||||
|
||||
// 正常订单:检查类 → 已校对(CHECK_VERIFIED=10),其余 → 已完成(COMPLETED=3)
|
||||
List<Long> checkReqIds = normalRequests.stream()
|
||||
List<Long> checkReqIds = allServiceRequests.stream()
|
||||
.filter(sr -> ActivityDefCategory.TEST.getValue().equals(sr.getCategoryEnum()))
|
||||
.map(ServiceRequest::getId).toList();
|
||||
List<Long> otherReqIds = normalRequests.stream()
|
||||
List<Long> otherReqIds = allServiceRequests.stream()
|
||||
.filter(sr -> !ActivityDefCategory.TEST.getValue().equals(sr.getCategoryEnum()))
|
||||
.map(ServiceRequest::getId).toList();
|
||||
// 检查类 → 已校对(CHECK_VERIFIED=10)
|
||||
@@ -463,7 +414,7 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
serviceRequestService.updateCompleteRequestStatus(otherReqIds, practitionerId, checkDate);
|
||||
}
|
||||
// 处理转科/出院等特殊医嘱
|
||||
for (ServiceRequest serviceRequest : normalRequests) {
|
||||
for (ServiceRequest serviceRequest : allServiceRequests) {
|
||||
if (ActivityDefCategory.TRANSFER.getValue().equals(serviceRequest.getCategoryEnum())) {
|
||||
encounterService.updateEncounterStatus(serviceRequest.getEncounterId(),
|
||||
EncounterZyStatus.PENDING_TRANSFER.getValue());
|
||||
@@ -474,30 +425,14 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
}
|
||||
}
|
||||
if (!medRequestList.isEmpty()) {
|
||||
List<Long> medReqIds = medRequestList.stream().map(PerformInfoDto::getRequestId).toList();
|
||||
// 查询药品请求,分离已停嘱(PENDING_STOP)的订单
|
||||
List<MedicationRequest> allMedRequests = medicationRequestService.list(
|
||||
new LambdaQueryWrapper<MedicationRequest>()
|
||||
.select(MedicationRequest::getId, MedicationRequest::getStatusEnum)
|
||||
.in(MedicationRequest::getId, medReqIds));
|
||||
List<Long> pendingStopMedIds = allMedRequests.stream()
|
||||
.filter(mr -> RequestStatus.PENDING_STOP.getValue().equals(mr.getStatusEnum()))
|
||||
.map(MedicationRequest::getId).toList();
|
||||
List<Long> normalMedIds = allMedRequests.stream()
|
||||
.filter(mr -> !RequestStatus.PENDING_STOP.getValue().equals(mr.getStatusEnum()))
|
||||
.map(MedicationRequest::getId).toList();
|
||||
|
||||
// 已停嘱订单 → 已停止(STOPPED)
|
||||
if (!pendingStopMedIds.isEmpty()) {
|
||||
medicationRequestService.update(new LambdaUpdateWrapper<MedicationRequest>()
|
||||
.in(MedicationRequest::getId, pendingStopMedIds)
|
||||
.set(MedicationRequest::getStatusEnum, RequestStatus.STOPPED.getValue())
|
||||
.set(MedicationRequest::getUpdateBy, SecurityUtils.getNickName()));
|
||||
}
|
||||
// 正常订单 → 已完成(COMPLETED)
|
||||
if (!normalMedIds.isEmpty()) {
|
||||
medicationRequestService.updateCompletedStatusBatch(normalMedIds, practitionerId, checkDate);
|
||||
}
|
||||
// 更新药品请求状态已完成
|
||||
medicationRequestService.updateCompletedStatusBatch(
|
||||
medRequestList.stream().map(PerformInfoDto::getRequestId).toList(), practitionerId, checkDate);
|
||||
}
|
||||
if (!deviceRequestList.isEmpty()) {
|
||||
// 更新耗材请求状态已完成
|
||||
deviceRequestService.updateCompletedStatusBatch(
|
||||
deviceRequestList.stream().map(PerformInfoDto::getRequestId).toList());
|
||||
}
|
||||
return R.ok(null, "校对成功");
|
||||
}
|
||||
@@ -510,14 +445,17 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
*/
|
||||
@Override
|
||||
public R<?> adviceReject(List<PerformInfoDto> performInfoList) {
|
||||
// 分别创建两个列表来存储不同类型的请求
|
||||
// 分别创建列表来存储不同类型的请求
|
||||
List<PerformInfoDto> serviceRequestList = new ArrayList<>();
|
||||
List<PerformInfoDto> medRequestList = new ArrayList<>();
|
||||
List<PerformInfoDto> deviceRequestList = new ArrayList<>();
|
||||
for (PerformInfoDto item : performInfoList) {
|
||||
if (CommonConstants.TableName.WOR_SERVICE_REQUEST.equals(item.getRequestTable())) {
|
||||
serviceRequestList.add(item);
|
||||
} else if (CommonConstants.TableName.MED_MEDICATION_REQUEST.equals(item.getRequestTable())) {
|
||||
medRequestList.add(item);
|
||||
} else if (CommonConstants.TableName.WOR_DEVICE_REQUEST.equals(item.getRequestTable())) {
|
||||
deviceRequestList.add(item);
|
||||
}
|
||||
}
|
||||
// 校验医嘱是否已执行,已执行的医嘱需要先取消执行后才能退回
|
||||
@@ -567,6 +505,11 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
medicationRequestService.updateDraftStatusBatch(
|
||||
medRequestList.stream().map(PerformInfoDto::getRequestId).toList(), practitionerId, checkDate, backReason);
|
||||
}
|
||||
if (!deviceRequestList.isEmpty()) {
|
||||
// 更新耗材请求状态待发送
|
||||
deviceRequestService.updateDraftStatusBatch(
|
||||
deviceRequestList.stream().map(PerformInfoDto::getRequestId).toList());
|
||||
}
|
||||
return R.ok(null, "退回成功");
|
||||
}
|
||||
|
||||
@@ -583,25 +526,12 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
Date exeDate = adviceExecuteParam.getExeDate();
|
||||
// 医嘱集合
|
||||
List<AdviceExecuteDetailParam> adviceExecuteDetailList = adviceExecuteParam.getAdviceExecuteDetailList();
|
||||
|
||||
// 前置校验:确保有待执行的医嘱且 executeTimes 不为空
|
||||
if (adviceExecuteDetailList == null || adviceExecuteDetailList.isEmpty()) {
|
||||
return R.fail("未选择需要执行的医嘱");
|
||||
}
|
||||
adviceExecuteDetailList.removeIf(item -> item.getExecuteTimes() == null || item.getExecuteTimes().isEmpty());
|
||||
if (adviceExecuteDetailList.isEmpty()) {
|
||||
return R.fail("所选医嘱没有可执行的时间点,请勾选预计执行时间后再操作");
|
||||
}
|
||||
|
||||
// 药品
|
||||
List<AdviceExecuteDetailParam> medicineList = adviceExecuteDetailList.stream()
|
||||
.filter(e -> CommonConstants.TableName.MED_MEDICATION_REQUEST.equals(e.getAdviceTable())).toList();
|
||||
// 诊疗
|
||||
List<AdviceExecuteDetailParam> activityList = adviceExecuteDetailList.stream()
|
||||
.filter(e -> CommonConstants.TableName.WOR_SERVICE_REQUEST.equals(e.getAdviceTable())).toList();
|
||||
|
||||
int totalCreatedCount = 0;
|
||||
|
||||
// -------------------------------------------药品
|
||||
if (!medicineList.isEmpty()) {
|
||||
// 组装药品请求用于执行的数据结构
|
||||
@@ -614,14 +544,14 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
}
|
||||
}
|
||||
// 处理药品执行
|
||||
totalCreatedCount += this.exeMedication(medUseExeList, exeDate);
|
||||
this.exeMedication(medUseExeList, exeDate);
|
||||
}
|
||||
// -------------------------------------------诊疗
|
||||
if (!activityList.isEmpty()) {
|
||||
// 组装诊疗请求用于执行的数据结构
|
||||
List<ServiceRequestUseExe> actUseExeList = this.assemblyActivity(activityList);
|
||||
// 处理诊疗执行
|
||||
totalCreatedCount += this.exeActivity(actUseExeList, exeDate);
|
||||
this.exeActivity(actUseExeList, exeDate);
|
||||
// 检查类医嘱执行后,状态改为"待接收"(PENDING_RECEIVE=11)
|
||||
List<Long> actReqIds = activityList.stream().map(AdviceExecuteDetailParam::getRequestId).toList();
|
||||
List<ServiceRequest> executedReqs = serviceRequestService.listByIds(actReqIds);
|
||||
@@ -640,11 +570,6 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
}
|
||||
}
|
||||
|
||||
// 后置校验:确认有执行记录被实际创建
|
||||
if (totalCreatedCount == 0) {
|
||||
return R.fail("执行失败,未生成任何执行记录,请检查医嘱状态后重试");
|
||||
}
|
||||
|
||||
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[]{"医嘱执行"}));
|
||||
}
|
||||
|
||||
@@ -655,7 +580,6 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> adviceCancel(AdviceExecuteParam adviceExecuteParam) {
|
||||
// 获取当前执行时间
|
||||
Date exeDate = DateUtils.getNowDate();
|
||||
@@ -702,7 +626,6 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
longMedDispensedList.add(medicationDispense);
|
||||
} else if (DispenseStatus.EXECUTED.getValue().equals(medicationDispense.getStatusEnum())
|
||||
|| DispenseStatus.SUBMITTED.getValue().equals(medicationDispense.getStatusEnum())) {
|
||||
longMedDispensedList.add(medicationDispense);
|
||||
longMedUndispenseList.add(medicationDispense);
|
||||
}
|
||||
}
|
||||
@@ -731,7 +654,6 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
tempMedDispensedList.add(medicationDispense);
|
||||
} else if (DispenseStatus.EXECUTED.getValue().equals(medicationDispense.getStatusEnum())
|
||||
|| DispenseStatus.SUBMITTED.getValue().equals(medicationDispense.getStatusEnum())) {
|
||||
tempMedDispensedList.add(medicationDispense);
|
||||
tempMedUndispenseList.add(medicationDispense);
|
||||
}
|
||||
}
|
||||
@@ -879,7 +801,7 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
if (!longMedUndispenseList.isEmpty()) {
|
||||
// 排除已汇总的药品
|
||||
List<MedicationDispense> medicationDispenseList
|
||||
= longMedUndispenseList.stream().filter(x -> x.getSummaryNo() == null).toList();
|
||||
= tempMedUndispenseList.stream().filter(x -> x.getSummaryNo() == null).toList();
|
||||
medicationDispenseService
|
||||
.removeByIds(medicationDispenseList.stream().map(MedicationDispense::getId).toList());
|
||||
}
|
||||
@@ -949,10 +871,8 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
*
|
||||
* @param medUseExeList 药品医嘱
|
||||
* @param exeDate 实际执行时间
|
||||
* @return 实际创建的执行记录数
|
||||
*/
|
||||
private int exeMedication(List<MedicationRequestUseExe> medUseExeList, Date exeDate) {
|
||||
int createdCount = 0;
|
||||
private void exeMedication(List<MedicationRequestUseExe> medUseExeList, Date exeDate) {
|
||||
// 长期医嘱
|
||||
List<MedicationRequestUseExe> longMedication = medUseExeList.stream()
|
||||
.filter(e -> TherapyTimeType.LONG_TERM.getValue().equals(e.getTherapyEnum())).toList();
|
||||
@@ -975,7 +895,6 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
MedicationRequest longMedicationRequest;
|
||||
ChargeItem chargeItem;
|
||||
for (MedicationRequestUseExe medicationRequestUseExe : longMedication) {
|
||||
if (medicationRequestUseExe.getExecuteTimes() == null) continue;
|
||||
for (String executeTime : medicationRequestUseExe.getExecuteTimes()) {
|
||||
longMedicationRequest = new MedicationRequest();
|
||||
BeanUtils.copyProperties(medicationRequestUseExe, longMedicationRequest);
|
||||
@@ -1005,7 +924,6 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
CommonConstants.TableName.MED_MEDICATION_REQUEST, EventStatus.COMPLETED,
|
||||
ProcedureCategory.INPATIENT_ADVICE, null, expectedDate, exeDate, longMedicationRequest.getGroupId(),
|
||||
null);
|
||||
createdCount++;
|
||||
|
||||
// 医嘱定价来源
|
||||
String orderPricingSource = TenantOptionUtil.getOptionContent(TenantOptionDict.ORDER_PRICING_SOURCE);
|
||||
@@ -1206,7 +1124,6 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
// 临时
|
||||
MedicationRequest tempMedicationRequest;
|
||||
for (MedicationRequestUseExe medicationRequestUseExe : tempMedication) {
|
||||
if (medicationRequestUseExe.getExecuteTimes() == null) continue;
|
||||
for (String executeTime : medicationRequestUseExe.getExecuteTimes()) {
|
||||
tempMedicationRequest = new MedicationRequest();
|
||||
BeanUtils.copyProperties(medicationRequestUseExe, tempMedicationRequest);
|
||||
@@ -1219,7 +1136,6 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
CommonConstants.TableName.MED_MEDICATION_REQUEST, EventStatus.COMPLETED,
|
||||
ProcedureCategory.INPATIENT_ADVICE, null, expectedDate, exeDate, tempMedicationRequest.getGroupId(),
|
||||
null);
|
||||
createdCount++;
|
||||
|
||||
// 更新药品放发状态
|
||||
medicationDispenseService.update(new LambdaUpdateWrapper<MedicationDispense>()
|
||||
@@ -1236,7 +1152,6 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
}
|
||||
}
|
||||
|
||||
return createdCount;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1244,10 +1159,8 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
*
|
||||
* @param actUseExeList 诊疗医嘱
|
||||
* @param exeDate 实际执行时间
|
||||
* @return 实际创建的执行记录数
|
||||
*/
|
||||
private int exeActivity(List<ServiceRequestUseExe> actUseExeList, Date exeDate) {
|
||||
int createdCount = 0;
|
||||
private void exeActivity(List<ServiceRequestUseExe> actUseExeList, Date exeDate) {
|
||||
// 长期医嘱
|
||||
List<ServiceRequestUseExe> longActivity = actUseExeList.stream()
|
||||
.filter(e -> TherapyTimeType.LONG_TERM.getValue().equals(e.getTherapyEnum())).toList();
|
||||
@@ -1272,7 +1185,6 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
ServiceRequest longServiceRequest;
|
||||
ChargeItem chargeItem;
|
||||
for (ServiceRequestUseExe serviceRequestUseExe : longActivity) {
|
||||
if (serviceRequestUseExe.getExecuteTimes() == null) continue;
|
||||
// 查询耗材的取药科室
|
||||
Long takeDeviceLocationId = doctorStationAdviceAppMapper
|
||||
.getTakeDeviceLocationId(serviceRequestUseExe.getEncounterId(), ItemCategoryCode.DEVICE.getCode());
|
||||
@@ -1287,7 +1199,6 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
longServiceRequest.getPatientId(), longServiceRequest.getId(),
|
||||
CommonConstants.TableName.WOR_SERVICE_REQUEST, EventStatus.COMPLETED,
|
||||
ProcedureCategory.INPATIENT_ADVICE, null, expectedDate, exeDate, null, null);
|
||||
createdCount++;
|
||||
|
||||
// 生成账单
|
||||
chargeItem = new ChargeItem();
|
||||
@@ -1345,7 +1256,6 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
// 临时
|
||||
ServiceRequest tempServiceRequest;
|
||||
for (ServiceRequestUseExe serviceRequestUseExe : tempActivity) {
|
||||
if (serviceRequestUseExe.getExecuteTimes() == null) continue;
|
||||
// 查询耗材的取药科室
|
||||
Long takeDeviceLocationId = doctorStationAdviceAppMapper
|
||||
.getTakeDeviceLocationId(serviceRequestUseExe.getEncounterId(), ItemCategoryCode.DEVICE.getCode());
|
||||
@@ -1360,7 +1270,6 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
tempServiceRequest.getPatientId(), tempServiceRequest.getId(),
|
||||
CommonConstants.TableName.WOR_SERVICE_REQUEST, EventStatus.COMPLETED,
|
||||
ProcedureCategory.INPATIENT_ADVICE, null, expectedDate, exeDate, null, null);
|
||||
createdCount++;
|
||||
|
||||
// 更新账单状态
|
||||
chargeItemService.update(
|
||||
@@ -1378,7 +1287,6 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
}
|
||||
}
|
||||
|
||||
return createdCount;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -65,7 +65,8 @@ public interface AdviceProcessAppMapper {
|
||||
Page<InpatientAdviceDto> selectInpatientAdvicePage(@Param("page") Page<InpatientAdviceDto> page,
|
||||
@Param(Constants.WRAPPER) QueryWrapper<InpatientAdviceParam> queryWrapper,
|
||||
@Param("medMedicationRequest") String medMedicationRequest,
|
||||
@Param("worServiceRequest") String worServiceRequest, @Param("draft") Integer draft,
|
||||
@Param("worServiceRequest") String worServiceRequest,
|
||||
@Param("worDeviceRequest") String worDeviceRequest, @Param("draft") Integer draft,
|
||||
@Param("active") Integer active, @Param("bed") Integer bed, @Param("admittingDoctor") String admittingDoctor,
|
||||
@Param("personalCashAccount") String personalCashAccount, @Param("billable") Integer billable,
|
||||
@Param("billed") Integer billed, @Param("refunded") Integer refunded, @Param("imp") Integer imp,
|
||||
|
||||
@@ -72,6 +72,12 @@ public class PathologyController {
|
||||
@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");
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.core.common.core.domain.R;
|
||||
import com.core.common.utils.AssignSeqUtil;
|
||||
import com.core.common.utils.MessageUtils;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import com.healthlink.his.common.constant.CommonConstants;
|
||||
import com.healthlink.his.common.constant.PromptMsgConstant;
|
||||
import com.healthlink.his.common.enums.*;
|
||||
@@ -18,7 +19,13 @@ import com.healthlink.his.web.regdoctorstation.dto.*;
|
||||
import com.healthlink.his.web.regdoctorstation.mapper.SpecialAdviceAppMapper;
|
||||
import com.healthlink.his.workflow.domain.ServiceRequest;
|
||||
import com.healthlink.his.workflow.service.IActivityDefinitionService;
|
||||
import com.healthlink.his.administration.domain.Encounter;
|
||||
import com.healthlink.his.administration.domain.Organization;
|
||||
import com.healthlink.his.administration.service.IEncounterService;
|
||||
import com.healthlink.his.administration.service.IOrganizationService;
|
||||
import com.healthlink.his.workflow.service.IServiceRequestService;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -56,6 +63,12 @@ public class SpecialAdviceAppServiceImpl implements ISpecialAdviceAppService {
|
||||
@Resource
|
||||
IOrderProcessService iOrderProcessService;
|
||||
|
||||
@Resource
|
||||
IEncounterService iEncounterService;
|
||||
|
||||
@Resource
|
||||
IOrganizationService iOrganizationService;
|
||||
|
||||
/**
|
||||
* 查询护理医嘱信息
|
||||
*
|
||||
@@ -351,6 +364,20 @@ public class SpecialAdviceAppServiceImpl implements ISpecialAdviceAppService {
|
||||
AdviceBaseDto activityAdviceBaseDto = iDoctorStationAdviceAppService
|
||||
.getAdviceBaseInfo(adviceBaseDto, null, null, null, null, 1, 1, null, List.of(3), null, null, null)
|
||||
.getRecords().get(0);
|
||||
// 查询患者当前科室(从就诊记录获取)
|
||||
Encounter encounter = iEncounterService.getById(encounterId);
|
||||
Long currentOrgId = encounter != null ? encounter.getOrganizationId() : activityAdviceBaseDto.getPositionId();
|
||||
|
||||
// 查询转入科室名称,用于医嘱名称拼接
|
||||
String targetOrgName = "";
|
||||
Long targetOrgId = transferOrganizationParam.getTargetOrganizationId();
|
||||
if (targetOrgId != null) {
|
||||
Organization targetOrg = iOrganizationService.getById(targetOrgId);
|
||||
if (targetOrg != null && StringUtils.isNotEmpty(targetOrg.getName())) {
|
||||
targetOrgName = targetOrg.getName();
|
||||
}
|
||||
}
|
||||
|
||||
// 保存转科医嘱请求
|
||||
ServiceRequest serviceRequest = new ServiceRequest();
|
||||
serviceRequest.setStatusEnum(RequestStatus.DRAFT.getValue());// 请求状态
|
||||
@@ -366,9 +393,18 @@ public class SpecialAdviceAppServiceImpl implements ISpecialAdviceAppService {
|
||||
serviceRequest.setPatientId(patientId); // 患者
|
||||
serviceRequest.setRequesterId(practitionerId); // 开方医生
|
||||
serviceRequest.setEncounterId(encounterId); // 就诊id
|
||||
serviceRequest.setOrgId(activityAdviceBaseDto.getPositionId()); // 执行科室
|
||||
serviceRequest.setOrgId(currentOrgId); // 执行科室(患者当前科室)
|
||||
serviceRequest.setConditionId(conditionId); // 诊断id
|
||||
serviceRequest.setEncounterDiagnosisId(encounterDiagnosisId); // 就诊诊断id
|
||||
// 设置医嘱名称:转科-转入科室名称
|
||||
try {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
ObjectNode contentNode = objectMapper.createObjectNode();
|
||||
contentNode.put("adviceName", "转科" + (StringUtils.isNotEmpty(targetOrgName) ? "-" + targetOrgName : ""));
|
||||
serviceRequest.setContentJson(objectMapper.writeValueAsString(contentNode));
|
||||
} catch (Exception e) {
|
||||
log.warn("设置转科医嘱名称失败", e);
|
||||
}
|
||||
iServiceRequestService.save(serviceRequest);
|
||||
|
||||
// 保存转科医嘱请求的过程数据
|
||||
|
||||
@@ -14,9 +14,9 @@ import java.math.BigDecimal;
|
||||
public class RequestFormDetailQueryDto {
|
||||
|
||||
/**
|
||||
* 诊疗活动定义ID(wor_service_request.activity_id,与开立检验时项目字典的 id / adviceDefinitionId 一致,用于编辑回显)
|
||||
* 诊疗活动定义ID(wor_service_request.id,与开立检验时项目字典的 id / adviceDefinitionId 一致,用于编辑回显)
|
||||
*/
|
||||
private Long activityId;
|
||||
private Long adviceDefinitionId;
|
||||
|
||||
/** 医嘱名称 */
|
||||
private String adviceName;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
-- Fix Bug #748: clinical_pathway_execution 缺少 HisBaseEntity 列
|
||||
-- V43 迁移因版本号低于已执行的 V2026_0608 而被 Flyway 跳过,此处重新添加缺失列
|
||||
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;
|
||||
@@ -14,6 +14,9 @@
|
||||
T1.maindise_flag,
|
||||
T1.diag_srt_no,
|
||||
T1.med_type_code,
|
||||
T1.onset_date AS onsetDate,
|
||||
T1.diagnosis_time AS diagnosisTime,
|
||||
T1.doctor AS diagnosisDoctor,
|
||||
T2.verification_status_enum,
|
||||
T2.yb_no
|
||||
FROM adm_encounter_diagnosis AS T1
|
||||
|
||||
@@ -5,76 +5,60 @@
|
||||
<mapper namespace="com.healthlink.his.web.inhospitalcharge.mapper.InHospitalRegisterAppMapper">
|
||||
|
||||
<select id="getInHospitalRegisterInfo" resultType="com.healthlink.his.web.inhospitalcharge.dto.InHospitalRegisterQueryDto">
|
||||
SELECT ihri.tenant_id,
|
||||
ihri.encounter_id,
|
||||
ihri.amb_encounter_id,
|
||||
ihri.patient_id,
|
||||
ihri.request_time,
|
||||
ihri.registrar,
|
||||
ihri.source_name,
|
||||
ihri.patient_name,
|
||||
ihri.gender_enum,
|
||||
ihri.birth_date,
|
||||
ihri.ward_name,
|
||||
ihri.contract_no,
|
||||
ihri.bus_no,
|
||||
ihri.admit_source_code,
|
||||
ihri.status_enum,
|
||||
ihri.id_card,
|
||||
ihri.organization_name
|
||||
from (SELECT ae.tenant_id,
|
||||
ae.ID AS encounter_id,
|
||||
ae.amb_encounter_id AS amb_encounter_id,
|
||||
ae.patient_id AS patient_id,
|
||||
ae.create_time AS request_time,
|
||||
aper.NAME AS registrar,
|
||||
ao.NAME AS source_name,
|
||||
ap.NAME AS patient_name,
|
||||
ap.gender_enum AS gender_enum,
|
||||
ap.birth_date AS birth_date,
|
||||
al.NAME AS ward_name,
|
||||
aa.contract_no,
|
||||
ae.bus_no,
|
||||
ae.admit_source_code,
|
||||
ae.status_enum,
|
||||
ap.id_card AS id_card,
|
||||
ao_zy.NAME AS organization_name
|
||||
FROM adm_encounter AS ae
|
||||
LEFT JOIN adm_organization AS ao_zy ON ao_zy.ID = ae.organization_id
|
||||
AND ao_zy.delete_flag = '0'
|
||||
LEFT JOIN adm_encounter AS ambae ON ae.amb_encounter_id = ambae.
|
||||
ID
|
||||
LEFT JOIN adm_organization AS ao ON ao.ID = ambae.organization_id
|
||||
AND ao.delete_flag = '0'
|
||||
LEFT JOIN adm_patient AS ap ON ap.ID = ae.patient_id
|
||||
AND ap.delete_flag = '0'
|
||||
LEFT JOIN adm_encounter_location AS ael ON ael.encounter_id = ae.ID
|
||||
AND ael.delete_flag = '0'
|
||||
AND ael.form_enum = #{formEnum}
|
||||
LEFT JOIN adm_location AS al ON al.ID = ael.location_id
|
||||
AND al.delete_flag = '0'
|
||||
LEFT JOIN adm_practitioner AS aper ON aper.ID = ae.registrar_id
|
||||
AND aper.delete_flag = '0'
|
||||
LEFT JOIN adm_account AS aa ON aa.encounter_id = ae.ID
|
||||
AND aa.delete_flag = '0'
|
||||
AND aa.type_code = '04'
|
||||
WHERE ae.delete_flag = '0'
|
||||
AND ae.class_enum = #{encounterClass}
|
||||
<if test='startTime != null'>
|
||||
AND ae.create_time >= #{startTime}
|
||||
</if>
|
||||
<if test='endTime != null'>
|
||||
AND ae.create_time <= #{endTime}
|
||||
</if>
|
||||
<if test='organizationId != null'>
|
||||
AND ae.organization_id = #{organizationId}
|
||||
</if>
|
||||
<if test="registeredFlag == '0'.toString()">
|
||||
AND ae.status_enum = #{encounterStatus}
|
||||
</if>
|
||||
<if test="registeredFlag == '1'.toString()">
|
||||
AND ae.status_enum != #{encounterStatus}
|
||||
</if>
|
||||
SELECT ihri.*
|
||||
FROM (
|
||||
SELECT ae.tenant_id,
|
||||
ae.ID AS encounter_id,
|
||||
ae.amb_encounter_id,
|
||||
ae.patient_id,
|
||||
ae.create_time AS request_time,
|
||||
aper.NAME AS registrar,
|
||||
ao.NAME AS source_name,
|
||||
ap.NAME AS patient_name,
|
||||
ap.gender_enum,
|
||||
ap.birth_date,
|
||||
al.NAME AS ward_name,
|
||||
aa.contract_no,
|
||||
ae.bus_no,
|
||||
ae.admit_source_code,
|
||||
ae.status_enum,
|
||||
ap.id_card,
|
||||
ao_zy.NAME AS organization_name
|
||||
FROM adm_encounter AS ae
|
||||
LEFT JOIN adm_patient AS ap ON ap.ID = ae.patient_id
|
||||
AND ap.delete_flag = '0'
|
||||
LEFT JOIN adm_organization AS ao_zy ON ao_zy.ID = ae.organization_id
|
||||
AND ao_zy.delete_flag = '0'
|
||||
LEFT JOIN adm_encounter_location AS ael ON ael.encounter_id = ae.ID
|
||||
AND ael.delete_flag = '0'
|
||||
AND ael.form_enum = #{formEnum}
|
||||
LEFT JOIN adm_location AS al ON al.ID = ael.location_id
|
||||
AND al.delete_flag = '0'
|
||||
LEFT JOIN adm_practitioner AS aper ON aper.ID = ae.registrar_id
|
||||
AND aper.delete_flag = '0'
|
||||
LEFT JOIN adm_account AS aa ON aa.encounter_id = ae.ID
|
||||
AND aa.delete_flag = '0'
|
||||
AND aa.type_code = '04'
|
||||
LEFT JOIN adm_encounter AS ambae ON ae.amb_encounter_id = ambae.ID
|
||||
LEFT JOIN adm_organization AS ao ON ao.ID = ambae.organization_id
|
||||
AND ao.delete_flag = '0'
|
||||
WHERE ae.delete_flag = '0'
|
||||
AND ae.class_enum = #{encounterClass}
|
||||
<if test="startTime != null">
|
||||
AND ae.create_time >= #{startTime}
|
||||
</if>
|
||||
<if test="endTime != null">
|
||||
AND ae.create_time <= #{endTime}
|
||||
</if>
|
||||
<if test="organizationId != null">
|
||||
AND ae.organization_id = #{organizationId}
|
||||
</if>
|
||||
<if test='registeredFlag == "0"'>
|
||||
AND ae.status_enum = #{encounterStatus}
|
||||
</if>
|
||||
<if test='registeredFlag == "1"'>
|
||||
AND ae.status_enum != #{encounterStatus}
|
||||
</if>
|
||||
) AS ihri
|
||||
${ew.customSqlSegment}
|
||||
ORDER BY ihri.request_time DESC
|
||||
@@ -202,4 +186,4 @@
|
||||
</if>
|
||||
AND tenant_id = 1 <!-- 多租户ID(若为动态,可改为参数传入) -->
|
||||
</select>
|
||||
</mapper>
|
||||
</mapper>
|
||||
|
||||
@@ -207,7 +207,7 @@
|
||||
NULL::numeric AS unit_price,
|
||||
NULL::numeric AS total_price,
|
||||
NULL::bigint AS stopper_id,
|
||||
T1.update_by AS stopper_name
|
||||
NULL::varchar AS stopper_name
|
||||
FROM med_medication_request AS T1
|
||||
LEFT JOIN med_medication_definition AS T2
|
||||
ON T2.id = T1.medication_id
|
||||
@@ -353,7 +353,7 @@
|
||||
NULL::numeric AS unit_price,
|
||||
NULL::numeric AS total_price,
|
||||
NULL::bigint AS stopper_id,
|
||||
T1.update_by AS stopper_name
|
||||
NULL::varchar AS stopper_name
|
||||
FROM wor_service_request AS T1
|
||||
LEFT JOIN wor_activity_definition AS T2
|
||||
ON T2.id = T1.activity_id
|
||||
@@ -439,6 +439,139 @@
|
||||
ELSE 1=1 END
|
||||
AND T1.refund_service_id IS NULL
|
||||
ORDER BY T1.status_enum )
|
||||
UNION
|
||||
( SELECT DISTINCT T1.encounter_id,
|
||||
T1.tenant_id,
|
||||
#{worDeviceRequest} AS advice_table,
|
||||
T1.id AS request_id,
|
||||
T1.req_authored_time AS start_time,
|
||||
NULL::timestamp 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,
|
||||
T1.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,
|
||||
ao1.id AS position_id,
|
||||
ao1."name" AS position_name,
|
||||
NULL::integer AS dispense_per_duration,
|
||||
1::numeric AS part_percent,
|
||||
ccd."name" AS condition_definition_name,
|
||||
NULL::integer AS therapy_enum,
|
||||
NULL::integer AS sort_number,
|
||||
T1.quantity 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,
|
||||
T2.category_code,
|
||||
NULL::integer AS dispense_status,
|
||||
NULL::numeric AS unit_price,
|
||||
NULL::numeric AS total_price,
|
||||
NULL::bigint AS stopper_id,
|
||||
NULL::varchar 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_organization AS ao1
|
||||
ON ao1.id = T1.org_id
|
||||
AND ao1.delete_flag = '0'
|
||||
LEFT JOIN cli_condition AS cc
|
||||
ON cc.id = T1.condition_id
|
||||
AND cc.delete_flag = '0'
|
||||
LEFT JOIN cli_condition_definition AS ccd
|
||||
ON ccd.id = cc.definition_id
|
||||
AND ccd.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 CASE WHEN T1.status_enum = #{draft}
|
||||
THEN FALSE
|
||||
ELSE TRUE END
|
||||
ORDER BY T1.status_enum )
|
||||
) AS ii
|
||||
${ew.customSqlSegment}
|
||||
</select>
|
||||
|
||||
@@ -190,6 +190,11 @@
|
||||
AND T9.status_enum = 2
|
||||
</if>
|
||||
|
||||
-- 待转科
|
||||
<if test="statusEnum == 2">
|
||||
AND T2.status_enum = 6
|
||||
</if>
|
||||
|
||||
-- 待出院
|
||||
<if test="statusEnum == 3">
|
||||
AND T2.status_enum = 4
|
||||
|
||||
@@ -2,10 +2,15 @@
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.healthlink.his.web.patientmanage.mapper.PatientManageMapper">
|
||||
<!-- 病人信息相关查询-->
|
||||
<!-- Bug#717: 移除无用关联子查询 identifier_no(DTO无对应字段),
|
||||
避免 TenantLineInnerInterceptor 用 JSqlParser 解析 SQL 时因裸列名导致 country_code ambiguous -->
|
||||
<select id="getPatientPage" resultType="com.healthlink.his.web.patientmanage.dto.PatientBaseInfoDto">
|
||||
SELECT
|
||||
(
|
||||
SELECT api.identifier_no
|
||||
FROM adm_patient_identifier api
|
||||
WHERE api.tenant_id = p.tenant_id
|
||||
AND api.patient_id = p.id
|
||||
LIMIT 1
|
||||
) AS identifier_no,
|
||||
p.tenant_id,
|
||||
p.id,
|
||||
p.active_flag,
|
||||
@@ -54,7 +59,7 @@
|
||||
FROM adm_patient p
|
||||
<where>
|
||||
p.delete_flag = '0'
|
||||
<if test="ew != null and ew.sqlSegment != null and ew.sqlSegment != ''">
|
||||
<if test="ew.sqlSegment != null and ew.sqlSegment != ''">
|
||||
AND ${ew.sqlSegment}
|
||||
</if>
|
||||
</where>
|
||||
@@ -99,7 +104,7 @@
|
||||
LEFT JOIN adm_patient AS pt ON enc.patient_id = pt.ID AND pt.delete_flag = '0'
|
||||
<where>
|
||||
enc.delete_flag = '0'
|
||||
<if test="ew != null and ew.sqlSegment != null and ew.sqlSegment != ''">
|
||||
<if test="ew.sqlSegment != null and ew.sqlSegment != ''">
|
||||
AND ${ew.sqlSegment}
|
||||
</if>
|
||||
</where>
|
||||
|
||||
@@ -97,10 +97,10 @@
|
||||
ON T4.med_req_id = T5.id
|
||||
AND T5.delete_flag = '0'
|
||||
WHERE <if test="statusEnum == null">
|
||||
T4.status_enum IN (#{inProgress},#{completed},#{preparation},#{prepared},#{summarized})
|
||||
T4.status_enum IN (1,#{inProgress},#{completed},#{preparation},#{prepared},#{summarized})
|
||||
</if>
|
||||
<if test="statusEnum == 3">
|
||||
T4.status_enum IN (#{inProgress},#{preparation},#{prepared},#{summarized})
|
||||
T4.status_enum IN (1,#{inProgress},#{preparation},#{prepared},#{summarized})
|
||||
</if>
|
||||
<if test="statusEnum == 4">
|
||||
T4.status_enum = #{completed}
|
||||
@@ -268,10 +268,10 @@
|
||||
-- 因发药配药合并,前台只能看到待发药,已发药状态,但是后台配药发药状态都查
|
||||
AND
|
||||
<if test="dispenseStatus == null">
|
||||
T1.status_enum IN (#{inProgress},#{completed},#{preparation},#{prepared},#{summarized})
|
||||
T1.status_enum IN (1,#{inProgress},#{completed},#{preparation},#{prepared},#{summarized})
|
||||
</if>
|
||||
<if test="dispenseStatus == 3">
|
||||
T1.status_enum IN (#{inProgress},#{preparation},#{prepared},#{summarized})
|
||||
T1.status_enum IN (1,#{inProgress},#{preparation},#{prepared},#{summarized})
|
||||
</if>
|
||||
<if test="dispenseStatus == 4">
|
||||
T1.status_enum = #{completed}
|
||||
|
||||
@@ -189,7 +189,6 @@
|
||||
T1.id AS request_id,
|
||||
T1.id || '-1' AS unique_key,
|
||||
T1.practitioner_id AS requester_id,
|
||||
ap.name AS requester_id_dict_text,
|
||||
T1.create_time AS request_time,
|
||||
CASE WHEN T1.practitioner_id = #{practitionerId} THEN '1' ELSE '0' END AS biz_request_flag,
|
||||
T1.content_json AS content_json,
|
||||
@@ -197,7 +196,6 @@
|
||||
T1.infusion_flag AS inject_flag,
|
||||
T1.group_id AS group_id,
|
||||
T2.NAME AS advice_name,
|
||||
T2.category_code AS category_code,
|
||||
T3.total_volume AS volume,
|
||||
T1.lot_number AS lot_number,
|
||||
T1.quantity AS quantity,
|
||||
@@ -225,7 +223,6 @@
|
||||
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
|
||||
FROM med_medication_request AS T1
|
||||
LEFT JOIN adm_practitioner AS ap ON ap.id = T1.practitioner_id AND ap.delete_flag = '0'
|
||||
LEFT JOIN med_medication_definition AS T2 ON T2.ID = T1.medication_id
|
||||
AND T2.delete_flag = '0'
|
||||
LEFT JOIN med_medication AS T3 ON T3.medication_def_id = T2.ID
|
||||
@@ -249,7 +246,6 @@
|
||||
T1.id AS request_id,
|
||||
T1.id || '-2' AS unique_key,
|
||||
T1.requester_id AS requester_id,
|
||||
ap.name AS requester_id_dict_text,
|
||||
T1.create_time AS request_time,
|
||||
CASE WHEN T1.requester_id = #{practitionerId} THEN '1' ELSE '0' END AS biz_request_flag,
|
||||
T1.content_json AS content_json,
|
||||
@@ -257,7 +253,6 @@
|
||||
null AS inject_flag,
|
||||
null AS group_id,
|
||||
T2.NAME AS advice_name,
|
||||
'' AS category_code,
|
||||
T2.SIZE AS volume,
|
||||
T1.lot_number AS lot_number,
|
||||
T1.quantity AS quantity,
|
||||
@@ -285,7 +280,6 @@
|
||||
NULL::timestamp AS stop_time,
|
||||
'' AS stop_user_name
|
||||
FROM wor_device_request AS T1
|
||||
LEFT JOIN adm_practitioner AS ap ON ap.id = T1.requester_id AND ap.delete_flag = '0'
|
||||
LEFT JOIN adm_device_definition AS T2 ON T2.ID = T1.device_def_id
|
||||
AND T2.delete_flag = '0'
|
||||
LEFT JOIN adm_charge_item AS T3
|
||||
@@ -306,7 +300,6 @@
|
||||
T1.id AS request_id,
|
||||
T1.id || '-3' AS unique_key,
|
||||
T1.requester_id AS requester_id,
|
||||
ap.name AS requester_id_dict_text,
|
||||
T1.create_time AS request_time,
|
||||
CASE WHEN T1.requester_id = #{practitionerId} THEN '1' ELSE '0' END AS biz_request_flag,
|
||||
T1.content_json AS content_json,
|
||||
@@ -314,7 +307,6 @@
|
||||
null AS inject_flag,
|
||||
null AS group_id,
|
||||
COALESCE(T2.NAME, T1.content_json::jsonb->>'surgeryName', T1.content_json::jsonb->>'adviceName') AS advice_name,
|
||||
'' AS category_code,
|
||||
'' AS volume,
|
||||
'' AS lot_number,
|
||||
T1.quantity AS quantity,
|
||||
@@ -342,7 +334,6 @@
|
||||
CASE WHEN T1.status_enum = 6 THEN T1.occurrence_end_time ELSE NULL END AS stop_time,
|
||||
CASE WHEN T1.status_enum = 6 THEN T1.update_by ELSE NULL END AS stop_user_name
|
||||
FROM wor_service_request AS T1
|
||||
LEFT JOIN adm_practitioner AS ap ON ap.id = T1.requester_id AND ap.delete_flag = '0'
|
||||
LEFT JOIN wor_activity_definition AS T2
|
||||
ON T2.ID = T1.activity_id
|
||||
AND T2.delete_flag = '0'
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
</select>
|
||||
|
||||
<select id="getRequestFormDetail" resultType="com.healthlink.his.web.regdoctorstation.dto.RequestFormDetailQueryDto">
|
||||
SELECT wsr.activity_id AS activity_id,
|
||||
SELECT wsr.activity_id AS advice_definition_id,
|
||||
wsr.quantity,
|
||||
wsr.unit_code,
|
||||
COALESCE(wad.NAME, wsr.content_json::jsonb->>'surgeryName') AS advice_name,
|
||||
|
||||
@@ -46,6 +46,24 @@
|
||||
<groupId>com.healthlink.his</groupId>
|
||||
<artifactId>healthlink-his-common</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson2</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.alibaba.fastjson2</groupId>
|
||||
<artifactId>fastjson2</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.alibaba.fastjson2</groupId>
|
||||
<artifactId>fastjson2-extension</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.opencsv</groupId>
|
||||
|
||||
@@ -4,7 +4,7 @@ rem 设置项目根目录
|
||||
set PROJECT_ROOT=%~dp0
|
||||
|
||||
rem 设置classpath
|
||||
set CLASSPATH=%PROJECT_ROOT%openhis-application\target\classes;%PROJECT_ROOT%openhis-domain\target\classes;%PROJECT_ROOT%openhis-common\target\classes;%PROJECT_ROOT%core-admin\target\classes;%PROJECT_ROOT%core-framework\target\classes;%PROJECT_ROOT%core-system\target\classes;%PROJECT_ROOT%core-quartz\target\classes;%PROJECT_ROOT%core-generator\target\classes;%PROJECT_ROOT%core-flowable\target\classes;%PROJECT_ROOT%core-common\target\classes
|
||||
set CLASSPATH=%PROJECT_ROOT%healthlink-his-application\target\classes;%PROJECT_ROOT%healthlink-his-domain\target\classes;%PROJECT_ROOT%healthlink-his-common\target\classes;%PROJECT_ROOT%core-admin\target\classes;%PROJECT_ROOT%core-framework\target\classes;%PROJECT_ROOT%core-system\target\classes;%PROJECT_ROOT%core-quartz\target\classes;%PROJECT_ROOT%core-generator\target\classes;%PROJECT_ROOT%core-flowable\target\classes;%PROJECT_ROOT%core-common\target\classes
|
||||
|
||||
rem 启动应用
|
||||
java -cp "%CLASSPATH%" com.openhis.OpenHisApplication
|
||||
java -cp "%CLASSPATH%" com.healthlink.his.HealthLinkHisApplication
|
||||
@@ -4,10 +4,10 @@
|
||||
PROJECT_ROOT=$(pwd)
|
||||
|
||||
# 设置classpath
|
||||
CLASSPATH="$PROJECT_ROOT/openhis-application/target/classes:$PROJECT_ROOT/openhis-domain/target/classes:$PROJECT_ROOT/openhis-common/target/classes:$PROJECT_ROOT/core-admin/target/classes:$PROJECT_ROOT/core-framework/target/classes:$PROJECT_ROOT/core-system/target/classes:$PROJECT_ROOT/core-quartz/target/classes:$PROJECT_ROOT/core-generator/target/classes:$PROJECT_ROOT/core-flowable/target/classes:$PROJECT_ROOT/core-common/target/classes"
|
||||
CLASSPATH="$PROJECT_ROOT/healthlink-his-application/target/classes:$PROJECT_ROOT/healthlink-his-domain/target/classes:$PROJECT_ROOT/healthlink-his-common/target/classes:$PROJECT_ROOT/core-admin/target/classes:$PROJECT_ROOT/core-framework/target/classes:$PROJECT_ROOT/core-system/target/classes:$PROJECT_ROOT/core-quartz/target/classes:$PROJECT_ROOT/core-generator/target/classes:$PROJECT_ROOT/core-flowable/target/classes:$PROJECT_ROOT/core-common/target/classes"
|
||||
|
||||
# 添加所有依赖jar包
|
||||
export CLASSPATH="$CLASSPATH:$(find $PROJECT_ROOT/openhis-application/target/dependency -name '*.jar' | tr '\n' ':')"
|
||||
export CLASSPATH="$CLASSPATH:$(find $PROJECT_ROOT/healthlink-his-application/target/dependency -name '*.jar' | tr '\n' ':')"
|
||||
|
||||
# 启动应用
|
||||
java -cp "$CLASSPATH" com.openhis.OpenHisApplication
|
||||
java -cp "$CLASSPATH" com.healthlink.his.HealthLinkHisApplication
|
||||
@@ -20,13 +20,13 @@ const useAppStore = defineStore(
|
||||
this.sidebar.opened = !this.sidebar.opened
|
||||
this.sidebar.withoutAnimation = withoutAnimation
|
||||
if (this.sidebar.opened) {
|
||||
Cookies.set('sidebarStatus', 1)
|
||||
Cookies.set('sidebarStatus', 1, { path: '/' })
|
||||
} else {
|
||||
Cookies.set('sidebarStatus', 0)
|
||||
Cookies.set('sidebarStatus', 0, { path: '/' })
|
||||
}
|
||||
},
|
||||
closeSideBar({ withoutAnimation }) {
|
||||
Cookies.set('sidebarStatus', 0)
|
||||
Cookies.set('sidebarStatus', 0, { path: '/' })
|
||||
this.sidebar.opened = false
|
||||
this.sidebar.withoutAnimation = withoutAnimation
|
||||
},
|
||||
@@ -35,7 +35,7 @@ const useAppStore = defineStore(
|
||||
},
|
||||
setSize(size) {
|
||||
this.size = size;
|
||||
Cookies.set('size', size)
|
||||
Cookies.set('size', size, { path: '/' })
|
||||
},
|
||||
toggleSideBarHide(status) {
|
||||
this.sidebar.hide = status
|
||||
|
||||
@@ -7,9 +7,9 @@ export function getToken() {
|
||||
}
|
||||
|
||||
export function setToken(token) {
|
||||
return Cookies.set(TokenKey, token)
|
||||
return Cookies.set(TokenKey, token, { path: '/' })
|
||||
}
|
||||
|
||||
export function removeToken() {
|
||||
return Cookies.remove(TokenKey)
|
||||
return Cookies.remove(TokenKey, { path: '/' })
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ export function getDiagnosisTreatmentList (query) {
|
||||
// 查询诊疗目录详细
|
||||
export function getDiagnosisTreatmentOne (id) {
|
||||
return request ({
|
||||
url: '/data-dictionary/diagnosis-treatment/information-one/',
|
||||
url: '/data-dictionary/diagnosis-treatment/information-one',
|
||||
method: 'get',
|
||||
params: {id}, // 确保参数正确传递
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<template>
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="left">
|
||||
<el-form
|
||||
@@ -147,7 +147,7 @@
|
||||
ref="tableRef"
|
||||
:data="infusionList"
|
||||
border
|
||||
style="width: 100%; height: 300px"
|
||||
style="width: 100%; flex: 1; min-height: 0"
|
||||
@checkbox-change="handleSelectionChange"
|
||||
@cell-click="handleRowClick"
|
||||
>
|
||||
@@ -231,7 +231,7 @@
|
||||
<vxe-table
|
||||
:data="historyRecordsList"
|
||||
border
|
||||
style="width: 100%; height: 300px"
|
||||
style="width: 100%; flex: 1; min-height: 0"
|
||||
>
|
||||
<vxe-column
|
||||
field="occurrenceEndTime"
|
||||
@@ -670,15 +670,24 @@ getList();
|
||||
.app-container {
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
height: calc(100vh - 84px);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.left {
|
||||
width: 28%;
|
||||
min-width: 0;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.right {
|
||||
margin-left: 2%;
|
||||
width: 70%;
|
||||
margin-left: 12px;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:deep(.vxe-table tbody tr:hover > td) {
|
||||
|
||||
@@ -60,12 +60,13 @@
|
||||
</el-form>
|
||||
|
||||
<!-- 表格 -->
|
||||
<div class="table-wrapper">
|
||||
<vxe-table
|
||||
ref="tableRef"
|
||||
v-loading="loading"
|
||||
:data="tableData"
|
||||
border
|
||||
max-height="calc(100vh - 280px)"
|
||||
height="100%"
|
||||
>
|
||||
<vxe-column field="formNo" title="申请单号" align="center" width="180" show-overflow />
|
||||
<vxe-column field="patientName" title="患者姓名" align="center" width="110" />
|
||||
@@ -106,6 +107,7 @@
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
</div>
|
||||
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
@@ -244,6 +246,18 @@ getListData()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.app-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100vh - 84px);
|
||||
overflow: hidden;
|
||||
}
|
||||
.table-wrapper {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.detail-content {
|
||||
.item-list {
|
||||
margin-top: 16px;
|
||||
|
||||
@@ -394,7 +394,7 @@
|
||||
>
|
||||
皮试:<el-checkbox
|
||||
v-model="scope.row.skinTestFlag"
|
||||
:true-value="1"
|
||||
:true-value="true"
|
||||
:false-value="0"
|
||||
@change="handleSkinTestChange(scope.row, scope.rowIndex)"
|
||||
>
|
||||
@@ -837,7 +837,7 @@
|
||||
>
|
||||
皮试:<el-checkbox
|
||||
v-model="scope.row.skinTestFlag"
|
||||
:true-value="1"
|
||||
:true-value="true"
|
||||
:false-value="0"
|
||||
@change="handleSkinTestChange(scope.row, scope.rowIndex)"
|
||||
>
|
||||
@@ -1332,7 +1332,7 @@
|
||||
<template v-if="scope.row.isEdit">
|
||||
<el-checkbox
|
||||
v-model="scope.row.skinTestFlag"
|
||||
:true-value="1"
|
||||
:true-value="true"
|
||||
:false-value="0"
|
||||
@change="handleSkinTestChange(scope.row, scope.rowIndex)"
|
||||
>
|
||||
@@ -1750,10 +1750,8 @@ onMounted(() => {
|
||||
createNewPrescription();
|
||||
handleAddPrescription(null, false);
|
||||
}
|
||||
// 默认展开个人:只请求个人组套
|
||||
if (props.patientInfo?.orgId) {
|
||||
fetchOrderGroups('personal');
|
||||
}
|
||||
// 默认展开个人:个人组套不依赖 orgId(使用 practitionerId 查询)
|
||||
fetchOrderGroups('personal');
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
@@ -1802,12 +1800,14 @@ watch(
|
||||
watch(
|
||||
() => props.patientInfo?.orgId,
|
||||
(orgId) => {
|
||||
if (!orgId) return;
|
||||
// 🔧 Bug #730 修复:个人组套不依赖 orgId,只需 practitionerId(登录用户自带)
|
||||
if (!orderGroupLoaded.value.personal) {
|
||||
fetchOrderGroups('personal');
|
||||
}
|
||||
// 预加载医嘱基础数据,提升搜索响应速度
|
||||
preloadAdviceData();
|
||||
if (orgId) {
|
||||
preloadAdviceData();
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
@@ -5056,8 +5056,9 @@ async function fetchOrderGroups(scope, { force = false } = {}) {
|
||||
|
||||
const orgId = props.patientInfo?.orgId;
|
||||
console.log('[fetchOrderGroups] orgId:', orgId);
|
||||
if (!orgId) {
|
||||
console.log('[fetchOrderGroups] orgId 为空,返回');
|
||||
// 🔧 Bug #730 修复:个人/科室组套不依赖 orgId,只有全院组套需要 orgId
|
||||
if (scope === 'hospital' && !orgId) {
|
||||
console.log('[fetchOrderGroups] 全院组套需要 orgId 但为空,返回');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,13 +64,15 @@
|
||||
|
||||
<script setup>
|
||||
import {ref} from 'vue';
|
||||
import {getTcmCondition, getTcmSyndrome} from '@/views/doctorstation/components/api';
|
||||
import {getTcmCondition, getTcmSyndrome, saveTcmDiagnosis} from '@/views/doctorstation/components/api';
|
||||
|
||||
const condition = ref('');
|
||||
const syndrome = ref('');
|
||||
const conditionOptions = ref([]);
|
||||
const syndromeOptions = ref([]);
|
||||
const diagnosisList = ref([]);
|
||||
const conditionYbNoMap = {};
|
||||
const syndromeYbNoMap = {};
|
||||
const openDiagnosis = ref(false);
|
||||
const emit = defineEmits(['flush']);
|
||||
const { proxy } = getCurrentInstance();
|
||||
@@ -83,19 +85,31 @@ const props = defineProps({
|
||||
function open() {}
|
||||
|
||||
function submit() {
|
||||
// 提交逻辑
|
||||
if (!condition.value || !syndrome.value) {
|
||||
proxy.$modal.msgWarning('请选择诊断和证候');
|
||||
return; // 确保选择了诊断和证候
|
||||
return;
|
||||
}
|
||||
|
||||
// 构建诊断数据,调用API保存到服务器
|
||||
const diagnosisChildList = [{
|
||||
conditionCode: condition.value,
|
||||
syndromeCode: syndrome.value,
|
||||
}];
|
||||
// syndromeGroupNo 使用时间戳,确保同组病证关联
|
||||
const syndromeGroupNo = String(Date.now());
|
||||
|
||||
// 构建诊断数据,字段名对齐后端 SaveDiagnosisChildParam
|
||||
const diagnosisChildList = [
|
||||
{
|
||||
definitionId: condition.value,
|
||||
ybNo: conditionYbNoMap[condition.value] || '',
|
||||
syndromeGroupNo: syndromeGroupNo,
|
||||
verificationStatusEnum: 4,
|
||||
maindiseFlag: 1,
|
||||
},
|
||||
{
|
||||
definitionId: syndrome.value,
|
||||
ybNo: syndromeYbNoMap[syndrome.value] || '',
|
||||
syndromeGroupNo: syndromeGroupNo,
|
||||
verificationStatusEnum: 4,
|
||||
},
|
||||
];
|
||||
|
||||
// 调用API保存到服务器
|
||||
saveTcmDiagnosis({
|
||||
patientId: props.patientInfo.patientId,
|
||||
encounterId: props.patientInfo.encounterId,
|
||||
@@ -119,17 +133,25 @@ function openDialog() {
|
||||
// 获取中医诊断选项
|
||||
getTcmCondition().then((res) => {
|
||||
conditionOptions.value = res.data.records.map((item) => ({
|
||||
value: item.ybNo,
|
||||
value: item.id,
|
||||
label: item.name,
|
||||
}));
|
||||
// 保存 ybNo 映射,提交时使用
|
||||
res.data.records.forEach((item) => {
|
||||
conditionYbNoMap[item.id] = item.ybNo;
|
||||
});
|
||||
});
|
||||
|
||||
// 获取中医证候选项
|
||||
getTcmSyndrome().then((res) => {
|
||||
syndromeOptions.value = res.data.records.map((item) => ({
|
||||
value: item.ybNo,
|
||||
value: item.id,
|
||||
label: item.name,
|
||||
}));
|
||||
// 保存 ybNo 映射,提交时使用
|
||||
res.data.records.forEach((item) => {
|
||||
syndromeYbNoMap[item.id] = item.ybNo;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
:model="queryParams"
|
||||
:inline="true"
|
||||
label-position="right"
|
||||
style="min-width: 500px"
|
||||
|
||||
>
|
||||
<el-form-item
|
||||
label="患者信息"
|
||||
@@ -70,7 +70,7 @@
|
||||
<vxe-table
|
||||
:row-config="{ isCurrent: true }" :data="patientList"
|
||||
border
|
||||
style="width: 100%; height: 60vh"
|
||||
style="width: 100%; flex: 1; min-height: 0"
|
||||
@cell-click="handleCurrentChange"
|
||||
>
|
||||
<vxe-column
|
||||
@@ -176,7 +176,7 @@
|
||||
v-loading="loading"
|
||||
:data="medicineInfoList"
|
||||
border
|
||||
style="width: 100%; height: 65vh; margin-top: 10px"
|
||||
style="width: 100%; flex: 1; min-height: 0; margin-top: 10px"
|
||||
:span-method="spanMethod"
|
||||
@select="handleSelectionChange"
|
||||
@cell-dblclick="handleCellDbClick"
|
||||
@@ -1191,21 +1191,33 @@ function handleCancel() {
|
||||
.app-container {
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
height: calc(100vh - 84px);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.left {
|
||||
width: 25%;
|
||||
min-width: 0;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
|
||||
.form {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-shrink: 0;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
margin-left: 2%;
|
||||
width: 74%;
|
||||
margin-left: 12px;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:deep(.vxe-table tbody tr:hover > td) {
|
||||
@@ -1248,25 +1260,7 @@ function handleCancel() {
|
||||
}
|
||||
|
||||
/* 其他已有样式保持不变 */
|
||||
.app-container {
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.left {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.form {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.right {
|
||||
margin-left: 2%;
|
||||
width: 74%;
|
||||
}
|
||||
|
||||
:deep(.vxe-table tbody tr:hover > td) {
|
||||
background-color: inherit !important;
|
||||
|
||||
@@ -77,14 +77,14 @@ const tableData=ref([]);const total=ref(0);const stats=ref({})
|
||||
const addVisible=ref(false);const completeVisible=ref(false)
|
||||
const addForm=ref({patientId:null,diseaseType:'',targetTime:90,doctor:''})
|
||||
const addFormRef=ref(null)
|
||||
const addFormRules={patientId:[{required:true,message:'请选择患者',trigger:'blur'}]}
|
||||
const addFormRules={patientId:[{required:true,message:'请选择患者',trigger:'change'}]}
|
||||
const completeForm=ref({doorToTreatmentTime:60});let currentId=null
|
||||
const q=ref({pageNo:1,pageSize:20,diseaseType:'',isAchieved:null})
|
||||
const loadData=async()=>{const r=await getPage(q.value);tableData.value=r.data?.records||[];total.value=r.data?.total||0}
|
||||
const refreshStats=async()=>{const r=await getStats({});stats.value=r.data||{}}
|
||||
const showAdd=()=>{addForm.value={patientId:null,diseaseType:'',targetTime:90,doctor:''};addVisible.value=true}
|
||||
const showComplete=(row)=>{currentId=row.id;completeForm.value={doorToTreatmentTime:60};completeVisible.value=true}
|
||||
const submitAdd=async()=>{if(addFormRef.value){try{await addFormRef.value.validate()}catch{return}}await activate(addForm.value);ElMessage.success('绿色通道已激活');addVisible.value=false;loadData();refreshStats()}
|
||||
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()}
|
||||
const doComplete=async()=>{await complete(currentId,completeForm.value);ElMessage.success('评估完成');completeVisible.value=false;loadData();refreshStats()}
|
||||
const delItem=async(id)=>{await del(id);ElMessage.success('已删除');loadData();refreshStats()}
|
||||
onMounted(()=>{loadData();refreshStats()})
|
||||
|
||||
@@ -574,7 +574,14 @@ const handleEdit = async (row) => {
|
||||
editFormRef.value?.getLocationInfo?.();
|
||||
editFormRef.value?.getDiagnosisList?.();
|
||||
editFormRef.value?.loadDoctorOptions?.();
|
||||
// fillForm 由 SurgeryForm 内部 editData watcher 在 getList 完成后自动调用
|
||||
await editFormRef.value?.getList?.();
|
||||
if (row.requestFormDetailList?.length > 0) {
|
||||
editFormRef.value?.fillForm?.(
|
||||
JSON.parse(row.descJson || '{}'),
|
||||
row.requestFormDetailList,
|
||||
row.requestFormId
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleEditSubmitOk = async () => {
|
||||
|
||||
@@ -149,7 +149,7 @@
|
||||
@click="() => (row.methodCode_dictText = dict.label)"
|
||||
@keyup="handleEnter('methodCode')"
|
||||
:key="dict.value"
|
||||
:label="dict.value + ' ' + dict.label"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
@@ -360,7 +360,7 @@
|
||||
<div class="form-group">
|
||||
<el-form-item label="给药途径:" prop="methodCode" class="required-field" data-prop="methodCode">
|
||||
<el-select v-model="row.methodCode" placeholder="给药途径" clearable filterable style="width: 120px">
|
||||
<el-option v-for="dict in config.methodCode" @click="() => (row.methodCode_dictText = dict.label)" :key="dict.value" :label="dict.value + ' ' + dict.label" :value="dict.value" />
|
||||
<el-option v-for="dict in config.methodCode" @click="() => (row.methodCode_dictText = dict.label)" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="用药频次:" prop="rateCode" class="required-field" data-prop="rateCode">
|
||||
|
||||
@@ -356,7 +356,6 @@ let surgeryRecordsCache = null; // 原始 API 记录
|
||||
let surgeryMappedCache = null; // 映射后的 el-transfer 数据
|
||||
let doctorCache = null; // 医生列表(含默认主刀医生 ID)
|
||||
const transferRef = ref(null);
|
||||
const listLoaded = ref(false); // 手术项目列表是否已加载完成
|
||||
const dbTotal = ref(0); // 数据库中的手术项目总数
|
||||
const checkedCount = computed(() => transferValue.value.length);
|
||||
const leftPanelFormat = computed(() => ({
|
||||
@@ -418,11 +417,10 @@ const getList = async (key) => {
|
||||
applicationList.value = surgeryMappedCache;
|
||||
applicationListAll.value = surgeryRecordsCache;
|
||||
dbTotal.value = surgeryRecordsCache.length;
|
||||
listLoaded.value = true;
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
getSurgeryPage({
|
||||
return getSurgeryPage({
|
||||
pageSize: 1000,
|
||||
keyword: key || undefined,
|
||||
})
|
||||
@@ -438,14 +436,12 @@ const getList = async (key) => {
|
||||
surgeryMappedCache = applicationList.value;
|
||||
}
|
||||
loading.value = false;
|
||||
listLoaded.value = true;
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error('手术项目加载失败:', e);
|
||||
applicationList.value = [];
|
||||
dbTotal.value = 0;
|
||||
loading.value = false;
|
||||
listLoaded.value = true;
|
||||
});
|
||||
};
|
||||
|
||||
@@ -475,7 +471,7 @@ const mapToTransferItem = (item) => ({
|
||||
const fillForm = (descJson, details, formId) => {
|
||||
editingRequestFormId.value = formId || '';
|
||||
// 回填已选手术项目到穿梭框
|
||||
const ids = (details || []).map((d) => String(d.activityId));
|
||||
const ids = (details || []).map((d) => String(d.adviceDefinitionId));
|
||||
transferValue.value = ids;
|
||||
// 回填表单字段
|
||||
if (descJson) {
|
||||
@@ -540,27 +536,6 @@ onMounted(() => {
|
||||
loadDoctorOptions();
|
||||
});
|
||||
|
||||
// 编辑模式:等手术项目列表加载完成后回填穿梭框
|
||||
watch(() => props.editData, (val) => {
|
||||
if (!val) return;
|
||||
const doFill = () => {
|
||||
if (val.requestFormDetailList?.length > 0) {
|
||||
fillForm(
|
||||
JSON.parse(val.descJson || '{}'),
|
||||
val.requestFormDetailList,
|
||||
val.requestFormId
|
||||
);
|
||||
}
|
||||
};
|
||||
if (listLoaded.value) {
|
||||
doFill();
|
||||
} else {
|
||||
const unwatch = watch(listLoaded, (loaded) => {
|
||||
if (loaded) { unwatch(); doFill(); }
|
||||
});
|
||||
}
|
||||
}, { immediate: true });
|
||||
|
||||
/**
|
||||
* 加载字典选项
|
||||
*/
|
||||
|
||||
@@ -97,6 +97,7 @@ import {transferOrganization} from './api.js';
|
||||
import {getOrgList, getWardList} from '@/api/public.js';
|
||||
import {patientInfo} from '../../../store/patient.js';
|
||||
|
||||
const emit = defineEmits(['success']);
|
||||
const { proxy } = getCurrentInstance();
|
||||
const dialogVisible = ref(false);
|
||||
const deptList = ref([]); // 科室列表
|
||||
@@ -151,6 +152,7 @@ function submitApplicationForm() {
|
||||
if (res.code == 200) {
|
||||
proxy.$modal.msgSuccess('转科申请已提交');
|
||||
dialogVisible.value = false;
|
||||
emit('success');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -55,6 +55,47 @@
|
||||
划价组套
|
||||
</el-button>
|
||||
</div>
|
||||
<!-- 操作栏:执行时间 + 总金额 + 确认/取消(固定在顶部,无需滚动) -->
|
||||
<div
|
||||
style="
|
||||
margin-bottom: 10px;
|
||||
padding: 8px 12px;
|
||||
background: #f5f7fa;
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
"
|
||||
>
|
||||
<div style="display: flex; align-items: center; gap: 10px">
|
||||
<span style="white-space: nowrap">执行时间:</span>
|
||||
<el-date-picker
|
||||
v-model="executeTime"
|
||||
type="datetime"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="选择日期时间"
|
||||
style="width: 200px"
|
||||
/>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; gap: 15px">
|
||||
<span style="font-size: 14px; font-weight: bold; white-space: nowrap">
|
||||
本次补费总金额:<span style="color: #ff4d4f">{{ totalAmount.toFixed(6) }}</span>
|
||||
</span>
|
||||
<el-button @click="handleCancel">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleConfirm"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 弹窗内容 - 左右布局 -->
|
||||
<div style="display: flex; gap: 20px; height: 70vh">
|
||||
<div
|
||||
@@ -300,46 +341,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部信息区域 -->
|
||||
<div style="margin-top: 15px; display: flex; flex-wrap: wrap; gap: 15px">
|
||||
<div style="display: flex; align-items: center">
|
||||
<span style="margin-right: 8px">执行时间:</span>
|
||||
<el-date-picker
|
||||
v-model="executeTime"
|
||||
type="datetime"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="选择日期时间"
|
||||
style="width: 200px"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 总金额和操作按钮(固定在弹窗底部) -->
|
||||
<div
|
||||
style="
|
||||
margin-top: 15px;
|
||||
padding-top: 15px;
|
||||
border-top: 1px solid #e4e7ed;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
"
|
||||
>
|
||||
<div style="font-size: 14px; font-weight: bold; text-align: right">
|
||||
本次补费总金额:<span style="color: #ff4d4f">{{ totalAmount.toFixed(6) }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<el-button @click="handleCancel">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleConfirm"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!-- 划价组套选择对话框 -->
|
||||
<el-dialog
|
||||
|
||||
@@ -321,16 +321,17 @@ function handleLogin() {
|
||||
loading.value = true;
|
||||
// 勾选了需要记住密码设置在 cookie 中设置记住用户名和密码
|
||||
if (loginForm.value.rememberMe) {
|
||||
Cookies.set('username', loginForm.value.username, { expires: 30 });
|
||||
Cookies.set('username', loginForm.value.username, { expires: 30, path: '/' });
|
||||
Cookies.set('password', encrypt(loginForm.value.password), {
|
||||
expires: 30,
|
||||
path: '/',
|
||||
});
|
||||
Cookies.set('rememberMe', loginForm.value.rememberMe, { expires: 30 });
|
||||
Cookies.set('rememberMe', loginForm.value.rememberMe, { expires: 30, path: '/' });
|
||||
} else {
|
||||
// 否则移除
|
||||
Cookies.remove('username');
|
||||
Cookies.remove('password');
|
||||
Cookies.remove('rememberMe');
|
||||
Cookies.remove('username', { path: '/' });
|
||||
Cookies.remove('password', { path: '/' });
|
||||
Cookies.remove('rememberMe', { path: '/' });
|
||||
}
|
||||
// 调用action的登录方法
|
||||
userStore
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
:model="queryParams"
|
||||
:inline="true"
|
||||
label-position="right"
|
||||
style="min-width: 500px"
|
||||
|
||||
>
|
||||
<el-form-item
|
||||
label="患者信息"
|
||||
@@ -86,7 +86,7 @@
|
||||
<vxe-table
|
||||
:row-config="{ isCurrent: true }" :data="patientList"
|
||||
border
|
||||
style="width: 100%; height: 60vh"
|
||||
style="width: 100%; flex: 1; min-height: 0"
|
||||
@cell-click="handleCurrentChange"
|
||||
>
|
||||
<vxe-column
|
||||
@@ -283,7 +283,7 @@
|
||||
v-loading="loading"
|
||||
:data="medicineInfoList"
|
||||
border
|
||||
style="width: 100%; height: 65vh; margin-top: 10px"
|
||||
style="width: 100%; flex: 1; min-height: 0; margin-top: 10px"
|
||||
:span-method="spanMethod"
|
||||
:cell-class-name="cellClassName"
|
||||
@select="handleSelectionChange"
|
||||
@@ -1485,21 +1485,33 @@ function validate() {
|
||||
.app-container {
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
height: calc(100vh - 84px);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.left {
|
||||
width: 25%;
|
||||
min-width: 0;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
|
||||
.form {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-shrink: 0;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
margin-left: 2%;
|
||||
width: 74%;
|
||||
margin-left: 12px;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* 表格文字颜色改为纯黑色 */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<template>
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form
|
||||
v-show="showSearch"
|
||||
@@ -103,23 +103,24 @@
|
||||
/>
|
||||
</el-row>
|
||||
|
||||
<vxe-table
|
||||
v-if="refreshTable"
|
||||
v-loading="loading"
|
||||
<el-table v-if="refreshTable" ref="menuTableRef" v-loading="loading"
|
||||
:data="menuList"
|
||||
:row-config="{ keyField: 'menuId' }"
|
||||
row-key="menuId"
|
||||
:default-expand-all="isExpandAll"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
>
|
||||
<vxe-column
|
||||
field="menuName"
|
||||
<el-table-column
|
||||
prop="menuName"
|
||||
title="菜单名称"
|
||||
:show-overflow="true"
|
||||
show-overflow-tooltip
|
||||
width="160"
|
||||
>
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.menuType === 'M'" style="font-weight: 600; font-size: 14px;">
|
||||
📁 {{ scope.row.menuName }}
|
||||
</span>
|
||||
<span
|
||||
v-if="scope.row.menuType === 'C'"
|
||||
v-else-if="scope.row.menuType === 'C'"
|
||||
class="menu-name-link"
|
||||
:title="`点击跳转到${scope.row.menuName}模块`"
|
||||
style="cursor: pointer; color: #3B82F6;"
|
||||
@@ -127,86 +128,84 @@
|
||||
>
|
||||
{{ scope.row.menuName }}
|
||||
</span>
|
||||
<span v-else>{{ scope.row.menuName }}</span>
|
||||
<span v-else style="color: #909399;">
|
||||
⚙️ {{ scope.row.menuName }}
|
||||
</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column
|
||||
field="icon"
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="icon"
|
||||
title="图标"
|
||||
align="center"
|
||||
width="100"
|
||||
>
|
||||
<template #default="scope">
|
||||
<svg-icon :icon-class="scope.row.icon" />
|
||||
<svg-icon v-if="scope.row.icon" :icon-class="scope.row.icon" />
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column
|
||||
field="orderNum"
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="orderNum"
|
||||
title="排序"
|
||||
width="60"
|
||||
/>
|
||||
<vxe-column
|
||||
field="perms"
|
||||
<el-table-column
|
||||
prop="perms"
|
||||
title="权限标识"
|
||||
:show-overflow="true"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<vxe-column
|
||||
field="path"
|
||||
<el-table-column
|
||||
prop="path"
|
||||
title="路由地址"
|
||||
:show-overflow="true"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<vxe-column
|
||||
field="fullPath"
|
||||
<el-table-column
|
||||
prop="fullPath"
|
||||
title="完整路径"
|
||||
:show-overflow="true"
|
||||
show-overflow-tooltip
|
||||
>
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.fullPath">{{ scope.row.fullPath }}</span>
|
||||
<span v-else-if="scope.row.path">{{ scope.row.path }}</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column
|
||||
field="component"
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="component"
|
||||
title="组件路径"
|
||||
:show-overflow="true"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<vxe-column
|
||||
field="status"
|
||||
<el-table-column
|
||||
prop="status"
|
||||
title="状态"
|
||||
width="80"
|
||||
>
|
||||
<template #default="scope">
|
||||
<dict-tag
|
||||
:options="processedSysNormalDisable"
|
||||
:value="scope.row.status"
|
||||
<dict-tag v-if="scope.row.status !== null && scope.row.status !== undefined" :options="processedSysNormalDisable" :value="scope.row.status"
|
||||
class="dict-tag"
|
||||
/>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column
|
||||
field="visible"
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="visible"
|
||||
title="显示状态"
|
||||
width="100"
|
||||
>
|
||||
<template #default="scope">
|
||||
<dict-tag
|
||||
:options="processedSysShowHide"
|
||||
:value="scope.row.visible"
|
||||
<dict-tag v-if="scope.row.visible !== null && scope.row.visible !== undefined" :options="processedSysShowHide" :value="scope.row.visible"
|
||||
class="dict-tag"
|
||||
/>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
title="创建时间"
|
||||
align="center"
|
||||
width="160"
|
||||
field="createTime"
|
||||
prop="createTime"
|
||||
>
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
title="操作"
|
||||
align="center"
|
||||
width="210"
|
||||
@@ -244,8 +243,8 @@
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 添加或修改菜单对话框 -->
|
||||
<el-dialog
|
||||
@@ -613,7 +612,7 @@ const title = ref("");
|
||||
const menuOptions = ref([]);
|
||||
const isExpandAll = ref(false);
|
||||
const refreshTable = ref(true);
|
||||
const iconSelectRef = ref(null);
|
||||
const iconSelectRef = ref(null);const menuTableRef = ref(null);
|
||||
|
||||
const data = reactive({
|
||||
form: {},
|
||||
@@ -739,8 +738,8 @@ async function handleAdd(row) {
|
||||
}
|
||||
/** 展开/折叠操作 */
|
||||
function toggleExpandAll() {
|
||||
refreshTable.value = false;
|
||||
isExpandAll.value = !isExpandAll.value;
|
||||
refreshTable.value = false;
|
||||
nextTick(() => {
|
||||
refreshTable.value = true;
|
||||
});
|
||||
@@ -879,4 +878,7 @@ getList();
|
||||
.menu-name-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
:deep(.el-table__row) {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user