体检车录入
This commit is contained in:
parent
0f1a02a2d8
commit
c5ba087051
550
src/views/Department-entry/All.vue
Normal file
550
src/views/Department-entry/All.vue
Normal file
@ -0,0 +1,550 @@
|
|||||||
|
<template>
|
||||||
|
<div class="all-container">
|
||||||
|
<!-- 检查结果部分 -->
|
||||||
|
<div class="exam-results">
|
||||||
|
<!-- 影像检查结果 -->
|
||||||
|
<div class="image-results">
|
||||||
|
<!-- 影像图片展示区 -->
|
||||||
|
<div class="image-gallery">
|
||||||
|
<div class="image-content">
|
||||||
|
<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"
|
||||||
|
: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>
|
||||||
|
<span>加载失败</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-image>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-empty v-else description="暂无影像资料" />
|
||||||
|
</div>
|
||||||
|
</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
|
||||||
|
},
|
||||||
|
examType: {
|
||||||
|
type: String,
|
||||||
|
default: '' // 默认为空
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 添加响应式引用
|
||||||
|
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 currentItem = ref(null)
|
||||||
|
|
||||||
|
// 修改获取影像图片URL的方法,根据检查类型过滤
|
||||||
|
const getImageUrls = async () => {
|
||||||
|
try {
|
||||||
|
|
||||||
|
|
||||||
|
// 检查必要参数
|
||||||
|
if (!reportData.value.medicalSn) {
|
||||||
|
console.warn('缺少体检编号(medicalSn)')
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取所有PACS数据
|
||||||
|
const response = await PacsDataApi.getPacsDataPage({
|
||||||
|
code: reportData.value.medicalSn,
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 100
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!response?.list) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
pacsData.value = response.list
|
||||||
|
|
||||||
|
// 根据检查类型过滤图片
|
||||||
|
let filteredData = response.list
|
||||||
|
|
||||||
|
// 根据检查类型匹配type字段
|
||||||
|
if (props.examType) {
|
||||||
|
// 检查类型与API中type字段的映射关系 - 扩展匹配模式
|
||||||
|
const typePatterns = {
|
||||||
|
'ultrasound': ['ultrasound', 'us', '超声', '彩超', 'b超', 'doppler'],
|
||||||
|
'ecg': ['ecg', 'ekg', '心电图', 'electrocardiogram'],
|
||||||
|
'blood': ['blood', 'cbc', '血常规', '血液', 'bloodtest'],
|
||||||
|
'urine': ['urine', 'ua', '尿常规', '尿液', 'urinalysis']
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前检查类型对应的匹配模式
|
||||||
|
const patterns = typePatterns[props.examType]
|
||||||
|
|
||||||
|
if (patterns && patterns.length > 0) {
|
||||||
|
// 使用模式列表进行匹配
|
||||||
|
filteredData = response.list.filter(item => {
|
||||||
|
if (!item.type) return false
|
||||||
|
|
||||||
|
const itemType = item.type.toLowerCase()
|
||||||
|
return patterns.some(pattern => itemType.includes(pattern.toLowerCase()))
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改:如果过滤后没有数据,直接返回空数组,显示"暂无影像资料"
|
||||||
|
if (filteredData.length === 0) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 直接使用data字段作为图片URL,过滤掉空值
|
||||||
|
const urls = filteredData.map((item) => item.data).filter((url) => url)
|
||||||
|
|
||||||
|
return urls
|
||||||
|
} catch (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(() => {
|
||||||
|
// 项目状态为0表示未检查,应该可以编辑
|
||||||
|
// 项目状态为1表示已检查,应该只读
|
||||||
|
return currentItem.value?.itemStatus === '1'
|
||||||
|
})
|
||||||
|
|
||||||
|
// 检查编辑权限的方法
|
||||||
|
const checkEditPermission = () => {
|
||||||
|
if (isReadOnly.value) {
|
||||||
|
ElMessage.warning('检查结果已保存,不可进行编辑')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存结果方法
|
||||||
|
const handleSaveResults = async () => {
|
||||||
|
try {
|
||||||
|
if (!checkEditPermission()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const userProfile = await getUserProfile()
|
||||||
|
user.value = userProfile
|
||||||
|
// 获取当前时间戳
|
||||||
|
const currentTime = new Date().getTime()
|
||||||
|
// 检查当前项目
|
||||||
|
if (!currentItem.value || !currentItem.value.id) {
|
||||||
|
ElMessage.error('未找到当前检查项目信息')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新检查项目结果
|
||||||
|
const updatedItems = [
|
||||||
|
{
|
||||||
|
id: currentItem.value.id, // 使用检查项目ID
|
||||||
|
examDescription: imageFinding.value, // 检查所见
|
||||||
|
itemResult: imageDiagnosis.value, // 检查结果
|
||||||
|
itemStatus: '1', // 已检查
|
||||||
|
inspectdoctor: user.value?.nickname || '',
|
||||||
|
inspecttime: currentTime
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
const updateResult = await PatientitemsApi.updatePatientitemsBatch(updatedItems)
|
||||||
|
|
||||||
|
// 更新当前项目状态
|
||||||
|
currentItem.value.itemStatus = '1'
|
||||||
|
currentItem.value.examDescription = imageFinding.value
|
||||||
|
currentItem.value.itemResult = imageDiagnosis.value
|
||||||
|
|
||||||
|
ElMessage.success('保存成功')
|
||||||
|
} catch (error) {
|
||||||
|
console.error('保存失败:', error)
|
||||||
|
console.error('错误详情:', error.response || error)
|
||||||
|
ElMessage.error(`保存失败: ${error.message || '未知错误'}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载患者数据和检查项目
|
||||||
|
const loadPatientData = async (patient) => {
|
||||||
|
if (!patient || !patient.id) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const cacheKey = patient.id
|
||||||
|
if (patientDataCache.value.has(cacheKey)) {
|
||||||
|
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
|
||||||
|
|
||||||
|
// 获取患者检查项目数据
|
||||||
|
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) {
|
||||||
|
// 选择第一个检查项目作为当前项目
|
||||||
|
currentItem.value = patientItemsResponse.list[0]
|
||||||
|
|
||||||
|
console.log('找到的当前检查项目:', currentItem.value)
|
||||||
|
|
||||||
|
// 如果找到了检查项目,加载其检查所见和结果
|
||||||
|
if (currentItem.value) {
|
||||||
|
imageFinding.value = currentItem.value.examDescription || ''
|
||||||
|
imageDiagnosis.value = currentItem.value.itemResult || ''
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载所有影像数据,不再按类型过滤
|
||||||
|
imageUrls.value = await getImageUrls()
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取患者检查项目失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 缓存数据
|
||||||
|
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 }
|
||||||
|
)
|
||||||
|
|
||||||
|
// 监听检查类型变化
|
||||||
|
watch(
|
||||||
|
() => props.examType,
|
||||||
|
async (newType) => {
|
||||||
|
if (newType && reportData.value.medicalSn) {
|
||||||
|
console.log('检查类型变更为:', newType)
|
||||||
|
imageUrls.value = await getImageUrls()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
// 修改组件挂载时的逻辑
|
||||||
|
onMounted(async () => {
|
||||||
|
if (props.patient) {
|
||||||
|
// 加载患者数据和检查项目
|
||||||
|
await loadPatientData(props.patient)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 添加获取检查类型标题的方法
|
||||||
|
const getExamTypeTitle = () => {
|
||||||
|
const typeMap = {
|
||||||
|
ultrasound: '超声',
|
||||||
|
ecg: '心电图',
|
||||||
|
blood: '血常规',
|
||||||
|
urine: '尿常规'
|
||||||
|
}
|
||||||
|
return typeMap[props.examType] || '检查'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.all-container {
|
||||||
|
height: 520px;
|
||||||
|
padding: 10px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.exam-results {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-results {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-gallery {
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-content {
|
||||||
|
height: 100%;
|
||||||
|
padding: 8px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
|
||||||
|
gap: 10px;
|
||||||
|
height: 100%;
|
||||||
|
place-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-item {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
max-width: 600px;
|
||||||
|
max-height: 450px;
|
||||||
|
aspect-ratio: 4/3;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: transform 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-item:hover {
|
||||||
|
transform: scale(1.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
.single-image {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.single-image .image-item {
|
||||||
|
width: 90%;
|
||||||
|
height: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.medical-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-images {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
|
||||||
|
.findings-diagnosis-container {
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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: 120px;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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 {
|
||||||
|
background: #fff;
|
||||||
|
border-top: 1px solid #ebeef5;
|
||||||
|
margin-top: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-content {
|
||||||
|
padding: 15px 0;
|
||||||
|
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 {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 8px;
|
||||||
|
background: #f8f9fa;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
</style>
|
2447
src/views/Department-entry/Medical-examination-vehicle.vue
Normal file
2447
src/views/Department-entry/Medical-examination-vehicle.vue
Normal file
File diff suppressed because it is too large
Load Diff
@ -1133,6 +1133,7 @@ const handlePersonInfoPrintInspection = async () => {
|
|||||||
let ext = {
|
let ext = {
|
||||||
callback: () => {
|
callback: () => {
|
||||||
console.log("浏览器打印窗口已打开");
|
console.log("浏览器打印窗口已打开");
|
||||||
|
console.log(templateRef.value)
|
||||||
},
|
},
|
||||||
styleHandler: () => {
|
styleHandler: () => {
|
||||||
// 重写 文本 打印样式
|
// 重写 文本 打印样式
|
||||||
|
Loading…
Reference in New Issue
Block a user