Compare commits

..

8 Commits

Author SHA1 Message Date
张飞
4f6ad79527 Fix Bug #362: 住院护士站:入出转管理双击查看详情时,"入科时间"字段显示当前系统时间而非实际入科时间
在 selectAdmissionPatientInfo SQL 中,startTime 原取自 bed.start_time(床位级别的位置记录),
当该 LEFT JOIN 无匹配记录时返回 NULL,前端 fallback 到当前系统时间。
改为 COALESCE(bed.start_time, ae.start_time),无床位记录时回退到 encounter 的入院时间。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 01:03:05 +08:00
关羽
1b6f52907d Fix Bug #492: 【门诊手术安排】关闭"手术计费"主弹窗后,项目字典选择列表依然残留悬浮在界面上
根因:el-popover 使用 :visible 受控模式,closeAllPopovers() 将 showPopover 设为 false
后,Vue 尚未完成 DOM 更新时 showChargeDialog 已被设为 false,导致弹窗组件被销毁
而 popover 的 visible 状态变更未传播到 DOM,弹窗消失但 popover 残留。

修复:在 closeChargeDialog 中使用 nextTick 等待 Vue 完成 popover 关闭的 DOM 更新后,
再设置 showChargeDialog = false 关闭主弹窗。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 01:03:05 +08:00
赵云
13d3d7a98d Fix Bug #493: 【住院医生工作站-临床医嘱-检验申请】项目未维护执行科室时,医生手动选择发往科室后仍报错且数据被清空
根因:projectWithDepartment 函数定义时遗漏了 type 参数,导致函数体内引用 type 变量时报 ReferenceError(未定义),type === 2 的判断永远无法正确执行。用户在提交时手动选择的发往科室被清空且无法提交。

修复:在函数签名中添加 type 参数,与 working 版本 medicalExaminations.vue 保持一致。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 01:03:05 +08:00
刘备
852a2a83b0 Fix Bug #489: 【医嘱闭环】医生站签发单条长期药品医嘱,护士校对界面生成重复(两条)待校对记录
在住院医生站签发流程的 handMedication() 方法中增加去重逻辑,
与门诊医生站保持一致,使用 patientId+encounterId+adviceDefinitionId+dose+methodCode+rateCode
作为唯一键,防止前端重复提交导致数据库产生重复医嘱记录。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 01:03:05 +08:00
诸葛亮
b127fd93e4 Fix Bug #494: 住院医生工作站-检查申请:"申请单名称"字段显示为通用名称,未展示具体检查项目名称
根因:medicalExaminations.vue 保存检查申请单时,name 字段硬编码为 "检查申请单",
导致列表页所有记录的申请单名称均显示为固定字符串,无法区分具体检查项目。

修复:将 name 从硬编码改为从已选项目集合中提取 adviceName 并用顿号连接,
如选择 CT、超声两项则显示为 "CT、超声"。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 00:15:09 +08:00
刘备
4a6f0e61d4 Fix Bug #491: 【执行科室配置】保存配置时系统报错 - 修复Organization.getName()空指针异常
根因分析:
1. organizationLocationInit() 中 Organization.getName() 未做空值过滤,若数据库存在name为null的科室记录会NPE
2. addOrEditOrgLoc() 中 activityDefinitionMapper.selectById().getName() 未对selectById返回null做防护
3. addOrEditOrgLoc() 缺少organizationId前置校验,空值传入可能导致后续流程异常

修复内容:
- 第74行:stream中增加 .filter(organization -> organization != null && organization.getName() != null)
- 第136-138行:增加organizationId为null时的校验,返回友好错误提示
- 第145-147行:将activityDefinitionMapper.selectById结果先赋值再判空,避免NPE

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 00:12:31 +08:00
赵云
5f3370ef7f Fix Bug #488: 【临床医嘱】双击编辑待签发医嘱,医嘱类型回显为数字且点击确认报接口错误
修复 clickRowDb 函数中编辑条件过于严格的问题:原条件 `row.statusEnum == 1 && !row.requestId`
只允许"待保存"(无requestId)的医嘱进入编辑,导致"待签发"(有requestId)的医嘱无法编辑。
改为 `row.statusEnum == 1`,允许所有待签发状态的医嘱编辑。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 00:11:36 +08:00
张飞
4092abfce9 Fix Bug #477: 住院医生工作站-住院检查申请详情弹窗中"发往科室"字段显示为短横线(-),未正常获取数据
根因分析:
1. 前端组件使用了错误的API获取科室列表:表单使用getDepartmentList(/app-common/department-list)
   保存的targetDepartment ID,但详情弹窗使用getOrgList(/base-data-manage/organization/organization)
   查询,两个接口返回的数据结构和ID不同,导致recursionFun无法匹配到科室名称
2. recursionFun中obj.children可能为null/undefined,直接遍历会抛TypeError
3. getLocationInfo是异步调用,handleViewDetail可能在科室数据加载完成前被调用

修复:
- 统一使用getDepartmentList(@/api/public.js)获取科室数据,与表单组件保持一致
- recursionFun增加children空值保护
- handleViewDetail改为async,打开详情前确保科室数据已加载
2026-05-13 00:05:17 +08:00
7 changed files with 19 additions and 24 deletions

View File

