Compare commits

..

9 Commits

Author SHA1 Message Date
赵云
a3049bd1d7 Fix Bug #412: 门诊医生站:传染病报告卡保存失败,提示报错
根因分析:
- 前端在 buildSubmitData() 中使用 formData.diagnosisId || null 将空字符串转为 null
- 后端 InfectiousDiseaseReportDto.diagId 有 @NotNull 校验,导致 null 值被拒绝
- diagnosisId 来源于 show() 中 diagnosisData?.conditionId || diagnosisData?.definitionId
  使用 || 运算符会将 0 等假值跳过,可能导致 ID 丢失

修复内容:
1. show() 函数:使用显式 null/空字符串检查替代 || 运算符,确保 conditionId/definitionId 正确映射
2. handleSubmit():提交前增加 diagnosisId 非空校验,提前拦截并给出友好提示
3. buildSubmitData():diagId 使用 Number() 显式转换,确保发送正确的 Long 值

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

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

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

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 00:13:09 +08:00
2 changed files with 16 additions and 28 deletions

View File

@@ -1318,7 +1318,11 @@ async function show(diagnosisData) {
// 系统关联信息
encounterId: patientInfo.encounterId || '', // 就诊ID
patientId: patientInfo.patientId || '', // 患者ID
diagnosisId: diagnosisData?.conditionId || diagnosisData?.definitionId || '', // 诊断ID
diagnosisId: (diagnosisData?.conditionId != null && diagnosisData?.conditionId !== '')
? diagnosisData.conditionId
: (diagnosisData?.definitionId != null && diagnosisData?.definitionId !== '')
? diagnosisData.definitionId
: '', // 诊断ID
};
// 更新selectedDiseases数组
@@ -1373,7 +1377,7 @@ async function buildSubmitData() {
const submitData = {
cardNo: formData.cardNo,
visitId: props.patientInfo?.encounterId || formData.encounterId || null,
diagId: formData.diagnosisId || null,
diagId: formData.diagnosisId ? Number(formData.diagnosisId) : null,
patId: formData.patientId || null,
idType: 1, // 默认身份证
idNo: formData.idNo,
@@ -1539,6 +1543,12 @@ async function handleSubmit() {
return;
}
// 检查诊断ID是否有效后端 @NotNull 校验要求)
if (!form.value.diagnosisId) {
proxy.$modal.msgError('诊断信息不完整,请重新选择诊断后重试');
return;
}
// 开始加载状态,防止重复提交
submitLoading.value = true;

View File

@@ -682,7 +682,6 @@ async function handleCategoryExpand(cat) {
code: m.code,
price: m.price || 0,
packageName: m.packageName || '',
packageId: m.packageId || null,
packagePrice: m.packagePrice || null,
serviceFee: m.serviceFee || null
}));
@@ -1026,18 +1025,12 @@ function handleRowClick(row) {
code: md.code,
price: m.itemFee || 0, // fallback 到已保存的价格
packageName: md.packageName || '',
packageId: md.packageId || null,
packagePrice: md.packagePrice || null, // Bug #384修复: 套餐价格
serviceFee: md.serviceFee || null
}));
// 如果有已保存的检查方法信息,尝试匹配
if (m.checkMethodId) {
item.selectedMethod = item.methods.find(md => md.id === m.checkMethodId) || null;
// 从已保存的方法中获取套餐信息
if (item.selectedMethod?.packageId) {
item.isPackage = true;
item.packageId = item.selectedMethod.packageId;
}
}
}
} catch (err) {
@@ -1098,13 +1091,6 @@ async function handleMethodSelect(checked, method, cat) {
const existingItem = selectedItems.value.find(s => s.id === targetItem.id);
if (existingItem) {
existingItem.selectedMethod = method;
// 从方法中获取套餐信息
if (method.packageId) {
existingItem.isPackage = true;
existingItem.packageId = method.packageId;
// 预加载套餐明细
loadPackageDetailsForItem(existingItem);
}
updateMethodDisplay();
return;
}
@@ -1119,7 +1105,7 @@ async function handleMethodSelect(checked, method, cat) {
}
}
const newItem = {
selectedItems.value.push({
id: targetItem.id, name: targetItem.name,
price: targetItem.price, quantity: 1,
serviceFee: targetItem.serviceFee || 0,
@@ -1131,16 +1117,9 @@ async function handleMethodSelect(checked, method, cat) {
methods: [method],
selectedMethod: method,
expanded: false,
// 从方法中获取套餐信息(优先级高于项目本身的 packageName
isPackage: !!method.packageId || !!targetItem.packageName,
packageId: method.packageId || targetItem.packageId || null
};
selectedItems.value.push(newItem);
// 如果是套餐,预加载套餐明细
if (newItem.isPackage && newItem.packageId) {
loadPackageDetailsForItem(newItem);
}
isPackage: !!targetItem.packageName,
packageId: targetItem.packageId || null
});
// 自动回填执行科室
if (selectedItems.value.length === 1 && cat?.performDeptName) {
@@ -1185,7 +1164,6 @@ async function handleItemSelect(checked, item, cat) {
code: m.code,
price: m.price || item.price, // fallback 到项目价格
packageName: m.packageName || '',
packageId: m.packageId || null,
packagePrice: m.packagePrice || null, // Bug #384修复: 套餐价格
serviceFee: m.serviceFee || null // Bug #384修复: 服务费
}));