import XEUtils from "xe-utils"; import moment from "moment/moment"; import { useEventListener, useWebSocket } from "@vueuse/core"; import { documentVisibilityEnum } from "@/utils/cy-use/useChangeToken"; import { getServerDate } from "@/utils/moment-utils"; import router from "@/router"; import { getAllWards } from "@/api/login"; import sleep from "@/utils/sleep"; import env from "@/utils/setting"; import { isDev } from "@/utils/public"; import { magicApi } from "@/utils/database/magic-api-request"; import { useCompShallowRef } from "@/utils/useCompRef"; import RenderTable from "@/components/nursing-dashboard/RenderTable.vue"; import { stringNotBlank } from "@/utils/blank-utils"; function getWeek(date: any): string { // 参数时间戳 let week = moment(new Date(date)).day(); switch (week) { case 1: return "星期一"; case 2: return "星期二"; case 3: return "星期三"; case 4: return "星期四"; case 5: return "星期五"; case 6: return "星期六"; case 0: return "星期日"; default: return ""; } } export function anonymizeName(name: string) { if (!name) return ""; let prefix = ""; // 如果是婴儿 if (name.startsWith("(")) { const index = name.indexOf("("); const end = name.lastIndexOf(")"); prefix = name.substring(index, end + 1); name = name.substring(end + 1, name.length); } if (name.length == 2) { name = name.substring(0, 1) + "*"; return prefix + name; } else if (name.length == 3) { name = name.substring(0, 1) + "*" + name.substring(2, 3); return prefix + name; } else if (name.length > 3) { name = name.substring(0, 1) + "*" + "*" + name.substring(3, name.length); return prefix + name; } return ""; } const huloColor = { 病重: "#E21606", 病危: "#f89898", Ⅰ级: "#79bbff", Ⅱ级: "#12D4F9", Ⅲ级: "#30C8A0", }; export function getHuloColor(value: string) { return XEUtils.get(huloColor, value, "#b1b3b8"); } export type InpatientBrief = { bedNo: string; name: string; gender: number; indays: number; patNo: string; birthDate: string; admissDate: string; convertAdmissDate: string; physician: string; medType: string; medTypeName: string; surgery: string; // 护理级别 nursingLevel: string; // 病情医嘱:null,病重,病危 sickLevelOrderName: string; // 患者状态: 0-正常,1-病重,2-病危 sickLevel: number; leaveHospital: number; prompt: { text: string; color: string; }; }; interface CallData { ward: string; bedNo: string; emergency: boolean; state: "call" | string; // 可以更精确地定义可能的字符串值 call: boolean; group: string; } function openSocket(callStore) { const url = ref(""); let socket = null; function open(code: string) { if (socket != null) { socket.close(); } url.value = isDev ? `ws://172.16.30.66:20922/websocket/nursingRecordBoard/${code}` : `${env.VITE_SOCKET_V2}/nursingRecordBoard/${code}`; socket = useWebSocket(url, { autoReconnect: true, immediate: true, onMessage: (ws, message) => { try { const data = JSON.parse(message.data); callStore[data.code](data.data); } catch (e) { console.error(e); } }, heartbeat: { message: "ping", interval: 1000 * 60 * 3, pongTimeout: 1000, }, }); } return { open, }; } export function useInpatientBoard() { const bedCount = ref(0); const selectRef = ref(); const urlQuery = reactive({ speedBarDisplay: 5, refresh: 30, ward: "", wardName: "", tempId: "", tableDisplay: 2, }); const renderTableRef = useCompShallowRef(RenderTable); const store = reactive({ // 表格模板 htmlData: "", }); const callStore = reactive({ call: new Map(), urgentCallForHelp: new Map(), dialogVisible: true, }); const socketOnMessage = { call: (data: CallData) => { const group = data.group; if (data.call) { callStore[group].set(data.bedNo, data); } else { callStore[group].delete(data.bedNo); } }, empty: data => { callStore[data.group].clear(); }, }; const socket = openSocket(socketOnMessage); let refreshTimeOut; const data = ref([]); const allWards = ref<{ code: string; name: string }[]>([]); const time = reactive({ now: moment().format("YYYY-MM-DD HH:mm:ss"), weekName: "", }); const infoEl = ref(null); function changeRouterQuery() { const { wardName, ...tmp } = urlQuery; router .replace({ query: { ...tmp, }, }) .then(XEUtils.noop); } async function handleWardChange(code: string) { clearTimeout(refreshTimeOut); if (code) { urlQuery.ward = code; magicApi({ method: "get", params: { dept: code }, url: "/public/dashboard/patientList", }).then(res => { setData(res.data); bedCount.value = res.bedCount; changeRouterQuery(); }); await nextTick(); urlQuery.wardName = selectRef.value.states.selectedLabel; } await nextTick(); refreshTimeOut = setTimeout( () => { handleWardChange(urlQuery.ward); }, 60 * 1000 * urlQuery.refresh ); mutation.getTemplate(); socket.open(code); } async function setData(value: InpatientBrief[]) { if (XEUtils.isArray(value)) { data.value = value; mutation.boardStart(data.value); } else { data.value = []; } time.now = await getServerDate(); time.weekName = getWeek(time.now); } let interval = setInterval(() => { time.now = moment(time.now).add(1, "seconds").format("YYYY-MM-DD HH:mm:ss"); }, 1000); useEventListener(document, "visibilitychange", async val => { if (document.visibilityState === documentVisibilityEnum.hidden) { clearInterval(interval); } else { // @ts-ignore time.now = moment().format("YYYY-MM-DD HH:mm:ss"); interval = setInterval(() => { time.now = moment(time.now) .add(1, "seconds") .format("YYYY-MM-DD HH:mm:ss"); }, 1000); } }); function changeInterval() { changeRouterQuery(); } const mutation = { boardStart: (value: any[]): Promise | number => 0, async getTemplate() { let params = { ward: urlQuery.ward, id: "" }; if (stringNotBlank(urlQuery.tempId)) { params = { id: urlQuery.tempId, }; } const tmp = await magicApi({ url: "/public/dashboard/getTemplate", method: "get", params, }); if (tmp === store.htmlData) { renderTableRef.value.reloadData(); } else { store.htmlData = tmp; } }, changeTableDisplay() { renderTableRef.value.reloadData(); changeRouterQuery(); }, }; onMounted(async () => { const query = router.currentRoute.value.query; urlQuery.speedBarDisplay = XEUtils.toNumber( XEUtils.get(query, "speedBarDisplay", 3) ); urlQuery.tempId = query.tempId as string; urlQuery.refresh = XEUtils.toNumber(XEUtils.get(query, "refresh", 30)); urlQuery.tableDisplay = XEUtils.toNumber( XEUtils.get(query, "tableDisplay", 2) ); allWards.value = (await getAllWards()) as any; await sleep(500); const ward = XEUtils.get(query, "ward", "") as string; handleWardChange(ward); }); return { data, allWards, handleWardChange, selectRef, time, infoEl, changeInterval, urlQuery, bedCount, mutation, callStore, store, renderTableRef, }; } export type InpatientBoardType = ReturnType; export const InpatientBoardKey = "inpatientBoardV2";