Compare commits
9 Commits
bug464-fix
...
4b9553323e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b9553323e | ||
|
|
c9a158ddee | ||
|
|
a2095775bd | ||
|
|
c6f58596c0 | ||
|
|
4492666008 | ||
|
|
884fe09706 | ||
|
|
94040e68fb | ||
|
|
ae50a7042e | ||
|
|
9b1ac64cd6 |
@@ -178,6 +178,8 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
inpatientAdviceParam.setEncounterIds(null);
|
||||
Integer exeStatus = inpatientAdviceParam.getExeStatus();
|
||||
inpatientAdviceParam.setExeStatus(null);
|
||||
// requestStatus由前端tab控制,后端SQL已通过CASE条件处理校对状态过滤,无需再作为SQL条件
|
||||
inpatientAdviceParam.setRequestStatus(null);
|
||||
// 构建查询条件
|
||||
QueryWrapper<InpatientAdviceParam> queryWrapper
|
||||
= HisQueryUtils.buildQueryWrapper(inpatientAdviceParam, null, null, null);
|
||||
|
||||
@@ -280,9 +280,13 @@
|
||||
aa.balance_amount
|
||||
) AS personal_account
|
||||
ON personal_account.encounter_id = ae.id
|
||||
LEFT JOIN med_medication_dispense mmd
|
||||
ON mmd.med_req_id = T1.id
|
||||
AND mmd.delete_flag = '0'
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT status_enum
|
||||
FROM med_medication_dispense
|
||||
WHERE med_req_id = T1.id AND delete_flag = '0'
|
||||
ORDER BY create_time DESC
|
||||
LIMIT 1
|
||||
) mmd ON true
|
||||
WHERE T1.delete_flag = '0'
|
||||
AND T1.refund_medicine_id IS NULL
|
||||
AND T1.generate_source_enum = #{doctorPrescription}
|
||||
|
||||
@@ -13,15 +13,14 @@
|
||||
drf.requester_id,
|
||||
drf.create_time,
|
||||
ap.NAME AS patient_name,
|
||||
CASE MIN(wsr.status_enum)
|
||||
WHEN 1 THEN 0
|
||||
WHEN 2 THEN 1
|
||||
WHEN 3 THEN 4
|
||||
WHEN 4 THEN 4
|
||||
WHEN 5 THEN 5
|
||||
WHEN 6 THEN 5
|
||||
WHEN 7 THEN 5
|
||||
WHEN 8 THEN 6
|
||||
CASE
|
||||
WHEN MIN(wsr.status_enum) = 1 THEN 0
|
||||
WHEN MIN(wsr.status_enum) = 2 THEN 1
|
||||
WHEN MIN(wsr.status_enum) = 3 AND MAX(CASE WHEN wsr.performer_check_id IS NOT NULL THEN 1 ELSE 0 END) = 1 THEN 2
|
||||
WHEN MIN(wsr.status_enum) = 3 THEN 4
|
||||
WHEN MIN(wsr.status_enum) = 4 THEN 3
|
||||
WHEN MIN(wsr.status_enum) = 5 OR MIN(wsr.status_enum) = 6 OR MIN(wsr.status_enum) = 7 THEN 7
|
||||
WHEN MIN(wsr.status_enum) = 8 THEN 6
|
||||
ELSE NULL
|
||||
END AS status
|
||||
FROM doc_request_form AS drf
|
||||
@@ -41,15 +40,14 @@
|
||||
AND drf.create_time <= (#{endDate}::date + INTERVAL '1 day' - INTERVAL '1 second')
|
||||
</if>
|
||||
<if test="status != null and status != ''">
|
||||
AND CASE MIN(wsr.status_enum)
|
||||
WHEN 1 THEN 0
|
||||
WHEN 2 THEN 1
|
||||
WHEN 3 THEN 4
|
||||
WHEN 4 THEN 4
|
||||
WHEN 5 THEN 5
|
||||
WHEN 6 THEN 5
|
||||
WHEN 7 THEN 5
|
||||
WHEN 8 THEN 6
|
||||
AND CASE
|
||||
WHEN MIN(wsr.status_enum) = 1 THEN 0
|
||||
WHEN MIN(wsr.status_enum) = 2 THEN 1
|
||||
WHEN MIN(wsr.status_enum) = 3 AND MAX(CASE WHEN wsr.performer_check_id IS NOT NULL THEN 1 ELSE 0 END) = 1 THEN 2
|
||||
WHEN MIN(wsr.status_enum) = 3 THEN 4
|
||||
WHEN MIN(wsr.status_enum) = 4 THEN 3
|
||||
WHEN MIN(wsr.status_enum) = 5 OR MIN(wsr.status_enum) = 6 OR MIN(wsr.status_enum) = 7 THEN 7
|
||||
WHEN MIN(wsr.status_enum) = 8 THEN 6
|
||||
ELSE NULL
|
||||
END = #{status}::integer
|
||||
</if>
|
||||
@@ -164,7 +162,7 @@
|
||||
AND drf.prescription_no LIKE CONCAT('%', #{requestFormDto.surgeryNo}, '%')
|
||||
</if>
|
||||
<if test="requestFormDto.typeCode != null and requestFormDto.typeCode != ''">
|
||||
AND drf.type_code = #{requestFormDto.typeCode}
|
||||
AND drf.type_code IN (#{requestFormDto.typeCode}, 'SURGERY')
|
||||
</if>
|
||||
<if test="requestFormDto.applyTimeStart != null">
|
||||
AND drf.create_time >= #{requestFormDto.applyTimeStart}
|
||||
|
||||
@@ -49,6 +49,11 @@ public enum RequestStatus implements HisEnumInterface {
|
||||
*/
|
||||
ENDED(7, "ended", "不执行"),
|
||||
|
||||
/**
|
||||
* 已出报告
|
||||
*/
|
||||
COMPLETED_REPORT(8, "completed_report", "已出报告"),
|
||||
|
||||
/**
|
||||
* 未知
|
||||
*/
|
||||
|
||||
@@ -473,15 +473,12 @@ function calculateTotalPrice() {
|
||||
}
|
||||
});
|
||||
totalPrice.value = sum.toFixed(2);
|
||||
// Bug #464: 零售价与诊疗子项合计总价实时同步
|
||||
// Bug #464: 零售价与诊疗子项合计总价实时同步,直接赋值不使用nextTick避免多调用方竞争
|
||||
const hasValidItem = treatmentItems.value.some(
|
||||
(item) => item.adviceDefinitionId && item.adviceDefinitionId !== ''
|
||||
);
|
||||
if (hasValidItem) {
|
||||
// 使用 nextTick 确保总价更新后零售价才更新,避免 Vue 响应式时序问题
|
||||
nextTick(() => {
|
||||
form.value.retailPrice = parseFloat(totalPrice.value) || 0;
|
||||
});
|
||||
form.value.retailPrice = parseFloat(totalPrice.value) || 0;
|
||||
} else {
|
||||
form.value.retailPrice = undefined;
|
||||
}
|
||||
@@ -763,10 +760,7 @@ function selectRow(row, index) {
|
||||
treatmentItems.value[index].adviceDefinitionId = row.id;
|
||||
treatmentItems.value[index].retailPrice = row.retailPrice || 0;
|
||||
medicineSearchKey.value = '';
|
||||
// 使用 nextTick 确保 DOM 更新后再计算总价
|
||||
nextTick(() => {
|
||||
calculateTotalPrice();
|
||||
});
|
||||
calculateTotalPrice();
|
||||
}
|
||||
|
||||
// 清空诊疗子项
|
||||
|
||||
@@ -56,6 +56,13 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="申请单号" prop="applyNo" min-width="160" align="center" header-align="center" />
|
||||
<el-table-column label="单据状态" prop="applyStatus" width="100" align="center" header-align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="getStatusType(scope.row.applyStatus)" size="small">
|
||||
{{ getStatusLabel(scope.row.applyStatus, scope.row) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="检验项目" prop="itemName" min-width="170px" align="center" header-align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.itemName }}</span>
|
||||
@@ -1445,6 +1452,26 @@ const formatAmount = (amount) => {
|
||||
return num.toFixed(2)
|
||||
}
|
||||
|
||||
// 单据状态标签文字
|
||||
const getStatusLabel = (applyStatus, row) => {
|
||||
// applyStatus: 0=待开立, 1=已开立(已签发)
|
||||
// 结合收费/执行标记推导更丰富的状态
|
||||
if (applyStatus === 1) {
|
||||
// 已收费后根据执行标记判断
|
||||
if (row.needExecute === true) {
|
||||
return '已执行'
|
||||
}
|
||||
return '已开立'
|
||||
}
|
||||
return '待开立'
|
||||
}
|
||||
|
||||
// 单据状态标签颜色
|
||||
const getStatusType = (applyStatus) => {
|
||||
if (applyStatus === 1) return 'success'
|
||||
return 'info'
|
||||
}
|
||||
|
||||
// 格式化日期时间为字符串 YYYY-MM-DD HH:mm:ss
|
||||
const formatDateTime = (date) => {
|
||||
if (!date) return ''
|
||||
|
||||
@@ -513,6 +513,30 @@ const findTreeItem = (list, id) => {
|
||||
return null;
|
||||
};
|
||||
|
||||
const recursionFun = (targetDepartment) => {
|
||||
if (!targetDepartment) return '';
|
||||
let name = '';
|
||||
for (let index = 0; index < orgOptions.value.length; index++) {
|
||||
const obj = orgOptions.value[index];
|
||||
if (obj.id == targetDepartment) {
|
||||
name = obj.name;
|
||||
break;
|
||||
}
|
||||
const subObjArray = obj['children'];
|
||||
if (subObjArray && subObjArray.length > 0) {
|
||||
for (let i = 0; i < subObjArray.length; i++) {
|
||||
const item = subObjArray[i];
|
||||
if (item.id == targetDepartment) {
|
||||
name = item.name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (name) break;
|
||||
}
|
||||
return name;
|
||||
};
|
||||
|
||||
const handleViewDetail = async (row) => {
|
||||
// 确保科室数据已加载,以便将 ID 解析为名称
|
||||
if (!orgOptions.value || orgOptions.value.length === 0) {
|
||||
@@ -526,8 +550,7 @@ const handleViewDetail = async (row) => {
|
||||
const obj = JSON.parse(row.descJson);
|
||||
// 将发往科室 ID 转换为名称
|
||||
if (obj.targetDepartment) {
|
||||
const deptItem = findTreeItem(orgOptions.value, obj.targetDepartment);
|
||||
obj.targetDepartment = deptItem ? deptItem.name : obj.targetDepartment;
|
||||
obj.targetDepartment = recursionFun(obj.targetDepartment);
|
||||
}
|
||||
descJsonData.value = obj;
|
||||
} catch (e) {
|
||||
|
||||
@@ -183,6 +183,26 @@
|
||||
<el-button @click="detailDialogVisible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 编辑检验申请单弹窗 -->
|
||||
<el-dialog
|
||||
v-model="editDialogVisible"
|
||||
title="编辑检验申请单"
|
||||
width="1200px"
|
||||
destroy-on-close
|
||||
top="5vh"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<LaboratoryTests
|
||||
ref="editFormRef"
|
||||
@submitOk="handleEditSubmitOk"
|
||||
:editData="editRowData"
|
||||
/>
|
||||
<template #footer>
|
||||
<el-button @click="editDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitEditForm">确认</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -192,12 +212,17 @@ import {Refresh, Search} from '@element-plus/icons-vue';
|
||||
import {patientInfo} from '../../store/patient.js';
|
||||
import {getInspection, deleteRequestForm, withdrawRequestForm} from './api';
|
||||
import {getDepartmentList} from '@/api/public.js';
|
||||
import LaboratoryTests from '../order/applicationForm/laboratoryTests.vue';
|
||||
import {saveInspection} from '../order/applicationForm/api.js';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const tableData = ref([]);
|
||||
const loading = ref(false);
|
||||
const detailDialogVisible = ref(false);
|
||||
const editDialogVisible = ref(false);
|
||||
const editRowData = ref(null);
|
||||
const editFormRef = ref(null);
|
||||
const currentDetail = ref(null);
|
||||
const descJsonData = ref(null);
|
||||
const orgOptions = ref([]);
|
||||
@@ -433,10 +458,32 @@ const handleViewDetail = async (row) => {
|
||||
/**
|
||||
* 修改检验申请单(待签发状态)
|
||||
*/
|
||||
const handleEdit = (row) => {
|
||||
// 复用详情查看逻辑,后续可扩展为打开编辑弹窗
|
||||
handleViewDetail(row);
|
||||
proxy.$modal?.msgInfo?.('修改功能待接入,请通过详情弹窗查看后重新开立');
|
||||
const handleEdit = async (row) => {
|
||||
// 确保科室数据已加载
|
||||
if (!orgOptions.value || orgOptions.value.length === 0) {
|
||||
await getLocationInfo();
|
||||
}
|
||||
editRowData.value = row;
|
||||
editDialogVisible.value = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑弹窗提交成功回调
|
||||
*/
|
||||
const handleEditSubmitOk = async () => {
|
||||
editDialogVisible.value = false;
|
||||
editRowData.value = null;
|
||||
proxy.$modal?.msgSuccess?.('修改成功');
|
||||
await fetchData();
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑弹窗提交按钮
|
||||
*/
|
||||
const submitEditForm = () => {
|
||||
if (editFormRef.value?.submit) {
|
||||
editFormRef.value.submit();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -450,7 +497,7 @@ const handleDelete = async (row) => {
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await deleteRequestForm({ prescriptionNo: row.prescriptionNo });
|
||||
const res = await deleteRequestForm({ requestFormId: row.requestFormId });
|
||||
if (res?.code === 200) {
|
||||
proxy.$modal?.msgSuccess?.('删除成功');
|
||||
await fetchData();
|
||||
@@ -473,7 +520,7 @@ const handleWithdraw = async (row) => {
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await withdrawRequestForm({ prescriptionNo: row.prescriptionNo });
|
||||
const res = await withdrawRequestForm({ requestFormId: row.requestFormId });
|
||||
if (res?.code === 200) {
|
||||
proxy.$modal?.msgSuccess?.('撤回成功');
|
||||
await fetchData();
|
||||
|
||||
@@ -155,7 +155,13 @@ const findTreeItem = (list, id) => {
|
||||
return null;
|
||||
};
|
||||
const emits = defineEmits(['submitOk']);
|
||||
const props = defineProps({});
|
||||
const props = defineProps({
|
||||
editData: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
const isEditMode = computed(() => !!props.editData?.requestFormId);
|
||||
const state = reactive({});
|
||||
const applicationListAll = ref([]);
|
||||
const loading = ref(false);
|
||||
@@ -331,6 +337,44 @@ watch(
|
||||
projectWithDepartment(newValue, 1);
|
||||
}
|
||||
);
|
||||
|
||||
// 编辑模式下,回显已有数据
|
||||
watch(
|
||||
() => props.editData,
|
||||
(newData) => {
|
||||
if (!newData || !newData.requestFormId) return;
|
||||
|
||||
// 解析 descJson 回填表单
|
||||
if (newData.descJson) {
|
||||
try {
|
||||
const obj = JSON.parse(newData.descJson);
|
||||
Object.keys(form).forEach((key) => {
|
||||
if (obj[key] !== undefined) {
|
||||
form[key] = obj[key];
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('解析 descJson 失败:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// 回填已选项目
|
||||
if (newData.requestFormDetailList && newData.requestFormDetailList.length > 0) {
|
||||
// 从全部数据中匹配已选项目
|
||||
const selectedIds = [];
|
||||
newData.requestFormDetailList.forEach((detail) => {
|
||||
const matched = applicationListAll.value.find(
|
||||
(item) => item.adviceName === detail.adviceName
|
||||
);
|
||||
if (matched) {
|
||||
selectedIds.push(matched.adviceDefinitionId);
|
||||
}
|
||||
});
|
||||
transferValue.value = selectedIds;
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
const submit = () => {
|
||||
if (transferValue.value.length == 0) {
|
||||
return proxy.$message.error('请选择申请单');
|
||||
@@ -363,14 +407,14 @@ const submit = () => {
|
||||
patientId: patientInfo.value.patientId, //患者ID
|
||||
encounterId: patientInfo.value.encounterId, // 就诊ID
|
||||
organizationId: patientInfo.value.inHospitalOrgId, // 医疗机构ID
|
||||
requestFormId: '', // 申请单ID
|
||||
requestFormId: isEditMode.value ? props.editData.requestFormId : '', // 申请单ID(编辑模式传入,新增为空)
|
||||
name: '检验申请单',
|
||||
descJson: JSON.stringify(form),
|
||||
categoryEnum: '21', // 21 检验 22 检查 23 输血 24 手术(避开 adviceType 1-6 碰撞)
|
||||
};
|
||||
saveInspection(params).then((res) => {
|
||||
if (res.code === 200) {
|
||||
proxy.$message.success(res.msg);
|
||||
proxy.$message.success(isEditMode.value ? '修改成功' : res.msg);
|
||||
transferValue.value = [];
|
||||
emits('submitOk');
|
||||
} else {
|
||||
|
||||
@@ -606,21 +606,26 @@ function getItemType_Text(type) {
|
||||
return map[type] || '其他';
|
||||
}
|
||||
function getUnitCodeOptions(row) {
|
||||
const unitCodes = [
|
||||
{ code: row.unitCode != null ? String(row.unitCode) : null, codeText: row.unitCode_dictText },
|
||||
{ code: row.minUnitCode != null ? String(row.minUnitCode) : null, codeText: row.minUnitCode_dictText },
|
||||
];
|
||||
// 过滤掉 code 为空的单位选项
|
||||
const validUnitCodes = unitCodes.filter(item => item.code != null && item.code !== '');
|
||||
// 使用 Set 来跟踪已经存在的 code
|
||||
const unitCodes = [];
|
||||
// 大单位:优先用 code,code 缺失时用字典文本兜底
|
||||
if (row.unitCode != null && String(row.unitCode) !== '') {
|
||||
unitCodes.push({ code: String(row.unitCode), codeText: row.unitCode_dictText });
|
||||
} else if (row.unitCode_dictText) {
|
||||
unitCodes.push({ code: row.unitCode_dictText, codeText: row.unitCode_dictText });
|
||||
}
|
||||
// 小单位:同上
|
||||
if (row.minUnitCode != null && String(row.minUnitCode) !== '') {
|
||||
unitCodes.push({ code: String(row.minUnitCode), codeText: row.minUnitCode_dictText });
|
||||
} else if (row.minUnitCode_dictText) {
|
||||
unitCodes.push({ code: row.minUnitCode_dictText, codeText: row.minUnitCode_dictText });
|
||||
}
|
||||
// 去重
|
||||
const seenCodes = new Set();
|
||||
const uniqueUnitCodes = validUnitCodes.filter((item) => {
|
||||
// 如果 Set 中没有这个 code,就保留它,并把它加入 Set
|
||||
const uniqueUnitCodes = unitCodes.filter((item) => {
|
||||
if (!seenCodes.has(item.code)) {
|
||||
seenCodes.add(item.code);
|
||||
return true;
|
||||
}
|
||||
// 如果已经存在,就过滤掉
|
||||
return false;
|
||||
});
|
||||
return uniqueUnitCodes;
|
||||
|
||||
@@ -463,20 +463,45 @@ function watchPatientSelection() {
|
||||
}, 300);
|
||||
}
|
||||
|
||||
/** 查询科室 */
|
||||
/** 查询科室(支持树形/扁平多种响应结构) */
|
||||
const getLocationInfo = () => {
|
||||
getOrgList().then((res) => {
|
||||
orgOptions.value = res.data?.records[0]?.children;
|
||||
if (!res.data) {
|
||||
orgOptions.value = [];
|
||||
return;
|
||||
}
|
||||
// 尝试从树形结构取:records[0].children
|
||||
if (res.data.records && res.data.records.length > 0) {
|
||||
if (res.data.records[0].children && res.data.records[0].children.length > 0) {
|
||||
orgOptions.value = res.data.records[0].children;
|
||||
return;
|
||||
}
|
||||
// 如果 records[0] 有 id 和 name(非树根节点),直接用所有 records
|
||||
if (res.data.records[0].id) {
|
||||
orgOptions.value = res.data.records;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 兜底:如果 data 本身是数组
|
||||
if (Array.isArray(res.data)) {
|
||||
orgOptions.value = res.data;
|
||||
return;
|
||||
}
|
||||
orgOptions.value = [];
|
||||
}).catch(() => {
|
||||
console.warn('科室列表加载失败(可能无权限)');
|
||||
orgOptions.value = [];
|
||||
});
|
||||
};
|
||||
getLocationInfo();
|
||||
|
||||
// 映射
|
||||
// 映射(查找失败时返回 '-' 而非显示内码)
|
||||
const selectOrg = (itemid) => {
|
||||
if (!itemid) return '-';
|
||||
const item = orgOptions.value.find((item) => {
|
||||
return item.id == itemid;
|
||||
});
|
||||
return item?.name;
|
||||
return item?.name || '-';
|
||||
};
|
||||
// 重置
|
||||
const onReset = () => {
|
||||
|
||||
Reference in New Issue
Block a user