diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/consultation/appservice/impl/ConsultationAppServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/consultation/appservice/impl/ConsultationAppServiceImpl.java index 3405ddf7..54007cda 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/consultation/appservice/impl/ConsultationAppServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/consultation/appservice/impl/ConsultationAppServiceImpl.java @@ -725,47 +725,50 @@ public class ConsultationAppServiceImpl implements IConsultationAppService { dto.setInvitedList(invitedDtoList); - // 🎯 如果会诊已完成或已签名,填充会诊记录信息(从已签名的医生中获取) - if (entity.getConsultationStatus() != null && - (entity.getConsultationStatus() == ConsultationStatusEnum.SIGNED.getCode() || - entity.getConsultationStatus() == ConsultationStatusEnum.COMPLETED.getCode())) { - - // 查询所有已确认和已签名的医生(invited_status >= 2) - // invited_status: 1-已提交,2-已确认,3-已签名 + + // 🎯 如果会诊已确认、已签名或已完成,填充会诊记录信息 + // 会诊状态:20=已确认,30=已签名,40=已完成 + if (entity.getConsultationStatus() != null && + entity.getConsultationStatus() >= ConsultationStatusEnum.CONFIRMED.getCode()) { + + // 查询所有已确认和已签名的医生(invited_status >= 20) List confirmedAndSignedPhysicians = invitedList.stream() - .filter(inv -> inv.getInvitedStatus() != null && inv.getInvitedStatus() >= 2) + .filter(inv -> inv.getInvitedStatus() != null && inv.getInvitedStatus() >= ConsultationStatusEnum.CONFIRMED.getCode()) .collect(Collectors.toList()); - - // 查询所有已签名的医生(invited_status = 3) + + // 查询所有已签名的医生(invited_status >= 30) List signedPhysicians = invitedList.stream() - .filter(inv -> inv.getInvitedStatus() != null && inv.getInvitedStatus() >= 3) + .filter(inv -> inv.getInvitedStatus() != null && inv.getInvitedStatus() >= ConsultationStatusEnum.SIGNED.getCode()) .collect(Collectors.toList()); - + if (!confirmedAndSignedPhysicians.isEmpty()) { - // 1. 会诊邀请参加医师:拼接所有已确认和已签名医生的"科室 - 姓名" + // 1. 会诊确认参加医师:拼接所有已确认和已签名医生的"科室 - 姓名" String invitedPhysiciansText = confirmedAndSignedPhysicians.stream() .map(inv -> inv.getInvitedDepartmentName() + "-" + inv.getInvitedPhysicianName()) .collect(Collectors.joining("、")); dto.setInvitedPhysiciansText(invitedPhysiciansText); - - // 2. 会诊意见:汇总所有已签名医生的意见(只有已签名医生才能填写意见) + + // 2. 会诊意见:汇总所有已确认医生的意见 + String consultationOpinion = confirmedAndSignedPhysicians.stream() + .filter(inv -> StringUtils.hasText(inv.getConfirmOpinion())) + .map(ConsultationInvited::getConfirmOpinion) + .collect(Collectors.joining("\n")); + dto.setConsultationOpinion(consultationOpinion); + + // 3. 所属医生、代表科室:使用第一个确认的医生 + ConsultationInvited firstConfirmed = confirmedAndSignedPhysicians.get(0); + dto.setAttendingPhysician(firstConfirmed.getInvitedPhysicianName()); + dto.setRepresentDepartment(firstConfirmed.getInvitedDepartmentName()); + + // 4. 签名医生、签名时间:只有已签名医生才有 if (!signedPhysicians.isEmpty()) { - String consultationOpinion = signedPhysicians.stream() - .filter(inv -> StringUtils.hasText(inv.getConfirmOpinion())) - .map(ConsultationInvited::getConfirmOpinion) - .collect(Collectors.joining("\n")); - dto.setConsultationOpinion(consultationOpinion); - - // 3. 所属医生、代表科室、签名医生、签名时间:使用第一个签名的医生 ConsultationInvited firstSigned = signedPhysicians.get(0); - dto.setAttendingPhysician(firstSigned.getInvitedPhysicianName()); - dto.setRepresentDepartment(firstSigned.getInvitedDepartmentName()); dto.setSignPhysician(firstSigned.getInvitedPhysicianName()); dto.setSignTime(firstSigned.getSignatureTime()); - - log.info("填充会诊记录信息,已确认和已签名医生数:{},已签名医生数:{}", - confirmedAndSignedPhysicians.size(), signedPhysicians.size()); } + + log.info("填充会诊记录信息,已确认和已签名医生数:{},已签名医生数:{}", + confirmedAndSignedPhysicians.size(), signedPhysicians.size()); } } } diff --git a/openhis-ui-vue3/src/views/consultationmanagement/consultationapplication/api.js b/openhis-ui-vue3/src/views/consultationmanagement/consultationapplication/api.js index 4270bbeb..e6b21b12 100644 --- a/openhis-ui-vue3/src/views/consultationmanagement/consultationapplication/api.js +++ b/openhis-ui-vue3/src/views/consultationmanagement/consultationapplication/api.js @@ -123,3 +123,15 @@ export function getConsultationActivities() { }) } +/** + * 获取会诊意见列表 + * @param {String} consultationId 会诊申请单号 + */ +export function getConsultationOpinions(consultationId) { + return request({ + url: '/consultation/confirmation/opinions', + method: 'get', + params: { consultationId } + }) +} + diff --git a/openhis-ui-vue3/src/views/consultationmanagement/consultationapplication/index.vue b/openhis-ui-vue3/src/views/consultationmanagement/consultationapplication/index.vue index 165d72f2..8e8489d5 100644 --- a/openhis-ui-vue3/src/views/consultationmanagement/consultationapplication/index.vue +++ b/openhis-ui-vue3/src/views/consultationmanagement/consultationapplication/index.vue @@ -11,8 +11,7 @@ - - + @@ -69,8 +68,6 @@ - - @@ -109,7 +106,7 @@ v-loading="loading" height="400" > - + @@ -213,7 +210,7 @@ - + @@ -270,6 +267,14 @@ + + + 紧急 + + + + + @@ -293,8 +298,8 @@ - - + + @@ -360,9 +365,9 @@ import { ref, reactive, onMounted, computed } from 'vue' import { ElMessage, ElMessageBox } from 'element-plus' import { Search, Refresh, Printer, Edit, View, Delete } from '@element-plus/icons-vue' -import { queryConsultationListPage, cancelConsultation, saveConsultation } from './api' -// 迁移到 hiprint +import { queryConsultationListPage, cancelConsultation, saveConsultation, getConsultationOpinions } from './api' import { simplePrint, PRINT_TEMPLATE } from '@/utils/printUtils.js' +import { formatDate } from '@/utils/index.js' const loading = ref(false) const saving = ref(false) @@ -371,11 +376,10 @@ const currentRow = ref(null) const dialogVisible = ref(false) const isViewMode = ref(false) const formRef = ref(null) +const opinionList = ref([]) // 会诊意见列表 -// 用于取消请求的控制器 let abortController = null -// 分页参数 const pagination = reactive({ currentPage: 1, pageSize: 10, @@ -393,7 +397,17 @@ const queryParams = reactive({ patientName: '' }) -const formData = ref({ +// 会诊状态常量 +const STATUS = { + NOT_SUBMITTED: 0, + SUBMITTED: 10, + CONFIRMED: 20, + SIGNED: 30, + ENDED: 40 +} + +// 初始表单数据模板 +const getInitialFormData = () => ({ id: null, consultationId: '', patientId: null, @@ -415,6 +429,7 @@ const formData = ref({ consultationActivityId: null, consultationActivityName: '', consultationUrgency: '', + isUrgent: false, consultationStatus: 0, consultationOpinion: '', consultingPhysicians: '', @@ -425,9 +440,50 @@ const formData = ref({ attendingPhysician: '', representDepartment: '', signPhysician: '', - signTime: null + signTime: null, + confirmingPhysician: '' }) +// 从 row 数据填充表单 +const populateFormData = (row) => ({ + id: row.id || null, + consultationId: row.consultationId || '', + patientId: row.patientId || null, + patientName: row.patientName || '', + genderEnum: row.genderEnum || null, + age: row.age || null, + patientBusNo: row.patientBusNo || '', + patientIdentifierNo: row.patientIdentifierNo || '', + encounterId: row.encounterId || null, + departmentId: row.departmentId || null, + department: row.department || '', + requestingPhysicianId: row.requestingPhysicianId || null, + requestingPhysician: row.requestingPhysician || '', + invitedObject: row.invitedObject || '', + consultationDate: row.consultationDate || '', + consultationRequestDate: row.consultationRequestDate || null, + consultationPurpose: row.consultationPurpose || '', + provisionalDiagnosis: row.provisionalDiagnosis || '', + consultationActivityId: row.consultationActivityId || null, + consultationActivityName: row.consultationActivityName || '', + consultationUrgency: row.consultationUrgency || '', + isUrgent: row.consultationUrgency === '2', + consultationStatus: row.consultationStatus || 0, + consultationOpinion: row.consultationOpinion || '', + consultingPhysicians: row.consultingPhysicians || '', + signingPhysicianId: row.signingPhysicianId || null, + signingPhysicianName: row.signingPhysicianName || '', + signingTime: row.signingTime || null, + invitedPhysiciansText: row.invitedPhysiciansText || '', + attendingPhysician: row.attendingPhysician || '', + representDepartment: row.representDepartment || '', + signPhysician: row.signPhysician || '', + signTime: row.signTime || null, + confirmingPhysician: '' +}) + +const formData = ref(getInitialFormData()) + const formRules = { requestingPhysician: [ { required: true, message: '请输入申请医师', trigger: 'blur' } @@ -444,23 +500,7 @@ const dialogTitle = computed(() => { return isViewMode.value ? '会诊申请查看' : '会诊申请编辑' }) -const formatDateTime = (date) => { - if (!date) return '' - const d = new Date(date) - if (isNaN(d.getTime())) return '' - - const pad = (value) => String(value).padStart(2, '0') - const yyyy = d.getFullYear() - const mm = pad(d.getMonth() + 1) - const dd = pad(d.getDate()) - const hh = pad(d.getHours()) - const mi = pad(d.getMinutes()) - const ss = pad(d.getSeconds()) - return `${yyyy}-${mm}-${dd} ${hh}:${mi}:${ss}` -} - const handleQuery = async () => { - // 验证时间范围 if (queryParams.startTime && queryParams.endTime) { const start = new Date(queryParams.startTime) const end = new Date(queryParams.endTime) @@ -469,8 +509,6 @@ const handleQuery = async () => { return } } - - // 重置到第一页 pagination.currentPage = 1 await loadData() } @@ -494,25 +532,20 @@ const handleSizeChange = (val) => { } const handleCurrentChange = (val) => { - // 如果正在加载,忽略此次操作 - if (loading.value) { - return - } + if (loading.value) return pagination.currentPage = val loadData() } const handlePrint = async (row) => { - // 优先使用传入的 row,如果没有传入则使用 currentRow const printRow = row || currentRow.value - + if (!printRow) { ElMessage.warning('请先选择一条记录') return } - + try { - // 构建打印数据 const printData = { patientName: printRow.patientName || '', gender: printRow.genderEnum === 1 ? '男' : '女', @@ -534,138 +567,77 @@ const handleRowChange = (row) => { currentRow.value = row } -const handleEdit = (row) => { - // 检查是否已结束 - if (row.consultationStatus >= 40) { +// 加载会诊意见列表 +const loadConsultationOpinions = async (consultationId) => { + try { + const res = await getConsultationOpinions(consultationId) + if (res.code === 200) { + opinionList.value = res.data || [] + } + } catch (error) { + console.error('加载会诊意见失败', error) + opinionList.value = [] + } +} + +// 打开弹窗的统一方法 +const openDialog = async (row, viewOnly = false) => { + if (!viewOnly && row.consultationStatus >= STATUS.ENDED) { ElMessage.warning('已结束的会诊申请不可编辑') return } + isViewMode.value = viewOnly + formData.value = populateFormData(row) - isViewMode.value = false - // 确保所有字段都复制到formData中 - formData.value = { - id: row.id || null, - consultationId: row.consultationId || '', - patientId: row.patientId || null, - patientName: row.patientName || '', - genderEnum: row.genderEnum || null, - age: row.age || null, - patientBusNo: row.patientBusNo || '', - patientIdentifierNo: row.patientIdentifierNo || '', - encounterId: row.encounterId || null, - departmentId: row.departmentId || null, - department: row.department || '', - requestingPhysicianId: row.requestingPhysicianId || null, - requestingPhysician: row.requestingPhysician || '', - invitedObject: row.invitedObject || '', - consultationDate: row.consultationDate || '', - consultationRequestDate: row.consultationRequestDate || null, - consultationPurpose: row.consultationPurpose || '', - provisionalDiagnosis: row.provisionalDiagnosis || '', - consultationActivityId: row.consultationActivityId || null, - consultationActivityName: row.consultationActivityName || '', - consultationUrgency: row.consultationUrgency || '', - consultationStatus: row.consultationStatus || 0, - consultationOpinion: row.consultationOpinion || '', - consultingPhysicians: row.consultingPhysicians || '', - signingPhysicianId: row.signingPhysicianId || null, - signingPhysicianName: row.signingPhysicianName || '', - signingTime: row.signingTime || null, - invitedPhysiciansText: row.invitedPhysiciansText || '', - attendingPhysician: row.attendingPhysician || '', - representDepartment: row.representDepartment || '', - signPhysician: row.signPhysician || '', - signTime: row.signTime || null + // 加载会诊意见列表 + await loadConsultationOpinions(row.consultationId) + + // 从会诊意见中填充会诊记录相关字段 + if (opinionList.value.length > 0) { + // 获取所有已确认参加的医师名称 + const confirmedPhysicians = opinionList.value + .filter(op => op.physicianName) + .map(op => op.physicianName) + .join('、') + formData.value.confirmingPhysician = confirmedPhysicians + + // 取第一条意见填充会诊意见字段 + const firstOpinion = opinionList.value[0] + formData.value.consultationOpinion = firstOpinion.opinion || '' + formData.value.attendingPhysician = firstOpinion.physicianName || '' + formData.value.representDepartment = firstOpinion.deptName || '' + + // 查找已签名的意见 + const signedOpinion = opinionList.value.find(op => op.isSigned) + if (signedOpinion) { + formData.value.signPhysician = signedOpinion.physicianName || '' + formData.value.signTime = signedOpinion.signatureTime || null + } } + dialogVisible.value = true } -const handleView = (row) => { - isViewMode.value = true - // 确保所有字段都复制到formData中 - formData.value = { - id: row.id || null, - consultationId: row.consultationId || '', - patientId: row.patientId || null, - patientName: row.patientName || '', - genderEnum: row.genderEnum || null, - age: row.age || null, - patientBusNo: row.patientBusNo || '', - patientIdentifierNo: row.patientIdentifierNo || '', - encounterId: row.encounterId || null, - departmentId: row.departmentId || null, - department: row.department || '', - requestingPhysicianId: row.requestingPhysicianId || null, - requestingPhysician: row.requestingPhysician || '', - invitedObject: row.invitedObject || '', - consultationDate: row.consultationDate || '', - consultationRequestDate: row.consultationRequestDate || null, - consultationPurpose: row.consultationPurpose || '', - provisionalDiagnosis: row.provisionalDiagnosis || '', - consultationActivityId: row.consultationActivityId || null, - consultationActivityName: row.consultationActivityName || '', - consultationUrgency: row.consultationUrgency || '', - consultationStatus: row.consultationStatus || 0, - consultationOpinion: row.consultationOpinion || '', - consultingPhysicians: row.consultingPhysicians || '', - signingPhysicianId: row.signingPhysicianId || null, - signingPhysicianName: row.signingPhysicianName || '', - signingTime: row.signingTime || null, - invitedPhysiciansText: row.invitedPhysiciansText || '', - attendingPhysician: row.attendingPhysician || '', - representDepartment: row.representDepartment || '', - signPhysician: row.signPhysician || '', - signTime: row.signTime || null - } - dialogVisible.value = true -} +const handleEdit = (row) => openDialog(row, false) +const handleView = (row) => openDialog(row, true) const handleDialogClose = () => { formRef.value?.clearValidate() - formData.value = { - id: null, - consultationId: '', - patientId: null, - patientName: '', - genderEnum: null, - age: null, - patientBusNo: '', - patientIdentifierNo: '', - encounterId: null, - departmentId: null, - department: '', - requestingPhysicianId: null, - requestingPhysician: '', - invitedObject: '', - consultationDate: '', - consultationRequestDate: null, - consultationPurpose: '', - provisionalDiagnosis: '', - consultationActivityId: null, - consultationActivityName: '', - consultationUrgency: '', - consultationStatus: 0, - consultationOpinion: '', - consultingPhysicians: '', - signingPhysicianId: null, - signingPhysicianName: '', - signingTime: null, - invitedPhysiciansText: '', - attendingPhysician: '', - representDepartment: '', - signPhysician: '', - signTime: null - } + formData.value = getInitialFormData() + opinionList.value = [] } const handleSave = async () => { try { - // 表单验证 await formRef.value.validate() - saving.value = true - const res = await saveConsultation(formData.value) - + // 将 isUrgent 转换回 consultationUrgency + const submitData = { + ...formData.value, + consultationUrgency: formData.value.isUrgent ? '2' : '1' + } + const res = await saveConsultation(submitData) + if (res.code === 200) { ElMessage.success('保存成功') dialogVisible.value = false @@ -684,8 +656,7 @@ const handleSave = async () => { } const handleDelete = async (row) => { - // 检查是否已结束 - if (row.consultationStatus >= 40) { + if (row.consultationStatus >= STATUS.ENDED) { ElMessage.warning('已结束的会诊申请不可作废') return } @@ -717,18 +688,14 @@ const handleDelete = async (row) => { } const loadData = async () => { - // 如果正在加载,取消上一个请求 if (loading.value && abortController) { abortController.abort() } - + try { loading.value = true - - // 创建新的 AbortController abortController = new AbortController() - - // 构建查询参数 + const queryData = { department: queryParams.applyDept, requestingPhysician: queryParams.applyDoctor, @@ -737,23 +704,16 @@ const loadData = async () => { consultationRequestDate: queryParams.startTime, consultationUrgency: queryParams.urgency } - - console.log('查询参数:', queryData, '页码:', pagination.currentPage, '每页:', pagination.pageSize) - + const res = await queryConsultationListPage(queryData, pagination.currentPage, pagination.pageSize) - - console.log('查询结果:', res) - + if (res.code === 200) { tableData.value = res.data.records || [] pagination.total = res.data.total || 0 - - // 如果没有查询结果,显示提示 if (tableData.value.length === 0 && pagination.currentPage === 1) { ElMessage.info('暂无查询结果') } } else { - // 忽略"数据正在处理"的错误提示 if (!res.msg || !res.msg.includes('数据正在处理')) { ElMessage.error(res.msg || '加载数据失败') } @@ -761,20 +721,15 @@ const loadData = async () => { pagination.total = 0 } } catch (error) { - // 忽略取消请求的错误 if (error.name === 'AbortError' || error.name === 'CanceledError') { - console.log('请求已取消') return } - - console.error('加载数据失败:', error) - - // 忽略"数据正在处理"的错误提示 + const errorMsg = error.message || error.msg || '网络错误' if (!errorMsg.includes('数据正在处理')) { ElMessage.error('加载数据失败: ' + errorMsg) } - + tableData.value = [] pagination.total = 0 } finally {