Compare commits

...

7 Commits

Author SHA1 Message Date
赵云
d61373593e Fix Bug #453: 住院医生站-临床医嘱:开立医嘱时输入"级护理"检索结果显示"暂无数据"
根因:新行未选医嘱类型时,adviceType为undefined,handleFocus回退为默认值1(药品)
并携带categoryCode='2'(西药),导致searchKey为空时仅搜索西药库,护理项目被过滤

修复:refresh函数新增adviceType为空时的跨类型搜索分支,同时清空categoryCode
避免按药品分类过滤导致诊疗类护理项目被排除

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 14:08:53 +08:00
赵云
d2699f5cdd Fix Bug #480: [住院护士站-医嘱执行] 非耗材类医嘱执行报"耗材库存"错误且全选逻辑联动异常
根因分析:
1. 非耗材类医嘱执行报"耗材库存"错误: handleExecute 中无条件调用 lotNumberMatch,
   后端会校验该就诊下所有待发放耗材库存,即使当前执行的是口服药等非耗材类医嘱
2. 全选联动异常: msgSuccess 在 handleGetPrescription 之前执行,数据刷新后
   defaultSelectAllRows 重新选中所有行,用户关闭弹窗后看到全选效果

修复方案:
1. 增加医嘱类型判断,仅当选中医嘱包含药品(med_medication_request)或耗材(device)
   类型时才调用 lotNumberMatch
2. 调整执行顺序:先刷新数据再显示成功弹窗,避免用户看到数据刷新的副作用

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 14:06:20 +08:00
赵云
7deba511d4 Fix Bug #494: 住院医生工作站-检查申请:"申请单名称"字段显示为通用名称,未展示具体检查项目名称
根因:保存检查申请时,name 字段硬编码为"检查申请单",导致列表中无法展示具体检查项目名称。
修复:在保存时从选中的检查项目中动态提取名称(使用 adviceName 字段,以"、"分隔拼接),
      当无具体名称时仍使用"检查申请单"作为兜底。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 13:50:00 +08:00
赵云
3fed829cc8 Fix Bug #466: [住院医生工作站-检验申请] 申请单界面缺失核心质控字段(申请类型、标本类型、执行时间)及联动逻辑
根因分析:前端表单已包含申请类型、标本类型、执行时间三个字段,但缺少标本类型联动逻辑。
当医生选择检验项目时,系统应根据所选项目的 sampleType 自动带出标本类型,而非始终显示硬编码默认值"血液"。

修复内容:
- 在 selectedInspectionItems watch 中新增标本类型自动带出逻辑:当标本类型为空或仍为初始化默认值"血液"时,根据第一个检验项目的 sampleType 自动设置
- 当检验项目被清空时,同时清空标本类型(下次选择时会重新自动设置)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 13:49:50 +08:00
赵云
5cbaee98f7 Fix Bug #497: 【住院医生工作站-检查申请】检查申请列表缺失"申请单状态"列及全流程闭环状态流转逻辑
根因:get-check 接口只接收 encounterId 参数,忽略前端传递的 startDate/endDate/status 筛选参数,
导致日期筛选和状态筛选全部失效。同类型的 get-inspection 接口已正确支持这些参数。
修复:在 controller 的 get-check 方法增加 startDate、endDate、status 三个 @RequestParam,
调用 5 参数重载的 service 方法,使筛选参数正确传递到 SQL 层。
前端 examineApplication.vue 已包含状态列、parseStatus 映射、状态筛选下拉框,无需修改。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 13:48:35 +08:00
赵云
d4da94c400 Fix Bug #493: 【住院医生工作站-临床医嘱-检验申请】项目未维护执行科室时,医生手动选择发往科室后仍报错且数据被清空
根因:projectWithDepartment() 在提交时会清空用户手动选择的发往科室,
且项目未配置执行科室时 findTreeItem 返回 null 导致校验失败。
同时 submit() 使用 item.positionId(可能为 undefined)作为执行科室。

修复:
1. 清空科室前保存用户手动选择的值(manualDept)
2. type=2(提交)且 findItem 不存在时,若用户已手动选择科室则恢复并允许通过
3. positionId 兜底使用 form.targetDepartment

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 13:48:13 +08:00
赵云
3103c619f2 Fix Bug #444: 【手术管理-门诊手术安排】生成临时医嘱界面,"已引用计费药品"列表未正常显示药品详细名称信息
根因:后端 getRequestBaseInfo 接口通过 SQL UNION ALL 返回三类数据(药品adviceType=1、耗材adviceType=2、项目adviceType=3),
前端 handleMedicalAdvice 和 handleQuoteBilling 两处过滤逻辑均未按 adviceType 筛选,导致手术诊疗项目(如"小腿烧伤扩创交腿皮瓣修复术")
和检查项目(如"心脏彩色多普勒超声")混入"已引用计费药品"列表。

