新增模块 心电
This commit is contained in:
parent
76e9332870
commit
06521f4d32
79
src/api/tblist/ecganalysisparas/index.ts
Normal file
79
src/api/tblist/ecganalysisparas/index.ts
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// 心电分析数据 VO
|
||||||
|
export interface EcganalysisparasVO {
|
||||||
|
id: string // 主键
|
||||||
|
orgId: string // 机构ID
|
||||||
|
examId: string // 检查ID:体检编号、住院号、门诊号等
|
||||||
|
collectionTime: Date // 采集时间
|
||||||
|
hr: string // 心率
|
||||||
|
pAxle: string // P电轴
|
||||||
|
qrsAxle: string // QRS电轴
|
||||||
|
tAxle: string // T电轴
|
||||||
|
pTimeLimit: string // P波时限
|
||||||
|
pr: string // PR间期
|
||||||
|
qrsTimeLimit: string // QRS时限
|
||||||
|
qt: string // QT间期
|
||||||
|
qtc: string // QTC间期
|
||||||
|
rv5: string // 胸导V5导联电压
|
||||||
|
sv1: string // V1导联S波深度
|
||||||
|
rv5Sv1: string // RV5+SV1
|
||||||
|
snapshotTime: Date // 快照时间:参考心电波形的起始时间
|
||||||
|
autoDiagResult: string // 算法自动诊断结果
|
||||||
|
autoDiagTime: Date // 自动诊断的时间
|
||||||
|
doctorDiagResult: string // 医生诊断结果
|
||||||
|
doctorDiagTime: string // 医生诊断的时间
|
||||||
|
doctorName: string // 诊断医生的姓名
|
||||||
|
doctorId: string // 诊断医生的医生id
|
||||||
|
departId: string // 诊断医生的科室id
|
||||||
|
departName: string // 诊断医生的科室名称
|
||||||
|
isDelete: string // 是否删除: 1 为删除
|
||||||
|
deleteTime: Date // 删除时间
|
||||||
|
deleteDoctorName: string // 执行删除操作的医生姓名
|
||||||
|
deleteDoctorId: string // 执行删除操作的医生id
|
||||||
|
ecgDataFilePath: string // 心电数据文件的路径: 路径或URL
|
||||||
|
ecgJsonDataFilePath: string // 心电数据json格式的数据文件路径:路径或URL
|
||||||
|
createDate: Date // 分析参数的创建时间
|
||||||
|
}
|
||||||
|
|
||||||
|
// 心电分析数据 API
|
||||||
|
export const EcganalysisparasApi = {
|
||||||
|
// 查询心电分析数据分页
|
||||||
|
getEcganalysisparasPage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/tblist/ecganalysisparas/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询心电分析数据详情
|
||||||
|
getEcganalysisparas: async (id: number) => {
|
||||||
|
return await request.get({ url: `/tblist/ecganalysisparas/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增心电分析数据
|
||||||
|
createEcganalysisparas: async (data: EcganalysisparasVO) => {
|
||||||
|
return await request.post({ url: `/tblist/ecganalysisparas/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改心电分析数据
|
||||||
|
updateEcganalysisparas: async (data: EcganalysisparasVO) => {
|
||||||
|
return await request.put({ url: `/tblist/ecganalysisparas/update`, data })
|
||||||
|
},
|
||||||
|
// 保存心电分析数据
|
||||||
|
SaveEcganalysisparas: async (data: EcganalysisparasVO) => {
|
||||||
|
return await request.put({ url: `/tblist/ecganalysisparas/save`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除心电分析数据
|
||||||
|
deleteEcganalysisparas: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/tblist/ecganalysisparas/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出心电分析数据 Excel
|
||||||
|
exportEcganalysisparas: async (params) => {
|
||||||
|
return await request.download({ url: `/tblist/ecganalysisparas/export-excel`, params })
|
||||||
|
},
|
||||||
|
// 按照examId查询心电分析数据详情
|
||||||
|
getexamIDdata: async (examId: String) => {
|
||||||
|
return await request.get({ url: `/tblist/ecganalysisparas/getexamIDdata?examId=` + examId })
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
@ -5,7 +5,7 @@ import remainingRouter from './modules/remaining'
|
|||||||
|
|
||||||
// 创建路由实例
|
// 创建路由实例
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(), // createWebHashHistory URL带#,createWebHistory URL不带# liunx 病理 需要在这里加 '/bl/'
|
history: createWebHistory(), // createWebHashHistory URL带#,createWebHistory URL不带# liunx 病理 需要在这里加 '/bl/' 李晓东
|
||||||
strict: true,
|
strict: true,
|
||||||
routes: remainingRouter as RouteRecordRaw[],
|
routes: remainingRouter as RouteRecordRaw[],
|
||||||
scrollBehavior: () => ({ left: 0, top: 0 })
|
scrollBehavior: () => ({ left: 0, top: 0 })
|
||||||
|
@ -88,6 +88,22 @@ export function getNowDateTimeS() {
|
|||||||
const formattedDate = dayjs(formattedDateTime).toDate();
|
const formattedDate = dayjs(formattedDateTime).toDate();
|
||||||
return formattedDate;
|
return formattedDate;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 获取当前的日期+时间 YYYY-MM-DD HH:mm:ss 后端字段是LocalDateTime
|
||||||
|
*/
|
||||||
|
export function getCurrentLocalDateTime () {
|
||||||
|
const now = new Date();
|
||||||
|
const year = now.getFullYear();
|
||||||
|
const month = String(now.getMonth() + 1).padStart(2, '0'); // 月份从0开始,所以需要+1
|
||||||
|
const day = String(now.getDate()).padStart(2, '0');
|
||||||
|
const hour = String(now.getHours()).padStart(2, '0');
|
||||||
|
const minute = String(now.getMinutes()).padStart(2, '0');
|
||||||
|
const second = String(now.getSeconds()).padStart(2, '0');
|
||||||
|
const value=`${year}-${month}-${day}T${hour}:${minute}:${second}`
|
||||||
|
|
||||||
|
// 构建LocalDateTime格式的字符串
|
||||||
|
return value ;
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* 获取当前日期是第几周
|
* 获取当前日期是第几周
|
||||||
* @param dateTime 当前传入的日期值
|
* @param dateTime 当前传入的日期值
|
||||||
|
116
src/views/ECG/ECGBB.vue
Normal file
116
src/views/ECG/ECGBB.vue
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="container"
|
||||||
|
ref="container"
|
||||||
|
@mousemove="handleMouseMove"
|
||||||
|
@mouseleave="hideCursor"
|
||||||
|
@click="handleClick"
|
||||||
|
>
|
||||||
|
<canvas
|
||||||
|
ref="cursorCanvas"
|
||||||
|
class="cursor-canvas"
|
||||||
|
:style="cursorStyle"
|
||||||
|
></canvas>
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted } from 'vue';
|
||||||
|
|
||||||
|
const container = ref(null);
|
||||||
|
const cursorCanvas = ref(null);
|
||||||
|
const isCursorVisible = ref(false);
|
||||||
|
const cursorSize = 50; // 圆形光标的大小
|
||||||
|
const cursorStyle = reactive({
|
||||||
|
display: 'none',
|
||||||
|
position: 'absolute',
|
||||||
|
border: '1px solid #b72525',
|
||||||
|
borderRadius: '50%',
|
||||||
|
});
|
||||||
|
|
||||||
|
const cursorPosition = reactive({ x: 0, y: 0 });
|
||||||
|
|
||||||
|
function handleMouseMove(event) {
|
||||||
|
if (!container.value) return;
|
||||||
|
|
||||||
|
const bounds = container.value.getBoundingClientRect();
|
||||||
|
const mouseX = event.clientX - bounds.left;
|
||||||
|
const mouseY = event.clientY - bounds.top;
|
||||||
|
|
||||||
|
cursorPosition.x = mouseX;
|
||||||
|
cursorPosition.y = mouseY;
|
||||||
|
|
||||||
|
cursorStyle.left = `${mouseX - cursorSize / 2}px`;
|
||||||
|
cursorStyle.top = `${mouseY - cursorSize / 2}px`;
|
||||||
|
cursorStyle.display = 'block'; // 显示圆形光标
|
||||||
|
|
||||||
|
isCursorVisible.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideCursor() {
|
||||||
|
cursorStyle.display = 'none';
|
||||||
|
isCursorVisible.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleClick(event) {
|
||||||
|
if (!isCursorVisible.value) return;
|
||||||
|
|
||||||
|
// 截图并转换为 Base64
|
||||||
|
const imageDataUrl = getImageData(cursorPosition.x, cursorPosition.y, cursorSize);
|
||||||
|
console.log(imageDataUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getImageData(x, y, size) {
|
||||||
|
const tempCanvas = document.createElement('canvas');
|
||||||
|
tempCanvas.width = size;
|
||||||
|
tempCanvas.height = size;
|
||||||
|
const ctx = tempCanvas.getContext('2d');
|
||||||
|
|
||||||
|
// 遍历所有子元素,找到包含鼠标位置的 canvas,并截图
|
||||||
|
const elements = container.value.querySelectorAll('canvas');
|
||||||
|
for (const element of elements) {
|
||||||
|
const elemCtx = element.getContext('2d');
|
||||||
|
if (elemCtx) {
|
||||||
|
// 计算截取区域的坐标和尺寸
|
||||||
|
const elemBounds = element.getBoundingClientRect();
|
||||||
|
const elemX = x - elemBounds.left + window.scrollX;
|
||||||
|
const elemY = y - elemBounds.top + window.scrollY;
|
||||||
|
|
||||||
|
// 将图像区域绘制到临时 canvas 上
|
||||||
|
ctx.drawImage(
|
||||||
|
element,
|
||||||
|
elemX,
|
||||||
|
elemY,
|
||||||
|
size,
|
||||||
|
size,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
size,
|
||||||
|
size
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tempCanvas.toDataURL('image/png');
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
cursorCanvas.value.width = cursorSize;
|
||||||
|
cursorCanvas.value.height = cursorSize;
|
||||||
|
cursorCanvas.value.getContext('2d').clearRect(0, 0, cursorSize, cursorSize);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cursor-canvas {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
145
src/views/ECG/ECGFD.vue
Normal file
145
src/views/ECG/ECGFD.vue
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="magnifier-container"
|
||||||
|
ref="magnifierContainer"
|
||||||
|
@mousemove="handleMouseMove"
|
||||||
|
@mouseleave="hideMagnifier"
|
||||||
|
>
|
||||||
|
<canvas
|
||||||
|
class="magnifier-lens"
|
||||||
|
v-show="isMagnifierVisible"
|
||||||
|
ref="magnifierCanvas"
|
||||||
|
:style="lensStyle"
|
||||||
|
></canvas>
|
||||||
|
<slot></slot> <!-- 插槽用于放置需要显示图像的元素 -->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted } from 'vue';
|
||||||
|
|
||||||
|
const magnifierContainer = ref(null);
|
||||||
|
const magnifierCanvas = ref(null);
|
||||||
|
const isMagnifierVisible = ref(false);
|
||||||
|
const lensSize = 150; // 正方形区域的边长
|
||||||
|
const magnification = ref(2); // 放大倍数
|
||||||
|
|
||||||
|
const lensStyle = reactive({
|
||||||
|
width: `${lensSize}px`,
|
||||||
|
height: `${lensSize}px`,
|
||||||
|
position: 'absolute',
|
||||||
|
border: '1px solid #ca0707', // 正方形区域的边框
|
||||||
|
pointerEvents: 'none'
|
||||||
|
});
|
||||||
|
|
||||||
|
const magnifierCtx = ref(null); // 定义为响应式引用
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
magnifierCanvas.value.width = lensSize;
|
||||||
|
magnifierCanvas.value.height = lensSize;
|
||||||
|
magnifierCtx.value = magnifierCanvas.value.getContext('2d');
|
||||||
|
});
|
||||||
|
|
||||||
|
// function handleMouseMove(event) {
|
||||||
|
// isMagnifierVisible.value = true;
|
||||||
|
// const bounds = magnifierContainer.value.getBoundingClientRect();
|
||||||
|
// const mouseX = event.clientX - bounds.left;
|
||||||
|
// const mouseY = event.clientY - bounds.top;
|
||||||
|
|
||||||
|
// lensStyle.left = `${mouseX - lensSize / 2}px`;
|
||||||
|
// lensStyle.top = `${mouseY - lensSize / 2}px`;
|
||||||
|
// lensStyle.display = 'block'; // 显示正方形区域
|
||||||
|
|
||||||
|
// // 清除之前的画布内容
|
||||||
|
// magnifierCtx.value.clearRect(0, 0, lensSize, lensSize);
|
||||||
|
|
||||||
|
// // 获取鼠标下的图像区域
|
||||||
|
// const dx = mouseX - lensSize / 2;
|
||||||
|
// const dy = mouseY - lensSize / 2;
|
||||||
|
// const dw = lensSize / magnification.value; // 目标宽度
|
||||||
|
// const dh = lensSize / magnification.value; // 目标高度
|
||||||
|
|
||||||
|
// // 将图像区域绘制到放大镜画布上
|
||||||
|
// magnifierCtx.value.drawImage(
|
||||||
|
// magnifierCanvas.value,
|
||||||
|
// dx,
|
||||||
|
// dy,
|
||||||
|
// dw,
|
||||||
|
// dh,
|
||||||
|
// 0,
|
||||||
|
// 0,
|
||||||
|
// lensSize,
|
||||||
|
// lensSize
|
||||||
|
// );
|
||||||
|
// const imageDataUrl = magnifierCanvas.value.toDataURL('image/png');
|
||||||
|
// console.log( imageDataUrl)
|
||||||
|
// }
|
||||||
|
|
||||||
|
function handleMouseMove(event) {
|
||||||
|
isMagnifierVisible.value = true;
|
||||||
|
const bounds = magnifierContainer.value.getBoundingClientRect();
|
||||||
|
const mouseX = event.clientX - bounds.left;
|
||||||
|
const mouseY = event.clientY - bounds.top;
|
||||||
|
|
||||||
|
lensStyle.left = `${mouseX - lensSize / 2}px`;
|
||||||
|
lensStyle.top = `${mouseY - lensSize / 2}px`;
|
||||||
|
lensStyle.display = 'block'; // 显示正方形区域
|
||||||
|
|
||||||
|
// 清除之前的画布内容
|
||||||
|
magnifierCtx.value.clearRect(0, 0, lensSize, lensSize);
|
||||||
|
|
||||||
|
// 遍历所有子元素,找到包含鼠标位置的元素,并截图
|
||||||
|
const elements = magnifierContainer.value.querySelectorAll('canvas, img');
|
||||||
|
for (const element of elements) {
|
||||||
|
const elemCtx = element.getContext ? element.getContext('2d') : null;
|
||||||
|
if (elemCtx && element.contains(event.target)) {
|
||||||
|
// 计算截取区域的坐标和尺寸,考虑放大倍数
|
||||||
|
const magnificationFactor = 2; // 放大倍数,可以根据需要调整
|
||||||
|
const sx = Math.max(0, mouseX - lensSize / 2) * magnificationFactor;
|
||||||
|
const sy = Math.max(0, mouseY - lensSize / 2) * magnificationFactor;
|
||||||
|
const sw = lensSize * magnificationFactor;
|
||||||
|
const sh = lensSize * magnificationFactor;
|
||||||
|
|
||||||
|
// 确保截取区域不会超出元素的边界
|
||||||
|
const scaledWidth = Math.min(sw, element.width);
|
||||||
|
const scaledHeight = Math.min(sh, element.height);
|
||||||
|
|
||||||
|
// 将图像区域绘制到放大镜画布上
|
||||||
|
magnifierCtx.value.drawImage(
|
||||||
|
element,
|
||||||
|
sx,
|
||||||
|
sy,
|
||||||
|
scaledWidth,
|
||||||
|
scaledHeight,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
lensSize,
|
||||||
|
lensSize
|
||||||
|
);
|
||||||
|
|
||||||
|
// 将放大镜画布的内容转换为 base64
|
||||||
|
const imageDataUrl = magnifierCanvas.value.toDataURL('image/png');
|
||||||
|
// console.log(imageDataUrl);
|
||||||
|
break; // 找到正确的元素后退出循环
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideMagnifier() {
|
||||||
|
isMagnifierVisible.value = false;
|
||||||
|
lensStyle.display = 'none'; // 隐藏正方形区域
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.magnifier-container {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden; /* 防止正方形区域超出容器 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.magnifier-lens {
|
||||||
|
|
||||||
|
z-index: 2000;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
475
src/views/ECG/ECGForm.vue
Normal file
475
src/views/ECG/ECGForm.vue
Normal file
@ -0,0 +1,475 @@
|
|||||||
|
<template>
|
||||||
|
<!-- <div class="myArea"> -->
|
||||||
|
<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"
|
||||||
|
|
||||||
|
>
|
||||||
|
<div class="mycontainer">
|
||||||
|
<div class="myleft-box">
|
||||||
|
<el-container>
|
||||||
|
<!--头部 患者信息-->
|
||||||
|
<el-header style="background-color: rgb(0, 157, 224); height: 40px">
|
||||||
|
<div style="font-size: 20px; color: aliceblue">
|
||||||
|
<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">
|
||||||
|
检查日期:{{ formatDate(rowinfo.examDate, 'YYYY-MM-DD HH:mm:ss') }}</span
|
||||||
|
>
|
||||||
|
<span style="margin-left: 10px">检查机构: {{ rowinfo.orgName }}</span>
|
||||||
|
</div>
|
||||||
|
</el-header>
|
||||||
|
<!--头部 功能按钮-->
|
||||||
|
<el-header style="height: 40px; padding: 0px">
|
||||||
|
<el-button-group class="ml-4" style="margin-top: 4px; margin-left: 0px">
|
||||||
|
<el-button type="primary" :icon="Edit">采集</el-button>
|
||||||
|
<el-button type="primary" :icon="Edit">分享</el-button>
|
||||||
|
<el-button type="primary" :icon="Edit">重采</el-button>
|
||||||
|
<el-button type="primary" :icon="Edit">提交诊断</el-button>
|
||||||
|
<el-button type="primary" :icon="Edit">打印</el-button>
|
||||||
|
</el-button-group>
|
||||||
|
</el-header>
|
||||||
|
<el-container>
|
||||||
|
<!--左侧 心电图区域-->
|
||||||
|
<el-aside width="97%" style="height: 750px">
|
||||||
|
<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"/>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</el-aside>
|
||||||
|
<!--右侧 功能按钮-->
|
||||||
|
<el-main style="padding: 1px">
|
||||||
|
<div style="margin-top: 30px; display: flex; flex-direction: column">
|
||||||
|
<el-button
|
||||||
|
style="width: 30px; height: 30px; margin-bottom: 10px"
|
||||||
|
type="primary"
|
||||||
|
:icon="Edit"
|
||||||
|
/>
|
||||||
|
<span style="font-size: 15px; margin-bottom: 10px">走速</span>
|
||||||
|
<el-button
|
||||||
|
style="width: 30px; height: 30px; margin-bottom: 10px"
|
||||||
|
type="primary"
|
||||||
|
:icon="Edit"
|
||||||
|
/>
|
||||||
|
<span style="font-size: 15px; margin-bottom: 10px">振幅</span>
|
||||||
|
|
||||||
|
<el-button
|
||||||
|
style="width: 30px; height: 30px; margin-bottom: 10px"
|
||||||
|
type="primary"
|
||||||
|
:icon="Edit"
|
||||||
|
@click="measure()"
|
||||||
|
/>
|
||||||
|
<span style="font-size: 15px; margin-bottom: 10px">测量</span>
|
||||||
|
|
||||||
|
<el-button
|
||||||
|
style="width: 30px; height: 30px; margin-bottom: 10px"
|
||||||
|
type="primary"
|
||||||
|
:icon="Edit"
|
||||||
|
/>
|
||||||
|
<span style="font-size: 15px; margin-bottom: 10px">放大</span>
|
||||||
|
|
||||||
|
<el-button
|
||||||
|
style="width: 30px; height: 30px; margin-bottom: 10px"
|
||||||
|
type="primary"
|
||||||
|
:icon="Edit"
|
||||||
|
@click="FD()"
|
||||||
|
/>
|
||||||
|
<span style="font-size: 15px; margin-bottom: 10px">纠错</span>
|
||||||
|
|
||||||
|
<el-button
|
||||||
|
style="width: 30px; height: 30px; margin-bottom: 10px"
|
||||||
|
type="primary"
|
||||||
|
:icon="Edit"
|
||||||
|
@click="Isgriddisplay()"
|
||||||
|
/>
|
||||||
|
<span style="font-size: 15px; margin-bottom: 10px">网格</span>
|
||||||
|
</div>
|
||||||
|
</el-main>
|
||||||
|
</el-container>
|
||||||
|
</el-container>
|
||||||
|
</div>
|
||||||
|
<div class="myright-box">
|
||||||
|
<el-form :model="queryParams" label-width="auto" style="max-width: 600px; margin-top: 10px">
|
||||||
|
<!-- 第一行 -->
|
||||||
|
<el-row :gutter="24">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="心率">
|
||||||
|
<el-input v-model="queryParams.hr" suffix-icon="el-icon-date">
|
||||||
|
<template #append>bpm</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="P电轴">
|
||||||
|
<el-input v-model="queryParams.paxle" suffix-icon="el-icon-date">
|
||||||
|
<template #append>°</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 第二行 -->
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="QRS电轴">
|
||||||
|
<el-input v-model="queryParams.qrsAxle" suffix-icon="el-icon-date">
|
||||||
|
<template #append>°</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="T电轴">
|
||||||
|
<el-input v-model="queryParams.taxle" suffix-icon="el-icon-date">
|
||||||
|
<template #append>°</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 第三行 -->
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="P波时限">
|
||||||
|
<el-input v-model="queryParams.ptimeLimit" suffix-icon="el-icon-date">
|
||||||
|
<template #append>ms</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="PR间期">
|
||||||
|
<el-input v-model="queryParams.pr" suffix-icon="el-icon-date">
|
||||||
|
<template #append>ms</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 第四行 -->
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="QRS时限">
|
||||||
|
<el-input v-model="queryParams.qrsTimeLimit" suffix-icon="el-icon-date">
|
||||||
|
<template #append>ms</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="QT间期">
|
||||||
|
<el-input v-model="queryParams.qt" suffix-icon="el-icon-date">
|
||||||
|
<template #append>ms</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 第五行 -->
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="QTc">
|
||||||
|
<el-input v-model="queryParams.qtc" suffix-icon="el-icon-date">
|
||||||
|
<template #append>ms</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="RV5">
|
||||||
|
<el-input v-model="queryParams.rv5" suffix-icon="el-icon-date">
|
||||||
|
<template #append>mV</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 第六行 -->
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="SV1">
|
||||||
|
<el-input v-model="queryParams.sv1" suffix-icon="el-icon-date">
|
||||||
|
<template #append>mV</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="RV5+SV1">
|
||||||
|
<el-input v-model="queryParams.rv5Sv1" suffix-icon="el-icon-date">
|
||||||
|
<template #append>mV</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-tag type="info" style="font-size: 16px; width: 100%">心电事件快照</el-tag>
|
||||||
|
<el-input
|
||||||
|
v-model="snapshotTime"
|
||||||
|
style="width: 100%"
|
||||||
|
:rows="3"
|
||||||
|
type="textarea"
|
||||||
|
placeholder=""
|
||||||
|
/>
|
||||||
|
<el-tag type="info" style="font-size: 16px; width: 100%">智能词库</el-tag>
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.autoDiagResult"
|
||||||
|
style="width: 100%"
|
||||||
|
:rows="3"
|
||||||
|
type="textarea"
|
||||||
|
placeholder="Please input"
|
||||||
|
/>
|
||||||
|
<el-tag type="info" style="font-size: 16px; width: 100%">医生诊断结论</el-tag>
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.doctorDiagResult"
|
||||||
|
style="width: 100%"
|
||||||
|
:rows="4"
|
||||||
|
type="textarea"
|
||||||
|
placeholder="Please input"
|
||||||
|
ref="inputRef"
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
<el-button class="mybutwidth" type="success" @click="insertValue('I')">I</el-button>
|
||||||
|
<el-button class="mybutwidth" type="success" @click="insertValue('II')">II</el-button>
|
||||||
|
<el-button class="mybutwidth" type="success" @click="insertValue('III')">III</el-button>
|
||||||
|
<el-button class="mybutwidth" type="success" @click="insertValue('aVR')">aVR</el-button>
|
||||||
|
<el-button class="mybutwidth" type="success" @click="insertValue('aVL')">aVL</el-button>
|
||||||
|
<el-button class="mybutwidth" type="success" @click="insertValue('aVF')">aVF</el-button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-button class="mybutwidth" type="success" @click="insertValue('V3R')">V3R</el-button>
|
||||||
|
<el-button class="mybutwidth" type="success" @click="insertValue('V4R')">V4R</el-button>
|
||||||
|
<el-button class="mybutwidth" type="success" @click="insertValue('V5R')">V5R</el-button>
|
||||||
|
<el-button class="mybutwidth" type="success" @click="insertValue('V1')">V1</el-button>
|
||||||
|
<el-button class="mybutwidth" type="success" @click="insertValue('V2')">V2</el-button>
|
||||||
|
<el-button class="mybutwidth" type="success" @click="insertValue('V3')">V3</el-button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-button class="mybutwidth" type="success" @click="insertValue('V4')">V4</el-button>
|
||||||
|
<el-button class="mybutwidth" type="success" @click="insertValue('V5')">V5</el-button>
|
||||||
|
<el-button class="mybutwidth" type="success" @click="insertValue('V6')">V6</el-button>
|
||||||
|
<el-button class="mybutwidth" type="success" @click="insertValue('V7')">V7</el-button>
|
||||||
|
<el-button class="mybutwidth" type="success" @click="insertValue('V8')">V8</el-button>
|
||||||
|
<el-button class="mybutwidth" type="success" @click="insertValue('V9')">V9</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="mycenter-button">
|
||||||
|
<el-button style="width: 200px" type="primary" plain @click="save">保存</el-button>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
<!-- </div> -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { ArrowLeft, ArrowRight, Delete, Edit, Share } from '@element-plus/icons-vue'
|
||||||
|
import ECGhtml from '@/views/ECG/ECGhtml.vue'
|
||||||
|
import { EcganalysisparasApi, EcganalysisparasVO } from '@/api/tblist/ecganalysisparas'
|
||||||
|
import { dateFormatter, beginOfDay } from '@/utils/formatTime'
|
||||||
|
import { formatDate, getCurrentLocalDateTime } from '@/utils/formatTime'
|
||||||
|
import { getUserProfile, ProfileVO } from '@/api/system/user/profile'
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
const id = ref() //患者ID
|
||||||
|
const rowinfo = ref() //当前患者数据行
|
||||||
|
const snapshotTime = ref() //心电事件快照事件
|
||||||
|
// 定义一个响应式变量来控制子组件的显示
|
||||||
|
const isChildVisible = ref(false)
|
||||||
|
const inputRef = ref() // 用于获取el-input的DOM引用
|
||||||
|
const saveFormVO = ref<EcganalysisparasVO>({} as EcganalysisparasVO)
|
||||||
|
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 open = async (row: any) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = '心电分析'
|
||||||
|
id.value = row.regId
|
||||||
|
rowinfo.value = row
|
||||||
|
const data = await EcganalysisparasApi.getexamIDdata('MZCF0191729074962197_44')
|
||||||
|
queryParams.value = data
|
||||||
|
console.log(row)
|
||||||
|
snapshotTime.value = formattedDate(queryParams.value.snapshotTime)
|
||||||
|
getlogininfo()
|
||||||
|
calculateAge(row.birthday)
|
||||||
|
Isgrid.value=1// 没次打开都是显示的 只有点击网格才会变化
|
||||||
|
isChildVisible.value = true
|
||||||
|
}
|
||||||
|
// 返回的列表的数据
|
||||||
|
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
|
||||||
|
})
|
||||||
|
//
|
||||||
|
async function save() {
|
||||||
|
let timesta = new Date()
|
||||||
|
var localDateTime = new Date(timesta.getTime()).toISOString() // 转换为ISO格式的字符串
|
||||||
|
|
||||||
|
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.qrsTimeLimit = 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) {
|
||||||
|
message.success('保存成功')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//是否显示网格
|
||||||
|
function Isgriddisplay() {
|
||||||
|
const value=Isgrid.value === 1 ? 0 : 1;
|
||||||
|
Isgrid.value=value
|
||||||
|
}
|
||||||
|
//是否开启 测量
|
||||||
|
function measure() {
|
||||||
|
const value=Ismeasure.value === 1 ? 0 : 1;
|
||||||
|
Ismeasure.value=value
|
||||||
|
}
|
||||||
|
//是否开启 放大
|
||||||
|
function FD() {
|
||||||
|
const value=IsFD.value === false ? true : false;
|
||||||
|
IsFD.value=value
|
||||||
|
}
|
||||||
|
|
||||||
|
//根据光标位置 插入值
|
||||||
|
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 scoped>
|
||||||
|
.mycontainer {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.myleft-box {
|
||||||
|
flex: 4; /* 左侧盒子占据一半空间 */
|
||||||
|
border-style: solid; /* 设置边框样式为实线 */
|
||||||
|
border-width: 2px; /* 设置边框宽度为2像素 */
|
||||||
|
border-color: #000000; /* 设置边框颜色为黑色 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.myright-box {
|
||||||
|
flex: 1; /* 右侧盒子占据一半空间 */
|
||||||
|
}
|
||||||
|
.mybutwidth {
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mycenter-button {
|
||||||
|
display: flex; /* 启用Flexbox布局 */
|
||||||
|
justify-content: center; /* 水平居中 */
|
||||||
|
align-items: center; /* 垂直居中 */
|
||||||
|
height: 100px; /* 根据需要设置容器高度 */
|
||||||
|
}
|
||||||
|
/*心电图区域样式*/
|
||||||
|
|
||||||
|
/*心电图区域样式*/
|
||||||
|
</style>
|
164
src/views/ECG/ECGSB.vue
Normal file
164
src/views/ECG/ECGSB.vue
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
<template>
|
||||||
|
<div class="magnifying-glass">
|
||||||
|
<div class="source-box">
|
||||||
|
<div
|
||||||
|
class="zoom-box"
|
||||||
|
:style="{
|
||||||
|
left: zoomPoint.x + 'px',
|
||||||
|
top: zoomPoint.y + 'px'
|
||||||
|
}"
|
||||||
|
v-show="isShow"
|
||||||
|
></div>
|
||||||
|
<canvas id="source-canvas"></canvas>
|
||||||
|
</div>
|
||||||
|
<canvas
|
||||||
|
id="look-canvas"
|
||||||
|
v-show="isShow"
|
||||||
|
:style="{ top: lookPoint.top + 'px', left: lookPoint.left + 'px' }"
|
||||||
|
></canvas>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { onMounted, ref, reactive } from 'vue'
|
||||||
|
let canvas = null
|
||||||
|
let lookCanvas = null
|
||||||
|
// 桌布
|
||||||
|
let zoomBox = null
|
||||||
|
let canvasWidth = 50
|
||||||
|
let canvasHeight = 50
|
||||||
|
// look-canvas 的展示位置设置
|
||||||
|
let lookPoint = reactive({
|
||||||
|
top: 0,
|
||||||
|
left: 50
|
||||||
|
})
|
||||||
|
// 原图的坐标
|
||||||
|
let points = { x: 0, y: 0 }
|
||||||
|
// 放大 图片的坐标
|
||||||
|
let showPoint = { x: 0, y: 0 }
|
||||||
|
// 桌布位置坐标
|
||||||
|
let zoomPoint = reactive({
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
})
|
||||||
|
// 鼠标 mousedow 窗口坐标点记录
|
||||||
|
let startPoint = { x: 0, y: 0 }
|
||||||
|
let isShow = ref(false)
|
||||||
|
let image = null
|
||||||
|
// 放大倍数
|
||||||
|
let multiple = 3
|
||||||
|
// 获取图片资源
|
||||||
|
async function getImage(url) {
|
||||||
|
const response = await fetch(url)
|
||||||
|
const blob = await response.blob()
|
||||||
|
const image = await createImageBitmap(blob)
|
||||||
|
return image
|
||||||
|
}
|
||||||
|
onMounted(async () => {
|
||||||
|
image = await getImage(
|
||||||
|
'https://img2.baidu.com/it/u=2814429148,2262424695&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=1422'
|
||||||
|
)
|
||||||
|
canvas = document.getElementById('source-canvas')
|
||||||
|
lookCanvas = document.getElementById('look-canvas')
|
||||||
|
zoomBox = document.querySelector('.zoom-box')
|
||||||
|
|
||||||
|
canvas.width = canvasWidth
|
||||||
|
canvas.height = canvasHeight
|
||||||
|
lookCanvas.width = canvasWidth
|
||||||
|
lookCanvas.height = canvasHeight
|
||||||
|
|
||||||
|
let ctx = canvas.getContext('2d')
|
||||||
|
ctx.drawImage(image, 0, 0, canvasWidth, canvasHeight)
|
||||||
|
|
||||||
|
canvas.addEventListener('mousedown', canvasMousedown)
|
||||||
|
window.addEventListener('mouseup', windowMouseUp)
|
||||||
|
})
|
||||||
|
|
||||||
|
function canvasMousedown(e) {
|
||||||
|
let { offsetX, offsetY, clientX, clientY } = e
|
||||||
|
points = {
|
||||||
|
x: offsetX,
|
||||||
|
y: offsetY
|
||||||
|
}
|
||||||
|
startPoint = {
|
||||||
|
x: clientX,
|
||||||
|
y: clientY
|
||||||
|
}
|
||||||
|
setShowPoint(offsetX, offsetY)
|
||||||
|
isShow.value = true
|
||||||
|
lookCanvasDraw(lookCanvas, image, canvasWidth, canvasHeight, multiple)
|
||||||
|
window.addEventListener('mousemove', windowMouseMove)
|
||||||
|
}
|
||||||
|
|
||||||
|
function windowMouseUp(e) {
|
||||||
|
isShow.value = false
|
||||||
|
window.removeEventListener('mousemove', windowMouseMove)
|
||||||
|
}
|
||||||
|
|
||||||
|
function windowMouseMove(e) {
|
||||||
|
let { clientX, clientY } = e
|
||||||
|
let x = points.x + clientX - startPoint.x
|
||||||
|
let y = points.y + clientY - startPoint.y
|
||||||
|
|
||||||
|
setShowPoint(x, y)
|
||||||
|
lookCanvasDraw(lookCanvas, image, canvasWidth, canvasHeight, multiple)
|
||||||
|
}
|
||||||
|
|
||||||
|
function lookCanvasDraw(canvas, image, canvasWidth, canvasHeight, multiple = 2) {
|
||||||
|
let ctx = canvas.getContext('2d')
|
||||||
|
ctx.clearRect(0, 0, canvasWidth, canvasHeight)
|
||||||
|
ctx.drawImage(image, showPoint.x, showPoint.y, canvasWidth * multiple, canvasHeight * multiple)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置 放大镜查看 图片位置
|
||||||
|
function setShowPoint(X, Y) {
|
||||||
|
if (X > 500) {
|
||||||
|
X = 500
|
||||||
|
}
|
||||||
|
if (X < 0) {
|
||||||
|
X = 0
|
||||||
|
}
|
||||||
|
if (Y > 500) {
|
||||||
|
Y = 500
|
||||||
|
}
|
||||||
|
if (Y < 0) {
|
||||||
|
Y = 0
|
||||||
|
}
|
||||||
|
//
|
||||||
|
showPoint = {
|
||||||
|
x: -X * multiple + canvasWidth / 2,
|
||||||
|
y: -Y * multiple + canvasHeight / 2
|
||||||
|
}
|
||||||
|
// 桌布桌布设置
|
||||||
|
zoomPoint.x = X
|
||||||
|
zoomPoint.y = Y
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.magnifying-glass {
|
||||||
|
position: relative;
|
||||||
|
/* margin-left: 50px; */
|
||||||
|
}
|
||||||
|
.source-box {
|
||||||
|
/* margin-top: 50px; */
|
||||||
|
position: relative;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
.zoom-box {
|
||||||
|
position: absolute;
|
||||||
|
width: 20%;
|
||||||
|
height: 20%;
|
||||||
|
background-color: rgba(255, 0, 0, 0.2);
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#source-canvas,
|
||||||
|
#look-canvas {
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
#look-canvas {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
</style>
|
563
src/views/ECG/ECGhtml.vue
Normal file
563
src/views/ECG/ECGhtml.vue
Normal file
@ -0,0 +1,563 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- <button @click="moveCanvas('left')">左边-左移</button>
|
||||||
|
<button @click="moveCanvas('right')">左边-右移</button>-->
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<BB>
|
||||||
|
<div id="canvas-container">
|
||||||
|
<canvas ref="leftCanvas" id="leftCanvas" width="21" height="600"></canvas>
|
||||||
|
<canvas ref="bottomCanvas" id="bottomCanvas" width="1140" height="600"></canvas>
|
||||||
|
<canvas
|
||||||
|
ref="topCanvas"
|
||||||
|
id="topCanvas"
|
||||||
|
width="1140"
|
||||||
|
height="600"
|
||||||
|
@mousedown="handleMouseDown($event, 'L')"
|
||||||
|
></canvas>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</BB>
|
||||||
|
<div id="canvas-container1">
|
||||||
|
<canvas ref="rightCanvas" id="rightCanvas" width="21" height="600"></canvas>
|
||||||
|
<canvas ref="bottomCanvas1" id="bottomCanvas1" width="1140" height="600"></canvas>
|
||||||
|
<canvas
|
||||||
|
ref="topCanvas1"
|
||||||
|
id="topCanvas1"
|
||||||
|
width="1140"
|
||||||
|
height="600"
|
||||||
|
@mousedown="handleMouseDown($event, 'R')"
|
||||||
|
></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-slider v-model="sliderValue" :min="0" :max="50" :step="1" @input="handleSliderChange" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
|
import { number } from 'vue-types'
|
||||||
|
import Magnifier from './ECGFD.vue'
|
||||||
|
import sb from './ECGSB.vue'
|
||||||
|
import BB from './ECGBB.vue'
|
||||||
|
|
||||||
|
//读取出来的json
|
||||||
|
const text = ref()
|
||||||
|
const sliderValue = ref(0) // 初始化滑块值
|
||||||
|
|
||||||
|
const previousValue = ref(0) // 记录上一个滑块值
|
||||||
|
const swipeDirection = ref('') // 用于存储滑动方向
|
||||||
|
// 响应式引用
|
||||||
|
const leftCanvas = ref(null)
|
||||||
|
const rightCanvas = ref(null)
|
||||||
|
const bottomCanvas = ref(null)
|
||||||
|
const bottomCanvas1 = ref(null)
|
||||||
|
const topCanvas = ref(null)
|
||||||
|
const topCanvas1 = ref(null)
|
||||||
|
const url = ref()
|
||||||
|
/*鼠标绘制相关*/
|
||||||
|
const ctx = ref(null)
|
||||||
|
const isVertical = ref(false) // 控制线条类型,true 为竖直,false 为水平
|
||||||
|
const lastPoint = ref(null) // 用于存储上一个点的坐标
|
||||||
|
|
||||||
|
function handleMouseDown(event, type) {
|
||||||
|
if (type === 'L') {
|
||||||
|
ctx.value = topCanvas.value.getContext('2d')
|
||||||
|
} else if (type === 'R') {
|
||||||
|
ctx.value = topCanvas1.value.getContext('2d')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (infoParams.Ismeasure !== 1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const rect =
|
||||||
|
type === 'L'
|
||||||
|
? topCanvas.value.getBoundingClientRect()
|
||||||
|
: topCanvas1.value.getBoundingClientRect()
|
||||||
|
const x = event.clientX - rect.left
|
||||||
|
const y = event.clientY - rect.top
|
||||||
|
|
||||||
|
if (lastPoint.value) {
|
||||||
|
// 如果已经有一个点被记录,那么使用这个新点和上一个点绘制线条
|
||||||
|
drawLineAndDistance(lastPoint.value, { x, y })
|
||||||
|
lastPoint.value = null // 重置上一个点
|
||||||
|
} else {
|
||||||
|
// 记录这个点作为上一个点
|
||||||
|
lastPoint.value = { x, y }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateDistance(x1, y1, x2, y2) {
|
||||||
|
return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2))
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawLineAndDistance(point1, point2) {
|
||||||
|
//ctx.value.clearRect(0, 0, topCanvas.value.width, topCanvas.value.height); // 清除画布
|
||||||
|
|
||||||
|
// 绘制两个点
|
||||||
|
ctx.value.fillStyle = 'black'
|
||||||
|
ctx.value.beginPath()
|
||||||
|
ctx.value.arc(point1.x, point1.y, 1, 0, 2 * Math.PI)
|
||||||
|
ctx.value.fill()
|
||||||
|
ctx.value.beginPath()
|
||||||
|
ctx.value.arc(point2.x, point2.y, 1, 0, 2 * Math.PI)
|
||||||
|
ctx.value.fill()
|
||||||
|
|
||||||
|
// 绘制直线
|
||||||
|
ctx.value.beginPath()
|
||||||
|
ctx.value.moveTo(point1.x, point1.y)
|
||||||
|
ctx.value.lineTo(point2.x, point2.y)
|
||||||
|
ctx.value.strokeStyle = 'black'
|
||||||
|
ctx.value.lineWidth = 1
|
||||||
|
ctx.value.stroke()
|
||||||
|
|
||||||
|
// 计算并绘制距离文本
|
||||||
|
const distance = calculateDistance(point1.x, point1.y, point2.x, point2.y)
|
||||||
|
ctx.value.font = '11px Arial'
|
||||||
|
ctx.value.fillStyle = 'black'
|
||||||
|
ctx.value.fillText(`距离: ${distance.toFixed(2)}px`, point1.x + 10, point1.y - 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*鼠标绘制相关*/
|
||||||
|
|
||||||
|
const handleSliderChange = (value) => {
|
||||||
|
if (value > previousValue.value) {
|
||||||
|
swipeDirection.value = '右滑' // 向右滑动
|
||||||
|
moveCanvas('left')
|
||||||
|
} else if (value < previousValue.value) {
|
||||||
|
swipeDirection.value = '左滑' // 向左滑动
|
||||||
|
moveCanvas('right')
|
||||||
|
} else {
|
||||||
|
swipeDirection.value = '未滑动' // 没有滑动
|
||||||
|
}
|
||||||
|
previousValue.value = value // 更新上一个值
|
||||||
|
console.log('滑块值改变为:', value)
|
||||||
|
}
|
||||||
|
|
||||||
|
//渲染组件后执行
|
||||||
|
onMounted(async () => {
|
||||||
|
console.log('挂载完成' + infoParams.Isgrid)
|
||||||
|
// topCanvas.value = document.getElementById('topCanvas');
|
||||||
|
})
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
var canvasContainer = document.getElementById('canvas-container')
|
||||||
|
var canvasContainer1 = document.getElementById('canvas-container1')
|
||||||
|
// 获取元素的计算后的样式
|
||||||
|
var style = window.getComputedStyle(canvasContainer)
|
||||||
|
|
||||||
|
// 获取宽度
|
||||||
|
var widthPercentage = style.width
|
||||||
|
|
||||||
|
var widthInPixels = canvasContainer.offsetWidth
|
||||||
|
// 宽度除以 20 并取整
|
||||||
|
var adjustedWidth = widthInPixels / 20
|
||||||
|
// 判断 adjustedWidth 是否为整数
|
||||||
|
if (Number.isInteger(adjustedWidth)) {
|
||||||
|
canvasContainer.style.width = widthInPixels + 'px'
|
||||||
|
} else {
|
||||||
|
const integer = Math.round(adjustedWidth)
|
||||||
|
const awidth = integer * 20
|
||||||
|
canvasContainer.style.width = awidth - 20 + 'px'
|
||||||
|
canvasContainer1.style.width = awidth - 20 + 'px'
|
||||||
|
console.log('adjustedWidth 不是整数')
|
||||||
|
}
|
||||||
|
fetchData()
|
||||||
|
})
|
||||||
|
// 定义异步方法
|
||||||
|
const fetchData = async () => {
|
||||||
|
try {
|
||||||
|
text.value = await fetchFileContent(infoParams.jsonurl)
|
||||||
|
handleFileChange()
|
||||||
|
Bottom()
|
||||||
|
// console.log('获取到的数据:', text.value);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取数据时出错:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const inputSlider = (value) => {
|
||||||
|
setScrollTop(value)
|
||||||
|
}
|
||||||
|
const formatTooltip = (value) => {
|
||||||
|
return `${value} px`
|
||||||
|
}
|
||||||
|
async function fetchFileContent(url) {
|
||||||
|
try {
|
||||||
|
const response = await fetch(url)
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('网络响应不是 ok')
|
||||||
|
}
|
||||||
|
return await response.text() // 返回文本内容
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取文件内容时出错:', error)
|
||||||
|
throw error // 抛出错误以便调用者可以处理
|
||||||
|
}
|
||||||
|
}
|
||||||
|
///接受参数
|
||||||
|
const infoParams = defineProps({
|
||||||
|
jsonurl: String,
|
||||||
|
examId: String,
|
||||||
|
Isgrid: Number,
|
||||||
|
Ismeasure: Number,
|
||||||
|
Isfd: Boolean
|
||||||
|
})
|
||||||
|
|
||||||
|
// // 使用 watch 来监听 parentValue 的变化
|
||||||
|
// watch(
|
||||||
|
// () => infoParams.Isgrid,
|
||||||
|
// (newValue, oldValue) => {
|
||||||
|
// console.log(`Isgrid 从 ${oldValue} 变化到 ${newValue}`)
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// 监听多个值的变化
|
||||||
|
watch(
|
||||||
|
[() => infoParams.Isgrid, () => infoParams.Ismeasure],
|
||||||
|
([newIsGridValue, newAnotherValue], [oldIsGridView, oldAnotherValue]) => {
|
||||||
|
// 检查 isGrid 是否发生变化
|
||||||
|
if (newIsGridValue !== oldIsGridView) {
|
||||||
|
console.log(`isGrid 从 ${oldIsGridView} 变化到 ${newIsGridValue}`)
|
||||||
|
// 值发送变化的时候 重新绘制 先清除画布
|
||||||
|
|
||||||
|
eliminate(leftCanvas.value)
|
||||||
|
eliminate(rightCanvas.value)
|
||||||
|
eliminate(bottomCanvas.value)
|
||||||
|
eliminate(bottomCanvas1.value)
|
||||||
|
eliminate(topCanvas.value)
|
||||||
|
eliminate(topCanvas1.value)
|
||||||
|
Bottom()
|
||||||
|
}
|
||||||
|
// 检查 anotherValue 是否发生变化
|
||||||
|
if (newAnotherValue !== oldAnotherValue) {
|
||||||
|
console.log(`anotherValue 从 ${oldAnotherValue} 变化到 ${newAnotherValue}`)
|
||||||
|
// 是否开启测量
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// 响应式数据
|
||||||
|
let beatArray1 = []
|
||||||
|
let offset = 0
|
||||||
|
const spacing = 20
|
||||||
|
|
||||||
|
// 定义要处理的键
|
||||||
|
const leads = [
|
||||||
|
'LEAD_I',
|
||||||
|
'LEAD_II',
|
||||||
|
'LEAD_III',
|
||||||
|
'LEAD_AVR',
|
||||||
|
'LEAD_AVL',
|
||||||
|
'LEAD_AVF',
|
||||||
|
'LEAD_V1',
|
||||||
|
'LEAD_V2',
|
||||||
|
'LEAD_V3',
|
||||||
|
'LEAD_V4',
|
||||||
|
'LEAD_V5',
|
||||||
|
'LEAD_V6'
|
||||||
|
]
|
||||||
|
|
||||||
|
// 每个心电波形名称数组
|
||||||
|
const lead_name = ['I', 'II', 'III', 'aVR', 'aVL', 'aVF']
|
||||||
|
|
||||||
|
const rlead_name = ['V1', 'V2', 'V3', 'V4', 'V5', 'V6']
|
||||||
|
|
||||||
|
//将读取到的文件转换成数组
|
||||||
|
function handleFileChange() {
|
||||||
|
const json = JSON.parse(text.value)
|
||||||
|
leads.forEach((lead, index) => {
|
||||||
|
const value = json[lead].trim()
|
||||||
|
const commaSeparatedValue = value.replace(/\s+/g, ',')
|
||||||
|
const numberArray = commaSeparatedValue.split(',').map(Number)
|
||||||
|
beatArray1.push(numberArray)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义移动画布的函数
|
||||||
|
function moveCanvas(direction) {
|
||||||
|
if (direction === 'left') {
|
||||||
|
if (offset !== -20 * 40) offset -= spacing
|
||||||
|
} else if (direction === 'right') {
|
||||||
|
if (offset !== 0) offset += spacing
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (direction === 'left') {
|
||||||
|
// offset -= spacing
|
||||||
|
// } else if (direction === 'right') {
|
||||||
|
// offset += spacing
|
||||||
|
// }
|
||||||
|
topCanvas.value.style.left = offset + 'px'
|
||||||
|
topCanvas1.value.style.left = offset + 'px'
|
||||||
|
}
|
||||||
|
|
||||||
|
//清除画布内容
|
||||||
|
function eliminate(c_canvas) {
|
||||||
|
const ctx = c_canvas.getContext('2d')
|
||||||
|
ctx.clearRect(0, 0, c_canvas.width, c_canvas.height)
|
||||||
|
}
|
||||||
|
function Bottom() {
|
||||||
|
drawBottomCanvas()
|
||||||
|
drawTopCanvas()
|
||||||
|
}
|
||||||
|
// 绘制底层画布的内容
|
||||||
|
function drawBottomCanvas() {
|
||||||
|
if (infoParams.Isgrid === 1) {
|
||||||
|
lbackcanvas(leftCanvas.value)
|
||||||
|
rbackcanvas(rightCanvas.value)
|
||||||
|
drawMultipleLines(bottomCanvas.value, beatArray1)
|
||||||
|
drawMultipleLines(bottomCanvas1.value, beatArray1)
|
||||||
|
}
|
||||||
|
begin(leftCanvas.value, beatArray1)
|
||||||
|
beginr(rightCanvas.value, beatArray1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绘制顶层画布的内容
|
||||||
|
function drawTopCanvas() {
|
||||||
|
drawMultipleLinesl(topCanvas.value, beatArray1)
|
||||||
|
drawMultipleLinesr(topCanvas1.value, beatArray1)
|
||||||
|
}
|
||||||
|
//定标电压的画布
|
||||||
|
function lbackcanvas(c_canvas) {
|
||||||
|
drawBigBG(c_canvas)
|
||||||
|
drawSmallGrid(c_canvas)
|
||||||
|
drawMediumGrid(c_canvas)
|
||||||
|
}
|
||||||
|
function rbackcanvas(c_canvas) {
|
||||||
|
drawBigBG(c_canvas)
|
||||||
|
drawSmallGrid(c_canvas)
|
||||||
|
drawMediumGrid(c_canvas)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绘制函数
|
||||||
|
function drawBigBG(c_canvas) {
|
||||||
|
const context = c_canvas.getContext('2d')
|
||||||
|
context.globalAlpha = 1
|
||||||
|
context.fillStyle = 'rgba(0,0,0,0)'
|
||||||
|
context.fillRect(0, 0, c_canvas.width + 21, c_canvas.height + 21)
|
||||||
|
}
|
||||||
|
//画小格子
|
||||||
|
function drawSmallGrid(c_canvas) {
|
||||||
|
const context = c_canvas.getContext('2d')
|
||||||
|
context.globalAlpha = 1
|
||||||
|
context.fillStyle = '#ff6b64'
|
||||||
|
const dotMarginX = 20 / 5,
|
||||||
|
dotMarginY = 20 / 5
|
||||||
|
for (let i = dotMarginX; i < c_canvas.width; i += dotMarginX) {
|
||||||
|
if (i % 20 !== 0) {
|
||||||
|
for (let j = dotMarginY; j < c_canvas.height; j += dotMarginY) {
|
||||||
|
if (j % 20 !== 0) {
|
||||||
|
context.rect(i, j, 1, 0.5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
context.fill()
|
||||||
|
}
|
||||||
|
//中格子
|
||||||
|
function drawMediumGrid(c_canvas) {
|
||||||
|
const context = c_canvas.getContext('2d')
|
||||||
|
context.globalAlpha = 1
|
||||||
|
context.strokeStyle = '#ff6b64'
|
||||||
|
context.strokeWidth = 1.5
|
||||||
|
context.beginPath()
|
||||||
|
for (let x = 0.5; x < c_canvas.width; x += 20) {
|
||||||
|
context.moveTo(x, 0)
|
||||||
|
context.lineTo(x, c_canvas.height)
|
||||||
|
}
|
||||||
|
for (let y = 0.5; y < c_canvas.height; y += 20) {
|
||||||
|
context.moveTo(0, y)
|
||||||
|
context.lineTo(c_canvas.width, y)
|
||||||
|
}
|
||||||
|
context.stroke()
|
||||||
|
context.closePath()
|
||||||
|
}
|
||||||
|
|
||||||
|
function begin(c_canvas, beatArray) {
|
||||||
|
const ctx = c_canvas.getContext('2d')
|
||||||
|
ctx.globalAlpha = 1
|
||||||
|
ctx.strokeStyle = '#000000'
|
||||||
|
let offset = -50
|
||||||
|
const spacing = 100
|
||||||
|
beatArray.forEach((dataArray, index) => {
|
||||||
|
if (index <= 6) {
|
||||||
|
const x = 0
|
||||||
|
const y = offset - dataArray[index - 1] * 0.025
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.moveTo(x, y)
|
||||||
|
ctx.lineTo(x + 5, y)
|
||||||
|
ctx.moveTo(x + 5, y - 40)
|
||||||
|
ctx.lineTo(x + 15, y - 40)
|
||||||
|
ctx.moveTo(x + 5, y - 40)
|
||||||
|
ctx.lineTo(x + 5, y)
|
||||||
|
ctx.moveTo(x + 15, y - 40)
|
||||||
|
ctx.lineTo(x + 15, y)
|
||||||
|
ctx.moveTo(x + 15, y)
|
||||||
|
ctx.lineTo(x + 20, y)
|
||||||
|
ctx.stroke()
|
||||||
|
ctx.closePath()
|
||||||
|
if (index > 0 && index < 4) {
|
||||||
|
ctx.font = '15px Arial'
|
||||||
|
ctx.fillStyle = 'black'
|
||||||
|
ctx.fillText(lead_name[index - 1], x + 4, y + 14)
|
||||||
|
} else {
|
||||||
|
ctx.font = '10px Arial'
|
||||||
|
ctx.fillStyle = 'black'
|
||||||
|
ctx.fillText(lead_name[index - 1], x + 1, y + 12)
|
||||||
|
}
|
||||||
|
offset += spacing
|
||||||
|
}
|
||||||
|
})
|
||||||
|
ctx.strokeStyle = '#000000'
|
||||||
|
}
|
||||||
|
|
||||||
|
function beginr(c_canvas, beatArray) {
|
||||||
|
const ctx = c_canvas.getContext('2d')
|
||||||
|
ctx.globalAlpha = 1
|
||||||
|
ctx.strokeStyle = '#000000'
|
||||||
|
let offset = -50
|
||||||
|
const spacing = 100
|
||||||
|
beatArray.forEach((dataArray, index) => {
|
||||||
|
if (index <= 6) {
|
||||||
|
const x = 0
|
||||||
|
const y = offset - dataArray[index - 1] * 0.025
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.moveTo(x, y)
|
||||||
|
ctx.lineTo(x + 5, y)
|
||||||
|
ctx.moveTo(x + 5, y - 40)
|
||||||
|
ctx.lineTo(x + 15, y - 40)
|
||||||
|
ctx.moveTo(x + 5, y - 40)
|
||||||
|
ctx.lineTo(x + 5, y)
|
||||||
|
ctx.moveTo(x + 15, y - 40)
|
||||||
|
ctx.lineTo(x + 15, y)
|
||||||
|
ctx.moveTo(x + 15, y)
|
||||||
|
ctx.lineTo(x + 20, y)
|
||||||
|
ctx.stroke()
|
||||||
|
ctx.closePath()
|
||||||
|
ctx.font = '11px Arial'
|
||||||
|
ctx.fillStyle = 'black'
|
||||||
|
ctx.fillText(rlead_name[index - 1], x + 2, y + 12)
|
||||||
|
offset += spacing
|
||||||
|
}
|
||||||
|
})
|
||||||
|
ctx.strokeStyle = '#000000'
|
||||||
|
}
|
||||||
|
|
||||||
|
//背景
|
||||||
|
function drawMultipleLines(c_canvas, beatArrays) {
|
||||||
|
const ctx = c_canvas.getContext('2d')
|
||||||
|
ctx.clearRect(0, 0, c_canvas.width, c_canvas.height)
|
||||||
|
drawBigBG(c_canvas)
|
||||||
|
drawSmallGrid(c_canvas)
|
||||||
|
drawMediumGrid(c_canvas)
|
||||||
|
}
|
||||||
|
//左边心电图
|
||||||
|
function drawMultipleLinesl(c_canvas, beatArrays) {
|
||||||
|
const ctx = c_canvas.getContext('2d')
|
||||||
|
ctx.clearRect(0, 0, c_canvas.width, c_canvas.height)
|
||||||
|
let offset = 0
|
||||||
|
const spacing = 100
|
||||||
|
beatArrays.forEach((dataArray, index) => {
|
||||||
|
if (index <= 5) {
|
||||||
|
drawLine1(c_canvas, dataArray, offset, index)
|
||||||
|
offset += spacing
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//右边心电图
|
||||||
|
function drawMultipleLinesr(c_canvas, beatArrays) {
|
||||||
|
const ctx = c_canvas.getContext('2d')
|
||||||
|
ctx.clearRect(0, 0, c_canvas.width, c_canvas.height)
|
||||||
|
let offset = 0
|
||||||
|
const spacing = 100
|
||||||
|
beatArrays.forEach((dataArray, index) => {
|
||||||
|
if (index > 5) {
|
||||||
|
drawLine1(c_canvas, dataArray, offset, index)
|
||||||
|
offset += spacing
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//画心电图线
|
||||||
|
function drawLine1(c_canvas, beatArray, offset, index) {
|
||||||
|
const ctx = c_canvas.getContext('2d')
|
||||||
|
ctx.strokeStyle = '#030101'
|
||||||
|
ctx.lineWidth = 1
|
||||||
|
ctx.beginPath()
|
||||||
|
if (index <= 5) {
|
||||||
|
if (beatArray.length > 0) {
|
||||||
|
const firstX = 0
|
||||||
|
const firstY = 50 - beatArray[0] * 0.025 + offset
|
||||||
|
ctx.moveTo(firstX, firstY)
|
||||||
|
for (let i = 0; i < beatArray.length - 1; i++) {
|
||||||
|
const x2 = 0 + (i + 1) / 10
|
||||||
|
const y2 = 50 - beatArray[i + 1] * 0.025 + offset
|
||||||
|
ctx.lineTo(x2, y2)
|
||||||
|
}
|
||||||
|
ctx.stroke()
|
||||||
|
ctx.closePath()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (index > 5) {
|
||||||
|
if (beatArray.length > 0) {
|
||||||
|
const firstX = 0
|
||||||
|
const firstY = 50 - beatArray[0] * 0.025 + offset
|
||||||
|
ctx.moveTo(firstX, firstY)
|
||||||
|
for (let i = 0; i < beatArray.length - 1; i++) {
|
||||||
|
const x2 = 0 + (i + 1) / 10
|
||||||
|
const y2 = 50 - beatArray[i + 1] * 0.025 + offset
|
||||||
|
ctx.lineTo(x2, y2)
|
||||||
|
}
|
||||||
|
ctx.stroke()
|
||||||
|
ctx.closePath()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-start;
|
||||||
|
width: 100%;
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden;
|
||||||
|
height: 600px;
|
||||||
|
max-width: 3920px;
|
||||||
|
}
|
||||||
|
#canvas-container,
|
||||||
|
#canvas-container1 {
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: hidden;
|
||||||
|
position: relative;
|
||||||
|
width: 50%;
|
||||||
|
height: 600px;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
#bottomCanvas,
|
||||||
|
#bottomCanvas1 {
|
||||||
|
position: absolute;
|
||||||
|
/* width: 1140; */
|
||||||
|
height: 600px;
|
||||||
|
z-index: 0;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
#leftCanvas,
|
||||||
|
#rightCanvas {
|
||||||
|
position: absolute;
|
||||||
|
width: 21;
|
||||||
|
height: 600px;
|
||||||
|
z-index: 99;
|
||||||
|
background-color: rgb(255, 255, 255);
|
||||||
|
}
|
||||||
|
#topCanvas,
|
||||||
|
#topCanvas1 {
|
||||||
|
position: absolute;
|
||||||
|
width: 1140px;
|
||||||
|
height: 600px;
|
||||||
|
z-index: 1;
|
||||||
|
background: transparent;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
canvas {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
/* 添加其他样式 */
|
||||||
|
</style>
|
556
src/views/tblist/patientexamlistECG/index.vue
Normal file
556
src/views/tblist/patientexamlistECG/index.vue
Normal file
@ -0,0 +1,556 @@
|
|||||||
|
<template>
|
||||||
|
<ContentWrap style="height: 145px">
|
||||||
|
<!-- 搜索工作栏 超声工作站-->
|
||||||
|
<el-form
|
||||||
|
class="-mb-15px"
|
||||||
|
:model="queryParams"
|
||||||
|
ref="queryFormRef"
|
||||||
|
:inline="true"
|
||||||
|
label-width="100px"
|
||||||
|
>
|
||||||
|
<el-row :gutter="8">
|
||||||
|
<!-- 检查ID和患者姓名共一行 -->
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-row :gutter="8">
|
||||||
|
<el-col :span="4">
|
||||||
|
<el-form-item label="检查单号" prop="examId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.examId"
|
||||||
|
placeholder="检查单号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-160px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="4">
|
||||||
|
<el-form-item label="患者姓名" prop="pName">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.pname"
|
||||||
|
placeholder="请输入患者姓名"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-160px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<!-- 报告状态 -->
|
||||||
|
<el-col :span="4">
|
||||||
|
<el-form-item label="报告状态" prop="reportstatus">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.reportstatus"
|
||||||
|
placeholder="请选择报告状态"
|
||||||
|
clearable
|
||||||
|
class="!w-160px"
|
||||||
|
>
|
||||||
|
<el-option label="已分检" value="已分检" />
|
||||||
|
<el-option label="已分析" value="已分析" />
|
||||||
|
<el-option label="待分析" value="待分析" />
|
||||||
|
<el-option label="已审核" value="已审核" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<!-- 检查项目 -->
|
||||||
|
<el-col :span="4">
|
||||||
|
<el-form-item label="检查项目" prop="examItemName">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.examItemName"
|
||||||
|
placeholder="请输入检查项"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-160px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<!-- 检查日期独占一行 -->
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="检查日期" prop="examDate">
|
||||||
|
<!-- aaaaa -->
|
||||||
|
<el-radio-group
|
||||||
|
ref="examDate_radio"
|
||||||
|
v-model="examDate_radio_value"
|
||||||
|
@change="examDate_radio_change"
|
||||||
|
>
|
||||||
|
<el-radio style="margin-right: 15px" :value="0">全部</el-radio>
|
||||||
|
<el-radio style="margin-right: 15px" :value="1">今天</el-radio>
|
||||||
|
<el-radio style="margin-right: 15px" :value="2">昨天</el-radio>
|
||||||
|
<el-radio style="margin-right: 15px" :value="3">三天内</el-radio>
|
||||||
|
<el-radio style="margin-right: 15px" :value="4">一周</el-radio>
|
||||||
|
<el-radio style="margin-right: 25px" :value="5">
|
||||||
|
<el-date-picker
|
||||||
|
ref="examDate_picker"
|
||||||
|
:disabled="examDate_radio_value === 5 ? false : true"
|
||||||
|
v-model="queryParams.examDate"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
type="daterange"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button
|
||||||
|
@click="handleQuery"
|
||||||
|
style="
|
||||||
|
margin-right: 0px;
|
||||||
|
margin-left: auto;
|
||||||
|
background-color: rgba(56, 119, 246, 1);
|
||||||
|
font-size: 14px;
|
||||||
|
color: rgba(255, 255, 255, 1);
|
||||||
|
"
|
||||||
|
><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button
|
||||||
|
>
|
||||||
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</ContentWrap>
|
||||||
|
<ContentWrap style="height: 65px">
|
||||||
|
<el-form-item>
|
||||||
|
<!-- <el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="openForm('create')"
|
||||||
|
v-hasPermi="['tblist:patientexamlist:create']"
|
||||||
|
v-if="false"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||||
|
</el-button> -->
|
||||||
|
<el-button
|
||||||
|
style="
|
||||||
|
margin-right: 0px;
|
||||||
|
margin-left: auto;
|
||||||
|
background-color: rgb(56, 119, 246);
|
||||||
|
font-size: 14px;
|
||||||
|
color: rgb(255, 255, 255);
|
||||||
|
"
|
||||||
|
@click="handleExport"
|
||||||
|
:loading="exportLoading"
|
||||||
|
v-hasPermi="['tblist:patientexamlist:export']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
@click="dicomDataSync"
|
||||||
|
style="background-color: rgb(28, 176, 117); font-size: 14; color: rgb(255, 255, 255)"
|
||||||
|
><Icon icon="ep:refresh" class="mr-5px" /> 同步</el-button
|
||||||
|
>
|
||||||
|
<el-button
|
||||||
|
@click="selectcollect"
|
||||||
|
style="background-color: rgb(28, 176, 117); font-size: 14; color: rgb(255, 255, 255)"
|
||||||
|
><Icon icon="ep:search" class="mr-5px" /> 查询收藏</el-button
|
||||||
|
>
|
||||||
|
</el-form-item>
|
||||||
|
</ContentWrap>
|
||||||
|
<!-- 列表 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<el-table
|
||||||
|
v-loading="loading"
|
||||||
|
:data="list"
|
||||||
|
:stripe="true"
|
||||||
|
:show-overflow-tooltip="true"
|
||||||
|
@row-dblclick="handleEdit"
|
||||||
|
:header-cell-style="{ background: 'rgb(235, 241, 250)', height: '56px', color: '#333333' }"
|
||||||
|
:row-style="{ height: '56px' }"
|
||||||
|
>
|
||||||
|
<el-table-column type="index" width="50px" />
|
||||||
|
<el-table-column label="" width="100px" v-if="false">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-image :src="scope.row.thumbnailImgUrl" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="主键" align="center" prop="id" v-if="false" />
|
||||||
|
<el-table-column label="检查项目名称" align="center" prop="examItemName" width="160px" />
|
||||||
|
<el-table-column label="检查单号" align="center" prop="examId" width="140px" />
|
||||||
|
<el-table-column label="患者姓名" align="center" prop="pname" />
|
||||||
|
<el-table-column label="性别" align="center" prop="gender" />
|
||||||
|
<el-table-column label="出生日期" align="center" prop="birthday" v-if="false" />
|
||||||
|
<el-table-column
|
||||||
|
label="检查日期"
|
||||||
|
align="center"
|
||||||
|
prop="examDate"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column label="设备类型" align="center" prop="deviceType" />
|
||||||
|
<el-table-column label="序列/数量" align="center" prop="seDc" width="100px" />
|
||||||
|
|
||||||
|
<el-table-column label="报告状态" align="center" prop="reportstatus" width="100px">
|
||||||
|
<template #default="scope">
|
||||||
|
<!-- 使用Flexbox布局将内容垂直排列 -->
|
||||||
|
<div style="display: flex; flex-direction: column; align-items: center">
|
||||||
|
<div>
|
||||||
|
<el-tag :type="scope.row.reportstatus === '已审核' ? 'danger' : 'success'">
|
||||||
|
<span style="">{{ scope.row.reportstatus }}</span>
|
||||||
|
</el-tag>
|
||||||
|
</div>
|
||||||
|
<!-- 根据highLevelOrgId是否为空判断是否显示"已申请" -->
|
||||||
|
<div v-if="scope.row.highLevelOrgId">
|
||||||
|
<el-tag>
|
||||||
|
<span>已申请</span>
|
||||||
|
</el-tag>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
label="申请日期"
|
||||||
|
align="center"
|
||||||
|
prop="applicationDate"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
label="上传时间"
|
||||||
|
align="center"
|
||||||
|
prop="uploadDate"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column label="机构名称" align="center" prop="orgName" width="180px" />
|
||||||
|
<el-table-column label="机构ID" align="center" prop="orgId" v-if="false" />
|
||||||
|
<el-table-column
|
||||||
|
label="上级判读机构id列表:orgid1,orgid2,orgid3"
|
||||||
|
align="center"
|
||||||
|
prop="highLevelOrgId"
|
||||||
|
v-if="false"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
label="创建时间:年月日时分秒"
|
||||||
|
align="center"
|
||||||
|
prop="createDate"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
v-if="false"
|
||||||
|
/>
|
||||||
|
<el-table-column label="检查所见" align="center" prop="examDescription" v-if="false" />
|
||||||
|
<el-table-column label="诊断结论" align="center" prop="diagResults" v-if="false" />
|
||||||
|
<el-table-column
|
||||||
|
label="下诊断结论的时间:年月日时分秒"
|
||||||
|
align="center"
|
||||||
|
prop="diagDate"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
v-if="false"
|
||||||
|
/>
|
||||||
|
<el-table-column label="诊断医生" align="center" prop="diagDoctor" v-if="false" />
|
||||||
|
<el-table-column label="审核医生" align="center" prop="reviewDoctor" v-if="false" />
|
||||||
|
<el-table-column
|
||||||
|
label="审核日期:年月日时分秒"
|
||||||
|
align="center"
|
||||||
|
prop="reviewDate"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
v-if="false"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
label="框架需要:创建时间"
|
||||||
|
align="center"
|
||||||
|
prop="createTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
v-if="false"
|
||||||
|
/>
|
||||||
|
<el-table-column label="操作" align="center" fixed="right">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
@click="getuporghiorgid(scope.row.id, scope.row.orgId, scope.row.reportstatus)"
|
||||||
|
v-hasPermi="['tblist:patientexamlist:query']"
|
||||||
|
style="color: rgb(56, 119, 246)"
|
||||||
|
>
|
||||||
|
申请
|
||||||
|
</el-button>
|
||||||
|
<el-button link type="danger" @click="collect(scope.row.id, scope.row.isFavourite)">
|
||||||
|
<el-icon v-if="scope.row.isFavourite === '1'"><StarFilled /></el-icon>
|
||||||
|
<el-icon v-else><Star /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<Pagination
|
||||||
|
:total="total"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 表单弹窗:超声组件 -->
|
||||||
|
<ECGForm ref="ECG" @success="getList" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { dateFormatter, beginOfDay } from '@/utils/formatTime'
|
||||||
|
import download from '@/utils/download'
|
||||||
|
import { PatientexamlistApi, PatientexamlistVO } from '@/api/tblist/patientexamlist'
|
||||||
|
import ECGForm from '/src/views/ECG/ECGForm.vue'
|
||||||
|
|
||||||
|
/** PACS检查列表 列表 */
|
||||||
|
defineOptions({ name: 'PatientexamlistECG' })
|
||||||
|
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
|
const loading = ref(true) // 列表的加载中
|
||||||
|
const list = ref<PatientexamlistVO[]>([]) // 列表的数据
|
||||||
|
const total = ref(0) // 列表的总页数
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
examId: undefined,
|
||||||
|
pname: undefined,
|
||||||
|
gender: undefined,
|
||||||
|
birthday: undefined,
|
||||||
|
examDate: [] as any[],
|
||||||
|
deviceType: '',
|
||||||
|
seDc: undefined,
|
||||||
|
examItemName: undefined,
|
||||||
|
reportstatus: '',
|
||||||
|
applicationDate: [],
|
||||||
|
uploadDate: [],
|
||||||
|
orgName: undefined,
|
||||||
|
orgId: '',
|
||||||
|
highLevelOrgId: '',
|
||||||
|
createDate: [],
|
||||||
|
examDescription: undefined,
|
||||||
|
diagResults: undefined,
|
||||||
|
diagDate: [],
|
||||||
|
diagDoctor: undefined,
|
||||||
|
reviewDoctor: undefined,
|
||||||
|
reviewDate: [],
|
||||||
|
thumbnailImgUrl: undefined,
|
||||||
|
createTime: [],
|
||||||
|
isFavourite: ''
|
||||||
|
})
|
||||||
|
const queryFormRef = ref() // 搜索的表单
|
||||||
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
|
|
||||||
|
/** 超声组件 */
|
||||||
|
const ECG = ref()
|
||||||
|
const openultrForm = (row:any) => {
|
||||||
|
ECG.value.open(row)
|
||||||
|
}
|
||||||
|
/** 表格行点击 */
|
||||||
|
const clickNumber = ref(0)
|
||||||
|
function handleEdit(row) {
|
||||||
|
console.log(111111121212)
|
||||||
|
if (row.deviceType.includes('US')) {
|
||||||
|
//US是超声类
|
||||||
|
openultrForm(row)
|
||||||
|
|
||||||
|
/* clickNumber.value++;
|
||||||
|
if (clickNumber.value == 2) {
|
||||||
|
|
||||||
|
}
|
||||||
|
clickNumber.value = 0; */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** aaaaa **/
|
||||||
|
const examDate_picker = ref(null)
|
||||||
|
const examDate_radio = ref(null)
|
||||||
|
const examDate_radio_value = ref(1)
|
||||||
|
|
||||||
|
const examDate_radio_change = () => {
|
||||||
|
if ([1, 2, 3, 4].includes(examDate_radio_value.value)) {
|
||||||
|
let timesta = beginOfDay(new Date())
|
||||||
|
let timeend = beginOfDay(new Date())
|
||||||
|
timeend.setDate(timeend.getDate() + 1)
|
||||||
|
//判断当前选择的是那个时间
|
||||||
|
if (examDate_radio_value.value === 1) {
|
||||||
|
queryParams.examDate = [nowDate(timesta), nowDate(timeend)]
|
||||||
|
} else if (examDate_radio_value.value === 2) {
|
||||||
|
timesta.setDate(timesta.getDate() - 1)
|
||||||
|
timeend.setDate(timeend.getDate() - 1)
|
||||||
|
queryParams.examDate = [nowDate(timesta), nowDate(timeend)]
|
||||||
|
} else if (examDate_radio_value.value === 3) {
|
||||||
|
timesta.setDate(timesta.getDate() - 2)
|
||||||
|
queryParams.examDate = [nowDate(timesta), nowDate(timeend)]
|
||||||
|
} else if (examDate_radio_value.value === 4) {
|
||||||
|
timesta.setDate(timesta.getDate() - 6)
|
||||||
|
queryParams.examDate = [nowDate(timesta), nowDate(timeend)]
|
||||||
|
}
|
||||||
|
|
||||||
|
handleQuery()
|
||||||
|
} else if (5 === examDate_radio_value.value) {
|
||||||
|
queryParams.examDate = []
|
||||||
|
} else if (0 === examDate_radio_value.value) {
|
||||||
|
queryParams.examDate = []
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///转换时间格式
|
||||||
|
function nowDate(time) {
|
||||||
|
var year = time.getFullYear() // 年
|
||||||
|
var month = (time.getMonth() + 1).toString().padStart(2, '0') // 月
|
||||||
|
var date = time.getDate().toString().padStart(2, '0') // 日
|
||||||
|
var hour = time.getHours().toString().padStart(2, '0') // 时
|
||||||
|
var minute = time.getMinutes().toString().padStart(2, '0') // 分
|
||||||
|
var second = time.getSeconds().toString().padStart(2, '0') // 秒
|
||||||
|
return year + '-' + month + '-' + date + ' ' + hour + ':' + minute + ':' + second
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 查询列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
queryParams.deviceType = 'US'
|
||||||
|
const data = await PatientexamlistApi.getPatientexamlistPage(queryParams)
|
||||||
|
list.value = data.list
|
||||||
|
total.value = data.total
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 只查询收藏的数据
|
||||||
|
const selectcollect = () => {
|
||||||
|
queryFormRef.value.resetFields()
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
queryParams.deviceType = 'US'
|
||||||
|
queryParams.isFavourite = '1'
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 收藏功能
|
||||||
|
const collect = async (id: string, isFavourite: string) => {
|
||||||
|
if (isFavourite == '0') {
|
||||||
|
await PatientexamlistApi.CollectAndCancellation(id, '1')
|
||||||
|
message.success('收藏成功')
|
||||||
|
} else if (isFavourite == '1') {
|
||||||
|
await PatientexamlistApi.CollectAndCancellation(id, '0')
|
||||||
|
message.success('取消成功')
|
||||||
|
}
|
||||||
|
examDate_radio_change()
|
||||||
|
}
|
||||||
|
|
||||||
|
const dicomDataSync = async () => {
|
||||||
|
const data = await PatientexamlistApi.dicomDataSync()
|
||||||
|
if (data.code == 'success') {
|
||||||
|
if (data.syncItems == '0') {
|
||||||
|
message.info('暂无可同步数据')
|
||||||
|
} else {
|
||||||
|
queryParams.reportstatus = '待分析'
|
||||||
|
examDate_radio_value.value = 0
|
||||||
|
examDate_radio_change()
|
||||||
|
message.success('数据同步成功')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
message.error('数据同步失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
queryParams.isFavourite = ''
|
||||||
|
queryParams.deviceType = 'US'
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryFormRef.value.resetFields()
|
||||||
|
|
||||||
|
/** aaaaa **/
|
||||||
|
//新写法
|
||||||
|
examDate_radio_value.value = 1
|
||||||
|
examDate_radio_change()
|
||||||
|
if (5 === examDate_radio_value.value) handleQuery()
|
||||||
|
|
||||||
|
//老写法
|
||||||
|
//handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
const formRef = ref()
|
||||||
|
const openForm = (type: string, id?: number) => {
|
||||||
|
formRef.value.open(type, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 申请后更新上级机构字段*/
|
||||||
|
const getuporghiorgid = async (id: number, orgId: string, reportstatus: string) => {
|
||||||
|
try {
|
||||||
|
await message.confirm('是否要进行申请?', '确认提示')
|
||||||
|
const data = await PatientexamlistApi.getuporghiid(id, orgId)
|
||||||
|
if (data == '申请成功') {
|
||||||
|
message.success(t('common.delSuccess'))
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} else {
|
||||||
|
await message.info(data)
|
||||||
|
}
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
const handleDelete = async (id: number) => {
|
||||||
|
try {
|
||||||
|
// 删除的二次确认
|
||||||
|
await message.delConfirm()
|
||||||
|
// 发起删除
|
||||||
|
await PatientexamlistApi.deletePatientexamlist(id)
|
||||||
|
message.success(t('common.delSuccess'))
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
/** 申请按钮操作 */
|
||||||
|
const handleSub = async (id: number) => {
|
||||||
|
try {
|
||||||
|
// 删除的二次确认
|
||||||
|
await message.delConfirm()
|
||||||
|
// 发起删除
|
||||||
|
await PatientexamlistApi.deletePatientexamlist(id)
|
||||||
|
message.success(t('common.delSuccess'))
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
const handleExport = async () => {
|
||||||
|
try {
|
||||||
|
// 导出的二次确认
|
||||||
|
await message.exportConfirm()
|
||||||
|
// 发起导出
|
||||||
|
exportLoading.value = true
|
||||||
|
const data = await PatientexamlistApi.exportPatientexamlist(queryParams)
|
||||||
|
download.excel(data, 'PACS检查列表.xls')
|
||||||
|
} catch {
|
||||||
|
} finally {
|
||||||
|
exportLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 **/
|
||||||
|
onMounted(() => {
|
||||||
|
//在初始化的时候查询到当前登陆用户的机构 和上级机构
|
||||||
|
/** aaaaa **/
|
||||||
|
//新代码
|
||||||
|
examDate_radio_change()
|
||||||
|
if (5 === examDate_radio_value.value) handleQuery()
|
||||||
|
|
||||||
|
//老代码
|
||||||
|
//getList();
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* 为了防止 el-form-item 的标签文本换行,可以添加以下CSS样式 */
|
||||||
|
.el-form-item__label {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue
Block a user