Merge branch 'master' of http://114.55.171.231:3000/Euni4U/shanghai_vue3
This commit is contained in:
commit
7553f16226
61
src/api/arterialdata/index.ts
Normal file
61
src/api/arterialdata/index.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
// 动脉硬化检测数据 VO
|
||||
export interface arterialdataVO {
|
||||
id: number // 主键ID
|
||||
regid: string // 注册ID
|
||||
examid: string // 检查ID
|
||||
weartime: Date // 佩戴时间
|
||||
measuretime: Date // 测量时间
|
||||
deviceid: string // 设备ID
|
||||
devicename: string // 设备名称
|
||||
data: string // 检测数据
|
||||
createtime: Date // 创建时间
|
||||
updatetime: Date // 更新时间
|
||||
diagnosis: string // 诊断结论
|
||||
}
|
||||
|
||||
// 动脉硬化检测数据 API
|
||||
export const arterialdataApi = {
|
||||
// 查询动脉硬化检测数据分页
|
||||
getarterialdataPage: async (params: any) => {
|
||||
return await request.get({ url: `/system/arterialdata/page`, params })
|
||||
},
|
||||
|
||||
// 查询动脉硬化检测数据详情
|
||||
getarterialdata: async (id: number) => {
|
||||
return await request.get({ url: `/system/arterialdata/get?id=` + id })
|
||||
},
|
||||
|
||||
// 新增动脉硬化检测数据
|
||||
createarterialdata: async (data: arterialdataVO) => {
|
||||
return await request.post({ url: `/system/arterialdata/create`, data })
|
||||
},
|
||||
|
||||
// 修改动脉硬化检测数据
|
||||
updatearterialdata: async (data: arterialdataVO) => {
|
||||
return await request.put({ url: `/system/arterialdata/update`, data })
|
||||
},
|
||||
|
||||
// 删除动脉硬化检测数据
|
||||
deletearterialdata: async (id: number) => {
|
||||
return await request.delete({ url: `/system/arterialdata/delete?id=` + id })
|
||||
},
|
||||
|
||||
// 导出动脉硬化检测数据 Excel
|
||||
exportarterialdata: async (params) => {
|
||||
return await request.download({ url: `/system/arterialdata/export-excel`, params })
|
||||
},
|
||||
|
||||
// 根据检查ID&患者ID获取arterialdata数据
|
||||
getarterialdataByExamidAndRegid: async (examid: string, regid: string) => {
|
||||
return await request.get({
|
||||
url: `/system/arterialdata/getByExamidAndRegid?examid=` + examid + '®id=' + regid
|
||||
})
|
||||
},
|
||||
|
||||
//根据examid®id保存诊断结论
|
||||
savearterialdataDiagnosis: async (data: any) => {
|
||||
return await request.put({ url: `/system/arterialdata/saveDiagnosisByExamidAndRegid`, data })
|
||||
}
|
||||
}
|
||||
@ -1,116 +1,97 @@
|
||||
<template>
|
||||
<Dialog
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="`动脉硬化分析 - ${patientData.name}`"
|
||||
width="90%"
|
||||
:before-close="handleClose"
|
||||
title="动脉硬化分析"
|
||||
:fullscreen="true"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
class="arterial-analysis-dialog"
|
||||
@close="handleClose"
|
||||
>
|
||||
<div class="arteriosclerosis-analysis-container">
|
||||
<!-- 患者信息 -->
|
||||
<div class="patient-info">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<div class="info-item">
|
||||
<span class="label">姓名:</span>
|
||||
<span class="value">{{ patientData.name }}</span>
|
||||
<!-- 主要内容区域 -->
|
||||
<div class="main-content">
|
||||
<!-- 左侧图片展示区域 (3/4) -->
|
||||
<div class="left-panel">
|
||||
<!-- 图片展示区域 -->
|
||||
<div class="image-display-section">
|
||||
<div class="image-container full-height">
|
||||
<!-- 图片展示区域 -->
|
||||
<div v-if="arterialData && arterialData.data" class="image-wrapper">
|
||||
<img
|
||||
:src="arterialData.data"
|
||||
alt="动脉硬化检测图像"
|
||||
class="detection-image"
|
||||
@error="handleImageError"
|
||||
/>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div class="info-item">
|
||||
<span class="label">性别:</span>
|
||||
<span class="value">{{ patientData.gender }}</span>
|
||||
<!-- 占位符 -->
|
||||
<div v-else class="no-image-placeholder">
|
||||
<el-empty description="暂无影像" />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div class="info-item">
|
||||
<span class="label">年龄:</span>
|
||||
<span class="value">{{ patientData.age }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div class="info-item">
|
||||
<span class="label">检测时间:</span>
|
||||
<span class="value">{{ formatDateTime(patientData.measuretime) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 动脉硬化趋势图 -->
|
||||
<div class="chart-section">
|
||||
<h3>动脉硬化指标趋势</h3>
|
||||
<div ref="chartContainer" class="chart-container"></div>
|
||||
</div>
|
||||
<!-- 右侧诊断模板和结论区域 (1/4) -->
|
||||
<div class="right-panel">
|
||||
<!-- 诊断模板选择区域 -->
|
||||
<div class="diagnosis-selector">
|
||||
<h5 class="selector-title">
|
||||
诊断模板
|
||||
<el-input
|
||||
v-model="searchKeyword"
|
||||
placeholder="请输入关键词"
|
||||
clearable
|
||||
style="height: 40px; margin-top: 5px"
|
||||
size="medium"
|
||||
prefix-icon="Search"
|
||||
/>
|
||||
</h5>
|
||||
|
||||
<!-- 数据统计表格 -->
|
||||
<div class="statistics-section">
|
||||
<h3>检测数据统计</h3>
|
||||
<el-table :data="statisticsData" border style="width: 100%">
|
||||
<el-table-column prop="parameter" label="参数" width="200" />
|
||||
<el-table-column prop="value" label="数值" width="150" />
|
||||
<el-table-column prop="unit" label="单位" width="100" />
|
||||
<el-table-column prop="reference" label="参考范围" width="200" />
|
||||
<el-table-column prop="status" label="状态" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="getStatusType(row.status)" size="small">
|
||||
{{ row.status }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="description" label="说明" />
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="diagnosis-list">
|
||||
<div
|
||||
v-for="diag in filteredDiagnoses"
|
||||
:key="diag.code"
|
||||
class="diagnosis-item"
|
||||
@click="insertDiagnosis(diag.name)"
|
||||
>
|
||||
{{ diag.name }}
|
||||
</div>
|
||||
<div v-if="filteredDiagnoses.length == 0" class="no-results"> 暂无匹配的诊断模板 </div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分析结果 -->
|
||||
<div class="analysis-section">
|
||||
<h3>分析结果</h3>
|
||||
<el-form :model="analysisResult" label-width="120px">
|
||||
<el-form-item label="总体评估:">
|
||||
<!-- 诊断结论输入区域 -->
|
||||
<div class="analysis-section">
|
||||
<h3>诊断结论</h3>
|
||||
<el-form :model="analysisResult" label-width="80px" size="medium">
|
||||
<el-input
|
||||
v-model="analysisResult.overallAssessment"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入总体评估结果"
|
||||
:rows="8"
|
||||
resize="none"
|
||||
placeholder="请输入诊断结论"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="风险等级:">
|
||||
<el-select v-model="analysisResult.riskLevel" placeholder="请选择风险等级">
|
||||
<el-option label="低风险" value="low" />
|
||||
<el-option label="中风险" value="medium" />
|
||||
<el-option label="高风险" value="high" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="建议措施:">
|
||||
<el-input
|
||||
v-model="analysisResult.recommendations"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入建议措施"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="医生签名:">
|
||||
<el-input v-model="analysisResult.doctorSignature" placeholder="请输入医生姓名" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<!-- 底部操作按钮 -->
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<div class="bottom-actions">
|
||||
<el-button @click="handleClose">关闭</el-button>
|
||||
<el-button type="primary" @click="handleSave">保存分析结果</el-button>
|
||||
<el-button type="success" @click="handlePreviewReport">报告预览</el-button>
|
||||
<el-button type="primary" @click="handleSave">保存结论</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</Dialog>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, nextTick, watch, onUnmounted } from 'vue'
|
||||
import * as echarts from 'echarts'
|
||||
import { ref, reactive, nextTick, watch, computed } from 'vue'
|
||||
import { formatDate } from '@/utils/formatTime'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { arterialdataApi } from '@/api/arterialdata'
|
||||
|
||||
// 组件属性
|
||||
interface Props {
|
||||
@ -129,52 +110,93 @@ const emit = defineEmits(['update:modelValue', 'saved'])
|
||||
|
||||
// 响应式数据
|
||||
const dialogVisible = ref(false)
|
||||
const chartContainer = ref()
|
||||
let chartInstance: echarts.ECharts | null = null
|
||||
const currentRowData = ref<any>(null) // 存储传入的行数据
|
||||
const searchKeyword = ref('') // 搜索关键词
|
||||
|
||||
// 分析结果
|
||||
// 分析结果 - 只保留诊断结论字段
|
||||
const analysisResult = reactive({
|
||||
overallAssessment: '',
|
||||
riskLevel: '',
|
||||
recommendations: '',
|
||||
doctorSignature: ''
|
||||
overallAssessment: ''
|
||||
})
|
||||
|
||||
// 统计数据
|
||||
const statisticsData = ref([
|
||||
{
|
||||
parameter: 'PWV (脉搏波传导速度)',
|
||||
value: '8.5',
|
||||
unit: 'm/s',
|
||||
reference: '<10.0',
|
||||
status: '正常',
|
||||
description: '反映动脉弹性'
|
||||
},
|
||||
{
|
||||
parameter: 'ABI (踝臂指数)',
|
||||
value: '1.12',
|
||||
unit: '',
|
||||
reference: '0.9-1.3',
|
||||
status: '正常',
|
||||
description: '下肢血管状况'
|
||||
},
|
||||
{
|
||||
parameter: 'IMT (内膜中层厚度)',
|
||||
value: '0.8',
|
||||
unit: 'mm',
|
||||
reference: '<1.0',
|
||||
status: '正常',
|
||||
description: '颈动脉内膜厚度'
|
||||
},
|
||||
{
|
||||
parameter: 'AI (增强指数)',
|
||||
value: '25',
|
||||
unit: '%',
|
||||
reference: '<30',
|
||||
status: '正常',
|
||||
description: '动脉硬化程度'
|
||||
// 动脉硬化检测数据
|
||||
const arterialData = ref<any>(null)
|
||||
|
||||
// 动脉硬化诊断模板数据
|
||||
interface ArterialDiagnosis {
|
||||
name: string
|
||||
code: string
|
||||
category: string
|
||||
}
|
||||
|
||||
const arterialDiagnoses: ArterialDiagnosis[] = [
|
||||
// 正常结果
|
||||
{ name: '动脉硬化程度正常', code: 'ART001', category: 'normal' },
|
||||
{ name: '血管弹性良好', code: 'ART002', category: 'normal' },
|
||||
{ name: '血管壁厚度正常', code: 'ART003', category: 'normal' },
|
||||
{ name: '无明显斑块形成', code: 'ART004', category: 'normal' },
|
||||
{ name: '血流动力学指标正常', code: 'ART005', category: 'normal' },
|
||||
|
||||
// 轻度异常
|
||||
{ name: '轻度动脉硬化', code: 'ART006', category: 'mild' },
|
||||
{ name: '血管壁轻度增厚', code: 'ART007', category: 'mild' },
|
||||
{ name: '少量软斑块', code: 'ART008', category: 'mild' },
|
||||
{ name: '血管弹性轻度下降', code: 'ART009', category: 'mild' },
|
||||
{ name: '内膜中膜厚度轻度增加', code: 'ART010', category: 'mild' },
|
||||
|
||||
// 中度异常
|
||||
{ name: '中度动脉硬化', code: 'ART011', category: 'moderate' },
|
||||
{ name: '血管壁明显增厚', code: 'ART012', category: 'moderate' },
|
||||
{ name: '混合性斑块', code: 'ART013', category: 'moderate' },
|
||||
{ name: '轻度管腔狭窄', code: 'ART014', category: 'moderate' },
|
||||
{ name: '血管弹性明显下降', code: 'ART015', category: 'moderate' },
|
||||
{ name: '内膜中膜厚度明显增加', code: 'ART016', category: 'moderate' },
|
||||
|
||||
// 重度异常
|
||||
{ name: '重度动脉硬化', code: 'ART017', category: 'severe' },
|
||||
{ name: '血管壁严重增厚', code: 'ART018', category: 'severe' },
|
||||
{ name: '大量钙化斑块', code: 'ART019', category: 'severe' },
|
||||
{ name: '中重度管腔狭窄', code: 'ART020', category: 'severe' },
|
||||
{ name: '血管弹性严重下降', code: 'ART021', category: 'severe' },
|
||||
{ name: '多发性斑块', code: 'ART022', category: 'severe' },
|
||||
|
||||
// 钙化相关
|
||||
{ name: '血管钙化', code: 'ART023', category: 'calcification' },
|
||||
{ name: '钙化斑块', code: 'ART024', category: 'calcification' },
|
||||
{ name: '多发性钙化灶', code: 'ART025', category: 'calcification' },
|
||||
{ name: '钙化积分增高', code: 'ART026', category: 'calcification' },
|
||||
{ name: '冠状动脉钙化', code: 'ART027', category: 'calcification' },
|
||||
{ name: '颈动脉钙化', code: 'ART028', category: 'calcification' },
|
||||
|
||||
// 狭窄相关
|
||||
{ name: '血管狭窄', code: 'ART029', category: 'stenosis' },
|
||||
{ name: '轻度狭窄(<50%)', code: 'ART030', category: 'stenosis' },
|
||||
{ name: '中度狭窄(50-70%)', code: 'ART031', category: 'stenosis' },
|
||||
{ name: '重度狭窄(>70%)', code: 'ART032', category: 'stenosis' },
|
||||
{ name: '管腔直径减少', code: 'ART033', category: 'stenosis' },
|
||||
{ name: '血流速度增快', code: 'ART034', category: 'stenosis' },
|
||||
|
||||
// 其他异常
|
||||
{ name: '内膜剥脱', code: 'ART035', category: 'other' },
|
||||
{ name: '血管迂曲', code: 'ART036', category: 'other' },
|
||||
{ name: '血管扩张', code: 'ART037', category: 'other' },
|
||||
{ name: '动脉瘤样改变', code: 'ART038', category: 'other' },
|
||||
{ name: '血栓形成', code: 'ART039', category: 'other' },
|
||||
{ name: '纤维斑块', code: 'ART040', category: 'other' },
|
||||
{ name: '脂质斑块', code: 'ART041', category: 'other' },
|
||||
{ name: '不稳定斑块', code: 'ART042', category: 'other' },
|
||||
{ name: '易损斑块', code: 'ART043', category: 'other' },
|
||||
{ name: '血管重构', code: 'ART044', category: 'other' }
|
||||
]
|
||||
|
||||
// 过滤后的诊断模板
|
||||
const filteredDiagnoses = computed(() => {
|
||||
if (!searchKeyword.value) {
|
||||
return arterialDiagnoses
|
||||
}
|
||||
])
|
||||
return arterialDiagnoses.filter((diag) =>
|
||||
diag.name.toLowerCase().includes(searchKeyword.value.toLowerCase())
|
||||
)
|
||||
})
|
||||
|
||||
// 监听对话框显示状态
|
||||
watch(
|
||||
@ -183,7 +205,6 @@ watch(
|
||||
dialogVisible.value = newVal
|
||||
if (newVal) {
|
||||
nextTick(() => {
|
||||
initChart()
|
||||
loadAnalysisData()
|
||||
})
|
||||
}
|
||||
@ -198,119 +219,61 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
// 初始化图表
|
||||
const initChart = () => {
|
||||
if (!chartContainer.value) return
|
||||
|
||||
chartInstance = echarts.init(chartContainer.value)
|
||||
|
||||
const option = {
|
||||
title: {
|
||||
text: '动脉硬化指标变化趋势',
|
||||
left: 'center'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross'
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: ['PWV', 'ABI', 'IMT', 'AI'],
|
||||
top: 30
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: ['检测点1', '检测点2', '检测点3', '检测点4', '检测点5']
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: 'PWV (m/s)',
|
||||
position: 'left'
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
name: '其他指标',
|
||||
position: 'right'
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: 'PWV',
|
||||
type: 'line',
|
||||
yAxisIndex: 0,
|
||||
data: [8.2, 8.5, 8.3, 8.7, 8.5],
|
||||
itemStyle: { color: '#5470c6' }
|
||||
},
|
||||
{
|
||||
name: 'ABI',
|
||||
type: 'line',
|
||||
yAxisIndex: 1,
|
||||
data: [1.1, 1.12, 1.08, 1.15, 1.12],
|
||||
itemStyle: { color: '#91cc75' }
|
||||
},
|
||||
{
|
||||
name: 'IMT',
|
||||
type: 'line',
|
||||
yAxisIndex: 1,
|
||||
data: [0.7, 0.8, 0.75, 0.85, 0.8],
|
||||
itemStyle: { color: '#fac858' }
|
||||
},
|
||||
{
|
||||
name: 'AI',
|
||||
type: 'line',
|
||||
yAxisIndex: 1,
|
||||
data: [22, 25, 23, 28, 25],
|
||||
itemStyle: { color: '#ee6666' }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
chartInstance.setOption(option)
|
||||
}
|
||||
// 移除图表初始化函数,因为不再需要
|
||||
|
||||
// 加载分析数据
|
||||
const loadAnalysisData = async () => {
|
||||
try {
|
||||
// TODO: 调用动脉硬化分析API
|
||||
// const response = await ArterApi.getAnalysis(props.recordId)
|
||||
// analysisResult.overallAssessment = response.data.overallAssessment
|
||||
// analysisResult.riskLevel = response.data.riskLevel
|
||||
// analysisResult.recommendations = response.data.recommendations
|
||||
// analysisResult.doctorSignature = response.data.doctorSignature
|
||||
if (!currentRowData.value) {
|
||||
ElMessage.warning('缺少必要的检查数据')
|
||||
return
|
||||
}
|
||||
|
||||
// 模拟数据
|
||||
analysisResult.overallAssessment =
|
||||
'根据检测结果,患者动脉硬化程度处于正常范围内,各项指标均在参考值范围内。'
|
||||
analysisResult.riskLevel = 'low'
|
||||
analysisResult.recommendations = '建议保持健康的生活方式,定期进行体检,注意饮食和运动。'
|
||||
analysisResult.doctorSignature = ''
|
||||
const { examid, regid } = currentRowData.value
|
||||
if (!examid || !regid) {
|
||||
ElMessage.warning('缺少检查ID或患者ID')
|
||||
return
|
||||
}
|
||||
|
||||
// // 调用API获取arterialdata数据
|
||||
const response = await arterialdataApi.getarterialdataByExamidAndRegid(examid, regid)
|
||||
|
||||
if (response) {
|
||||
arterialData.value = response
|
||||
|
||||
// 处理data字段,去除可能的反引号和空格
|
||||
if (arterialData.value && arterialData.value.data) {
|
||||
// 如果data是字符串,直接处理
|
||||
if (typeof arterialData.value.data === 'string') {
|
||||
arterialData.value.data = arterialData.value.data.trim().replace(/^`|`$/g, '')
|
||||
}
|
||||
} else if (typeof arterialData.value === 'string') {
|
||||
// 如果整个response.data就是图片URL字符串,创建一个包含data字段的对象
|
||||
const imageUrl = arterialData.value.trim().replace(/^`|`$/g, '')
|
||||
arterialData.value = {
|
||||
data: imageUrl
|
||||
}
|
||||
}
|
||||
// 检查是否有已保存的诊断结论
|
||||
if (arterialData.value.diagnosis) {
|
||||
// 现在diagnosis直接是字符串,不需要JSON解析
|
||||
analysisResult.overallAssessment = arterialData.value.diagnosis
|
||||
} else {
|
||||
// 如果没有已保存的诊断结论,保持空白
|
||||
analysisResult.overallAssessment = ''
|
||||
}
|
||||
} else {
|
||||
// 如果没有数据,重置为空白
|
||||
analysisResult.overallAssessment = ''
|
||||
}
|
||||
// 如果没有已保存的分析结果,保持空白状态,不自动填写
|
||||
} catch (error) {
|
||||
console.error('加载分析数据失败:', error)
|
||||
ElMessage.error('加载分析数据失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 获取状态类型
|
||||
const getStatusType = (status: string) => {
|
||||
switch (status) {
|
||||
case '正常':
|
||||
return 'success'
|
||||
case '异常':
|
||||
return 'danger'
|
||||
case '临界':
|
||||
return 'warning'
|
||||
default:
|
||||
return 'info'
|
||||
}
|
||||
}
|
||||
// 移除getStatusType函数,因为不再需要
|
||||
|
||||
// 格式化日期时间
|
||||
const formatDateTime = (dateTime: string | Date) => {
|
||||
@ -318,120 +281,371 @@ const formatDateTime = (dateTime: string | Date) => {
|
||||
return formatDate(dateTime, 'YYYY-MM-DD HH:mm:ss')
|
||||
}
|
||||
|
||||
// 保存分析结果
|
||||
const handleSave = async () => {
|
||||
try {
|
||||
if (!analysisResult.overallAssessment.trim()) {
|
||||
ElMessage.warning('请输入总体评估')
|
||||
return
|
||||
}
|
||||
if (!analysisResult.riskLevel) {
|
||||
ElMessage.warning('请选择风险等级')
|
||||
return
|
||||
}
|
||||
if (!analysisResult.doctorSignature.trim()) {
|
||||
ElMessage.warning('请输入医生签名')
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: 调用保存API
|
||||
// await ArterApi.saveAnalysis({
|
||||
// recordId: props.recordId,
|
||||
// ...analysisResult
|
||||
// })
|
||||
|
||||
ElMessage.success('分析结果保存成功')
|
||||
emit('saved')
|
||||
} catch (error) {
|
||||
console.error('保存分析结果失败:', error)
|
||||
ElMessage.error('保存分析结果失败')
|
||||
}
|
||||
// 处理图片加载错误
|
||||
const handleImageError = (event: Event) => {
|
||||
console.log('图片加载失败:', event)
|
||||
ElMessage.warning('图片加载失败')
|
||||
}
|
||||
|
||||
// 报告预览
|
||||
const handlePreviewReport = () => {
|
||||
// 保存分析结果
|
||||
const handleSave = async () => {
|
||||
if (!analysisResult.overallAssessment.trim()) {
|
||||
ElMessage.warning('请先完成分析结果填写')
|
||||
ElMessage.warning('请输入诊断结论')
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: 实现报告预览功能
|
||||
ElMessage.info('报告预览功能开发中')
|
||||
if (!currentRowData.value?.examid || !currentRowData.value?.regid) {
|
||||
ElMessage.warning('缺少必要的患者信息')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
// 只传递必要的字段:examid、regid和诊断结论
|
||||
const saveData = {
|
||||
examid: currentRowData.value.examid,
|
||||
regid: currentRowData.value.regid,
|
||||
diagnosis: analysisResult.overallAssessment.trim()
|
||||
}
|
||||
|
||||
await arterialdataApi.savearterialdataDiagnosis(saveData)
|
||||
ElMessage.success('诊断结论已保存')
|
||||
} catch (error) {
|
||||
console.error('保存诊断失败:', error)
|
||||
ElMessage.error('保存诊断失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 插入诊断结论
|
||||
const insertDiagnosis = (diagnosis: string) => {
|
||||
const cursorPosition = analysisResult.overallAssessment.length
|
||||
if (
|
||||
analysisResult.overallAssessment &&
|
||||
!analysisResult.overallAssessment.endsWith('。') &&
|
||||
!analysisResult.overallAssessment.endsWith(',')
|
||||
) {
|
||||
analysisResult.overallAssessment += ',' + diagnosis
|
||||
} else {
|
||||
analysisResult.overallAssessment += diagnosis
|
||||
}
|
||||
}
|
||||
|
||||
// 应用诊断模板(保留原有功能,但不自动填写)
|
||||
const applyTemplate = (templateType: string) => {
|
||||
// 模板功能保留,但不自动填写诊断结论
|
||||
// 诊断结论应该根据接口查询结果显示
|
||||
ElMessage.success('模板应用成功')
|
||||
}
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
dialogVisible.value = false
|
||||
if (chartInstance) {
|
||||
chartInstance.dispose()
|
||||
chartInstance = null
|
||||
}
|
||||
|
||||
// 打开对话框的方法
|
||||
const open = async (rowData?: any) => {
|
||||
dialogVisible.value = true
|
||||
|
||||
// 存储传入的行数据
|
||||
if (rowData) {
|
||||
currentRowData.value = rowData
|
||||
// 先加载数据,再决定是否重置
|
||||
await loadAnalysisData()
|
||||
} else {
|
||||
// 如果没有行数据,重置所有字段
|
||||
analysisResult.overallAssessment = ''
|
||||
arterialData.value = null
|
||||
}
|
||||
}
|
||||
|
||||
// 组件卸载时清理图表
|
||||
onUnmounted(() => {
|
||||
if (chartInstance) {
|
||||
chartInstance.dispose()
|
||||
chartInstance = null
|
||||
}
|
||||
// 暴露方法给父组件
|
||||
defineExpose({
|
||||
open
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.arteriosclerosis-analysis-container {
|
||||
padding: 20px;
|
||||
.arterial-analysis-dialog {
|
||||
--el-dialog-padding-primary: 0;
|
||||
}
|
||||
|
||||
.patient-info {
|
||||
background: #f5f7fa;
|
||||
padding: 15px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
.arterial-analysis-dialog .el-dialog__body {
|
||||
padding: 0;
|
||||
height: calc(100vh - 120px);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
.arterial-analysis-dialog .el-dialog__footer {
|
||||
padding: 15px 20px;
|
||||
border-top: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.info-item .label {
|
||||
font-weight: bold;
|
||||
color: #606266;
|
||||
margin-right: 8px;
|
||||
.left-panel {
|
||||
width: 75%;
|
||||
overflow-y: auto;
|
||||
border-right: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.info-item .value {
|
||||
color: #303133;
|
||||
.right-panel {
|
||||
width: 25%;
|
||||
overflow-y: auto;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.chart-section,
|
||||
.statistics-section,
|
||||
.image-display-section,
|
||||
.analysis-section {
|
||||
margin-bottom: 30px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.chart-section h3,
|
||||
.statistics-section h3,
|
||||
.analysis-section h3 {
|
||||
margin-bottom: 15px;
|
||||
.section-title {
|
||||
margin: 0 0 15px 0;
|
||||
color: #303133;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
.image-display-section {
|
||||
height: 100%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.image-container {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
background: #fafafa;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
.image-container.full-height {
|
||||
height: calc(100vh - 160px);
|
||||
}
|
||||
|
||||
.placeholder-image {
|
||||
text-align: center;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.placeholder-image p {
|
||||
margin: 10px 0 0 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.placeholder-image .sub-text {
|
||||
font-size: 12px;
|
||||
color: #c0c4cc;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
/* 数据展示样式 */
|
||||
.data-display {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 20px;
|
||||
overflow-y: auto;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.data-display h3 {
|
||||
margin: 0 0 20px 0;
|
||||
color: #303133;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
border-bottom: 2px solid #409eff;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
/* 图片展示区域样式 */
|
||||
.image-section {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.image-section h4 {
|
||||
margin: 0 0 15px 0;
|
||||
color: #606266;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.image-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.detection-image {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.no-image-placeholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
color: #909399;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.no-image-placeholder p {
|
||||
margin: 10px 0 0 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.data-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.data-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.data-item label {
|
||||
font-weight: bold;
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.data-item span {
|
||||
color: #303133;
|
||||
font-size: 14px;
|
||||
padding: 5px 10px;
|
||||
background: #f5f7fa;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.data-json {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.data-json pre {
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
font-size: 12px;
|
||||
color: #303133;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.diagnosis-selector {
|
||||
margin-bottom: 20px;
|
||||
padding: 15px;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 6px;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.selector-title {
|
||||
font-size: 16px;
|
||||
margin-bottom: 10px;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.diagnosis-list {
|
||||
max-height: 45vh;
|
||||
overflow-y: auto;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 4px;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.diagnosis-item {
|
||||
padding: 8px 12px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.diagnosis-item:hover {
|
||||
background-color: #e6f7ff;
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.diagnosis-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.no-results {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.analysis-section {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.analysis-section h3 {
|
||||
margin: 0 0 15px 0;
|
||||
color: #303133;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.bottom-actions {
|
||||
background: #f5f7fa;
|
||||
padding: 15px 20px;
|
||||
border-top: 1px solid #e4e7ed;
|
||||
text-align: right;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.dialog-footer .el-button {
|
||||
.bottom-actions .el-button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 1200px) {
|
||||
.left-panel {
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.right-panel {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.main-content {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.left-panel,
|
||||
.right-panel {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.patient-info-inline {
|
||||
gap: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="arteriosclerosis-analysis">
|
||||
<!-- 动脉硬化分析弹窗组件 -->
|
||||
<Arter_analysis ref="arterAnalysisRef" />
|
||||
<Arter_analysis ref="arterAnalysisRef" v-model="showAnalysisDialog" />
|
||||
|
||||
<!-- 患者选择组件(后续可补充) -->
|
||||
<PatientSelect
|
||||
@ -193,12 +193,14 @@ import PatientSelect from '@/patientcom/index.vue'
|
||||
import { getUserProfile } from '@/api/system/user/profile'
|
||||
import { OrgApi } from '@/api/org'
|
||||
import { arterialApi } from '@/api/arterial'
|
||||
import { arterialdataApi } from '@/api/arterialdata'
|
||||
import { Search, Refresh, Plus, Edit, Check, Close } from '@element-plus/icons-vue'
|
||||
import dayjs from 'dayjs'
|
||||
import Arter_analysis from './Arter_analysis.vue'
|
||||
|
||||
const loading = ref(false)
|
||||
const total = ref(0)
|
||||
const showAnalysisDialog = ref(false)
|
||||
|
||||
// 查询参数
|
||||
const queryParams = reactive({
|
||||
@ -324,17 +326,15 @@ const handlePatientCancel = () => {
|
||||
|
||||
const onAnalyze = async (row: any) => {
|
||||
try {
|
||||
// 获取动脉硬化分析结果
|
||||
const res = await arterialApi.getArterialAnalysis(row.examid)
|
||||
const res = await arterialdataApi.getarterialdataByExamidAndRegid(row.examid, row.regid)
|
||||
if (res) {
|
||||
arterAnalysisRef.value?.open(row)
|
||||
showAnalysisDialog.value = true
|
||||
await arterAnalysisRef.value?.open(row)
|
||||
} else {
|
||||
ElMessage.error('暂无分析数据')
|
||||
ElMessage.error('暂无数据')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取分析数据失败:', error)
|
||||
// 如果获取分析数据失败,仍然可以打开分析弹窗进行新的分析
|
||||
arterAnalysisRef.value?.open(row)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -10,101 +10,92 @@
|
||||
class="ecg-workstation-dialog"
|
||||
@close="handleClose"
|
||||
>
|
||||
<!-- 主要内容区域 -->
|
||||
<div class="workstation-container">
|
||||
<!-- 工作区域 -->
|
||||
<!-- 左侧图片展示区域 (3/4) -->
|
||||
<div class="work-area">
|
||||
<el-row :gutter="16" style="height: 90vh">
|
||||
<!-- 左侧ECG报告图片显示区 (3/4) -->
|
||||
<el-col :span="18">
|
||||
<el-card shadow="never" class="ecg-image-display">
|
||||
<div class="ecg-image-container">
|
||||
<!-- ECG报告图片显示区域 -->
|
||||
<div
|
||||
class="image-viewer"
|
||||
v-loading="loading"
|
||||
element-loading-text="正在加载ECG数据..."
|
||||
>
|
||||
<img
|
||||
v-if="ecgImageUrl"
|
||||
:src="ecgImageUrl"
|
||||
alt="ECG报告"
|
||||
class="ecg-report-image"
|
||||
@load="handleImageLoad"
|
||||
@error="handleImageError"
|
||||
/>
|
||||
<div v-else class="image-placeholder">
|
||||
<el-empty description="暂无影像" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<!-- 图片展示区域 -->
|
||||
<div class="image-display-section">
|
||||
<div class="image-container full-height">
|
||||
<!-- 图片展示区域 -->
|
||||
<div v-if="ecgImageUrl" class="image-wrapper">
|
||||
<img
|
||||
:src="ecgImageUrl"
|
||||
alt="ECG报告"
|
||||
class="ecg-report-image"
|
||||
@load="handleImageLoad"
|
||||
@error="handleImageError"
|
||||
/>
|
||||
</div>
|
||||
<!-- 占位符 -->
|
||||
<div v-else class="no-image-placeholder">
|
||||
<el-empty description="暂无影像" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧诊断信息区 (1/4) -->
|
||||
<el-col :span="6">
|
||||
<el-card
|
||||
shadow="never"
|
||||
class="diagnosis-panel"
|
||||
v-loading="loading"
|
||||
element-loading-text="正在加载..."
|
||||
<!-- 右侧诊断模板和结论区域 (1/4) -->
|
||||
<div class="diagnosis-panel">
|
||||
<!-- 诊断模板选择区域 -->
|
||||
<div class="diagnosis-selector">
|
||||
<h5 class="selector-title">
|
||||
诊断模板
|
||||
<el-input
|
||||
v-model="searchKeyword"
|
||||
placeholder="请输入关键词"
|
||||
clearable
|
||||
style="height: 40px; margin-top: 5px"
|
||||
size="medium"
|
||||
prefix-icon="Search"
|
||||
/>
|
||||
</h5>
|
||||
|
||||
<div class="diagnosis-list">
|
||||
<div
|
||||
v-for="diag in filteredDiagnoses"
|
||||
:key="diag.code"
|
||||
class="diagnosis-item"
|
||||
@click="insertDiagnosis(diag.name)"
|
||||
>
|
||||
<div class="diagnosis-content">
|
||||
<!-- 诊断结果 -->
|
||||
<div class="diagnosis-section">
|
||||
<!-- 诊断结论选择列表 -->
|
||||
<div class="diagnosis-selector">
|
||||
<h5 class="selector-title"
|
||||
>诊断模板
|
||||
<el-input
|
||||
v-model="searchKeyword"
|
||||
placeholder="请输入关键词"
|
||||
clearable
|
||||
style="height: 40px; margin-top: 5px"
|
||||
size="small"
|
||||
prefix-icon="Search"
|
||||
/>
|
||||
</h5>
|
||||
{{ diag.name }}
|
||||
</div>
|
||||
<div v-if="filteredDiagnoses.length === 0" class="no-results">
|
||||
暂无匹配的诊断模板
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="diagnosis-list">
|
||||
<div
|
||||
v-for="diag in filteredDiagnoses"
|
||||
:key="diag.code"
|
||||
class="diagnosis-item"
|
||||
@click="insertDiagnosis(diag.name)"
|
||||
>
|
||||
{{ diag.name }}
|
||||
</div>
|
||||
<div v-if="filteredDiagnoses.length === 0" class="no-results">
|
||||
暂无匹配的诊断模板
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h4 class="section-title">诊断结论 </h4>
|
||||
<el-input
|
||||
v-model="diagnosisText"
|
||||
type="textarea"
|
||||
placeholder="请输入诊断结论..."
|
||||
:disabled="loading"
|
||||
:rows="5"
|
||||
resize="none"
|
||||
/>
|
||||
</div>
|
||||
<div class="diagnosis-actions">
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleSaveAnalysis"
|
||||
:loading="loading"
|
||||
:disabled="!patientData.examid || !patientData.regid"
|
||||
>
|
||||
保存结论
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 诊断结论输入区域 -->
|
||||
<div class="analysis-section">
|
||||
<h3>诊断结论</h3>
|
||||
<el-form label-width="80px" size="medium">
|
||||
<el-input
|
||||
v-model="diagnosisText"
|
||||
type="textarea"
|
||||
:rows="8"
|
||||
resize="none"
|
||||
placeholder="请输入诊断结论"
|
||||
/>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部操作按钮 -->
|
||||
<template #footer>
|
||||
<div class="bottom-actions">
|
||||
<el-button @click="handleClose">关闭</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleSaveAnalysis"
|
||||
:loading="loading"
|
||||
:disabled="!patientData.examid || !patientData.regid"
|
||||
>
|
||||
保存结论
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
@ -200,7 +191,6 @@ const loadEcgData = async (examid: string, regid: string) => {
|
||||
if (response.ecgdata) {
|
||||
ecgImageUrl.value = response.ecgdata
|
||||
}
|
||||
ElMessage.success('数据加载成功')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('数据加载失败:', error)
|
||||
@ -289,252 +279,195 @@ defineExpose({
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ecg-workstation-dialog :deep(.el-dialog__wrapper),
|
||||
.ecg-workstation-dialog :deep(.el-dialog),
|
||||
.ecg-workstation-dialog :deep(.el-dialog__body) {
|
||||
height: 90vh !important;
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
.ecg-workstation-dialog {
|
||||
--el-dialog-padding-primary: 0;
|
||||
}
|
||||
|
||||
.workstation-container,
|
||||
.work-area,
|
||||
.el-row,
|
||||
.el-col,
|
||||
.ecg-image-display,
|
||||
.diagnosis-panel {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.ecg-image-display :deep(.el-card__body),
|
||||
.diagnosis-panel :deep(.el-card__body) {
|
||||
height: 100%;
|
||||
.ecg-workstation-dialog .el-dialog__body {
|
||||
padding: 0;
|
||||
height: calc(100vh - 120px);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ecg-workstation-dialog .el-dialog__footer {
|
||||
padding: 15px 20px;
|
||||
border-top: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.workstation-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.work-area {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
padding: 16px;
|
||||
overflow: hidden;
|
||||
width: 75%;
|
||||
overflow-y: auto;
|
||||
border-right: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.patient-info {
|
||||
padding: 16px;
|
||||
background: #f6f8fa;
|
||||
}
|
||||
|
||||
.info-card {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.info-content {
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-weight: 500;
|
||||
color: #666;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.patient-info-header {
|
||||
padding: 16px;
|
||||
background: #f8f9fb;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.patient-info-header :deep(.el-descriptions) {
|
||||
background: white;
|
||||
}
|
||||
|
||||
.patient-info-header :deep(.el-descriptions__label) {
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
.diagnosis-panel {
|
||||
width: 25%;
|
||||
overflow-y: auto;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.patient-info-header :deep(.el-descriptions__content) {
|
||||
.image-display-section,
|
||||
.analysis-section {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
margin: 0 0 15px 0;
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.display-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.display-controls {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.ecg-image-container {
|
||||
.image-display-section {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: #f5f5f5;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.image-viewer {
|
||||
.image-container {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
background: #fafafa;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.image-container.full-height {
|
||||
height: calc(100vh - 180px);
|
||||
}
|
||||
|
||||
.image-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: auto;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ecg-report-image {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
border: 1px solid #ddd;
|
||||
background: white;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.image-placeholder {
|
||||
text-align: center;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.diagnosis-content {
|
||||
.no-image-placeholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.diagnosis-section {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.measurement-section,
|
||||
.diagnosis-section,
|
||||
.action-section {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 12px;
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
margin-left: 11px;
|
||||
}
|
||||
|
||||
.measurement-grid {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.measurement-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 6px 0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
color: #909399;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.param-label {
|
||||
color: #666;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.param-value {
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.diagnosis-text {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.diagnosis-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding-bottom: 5px;
|
||||
padding-right: 5px;
|
||||
.no-image-placeholder p {
|
||||
margin: 10px 0 0 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.diagnosis-selector {
|
||||
margin-bottom: 12px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
background-color: #fff;
|
||||
margin-bottom: 20px;
|
||||
padding: 15px;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 6px;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.selector-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
margin-bottom: 10px;
|
||||
color: #333;
|
||||
margin: 0;
|
||||
padding: 12px 16px 8px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.diagnosis-list {
|
||||
max-height: 50vh;
|
||||
max-height: 45vh;
|
||||
overflow-y: auto;
|
||||
padding: 8px;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 4px;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.diagnosis-item {
|
||||
font-size: 13px;
|
||||
color: #333;
|
||||
padding: 6px 12px;
|
||||
border-radius: 4px;
|
||||
padding: 8px 12px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
border: 1px solid transparent;
|
||||
margin-bottom: 2px;
|
||||
font-size: 14px;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.diagnosis-item:hover {
|
||||
background-color: #e6f7ff;
|
||||
border-color: #b3d8ff;
|
||||
color: #409eff;
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.diagnosis-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.no-results {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
color: #909399;
|
||||
font-size: 13px;
|
||||
padding: 8px 0;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.analysis-section {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.analysis-section h3 {
|
||||
margin: 0 0 15px 0;
|
||||
color: #303133;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.bottom-actions {
|
||||
background: #f5f7fa;
|
||||
padding: 15px 20px;
|
||||
border-top: 1px solid #e4e7ed;
|
||||
text-align: right;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.bottom-actions .el-button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 1200px) {
|
||||
.work-area {
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.diagnosis-panel {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.workstation-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.work-area,
|
||||
.diagnosis-panel {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user