566 lines
15 KiB
Vue
566 lines
15 KiB
Vue
<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>
|