体检车录入
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 = {
|
||||
callback: () => {
|
||||
console.log("浏览器打印窗口已打开");
|
||||
console.log(templateRef.value)
|
||||
},
|
||||
styleHandler: () => {
|
||||
// 重写 文本 打印样式
|
||||
|
Loading…
Reference in New Issue
Block a user