添加科室录入区分,修改部分字段
This commit is contained in:
parent
81762466b2
commit
345b725ab9
@ -20,6 +20,9 @@ export interface PatientitemsVO {
|
||||
positive: string // 是否阳性 1:阳性
|
||||
inspectdoctor: string // 检查医生
|
||||
inspecttime: Date // 检查时间
|
||||
groupname: string // 模块名称
|
||||
mealfrontorafter: string // 餐前餐后
|
||||
moduleName: string // 模块名称:体检单元
|
||||
}
|
||||
|
||||
// 患者体检项目 API
|
||||
|
@ -43,7 +43,7 @@
|
||||
<!-- 检查项目标签 -->
|
||||
<div class="exam-tabs">
|
||||
<div
|
||||
v-for="tab in examTabs"
|
||||
v-for="tab in filteredExamTabs"
|
||||
:key="tab.id"
|
||||
:class="['tab-item', { active: currentTab === tab.id }]"
|
||||
@click="switchTab(tab.id)"
|
||||
@ -59,7 +59,7 @@
|
||||
<div class="image-gallery">
|
||||
<div class="gallery-title">影像图片</div>
|
||||
<div class="image-container">
|
||||
<div v-if="imageUrls.length > 0" class="image-grid">
|
||||
<div v-if="imageUrls.length > 0" class="image-grid" :class="{'single-image': imageUrls.length === 1}">
|
||||
<div v-for="(url, index) in imageUrls" :key="index" class="image-item">
|
||||
<el-image
|
||||
:src="url"
|
||||
@ -98,10 +98,10 @@
|
||||
</div>
|
||||
|
||||
<div class="diagnosis-section">
|
||||
<div class="section-title">影像诊断</div>
|
||||
<div class="section-title">检查结果</div>
|
||||
<textarea
|
||||
v-model="imageDiagnosis"
|
||||
placeholder="请输入影像诊断"
|
||||
placeholder="请输入检查结果"
|
||||
class="diagnosis-textarea"
|
||||
:readonly="isReadOnly"
|
||||
></textarea>
|
||||
@ -111,7 +111,7 @@
|
||||
</div>
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<div class="action-footer">
|
||||
<div class="action-footer"></div>
|
||||
<div class="footer-content">
|
||||
<div class="doctor-info">
|
||||
<span>检查医生:{{ user?.nickname || '暂无' }}</span>
|
||||
@ -119,7 +119,6 @@
|
||||
</div>
|
||||
<div class="action-buttons">
|
||||
<button class="action-btn" @click="checkEditPermission">同步结果</button>
|
||||
<button class="action-btn">报告预览</button>
|
||||
<button class="action-btn" @click="checkEditPermission">弃检</button>
|
||||
<button
|
||||
v-if="!isReadOnly"
|
||||
@ -131,7 +130,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@ -164,20 +162,57 @@ const isImageDepartment = ref(false)
|
||||
|
||||
// 添加检查类型标签
|
||||
const examTabs = ref([
|
||||
{ id: 'ct', name: 'CT检查', color: '#409EFF' },
|
||||
{ id: 'mri', name: 'MRI检查', color: '#67C23A' },
|
||||
{ id: 'xray', name: 'X光检查', color: '#E6A23C' },
|
||||
{ id: 'ultrasound', name: '超声检查', color: '#F56C6C' },
|
||||
{ id: 'ecg', name: '心电图检查', color: '#909399' }
|
||||
{ id: 'ct', name: 'CT检查', color: '#409EFF', keywords: ['ct', 'CT'] },
|
||||
{ id: 'us', name: '超声检查', color: '#F56C6C', keywords: ['超声', '彩超', 'us', 'US'] },
|
||||
{ id: 'ecg', name: '心电图检查', color: '#909399', keywords: ['心电图', 'ecg', 'ECG'] }
|
||||
])
|
||||
|
||||
// 当前选中的检查类型
|
||||
const currentTab = ref('ct')
|
||||
|
||||
// 根据模块名称过滤标签
|
||||
const filteredExamTabs = ref([])
|
||||
|
||||
// 添加一个变量来存储当前检查项目
|
||||
const currentItem = ref(null)
|
||||
|
||||
// 切换检查类型
|
||||
const switchTab = async (tabId) => {
|
||||
console.log('切换到检查类型:', tabId)
|
||||
currentTab.value = tabId
|
||||
|
||||
// 查找当前标签对应的检查项目
|
||||
if (reportData.value.medicalSn) {
|
||||
try {
|
||||
const patientItemsResponse = await PatientitemsApi.getPatientitemsPage({
|
||||
medicalSn: reportData.value.medicalSn,
|
||||
pageNo: 1,
|
||||
pageSize: 100
|
||||
})
|
||||
|
||||
if (patientItemsResponse?.list && patientItemsResponse.list.length > 0) {
|
||||
const currentTabKeywords = examTabs.value.find(tab => tab.id === tabId)?.keywords || []
|
||||
currentItem.value = patientItemsResponse.list.find(item =>
|
||||
item.moduleName && currentTabKeywords.some(keyword => item.moduleName.includes(keyword))
|
||||
)
|
||||
|
||||
console.log('切换标签后找到的检查项目:', currentItem.value)
|
||||
|
||||
// 如果找到了检查项目,加载其检查所见和结果
|
||||
if (currentItem.value) {
|
||||
imageFinding.value = currentItem.value.examDescription || ''
|
||||
imageDiagnosis.value = currentItem.value.itemResult || ''
|
||||
} else {
|
||||
// 如果没找到,清空检查所见和结果
|
||||
imageFinding.value = ''
|
||||
imageDiagnosis.value = ''
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取患者检查项目失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
imageUrls.value = await getImageUrlsByType(tabId)
|
||||
console.log('获取到的图片URLs:', imageUrls.value)
|
||||
}
|
||||
@ -263,7 +298,10 @@ const formattedMedicalDateTime = computed(() => {
|
||||
|
||||
// 是否只读的计算属性
|
||||
const isReadOnly = computed(() => {
|
||||
return props.patient?.status === 1
|
||||
console.log('检查项目状态:', currentItem.value?.itemStatus)
|
||||
// 项目状态为0表示未检查,应该可以编辑
|
||||
// 项目状态为1表示已检查,应该只读
|
||||
return currentItem.value?.itemStatus === '1'
|
||||
})
|
||||
|
||||
// 检查编辑权限的方法
|
||||
@ -278,44 +316,59 @@ const checkEditPermission = () => {
|
||||
// 保存结果方法
|
||||
const handleSaveResults = async () => {
|
||||
try {
|
||||
if (!checkEditPermission()) {
|
||||
return
|
||||
}
|
||||
|
||||
console.log('开始保存检查结果')
|
||||
console.log('检查所见:', imageFinding.value)
|
||||
console.log('检查结果:', imageDiagnosis.value)
|
||||
|
||||
const userProfile = await getUserProfile()
|
||||
user.value = userProfile
|
||||
console.log('获取到的用户信息:', user.value)
|
||||
|
||||
// 获取当前时间戳
|
||||
const currentTime = new Date().getTime()
|
||||
|
||||
|
||||
// 检查当前项目
|
||||
console.log('当前检查项目:', currentItem.value)
|
||||
|
||||
if (!currentItem.value || !currentItem.value.id) {
|
||||
ElMessage.error('未找到当前检查项目信息')
|
||||
return
|
||||
}
|
||||
|
||||
// 更新检查项目结果
|
||||
const updatedItems = [{
|
||||
id: props.patient.id,
|
||||
examDescription: imageFinding.value,
|
||||
itemResult: imageDiagnosis.value,
|
||||
analyse: examConclusion.value,
|
||||
inspectdoctor: user.value?.nickname || '',
|
||||
id: currentItem.value.id, // 使用检查项目ID
|
||||
examDescription: imageFinding.value, // 检查所见
|
||||
itemResult: imageDiagnosis.value, // 检查结果
|
||||
itemStatus: '1', // 已检查
|
||||
inspectdoctor: user.value?.nickname || '',
|
||||
inspecttime: currentTime
|
||||
}]
|
||||
|
||||
await PatientitemsApi.updatePatientitemsBatch(updatedItems)
|
||||
console.log('准备提交的检查项目数据:', updatedItems)
|
||||
|
||||
const updateResult = await PatientitemsApi.updatePatientitemsBatch(updatedItems)
|
||||
console.log('检查项目更新结果:', updateResult)
|
||||
|
||||
// 更新患者状态为已检查
|
||||
if (props.patient) {
|
||||
const patientData = {
|
||||
...props.patient,
|
||||
status: 1,
|
||||
medicalDateTime: currentTime
|
||||
}
|
||||
await PatientApi.updatePatient(patientData)
|
||||
}
|
||||
// 更新当前项目状态
|
||||
currentItem.value.itemStatus = '1'
|
||||
currentItem.value.examDescription = imageFinding.value
|
||||
currentItem.value.itemResult = imageDiagnosis.value
|
||||
|
||||
ElMessage.success('保存成功')
|
||||
|
||||
} catch (error) {
|
||||
console.error('保存失败:', error)
|
||||
ElMessage.error(`保存失败: ${error.message}`)
|
||||
console.error('错误详情:', error.response || error)
|
||||
ElMessage.error(`保存失败: ${error.message || '未知错误'}`)
|
||||
}
|
||||
}
|
||||
|
||||
// 加载患者数据
|
||||
// 加载患者数据和检查项目
|
||||
const loadPatientData = async (patient) => {
|
||||
if (!patient || !patient.id) {
|
||||
console.log('没有有效的患者数据')
|
||||
@ -348,6 +401,65 @@ const loadPatientData = async (patient) => {
|
||||
user.value = userProfile
|
||||
reportData.value = patientData
|
||||
|
||||
// 获取患者检查项目数据
|
||||
if (reportData.value.medicalSn) {
|
||||
try {
|
||||
const patientItemsResponse = await PatientitemsApi.getPatientitemsPage({
|
||||
medicalSn: reportData.value.medicalSn,
|
||||
pageNo: 1,
|
||||
pageSize: 100
|
||||
})
|
||||
|
||||
if (patientItemsResponse?.list && patientItemsResponse.list.length > 0) {
|
||||
// 从检查项目中提取moduleName
|
||||
const moduleNames = patientItemsResponse.list.map(item => item.moduleName).filter(Boolean)
|
||||
|
||||
// 根据moduleName过滤标签
|
||||
if (moduleNames.length > 0) {
|
||||
const matchedTabs = []
|
||||
|
||||
// 检查每个moduleName是否匹配任何标签
|
||||
for (const moduleName of moduleNames) {
|
||||
for (const tab of examTabs.value) {
|
||||
if (tab.keywords.some(keyword => moduleName.includes(keyword)) &&
|
||||
!matchedTabs.some(t => t.id === tab.id)) {
|
||||
matchedTabs.push(tab)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 设置匹配的标签
|
||||
if (matchedTabs.length > 0) {
|
||||
// 只显示匹配的标签
|
||||
filteredExamTabs.value = matchedTabs
|
||||
|
||||
// 设置第一个匹配的标签为当前标签
|
||||
currentTab.value = matchedTabs[0].id
|
||||
|
||||
// 查找当前标签对应的检查项目
|
||||
const currentTabKeywords = examTabs.value.find(tab => tab.id === currentTab.value)?.keywords || []
|
||||
currentItem.value = patientItemsResponse.list.find(item =>
|
||||
item.moduleName && currentTabKeywords.some(keyword => item.moduleName.includes(keyword))
|
||||
)
|
||||
|
||||
console.log('找到的当前检查项目:', currentItem.value)
|
||||
|
||||
// 如果找到了检查项目,加载其检查所见和结果
|
||||
if (currentItem.value) {
|
||||
imageFinding.value = currentItem.value.examDescription || ''
|
||||
imageDiagnosis.value = currentItem.value.itemResult || ''
|
||||
}
|
||||
|
||||
// 加载当前标签的影像数据
|
||||
imageUrls.value = await getImageUrlsByType(currentTab.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取患者检查项目失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 缓存数据
|
||||
patientDataCache.value.set(cacheKey, {
|
||||
reportData: { ...reportData.value }
|
||||
@ -373,9 +485,11 @@ watch(() => props.patient, (newPatient) => {
|
||||
// 修改组件挂载时的逻辑
|
||||
onMounted(async () => {
|
||||
if (props.patient) {
|
||||
// 初始化为所有标签,防止界面空白
|
||||
filteredExamTabs.value = examTabs.value
|
||||
|
||||
// 加载患者数据和检查项目
|
||||
await loadPatientData(props.patient)
|
||||
// 加载默认tab的影像数据
|
||||
imageUrls.value = await getImageUrlsByType(currentTab.value)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@ -551,9 +665,10 @@ onMounted(async () => {
|
||||
}
|
||||
|
||||
.image-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
|
||||
gap: 20px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 600px; /* 增加间距从20px到40px */
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.image-item {
|
||||
@ -563,6 +678,13 @@ onMounted(async () => {
|
||||
transition: transform 0.3s;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
|
||||
aspect-ratio: 4/3;
|
||||
width: calc(45% - 20px); /* 减小宽度比例,增加间距 */
|
||||
max-width: 480px;
|
||||
}
|
||||
|
||||
/* 单张图片时的样式 */
|
||||
.single-image .image-item {
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.medical-image {
|
||||
|
@ -9,7 +9,7 @@
|
||||
<div class="search-box medical-sn-search">
|
||||
<input
|
||||
v-model="medicalSnQuery"
|
||||
placeholder="请输入体检编号"
|
||||
placeholder="请输入体检编号"
|
||||
@keyup.enter="handleMedicalSnSearch"
|
||||
/>
|
||||
</div>
|
||||
@ -27,11 +27,11 @@
|
||||
<span class="name">{{ patient.pname }}</span>
|
||||
<span class="medical-sn">{{ patient.medicalSn }}</span>
|
||||
<el-tag
|
||||
:type="getStatusTagType(patient.status)"
|
||||
:type="getStatusTagType(patient)"
|
||||
size="small"
|
||||
class="status-tag"
|
||||
>
|
||||
{{ getStatusText(patient.status) }}
|
||||
{{ getStatusText(patient) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
@ -241,7 +241,7 @@
|
||||
<button
|
||||
v-if="!isReadOnly"
|
||||
class="action-btn primary"
|
||||
@click="handleSaveResults"
|
||||
@click="handleSaveClick"
|
||||
>
|
||||
保存结果
|
||||
</button>
|
||||
@ -437,7 +437,7 @@ const handleMedicalSnSearch = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 修改获取患者列表数据的函数
|
||||
// 修改获取患者列表数据的函数,确保状态更新
|
||||
const getPatientList = async () => {
|
||||
try {
|
||||
const params = {
|
||||
@ -445,9 +445,16 @@ const getPatientList = async () => {
|
||||
pageSize: pageSize.value
|
||||
}
|
||||
const res = await PatientApi.getPatientPage(params)
|
||||
originalPatients.value = res.list // 保存原始列表
|
||||
patients.value = res.list
|
||||
total.value = res.total
|
||||
|
||||
// 如果当前有选中的患者,更新其状态
|
||||
if (selectedPatient.value) {
|
||||
const updatedPatient = res.list.find(p => p.id === selectedPatient.value.id)
|
||||
if (updatedPatient) {
|
||||
selectedPatient.value = updatedPatient
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取患者列表出错:', error)
|
||||
message.error('获取患者列表出错')
|
||||
@ -463,15 +470,28 @@ const getpatientitemData = async (medicalSn) => {
|
||||
pageSize: 100
|
||||
}
|
||||
const itemsRes = await PatientitemsApi.getPatientitemsPage(params)
|
||||
|
||||
if (itemsRes.list && itemsRes.list.length > 0) {
|
||||
patientitemData.value = itemsRes.list[0]
|
||||
|
||||
// 获取用户信息
|
||||
try {
|
||||
const userProfile = await getUserProfile()
|
||||
user.value = userProfile
|
||||
} catch (userError) {
|
||||
console.error('获取用户信息失败:', userError)
|
||||
const userProfile = await getUserProfile()
|
||||
user.value = userProfile
|
||||
|
||||
// 检查当前部门的项目状态
|
||||
const currentDeptItems = itemsRes.list.filter(item =>
|
||||
item.sectionID === userProfile.deptId || item.sectionID == userProfile.deptId
|
||||
)
|
||||
// 如果有项目且都是已检查状态,更新患者状态
|
||||
if (currentDeptItems.length > 0 && currentDeptItems.every(item => item.itemStatus === '1')) {
|
||||
// 更新患者列表中的状态
|
||||
const patientIndex = patients.value.findIndex(p => p.medicalSn === medicalSn)
|
||||
if (patientIndex !== -1) {
|
||||
patients.value[patientIndex] = {
|
||||
...patients.value[patientIndex],
|
||||
examStatus: '1' // 添加检查状态属性
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
@ -522,11 +542,15 @@ const loadPatientData = async (patient) => {
|
||||
// 如果不是特殊科室,继续加载常规检查数据
|
||||
if (!isImageDepartment.value && !isBloodTest.value) {
|
||||
if (itemsRes.list && itemsRes.list.length > 0) {
|
||||
examConclusion.value = itemsRes.list[0].analyse || ''
|
||||
|
||||
const itemsBySection = {}
|
||||
// 筛选属于当前用户部门的项目
|
||||
const filteredItems = itemsRes.list.filter(item => item.sectionID == userProfile.deptId)
|
||||
|
||||
// 从第一个项目获取体检小结
|
||||
if (filteredItems.length > 0) {
|
||||
examConclusion.value = filteredItems[0].analyse || ''
|
||||
}
|
||||
|
||||
filteredItems.forEach(item => {
|
||||
const sectionType = '一般检查'
|
||||
if (!itemsBySection[sectionType]) {
|
||||
@ -536,14 +560,16 @@ const loadPatientData = async (patient) => {
|
||||
const processedItem = {
|
||||
id: item.id,
|
||||
name: item.itemName,
|
||||
value: item.itemResult,
|
||||
value: item.itemResult || '', // 确保正确映射 itemResult 到 value
|
||||
unit: item.unit,
|
||||
reference: `${item.lowValue}-${item.highValue}`,
|
||||
note: getStatusNote(item),
|
||||
risk: getRiskLevel(item),
|
||||
status: getRowStatus(item),
|
||||
positive: item.positive === '1' ? '阳性' : '阴性',
|
||||
itemStatus: item.itemStatus
|
||||
itemStatus: item.itemStatus,
|
||||
examDescription: item.examDescription || '',
|
||||
analyse: item.analyse || ''
|
||||
}
|
||||
|
||||
itemsBySection[sectionType].push(processedItem)
|
||||
@ -991,20 +1017,50 @@ const handleSearch = () => {
|
||||
)
|
||||
}
|
||||
|
||||
// 添加是否只读的计算属性
|
||||
const isReadOnly = computed(() => {
|
||||
return selectedPatient.value?.status === 1
|
||||
// 添加计算属性检查是否所有项目都已完成
|
||||
const isAllItemsChecked = computed(() => {
|
||||
if (!sortedExamItems.value || sortedExamItems.value.length === 0) return false
|
||||
return sortedExamItems.value.every(item => item.itemStatus === '1')
|
||||
})
|
||||
|
||||
// 检查编辑权限的方法
|
||||
// 修改检查编辑权限的方法
|
||||
const checkEditPermission = () => {
|
||||
if (isReadOnly.value) {
|
||||
ElMessage.warning('检查结果已保存,不可进行编辑')
|
||||
if (isAllItemsChecked.value) {
|
||||
ElMessage.warning('所有检查项目已完成,不可进行编辑')
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 修改结果变化处理函数
|
||||
const handleResultChange = (item) => {
|
||||
if (!checkEditPermission()) {
|
||||
// 如果没有编辑权限,恢复原值
|
||||
item.value = item.originalValue || ''
|
||||
return
|
||||
}
|
||||
|
||||
// 如果有输入值,设置为已检状态
|
||||
if (item.value) {
|
||||
item.itemStatus = '1'
|
||||
} else {
|
||||
item.itemStatus = '0'
|
||||
}
|
||||
|
||||
item.originalValue = item.value
|
||||
|
||||
if (item.reference && item.reference !== 'null-null') {
|
||||
const value = parseFloat(item.value)
|
||||
const [low, high] = item.reference.split('-').map(val => val === 'null' ? null : Number(val))
|
||||
|
||||
if (low !== null && high !== null) {
|
||||
item.note = getStatusNote({ itemResult: value, lowValue: low, highValue: high })
|
||||
item.risk = getRiskLevel({ itemResult: value, lowValue: low, highValue: high })
|
||||
item.status = getRowStatus({ itemResult: value, lowValue: low, highValue: high })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 修改操作处理函数
|
||||
const handleOperation = ({ type, item }) => {
|
||||
if (!checkEditPermission()) return
|
||||
@ -1012,9 +1068,11 @@ const handleOperation = ({ type, item }) => {
|
||||
switch (type) {
|
||||
case 'positive':
|
||||
item.positive = '阳性'
|
||||
item.itemStatus = '1'
|
||||
break
|
||||
case 'negative':
|
||||
item.positive = '阴性'
|
||||
item.itemStatus = '1'
|
||||
break
|
||||
case 'abandon':
|
||||
if (item.itemStatus === '2') {
|
||||
@ -1040,126 +1098,137 @@ const handleOperation = ({ type, item }) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 修改结果变化处理函数
|
||||
const handleResultChange = (item) => {
|
||||
if (!checkEditPermission()) {
|
||||
item.value = item.originalValue || ''
|
||||
return
|
||||
}
|
||||
|
||||
item.itemStatus = '1' // 设置为已检状态
|
||||
|
||||
// 如果没有有效的参考值,所有相关字段都设为空
|
||||
if (!item.reference || item.reference === 'null-null') {
|
||||
item.note = ''
|
||||
item.risk = ''
|
||||
item.status = ''
|
||||
return
|
||||
}
|
||||
|
||||
const value = parseFloat(item.value)
|
||||
const [low, high] = item.reference.split('-').map(val => val === 'null' ? null : Number(val))
|
||||
|
||||
if (low === null || high === null) {
|
||||
item.note = ''
|
||||
item.risk = ''
|
||||
item.status = ''
|
||||
return
|
||||
}
|
||||
|
||||
item.note = getStatusNote({ itemResult: value, lowValue: low, highValue: high })
|
||||
item.risk = getRiskLevel({ itemResult: value, lowValue: low, highValue: high })
|
||||
item.status = getRowStatus({ itemResult: value, lowValue: low, highValue: high })
|
||||
}
|
||||
|
||||
// 添加状态映射函数
|
||||
const getItemStatusText = (status) => {
|
||||
const statusMap = {
|
||||
'0': '未检查',
|
||||
'1': '已检查',
|
||||
'2': '已弃检',
|
||||
'3': '待查'
|
||||
}
|
||||
return statusMap[status] || status
|
||||
}
|
||||
|
||||
// 修改保存结果方法中的相关逻辑
|
||||
// 修改保存结果方法
|
||||
const handleSaveResults = async () => {
|
||||
if (!checkEditPermission()) return
|
||||
|
||||
try {
|
||||
const userProfile = await getUserProfile()
|
||||
user.value = userProfile
|
||||
|
||||
// 获取当前时间戳
|
||||
const currentTime = new Date().getTime()
|
||||
|
||||
// 1. 更新检查项目结果
|
||||
const updatedItems = Object.values(examItems.value).flatMap(sectionItems =>
|
||||
sectionItems.map(item => ({
|
||||
id: item.id,
|
||||
status: item.status,
|
||||
itemResult: item.value || '',
|
||||
positive: item.positive === '阳性' ? '1' : '0',
|
||||
analyse: examConclusion.value,
|
||||
inspectdoctor: user.value?.nickname || '',
|
||||
itemStatus: item.itemStatus,
|
||||
inspecttime: currentTime
|
||||
}))
|
||||
)
|
||||
|
||||
await PatientitemsApi.updatePatientitemsBatch(updatedItems)
|
||||
|
||||
// 2. 更新患者状态为已检查
|
||||
if (selectedPatient.value) {
|
||||
const patientData = {
|
||||
...selectedPatient.value,
|
||||
status: 1,
|
||||
medicalDateTime: currentTime
|
||||
}
|
||||
await PatientApi.updatePatient(patientData)
|
||||
const currentTimestamp = Date.now()
|
||||
|
||||
// 构建更新项目数组,将体检小结保存到每个项目中
|
||||
const updatedItems = sortedExamItems.value.map(item => {
|
||||
const status = item.value ? '1' : '0'
|
||||
|
||||
// 3. 刷新患者列表
|
||||
await getPatientList()
|
||||
|
||||
return {
|
||||
id: item.id,
|
||||
medicalSn: selectedPatient.value?.medicalSn,
|
||||
itemStatus: status,
|
||||
itemResult: item.value || '',
|
||||
examDescription: item.examDescription || '',
|
||||
analyse: examConclusion.value || '', // 每个项目都保存体检小结
|
||||
inspectdoctor: user.value?.nickname || '',
|
||||
inspecttime: currentTimestamp,
|
||||
positive: item.positive === '阳性' ? '1' : '0',
|
||||
sectionID: user.value?.deptId
|
||||
}
|
||||
})
|
||||
|
||||
if (updatedItems.length === 0) {
|
||||
ElMessage.warning('没有需要保存的检查项目')
|
||||
return
|
||||
}
|
||||
|
||||
message.success('保存成功')
|
||||
|
||||
// 4. 清空所有相关数据
|
||||
selectedPatient.value = null
|
||||
examItems.value = {}
|
||||
examTabs.value = []
|
||||
currentTab.value = ''
|
||||
examConclusion.value = ''
|
||||
patients.value = []
|
||||
originalPatients.value = []
|
||||
medicalSnQuery.value = '' // 清空体检编号搜索框
|
||||
searchQuery.value = '' // 清空搜索框
|
||||
reportData.value = {
|
||||
medicalSn: '',
|
||||
cardId: '',
|
||||
pName: '',
|
||||
gender: '',
|
||||
birthday: '',
|
||||
nationality: '',
|
||||
nation: '',
|
||||
race: '',
|
||||
phoneNum: '',
|
||||
status: 0,
|
||||
reportType: '',
|
||||
medicalDateTime: '',
|
||||
chargeType: '',
|
||||
totalPrice: 0,
|
||||
headPicUrl: '',
|
||||
summaryResult: '',
|
||||
auditor: '',
|
||||
auditorTime: ''
|
||||
|
||||
const res = await PatientitemsApi.updatePatientitemsBatch(updatedItems)
|
||||
|
||||
ElMessage.success('保存成功')
|
||||
|
||||
// 重新获取最新数据
|
||||
try {
|
||||
const params = {
|
||||
medicalSn: selectedPatient.value?.medicalSn,
|
||||
pageNo: 1,
|
||||
pageSize: 100
|
||||
}
|
||||
const itemsRes = await PatientitemsApi.getPatientitemsPage(params)
|
||||
|
||||
if (itemsRes.list && itemsRes.list.length > 0) {
|
||||
// 获取当前科室的项目
|
||||
const currentDeptItems = itemsRes.list.filter(item =>
|
||||
item.sectionID === user.value?.deptId
|
||||
)
|
||||
|
||||
// 检查是否所有项目都已完成
|
||||
const allChecked = currentDeptItems.every(item => item.itemStatus === '1')
|
||||
|
||||
// 从任意一个项目中获取体检小结
|
||||
if (currentDeptItems.length > 0) {
|
||||
const anyItem = currentDeptItems.find(item => item.analyse)
|
||||
if (anyItem) {
|
||||
examConclusion.value = anyItem.analyse
|
||||
}
|
||||
}
|
||||
|
||||
// 更新本地数据
|
||||
sortedExamItems.value = sortedExamItems.value.map(item => {
|
||||
const updatedItem = itemsRes.list.find(u => u.id === item.id)
|
||||
if (updatedItem) {
|
||||
return {
|
||||
...item,
|
||||
itemStatus: updatedItem.itemStatus,
|
||||
value: updatedItem.itemResult || '',
|
||||
examDescription: updatedItem.examDescription,
|
||||
analyse: updatedItem.analyse,
|
||||
positive: updatedItem.positive === '1' ? '阳性' : '阴性'
|
||||
}
|
||||
}
|
||||
return item
|
||||
})
|
||||
|
||||
// 更新左侧患者列表状态
|
||||
if (selectedPatient.value) {
|
||||
const patientIndex = patients.value.findIndex(p => p.medicalSn === selectedPatient.value.medicalSn)
|
||||
if (patientIndex !== -1) {
|
||||
const allItemsChecked = currentDeptItems.every(item => item.itemStatus === '1')
|
||||
|
||||
// 更新患者状态
|
||||
patients.value[patientIndex] = {
|
||||
...patients.value[patientIndex],
|
||||
examStatus: allItemsChecked ? '1' : '0'
|
||||
}
|
||||
|
||||
// 更新原始患者列表
|
||||
if (originalPatients.value) {
|
||||
const originalIndex = originalPatients.value.findIndex(p => p.medicalSn === selectedPatient.value.medicalSn)
|
||||
if (originalIndex !== -1) {
|
||||
originalPatients.value[originalIndex] = {
|
||||
...originalPatients.value[originalIndex],
|
||||
examStatus: allItemsChecked ? '1' : '0'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('刷新数据失败:', error)
|
||||
}
|
||||
|
||||
|
||||
// 更新缓存
|
||||
if (selectedPatient.value) {
|
||||
const cacheKey = selectedPatient.value.id
|
||||
patientDataCache.value.delete(cacheKey)
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('保存失败:', error)
|
||||
message.error(`保存失败: ${error.message}`)
|
||||
ElMessage.error(`保存失败: ${error.message || '请检查数据是否完整'}`)
|
||||
}
|
||||
}
|
||||
|
||||
// 添加禁用状态的计算属性,用于控制界面元素
|
||||
const isDisabled = computed(() => {
|
||||
return isAllItemsChecked.value
|
||||
})
|
||||
|
||||
// 添加只读状态的计算属性
|
||||
const isReadOnly = computed(() => {
|
||||
return isAllItemsChecked.value
|
||||
})
|
||||
|
||||
// 添加分页处理函数
|
||||
const handleCurrentChange = (val) => {
|
||||
pageNo.value = val
|
||||
@ -1204,24 +1273,42 @@ const isImageExam = computed(() => {
|
||||
})
|
||||
})
|
||||
|
||||
// 添加状态文本映射函数
|
||||
const getStatusText = (status) => {
|
||||
const statusMap = {
|
||||
'0': '待检查',
|
||||
'1': '已检查',
|
||||
'2': '已弃检'
|
||||
// 添加检查项目状态的计算属性
|
||||
const patientExamStatus = computed(() => {
|
||||
if (!selectedPatient.value?.medicalSn) return '0'
|
||||
|
||||
const currentItems = Object.values(examItems.value)
|
||||
.flat()
|
||||
.filter(item => item.sectionID === user.value?.deptId)
|
||||
|
||||
if (!currentItems.length) return '0'
|
||||
|
||||
const allChecked = currentItems.every(item => item.itemStatus === '1')
|
||||
return allChecked ? '1' : '0'
|
||||
})
|
||||
|
||||
// 修改获取状态文本的方法
|
||||
const getStatusText = (patient) => {
|
||||
if (patient.examStatus === '1') {
|
||||
return '已检查'
|
||||
}
|
||||
return statusMap[status] || '未知'
|
||||
|
||||
if (selectedPatient.value?.id === patient.id) {
|
||||
const currentDeptItems = Object.values(examItems.value)
|
||||
.flat()
|
||||
.filter(item => item.sectionID === user.value?.deptId)
|
||||
|
||||
if (currentDeptItems.length > 0 && currentDeptItems.every(item => item.itemStatus === '1')) {
|
||||
return '已检查'
|
||||
}
|
||||
}
|
||||
|
||||
return '待检查'
|
||||
}
|
||||
|
||||
// 添加状态标签类型映射函数
|
||||
const getStatusTagType = (status) => {
|
||||
const typeMap = {
|
||||
'0': 'info', // 灰蓝色
|
||||
'1': 'success', // 绿色
|
||||
'2': 'danger' // 红色
|
||||
}
|
||||
return typeMap[status] || ''
|
||||
// 修改状态标签类型
|
||||
const getStatusTagType = (patient) => {
|
||||
return getStatusText(patient) === '已检查' ? 'success' : 'info'
|
||||
}
|
||||
|
||||
// 添加参考值格式化函数
|
||||
@ -1243,11 +1330,9 @@ const isImageDepartment = ref(false)
|
||||
const isBloodTest = computed(() => {
|
||||
if (!selectedPatient.value) return false
|
||||
|
||||
// 获取当前用户部门下的检查项目
|
||||
const currentItems = Object.values(examItems.value)
|
||||
.flat()
|
||||
.filter(item => {
|
||||
// 检查项目名称中包含血常规相关关键词
|
||||
const itemName = (item.name || '').toLowerCase()
|
||||
return itemName.includes('血常规') ||
|
||||
itemName.includes('血细胞') ||
|
||||
|
@ -1035,9 +1035,10 @@ const handlePersonInfoSave = async () => {
|
||||
itemStatus: '0',
|
||||
createTime: new Date().getTime(),
|
||||
headimage: avatar,
|
||||
groupname: item.groupname,
|
||||
groupcode: item.groupcode,
|
||||
mealfrontorafter: item.mealfrontorafter
|
||||
groupname: item.groupname || '',
|
||||
groupcode: item.groupcode || '',
|
||||
mealfrontorafter: item.mealfrontorafter || '',
|
||||
moduleName: item.moduleName || '' // 使用项目中的moduleName字段
|
||||
}))
|
||||
|
||||
await PatientitemsApi.createPatientitemsBatch(saveItems)
|
||||
@ -1222,7 +1223,7 @@ const getSectionName = async (sectionID) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 修改加载患者项目的方法,移除调试日志
|
||||
// 修改加载患者项目的方法,确保moduleName正确加载
|
||||
const loadPatientProjects = async (medicalSn) => {
|
||||
if (!medicalSn) {
|
||||
comboInfoTable1.value = []
|
||||
@ -1249,18 +1250,20 @@ const loadPatientProjects = async (medicalSn) => {
|
||||
// 获取科室名称
|
||||
const sectionName = await getSectionName(item.sectionID)
|
||||
|
||||
console.log('加载项目,moduleName:', item.moduleName)
|
||||
|
||||
projectDetails.push({
|
||||
name: item.itemName,
|
||||
price: item.price || 0,
|
||||
discount: item.discounted || 0,
|
||||
discountPrice: item.discountedPrice || 0,
|
||||
moduleName: item.moduleName || '',
|
||||
moduleName: item.moduleName || '', // 确保加载moduleName
|
||||
section: sectionName,
|
||||
sectionID: item.sectionID || '',
|
||||
itemCode: item.itemCode,
|
||||
groupname: item.groupname || '', // 添加模块名称
|
||||
groupcode: item.groupcode || '', // 添加模块ID
|
||||
mealfrontorafter: item.mealfrontorafter || '' // 添加餐前餐后
|
||||
groupname: item.groupname || '',
|
||||
groupcode: item.groupcode || '',
|
||||
mealfrontorafter: item.mealfrontorafter || ''
|
||||
})
|
||||
}
|
||||
|
||||
@ -1453,7 +1456,7 @@ const handleCheckInfoSelection = (selection) => {
|
||||
checkInfoSelectedData.value = selection
|
||||
}
|
||||
|
||||
// 修改确认选择项目的方法,移除调试日志
|
||||
// 修改确认选择项目的方法,确保正确的moduleName被保存
|
||||
const confirmSelectedProjects = async () => {
|
||||
try {
|
||||
let selectedProjects: ProjectDetail[] = []
|
||||
@ -1498,7 +1501,7 @@ const confirmSelectedProjects = async () => {
|
||||
price: item.price || 0,
|
||||
discount: item.discounted || 0,
|
||||
discountPrice: item.discountedPrice || 0,
|
||||
moduleName: item.moduleName || moduleItem.examModuleName,
|
||||
moduleName: item.moduleName || '', // 优先使用项目的moduleName
|
||||
itemCode: moduleItem.itemCode,
|
||||
groupname: item.groupname || '',
|
||||
groupcode: item.groupcode || '',
|
||||
@ -1530,7 +1533,7 @@ const confirmSelectedProjects = async () => {
|
||||
price: item.price,
|
||||
discount: item.discounted,
|
||||
discountPrice: item.discountedPrice,
|
||||
moduleName: item.moduleName,
|
||||
moduleName: item.moduleName || '', // 使用项目的moduleName
|
||||
itemCode: item.itemCode,
|
||||
groupname: item.groupname || '',
|
||||
groupcode: item.groupcode || '',
|
||||
|
@ -69,6 +69,8 @@
|
||||
<el-table-column prop="highValue" label="取值上限" :resizable="false" />
|
||||
<el-table-column prop="lowValue" label="取值下限" :resizable="false" />
|
||||
<el-table-column prop="moduleName" label="体检单元" :resizable="false" />
|
||||
<el-table-column prop="groupname" label="模块名称" :resizable="false" />
|
||||
<el-table-column prop="mealfrontorafter" label="餐前餐后" :resizable="false" />
|
||||
<el-table-column label="操作" width="180" :resizable="false">
|
||||
<template #default="scope">
|
||||
<el-dropdown>
|
||||
@ -129,6 +131,8 @@ interface QueryParams {
|
||||
section?: string
|
||||
currentSelection: string | number
|
||||
moduleName?: string
|
||||
groupname?: string
|
||||
mealfrontorafter?: string
|
||||
}
|
||||
|
||||
const queryParams = reactive<QueryParams>({
|
||||
@ -136,7 +140,9 @@ const queryParams = reactive<QueryParams>({
|
||||
projectName: '',
|
||||
projectCode: '',
|
||||
pageNo: 1,
|
||||
pageSize: 10
|
||||
pageSize: 10,
|
||||
groupname: '',
|
||||
mealfrontorafter: ''
|
||||
})
|
||||
|
||||
// 新增组件
|
||||
@ -192,6 +198,15 @@ const getTableData = async () => {
|
||||
params.section = queryParams.currentSelection
|
||||
}
|
||||
|
||||
// 添加模块名称和餐前餐后的查询条件
|
||||
if (queryParams.groupname?.trim()) {
|
||||
params.groupname = queryParams.groupname.trim()
|
||||
}
|
||||
|
||||
if (queryParams.mealfrontorafter?.trim()) {
|
||||
params.mealfrontorafter = queryParams.mealfrontorafter.trim()
|
||||
}
|
||||
|
||||
const data = await itemsApi.getitemsPage(params)
|
||||
if (data && data.list) {
|
||||
tableData.value = data.list
|
||||
|
210
src/views/summary/reprot-print/report-print.vue
Normal file
210
src/views/summary/reprot-print/report-print.vue
Normal file
@ -0,0 +1,210 @@
|
||||
<template>
|
||||
<ContentWrap style="height: 70px; display: flex; align-items: center;">
|
||||
<!-- 搜索工作栏 -->
|
||||
<el-form
|
||||
class="-mb-15px"
|
||||
:model="queryParams"
|
||||
ref="queryFormRef"
|
||||
:inline="true"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="体检编号" prop="medicalSn">
|
||||
<el-input
|
||||
v-model="queryParams.medicalSn"
|
||||
placeholder="请输入体检编号"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="pname">
|
||||
<el-input
|
||||
v-model="queryParams.pname"
|
||||
placeholder="请输入姓名"
|
||||
clearable
|
||||
@input="handleQuery"
|
||||
class="!w-200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="体检日期" prop="medicalDateTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.medicalDateTime"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
:default-time="[
|
||||
new Date(2000, 1, 1, 0, 0, 0),
|
||||
new Date(2000, 1, 1, 23, 59, 59)
|
||||
]"
|
||||
clearable
|
||||
class="!w-320px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleQuery">
|
||||
<Icon icon="ep:search" class="mr-5px" /> 查询
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="list"
|
||||
:stripe="true"
|
||||
:show-overflow-tooltip="true"
|
||||
:header-cell-style="{ background: 'rgb(235, 241, 250)', height: '56px',color:'#333333' }"
|
||||
:row-style="{ height: '56px' }"
|
||||
>
|
||||
<el-table-column label="体检编号" align="center" prop="medicalSn" />
|
||||
<el-table-column label="姓名" align="center" prop="pname" />
|
||||
<el-table-column label="性别" align="center" prop="gender" />
|
||||
<el-table-column
|
||||
label="体检日期"
|
||||
align="center"
|
||||
prop="medicalDateTime"
|
||||
:formatter="dateFormatter"
|
||||
min-width="120"
|
||||
/>
|
||||
<el-table-column label="操作" align="center" fixed="right" width="120px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="handlePrint(scope.row)"
|
||||
>
|
||||
打印报告
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页 -->
|
||||
<Pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 表单弹窗:添加/修改 -->
|
||||
<DepartmentForm ref="formRef" @success="getList" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PatientApi, type PatientVO } from '@/api/inspect/inspectpatient'
|
||||
|
||||
defineOptions({ name: 'Department' })
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
const { t } = useI18n() // 国际化
|
||||
const loading = ref(true) // 列表的加载中
|
||||
const allList = ref<PatientVO[]>([]) // 存储所有数据
|
||||
const list = ref<PatientVO[]>([]) // 用于展示的数据
|
||||
const total = ref(0) // 列表的总页数
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
medicalSn: undefined,
|
||||
pname: undefined,
|
||||
medicalDateTime: [],
|
||||
auditStatus: 0
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
|
||||
/** 获取列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await PatientApi.getPatientPage({
|
||||
pageNo: queryParams.pageNo,
|
||||
pageSize: queryParams.pageSize,
|
||||
medicalSn: queryParams.medicalSn,
|
||||
pname: queryParams.pname,
|
||||
medicalDateTime: queryParams.medicalDateTime,
|
||||
auditStatus: queryParams.auditStatus
|
||||
})
|
||||
list.value = data.list
|
||||
total.value = data.total
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 搜索操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields()
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
/** 添加/修改操作 */
|
||||
const formRef = ref()
|
||||
const openForm = (type: string, username: string, id?: number) => {
|
||||
formRef.value.open(type, username, id)
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
// 删除的二次确认
|
||||
await message.delConfirm()
|
||||
// 发起删除
|
||||
await DepartmentApi.deleteDepartment(id)
|
||||
message.success(t('common.delSuccess'))
|
||||
// 刷新列表
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
// 导出的二次确认
|
||||
await message.exportConfirm()
|
||||
// 发起导出
|
||||
exportLoading.value = true
|
||||
const data = await DepartmentApi.exportDepartment(queryParams)
|
||||
download.excel(data, '科室管理.xls')
|
||||
} catch {
|
||||
} finally {
|
||||
exportLoading.value = false
|
||||
}
|
||||
}
|
||||
//获取当前登录人信息
|
||||
const getlogininfo = async () => {
|
||||
Profilevo.value = await getUserProfile()
|
||||
}
|
||||
/** 初始化 **/
|
||||
onMounted(() => {
|
||||
getlogininfo()
|
||||
getList() // 改为直接调用 getList
|
||||
})
|
||||
|
||||
/** 打印报告按钮操作 */
|
||||
const handlePrint = async (row: PatientVO) => {
|
||||
try {
|
||||
const blob = await PatientApi.exportPatient({ medicalSn: row.medicalSn })
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
window.open(url)
|
||||
window.URL.revokeObjectURL(url)
|
||||
} catch (error) {
|
||||
message.error('打印报告失败')
|
||||
}
|
||||
}
|
||||
|
||||
/** 日期格式化 */
|
||||
const dateFormatter = (row: any, column: any) => {
|
||||
if (!row.medicalDateTime) return ''
|
||||
const date = new Date(row.medicalDateTime)
|
||||
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`
|
||||
}
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user