修复:在两个函数的 filter 条件中增加 adviceType === 1 的判断,仅保留药品类数据。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 13:46:54 +08:00
7 changed files with 56 additions and 22 deletions

View File

@@ -81,14 +81,21 @@ public class RequestFormManageController {
* 查询检查申请单
*
* @param encounterId 就诊id
* @param startDate 开始日期可选格式yyyy-MM-dd
* @param endDate 结束日期可选格式yyyy-MM-dd
* @param status 单据状态(可选)
* @return 检查申请单
*/
@GetMapping(value = "/get-check")
public R<?> getCheckRequestForm(@RequestParam(required = false) Long encounterId) {
public R<?> getCheckRequestForm(
@RequestParam(required = false) Long encounterId,
@RequestParam(required = false) String startDate,
@RequestParam(required = false) String endDate,
@RequestParam(required = false) String status) {
if (encounterId == null) {
return R.fail("就诊ID不能为空");
}
return R.ok(iRequestFormManageAppService.getRequestForm(encounterId, ActivityDefCategory.TEST.getCode()));
return R.ok(iRequestFormManageAppService.getRequestForm(encounterId, ActivityDefCategory.TEST.getCode(), startDate, endDate, status));
}
/**

View File

@@ -2063,15 +2063,20 @@ watch(() => props.patientInfo, async (newVal) => {
}
}, { deep: true, immediate: true })
// Bug #329: 监听已选择的检验项目,自动更新检验项目文本并设置默认执行科室
// Bug #329/#466: 监听已选择的检验项目,自动更新检验项目文本并设置默认执行科室、标本类型
watch(() => selectedInspectionItems.value, async (newVal) => {
if (newVal && newVal.length > 0) {
formData.inspectionItemsText = newVal.map(item => item.itemName).join('+')
const firstItem = newVal[0]
// Bug #466: 如果标本类型为空或仍为初始化默认值,根据第一个检验项目的 sampleType 自动设置默认标本类型
if ((!formData.specimenName || formData.specimenName === '血液') && firstItem.sampleType) {
formData.specimenName = firstItem.sampleType
}
// Bug #329: 如果执行科室为空,根据第一个检验项目的检验类型自动设置默认执行科室
if (!formData.executeDepartment) {
const firstItem = newVal[0]
// 根据检验项目的 inspectionTypeId 获取默认执行科室
if (firstItem.inspectionTypeId) {
const defaultDeptCode = await getDefaultPerformDeptCode(firstItem.inspectionTypeId)
@@ -2081,9 +2086,10 @@ watch(() => selectedInspectionItems.value, async (newVal) => {
}
}
} else {
// Bug #329: 当项目被清空时,同时清空执行科室(下次选择项目时会重新自动设置)
// Bug #329: 当项目被清空时,同时清空执行科室和标本类型(下次选择项目时会重新自动设置)
formData.inspectionItemsText = ''
formData.executeDepartment = ''
formData.specimenName = ''
}
}, { deep: true })

View File

@@ -86,14 +86,14 @@ const tableColumns = computed<TableColumn[]>(() => [
* @param searchKey 搜索关键词
*/
function refresh(adviceType: any, categoryCode: string, searchKey: string) {
// 有搜索词时跨类型搜索,避免用户输入"级护理"但因当前adviceType为药品而搜不到诊疗类护理项目
if (searchKey) {
// 有搜索词时跨类型搜索,或adviceType为空时也跨类型搜索新行未选类型时默认搜全部避免用户输入"级护理"但因当前adviceType为药品而搜不到诊疗类护理项目
if (searchKey || adviceType === undefined || adviceType === '') {
queryParams.value.adviceTypes = '1,2,3,6';
queryParams.value.categoryCode = '';
} else {
queryParams.value.adviceTypes =
adviceType !== undefined && adviceType !== '' ? String(adviceType) : '1,2,3,6';
queryParams.value.adviceTypes = String(adviceType);
queryParams.value.categoryCode = categoryCode || '';
}
queryParams.value.categoryCode = categoryCode || '';
queryParams.value.searchKey = searchKey || '';
getList();
}

View File

@@ -176,6 +176,8 @@ const projectWithDepartment = (selectProjectIds, type) => {
});
arr.push(searchData);
});
// 保存用户手动选择的发往科室(提交时需要保留)
const manualDept = type === 2 ? form.targetDepartment : '';
// 清空科室
form.targetDepartment = '';
if (arr.length > 0) {
@@ -194,11 +196,17 @@ const projectWithDepartment = (selectProjectIds, type) => {
// 选中项目中的执行科室id与全部科室数据做匹配
const findItem = findTreeItem(orgOptions.value, obj.orgId);
if (!findItem) {
isRelease = false;
ElMessage({
type: 'error',
message: '未找到项目执行的科室',
});
// type=2(提交)时,若用户已手动选择发往科室,则允许提交
if (type === 2 && manualDept) {
form.targetDepartment = manualDept;
isRelease = true;
} else {
isRelease = false;
ElMessage({
type: 'error',
message: '未找到项目执行的科室',
});
}
}
if (type == 1) {
if (isRelease) {
@@ -232,7 +240,7 @@ const submit = () => {
unitCode: item.priceList[0].unitCode /** 请求单位编码 */,
unitPrice: item.priceList[0].price /** 单价 */,
totalPrice: item.priceList[0].price /** 总价 */,
positionId: item.positionId, //执行科室id
positionId: item.positionId || form.targetDepartment, //执行科室id未配置时使用用户手动选择的科室
ybClassEnum: item.ybClassEnum, //类别医保编码
conditionId: item.conditionId, //诊断ID
encounterDiagnosisId: item.encounterDiagnosisId, //就诊诊断id

View File

@@ -281,13 +281,14 @@ const submit = () => {
accountId: patientInfo.value.accountId, // // 账户id
};
});
const itemNames = applicationListAllFilter.map(item => item.adviceName).filter(Boolean).join('、');
saveCheckd({
activityList: applicationListAllFilter,
patientId: patientInfo.value.patientId, //患者ID
encounterId: patientInfo.value.encounterId, // 就诊ID
organizationId: patientInfo.value.inHospitalOrgId, // 医疗机构ID
requestFormId: '', // 申请单ID
name: '检查申请单',
name: itemNames || '检查申请单',
descJson: JSON.stringify(form),
categoryEnum: '2', // 1 检验 2 检查 3 输血 4 手术
}).then((res) => {

View File

@@ -469,11 +469,19 @@ function handleExecute() {
console.log(list, 'list');
adviceExecute({ exeDate: exeDate.value, adviceExecuteDetailList: list }).then((res) => {
if (res.code == 200) {
proxy.$modal.msgSuccess(res.msg || '医嘱执行成功');
handleGetPrescription();
lotNumberMatch({ encounterIdList: encounterIds }, { skipErrorMsg: true }).catch((error) => {
console.warn('lotNumberMatch failed after adviceExecute:', error);
});
// 仅当选中医嘱中包含药品/耗材类医嘱时,才调用耗材批号匹配
const hasMedOrDevice = list.some(
(item) =>
item.adviceTable === 'med_medication_request' ||
String(item.adviceTable || '').includes('device'),
);
if (hasMedOrDevice) {
lotNumberMatch({ encounterIdList: encounterIds }, { skipErrorMsg: true }).catch((error) => {
console.warn('lotNumberMatch failed after adviceExecute:', error);
});
}
proxy.$modal.msgSuccess(res.msg || '医嘱执行成功');
} else {
proxy.$modal.msgError(res.msg || '医嘱执行失败');
}

View File

@@ -1481,6 +1481,8 @@ function handleMedicalAdvice(row) {
const filteredItems = res.data.filter(item => {
// 匹配 encounterId
if (item.encounterId !== row.visitId) return false;
// 仅保留药品adviceType=1过滤耗材(2)和项目(3)
if (item.adviceType !== 1 && item.advice_type !== 1) return false;
// 过滤掉名称为空的项目
const medicineName = item.adviceName || item.advice_name;
if (!medicineName || medicineName.trim() === '') return false;
@@ -1743,6 +1745,8 @@ function handleQuoteBilling() {
const filteredItems = res.data.filter(item => {
// 匹配 encounterId
if (item.encounterId !== temporaryPatientInfo.value.visitId) return false;
// 仅保留药品adviceType=1过滤耗材(2)和项目(3)
if (item.adviceType !== 1 && item.advice_type !== 1) return false;
// 过滤掉名称为空的项目
const medicineName = item.adviceName || item.advice_name;
return medicineName && medicineName.trim() !== '';