ecg-form/src/views/ECG/ECGForm.vue
2025-05-20 10:45:12 +08:00

1370 lines
47 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<el-dialog
:title="dialogTitle"
v-model="dialogVisible"
:fullscreen="true"
append-to-body
:close-on-click-modal="false"
:close-on-press-escape="false"
:destroy-on-close="true"
@close="
() => {
isshowwjz = false
isshowysb = false
isChildVisible = false
}
"
>
<div id="ECGForm_main" class="mycontainer" v-loading="loading">
<div class="myleft-box">
<el-container>
<!--头部 患者信息-->
<el-header
style="background-color: rgb(79, 138, 240); border-radius: 8px 0 0 0; height: 40px"
>
<div style="font-size: 20px; color: aliceblue; margin-top: 6px; margin-left: -10px">
<span>{{ rowinfo.pname }}</span>
<span style="margin-left: 10px"> {{ rowinfo.gender }}</span>
<!-- <span style="margin-left: 10px"> {{ age + '岁' }}</span> -->
<span style="margin-left: 10px"> 检查编号:{{ rowinfo.examId }}</span>
<span style="margin-left: 10px">
检查日期:{{ rowinfo.examDate ? formatDate(new Date(rowinfo.examDate), 'YYYY-MM-DD') : '' }}</span
>
<span style="margin-left: 10px">检查机构: {{ rowinfo.orgName }}</span>
</div>
</el-header>
<!--头部 功能按钮-->
<el-header style="height: 40px; padding: 0px; margin: 2px 5.2px">
<el-button-group class="ml-4" style="margin-top: 4px; margin-left: 0px">
<el-popover placement="bottom" :width="250" trigger="click" :disabled="isshare">
<div style="display: flex; flex-direction: column; align-items: center">
<canvas ref="qrcodeRef" width="200" height="200"></canvas>
<el-button
type="primary"
style="margin-top: 10px; width: 120px"
@click="touchCopy"
>复制链接</el-button
>
</div>
<template #reference>
<el-button type="primary" plain :icon="Share" @click="shareclick()"
>分享</el-button
>
</template>
</el-popover>
<el-button
type="primary"
plain
:icon="Edit"
@click="getuporghiorgid(Primarykey, orgid)"
>申请诊断</el-button
>
<el-button type="primary" plain @click="print"
><el-icon><Printer /></el-icon>打印</el-button
>
<el-button type="primary" plain @click="ECGApplyDialog"
><el-icon><User /></el-icon>申请返修</el-button
>
<el-button type="primary" plain @click="process"
><el-icon><Edit /></el-icon>审核</el-button
>
<el-button type="primary" plain @click="openECGDialog" v-if="isshowwjz"
><el-icon><Warning /></el-icon>危急值</el-button
>
<el-button type="danger" plain @click="openreprotdiag" v-if="isshowysb"
><el-icon><Check /></el-icon>已上报</el-button
>
</el-button-group>
</el-header>
<el-container>
<!--左侧 心电图区域-->
<el-aside width="96%" style="height: 81vh">
<el-tabs type="border-card" style="height: 99%">
<el-tab-pane :label="snapshotTime">
<!--心电图-->
<ECGhtml
v-if="isChildVisible"
:jsonurl="queryParams.ecgJsonDataFilePath"
:-isgrid="Isgrid"
:-ismeasure="Ismeasure"
:-isfd="IsFD"
:lineratio="lineratio"
:suduratio="suduratio"
:isrefresh="isrefresh"
:iscorrect="correct"
@update:value="handleUpdate"
/>
<ECGPicture v-if="isPictureVisible" :jsonurl="queryParams.ecgJsonDataFilePath" />
</el-tab-pane>
</el-tabs>
</el-aside>
<!--右侧 功能按钮-->
<el-main style="padding: 1px">
<div
style="margin-top: 30px; display: flex; flex-direction: column; align-items: center"
>
<el-dropdown placement="bottom" trigger="click" @command="handlezsCommand">
<el-button
style="width: 30px; height: 30px; margin-bottom: 10px"
type="primary"
plain
:disabled="buttonDisabled"
>
<el-icon><Odometer /></el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="0.2">5mm/s</el-dropdown-item>
<el-dropdown-item command="0.4">10mm/s</el-dropdown-item>
<el-dropdown-item command="0.5">12.5mm/s</el-dropdown-item>
<el-dropdown-item command="1">25mm/s</el-dropdown-item>
<el-dropdown-item command="2">50mm/s</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<span style="font-size: 15px; margin-bottom: 10px">走速</span>
<el-dropdown placement="bottom" trigger="click" @command="handleCommand">
<el-button
style="width: 30px; height: 30px; margin-bottom: 10px"
type="primary"
plain
:disabled="buttonDisabled"
>
<el-icon><Histogram /></el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="0.012">2.5mm/mv</el-dropdown-item>
<el-dropdown-item command="0.025">5mm/mv</el-dropdown-item>
<el-dropdown-item command="0.05">10mm/mv</el-dropdown-item>
<el-dropdown-item command="0.1">20mm/mv</el-dropdown-item>
<el-dropdown-item command="0.2">40mm/mv</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<span style="font-size: 15px; margin-bottom: 10px">振幅</span>
<el-button
style="width: 30px; height: 30px; margin-bottom: 10px"
type="primary"
plain
:disabled="buttonDisabled"
@click="measure()"
>
<el-icon><EditPen /></el-icon>
</el-button>
<span style="font-size: 15px; margin-bottom: 10px">测量</span>
<el-button
style="width: 30px; height: 30px; margin-bottom: 10px"
type="primary"
plain
:disabled="buttonDisabled"
@click="FD()"
>
<el-icon><ZoomIn /></el-icon>
</el-button>
<span style="font-size: 15px; margin-bottom: 10px">放大</span>
<el-button
style="width: 30px; height: 30px; margin-bottom: 10px"
type="primary"
plain
:disabled="buttonDisabled"
@click="iscorrect()"
>
<el-icon><Switch /></el-icon>
</el-button>
<span style="font-size: 15px; margin-bottom: 10px">纠错</span>
<el-button
style="width: 30px; height: 30px; margin-bottom: 10px"
type="primary"
plain
:disabled="buttonDisabled"
@click="Isgriddisplay()"
>
<el-icon><Grid /></el-icon>
</el-button>
<span style="font-size: 15px; margin-bottom: 10px">网格</span>
<el-button
style="width: 30px; height: 30px; margin-bottom: 10px"
type="primary"
plain
:disabled="buttonDisabled"
@click="Refresh"
>
<el-icon><RefreshRight /></el-icon>
</el-button>
<span style="font-size: 15px; margin-bottom: 10px">刷新</span>
<el-button
style="width: 30px; height: 30px; margin-bottom: 10px"
type="primary"
plain
:disabled="buttonDisabled"
@click="opencomparediag"
>
<el-icon><Reading /></el-icon>
</el-button>
<span style="font-size: 15px; margin-bottom: 10px">对比</span>
</div>
</el-main>
</el-container>
</el-container>
</div>
<div class="myright-box">
<el-form
id="elform"
:model="queryParams"
label-width="63.4px"
style="
max-width: 600px;
margin-top: 6px;
margin-left: 5px;
margin-right: 5px;
margin-bottom: 9px;
min-height: 88vh;
"
>
<!-- 第一行 -->
<el-row style="margin-right: 1px; height: 35px">
<el-col :span="12" class="-ml-1px pr-9px">
<el-form-item label="心率">
<el-input v-model="queryParams.hr" class="w-100%">
<template #append>
<div class="-ml-20px -mr-20px">bpm</div>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="P电轴">
<el-input v-model="queryParams.paxle" class="w-100%">
<template #append>
<div class="-ml-20px -mr-20px">°</div>
</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
<!-- 第二行 -->
<el-row style="margin-right: 1px; height: 35px">
<el-col :span="12" class="-ml-1px pr-9px">
<el-form-item label="QRS电轴">
<el-input v-model="queryParams.qrsAxle" class="w-100%">
<template #append>
<div class="-ml-20px -mr-20px">°</div>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="T电轴">
<el-input v-model="queryParams.taxle" class="w-100%">
<template #append>
<div class="-ml-20px -mr-20px">°</div>
</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
<!-- 第三行 -->
<el-row style="margin-right: 1px; height: 35px">
<el-col :span="12" class="-ml-1px pr-9px">
<el-form-item label="P波时限">
<el-input v-model="queryParams.ptimeLimit" class="w-100%">
<template #append>
<div class="-ml-20px -mr-20px">ms</div>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="PR间期">
<el-input v-model="queryParams.pr" class="w-100%">
<template #append>
<div class="-ml-20px -mr-20px">ms</div>
</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
<!-- 第四行 -->
<el-row style="margin-right: 1px; height: 35px">
<el-col :span="12" class="-ml-1px pr-9px">
<el-form-item label="QRS时限">
<el-input v-model="queryParams.qrsTimeLimit" class="w-100%">
<template #append>
<div class="-ml-20px -mr-20px">ms</div>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="QT间期">
<el-input v-model="queryParams.qt" class="w-100%">
<template #append>
<div class="-ml-20px -mr-20px">ms</div>
</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
<!-- 第五行 -->
<el-row style="margin-right: 1px; height: 35px">
<el-col :span="12" class="-ml-1px pr-9px">
<el-form-item label="QTc">
<el-input v-model="queryParams.qtc" class="w-100%">
<template #append>
<div class="-ml-20px -mr-20px">ms</div>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="RV5">
<el-input v-model="queryParams.rv5" class="w-100%">
<template #append>
<div class="-ml-20px -mr-20px">mV</div>
</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
<!-- 第六行 -->
<el-row style="margin-right: 1px; margin-bottom: 5.2px; height: 35px">
<el-col :span="12" class="-ml-1px pr-9px">
<el-form-item label="SV1">
<el-input v-model="queryParams.sv1" class="w-100%">
<template #append>
<div class="-ml-20px -mr-20px">mV</div>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="RV5+SV1">
<el-input v-model="queryParams.rv5Sv1" class="w-100%">
<template #append>
<div class="-ml-20px -mr-20px">mV</div>
</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-tag
type="info"
style="justify-content: left; font-size: 16px; width: 100%; color: black"
>
<span class="ml-2px">心电事件快照</span>
</el-tag>
<el-input
v-model="snapshotTime"
style="width: 100%"
:rows="4"
type="textarea"
placeholder=""
/>
<el-tag
type="info"
style="justify-content: left; font-size: 16px; width: 100%; color: black"
>
<span class="ml-2px">智能词库</span>
</el-tag>
<el-input
v-model="queryParams.autoDiagResult"
style="width: 100%"
:rows="4"
type="textarea"
placeholder=""
/>
<el-tag
type="info"
style="justify-content: left; font-size: 16px; width: 100%; color: black"
>
<span class="ml-2px">
<span style="vertical-align: middle">医生诊断结论</span>
<el-button @click="zdmodle" type="text" class="ml-18px">诊断模版</el-button>
</span>
</el-tag>
<el-input
class="your-component"
v-model="queryParams.doctorDiagResult"
style="width: 100%"
type="textarea"
placeholder=""
ref="inputRef"
:rows="eltextrow"
/>
<div class="mybtnsty">
<div>
<el-button class="mybutwidth" type="warning" @click="insertValue('I')">I</el-button>
<el-button class="mybutwidth" type="warning" @click="insertValue('II')">II</el-button>
<el-button class="mybutwidth" type="warning" @click="insertValue('III')">
III
</el-button>
<el-button class="mybutwidth" type="warning" @click="insertValue('aVR')">
aVR
</el-button>
<el-button class="mybutwidth" type="warning" @click="insertValue('aVL')">
aVL
</el-button>
<el-button class="mybutwidth" type="warning" @click="insertValue('aVF')">
aVF
</el-button>
</div>
<div>
<el-button class="mybutwidth" type="warning" @click="insertValue('V3R')">
V3R
</el-button>
<el-button class="mybutwidth" type="warning" @click="insertValue('V4R')">
V4R
</el-button>
<el-button class="mybutwidth" type="warning" @click="insertValue('V5R')">
V5R
</el-button>
<el-button class="mybutwidth" type="warning" @click="insertValue('V1')">V1</el-button>
<el-button class="mybutwidth" type="warning" @click="insertValue('V2')">V2</el-button>
<el-button class="mybutwidth" type="warning" @click="insertValue('V3')">V3</el-button>
</div>
<div>
<el-button class="mybutwidth" type="warning" @click="insertValue('V4')">V4</el-button>
<el-button class="mybutwidth" type="warning" @click="insertValue('V5')">V5</el-button>
<el-button class="mybutwidth" type="warning" @click="insertValue('V6')">V6</el-button>
<el-button class="mybutwidth" type="warning" @click="insertValue('V7')">V7</el-button>
<el-button class="mybutwidth" type="warning" @click="insertValue('V8')">V8</el-button>
<el-button class="mybutwidth" type="warning" @click="insertValue('V9')">V9</el-button>
</div>
</div>
<div class="mycenter-button">
<el-button
style="width: 200px"
type="primary"
@click="getuporghiorgid(Primarykey, orgid)"
>
申请诊断
</el-button>
<el-button style="width: 200px" type="primary" @click="save" :disabled="savedisabled">
保存
</el-button>
</div>
</el-form>
</div>
</div>
</el-dialog>
<el-drawer v-model="drawer" :with-header="false" :modal="true" size="23.02%">
<div style="position: relative; z-index: 100">
<el-button link @click="drawer = false" style="position: absolute; top: -6px; right: -2px">
<Icon icon="ep:close" />
</el-button>
</div>
<span>诊断数据模版</span>
<div class="h-90.78vh">
<el-scrollbar>
<el-tree
style="padding-top: 15px; padding-bottom: 20px; min-width: 195px; font-size: 20px"
class="treeStyle"
:check-on-click-node="true"
:highlight-current="true"
:default-expand-all="true"
:data="treeData"
:props="treeDefaultProps"
node-key="id"
:show-checkbox="false"
:check-strictly="true"
@check="handleTreeNodeClick"
ref="selectTree"
:expand-on-click-node="false"
/>
</el-scrollbar>
</div>
</el-drawer>
<el-dialog
title=""
v-model="isdiagshow"
:fullscreen="true"
append-to-body
:close-on-click-modal="false"
:close-on-press-escape="false"
:destroy-on-close="true"
@close="printclose"
>
<!--打印弹窗(老)-->
<ECGprint :imagebase64="imagebase64" />
</el-dialog>
<div style="position: fixed; top: 0; left: 0; z-index: -100">
<div id="hiddenPdfDiv" v-if="false && isprintimage">
<!--心电图-->
<ECGhtmlprint
style="height: 1080px; width: 1920px; page-break-after: always; visibility: hidden"
:extraInfo="queryParams"
:jsonurl="queryParams.ecgJsonDataFilePath"
:-isgrid="Isgrid"
:-ismeasure="Ismeasure"
:-isfd="IsFD"
:lineratio="0.025"
:suduratio="suduratio"
:isrefresh="isrefresh"
:iscorrect="correct"
@update:value="handleUpdate"
:printimage="isprintimage"
@update:image="updateimagebase"
:age="age"
:billDoctorDepartment="rowinfo.billDoctorDepartment"
:doctorname="rowinfo.doctorname"
:regId="id"
:pname="rowinfo.pname"
:gender="rowinfo.gender"
/>
</div>
</div>
<el-dialog
v-model="isdiagshow"
:fullscreen="true"
append-to-body
:close-on-click-modal="false"
:destroy-on-close="true"
@closed="printclose"
>
<!--打印弹窗(新)-->
<template #title>
<div
style="
margin-bottom: -18px;
text-align: center;
font-family: Arial, sans-serif;
color: #6e6666;
font-size: 24px;
"
>
打印预览
</div>
</template>
<div>
<div style="text-align: right">
<el-button
v-if="false"
type="primary"
style="width: 90px"
v-print="{ id: 'printMe_ecg' }"
:loading="!imagebase64_new"
>
<span>打印</span>
</el-button>
</div>
<el-divider style="margin-top: 8px; margin-bottom: 1px" />
</div>
<div id="printMe_ecg">
<div class="page-item-ecg">
<ReportInfoECG
v-if="false"
style="height: 99.888%"
:extraInfo="queryParams"
:jsonurl="queryParams.ecgJsonDataFilePath"
:lineratio="0.025"
:suduratio="suduratio"
:age="age"
:billDoctorDepartment="rowinfo.billDoctorDepartment"
:doctorname="rowinfo.doctorname"
:regId="id"
:orgName="rowinfo.orgName"
:pname="rowinfo.pname"
:gender="rowinfo.gender"
/>
<el-image
v-if="false"
alt=""
fit="fill"
loading="eager"
:style="{
width: '100%',
imageRendering: 'high-quality',
minHeight: imagebase64_new ? '0' : '68vh'
}"
:src="imagebase64_new"
crossorigin="anonymous"
v-loading="!imagebase64_new"
>
<template #error>
<div style="text-align: center; font-size: 20px; margin-top: 6vh">加载中...</div>
</template>
</el-image>
<div v-loading="!imagebase64_new" element-loading-text="加载中...">
<el-image :src="imagebase64_new"/>
<!-- <iframe
v-if="true"
id="pdf_view"
name="pdf_view"
:src="imagebase64_new ? imagebase64_new + '#view=Fit&navpanes=0' : 'about:blank'"
frameborder="0"
class="pdf_view"
width="100%"
height="100%"
></iframe>-->
</div>
</div>
</div>
</el-dialog>
<div style="position: fixed; top: 0; left: 0; z-index: -1100">
<!-- html2canvas处理时宽/高不确定可能导致异常效果,可以增加相应宽/高,或者固定宽高尺寸 -->
<div v-if="isprintimage" id="ecg_pdf" class="page-pdf-ecg">
<ReportInfoECG
style="height: 99.888%"
:isBackend="true"
:createPdf="updateimagebase_new"
:extraInfo="queryParams"
:jsonurl="queryParams.ecgJsonDataFilePath"
:lineratio="0.025"
:suduratio="suduratio"
:age="age"
:billDoctorDepartment="rowinfo.billDoctorDepartment"
:doctorname="rowinfo.doctorname"
:regId="id"
:orgName="rowinfo.orgName"
:pname="rowinfo.pname"
:gender="rowinfo.gender"
/>
</div>
</div>
<ECGWarningDialog ref="ECGDialog" />
<ECGReport ref="ECGReportDialog" />
<ECGCopmareDialog ref="ECGCompare" />
<ECGApplyforRepair ref="ECGApply" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { ArrowLeft, ArrowRight, Delete, Edit, Share, Check } from '@element-plus/icons-vue'
import ECGhtml from '@/views/ECG/ECGhtml.vue'
import ECGhtmlprint from '@/views/ECG/ECGhtmlprint.vue'
import ECGPicture from '@/views/ECG/ECGPicture.vue'
import { EcganalysisparasApi, EcganalysisparasVO } from '@/api/tblist/ecganalysisparas'
import { formatDate } from '@/utils/formatTime'
import { getUserProfile, ProfileVO } from '@/api/system/user/profile'
import { ultrasoniccomApi, updateexamineimageVO } from '@/api/ultrasoniccom'
import { PatientexamlistApi, PatientexamlistVO } from '@/api/tblist/patientexamlist'
import QRCode from 'qrcode'
import ECGprint from '@/views/ECG/ECGprint.vue'
import ReportInfoECG from '@/views/applyregistration/reportPrintStatistics/ReportInfoECG.vue'
import htmlToPdf from '@/utils/htmlPdf'
import ECGWarningDialog from '@/views/ECG/ECGWaring/ECGWarningDialog.vue'
import ECGReport from '@/views/ECG/ECGWaring/ECGReport.vue'
import { WarningApi, WarningVO } from '@/api/system/warning'
import ECGCopmareDialog from '@/views/ECG/ECGCompare.vue'
import ECGApplyforRepair from '@/views/ECG/ECGModify/ECGApplyforRepair.vue'
import useClipboard from 'vue-clipboard3' //复制组件
import ECGSB from '@/views/ECG/ECGSB.vue'
import { ElLoading } from 'element-plus'
import { log } from 'console'
import { processImageApi } from '@/api/processImage'
const { toClipboard } = useClipboard()
const emit = defineEmits(['success']) // 定义 success 事件用于操作成功后的回调
const message = useMessage() // 消息弹窗
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const id = ref() //患者ID
const orgid = ref() //机构编码
const Primarykey = ref() //主键ID
const rowinfo = ref<any>({}) //当前患者数据行
const snapshotTime = ref() //心电事件快照事件
const isChildVisible = ref(false)
const inputRef = ref() // 用于获取el-input的DOM引用
const saveFormVO = ref<EcganalysisparasVO>({} as EcganalysisparasVO)
//基本信息
const applyFormVO = ref<PatientexamlistVO>({} as PatientexamlistVO)
const examineFormVO = ref<PatientexamlistVO>({} as PatientexamlistVO)
const Profilevo = ref<ProfileVO>({} as ProfileVO) //当前登录人信息
const age = ref() //年龄
const Isgrid = ref(1) //是否显示网格 1显示 0不显示
const Ismeasure = ref(0) //是否开启测量 1开启 0 不开启
const IsFD = ref(false) //是否开启放大
const lineratio = ref(0.05) //画线的系数 振幅
const suduratio = ref(1) //画线的系数 走速
const drawer = ref(false) //是否显示抽屉
const diagnosemodel = ref() //存放诊断模版
const isrefresh = ref(false) //是否刷新
const correct = ref(false) //纠错功能
const eltextrow = ref(4) //诊断内容占据的行
const isshare = ref(true) //是否展示分享二维码
const qrcodeRef = ref(null)
const isdiagshow = ref(false) //是否显示打印窗体
const imagebase64 = ref('')
const imagebase64_new = ref<any>('')
const isprintimage = ref(false) //是否生成打印文件base64
const ECGDialog = ref() //危急值消息弹窗
const isshowwjz = ref(false)
const isshowysb = ref(false)
const ECGReportDialog = ref() //危急值消息弹窗
const ECGCompare = ref() //心电图对比弹窗
const ECGApply = ref() //申请返修弹窗
const keyid = ref() //当前数据行的主键ID
const savedisabled = ref(false) //保存按钮是否可用
const isPictureVisible = ref(false) //是否显示图片
const loading = ref(false) // 点击审核后的加载
// 树配置项
const treeDefaultProps = {
children: 'children',
label: 'tempname'
}
// 通用树数据
const treeData = ref([])
// 添加按钮禁用状态控制
const buttonDisabled = ref(false)
// 可以添加一个方法来统一控制按钮状态
const setButtonsDisabled = (disabled: boolean) => {
buttonDisabled.value = disabled
}
/** 打开弹窗 */
const open = async (row: any) => {
dialogVisible.value = true
dialogTitle.value = '心电分析'
resetForm()
id.value = row.regId
keyid.value = row.id
Primarykey.value = row.id
orgid.value = row.orgId
rowinfo.value = row
const data = await EcganalysisparasApi.getexamIDdata(rowinfo.value.examId, orgid.value)
queryParams.value = data
console.log(data)
console.log(queryParams.value)
if (
queryParams.value.ecgJsonDataFilePath &&
(queryParams.value.ecgJsonDataFilePath.toUpperCase().endsWith('.BMP') ||
queryParams.value.ecgJsonDataFilePath.toUpperCase().endsWith('.JPG') ||
queryParams.value.ecgJsonDataFilePath.toUpperCase().endsWith('.PNG'))
) {
isPictureVisible.value = true
isChildVisible.value = false
setButtonsDisabled(true) //右侧功能按钮不可用
} else if (
queryParams.value.ecgJsonDataFilePath &&
queryParams.value.ecgJsonDataFilePath.toUpperCase().endsWith('.TXT')
) {
isChildVisible.value = true
isPictureVisible.value = false
setButtonsDisabled(false) //右侧功能按钮可用
} else {
isChildVisible.value = false
isPictureVisible.value = false
setButtonsDisabled(true) //右侧功能按钮不可用
ElMessage.warning('数据格式有误')
return
}
// snapshotTime.value = formattedDate(queryParams.value.snapshotTime)
snapshotTime.value = queryParams.value.snapshotTime ? formatDate(new Date(queryParams.value.snapshotTime), 'YYYY-MM-DD') : ''
await getlogininfo()
await getPatientexamlist(keyid.value)
calculateAge(row.birthday)
Isgrid.value = 1 // 没次打开都是显示的 只有点击网格才会变化
nextTick(() => {
/* 计算右侧诊断*/
const canvasContainer = document.getElementById('elform')
if (canvasContainer) {
let sl = 300
const heightInPixels = canvasContainer.offsetHeight
if (heightInPixels > 1000) {
sl = -100
}
const divisor = 60 // 假设你想除以的数是2
const result = (heightInPixels - sl) / divisor
const integer = Math.round(result)
eltextrow.value = integer
}
})
//查询当前患者的危急值相关信息
const warningdata = await WarningApi.getexmidororgiddata(row.examId, row.orgId)
//判断是否显示危急值上报功能 条件是当前机构等于上级机构
isshowwjz.value = Profilevo.value.orgId === row.highLevelOrgId ? true : false
if (warningdata && warningdata.reportDate) {
isshowysb.value = Profilevo.value.orgId === row.orgId ? true : false
}
//判断保存按钮是否可用 审核后不允许在保存
savedisabled.value = applyFormVO.value.reportstatus === '已审核' ? true : false
}
//审核功能
async function process() {
if (applyFormVO.value.reportstatus === '已分析') {
// 审核确认
await message.delConfirm('是否进行审核操作', '审核')
loading.value = true
// return
const response = await PatientexamlistApi.examine(keyid.value,Profilevo.value.doctorname,Profilevo.value.doctorID)
if (response) {
message.alertSuccess('审核成功')
let data = Object.assign({},processImageApi.paramsList[rowinfo.value.orgName])
// data.imagePath = "F:\\陕西省咸阳市礼泉县心电图FTP\\ecgimage\\北屯中心卫生院\\K021180213001N0003_20250418161404.jpg"
data.imagePath = queryParams.value.ecgJsonDataFilePath
// data.imagePath = "https://zzxmc.gw12320.com/ecgimage/%E5%8C%97%E5%B1%AF%E4%B8%AD%E5%BF%83%E5%8D%AB%E7%94%9F%E9%99%A2/K021180213001N0003_20250418162136.jpg"
data.examId = rowinfo.value.examId
data.orgId = rowinfo.value.orgId
data.watermarkText = data.step + queryParams.value.doctorDiagResult
// console.log(data)
data.imagePath = processImageApi.urlToAddress(data.imagePath)
const processResponse = await processImageApi.processImg(data)
// 1. 解析外层 JSON 的 data 字符串
const dataObj = JSON.parse(processResponse.data);
// 2. 直接获取 updateSuccess 的值
const updateSuccess = dataObj.updateSuccess;
if (!updateSuccess){
message.warning('诊断图片生成异常')
}
console.log("processResponse",processResponse)
console.log("updateSuccess",updateSuccess)
console.log("dataObj",dataObj)
await getPatientexamlist(keyid.value)
emit('success')
savedisabled.value = true
}
} else if (applyFormVO.value.reportstatus === '已审核') {
message.warning('已经审核,无需再次审核')
} else {
message.warning('请先进行保存')
}
}
//查询当前患者数据
async function getPatientexamlist(id) {
const data = await PatientexamlistApi.getPatientexamlist(id)
applyFormVO.value = data
}
// 返回的列表的数据
const queryParams = ref({
id: '',
orgId: '',
examId: '',
collectionTime: undefined,
hr: '',
paxle: '',
qrsAxle: '',
taxle: '',
ptimeLimit: '',
pr: '',
qrsTimeLimit: '',
qt: '',
qtc: '',
rv5: '',
sv1: '',
rv5Sv1: '',
snapshotTime: undefined,
autoDiagResult: '',
autoDiagTime: undefined,
doctorDiagResult: '',
doctorDiagTime: undefined,
doctorName: '',
doctorId: '',
departId: '',
departName: '',
isDelete: '',
deleteTime: undefined,
deleteDoctorName: '',
deleteDoctorId: '',
ecgDataFilePath: '',
ecgJsonDataFilePath: '',
createDate: undefined
})
const save = async () => {
const loading = ElLoading.service({
target: 'ECGForm_main',
lock: true,
text: '数据保存中...'
})
try {
saveFormVO.value.id = queryParams.value.id
saveFormVO.value.hr = queryParams.value.hr
saveFormVO.value.paxle = queryParams.value.paxle
saveFormVO.value.qrsAxle = queryParams.value.qrsAxle
saveFormVO.value.taxle = queryParams.value.taxle
saveFormVO.value.ptimeLimit = queryParams.value.ptimeLimit
saveFormVO.value.pr = queryParams.value.pr
saveFormVO.value.qrsTimeLimit = queryParams.value.qrsTimeLimit
saveFormVO.value.qt = queryParams.value.qt
saveFormVO.value.qtc = queryParams.value.qtc
saveFormVO.value.rv5 = queryParams.value.rv5
saveFormVO.value.sv1 = queryParams.value.sv1
saveFormVO.value.rv5Sv1 = queryParams.value.rv5Sv1
saveFormVO.value.autoDiagResult = queryParams.value.autoDiagResult
saveFormVO.value.doctorDiagResult = queryParams.value.doctorDiagResult
saveFormVO.value.doctorName = Profilevo.value.doctorname
saveFormVO.value.doctorId = Profilevo.value.doctorID
// saveFormVO.value.departId=queryParams.value.departId
// saveFormVO.value.departName=queryParams.value.departName
const ret = await EcganalysisparasApi.SaveEcganalysisparas(saveFormVO.value)
if (ret) {
//更新主表数据
examineFormVO.value.id = keyid.value
examineFormVO.value.diagDoctor = Profilevo.value.doctorname
examineFormVO.value.diagDoctorId = Profilevo.value.doctorID
examineFormVO.value.reportstatus = '已分析'
await PatientexamlistApi.examineupdatelist(examineFormVO.value)
const data = await EcganalysisparasApi.getexamIDdata(rowinfo.value.examId, orgid.value)
queryParams.value = data
//生成pdf
/* saveFormVO.value.regId = id.value
saveFormVO.value.examId = rowinfo.value.examId
saveFormVO.value.orgId = orgid.value
saveFormVO.value.name = rowinfo.value.pname
saveFormVO.value.gender = rowinfo.value.gender
saveFormVO.value.age = age.value
saveFormVO.value.diagtime = queryParams.value.doctorDiagTime
saveFormVO.value.ecgJsonDataFilePath = queryParams.value.ecgJsonDataFilePath
if (
queryParams.value.ecgJsonDataFilePath &&
!(
queryParams.value.ecgJsonDataFilePath.toUpperCase().endsWith('.BMP') ||
queryParams.value.ecgJsonDataFilePath.toUpperCase().endsWith('.JPG') ||
queryParams.value.ecgJsonDataFilePath.toUpperCase().endsWith('.PNG')
)
) {
await EcganalysisparasApi.SaveEcgPdf(saveFormVO.value)
} else {
await EcganalysisparasApi.SaveEcgPdf_image({
type: '2',
filepath: queryParams.value.ecgJsonDataFilePath,
regid: id.value,
examid: rowinfo.value.examId,
orgid: orgid.value,
diagContent: queryParams.value.doctorDiagResult,
doctorId: Profilevo.value.doctorID,
doctorName: Profilevo.value.doctorname
})
} */
//查询主表数据
await getPatientexamlist(keyid.value)
loading.close()
message.alertSuccess('保存成功')
emit('success')
//ElMessage.info('开始保存pdf')
// setTimeout(() => {
// isprintimage.value = true
// }, 900)
}
} catch {
} finally {
loading.close()
}
}
//展示图片
function updateimagebase(newValue) {
imagebase64.value = newValue
}
const updateimagebase_new = async () => {
try {
const image_base64 = await htmlToPdf.getDivContentAsBase64('#ecg_pdf')
try {
//生成PDF
htmlToPdf
.createPdfFromBase64(image_base64)
.then((pdfBase64) => {
PatientexamlistApi.ftppdf({
id: Primarykey.value,
imagebase: pdfBase64,
model: '0',
folderPath: 'C:\\work\\pacs' + '\\' + Primarykey.value
})
ElMessage.info('pdf保存成功')
})
.catch((error) => {
console.log(error)
})
} finally {
}
} catch {
} finally {
nextTick(() => {
isprintimage.value = false
})
}
}
//重置数据
function resetForm() {
Isgrid.value = 1 //是否显示网格 1显示 0不显示
Ismeasure.value = 0 //是否开启测量 1开启 0 不开启
IsFD.value = false //是否开启放大
lineratio.value = 0.05 //画线的系数 振幅
suduratio.value = 1 //画线的系数 走速
applyFormVO.value = {} as PatientexamlistVO
examineFormVO.value = {} as PatientexamlistVO
}
//关闭打印窗口
function printclose() {
isprintimage.value = false
imagebase64.value = ''
imagebase64_new.value = ''
isdiagshow.value = false
}
//打印
function print() {
//isprintimage.value = false
isdiagshow.value = false
if (applyFormVO.value && applyFormVO.value.reportstatus != '已审核') {
message.alertError('请审核后再进行打印')
} else if (!applyFormVO.value.pdfurl) {
message.alertError('未获取到相关数据')
} else {
//isprintimage.value = true
isdiagshow.value = true
nextTick(() => {
setTimeout(async () => {
if (applyFormVO.value.pdfurl) {
imagebase64_new.value = applyFormVO.value.pdfurl.trim()
} else if (false) {
let doctorEcgDiagInfo: any = null
if (queryParams.value && queryParams.value.doctorId) {
doctorEcgDiagInfo = await EcganalysisparasApi.getDoctorBydoctorID(
queryParams.value.doctorId.trim()
)
}
let mapRes = await EcganalysisparasApi.getEcgPdfImage({
type: 2,
regid: id.value,
examid: queryParams.value.examId,
name: rowinfo.value.pname,
gender: rowinfo.value.gender,
age: age.value,
ward: '',
hr: queryParams.value.hr,
pr: queryParams.value.pr,
qrs: queryParams.value.qrsAxle,
qtqtc: queryParams.value.qt + '/' + queryParams.value.qtc,
rv5sv1: queryParams.value.rv5 + '/' + queryParams.value.sv1,
rv5sv1plus: (
Number(queryParams.value.rv5 ? queryParams.value.rv5 : '') +
Number(queryParams.value.sv1 ? queryParams.value.sv1 : '')
).toString(),
pt:
queryParams.value.paxle +
'/' +
queryParams.value.taxle +
'/' +
queryParams.value.qrsAxle,
ptimelimit: queryParams.value.ptimeLimit,
diagnosisHint: '',
department: rowinfo.value.billDoctorDepartment,
doctorDiagTime: formatDate(
queryParams.value.doctorDiagTime as any,
'YYYY-MM-DD HH:mm:ss'
),
diagContent: queryParams.value.doctorDiagResult,
DepartName: queryParams.value.departName,
doctorName: queryParams.value.doctorName,
image: doctorEcgDiagInfo ? doctorEcgDiagInfo.esignatureUrl : '',
filepath: queryParams.value.ecgJsonDataFilePath,
orgid: orgid.value,
orgname: rowinfo.value.orgName
})
if (mapRes && mapRes.code == '200') {
imagebase64_new.value = mapRes.dataImage
}
}
}, 100)
})
}
}
//纠错窗体回传值
const handleUpdate = (newValue) => {
correct.value = newValue
}
//申请返修界面弹窗
function ECGApplyDialog() {
ECGApply.value.opendiag(
'1',
rowinfo.value,
Profilevo.value.orgId,
Profilevo.value.doctorname,
Profilevo.value.id,
applyFormVO.value.reportstatus
)
}
//危急值弹窗
function openECGDialog() {
ECGDialog.value.opendiag('1', rowinfo.value)
}
//已上报危急值弹窗
function openreprotdiag() {
ECGReportDialog.value.opendiag(rowinfo.value)
}
//对比弹窗
function opencomparediag() {
ECGCompare.value.opencomparediag(rowinfo.value, queryParams.value.snapshotTime)
}
//纠错
function iscorrect() {
correct.value = correct.value ? false : true
}
//刷新
function Refresh() {
isrefresh.value = isrefresh.value ? false : true
}
//复制链接
function touchCopy() {
// 调用
if (applyFormVO.value.pdfurl) {
toClipboard(applyFormVO.value.pdfurl)
message.alertSuccess('复制成功')
} else {
message.alertError('请先保存后再进行复制')
}
}
/** 申请后更新上级机构字段*/
const getuporghiorgid = async (id: number, orgId: string) => {
try {
let orgInfo: any = null
if (Profilevo.value.orgId) orgInfo = await EcganalysisparasApi.getOrg(Profilevo.value.orgId)
if (!orgInfo || !orgInfo.highLevelOrgID) {
message.alertWarning('请先设置当前用户的上级机构')
return
}
if (applyFormVO.value.highLevelOrgId) {
message.alertWarning('已提交申请')
return
}
await message.confirm('是否要进行申请?', '确认提示')
const data = await PatientexamlistApi.getuporghiid(id, orgId)
if (data == '申请成功') {
message.success('申请成功')
} else {
await message.info(data)
}
} catch {}
}
// 树节点选中事件
const handleTreeNodeClick = async (data) => {
if (data.dataType === '0') {
const confirmed = await message.delConfirm('是否选择当前诊断', '确认')
if (confirmed) {
diagnosemodel.value = data.diagResults
insertValue(diagnosemodel.value)
drawer.value = false
console.log(diagnosemodel.value)
}
}
}
//诊断模版
async function zdmodle() {
const dd = await ultrasoniccomApi.getreporttemplatelist(orgid.value, '', '')
treeData.value = dd
drawer.value = drawer.value ? false : true
}
//获取振幅
function handleCommand(value) {
lineratio.value = value
}
//走苏
function handlezsCommand(value) {
suduratio.value = value
}
//是否显示网格
function Isgriddisplay() {
const value = Isgrid.value === 1 ? 0 : 1
Isgrid.value = value
}
//是否开启 测量
function measure() {
const value = Ismeasure.value === 1 ? 0 : 1
Ismeasure.value = value
if (value === 1) {
message.alertSuccess('开启测量')
} else {
message.alertSuccess('关闭测量')
}
}
//是否开启 放大
function FD() {
const value = IsFD.value === false ? true : false
IsFD.value = value
if (value) {
message.alertSuccess('开启放大')
} else {
message.alertSuccess('关闭放大')
}
}
//分享点击
function shareclick() {
if (applyFormVO.value.diagDate) {
isshare.value = false
// 确保 DOM 已经渲染
QRCode.toCanvas(qrcodeRef.value, applyFormVO.value.pdfurl, function (error) {
if (error) console.error(error)
console.log('QR code generated!')
})
} else {
isshare.value = true
message.alertError('请保存后再进行分享')
}
}
//根据光标位置 插入值
const insertValue = (textvalue: String) => {
const textarea = inputRef.value.$el.querySelector('textarea') // 获取textarea DOM元素
const start = textarea.selectionStart // 光标位置
const end = textarea.selectionEnd
const value = textarea.value // 当前输入框的值
queryParams.value.doctorDiagResult = value.slice(0, start) + textvalue + value.slice(end)
// 更新光标位置
textarea.selectionStart = textarea.selectionEnd = start + textvalue.length
//textarea.focus() // 使输入框重新获得焦点
}
// 创建一个计算属性来转换时间戳
function formattedDate(timestamp) {
const date = new Date(timestamp)
const strdata = formatDate(date, 'YYYY-MM-DD HH:mm:ss')
return strdata // 转换为本地日期时间字符串
}
//获取当前登录人信息
const getlogininfo = async () => {
Profilevo.value = await getUserProfile()
}
// 计算年龄
const calculateAge = (birthdate) => {
if (!birthdate) {
age.value = null
return
}
const today = new Date()
const birth = new Date(birthdate)
let yearsDiff = today.getFullYear() - birth.getFullYear()
// Check if the birthday hasn't occurred yet this year
const hasBirthdayPassed =
today.getMonth() > birth.getMonth() ||
(today.getMonth() === birth.getMonth() && today.getDate() >= birth.getDate())
if (!hasBirthdayPassed) {
yearsDiff--
}
age.value = yearsDiff
}
/*心电图数据相关*/
/*心电图数据相关*/
defineOptions({ name: 'ECGForm' })
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
</script>
<style lang="scss" scoped>
#elform :deep(.el-form-item__label) {
padding-right: 5px;
}
.mycontainer {
display: flex;
width: 100%;
min-height: 90vh;
}
.myleft-box {
flex: 4; /* 左侧盒子占据一半空间 */
border-style: solid; /* 设置边框样式为实线 */
border-width: 1px; /* 设置边框宽度为2像素 */
border-color: #cccccc; /* 设置边框颜色为黑色 */
border-radius: 8px 0 0 8px;
min-height: 90vh;
}
.myright-box {
flex: 1; /* 右侧盒子占据一半空间 */
border-style: solid solid solid; /* 上、右、下边框为实线 */
border-width: 1px; /* 设置边框宽度为1像素 */
border-color: #cccccc; /* 设置边框颜色为灰色 */
border-left-style: none; /* 移除左边边框 */
border-radius: 0 8px 8px 0;
min-height: 90vh;
}
.mybutwidth {
margin-left: 10px;
margin-bottom: 5px;
width: 50px;
}
.mycenter-button {
display: flex; /* 启用Flexbox布局 */
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
height: 30px; /* 根据需要设置容器高度 */
margin-top: 10px;
}
.mybtnsty {
margin-top: 10px;
display: flex;
flex-direction: column;
align-items: center;
}
/*心电图区域样式*/
/*心电图区域样式*/
/* 打印(报告单) */
.page-item-ecg {
padding: 1mm 1mm 0.12mm 1mm;
max-width: 1200px;
margin: 1.2vh auto 0 auto;
border: 2px solid #ccc;
border-radius: 8px;
}
.page-pdf-ecg {
border-width: 0;
padding: 0 0.8mm 0 0.8mm;
width: 294mm;
height: 206mm;
page-break-after: always;
}
@media print {
.ignore-print {
display: none;
}
.page-item-ecg {
border-width: 0;
height: 204.6mm;
page-break-after: always;
padding: 0;
max-width: none;
width: calc(100% - 2mm);
margin: 1.4mm 0 0 1mm;
}
}
</style>