新增科室录入界面区分以及接口
This commit is contained in:
parent
9c6305a0d2
commit
81762466b2
49
src/api/inspect/ inspectlisdata/index.ts
Normal file
49
src/api/inspect/ inspectlisdata/index.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
// lis抓取数据 VO
|
||||
export interface LisDataVO {
|
||||
id: number // 主键
|
||||
code: string // 体检编号
|
||||
type: string // 类型
|
||||
equipmentManufacturerModel: string // 设备厂商型号
|
||||
item: string // 项目
|
||||
personName: string // 检测者姓名
|
||||
time: Date // 检测时间
|
||||
data: string // 数据
|
||||
remark: string // 备注
|
||||
delFlag: number // 是否删除(0-未删除,1-已删除)
|
||||
createId: string // 创建人
|
||||
}
|
||||
|
||||
// lis抓取数据 API
|
||||
export const LisDataApi = {
|
||||
// 查询lis抓取数据分页
|
||||
getLisDataPage: async (params: any) => {
|
||||
return await request.get({ url: `/inspect/lis-data/page`, params })
|
||||
},
|
||||
|
||||
// 查询lis抓取数据详情
|
||||
getLisData: async (id: number) => {
|
||||
return await request.get({ url: `/inspect/lis-data/get?id=` + id })
|
||||
},
|
||||
|
||||
// 新增lis抓取数据
|
||||
createLisData: async (data: LisDataVO) => {
|
||||
return await request.post({ url: `/inspect/lis-data/create`, data })
|
||||
},
|
||||
|
||||
// 修改lis抓取数据
|
||||
updateLisData: async (data: LisDataVO) => {
|
||||
return await request.put({ url: `/inspect/lis-data/update`, data })
|
||||
},
|
||||
|
||||
// 删除lis抓取数据
|
||||
deleteLisData: async (id: number) => {
|
||||
return await request.delete({ url: `/inspect/lis-data/delete?id=` + id })
|
||||
},
|
||||
|
||||
// 导出lis抓取数据 Excel
|
||||
exportLisData: async (params) => {
|
||||
return await request.download({ url: `/inspect/lis-data/export-excel`, params })
|
||||
},
|
||||
}
|
50
src/api/inspect/inspectpacsdata/index.ts
Normal file
50
src/api/inspect/inspectpacsdata/index.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
// pacs抓取数据 VO
|
||||
export interface PacsDataVO {
|
||||
id: number // 主键
|
||||
code: string // 体检编号
|
||||
data: string // 数据
|
||||
time: Date // 监测时间
|
||||
equipmentManufacturerModel: string // 设备厂商型号
|
||||
item: string // 项目
|
||||
type: string // 类型
|
||||
remark: string // 备注
|
||||
delFlag: number // 是否删除(0-未删除,1-已删除)
|
||||
createId: string // 创建人
|
||||
createTime: Date // 创建时间
|
||||
personName: string // 检测者姓名
|
||||
}
|
||||
|
||||
// pacs抓取数据 API
|
||||
export const PacsDataApi = {
|
||||
// 查询pacs抓取数据分页
|
||||
getPacsDataPage: async (params: any) => {
|
||||
return await request.get({ url: `/inspect/pacs-data/page`, params })
|
||||
},
|
||||
|
||||
// 查询pacs抓取数据详情
|
||||
getPacsData: async (id: number) => {
|
||||
return await request.get({ url: `/inspect/pacs-data/get?id=` + id })
|
||||
},
|
||||
|
||||
// 新增pacs抓取数据
|
||||
createPacsData: async (data: PacsDataVO) => {
|
||||
return await request.post({ url: `/inspect/pacs-data/create`, data })
|
||||
},
|
||||
|
||||
// 修改pacs抓取数据
|
||||
updatePacsData: async (data: PacsDataVO) => {
|
||||
return await request.put({ url: `/inspect/pacs-data/update`, data })
|
||||
},
|
||||
|
||||
// 删除pacs抓取数据
|
||||
deletePacsData: async (id: number) => {
|
||||
return await request.delete({ url: `/inspect/pacs-data/delete?id=` + id })
|
||||
},
|
||||
|
||||
// 导出pacs抓取数据 Excel
|
||||
exportPacsData: async (params) => {
|
||||
return await request.download({ url: `/inspect/pacs-data/export-excel`, params })
|
||||
},
|
||||
}
|
@ -447,22 +447,15 @@ const fetchPatientsByDate = async () => {
|
||||
`${formatDate(endDate)} 23:59:59`
|
||||
],
|
||||
// 添加搜索关键词
|
||||
pname: searchQuery.value || undefined
|
||||
pname: searchQuery.value || undefined,
|
||||
// 添加收费状态筛选参数
|
||||
chargeStatus: chargeStatus.value === 'paid' ? '1' : '0'
|
||||
}
|
||||
|
||||
const res = await PatientApi.getPatientPage(params)
|
||||
|
||||
// 在前端根据chargeType字段筛选
|
||||
if (chargeStatus.value === 'unpaid') {
|
||||
// 筛选未收费的患者(chargeType为null、undefined或空字符串)
|
||||
patients.value = res.list.filter(patient => !patient.chargeType || patient.chargeType === '')
|
||||
} else {
|
||||
// 筛选已收费的患者(chargeType有值且不为空字符串)
|
||||
patients.value = res.list.filter(patient => patient.chargeType && patient.chargeType !== '')
|
||||
}
|
||||
|
||||
// 更新总数
|
||||
total.value = patients.value.length
|
||||
patients.value = res.list || []
|
||||
total.value = res.total || 0
|
||||
|
||||
// 如果没有查询到患者,清除选中状态
|
||||
if (patients.value.length === 0) {
|
||||
@ -576,8 +569,10 @@ onMounted(() => {
|
||||
// 设置默认为今日
|
||||
const today = new Date()
|
||||
selectedPeriod.value = 'today'
|
||||
const todayStart = new Date(today.setHours(0, 0, 0, 0))
|
||||
const todayEnd = new Date(today.setHours(23, 59, 59, 999))
|
||||
const todayStart = new Date(today)
|
||||
todayStart.setHours(0, 0, 0, 0)
|
||||
const todayEnd = new Date(today)
|
||||
todayEnd.setHours(23, 59, 59, 999)
|
||||
customDateRange.value = [todayStart, todayEnd]
|
||||
|
||||
// 获取今日数据
|
||||
|
710
src/views/Department-entry/CT.vue
Normal file
710
src/views/Department-entry/CT.vue
Normal file
@ -0,0 +1,710 @@
|
||||
<template>
|
||||
<div class="ct-container">
|
||||
<!-- 基本信息 -->
|
||||
<div class="basic-info">
|
||||
<div class="photo-box">
|
||||
<img v-if="reportData.headPicUrl" :src="reportData.headPicUrl" alt="头像" class="photo"/>
|
||||
<div v-else class="no-photo">个人照片</div>
|
||||
</div>
|
||||
<div class="info-grid">
|
||||
<div class="info-row">
|
||||
<div class="info-item">
|
||||
<label>体检编号:</label>
|
||||
<span>{{ reportData.medicalSn }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>身份证号:</label>
|
||||
<span>{{ reportData.cardId }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>姓名:</label>
|
||||
<span>{{ reportData.pname }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<div class="info-item">
|
||||
<label>性别:</label>
|
||||
<span>{{ reportData.gender }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>年龄:</label>
|
||||
<span>{{ age }}岁</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>电话:</label>
|
||||
<span>{{ reportData.phoneNum }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 检查结果部分 -->
|
||||
<div class="exam-results">
|
||||
<!-- 检查项目标签 -->
|
||||
<div class="exam-tabs">
|
||||
<div
|
||||
v-for="tab in examTabs"
|
||||
:key="tab.id"
|
||||
:class="['tab-item', { active: currentTab === tab.id }]"
|
||||
@click="switchTab(tab.id)"
|
||||
>
|
||||
<div class="tab-indicator" :style="{ background: tab.color }"></div>
|
||||
<span>{{ tab.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 影像检查结果 -->
|
||||
<div class="image-results">
|
||||
<!-- 影像图片展示区 -->
|
||||
<div class="image-gallery">
|
||||
<div class="gallery-title">影像图片</div>
|
||||
<div class="image-container">
|
||||
<div v-if="imageUrls.length > 0" class="image-grid">
|
||||
<div v-for="(url, index) in imageUrls" :key="index" class="image-item">
|
||||
<el-image
|
||||
:src="url"
|
||||
:preview-src-list="imageUrls"
|
||||
:initial-index="index"
|
||||
fit="contain"
|
||||
class="medical-image"
|
||||
@error="handleImageError"
|
||||
:preview-teleported="true"
|
||||
>
|
||||
<template #error>
|
||||
<div class="image-error">
|
||||
<el-icon><Picture /></el-icon>
|
||||
<div class="error-text">加载失败</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="no-images">
|
||||
<el-empty description="暂无影像资料" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 检查所见和诊断 -->
|
||||
<div class="findings-diagnosis-container">
|
||||
<div class="findings-section">
|
||||
<div class="section-title">检查所见</div>
|
||||
<textarea
|
||||
v-model="imageFinding"
|
||||
placeholder="请输入检查所见"
|
||||
class="findings-textarea"
|
||||
:readonly="isReadOnly"
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
<div class="diagnosis-section">
|
||||
<div class="section-title">影像诊断</div>
|
||||
<textarea
|
||||
v-model="imageDiagnosis"
|
||||
placeholder="请输入影像诊断"
|
||||
class="diagnosis-textarea"
|
||||
:readonly="isReadOnly"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<div class="action-footer">
|
||||
<div class="footer-content">
|
||||
<div class="doctor-info">
|
||||
<span>检查医生:{{ user?.nickname || '暂无' }}</span>
|
||||
<span>检查日期:{{ formattedMedicalDateTime }}</span>
|
||||
</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"
|
||||
class="action-btn primary"
|
||||
@click="handleSaveResults"
|
||||
>
|
||||
保存结果
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox, ElLoading } from 'element-plus'
|
||||
import { PatientApi } from '@/api/inspect/inspectpatient'
|
||||
import { PatientitemsApi } from '@/api/inspect/inspectpatientitems'
|
||||
import { getUserProfile } from '@/api/system/user/profile'
|
||||
import { PacsDataApi } from '@/api/inspect/inspectpacsdata'
|
||||
import { Picture } from '@element-plus/icons-vue'
|
||||
|
||||
// 添加props定义
|
||||
const props = defineProps({
|
||||
patient: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
// 添加响应式引用
|
||||
const reportData = ref({})
|
||||
const imageUrls = ref([])
|
||||
const imageFinding = ref('')
|
||||
const imageDiagnosis = ref('')
|
||||
const examConclusion = ref('')
|
||||
const user = ref(null)
|
||||
const patientDataCache = ref(new Map())
|
||||
const pacsData = ref([])
|
||||
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' }
|
||||
])
|
||||
|
||||
// 当前选中的检查类型
|
||||
const currentTab = ref('ct')
|
||||
|
||||
// 切换检查类型
|
||||
const switchTab = async (tabId) => {
|
||||
console.log('切换到检查类型:', tabId)
|
||||
currentTab.value = tabId
|
||||
imageUrls.value = await getImageUrlsByType(tabId)
|
||||
console.log('获取到的图片URLs:', imageUrls.value)
|
||||
}
|
||||
|
||||
// 修改获取影像图片URL的方法
|
||||
const getImageUrlsByType = async (type) => {
|
||||
try {
|
||||
console.log('开始获取PACS数据, 参数:', {
|
||||
code: reportData.value.medicalSn,
|
||||
type: type.toUpperCase(),
|
||||
pageNo: 1,
|
||||
pageSize: 100
|
||||
})
|
||||
|
||||
// 检查必要参数
|
||||
if (!reportData.value.medicalSn) {
|
||||
console.warn('缺少体检编号(medicalSn)')
|
||||
return []
|
||||
}
|
||||
|
||||
// 简化请求参数,只传递必要的字段
|
||||
const response = await PacsDataApi.getPacsDataPage({
|
||||
code: reportData.value.medicalSn,
|
||||
type: type.toUpperCase(),
|
||||
pageNo: 1,
|
||||
pageSize: 100
|
||||
})
|
||||
|
||||
if (!response?.list) {
|
||||
console.warn('PACS数据列表为空')
|
||||
return []
|
||||
}
|
||||
|
||||
pacsData.value = response.list
|
||||
// 直接使用data字段作为图片URL,过滤掉空值
|
||||
const urls = response.list
|
||||
.map(item => item.data)
|
||||
.filter(url => url)
|
||||
|
||||
return urls
|
||||
} catch (error) {
|
||||
console.error('获取PACS数据失败:', error)
|
||||
ElMessage.error('获取影像数据失败,请联系管理员')
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
// 处理图片加载错误
|
||||
const handleImageError = (e) => {
|
||||
e.target.src = 'https://via.placeholder.com/500x400?text=Image+Not+Found'
|
||||
}
|
||||
|
||||
// 年龄计算属性
|
||||
const age = computed(() => {
|
||||
if (!reportData.value.birthday) return ''
|
||||
|
||||
// 处理 YYYY-MM-DD 格式的生日
|
||||
const birthDate = new Date(reportData.value.birthday)
|
||||
if (isNaN(birthDate.getTime())) return '' // 日期无效时返回空字符串
|
||||
|
||||
const today = new Date()
|
||||
let age = today.getFullYear() - birthDate.getFullYear()
|
||||
const monthDiff = today.getMonth() - birthDate.getMonth()
|
||||
|
||||
// 如果还没到生日月份,或者是生日月但还没到具体日期,年龄减1
|
||||
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
|
||||
age--
|
||||
}
|
||||
|
||||
return age
|
||||
})
|
||||
|
||||
// 格式化后的检查日期计算属性
|
||||
const formattedMedicalDateTime = computed(() => {
|
||||
if (!reportData.value.medicalDateTime) return ''
|
||||
const date = new Date(reportData.value.medicalDateTime)
|
||||
return date.toLocaleDateString('zh-CN', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit'
|
||||
}).replace(/\//g, '-')
|
||||
})
|
||||
|
||||
// 是否只读的计算属性
|
||||
const isReadOnly = computed(() => {
|
||||
return props.patient?.status === 1
|
||||
})
|
||||
|
||||
// 检查编辑权限的方法
|
||||
const checkEditPermission = () => {
|
||||
if (isReadOnly.value) {
|
||||
ElMessage.warning('检查结果已保存,不可进行编辑')
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 保存结果方法
|
||||
const handleSaveResults = async () => {
|
||||
try {
|
||||
const userProfile = await getUserProfile()
|
||||
user.value = userProfile
|
||||
|
||||
// 获取当前时间戳
|
||||
const currentTime = new Date().getTime()
|
||||
|
||||
// 更新检查项目结果
|
||||
const updatedItems = [{
|
||||
id: props.patient.id,
|
||||
examDescription: imageFinding.value,
|
||||
itemResult: imageDiagnosis.value,
|
||||
analyse: examConclusion.value,
|
||||
inspectdoctor: user.value?.nickname || '',
|
||||
itemStatus: '1', // 已检查
|
||||
inspecttime: currentTime
|
||||
}]
|
||||
|
||||
await PatientitemsApi.updatePatientitemsBatch(updatedItems)
|
||||
|
||||
// 更新患者状态为已检查
|
||||
if (props.patient) {
|
||||
const patientData = {
|
||||
...props.patient,
|
||||
status: 1,
|
||||
medicalDateTime: currentTime
|
||||
}
|
||||
await PatientApi.updatePatient(patientData)
|
||||
}
|
||||
|
||||
ElMessage.success('保存成功')
|
||||
|
||||
} catch (error) {
|
||||
console.error('保存失败:', error)
|
||||
ElMessage.error(`保存失败: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
// 加载患者数据
|
||||
const loadPatientData = async (patient) => {
|
||||
if (!patient || !patient.id) {
|
||||
console.log('没有有效的患者数据')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('开始加载患者数据:', patient.id)
|
||||
const cacheKey = patient.id
|
||||
if (patientDataCache.value.has(cacheKey)) {
|
||||
console.log('使用缓存的患者数据')
|
||||
const cachedData = patientDataCache.value.get(cacheKey)
|
||||
reportData.value = cachedData.reportData
|
||||
return
|
||||
}
|
||||
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: '加载中...',
|
||||
background: 'rgba(255, 255, 255, 0.7)'
|
||||
})
|
||||
|
||||
try {
|
||||
// 获取用户信息和患者数据
|
||||
const [userProfile, patientData] = await Promise.all([
|
||||
getUserProfile(),
|
||||
PatientApi.getPatient(patient.id)
|
||||
])
|
||||
|
||||
user.value = userProfile
|
||||
reportData.value = patientData
|
||||
|
||||
// 缓存数据
|
||||
patientDataCache.value.set(cacheKey, {
|
||||
reportData: { ...reportData.value }
|
||||
})
|
||||
|
||||
} finally {
|
||||
loading.close()
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('获取患者详细信息出错:', error)
|
||||
ElMessage.error('获取患者详细信息失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 监听患者变化
|
||||
watch(() => props.patient, (newPatient) => {
|
||||
if (newPatient) {
|
||||
loadPatientData(newPatient)
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
// 修改组件挂载时的逻辑
|
||||
onMounted(async () => {
|
||||
if (props.patient) {
|
||||
await loadPatientData(props.patient)
|
||||
// 加载默认tab的影像数据
|
||||
imageUrls.value = await getImageUrlsByType(currentTab.value)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ct-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
background: #fff;
|
||||
height: 100%;
|
||||
padding: 20px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.basic-info {
|
||||
flex-shrink: 0; /* 防止基本信息被压缩 */
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
padding: 15px; /* 减小内边距 */
|
||||
background: #F8F9FA;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 15px; /* 减小底部间距 */
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.photo-box {
|
||||
width: 120px;
|
||||
height: 160px;
|
||||
background: #fff;
|
||||
border: 1px dashed #dcdfe6;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.no-photo {
|
||||
color: #909399;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.photo {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.info-grid {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.info-row:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.info-item label {
|
||||
color: #606266;
|
||||
margin-right: 8px;
|
||||
white-space: nowrap;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.info-item span {
|
||||
color: #333;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.exam-results {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0; /* 关键:允许内容收缩 */
|
||||
overflow: hidden; /* 防止溢出 */
|
||||
}
|
||||
|
||||
.exam-tabs {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
margin-bottom: 15px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
background: #fff;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.tab-item {
|
||||
position: relative;
|
||||
padding: 8px 16px;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
border: 1px solid #dcdfe6;
|
||||
transition: all 0.3s;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.tab-indicator {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.tab-item.active {
|
||||
background: #f5f7fa;
|
||||
border-color: #409EFF;
|
||||
font-weight: 500;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.tab-item:hover:not(.active) {
|
||||
border-color: #c0c4cc;
|
||||
background: #f9f9f9;
|
||||
}
|
||||
|
||||
.image-results {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0; /* 关键:允许内容收缩 */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.image-gallery {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 20px;
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.gallery-title {
|
||||
padding: 12px 15px;
|
||||
font-weight: 500;
|
||||
background: #f5f7fa;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.image-container {
|
||||
flex: 1;
|
||||
padding: 15px;
|
||||
min-height: 0; /* 允许容器收缩 */
|
||||
overflow: auto; /* 如果内容过多,只在图片区域显示滚动条 */
|
||||
}
|
||||
|
||||
.image-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.image-item {
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
transition: transform 0.3s;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
|
||||
aspect-ratio: 4/3;
|
||||
}
|
||||
|
||||
.medical-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.no-images {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 300px;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.findings-diagnosis-container {
|
||||
flex-shrink: 0; /* 防止诊断区域被压缩 */
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.findings-section,
|
||||
.diagnosis-section {
|
||||
flex: 1;
|
||||
padding: 15px;
|
||||
background: #f8f9fa;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
margin-bottom: 15px;
|
||||
padding-left: 10px;
|
||||
border-left: 4px solid #409eff;
|
||||
}
|
||||
|
||||
.findings-textarea,
|
||||
.diagnosis-textarea {
|
||||
height: 100px; /* 减小文本框高度 */
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
resize: none;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
background: #fff;
|
||||
transition: border-color 0.3s;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.findings-textarea:focus,
|
||||
.diagnosis-textarea:focus {
|
||||
outline: none;
|
||||
border-color: #409EFF;
|
||||
box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
|
||||
}
|
||||
|
||||
.findings-textarea[readonly],
|
||||
.diagnosis-textarea[readonly] {
|
||||
background-color: #f5f7fa;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.action-footer {
|
||||
flex-shrink: 0; /* 防止底部操作栏被压缩 */
|
||||
margin-top: 15px;
|
||||
background: #fff;
|
||||
border-top: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
.footer-content {
|
||||
padding: 15px 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.doctor-info {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
padding: 8px 20px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
background: #f0f2f5;
|
||||
color: #606266;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: all 0.3s;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.action-btn:hover {
|
||||
background: #e6e8eb;
|
||||
}
|
||||
|
||||
.action-btn.primary {
|
||||
background: #409EFF;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.action-btn.primary:hover {
|
||||
background: #66b1ff;
|
||||
}
|
||||
|
||||
/* 添加图片错误状态的样式 */
|
||||
.image-error {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
background: #f8f9fa;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.error-text {
|
||||
margin-top: 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* 自定义 el-image 预览样式 */
|
||||
:deep(.el-image-viewer__wrapper) {
|
||||
.el-image-viewer__btn {
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
&:hover {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -53,7 +53,18 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右侧检查结果 -->
|
||||
<div class="report-content" v-if="selectedPatient">
|
||||
<template v-if="selectedPatient">
|
||||
|
||||
<!-- 根据科室类型动态显示不同组件 -->
|
||||
<CT v-if="isImageDepartment" :patient="selectedPatient" />
|
||||
<blood-test
|
||||
v-else-if="isBloodTest"
|
||||
:patient="selectedPatient"
|
||||
:user="user"
|
||||
/>
|
||||
|
||||
<!-- 常规检查结果界面 -->
|
||||
<div class="report-content" v-else>
|
||||
<!-- 基本信息 -->
|
||||
<div class="basic-info">
|
||||
<div class="photo-box">
|
||||
@ -238,6 +249,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 添加未选择患者时的提示 -->
|
||||
<div class="empty-content" v-else>
|
||||
@ -281,7 +293,9 @@ import { PatientApi } from '@/api/inspect/inspectpatient'
|
||||
import { PatientitemsApi } from '@/api/inspect/inspectpatientitems'
|
||||
import { getUserProfile } from '@/api/system/user/profile'
|
||||
import ExamImages from './Exam_images.vue'
|
||||
import CT from './CT.vue' // 导入CT组件
|
||||
import { ArrowDown } from '@element-plus/icons-vue'
|
||||
import BloodTest from './blood.vue' // 导入血常规组件
|
||||
|
||||
const dialogTitle = ref('体检报告')
|
||||
const { t } = useI18n() // 国际化
|
||||
@ -456,7 +470,6 @@ const getpatientitemData = async (medicalSn) => {
|
||||
try {
|
||||
const userProfile = await getUserProfile()
|
||||
user.value = userProfile
|
||||
console.log('当前登录用户信息:', userProfile)
|
||||
} catch (userError) {
|
||||
console.error('获取用户信息失败:', userError)
|
||||
}
|
||||
@ -500,16 +513,20 @@ const loadPatientData = async (patient) => {
|
||||
])
|
||||
|
||||
user.value = userProfile
|
||||
const userDeptId = userProfile // 获取用户部门ID
|
||||
|
||||
// 检查用户是否属于影像科或血常规科室
|
||||
isImageDepartment.value = checkIsImageDepartment(userProfile.deptId)
|
||||
|
||||
reportData.value = patientData
|
||||
|
||||
// 如果不是特殊科室,继续加载常规检查数据
|
||||
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)
|
||||
console.log('当前登录用户信息:',filteredItems )
|
||||
filteredItems.forEach(item => {
|
||||
const sectionType = '一般检查'
|
||||
if (!itemsBySection[sectionType]) {
|
||||
@ -544,6 +561,7 @@ const loadPatientData = async (patient) => {
|
||||
currentTab.value = examTabs.value[0].id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
patientDataCache.value.set(cacheKey, {
|
||||
reportData: { ...reportData.value },
|
||||
@ -562,6 +580,23 @@ const loadPatientData = async (patient) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 修改检查是否为影像科的函数
|
||||
const checkIsImageDepartment = (deptId) => {
|
||||
|
||||
// 强制返回true用于测试
|
||||
// return true;
|
||||
|
||||
// 如果deptId是对象,尝试获取其id属性
|
||||
const id = typeof deptId === 'object' ? deptId.id || deptId.deptId : deptId
|
||||
|
||||
// 影像科的ID列表 - 根据实际情况调整
|
||||
const imageDeptIds = ['7', '8', '9', '10', '11', '12', '13', 'CT室', 'DR室', '超声科', '放射科', '影像科', 'CT', 'MRI', '超声', '放射']
|
||||
|
||||
// 检查ID是否在列表中
|
||||
const result = imageDeptIds.includes(String(id))
|
||||
return result
|
||||
}
|
||||
|
||||
// 修改获取状态提示的函数
|
||||
const getStatusNote = (item) => {
|
||||
if (!item.reference || item.reference === 'null-null') {
|
||||
@ -673,10 +708,12 @@ const handlePatientSelect = async (patient) => {
|
||||
} catch (error) {
|
||||
console.error('切换患者失败:', error)
|
||||
message.error('切换患者失败')
|
||||
// 出错时重置状态
|
||||
isImageDepartment.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
onMounted(async () => {
|
||||
// 清理页面状态
|
||||
patients.value = []
|
||||
selectedPatient.value = null
|
||||
@ -720,6 +757,16 @@ onMounted(() => {
|
||||
inspecttime: ''
|
||||
}
|
||||
customDateRange.value = []
|
||||
|
||||
// 初始化科室类型
|
||||
try {
|
||||
const userProfile = await getUserProfile()
|
||||
user.value = userProfile
|
||||
isImageDepartment.value = checkIsImageDepartment(userProfile.deptId)
|
||||
} catch (error) {
|
||||
console.error('获取用户信息失败:', error)
|
||||
isImageDepartment.value = false
|
||||
}
|
||||
})
|
||||
|
||||
// 当前选中的时间周期
|
||||
@ -928,7 +975,6 @@ const user = ref(null)
|
||||
// 加载数据
|
||||
const loadData = async () => {
|
||||
reportData.value = await PatientApi.getPatient(1)
|
||||
console.log(reportData.value.birthday)
|
||||
}
|
||||
|
||||
// 添加搜索处理函数
|
||||
@ -1190,6 +1236,30 @@ const formatReference = (reference) => {
|
||||
return `${low}-${high}`
|
||||
}
|
||||
|
||||
// 添加isImageDepartment的响应式引用
|
||||
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('血细胞') ||
|
||||
itemName.includes('血红蛋白') ||
|
||||
itemName.includes('白细胞') ||
|
||||
itemName.includes('红细胞') ||
|
||||
itemName.includes('血小板')
|
||||
})
|
||||
|
||||
return currentItems.length > 0
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@ -1866,7 +1936,6 @@ const formatReference = (reference) => {
|
||||
background-color: #f5f7fa;
|
||||
cursor: not-allowed;
|
||||
color: #606266;
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* 修改弃检行的样式判断 */
|
||||
|
284
src/views/Department-entry/blood.vue
Normal file
284
src/views/Department-entry/blood.vue
Normal file
@ -0,0 +1,284 @@
|
||||
<template>
|
||||
<div class="blood-test-container">
|
||||
<!-- 检查结果表格 -->
|
||||
<div class="result-table">
|
||||
<!-- 表头部分 -->
|
||||
<div class="table-header">
|
||||
<div class="header-row">
|
||||
<div class="header-cell" style="width: 5%">#</div>
|
||||
<div class="header-cell" style="width: 15%">体检项目</div>
|
||||
<div class="header-cell" style="width: 20%">明细结果</div>
|
||||
<div class="header-cell" style="width: 10%">单位</div>
|
||||
<div class="header-cell" style="width: 15%">参考值</div>
|
||||
<div class="header-cell" style="width: 10%">提示</div>
|
||||
<div class="header-cell" style="width: 15%">危险程度</div>
|
||||
<div class="header-cell" style="width: 10%">是否阳性</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 表格内容部分 -->
|
||||
<div class="table-body">
|
||||
<div
|
||||
v-for="(item, index) in bloodTestItems"
|
||||
:key="item.id"
|
||||
class="table-row"
|
||||
:class="{
|
||||
'warning-row': item.status === 'warning',
|
||||
'danger-row': item.status === 'danger'
|
||||
}"
|
||||
>
|
||||
<div class="table-cell" style="width: 5%">{{ index + 1 }}</div>
|
||||
<div class="table-cell" style="width: 15%">{{ item.name }}</div>
|
||||
<div class="table-cell" style="width: 20%">{{ item.value }}</div>
|
||||
<div class="table-cell" style="width: 10%">{{ item.unit }}</div>
|
||||
<div class="table-cell" style="width: 15%">{{ formatReference(item.reference) }}</div>
|
||||
<div class="table-cell" style="width: 10%">{{ item.note }}</div>
|
||||
<div class="table-cell" style="width: 15%">{{ item.risk }}</div>
|
||||
<div class="table-cell" style="width: 10%">
|
||||
<el-tag
|
||||
v-if="item.positive === '阳性'"
|
||||
type="danger"
|
||||
size="small"
|
||||
effect="light"
|
||||
>
|
||||
阳性
|
||||
</el-tag>
|
||||
<span v-else>阴性</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<div class="action-footer">
|
||||
<div class="left-section">
|
||||
<span>检查医生:{{ user?.nickname || '暂无' }}</span>
|
||||
<span style="margin-left: 100px;">检查日期:{{ formattedMedicalDateTime }}</span>
|
||||
</div>
|
||||
<div class="right-section">
|
||||
<div class="action-buttons">
|
||||
<button class="action-btn" @click="handleSyncResults">同步结果</button>
|
||||
<button class="action-btn">报告预览</button>
|
||||
<button
|
||||
class="action-btn primary"
|
||||
@click="handleSaveResults"
|
||||
>
|
||||
保存结果
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, computed } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { PatientitemsApi } from '@/api/inspect/inspectpatientitems'
|
||||
|
||||
export default {
|
||||
name: 'BloodTest',
|
||||
props: {
|
||||
patient: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
user: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
const bloodTestItems = ref([])
|
||||
const formattedMedicalDateTime = computed(() => {
|
||||
return new Date().toLocaleDateString('zh-CN')
|
||||
})
|
||||
|
||||
// 格式化参考值显示
|
||||
const formatReference = (reference) => {
|
||||
if (!reference || reference === 'null-null') return '-'
|
||||
const [low, high] = reference.split('-')
|
||||
if (!low || !high || low === 'null' || high === 'null') return '-'
|
||||
return `${low}-${high}`
|
||||
}
|
||||
|
||||
// 同步结果处理函数
|
||||
const handleSyncResults = async () => {
|
||||
try {
|
||||
const params = {
|
||||
medicalSn: props.patient.medicalSn,
|
||||
pageNo: 1,
|
||||
pageSize: 100
|
||||
}
|
||||
const res = await PatientitemsApi.getPatientitemsPage(params)
|
||||
if (res.list && res.list.length > 0) {
|
||||
bloodTestItems.value = res.list.map(item => ({
|
||||
id: item.id,
|
||||
name: item.itemName,
|
||||
value: item.itemResult,
|
||||
unit: item.unit,
|
||||
reference: `${item.lowValue}-${item.highValue}`,
|
||||
note: getStatusNote(item),
|
||||
risk: getRiskLevel(item),
|
||||
status: getRowStatus(item),
|
||||
positive: item.positive === '1' ? '阳性' : '阴性'
|
||||
}))
|
||||
ElMessage.success('同步结果成功')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('同步结果失败:', error)
|
||||
ElMessage.error('同步结果失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 保存结果处理函数
|
||||
const handleSaveResults = async () => {
|
||||
try {
|
||||
const updatedItems = bloodTestItems.value.map(item => ({
|
||||
id: item.id,
|
||||
itemResult: item.value,
|
||||
positive: item.positive === '阳性' ? '1' : '0',
|
||||
inspectdoctor: props.user?.nickname || '',
|
||||
inspecttime: new Date().getTime()
|
||||
}))
|
||||
|
||||
await PatientitemsApi.updatePatientitemsBatch(updatedItems)
|
||||
ElMessage.success('保存成功')
|
||||
} catch (error) {
|
||||
console.error('保存失败:', error)
|
||||
ElMessage.error('保存失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 辅助函数
|
||||
const getStatusNote = (item) => {
|
||||
if (!item.itemResult || !item.lowValue || !item.highValue) return ''
|
||||
const value = parseFloat(item.itemResult)
|
||||
const low = parseFloat(item.lowValue)
|
||||
const high = parseFloat(item.highValue)
|
||||
|
||||
if (value < low) return '↓'
|
||||
if (value > high) return '↑'
|
||||
return '-'
|
||||
}
|
||||
|
||||
const getRiskLevel = (item) => {
|
||||
if (!item.itemResult || !item.lowValue || !item.highValue) return ''
|
||||
const value = parseFloat(item.itemResult)
|
||||
const low = parseFloat(item.lowValue)
|
||||
const high = parseFloat(item.highValue)
|
||||
|
||||
if (value < low) return '低于正常值'
|
||||
if (value > high) return '高于正常值'
|
||||
return '正常'
|
||||
}
|
||||
|
||||
const getRowStatus = (item) => {
|
||||
if (!item.itemResult || !item.lowValue || !item.highValue) return ''
|
||||
const value = parseFloat(item.itemResult)
|
||||
const high = parseFloat(item.highValue)
|
||||
|
||||
if (value > high) return 'danger'
|
||||
return ''
|
||||
}
|
||||
|
||||
return {
|
||||
bloodTestItems,
|
||||
formattedMedicalDateTime,
|
||||
formatReference,
|
||||
handleSyncResults,
|
||||
handleSaveResults
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.blood-test-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
background: #fff;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.result-table {
|
||||
margin: 20px;
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.table-header {
|
||||
background: #f5f7fa;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
.header-row {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.header-cell {
|
||||
padding: 12px 8px;
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
text-align: left;
|
||||
border-right: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
.table-body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
display: flex;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
.table-row.danger-row {
|
||||
background: #fef0f0;
|
||||
}
|
||||
|
||||
.table-cell {
|
||||
padding: 12px 8px;
|
||||
border-right: 1px solid #ebeef5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.action-footer {
|
||||
padding: 16px 20px;
|
||||
border-top: 1px solid #ebeef5;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
padding: 8px 16px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
background: #409EFF;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.action-btn:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.action-btn.primary {
|
||||
background: #67C23A;
|
||||
}
|
||||
</style>
|
@ -1005,7 +1005,26 @@ const handlePersonInfoSave = async () => {
|
||||
if (result) {
|
||||
// 保存患者项目
|
||||
if (comboInfoTable1.value.length > 0) {
|
||||
const saveItems: PatientitemsVO[] = comboInfoTable1.value.map(item => ({
|
||||
// 先获取患者现有的项目列表
|
||||
const existingItems = await PatientitemsApi.getPatientitemsPage({
|
||||
medicalSn: personParam.value.testNum,
|
||||
pageNo: 1,
|
||||
pageSize: 100
|
||||
})
|
||||
|
||||
// 创建现有项目的itemCode集合,用于快速查找
|
||||
const existingItemCodes = new Set(
|
||||
existingItems?.list?.map(item => item.itemCode) || []
|
||||
)
|
||||
|
||||
// 过滤出需要新增的项目(不在现有项目中的)
|
||||
const newItems = comboInfoTable1.value.filter(
|
||||
item => !existingItemCodes.has(item.itemCode)
|
||||
)
|
||||
|
||||
if (newItems.length > 0) {
|
||||
// 直接使用项目中已有的字段值,不使用默认值
|
||||
const saveItems: PatientitemsVO[] = newItems.map(item => ({
|
||||
medicalSn: personParam.value.testNum,
|
||||
itemName: item.name,
|
||||
itemCode: item.itemCode,
|
||||
@ -1014,12 +1033,16 @@ const handlePersonInfoSave = async () => {
|
||||
discounted: item.discount,
|
||||
sectionID: item.sectionID,
|
||||
itemStatus: '0',
|
||||
createTime: new Date().getTime(), // 修改为时间戳
|
||||
headimage: avatar
|
||||
createTime: new Date().getTime(),
|
||||
headimage: avatar,
|
||||
groupname: item.groupname,
|
||||
groupcode: item.groupcode,
|
||||
mealfrontorafter: item.mealfrontorafter
|
||||
}))
|
||||
|
||||
await PatientitemsApi.createPatientitemsBatch(saveItems)
|
||||
}
|
||||
}
|
||||
|
||||
message.success('保存成功')
|
||||
personInfoCustomAdd.value = false
|
||||
@ -1170,7 +1193,36 @@ watch(() => searchForm_extra.value.passStatus, () => {
|
||||
const selectedPatient = ref(null)
|
||||
const selectedPatientId = ref(null)
|
||||
|
||||
// 修改加载患者项目的方法,减少不必要的API请求
|
||||
// 添加科室缓存,避免重复请求
|
||||
const departmentCache = ref(new Map())
|
||||
|
||||
// 添加获取科室名称的方法
|
||||
const getSectionName = async (sectionID) => {
|
||||
if (!sectionID) return '暂无科室'
|
||||
|
||||
// 如果缓存中已有该科室,直接返回
|
||||
if (departmentCache.value.has(sectionID)) {
|
||||
return departmentCache.value.get(sectionID)
|
||||
}
|
||||
|
||||
try {
|
||||
// 获取所有科室
|
||||
const departments = await DepartmentApi.getListDepartment()
|
||||
|
||||
// 将所有科室信息缓存
|
||||
departments.forEach(dept => {
|
||||
departmentCache.value.set(dept.departmentCode, dept.departmentName)
|
||||
})
|
||||
|
||||
// 返回对应的科室名称
|
||||
return departmentCache.value.get(sectionID) || '暂无科室'
|
||||
} catch (error) {
|
||||
console.error('获取科室信息失败:', error)
|
||||
return '暂无科室'
|
||||
}
|
||||
}
|
||||
|
||||
// 修改加载患者项目的方法,移除调试日志
|
||||
const loadPatientProjects = async (medicalSn) => {
|
||||
if (!medicalSn) {
|
||||
comboInfoTable1.value = []
|
||||
@ -1191,16 +1243,26 @@ const loadPatientProjects = async (medicalSn) => {
|
||||
}
|
||||
|
||||
// 直接从API返回的数据构建项目列表,不再查询项目详情
|
||||
const projectDetails: ProjectDetail[] = patientItemsRes.list.map(item => ({
|
||||
const projectDetails: ProjectDetail[] = []
|
||||
|
||||
for (const item of patientItemsRes.list) {
|
||||
// 获取科室名称
|
||||
const sectionName = await getSectionName(item.sectionID)
|
||||
|
||||
projectDetails.push({
|
||||
name: item.itemName,
|
||||
price: item.price || 0,
|
||||
discount: item.discounted || 0,
|
||||
discountPrice: item.discountedPrice || 0,
|
||||
moduleName: item.moduleName || '',
|
||||
section: item.section || '',
|
||||
section: sectionName,
|
||||
sectionID: item.sectionID || '',
|
||||
itemCode: item.itemCode
|
||||
}))
|
||||
itemCode: item.itemCode,
|
||||
groupname: item.groupname || '', // 添加模块名称
|
||||
groupcode: item.groupcode || '', // 添加模块ID
|
||||
mealfrontorafter: item.mealfrontorafter || '' // 添加餐前餐后
|
||||
})
|
||||
}
|
||||
|
||||
// 强制更新视图
|
||||
comboInfoTable1.value = []
|
||||
@ -1391,7 +1453,7 @@ const handleCheckInfoSelection = (selection) => {
|
||||
checkInfoSelectedData.value = selection
|
||||
}
|
||||
|
||||
// 修改确认选择项目的方法
|
||||
// 修改确认选择项目的方法,移除调试日志
|
||||
const confirmSelectedProjects = async () => {
|
||||
try {
|
||||
let selectedProjects: ProjectDetail[] = []
|
||||
@ -1424,16 +1486,23 @@ const confirmSelectedProjects = async () => {
|
||||
|
||||
if (itemDetail?.list?.[0]) {
|
||||
const item = itemDetail.list[0]
|
||||
|
||||
// 获取科室名称
|
||||
const sectionName = await getSectionName(item.sectionID)
|
||||
|
||||
processedItemCodes.add(moduleItem.itemCode)
|
||||
selectedProjects.push({
|
||||
name: item.itemName,
|
||||
section: item.section, // 使用科室名称
|
||||
sectionID: item.sectionID, // 保存科室ID用于后端
|
||||
section: sectionName,
|
||||
sectionID: item.sectionID,
|
||||
price: item.price || 0,
|
||||
discount: item.discounted || 0,
|
||||
discountPrice: item.discountedPrice || 0,
|
||||
moduleName: item.moduleName || moduleItem.examModuleName,
|
||||
itemCode: moduleItem.itemCode
|
||||
itemCode: moduleItem.itemCode,
|
||||
groupname: item.groupname || '',
|
||||
groupcode: item.groupcode || '',
|
||||
mealfrontorafter: item.mealfrontorafter || ''
|
||||
})
|
||||
}
|
||||
} catch (itemError) {
|
||||
@ -1450,16 +1519,22 @@ const confirmSelectedProjects = async () => {
|
||||
continue
|
||||
}
|
||||
|
||||
// 获取科室名称
|
||||
const sectionName = await getSectionName(item.sectionID)
|
||||
|
||||
processedItemCodes.add(item.itemCode)
|
||||
selectedProjects.push({
|
||||
name: item.itemName,
|
||||
section: item.section, // 使用科室名称
|
||||
sectionID: item.sectionID, // 保存科室ID用于后端
|
||||
section: sectionName,
|
||||
sectionID: item.sectionID,
|
||||
price: item.price,
|
||||
discount: item.discounted,
|
||||
discountPrice: item.discountedPrice,
|
||||
moduleName: item.moduleName,
|
||||
itemCode: item.itemCode
|
||||
itemCode: item.itemCode,
|
||||
groupname: item.groupname || '',
|
||||
groupcode: item.groupcode || '',
|
||||
mealfrontorafter: item.mealfrontorafter || ''
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1509,6 +1584,9 @@ interface ProjectDetail {
|
||||
discountPrice: number
|
||||
moduleName: string
|
||||
itemCode: string
|
||||
groupname?: string // 添加模块名称
|
||||
groupcode?: string // 添加模块ID
|
||||
mealfrontorafter?: string // 添加餐前餐后
|
||||
}
|
||||
|
||||
// 添加删除选中项目的方法
|
||||
|
Loading…
Reference in New Issue
Block a user