From fbb37cbba51cf4fff14cafad214935516434ac92 Mon Sep 17 00:00:00 2001
From: zhangchen <1652267879@qq.com>
Date: 星期五, 25 七月 2025 01:43:50 +0800
Subject: [PATCH] ID1625-暂存
---
src/views/mobile/bedsideAuxiliaryScreen/components/Header.vue | 73 ++++++++++++++
src/store/type/bedsideAuxiliaryScreen.type.ts | 51 +++++++---
src/store/type/task.type.ts | 12 ++
src/views/mobile/bedsideAuxiliaryScreen/components/ScheduledTask.vue | 48 +++++++++
src/store/bedsideAuxiliaryScreen.ts | 69 +++++++++++++
5 files changed, 229 insertions(+), 24 deletions(-)
diff --git a/src/store/bedsideAuxiliaryScreen.ts b/src/store/bedsideAuxiliaryScreen.ts
index 4f07588..11ff7fa 100644
--- a/src/store/bedsideAuxiliaryScreen.ts
+++ b/src/store/bedsideAuxiliaryScreen.ts
@@ -1,8 +1,10 @@
import { defineStore } from "pinia";
import { ref } from "vue";
+import dayjs from "dayjs";
import cache from "../utils/cache";
import { EventSourcePolyfill } from "event-source-polyfill";
-import type { BedsideAuxiliaryScreen } from "./type/bedsideAuxiliaryScreen.type";
+import type { BedsideAuxiliaryScreen, SseMsgData } from "./type/bedsideAuxiliaryScreen.type";
+import type { Task } from "./type/task.type";
import {
defaultDeviceData,
defaultconsumablesCollection,
@@ -19,6 +21,9 @@
/** 设备信息数据 */
const deviceData = ref<BedsideAuxiliaryScreen>(defaultDeviceData());
+ /** 任务列表 */
+ const taskData = ref<Task[]>([]);
+
/**
* 设置设备编号
* @param code
@@ -26,6 +31,47 @@
const setDeviceCode = (code: string) => {
deviceCode.value = code;
cache.set("devcieCode", code);
+ };
+
+ /**
+ * 清除设备信息
+ */
+ const clearDevice = () => {
+ deviceData.value = defaultDeviceData();
+ };
+
+ /**
+ * 追加定时任务
+ * @param taskItem
+ */
+ const pushTask = (taskItem: Task) => {
+ taskData.value.push(taskItem);
+ };
+
+ /**
+ * 是否将当前任务设置为已过期
+ * @param i
+ */
+ // const deleteTask = (i: number) => {
+ // const task = taskData.value[i];
+ // if (task) {
+ // // 二次判断,判断任务时间是否早于或等于当前时间
+ // const taskTime = dayjs(task.taskDate).second(0).millisecond(0);
+ // const now = dayjs().second(0).millisecond(0); // 秒和毫秒都去掉
+ // if (!taskTime.isAfter(now)) {
+ // taskData.value[i].overdue = true
+ // }
+ // }
+ // };
+
+ /** 设置当前定时任务 */
+ const setSyncTask = (taskItem: Task) => {
+ taskData.value = [taskItem];
+ };
+
+ /** 清除当前定时任务 */
+ const clearTask = () => {
+ taskData.value = [];
};
// SSE 相关状态
@@ -85,10 +131,21 @@
let end = msg.length - 1;
if (beng !== -1 && end !== -1 && dif !== -1) {
const datax = msg.slice(beng, end + 1);
- const dataBody = JSON.parse(datax);
+ const dataBody = JSON.parse(datax) as SseMsgData;
console.log("dataBody: ", dataBody);
// 倒计时提示文本
- if (dataBody.倒计时?.提示文本) {
+ if (dataBody.倒计时?.提醒文本) {
+ const taskTime = dayjs(dataBody.倒计时?.当前服务器时间).add(dataBody.倒计时?.设定提醒倒计时, 'minute')
+ setSyncTask({
+ deviceCode: dataBody.IOT信息.设备唯一编号,
+ recordCode: dataBody.透析状态?.透析单编号,
+ taskDate: taskTime.format('YYYY-MM-DD HH:mm'),
+ taskName: dataBody.倒计时?.提醒文本,
+ overdue: false,
+ countdown: dataBody.倒计时?.设定提醒倒计时
+ })
+ } else {
+ clearTask();
}
deviceData.value = formatDeviceData(dataBody);
@@ -104,6 +161,8 @@
source.value.close();
source.value = null;
isConnected.value = false;
+ clearDevice();
+ clearTask();
console.log("[SSE] 连接已关闭");
}
};
@@ -125,6 +184,10 @@
connect,
close,
refresh,
+ taskData,
+ pushTask,
+ setSyncTask,
+ clearTask,
};
}
);
diff --git a/src/store/type/bedsideAuxiliaryScreen.type.ts b/src/store/type/bedsideAuxiliaryScreen.type.ts
index 14fabbc..a5526ef 100644
--- a/src/store/type/bedsideAuxiliaryScreen.type.ts
+++ b/src/store/type/bedsideAuxiliaryScreen.type.ts
@@ -57,7 +57,10 @@
分区编号: string;
处方脱水量: number | null;
实时ktv: string;
- 实时ktv计算结果列表: null | { realTimeKtvCalcDetailResultInfo: KtvItem[], 透析单编号: string };
+ 实时ktv计算结果列表: null | {
+ realTimeKtvCalcDetailResultInfo: KtvItem[];
+ 透析单编号: string;
+ };
实时脱水量: number | null;
干体重: number | null;
年龄: number | null;
@@ -117,7 +120,7 @@
透析状态: string; // '0.0'这种格式的,得格式化一下
透析结束时间: number | null;
透析处方备注: string;
- 最近最大脱水量透析时长: string
+ 最近最大脱水量透析时长: string;
}
export interface VascularAccess {
@@ -156,15 +159,23 @@
项目结果: string;
}
+export interface Countdown {
+ 当前服务器时间?: string;
+ 提醒文本?: string;
+ 提醒文本字典?: any[];
+ 设定提醒倒计时?: number;
+}
+
export interface SseMsgData {
IOT信息: IotInfo | null;
使用耗材字典: ConsumablesCollection | null; // 当透析状态为治疗中时该字段为null
- 倒计时: "";
+ 倒计时: Countdown | null;
推送类型: PushType;
透析状态: DialysisStatus | null;
}
export interface BedsideAuxiliaryScreen {
+ deviceCode: string;
devicdeNo: string | number;
recordCode: string;
patientCode: string;
@@ -294,7 +305,7 @@
dryWeight: null, // 干体重
preDialysisWeight: null, // 透前称重
weightAfterLastDialysis: null, // 上次透后称重
- weightIncrease: null, // 体重增加
+ weightIncrease: null, // 体重增加
weightIncreaseRate: null, // 体重增长率
};
};
@@ -374,6 +385,7 @@
? EPageType.LOADING
: EPatForm.OUTPATIENT_SERVICE;
return {
+ deviceCode: "", // 设备code
devicdeNo: "", // 设备号
recordCode: "", // 透析单code
patientCode: "", // 患者code
@@ -396,10 +408,12 @@
export const formatDeviceData = (
seeMsg: SseMsgData
): BedsideAuxiliaryScreen => {
+
const result = defaultDeviceData();
// 默认床号(设备号)
result.devicdeNo = seeMsg.IOT信息?.床号;
+ result.deviceCode = seeMsg.IOT信息?.设备唯一编号;
if (seeMsg.推送类型 === EPushType.SPHYGMOMANOMETR) {
result.pageType = EPageType.SPHYGMOMANOMETER;
@@ -456,7 +470,8 @@
seeMsg.透析状态?.最近最大脱水量日期 ?? "";
signedIn.dryWeight = seeMsg.透析状态?.干体重 ?? null;
signedIn.preDialysisWeight = seeMsg.透析状态?.透前称重 ?? null;
- signedIn.weightAfterLastDialysis = seeMsg.透析状态?.上次透后称重 ?? null;
+ signedIn.weightAfterLastDialysis =
+ seeMsg.透析状态?.上次透后称重 ?? null;
signedIn.weightIncrease = seeMsg.透析状态?.体重增加 ?? null;
signedIn.weightIncreaseRate = seeMsg.透析状态?.体重增长率 ?? null;
@@ -475,8 +490,10 @@
seeMsg.透析状态?.最近最大脱水量 ?? "";
underTreatment.maximumDehydrationCapacityDate =
seeMsg.透析状态?.最近最大脱水量日期 ?? "";
- underTreatment.maximumDehydrationDuration = seeMsg.透析状态?.最近最大脱水量透析时长 ?? "";
- underTreatment.prescriptionRemarks = seeMsg.透析状态?.透析处方备注 ?? "";
+ underTreatment.maximumDehydrationDuration =
+ seeMsg.透析状态?.最近最大脱水量透析时长 ?? "";
+ underTreatment.prescriptionRemarks =
+ seeMsg.透析状态?.透析处方备注 ?? "";
underTreatment.abnormalItems = seeMsg.透析状态?.异常检验指标 ?? [];
underTreatment.prescriptionDialysisDuration =
seeMsg.透析状态?.透析处方的时长 ?? null;
@@ -503,9 +520,13 @@
underTreatment.monitoringRecord = seeMsg.透析状态?.监测记录列表 ?? [];
underTreatment.doctorAdvice = seeMsg.透析状态?.透析单医嘱列表 ?? [];
underTreatment.bloodFlow = "";
- underTreatment.dialysisFluidFlowRate = seeMsg.透析状态?.iot_血流量 ?? null;
- underTreatment.bloodVolumeMonitoring = seeMsg.透析状态?.iot_透析液流速 ?? null;
- underTreatment.ktvList = seeMsg.透析状态?.实时ktv计算结果列表?.realTimeKtvCalcDetailResultInfo ?? [];
+ underTreatment.dialysisFluidFlowRate =
+ seeMsg.透析状态?.iot_血流量 ?? null;
+ underTreatment.bloodVolumeMonitoring =
+ seeMsg.透析状态?.iot_透析液流速 ?? null;
+ underTreatment.ktvList =
+ seeMsg.透析状态?.实时ktv计算结果列表
+ ?.realTimeKtvCalcDetailResultInfo ?? [];
result.underTreatment = underTreatment;
}
}
@@ -563,10 +584,10 @@
export const formatSubstituteMode = (mode: string) => {
let result = "";
- if (mode === '前置换') {
- result = '前'
- } else if (mode === '后置换') {
- result = '后'
+ if (mode === "前置换") {
+ result = "前";
+ } else if (mode === "后置换") {
+ result = "后";
}
return result;
-}
+};
diff --git a/src/store/type/task.type.ts b/src/store/type/task.type.ts
new file mode 100644
index 0000000..75b2189
--- /dev/null
+++ b/src/store/type/task.type.ts
@@ -0,0 +1,12 @@
+export interface Task {
+ /** 设备code */
+ deviceCode: string;
+ /** 透析单code */
+ recordCode?: string;
+ /** 任务提醒时间 */
+ taskDate: string;
+ /** 任务名称 */
+ taskName: string;
+ /** 是否过期 */
+ overdue: boolean;
+}
diff --git a/src/views/mobile/bedsideAuxiliaryScreen/components/Header.vue b/src/views/mobile/bedsideAuxiliaryScreen/components/Header.vue
index f8d9a68..6efe7bc 100644
--- a/src/views/mobile/bedsideAuxiliaryScreen/components/Header.vue
+++ b/src/views/mobile/bedsideAuxiliaryScreen/components/Header.vue
@@ -23,10 +23,16 @@
{{ patientInfo.patForm }}:{{ patientInfo.patFormNumber }}</span
>
</template>
+ {{ taskCountdown }}
</template>
</div>
<div class="header-right">
- <img :src="atRegularTimeImg" class="btn-img" alt="" @click="openScheduledTaskDialog" />
+ <img
+ :src="atRegularTimeImg"
+ class="btn-img"
+ alt=""
+ @click="openScheduledTaskDialog"
+ />
<img
:src="setUpImg"
class="btn-img"
@@ -43,13 +49,22 @@
</template>
<script lang="ts" setup name="Header">
-import { ref, computed, defineAsyncComponent } from "vue";
+import {
+ ref,
+ computed,
+ defineAsyncComponent,
+ onMounted,
+ onUnmounted,
+ watch,
+} from "vue";
+import dayjs from "dayjs";
+import type { Task } from "@/store/type/task.type";
const SettingDeviceDialog = defineAsyncComponent(
() => import("./SettingDeviceDialog.vue")
);
const ScheduledTaskDialog = defineAsyncComponent(
() => import("./ScheduledTask.vue")
-)
+);
import atRegularTimeImg from "../../../../img/dingshi.png";
import setUpImg from "../../../../img/shezhi.png";
import userImg from "../../../../img/user.png";
@@ -60,8 +75,11 @@
const bedsideAuxiliaryScreenStore = useBedsideAuxiliaryScreenStore();
+let timer: number;
+
const settingDeviceDialogRef = ref<any>(null);
const scheduledTaskDialogRef = ref<any>(null);
+const taskCountdown = ref(""); // 定时任务倒计时文本
const pageType = computed(() => {
return bedsideAuxiliaryScreenStore.deviceData.pageType;
@@ -82,6 +100,23 @@
};
});
+watch(
+ () => bedsideAuxiliaryScreenStore.taskData,
+ (newData: Task[]) => {
+ console.log('定时任务更新了')
+ if (
+ bedsideAuxiliaryScreenStore.deviceData.deviceCode &&
+ newData.length > 0
+ ) {
+ console.log('newData: ', newData)
+ updateCountdown(newData[0].taskDate);
+ } else {
+ taskCountdown.value = "";
+ }
+ },
+ { deep: true }
+);
+
const openSettingDeviceDialog = () => {
settingDeviceDialogRef.value?.openDialog();
};
@@ -96,6 +131,38 @@
type: "warning",
});
};
+
+const getCountdown = (taskDate: string) => {
+ const now = dayjs();
+ const target = dayjs(taskDate).second(0).millisecond(0);
+
+ const diff = target.diff(now, "second");
+
+ if (diff <= 0) return "";
+
+ const minutes = Math.floor(diff / 60);
+ const seconds = diff % 60;
+
+ return `${minutes}m${seconds}s`;
+};
+
+const updateCountdown = (taskDate: string) => {
+ taskCountdown.value = getCountdown(taskDate);
+ timer = window.setInterval(updateCountdown, 1000);
+};
+
+onMounted(() => {
+ if (
+ bedsideAuxiliaryScreenStore.deviceData.deviceCode &&
+ bedsideAuxiliaryScreenStore.taskData.length > 0
+ ) {
+ getCountdown(bedsideAuxiliaryScreenStore.taskData[0].taskDate);
+ }
+});
+
+onUnmounted(() => {
+ timer && clearInterval(timer);
+});
</script>
<style lang="less" scoped>
diff --git a/src/views/mobile/bedsideAuxiliaryScreen/components/ScheduledTask.vue b/src/views/mobile/bedsideAuxiliaryScreen/components/ScheduledTask.vue
index 96a2c1a..9a4e12b 100644
--- a/src/views/mobile/bedsideAuxiliaryScreen/components/ScheduledTask.vue
+++ b/src/views/mobile/bedsideAuxiliaryScreen/components/ScheduledTask.vue
@@ -38,7 +38,7 @@
<div class="content-left-stereotyped-writing">
<div class="stereotyped-writing">
<input
- v-model="taskName"
+ v-model.trim="taskName"
type="text"
:disabled="isInpDisabled"
class="stereotyped-writing-input"
@@ -70,6 +70,10 @@
<script lang="ts" setup>
import { computed, ref } from "vue";
+import dayjs from "dayjs";
+import { setTimeoutAlert } from "@/utils/httpApi";
+import { useBedsideAuxiliaryScreenStore } from "@/store/bedsideAuxiliaryScreen";
+
// @ts-ignore
import TimePicker from "./TimePicker.vue";
@@ -81,6 +85,7 @@
import tdddbaojing from "@/assets/tzddd.mp3";
import tzxllbaojing from "@/assets/tzxll.mp3";
import cgbaojing from "@/assets/cg.mp3";
+import { ElMessage } from "element-plus";
interface TaskItem {
label: string;
@@ -94,14 +99,18 @@
value: number;
}
+const bedsideAuxiliaryScreenStore = useBedsideAuxiliaryScreenStore();
+
const isShow = ref(false);
const taskName = ref(""); // 任务名称
const isInpDisabled = ref(false); // 输入框是否禁用
-const timeValue = ref("19:16");
+const timeValue = ref("");
const detaCheck = ref<number | null>(); // 这个是判断时间按钮的
+
+const loading = ref(false);
const taskOptions = ref<TaskItem[]>([
{
@@ -155,6 +164,8 @@
const openDialog = () => {
isShow.value = true;
+ const time = dayjs();
+ timeValue.value = time.format("HH:mm");
};
const onStereotypedWritingClick = (item: TaskItem) => {
@@ -197,7 +208,38 @@
isShow.value = false;
};
-const handleConfirm = () => {};
+const handleConfirm = async () => {
+ const today = dayjs().format("YYYY-MM-DD");
+ const fullDateTime = dayjs(`${today} ${timeValue.value}`).second(0).millisecond(0); // 秒和毫秒都去掉,要不然间隔短了就是0分钟
+
+ const now = dayjs().second(0).millisecond(0);; // 秒和毫秒都去掉
+ if (!fullDateTime.isAfter(now))
+ return ElMessage.warning("任务提醒时间不能早于或等于当前时间");
+ if (!taskName.value) return ElMessage.warning("任务内容不能为空");
+ loading.value = true;
+ try {
+ const diffMinutes = fullDateTime.diff(now, "minute");
+ const params = {
+ deviceCode: bedsideAuxiliaryScreenStore.deviceData.deviceCode,
+ minutes: diffMinutes,
+ alertText: taskName.value,
+ }
+ const recordCode = bedsideAuxiliaryScreenStore.deviceData.recordCode;
+ const { data, message } = await setTimeoutAlert(params);
+ if (data !== "OK") return ElMessage.warning(message);
+ ElMessage.success('操作成功');
+ bedsideAuxiliaryScreenStore.setSyncTask({
+ deviceCode: params.deviceCode,
+ recordCode: recordCode,
+ taskDate: dayjs(fullDateTime).format("YYYY-MM-DD HH:mm"),
+ taskName: params.alertText,
+ overdue: false
+ });
+ handleCancel();
+ } finally {
+ loading.value = false;
+ }
+};
defineExpose({
openDialog,
--
Gitblit v1.8.0