inspect-front/src/views/Department-entry/summary.vue
2025-04-07 09:59:25 +08:00

566 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="summary-container">
<div class="summary-header">
<div class="title-with-button">
<h3>体检汇总</h3>
<el-button type="text" @click="openTemplateDrawer" style="margin-left: 15px;">诊断模板</el-button>
<span style="margin-left: 15px;">总检医生</span>
<el-select
v-model="selectedDoctor"
placeholder="请选择总检医生"
style="margin-left: 15px; width: 200px;"
clearable
:disabled="isReadOnly"
value-key="doctorid"
>
<el-option
v-for="doctor in doctorList"
:key="doctor.doctorid"
:label="doctor.doctorname"
:value="doctor.doctorid+'|'+doctor.doctorname"
/>
</el-select>
</div>
</div>
<div class="summary-content">
<!-- 始终显示文本框,即使没有数据 -->
<div class="summary-textarea-container">
<textarea
class="summary-textarea"
v-model="editableSummary"
placeholder="请输入体检汇总内容"
:readonly="isReadOnly"
></textarea>
</div>
</div>
<!-- 添加诊断模板抽屉组件 -->
<template-drawer
v-model="drawerVisible"
@select-template="insertTemplate"
/>
</div>
</template>
<script setup>
import { ref, onMounted, watch } from 'vue'
import { PatientitemsApi } from '@/api/inspect/inspectpatientitems'
import { PatientApi } from '@/api/inspect/inspectpatient'
import { ElLoading, ElMessage } from 'element-plus'
import { Refresh } from '@element-plus/icons-vue'
import TemplateDrawer from '@/views/Department-entry/Drawer-Template.vue'
import { DoctorApi } from '@/api/inspect/inspectdoctor'
const props = defineProps({
patient: {
type: Object,
required: true
},
reportData: {
type: Object,
default: () => ({})
},
conclusionData: {
type: Object,
default: () => ({})
}
})
// 添加emit以便与父组件通信
const emit = defineEmits(['save-summary', 'update:patient'])
// 汇总数据
const summaryData = ref({
general: { summary: '' },
ultrasound: { finding: '', diagnosis: '' },
ecg: { finding: '', diagnosis: '' },
blood: { summary: '' },
urine: { summary: '' },
biochemical: { summary: '' }
})
// 可编辑的汇总文本
const editableSummary = ref('')
// 添加患者状态检查
const isReadOnly = ref(false)
// 检查患者状态
const checkPatientStatus = () => {
if (props.patient?.status) {
// 同时处理字符串和数字类型的状态值
isReadOnly.value = String(props.patient.status) === '1'
}
}
// 格式化汇总数据为文本
const formatSummaryData = () => {
let result = ''
// 一般检查
if (summaryData.value.general?.summary) {
result += '【一般检查】\n' + summaryData.value.general.summary + '\n\n'
}
// 超声检查
if (summaryData.value.ultrasound?.finding || summaryData.value.ultrasound?.diagnosis) {
result += '【超声】\n'
if (summaryData.value.ultrasound.finding) {
result += '检查所见:' + summaryData.value.ultrasound.finding + '\n'
}
if (summaryData.value.ultrasound.diagnosis) {
result += '检查结果:' + summaryData.value.ultrasound.diagnosis + '\n'
}
result += '\n'
}
// 心电图检查
if (summaryData.value.ecg?.finding || summaryData.value.ecg?.diagnosis) {
result += '【心电图】\n'
if (summaryData.value.ecg.finding) {
result += '检查所见:' + summaryData.value.ecg.finding + '\n'
}
if (summaryData.value.ecg.diagnosis) {
result += '检查结果:' + summaryData.value.ecg.diagnosis + '\n'
}
result += '\n'
}
// 血常规
if (summaryData.value.blood?.summary) {
result += '【血常规】\n' + summaryData.value.blood.summary + '\n\n'
}
// 尿常规
if (summaryData.value.urine?.summary) {
result += '【尿常规】\n' + summaryData.value.urine.summary + '\n\n'
}
// 生化
if (summaryData.value.biochemical?.summary) {
result += '【生化】\n' + summaryData.value.biochemical.summary + '\n\n'
}
return result
}
// 从DOM中获取各个标签页的数据
const getDataFromDOM = () => {
try {
const parentDoc = window.parent ? window.parent.document : document
// 更新选择器以匹配体检车页面的结构
const selectors = {
general: ['[data-tab="general"] .summary-textarea', '#体检小结', '[placeholder*="体检小结"]'],
ultrasoundFinding: [
'[data-tab="ultrasound"] .findings-textarea',
'[data-tab="ultrasound-finding"]'
],
ultrasoundDiagnosis: [
'[data-tab="ultrasound"] .diagnosis-textarea',
'[data-tab="ultrasound-diagnosis"]'
],
ecgFinding: ['[data-tab="ecg"] .findings-textarea', '[data-tab="ecg-finding"]'],
ecgDiagnosis: ['[data-tab="ecg"] .diagnosis-textarea', '[data-tab="ecg-diagnosis"]'],
blood: ['[data-tab="blood"] .summary-textarea'],
urine: ['[data-tab="urine"] .summary-textarea'],
biochemical: ['[data-tab="biochemical"] .summary-textarea']
}
// 尝试使用不同的选择器获取元素
const getElementValue = (selectorList) => {
for (const selector of selectorList) {
const element = parentDoc.querySelector(selector)
if (element) {
return element.value || ''
}
}
return ''
}
// 获取各个标签页的内容
const generalSummary = getElementValue(selectors.general)
const ultrasoundFinding = getElementValue(selectors.ultrasoundFinding)
const ultrasoundDiagnosis = getElementValue(selectors.ultrasoundDiagnosis)
const ecgFinding = getElementValue(selectors.ecgFinding)
const ecgDiagnosis = getElementValue(selectors.ecgDiagnosis)
const bloodSummary = getElementValue(selectors.blood)
const urineSummary = getElementValue(selectors.urine)
const biochemicalSummary = getElementValue(selectors.biochemical)
// 如果没有找到一般检查小结,尝试从体检小结文本框获取
if (!generalSummary) {
const generalTextarea =
parentDoc.querySelector('#体检小结') ||
parentDoc.querySelector('.体检小结') ||
parentDoc.querySelector('[placeholder*="体检小结"]')
if (generalTextarea) {
const generalText = generalTextarea.value || ''
// 更新汇总数据
return {
general: { summary: generalText },
ultrasound: { finding: ultrasoundFinding, diagnosis: ultrasoundDiagnosis },
ecg: { finding: ecgFinding, diagnosis: ecgDiagnosis },
blood: { summary: bloodSummary },
urine: { summary: urineSummary },
biochemical: { summary: biochemicalSummary }
}
}
}
// 更新汇总数据
return {
general: { summary: generalSummary },
ultrasound: { finding: ultrasoundFinding, diagnosis: ultrasoundDiagnosis },
ecg: { finding: ecgFinding, diagnosis: ecgDiagnosis },
blood: { summary: bloodSummary },
urine: { summary: urineSummary },
biochemical: { summary: biochemicalSummary }
}
} catch (error) {
console.error('从DOM中获取数据失败:', error)
return null
}
}
// 加载患者的所有检查项目数据
const loadPatientItems = async () => {
if (!props.patient || !props.patient.medicalSn) {
console.error('患者信息不存在或体检编号为空', props.patient)
ElMessage.warning('患者信息不完整,无法加载汇总数据')
return
}
try {
const loading = ElLoading.service({
lock: true,
text: '加载汇总数据中...',
background: 'rgba(255, 255, 255, 0.7)'
})
// 检查患者状态
checkPatientStatus()
// 优先使用props中的conclusionData
if (props.conclusionData) {
summaryData.value = props.conclusionData
} else if (window.parent?.conclusionData) {
const parentData = window.parent.conclusionData
// 复制父组件的数据到本地
summaryData.value = {
general: { summary: parentData.general?.summary || '' },
ultrasound: {
finding: parentData.ultrasound?.finding || '',
diagnosis: parentData.ultrasound?.diagnosis || ''
},
ecg: {
finding: parentData.ecg?.finding || '',
diagnosis: parentData.ecg?.diagnosis || ''
},
blood: { summary: parentData.blood?.summary || '' },
urine: { summary: parentData.urine?.summary || '' },
biochemical: { summary: parentData.biochemical?.summary || '' }
}
} else {
console.warn('父窗口中没有找到conclusionData尝试从全局变量获取')
// 尝试从全局变量获取
if (window.conclusionData) {
summaryData.value = window.conclusionData
} else {
console.warn('全局变量中没有找到conclusionData尝试从props获取')
// 尝试从props中获取数据
if (props.reportData && props.reportData.conclusionData) {
summaryData.value = props.reportData.conclusionData
} else {
// 尝试直接从父组件的DOM中获取数据
const domData = getDataFromDOM()
if (domData) {
summaryData.value = domData
} else {
console.error('无法从任何来源获取汇总数据')
ElMessage.warning('无法获取汇总数据,请检查数据来源')
}
}
}
}
// 格式化汇总数据并设置为可编辑文本
const formattedText = formatSummaryData()
editableSummary.value = formattedText
loading.close()
} catch (error) {
console.error('加载汇总数据失败:', error)
ElMessage.error('加载汇总数据失败: ' + error.message)
loading.close()
}
}
const saving = ref(false)
// 保存汇总内容到PatientApi的summaryResult字段
const saveSummary = async () => {
if (isReadOnly.value) {
ElMessage.warning('已检查患者不可修改汇总内容')
return false
}
if (!editableSummary.value) {
ElMessage.warning('体检汇总内容为空,请检查汇总内容')
return false
}
if (!props.patient || !props.patient.medicalSn) {
ElMessage.warning('患者信息不完整,无法保存汇总数据')
return false
}
if (!selectedDoctor.value) {
ElMessage.warning('请选择总检医生')
return false
}
try {
saving.value = true
// 准备保存的数据
const saveData = {
medicalSn: props.patient.medicalSn,
summaryResult: editableSummary.value,
}
//更新总检医生id
const saveData2 = {
medicalSn: props.patient.medicalSn,
chiefinspectorid: parseInt(selectedDoctor.value.split('|')[0]),
chiefinspector: selectedDoctor.value.split('|')[1]
}
// 调用API保存数据
const response = await PatientApi.updatemedicalSn(saveData)
const response2 = await PatientApi.updatedoctorid(saveData2)
if (response && response.code === 200) {
ElMessage.success('体检汇总保存成功')
// 保存成功后重新查询患者数据
const patientData = await PatientApi.getPatient(props.patient.id)
if (patientData && patientData.code === 200 && patientData.data) {
// 通过emit通知父组件更新患者信息
emit('update:patient', patientData.data)
}
// 检查患者状态
checkPatientStatus()
return true
}
return false
} catch (error) {
console.error('保存汇总数据失败:', error)
ElMessage.error('保存汇总数据失败: ' + error.message)
return false
} finally {
saving.value = false
}
}
// 查询患者数据
const queryPatientData = async () => {
if (!props.patient || !props.patient.medicalSn) {
return
}
try {
const response = await PatientApi.getByMedicalSn(props.patient.medicalSn)
if (response && response.code === 200 && response.data) {
if (response.data.summaryResult) {
editableSummary.value = response.data.summaryResult
}
if (response.data.status) {
isReadOnly.value = response.data.status === 2
}
console.log(response.data.chiefinspector)
// 添加对医生ID的处理
if (response.data.chiefinspector) {
selectedDoctor.value = response.data.chiefinspector
}
}
} catch (error) {
console.error('查询患者数据失败:', error)
}
}
// 医生列表数据
const doctorList = ref([])
const selectedDoctor = ref(null)
// 根据医生ID查询医生信息
const getDoctorInfo = async (doctorId) => {
try {
const response = await DoctorApi.getDoctorById(doctorId)
if (response) {
selectedDoctor.value = response
}
} catch (error) {
console.error('查询医生信息失败:', error)
}
}
// 加载医生列表
const loadDoctorList = async () => {
try {
const queryParams = {
pageNo: 1,
pageSize: 100,
}
const response = await DoctorApi.getDoctorPage(queryParams)
if (response && response.list && response.list.length > 0) {
doctorList.value = response.list
}
} catch (error) {
console.error('加载医生列表失败:', error)
ElMessage.error('加载医生列表失败')
}
}
// 初始化数据
const initData = () => {
loadPatientItems()
checkPatientStatus()
loadDoctorList()
}
// 组件挂载时加载数据
onMounted(() => {
initData()
})
// 监听患者信息变化
watch(() => props.patient, (newVal) => {
if (newVal) {
checkPatientStatus()
if (newVal.medicalSn) {
loadPatientItems()
}
if (newVal.chiefinspector) {
selectedDoctor.value = newVal.chiefinspector
}
}
}, { deep: true, immediate: true })
// 抽屉可见性控制
const drawerVisible = ref(false)
// 打开模板抽屉
const openTemplateDrawer = () => {
if (isReadOnly.value) {
ElMessage.warning('已检查患者不可修改汇总内容')
return
}
drawerVisible.value = true
}
// 插入选中的模板内容
const insertTemplate = (templateContent) => {
if (isReadOnly.value) return
// 在当前光标位置或末尾插入模板内容
editableSummary.value += templateContent
// 可选:插入后关闭抽屉
drawerVisible.value = false
}
// 暴露保存汇总方法给父组件调用
defineExpose({
saveSummary,
validateSummaryDoctor: () => {
if (!selectedDoctor.value) {
ElMessage.warning('请选择总检医生')
return false
}
return true
}
})
</script>
<style scoped>
.summary-container {
height: 100%;
overflow-y: auto;
padding: 15px;
}
.summary-header {
margin-bottom: 20px;
border-bottom: 1px solid #ebeef5;
padding-bottom: 10px;
}
.title-with-button {
display: flex;
align-items: center;
}
.summary-header h3 {
margin: 0;
font-size: 18px;
color: #303133;
}
.summary-content {
height: calc(100% - 60px);
}
.summary-textarea-container {
height: 100%;
width: 100%;
}
.summary-textarea {
width: 100%;
height: 100%;
min-height: 500px;
padding: 20px;
border: 1px solid #333333;
border-radius: 4px;
font-size: 14px;
line-height: 1.8;
color: #606266;
resize: none;
background-color: #ffffff;
font-family: Arial, sans-serif;
outline: none;
}
.summary-textarea:focus {
border-color: #333333;
box-shadow: none;
}
.empty-data {
display: flex;
justify-content: center;
align-items: center;
height: 300px;
background: #ffffff;
border-radius: 4px;
border: 1px solid #dcdfe6;
}
.refresh-button {
margin-left: 10px;
}
.summary-textarea[readonly] {
background-color: #f5f7fa;
cursor: not-allowed;
opacity: 0.9;
}
</style>