| src/store/bedsideAuxiliaryScreen.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/store/type/bedsideAuxiliaryScreen.type.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/store/type/task.type.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/mobile/bedsideAuxiliaryScreen/components/Header.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/mobile/bedsideAuxiliaryScreen/components/ScheduledTask.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
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, }; } ); 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; } }; src/store/type/task.type.ts
New file @@ -0,0 +1,12 @@ export interface Task { /** 设备code */ deviceCode: string; /** 透析单code */ recordCode?: string; /** 任务提醒时间 */ taskDate: string; /** 任务名称 */ taskName: string; /** 是否过期 */ overdue: boolean; } 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> 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,