18 Commits

Author SHA1 Message Date
c687167044 bug 486 [住院医生工作站-临床医嘱] 医嘱检索框不支持全局模糊搜索,未选“医嘱类型”时检索结果为空 删去了搜索条件的默认值 2026-05-11 23:05:11 +08:00
wangjian963
7aa93c34a5 506 门诊挂号:门诊诊前退号后,数据库多表状态值变更与 PRD 定义不符
CommonConstants.AppointmentOrderStatus 常量 → OrderStatus 枚举重构
   新增枚举:0=患者取消 / 1=有效 / 2=系统取消 / 3=已完成
   退号流程加乐观锁防并发,slot 状态改回待约,退号日志独立事务 修复 XML 中 Integer 比较用字符串的问题
Bug #411 — 诊室过滤栏从科室下拉框改为诊室按钮组
2026-05-11 23:05:11 +08:00
赵云
a844920e3f Fix Bug #502: 【住院护士站-汇总发药申请】顶部医嘱类型(长期/临时)过滤按钮点击无响应
根因:父组件 index.vue 中 therapyEnum 变量未声明为 ref,且未通过 props 传递给子组件 prescriptionList.vue,
导致点击"长期/临时"按钮时数据流断裂,子组件 API 调用始终使用本地未变化的 therapyEnum 值。

修复:
1. index.vue 新增 const therapyEnum = ref(undefined)
2. index.vue 新增 handleTherapyChange() 调用 handleGetPrescription() 刷新列表
3. index.vue 将 therapyEnum 作为 prop 传入 PrescriptionList
4. prescriptionList.vue 将本地 therapyEnum ref 改为 props 接收
2026-05-11 15:26:58 +08:00
赵云
b02c6f6456 fix: 恢复 Bug #497 的后端修改 + 数据库字段同步 (ALTER TABLE doc_request_form ADD COLUMN status) 2026-05-11 15:26:58 +08:00
关羽
9e2d683e19 fix: 还原 Bug #443/#475/#477/#486/#497 引入的 getRequestForm 编译错误 2026-05-11 15:26:58 +08:00
赵云
51f4b84842 fix: 完整回退 Bug #497 的后端修改(SQL/Java接口/Impl/Dto) 2026-05-11 15:26:58 +08:00
关羽
c0ea55a74d Fix Bug #486: [住院医生工作站-临床医嘱] 医嘱检索框不支持全局模糊搜索,未选"医嘱类型"时检索结果为空
根因:handleFocus/handleChange 中 categoryCode 的计算逻辑错误。当新增行未选择
医嘱类型时(row.adviceType 为 undefined),代码回退到 adviceQueryParams 的默认值并
匹配到具体药品分类(如西药 categoryCode='2'),导致搜索被限制在单一分类而非全局药库。

修复:简化 categoryCode 判定为 `row.adviceType !== undefined ? selectedItem.categoryCode : ''`,
未选类型时传空 categoryCode,使 searchKey 在全药库范围内模糊匹配。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 15:26:58 +08:00
赵云
7990247a97 fix: 完全回退 Bug #497 引入的 drf.status 字段(数据库不存在) 2026-05-11 15:26:58 +08:00
关羽
94a6f9553c Fix Bug #477: 住院医生工作站-住院检查申请详情弹窗中"发往科室"字段显示为短横线(-),未正常获取数据
根因:handleViewDetail 为同步方法,点击详情时 getLocationInfo 尚未返回,
orgOptions 为空导致 recursionFun 无法将 targetDepartment ID 解析为科室名称。

修复:
1. 前端(4个申请组件):handleViewDetail 改为 async,解析 descJson 前确保 orgOptions 已加载
2. 前端:watch encounterId 改为 Promise.all 并行加载数据和科室列表
3. 后端:新增 keyword 关键字筛选参数(申请单号/检查项目模糊匹配)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 15:26:58 +08:00
关羽
bef429df0c Fix Bug #491: 【执行科室配置】保存配置时系统报错
根因: addOrEditOrgLoc 方法中 organizationService.getById() 返回 null 时
直接调用 .getName() 导致 NullPointerException。当数据库中某条执行科室配置
关联的 organizationId 对应的科室记录已被删除时触发此问题。

