From bfb6ee5b32c8a27d2d56076944bdcd071d09a083 Mon Sep 17 00:00:00 2001 From: Flow <958079825@qq.com> Date: Mon, 28 Jul 2025 10:53:06 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A8=E6=80=81=E8=A1=80=E5=8E=8B=E5=8F=82?= =?UTF-8?q?=E8=80=83=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/analysis/ABPM/analysis.vue | 293 ++++++++++++++++++++++++--- 1 file changed, 268 insertions(+), 25 deletions(-) diff --git a/src/views/analysis/ABPM/analysis.vue b/src/views/analysis/ABPM/analysis.vue index 2e40a12..966ef2d 100644 --- a/src/views/analysis/ABPM/analysis.vue +++ b/src/views/analysis/ABPM/analysis.vue @@ -218,8 +218,10 @@ import { Loading, Delete } from '@element-plus/icons-vue' import { ElMessageBox, ElMessage } from 'element-plus' import { AbpmdataApi } from '@/api/abpmdata' import { abpmApi } from '@/api/abpm' +import { ThresholdsApi } from '@/api/system/thresholds' import dayjs from 'dayjs' import { formatDate } from '@/utils/formatTime' +import { getUserProfile } from '@/api/system/user/profile' // 控制弹窗显示 const visible = ref(false) @@ -268,6 +270,138 @@ const patientData = reactive({ // 分析结果内容 - 清空测试内容 const analysisResult = ref('') +// 阈值配置数据 +const thresholds = ref({}) + +// 默认阈值配置 +const defaultThresholds = { + // 血压分级阈值 + bp_normal_systolic: 120, + bp_normal_diastolic: 80, + bp_mild_systolic: 140, + bp_mild_diastolic: 90, + bp_moderate_systolic: 180, + bp_moderate_diastolic: 110, + + // 整天血压正常值 + bp_all_day_systolic: 130, + bp_all_day_diastolic: 80, + + // 白天血压正常值 + bp_daytime_systolic: 135, + bp_daytime_diastolic: 85, + + // 夜间血压正常值 + bp_nighttime_systolic: 120, + bp_nighttime_diastolic: 70, + + // 血压负荷正常范围 + bp_load_min: 5, + bp_load_max: 15, + + // 夜间血压下降正常范围 + bp_drop_min: 10, + bp_drop_max: 20, + + // 血压负荷阈值 + bp_load_total_systolic: 140, + bp_load_total_diastolic: 90, + bp_load_daytime_systolic: 135, + bp_load_daytime_diastolic: 85, + bp_load_nighttime_systolic: 120, + bp_load_nighttime_diastolic: 70 +} + +// 加载阈值配置 +const loadThresholds = async (orgid: number) => { + try { + const userinfo = await getUserProfile() + if (userinfo) { + orgid = userinfo.orgid + } + const res = await ThresholdsApi.getThresholdsByOrgId(orgid) + if (res && res && res.length > 0) { + // 解析按时间段分组的阈值数据 + const thresholdMap: any = {} + + res.forEach((periodGroup: any) => { + const periodType = periodGroup.periodType + const thresholdsList = periodGroup.thresholdsList || [] + + thresholdsList.forEach((threshold: any) => { + const metricType = threshold.metrictype + const key = `${periodType}_${metricType}` + thresholdMap[key] = { + minValue: threshold.minValue, + maxValue: threshold.maxValue, + unit: threshold.unit + } + }) + }) + + // 合并接口数据和默认值 + thresholds.value = { + // 血压分级阈值 - 使用全天的收缩压和舒张压阈值 + bp_normal_systolic: + thresholdMap['全天_收缩压']?.maxValue || defaultThresholds.bp_normal_systolic, + bp_normal_diastolic: + thresholdMap['全天_舒张压']?.maxValue || defaultThresholds.bp_normal_diastolic, + bp_mild_systolic: defaultThresholds.bp_mild_systolic, // 轻度高血压阈值保持默认 + bp_mild_diastolic: defaultThresholds.bp_mild_diastolic, + bp_moderate_systolic: defaultThresholds.bp_moderate_systolic, // 中度高血压阈值保持默认 + bp_moderate_diastolic: defaultThresholds.bp_moderate_diastolic, + + // 整天血压正常值 + bp_all_day_systolic: + thresholdMap['全天_收缩压']?.maxValue || defaultThresholds.bp_all_day_systolic, + bp_all_day_diastolic: + thresholdMap['全天_舒张压']?.maxValue || defaultThresholds.bp_all_day_diastolic, + + // 白天血压正常值 + bp_daytime_systolic: + thresholdMap['白天_收缩压']?.maxValue || defaultThresholds.bp_daytime_systolic, + bp_daytime_diastolic: + thresholdMap['白天_舒张压']?.maxValue || defaultThresholds.bp_daytime_diastolic, + + // 夜间血压正常值 + bp_nighttime_systolic: + thresholdMap['夜间_收缩压']?.maxValue || defaultThresholds.bp_nighttime_systolic, + bp_nighttime_diastolic: + thresholdMap['夜间_舒张压']?.maxValue || defaultThresholds.bp_nighttime_diastolic, + + // 血压负荷正常范围 - 保持默认值 + bp_load_min: defaultThresholds.bp_load_min, + bp_load_max: defaultThresholds.bp_load_max, + + // 夜间血压下降正常范围 - 保持默认值 + bp_drop_min: defaultThresholds.bp_drop_min, + bp_drop_max: defaultThresholds.bp_drop_max, + + // 血压负荷阈值 - 使用对应时间段的阈值 + bp_load_total_systolic: + thresholdMap['全天_收缩压']?.maxValue || defaultThresholds.bp_load_total_systolic, + bp_load_total_diastolic: + thresholdMap['全天_舒张压']?.maxValue || defaultThresholds.bp_load_total_diastolic, + bp_load_daytime_systolic: + thresholdMap['白天_收缩压']?.maxValue || defaultThresholds.bp_load_daytime_systolic, + bp_load_daytime_diastolic: + thresholdMap['白天_舒张压']?.maxValue || defaultThresholds.bp_load_daytime_diastolic, + bp_load_nighttime_systolic: + thresholdMap['夜间_收缩压']?.maxValue || defaultThresholds.bp_load_nighttime_systolic, + bp_load_nighttime_diastolic: + thresholdMap['夜间_舒张压']?.maxValue || defaultThresholds.bp_load_nighttime_diastolic + } + } else { + // 如果接口没有返回数据,使用默认配置 + thresholds.value = { ...defaultThresholds } + } + } catch (error) { + console.warn('加载阈值配置失败,使用默认配置:', error) + // 如果接口调用失败,使用默认配置 + thresholds.value = { ...defaultThresholds } + } +} + // 打开弹窗方法 - 增加数据参数 const open = async (rowData?: any) => { if (rowData) { @@ -281,6 +415,8 @@ const open = async (rowData?: any) => { loading.value = true try { + // 首先加载阈值配置 + await loadThresholds(rowData.orgid || 1) // 1. 首先通过条件查询获取ABPM记录ID const abpmPageRes = await abpmApi.getabpmPage({ examid: rowData.examid, @@ -632,9 +768,13 @@ const getGenderText = (gender: string) => { // 血压状态判断函数 const getBPStatus = (systolic: number, diastolic: number) => { - if (systolic < 120 && diastolic < 80) return '正常血压' - if (systolic < 140 && diastolic < 90) return '轻度高血压' - if (systolic < 180 && diastolic < 110) return '中度高血压' + const config = thresholds.value + if (systolic < config.bp_normal_systolic && diastolic < config.bp_normal_diastolic) + return '正常血压' + if (systolic < config.bp_mild_systolic && diastolic < config.bp_mild_diastolic) + return '轻度高血压' + if (systolic < config.bp_moderate_systolic && diastolic < config.bp_moderate_diastolic) + return '中度高血压' return '重度高血压' } @@ -806,19 +946,24 @@ const generateAnalysisReport = (rawList: any[]) => { const nighttimeMeanPressure = Math.round((nighttimeSystolic + 2 * nighttimeDiastolic) / 3) // 计算血压负荷(异常血压占比) + const config = thresholds.value const totalSystolicLoad = ( - (systolicValues.filter((v) => v >= 140).length / systolicValues.length) * + (systolicValues.filter((v) => v >= config.bp_load_total_systolic).length / + systolicValues.length) * 100 ).toFixed(2) const totalDiastolicLoad = ( - (diastolicValues.filter((v) => v >= 90).length / diastolicValues.length) * + (diastolicValues.filter((v) => v >= config.bp_load_total_diastolic).length / + diastolicValues.length) * 100 ).toFixed(2) const daytimeSystolicLoad = daytimeData.length > 0 ? ( - (daytimeData.filter((item) => (Number(item.systolicpressure) || 0) >= 135).length / + (daytimeData.filter( + (item) => (Number(item.systolicpressure) || 0) >= config.bp_load_daytime_systolic + ).length / daytimeData.length) * 100 ).toFixed(2) @@ -826,7 +971,9 @@ const generateAnalysisReport = (rawList: any[]) => { const daytimeDiastolicLoad = daytimeData.length > 0 ? ( - (daytimeData.filter((item) => (Number(item.diastolicpressure) || 0) >= 85).length / + (daytimeData.filter( + (item) => (Number(item.diastolicpressure) || 0) >= config.bp_load_daytime_diastolic + ).length / daytimeData.length) * 100 ).toFixed(2) @@ -835,7 +982,9 @@ const generateAnalysisReport = (rawList: any[]) => { const nighttimeSystolicLoad = nighttimeData.length > 0 ? ( - (nighttimeData.filter((item) => (Number(item.systolicpressure) || 0) >= 120).length / + (nighttimeData.filter( + (item) => (Number(item.systolicpressure) || 0) >= config.bp_load_nighttime_systolic + ).length / nighttimeData.length) * 100 ).toFixed(2) @@ -843,7 +992,9 @@ const generateAnalysisReport = (rawList: any[]) => { const nighttimeDiastolicLoad = nighttimeData.length > 0 ? ( - (nighttimeData.filter((item) => (Number(item.diastolicpressure) || 0) >= 70).length / + (nighttimeData.filter( + (item) => (Number(item.diastolicpressure) || 0) >= config.bp_load_nighttime_diastolic + ).length / nighttimeData.length) * 100 ).toFixed(2) @@ -861,16 +1012,16 @@ const generateAnalysisReport = (rawList: any[]) => { // 判断杓型 const getSystolicDropType = (drop: number) => { - if (drop >= 10 && drop <= 20) return '杓型' - if (drop > 20) return '深杓型' - if (drop >= 0 && drop < 10) return '非杓型' + if (drop >= config.bp_drop_min && drop <= config.bp_drop_max) return '杓型' + if (drop > config.bp_drop_max) return '深杓型' + if (drop >= 0 && drop < config.bp_drop_min) return '非杓型' return '反杓型' } const getDiastolicDropType = (drop: number) => { - if (drop >= 10 && drop <= 20) return '杓型' - if (drop > 20) return '深杓型' - if (drop >= 0 && drop < 10) return '非杓型' + if (drop >= config.bp_drop_min && drop <= config.bp_drop_max) return '杓型' + if (drop > config.bp_drop_max) return '深杓型' + if (drop >= 0 && drop < config.bp_drop_min) return '非杓型' return '反杓型' } @@ -884,14 +1035,14 @@ const generateAnalysisReport = (rawList: any[]) => { } const getLoadStatusText = (load: number) => { - return load >= 5 && load <= 15 ? '正常' : '异常' + return load >= config.bp_load_min && load <= config.bp_load_max ? '正常' : '异常' } // 生成结论建议 const generateConclusion = () => { const issues: string[] = [] - if (avgSystolic >= 130 || avgDiastolic >= 80) { + if (avgSystolic >= config.bp_all_day_systolic || avgDiastolic >= config.bp_all_day_diastolic) { issues.push('全程平均血压轻度升高') } @@ -903,7 +1054,7 @@ const generateAnalysisReport = (rawList: any[]) => { issues.push('夜间血压负荷>40%') } - if (Number(systolicDrop) < 10 || Number(diastolicDrop) < 10) { + if (Number(systolicDrop) < config.bp_drop_min || Number(diastolicDrop) < config.bp_drop_min) { issues.push('夜间血压下降不足') } @@ -918,12 +1069,12 @@ const generateAnalysisReport = (rawList: any[]) => { return `全程检测血压次数${totalCount}次,有效次数${effectiveCount}次,有效率${effectiveRate}%; 最高收缩压${maxSystolic}mmHg,发生于${maxSystolicTime};最高舒张压${maxDiastolic}mmHg,发生于${maxDiastolicTime}; 最低收缩压${minSystolic}mmHg,发生于${minSystolicTime};最低舒张压${minDiastolic}mmHg,发生于${minDiastolicTime}; -整天血压平均值:收缩压${avgSystolic}mmHg(${getStatusText(avgSystolic, 130)}) (正常值<130mmHg);舒张压${avgDiastolic}mmHg(${getStatusText(avgDiastolic, 80)}) (正常值<80mmHg);平均压${avgMeanPressure}mmHg; -白天血压平均值:收缩压${daytimeSystolic}mmHg(${getStatusText(daytimeSystolic, 135)}) (正常值<135mmHg);舒张压${daytimeDiastolic}mmHg(${getStatusText(daytimeDiastolic, 85)}) (正常值<85mmHg);平均压${daytimeMeanPressure}mmHg; -夜间血压平均值:收缩压${nighttimeSystolic}mmHg(${getStatusText(nighttimeSystolic, 120)}) (正常值<120mmHg);舒张压${nighttimeDiastolic}mmHg(${getStatusText(nighttimeDiastolic, 70)}) (正常值<70mmHg);平均压${nighttimeMeanPressure}mmHg; -收缩压负荷:整天${totalSystolicLoad}% (${getLoadStatusText(Number(totalSystolicLoad))})(正常范围5%-15%); 白天${daytimeSystolicLoad}% (${getLoadStatusText(Number(daytimeSystolicLoad))})(正常范围5%-15%);夜间${nighttimeSystolicLoad}% (${getLoadStatusText(Number(nighttimeSystolicLoad))})(正常范围5%-15%); -舒张压负荷:整天${totalDiastolicLoad}% (${getLoadStatusText(Number(totalDiastolicLoad))})(正常范围5%-15%); 白天${daytimeDiastolicLoad}% (${getLoadStatusText(Number(daytimeDiastolicLoad))})(正常范围5%-15%);夜间${nighttimeDiastolicLoad}% (${getLoadStatusText(Number(nighttimeDiastolicLoad))})(正常范围5%-15%); -夜间比白天血压下降:收缩压${systolicDrop}% (${getSystolicDropType(Number(systolicDrop))}) (正常值 10%-20%);舒张压${diastolicDrop}% (${getDiastolicDropType(Number(diastolicDrop))}) (正常值 10%-20%); +整天血压平均值:收缩压${avgSystolic}mmHg(${getStatusText(avgSystolic, config.bp_all_day_systolic)}) (正常值<${config.bp_all_day_systolic}mmHg);舒张压${avgDiastolic}mmHg(${getStatusText(avgDiastolic, config.bp_all_day_diastolic)}) (正常值<${config.bp_all_day_diastolic}mmHg);平均压${avgMeanPressure}mmHg; +白天血压平均值:收缩压${daytimeSystolic}mmHg(${getStatusText(daytimeSystolic, config.bp_daytime_systolic)}) (正常值<${config.bp_daytime_systolic}mmHg);舒张压${daytimeDiastolic}mmHg(${getStatusText(daytimeDiastolic, config.bp_daytime_diastolic)}) (正常值<${config.bp_daytime_diastolic}mmHg);平均压${daytimeMeanPressure}mmHg; +夜间血压平均值:收缩压${nighttimeSystolic}mmHg(${getStatusText(nighttimeSystolic, config.bp_nighttime_systolic)}) (正常值<${config.bp_nighttime_systolic}mmHg);舒张压${nighttimeDiastolic}mmHg(${getStatusText(nighttimeDiastolic, config.bp_nighttime_diastolic)}) (正常值<${config.bp_nighttime_diastolic}mmHg);平均压${nighttimeMeanPressure}mmHg; +收缩压负荷:整天${totalSystolicLoad}% (${getLoadStatusText(Number(totalSystolicLoad))})(正常范围${config.bp_load_min}%-${config.bp_load_max}%); 白天${daytimeSystolicLoad}% (${getLoadStatusText(Number(daytimeSystolicLoad))})(正常范围${config.bp_load_min}%-${config.bp_load_max}%);夜间${nighttimeSystolicLoad}% (${getLoadStatusText(Number(nighttimeSystolicLoad))})(正常范围${config.bp_load_min}%-${config.bp_load_max}%); +舒张压负荷:整天${totalDiastolicLoad}% (${getLoadStatusText(Number(totalDiastolicLoad))})(正常范围${config.bp_load_min}%-${config.bp_load_max}%); 白天${daytimeDiastolicLoad}% (${getLoadStatusText(Number(daytimeDiastolicLoad))})(正常范围${config.bp_load_min}%-${config.bp_load_max}%);夜间${nighttimeDiastolicLoad}% (${getLoadStatusText(Number(nighttimeDiastolicLoad))})(正常范围${config.bp_load_min}%-${config.bp_load_max}%); +夜间比白天血压下降:收缩压${systolicDrop}% (${getSystolicDropType(Number(systolicDrop))}) (正常值 ${config.bp_drop_min}%-${config.bp_drop_max}%);舒张压${diastolicDrop}% (${getDiastolicDropType(Number(diastolicDrop))}) (正常值 ${config.bp_drop_min}%-${config.bp_drop_max}%); ${generateConclusion()}` } @@ -1195,13 +1346,105 @@ const clearAllData = () => { analysisResult.value = '暂无数据,无法生成分析报告' } +// 计算饼图统计数据 +const calculatePieChartStats = () => { + const data = chartDataTable.value + if (!data || data.length === 0) { + return { + systolic: { + day: { normal: 0, abnormal: 0 }, + night: { normal: 0, abnormal: 0 }, + allDay: { normal: 0, abnormal: 0 } + }, + diastolic: { + day: { normal: 0, abnormal: 0 }, + night: { normal: 0, abnormal: 0 }, + allDay: { normal: 0, abnormal: 0 } + }, + heartRate: { + day: { normal: 0, abnormal: 0 }, + night: { normal: 0, abnormal: 0 }, + allDay: { normal: 0, abnormal: 0 } + } + } + } + + // 时间分割函数 + const isDaytime = (timeStr: string) => { + const hour = parseInt(timeStr.split(':')[0]) + return hour >= 8 && hour < 22 + } + + // 分类数据 + const daytimeData = data.filter((item) => isDaytime(item.time)) + const nighttimeData = data.filter((item) => !isDaytime(item.time)) + + // 计算统计函数 + const calculateStats = (dataSet: any[], type: 'systolic' | 'diastolic' | 'heartRate') => { + let normalCount = 0 + let abnormalCount = 0 + + dataSet.forEach((item) => { + let value: number + let isNormal = false + + if (type === 'systolic') { + value = item.systolic + // 白天: 90-140, 夜间: 80-120 + const isDayTime = isDaytime(item.time) + isNormal = isDayTime ? value >= 90 && value <= 140 : value >= 80 && value <= 120 + } else if (type === 'diastolic') { + value = item.diastolic + // 白天: 65-90, 夜间: 55-80 + const isDayTime = isDaytime(item.time) + isNormal = isDayTime ? value >= 65 && value <= 90 : value >= 55 && value <= 80 + } else { + // heartRate + value = item.heartRate + // 心率: 50-90 + isNormal = value >= 50 && value <= 90 + } + + if (isNormal) { + normalCount++ + } else { + abnormalCount++ + } + }) + + return { normal: normalCount, abnormal: abnormalCount } + } + + return { + systolic: { + day: calculateStats(daytimeData, 'systolic'), + night: calculateStats(nighttimeData, 'systolic'), + allDay: calculateStats(data, 'systolic') + }, + diastolic: { + day: calculateStats(daytimeData, 'diastolic'), + night: calculateStats(nighttimeData, 'diastolic'), + allDay: calculateStats(data, 'diastolic') + }, + heartRate: { + day: calculateStats(daytimeData, 'heartRate'), + night: calculateStats(nighttimeData, 'heartRate'), + allDay: calculateStats(data, 'heartRate') + } + } +} + // 处理报告预览 const handleReportPreview = () => { + // 计算饼图统计数据 + const pieChartStats = calculatePieChartStats() + // 构造要传递的数据 const reportData = { patientData: patientData, chartDataTable: chartDataTable.value, - analysisResult: analysisResult.value + analysisResult: analysisResult.value, + pieChartStats: pieChartStats } // 打开新窗口并全屏展示 abpm-report-template.html (注意路径不包含public)