@@ -162,15 +162,11 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
serviceRequest.setEncounterId(encounterId); // 就诊id
serviceRequest.setAuthoredTime(curDate); // 请求签发时间
// 优先使用前端传来的 positionId用户手动选择的发往科室未传时从配置表查找
Long positionId = activitySaveDto.getPositionId();
Long positionId = activityOrganizationConfig.stream()
.filter(dto -> activitySaveDto.getAdviceDefinitionId().equals(dto.getActivityDefinitionId()))
.map(ActivityOrganizationConfigDto::getOrganizationId).findFirst().orElse(null);
if (positionId == null) {
positionId = activityOrganizationConfig.stream()
.filter(dto -> activitySaveDto.getAdviceDefinitionId().equals(dto.getActivityDefinitionId()))
.map(ActivityOrganizationConfigDto::getOrganizationId).findFirst().orElse(null);
if (positionId == null) {
throw new ServiceException(activitySaveDto.getAdviceDefinitionName() + "未配置当前时间段的执行科室");
}
throw new ServiceException(activitySaveDto.getAdviceDefinitionName() + "未配置当前时间段的执行科室");
}
serviceRequest.setOrgId(positionId); // 执行科室

View File

@@ -992,9 +992,7 @@ function handleRowClick(row) {
selectedItems.value = [];
activeDetailTab.value = 'applyForm';
request({ url: `/exam/apply/${row.applyNo}`, method: 'get' }).then(async res => {
// Axios interceptor already returns res.data (AjaxResult body: {code, data, items})
// Don't double-unwrap: if res has 'code', use res directly; otherwise fall back to res.data
const d = (res && res.code !== undefined) ? res : (res.data || res);
const d = res.data || res;
if (d.data) Object.assign(form, d.data);
if (d.items && Array.isArray(d.items)) {
try {

View File

@@ -225,13 +225,9 @@ const submit = () => {
if (transferValue.value.length == 0) {
return proxy.$message.error('请选择申请单');
}
// 🔧 Bug #516: 捕获用户手动选择的发往科室,避免 projectWithDepartment 将其覆盖为默认科室
const savedTargetDept = form.targetDepartment;
if (!projectWithDepartment(transferValue.value, 2)) {
return;
}
// 用户手动选择的发往科室优先于项目默认执行科室
const targetDept = savedTargetDept || form.targetDepartment;
let applicationListAllFilter = applicationListAll.value.filter((item) => {
return transferValue.value.includes(item.adviceDefinitionId);
});
@@ -242,7 +238,7 @@ const submit = () => {
unitCode: item.priceList[0].unitCode /** 请求单位编码 */,
unitPrice: item.priceList[0].price /** 单价 */,
totalPrice: item.priceList[0].price /** 总价 */,
positionId: targetDept || item.positionId, // 用户指定发往科室优先于项目默认执行科室
positionId: item.positionId || form.targetDepartment, //执行科室id未配置时使用用户手动选择的科室
ybClassEnum: item.ybClassEnum, //类别医保编码
conditionId: item.conditionId, //诊断ID
encounterDiagnosisId: item.encounterDiagnosisId, //就诊诊断id

View File

@@ -483,7 +483,7 @@ const submit = () => {
encounterId: patientInfo.value.encounterId,
organizationId: patientInfo.value.inHospitalOrgId,
requestFormId: '',
name: '检查申请单',
name: applicationListAllFilter.map(item => item.adviceName).join('、'),
descJson: JSON.stringify(submitForm),
categoryEnum: '2',
}).then((res) => {

View File

@@ -801,9 +801,7 @@ function clickRowDb(row, column, event) {
return;
}
row.showPopover = false;
// 允许所有 statusEnum==1 的医嘱进入编辑
// 1. 新医嘱(无 requestId待保存
// 2. 护士退回医嘱(有 requestId退回后状态重置为 DRAFT(1),需允许医生编辑修改后重新签发
// 仅”待签发(statusEnum==1)”允许编辑;”已签发(statusEnum==2)”及之后状态不允许编辑
if (row.statusEnum == 1) {
// 确保治疗类型为字符串,方便与单选框 label 对齐,默认为长期医嘱('1')
row.therapyEnum = String(row.therapyEnum ?? '1');

View File

@@ -19,10 +19,14 @@
<el-tab-pane label="检验申请" name="test">
<TestApplication ref="testApplicationRef" :show-status-column="true" />
</el-tab-pane>
```vue
<el-tab-pane label="检查申请" name="examine">
<ExamineApplication ref="examineApplicationRef" />
</el-tab-pane>
<!-- 汇总发药申请属于护士站职能医生站不显示 -->
```
<el-tab-pane label="汇总发药申请" name="summaryDrug">
<SummaryDrugApplication ref="summaryDrugApplicationRef" />
</el-tab-pane>
<el-tab-pane label="手术申请" name="surgery">
<SurgeryApplication ref="surgeryApplicationRef" />
</el-tab-pane>

View File

@@ -1416,9 +1416,12 @@ function closeChargeDialog() {
if (prescriptionRef.value && prescriptionRef.value.closeAllPopovers) {
prescriptionRef.value.closeAllPopovers()
}
showChargeDialog.value = false
chargePatientInfo.value = {}
chargeSurgeryInfo.value = {}
// 等 Vue 完成 DOM 更新后再关闭弹窗,确保 popover 先消失
nextTick(() => {
showChargeDialog.value = false
chargePatientInfo.value = {}
chargeSurgeryInfo.value = {}
})
}
// 🔧 新增:标志位,用于区分是"打开"还是"刷新"