修复: 在调用 getName() 前增加 null 检查,返回"未知科室"作为降级提示。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 15:26:58 +08:00
关羽
aaaf548003 Fix Bug #500: 【门诊医生站】检查申请右侧"检查项目分类"切换时,界面出现明显抖动/闪烁
根因分析:
1. el-collapse accordion 模式下快速切换分类时,连续的折叠/展开动画重叠,
   Element Plus 在动画过程中重新计算面板高度,导致高度跳变和白屏闪烁
2. 折叠容器缺少 overflow:hidden,动画过渡期间内容溢出造成闪烁

修复方案:
1. 添加 isAnimating 防抖标志,handleCollapseChange 中 300ms 内忽略后续点击
   (与 CSS 过渡时长一致),让当前动画完整执行后再响应下一次切换
2. .collapse-scroll 添加 overflow-x:hidden,防止水平方向溢出
3. :deep(.el-collapse-item__wrap) 添加 overflow:hidden 替代 will-change:height,
   避免强制 GPU 合成层带来的性能开销

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 15:26:58 +08:00
赵云
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
5 changed files with 25 additions and 17 deletions

View File

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

View File

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

View File

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

View File

@@ -197,7 +197,6 @@
style="width: 62%" style="width: 62%"
v-model="scope.row.adviceName" v-model="scope.row.adviceName"
placeholder="请选择项目" placeholder="请选择项目"
@input="handleChange"
@click="handleFocus(scope.row, scope.$index)" @click="handleFocus(scope.row, scope.$index)"
@keyup.enter.stop="handleFocus(scope.row, scope.$index)" @keyup.enter.stop="handleFocus(scope.row, scope.$index)"
@keydown=" @keydown="
@@ -380,7 +379,7 @@ const form = ref({
prescriptionList: prescriptionList.value, prescriptionList: prescriptionList.value,
}); });
const adviceQueryParams = ref({ const adviceQueryParams = ref({
adviceType: 1, adviceType: '',
categoryCode: '', // 初始为空,等待加载配置后动态设置 categoryCode: '', // 初始为空,等待加载配置后动态设置
searchKey: '', searchKey: '',
}); });
@@ -686,7 +685,7 @@ function loadConfiguredCategories() {
nextTick(() => { nextTick(() => {
// 创建新对象触发响应式更新 // 创建新对象触发响应式更新
adviceQueryParams.value = { adviceQueryParams.value = {
adviceType: 1, adviceType: '',
categoryCode: defaultCategoryCode, categoryCode: defaultCategoryCode,
searchKey: '', searchKey: '',
}; };
@@ -802,10 +801,8 @@ function clickRowDb(row, column, event) {
return; return;
} }
row.showPopover = false; row.showPopover = false;
// 允许所有 statusEnum==1 的医嘱进入编辑 // “待签发(已保存 requestId存在)”不允许再编辑;仅“待保存(无requestId)”允许编辑
// 1. 新医嘱(无 requestId):待保存 if (row.statusEnum == 1 && !row.requestId) {
// 2. 护士退回医嘱(有 requestId退回后状态重置为 DRAFT(1),需允许医生编辑修改后重新签发
if (row.statusEnum == 1) {
// 确保治疗类型为字符串,方便与单选框 label 对齐,默认为长期医嘱('1') // 确保治疗类型为字符串,方便与单选框 label 对齐,默认为长期医嘱('1')
row.therapyEnum = String(row.therapyEnum ?? '1'); row.therapyEnum = String(row.therapyEnum ?? '1');
row.isEdit = true; row.isEdit = true;

View File

@@ -1481,6 +1481,8 @@ function handleMedicalAdvice(row) {
const filteredItems = res.data.filter(item => { const filteredItems = res.data.filter(item => {
// 匹配 encounterId // 匹配 encounterId
if (item.encounterId !== row.visitId) return false; 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; const medicineName = item.adviceName || item.advice_name;
if (!medicineName || medicineName.trim() === '') return false; if (!medicineName || medicineName.trim() === '') return false;
@@ -1743,6 +1745,8 @@ function handleQuoteBilling() {
const filteredItems = res.data.filter(item => { const filteredItems = res.data.filter(item => {
// 匹配 encounterId // 匹配 encounterId
if (item.encounterId !== temporaryPatientInfo.value.visitId) return false; 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; const medicineName = item.adviceName || item.advice_name;
return medicineName && medicineName.trim() !== ''; return medicineName && medicineName.trim() !== '';