Merge branch 'master' of http://114.55.171.231:3000/Euni4U/shanghai_vue3
This commit is contained in:
commit
713c9f5b71
76
src/api/arterial/index.ts
Normal file
76
src/api/arterial/index.ts
Normal file
@ -0,0 +1,76 @@
|
||||
import request from '@/config/axios'
|
||||
import { patientinfoVO } from '../patientinfo'
|
||||
|
||||
// 动脉硬化检测患者 VO
|
||||
export interface arterialVO {
|
||||
id: number // 主键
|
||||
examid: string // 检查ID
|
||||
regid: string // 患者注册ID
|
||||
name: string // 患者姓名
|
||||
gender: string // 性别
|
||||
age: string // 年龄
|
||||
orgid: string // 机构ID
|
||||
orgname: string // 机构名称
|
||||
managerorg: string // 管理机构
|
||||
deviceid: string // 设备ID
|
||||
devicename: string // 设备名称
|
||||
status: number // 状态: 0=申请中, 1=已申请
|
||||
weartime: Date // 佩戴时间
|
||||
analysisresult: string // 分析结果
|
||||
createtime: Date // 创建时间
|
||||
updatetime: Date // 更新时间
|
||||
}
|
||||
|
||||
// 动脉硬化检测患者 API
|
||||
export const arterialApi = {
|
||||
// 查询动脉硬化检测患者分页
|
||||
getarterialPage: async (params: any) => {
|
||||
return await request.get({ url: `/system/arterial/page`, params })
|
||||
},
|
||||
|
||||
// 查询动脉硬化检测患者详情
|
||||
getarterial: async (id: number) => {
|
||||
return await request.get({ url: `/system/arterial/get?id=` + id })
|
||||
},
|
||||
|
||||
// 新增动脉硬化检测患者
|
||||
createarterial: async (data: arterialVO) => {
|
||||
return await request.post({ url: `/system/arterial/create`, data })
|
||||
},
|
||||
|
||||
// 修改动脉硬化检测患者
|
||||
updatearterial: async (data: arterialVO) => {
|
||||
return await request.put({ url: `/system/arterial/update`, data })
|
||||
},
|
||||
|
||||
// 删除动脉硬化检测患者
|
||||
deletearterial: async (id: number) => {
|
||||
return await request.delete({ url: `/system/arterial/delete?id=` + id })
|
||||
},
|
||||
|
||||
// 导出动脉硬化检测患者 Excel
|
||||
exportarterial: async (params) => {
|
||||
return await request.download({ url: `/system/arterial/export-excel`, params })
|
||||
},
|
||||
|
||||
// 批量新增动脉硬化患者数据
|
||||
insertArterialPatientData: async (data: patientinfoVO[]) => {
|
||||
return await request.post({ url: `/system/arterial/insertArterialPatientData`, data })
|
||||
},
|
||||
|
||||
// 根据examid更新动脉硬化分析结果
|
||||
updateArterialAnalysis: async (examid: string, analysisResult: string) => {
|
||||
return await request.put({
|
||||
url: `/system/arterial/updateArterialAnalysis`,
|
||||
params: {
|
||||
examid,
|
||||
analysisResult
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 根据examid查询动脉硬化分析结果
|
||||
getArterialAnalysis: async (examid: string) => {
|
||||
return await request.get({ url: `/system/arterial/getArterialAnalysis`, params: { examid } })
|
||||
}
|
||||
}
|
||||
@ -209,6 +209,7 @@ import { Search, Refresh, Delete } from '@element-plus/icons-vue'
|
||||
import { StaticecgApi } from '@/api/staticecg'
|
||||
import { Spo2infoApi } from '@/api/spo2info'
|
||||
import { CgmApi } from '@/api/cgm/index'
|
||||
import { arterialApi } from '@/api/arterial/index'
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
@ -368,6 +369,10 @@ const handleConfirm = async () => {
|
||||
// 批量新增CGM患者数据
|
||||
await CgmApi.insertCgmPatientData(selectedPatients.value)
|
||||
}
|
||||
if (props.type === 'arteriosclerosis') {
|
||||
// 批量新增动脉硬化患者数据
|
||||
await arterialApi.insertArterialPatientData(selectedPatients.value)
|
||||
}
|
||||
handleCancel()
|
||||
} catch (error) {
|
||||
message.error('操作失败,请重试')
|
||||
|
||||
437
src/views/analysis/Arteriosclerosis/Arter_analysis.vue
Normal file
437
src/views/analysis/Arteriosclerosis/Arter_analysis.vue
Normal file
@ -0,0 +1,437 @@
|
||||
<template>
|
||||
<Dialog
|
||||
v-model="dialogVisible"
|
||||
:title="`动脉硬化分析 - ${patientData.name}`"
|
||||
width="90%"
|
||||
:before-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>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div class="info-item">
|
||||
<span class="label">性别:</span>
|
||||
<span class="value">{{ patientData.gender }}</span>
|
||||
</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 class="chart-section">
|
||||
<h3>动脉硬化指标趋势</h3>
|
||||
<div ref="chartContainer" class="chart-container"></div>
|
||||
</div>
|
||||
|
||||
<!-- 数据统计表格 -->
|
||||
<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="analysis-section">
|
||||
<h3>分析结果</h3>
|
||||
<el-form :model="analysisResult" label-width="120px">
|
||||
<el-form-item label="总体评估:">
|
||||
<el-input
|
||||
v-model="analysisResult.overallAssessment"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleClose">关闭</el-button>
|
||||
<el-button type="primary" @click="handleSave">保存分析结果</el-button>
|
||||
<el-button type="success" @click="handlePreviewReport">报告预览</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, nextTick, watch, onUnmounted } from 'vue'
|
||||
import * as echarts from 'echarts'
|
||||
import { formatDate } from '@/utils/formatTime'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
|
||||
// 组件属性
|
||||
interface Props {
|
||||
modelValue: boolean
|
||||
patientData: any
|
||||
recordId?: string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
modelValue: false,
|
||||
patientData: () => ({}),
|
||||
recordId: ''
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'saved'])
|
||||
|
||||
// 响应式数据
|
||||
const dialogVisible = ref(false)
|
||||
const chartContainer = ref()
|
||||
let chartInstance: echarts.ECharts | null = null
|
||||
|
||||
// 分析结果
|
||||
const analysisResult = reactive({
|
||||
overallAssessment: '',
|
||||
riskLevel: '',
|
||||
recommendations: '',
|
||||
doctorSignature: ''
|
||||
})
|
||||
|
||||
// 统计数据
|
||||
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: '动脉硬化程度'
|
||||
}
|
||||
])
|
||||
|
||||
// 监听对话框显示状态
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(newVal) => {
|
||||
dialogVisible.value = newVal
|
||||
if (newVal) {
|
||||
nextTick(() => {
|
||||
initChart()
|
||||
loadAnalysisData()
|
||||
})
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
watch(
|
||||
() => dialogVisible.value,
|
||||
(newVal) => {
|
||||
emit('update:modelValue', newVal)
|
||||
}
|
||||
)
|
||||
|
||||
// 初始化图表
|
||||
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
|
||||
|
||||
// 模拟数据
|
||||
analysisResult.overallAssessment =
|
||||
'根据检测结果,患者动脉硬化程度处于正常范围内,各项指标均在参考值范围内。'
|
||||
analysisResult.riskLevel = 'low'
|
||||
analysisResult.recommendations = '建议保持健康的生活方式,定期进行体检,注意饮食和运动。'
|
||||
analysisResult.doctorSignature = ''
|
||||
} 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'
|
||||
}
|
||||
}
|
||||
|
||||
// 格式化日期时间
|
||||
const formatDateTime = (dateTime: string | Date) => {
|
||||
if (!dateTime) return ''
|
||||
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 handlePreviewReport = () => {
|
||||
if (!analysisResult.overallAssessment.trim()) {
|
||||
ElMessage.warning('请先完成分析结果填写')
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: 实现报告预览功能
|
||||
ElMessage.info('报告预览功能开发中')
|
||||
}
|
||||
|
||||
// 关闭对话框
|
||||
const handleClose = () => {
|
||||
dialogVisible.value = false
|
||||
if (chartInstance) {
|
||||
chartInstance.dispose()
|
||||
chartInstance = null
|
||||
}
|
||||
}
|
||||
|
||||
// 组件卸载时清理图表
|
||||
onUnmounted(() => {
|
||||
if (chartInstance) {
|
||||
chartInstance.dispose()
|
||||
chartInstance = null
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.arteriosclerosis-analysis-container {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.patient-info {
|
||||
background: #f5f7fa;
|
||||
padding: 15px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.info-item .label {
|
||||
font-weight: bold;
|
||||
color: #606266;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.info-item .value {
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.chart-section,
|
||||
.statistics-section,
|
||||
.analysis-section {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.chart-section h3,
|
||||
.statistics-section h3,
|
||||
.analysis-section h3 {
|
||||
margin-bottom: 15px;
|
||||
color: #303133;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.dialog-footer .el-button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
||||
447
src/views/analysis/Arteriosclerosis/Arteriosclerosis.vue
Normal file
447
src/views/analysis/Arteriosclerosis/Arteriosclerosis.vue
Normal file
@ -0,0 +1,447 @@
|
||||
<template>
|
||||
<div class="arteriosclerosis-analysis">
|
||||
<!-- 动脉硬化分析弹窗组件 -->
|
||||
<Arter_analysis ref="arterAnalysisRef" />
|
||||
|
||||
<!-- 患者选择组件(后续可补充) -->
|
||||
<PatientSelect
|
||||
ref="patientSelectRef"
|
||||
title="选择患者"
|
||||
type="arteriosclerosis"
|
||||
:multiple="true"
|
||||
:max-select="50"
|
||||
@confirm="handlePatientConfirm"
|
||||
@cancel="handlePatientCancel"
|
||||
/>
|
||||
|
||||
<!-- 顶部筛选区 -->
|
||||
<el-card class="filter-card" shadow="never">
|
||||
<el-form :inline="true" :model="queryParams" class="filter-form">
|
||||
<el-form-item label="姓名:">
|
||||
<el-input
|
||||
v-model="queryParams.name"
|
||||
placeholder="请输入姓名"
|
||||
clearable
|
||||
style="width: 120px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="性别:">
|
||||
<el-select
|
||||
v-model="queryParams.gender"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 100px"
|
||||
>
|
||||
<el-option label="男" value="1" />
|
||||
<el-option label="女" value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="日期:">
|
||||
<el-date-picker
|
||||
v-model="queryParams.dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
style="width: 240px"
|
||||
value-format="YYYY-MM-DD"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态:">
|
||||
<el-select
|
||||
v-model="queryParams.status"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 140px"
|
||||
>
|
||||
<el-option label="已申请" value="1" />
|
||||
<el-option label="未申请" value="0" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="handleQuery"
|
||||
><el-icon><Search /></el-icon>搜索</el-button
|
||||
>
|
||||
<el-button @click="resetQuery"
|
||||
><el-icon><Refresh /></el-icon>重置</el-button
|
||||
>
|
||||
<el-button type="primary" @click="handleSelectPatients"
|
||||
><el-icon><Plus /></el-icon>选择患者</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<!-- 数据表格区 -->
|
||||
<el-card class="table-card" shadow="never" style="margin-top: 16px">
|
||||
<el-table v-loading="loading" :data="tableData" border stripe style="width: 100%">
|
||||
<el-table-column prop="examid" label="检查ID" align="center" min-width="220" />
|
||||
<el-table-column prop="name" label="姓名" align="center" min-width="90" />
|
||||
<el-table-column prop="gender" label="性别" align="center" min-width="60">
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.gender === '1' ? '男' : row.gender === '2' ? '女' : '未知' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="age" label="年龄" align="center" min-width="60">
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.age + '岁' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="weartime" label="佩戴时间" align="center" min-width="180">
|
||||
<template #default="{ row, $index }">
|
||||
<!-- 编辑状态 -->
|
||||
<div v-if="row.editingWearTime" style="display: flex; align-items: center; gap: 8px">
|
||||
<el-date-picker
|
||||
v-model="row.weartime"
|
||||
type="datetime"
|
||||
placeholder="选择时间"
|
||||
size="small"
|
||||
style="width: 130px"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
<el-button type="primary" size="small" @click="saveWearTime(row, $index)" link>
|
||||
<el-icon><Check /></el-icon>
|
||||
</el-button>
|
||||
<el-button size="small" @click="cancelEditWearTime(row, $index)" link>
|
||||
<el-icon><Close /></el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
<!-- 显示状态 -->
|
||||
<div
|
||||
v-else
|
||||
style="display: flex; align-items: center; justify-content: center; gap: 8px"
|
||||
>
|
||||
<span>{{ formatTime(row.weartime) }}</span>
|
||||
<el-button type="primary" size="small" @click="editWearTime(row, $index)" link>
|
||||
<el-icon><Edit /></el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="device" label="检测设备" align="center" min-width="150">
|
||||
<template #default="{ row, $index }">
|
||||
<!-- 编辑状态 -->
|
||||
<div v-if="row.editingDevice" style="display: flex; align-items: center; gap: 8px">
|
||||
<el-select
|
||||
v-model="row.deviceid"
|
||||
placeholder="选择设备"
|
||||
size="small"
|
||||
style="width: 110px"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in deviceList"
|
||||
:key="item.id"
|
||||
:label="item.deviceName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
<el-button type="primary" size="small" @click="saveDevice(row, $index)" link>
|
||||
<el-icon><Check /></el-icon>
|
||||
</el-button>
|
||||
<el-button size="small" @click="cancelEditDevice(row, $index)" link>
|
||||
<el-icon><Close /></el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
<!-- 显示状态 -->
|
||||
<div
|
||||
v-else
|
||||
style="display: flex; align-items: center; justify-content: center; gap: 8px"
|
||||
>
|
||||
<span>{{ row.devicename }}</span>
|
||||
<el-button type="primary" size="small" @click="editDevice(row, $index)" link>
|
||||
<el-icon><Edit /></el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="orgname" label="机构" align="center" min-width="120" />
|
||||
<el-table-column label="分析" align="center" min-width="70">
|
||||
<template #default="{ row }">
|
||||
<el-link type="primary" @click="onAnalyze(row)">分析</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="报告" align="center" min-width="70">
|
||||
<template #default="{ row }">
|
||||
<el-link type="primary" @click="onViewReport(row)">查看</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" label="状态" align="center" min-width="70">
|
||||
<template #default="{ row }">
|
||||
<el-link v-if="row.status == '1'" type="success" :underline="false" disabled
|
||||
>已申请</el-link
|
||||
>
|
||||
<el-link v-else type="primary" @click="handleApply(row)">申请</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页 -->
|
||||
<Pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import PatientSelect from '@/patientcom/index.vue'
|
||||
import { getUserProfile } from '@/api/system/user/profile'
|
||||
import { OrgApi } from '@/api/org'
|
||||
import { arterialApi } from '@/api/arterial'
|
||||
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 queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
name: '',
|
||||
gender: '',
|
||||
dateRange: [],
|
||||
status: '',
|
||||
orgid: '',
|
||||
orgname: '',
|
||||
age: ''
|
||||
})
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref<any[]>([])
|
||||
|
||||
const patientSelectRef = ref()
|
||||
const arterAnalysisRef = ref()
|
||||
|
||||
// 设备下拉测试数据
|
||||
const deviceList = ref<any[]>([])
|
||||
const getDeviceList = () => {
|
||||
deviceList.value = [
|
||||
{ id: '1001', deviceName: '动脉硬化检测仪-1001' },
|
||||
{ id: '1002', deviceName: '动脉硬化检测仪-1002' },
|
||||
{ id: '1003', deviceName: '动脉硬化检测仪-1003' }
|
||||
]
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getDeviceList()
|
||||
getList()
|
||||
})
|
||||
|
||||
// 获取列表数据
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
// 处理日期范围参数
|
||||
const params = { ...queryParams }
|
||||
if (params.dateRange && params.dateRange.length === 2) {
|
||||
params.startDate = params.dateRange[0]
|
||||
params.endDate = params.dateRange[1]
|
||||
delete params.dateRange
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
const userinfo = await getUserProfile()
|
||||
const orginfo = await OrgApi.getOrgByOrgId(userinfo.orgid)
|
||||
// 判断登陆人机构ID是否为超级管理员[0],或者为空
|
||||
if (userinfo.orgid != 0 && userinfo.orgid != null) {
|
||||
// 判断登陆人机构ID是否有等于父&上级机构ID,如果等于则查询子&下级机构ID
|
||||
if (userinfo.orgid != orginfo.parentOrgId) {
|
||||
params.orgid = userinfo.orgid
|
||||
const data = await arterialApi.getarterialPage(params)
|
||||
tableData.value = data.list
|
||||
total.value = data.total
|
||||
} else if (userinfo.orgid == orginfo.parentOrgId) {
|
||||
// 查询子&下级机构ID并查询对应机构的患者数据
|
||||
const childinfo = await OrgApi.getOrgByParentOrgId(userinfo.orgid)
|
||||
params.orgid = childinfo.orgId
|
||||
params.status = '1'
|
||||
const data = await arterialApi.getarterialPage(params)
|
||||
tableData.value = data.list
|
||||
total.value = data.total
|
||||
}
|
||||
} else if (userinfo.orgid == 0) {
|
||||
// 如果是超级管理员,查询全部
|
||||
const data = await arterialApi.getarterialPage(params)
|
||||
tableData.value = data.list
|
||||
total.value = data.total
|
||||
} else {
|
||||
console.error('用户机构为空')
|
||||
return
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取动脉硬化数据失败:', error)
|
||||
ElMessage.error('获取数据失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 查询、重置、选择患者等方法
|
||||
const handleQuery = () => {
|
||||
queryParams.pageNo = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
const resetQuery = () => {
|
||||
Object.assign(queryParams, {
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
name: '',
|
||||
gender: '',
|
||||
dateRange: [],
|
||||
status: '',
|
||||
age: ''
|
||||
})
|
||||
getList()
|
||||
}
|
||||
|
||||
const handleSelectPatients = () => {
|
||||
patientSelectRef.value?.open()
|
||||
}
|
||||
|
||||
const handlePatientConfirm = async (selectedPatients: any[]) => {
|
||||
try {
|
||||
await arterialApi.insertArterialPatientData(selectedPatients)
|
||||
ElMessage.success(`已成功添加 ${selectedPatients.length} 位患者到动脉硬化检测系统`)
|
||||
// 这里刷新表格数据以显示新添加的患者
|
||||
handleQuery()
|
||||
} catch (error) {
|
||||
console.error('添加动脉硬化患者数据失败:', error)
|
||||
ElMessage.error('添加患者数据失败,请重试')
|
||||
}
|
||||
}
|
||||
|
||||
const handlePatientCancel = () => {
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
const onAnalyze = async (row: any) => {
|
||||
try {
|
||||
// 获取动脉硬化分析结果
|
||||
const res = await arterialApi.getArterialAnalysis(row.examid)
|
||||
if (res) {
|
||||
arterAnalysisRef.value?.open(row)
|
||||
} else {
|
||||
ElMessage.error('暂无分析数据')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取分析数据失败:', error)
|
||||
// 如果获取分析数据失败,仍然可以打开分析弹窗进行新的分析
|
||||
arterAnalysisRef.value?.open(row)
|
||||
}
|
||||
}
|
||||
|
||||
const onViewReport = (row: any) => {
|
||||
ElMessage.success(`查看报告:${row.name}`)
|
||||
}
|
||||
|
||||
const handleApply = async (row: any) => {
|
||||
try {
|
||||
const userinfo = await getUserProfile()
|
||||
const orginfo = await OrgApi.getOrg(userinfo.orgid)
|
||||
if (orginfo.parentOrgId != null) {
|
||||
const updateData = { ...row, status: 1, managerorg: orginfo.parentOrgId }
|
||||
await arterialApi.updatearterial(updateData)
|
||||
ElMessage.success(`${row.name} 申请成功`)
|
||||
getList()
|
||||
} else {
|
||||
ElMessage.error('无上级机构')
|
||||
return
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('申请失败:', error)
|
||||
ElMessage.error('申请失败,请重试')
|
||||
}
|
||||
}
|
||||
|
||||
const formatTime = (timestamp: number | string) => {
|
||||
if (!timestamp) return ''
|
||||
const ts = typeof timestamp === 'string' ? parseInt(timestamp) : timestamp
|
||||
return dayjs(ts).isValid() ? dayjs(ts).format('YYYY-MM-DD HH:mm:ss') : timestamp
|
||||
}
|
||||
|
||||
// 编辑佩戴时间
|
||||
const editWearTime = (row: any, index: number) => {
|
||||
row.editingWearTime = true
|
||||
row.originalWeartime = row.weartime // 保存原始值
|
||||
}
|
||||
// 保存佩戴时间(传递时间戳)
|
||||
const saveWearTime = async (row: any, index: number) => {
|
||||
if (!row.weartime) {
|
||||
ElMessage.error('佩戴时间不能为空')
|
||||
return
|
||||
}
|
||||
try {
|
||||
const timestamp =
|
||||
typeof row.weartime === 'string' ? new Date(row.weartime).getTime() : row.weartime
|
||||
await arterialApi.updatearterial({ ...row, weartime: timestamp })
|
||||
row.weartime = timestamp // 本地同步为时间戳
|
||||
ElMessage.success('佩戴时间更新成功')
|
||||
row.editingWearTime = false
|
||||
getList()
|
||||
} catch (error) {
|
||||
console.error('更新佩戴时间失败:', error)
|
||||
ElMessage.error('更新佩戴时间失败,请重试')
|
||||
row.weartime = row.originalWeartime // 恢复原始值
|
||||
}
|
||||
}
|
||||
// 取消编辑佩戴时间
|
||||
const cancelEditWearTime = (row: any, index: number) => {
|
||||
row.weartime = row.originalWeartime
|
||||
row.editingWearTime = false
|
||||
}
|
||||
// 编辑设备
|
||||
const editDevice = (row: any, index: number) => {
|
||||
row.editingDevice = true
|
||||
row.originalDeviceId = row.deviceid // 保存原始值
|
||||
}
|
||||
// 保存设备
|
||||
const saveDevice = async (row: any, index: number) => {
|
||||
if (!row.deviceid) {
|
||||
ElMessage.error('设备不能为空')
|
||||
return
|
||||
}
|
||||
try {
|
||||
await arterialApi.updatearterial(row)
|
||||
ElMessage.success('设备更新成功')
|
||||
row.editingDevice = false
|
||||
getList()
|
||||
} catch (error) {
|
||||
console.error('更新设备失败:', error)
|
||||
ElMessage.error('更新设备失败,请重试')
|
||||
row.deviceid = row.originalDeviceId // 恢复原始值
|
||||
}
|
||||
}
|
||||
// 取消编辑设备
|
||||
const cancelEditDevice = (row: any, index: number) => {
|
||||
row.deviceid = row.originalDeviceId
|
||||
row.editingDevice = false
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.arteriosclerosis-analysis {
|
||||
padding: 24px;
|
||||
background: #f6f8fa;
|
||||
min-height: 100vh;
|
||||
}
|
||||
.filter-card {
|
||||
margin-bottom: 0;
|
||||
background: #fff;
|
||||
}
|
||||
.filter-form {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 8px 16px;
|
||||
}
|
||||
.table-card {
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue
Block a user