|
@@ -0,0 +1,312 @@
|
|
|
+import type {InjectionKey} from "vue";
|
|
|
+import XEUtils from "xe-utils";
|
|
|
+import moment from "moment/moment";
|
|
|
+import {useEventListener} from "@vueuse/core";
|
|
|
+import {documentVisibilityEnum} from "@/utils/cy-use/useChangeToken";
|
|
|
+import {getServerDate} from "@/utils/moment-utils";
|
|
|
+import {selectInpatientBriefs} from "@/api/dashboard";
|
|
|
+import router from "@/router";
|
|
|
+import {getAllWards} from "@/api/login";
|
|
|
+import sleep from "@/utils/sleep";
|
|
|
+
|
|
|
+
|
|
|
+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;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+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;
|
|
|
+}
|
|
|
+
|
|
|
+export function useInpatientBoard() {
|
|
|
+ const scrollingInfo = {
|
|
|
+ rowCount: 5,
|
|
|
+ interval: XEUtils.noop,
|
|
|
+ currentIndex: 0,
|
|
|
+ }
|
|
|
+
|
|
|
+ const current = reactive({
|
|
|
+ code: '',
|
|
|
+ name: '',
|
|
|
+ })
|
|
|
+ const selectRef = ref()
|
|
|
+
|
|
|
+ const speedBarDisplay = ref(3)
|
|
|
+ const data = ref<InpatientBrief[]>([])
|
|
|
+ const allWards = ref<{ code: string, name: string }[]>([])
|
|
|
+ const huliData = ref({})
|
|
|
+ const time = reactive({
|
|
|
+ now: moment().format('YYYY-MM-DD HH:mm:ss'),
|
|
|
+ weekName: ''
|
|
|
+ })
|
|
|
+ const infoEl = ref<HTMLDivElement | null>(null)
|
|
|
+ const dvTableData = reactive({
|
|
|
+ operation: {
|
|
|
+ config: {
|
|
|
+ align: 'left',
|
|
|
+ columnWidth: [60, 100],
|
|
|
+ header: ['姓名', '床号', '手术'],
|
|
|
+ data: [],
|
|
|
+ columnWidth: [50],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ huli: {
|
|
|
+ config: {
|
|
|
+ align: 'left',
|
|
|
+ columnWidth: [200],
|
|
|
+ header: ['名称', '数量'],
|
|
|
+ data: [],
|
|
|
+ },
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ function setDvTableData() {
|
|
|
+ data.value.forEach(item => {
|
|
|
+ if (item.surgery) {
|
|
|
+ dvTableData.operation.config.data.push([anonymizeName(item.name), item.bedNo, item.surgery])
|
|
|
+ }
|
|
|
+
|
|
|
+ })
|
|
|
+
|
|
|
+ for (let key in huliData.value) {
|
|
|
+ dvTableData.huli.config.data.push([key, huliData.value[key]])
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ async function handleWardChange(code: string) {
|
|
|
+ if (code) {
|
|
|
+ current.code = code;
|
|
|
+ selectInpatientBriefs(code).then((res) => {
|
|
|
+ // @ts-ignore
|
|
|
+ setData(res)
|
|
|
+ router.replace({
|
|
|
+ query: {
|
|
|
+ ward: code,
|
|
|
+ speedBarDisplay: speedBarDisplay.value
|
|
|
+ }
|
|
|
+ });
|
|
|
+ })
|
|
|
+ await nextTick()
|
|
|
+ current.name = selectRef.value.states.selectedLabel;
|
|
|
+ }
|
|
|
+
|
|
|
+ await nextTick();
|
|
|
+ }
|
|
|
+
|
|
|
+ async function setData(value: InpatientBrief[]) {
|
|
|
+ if (XEUtils.isArray(value)) {
|
|
|
+ clearInterval(scrollingInfo.interval)
|
|
|
+ data.value = value;
|
|
|
+ 护理分组()
|
|
|
+ setDvTableData()
|
|
|
+ } 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 = await getServerDate()
|
|
|
+ interval = setInterval(() => {
|
|
|
+ time.now = moment(time.now).add(1, 'seconds').format('YYYY-MM-DD HH:mm:ss')
|
|
|
+ }, 1000)
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ function 护理分组() {
|
|
|
+ huliData.value = {}
|
|
|
+ data.value.forEach((value) => {
|
|
|
+ let name = ''
|
|
|
+
|
|
|
+ if (value.nursingLevel) {
|
|
|
+ name = value.nursingLevel
|
|
|
+ }
|
|
|
+
|
|
|
+ if (value.sickLevelOrderName) {
|
|
|
+ name = value.sickLevelOrderName
|
|
|
+ }
|
|
|
+
|
|
|
+ if (name) {
|
|
|
+ // @ts-ignore
|
|
|
+ huliData.value[name] = (huliData.value[name] ?? 0) + 1;
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ function hasScrollDiv(divElement) {
|
|
|
+ // 获取div的总高度(包括内容和任何滚动条)
|
|
|
+ const totalHeight = divElement.scrollHeight;
|
|
|
+ // 获取可见区域的高度(不包含任何滚动条)
|
|
|
+ const clientHeight = divElement.clientHeight;
|
|
|
+ // 如果总高度大于可见区域的高度,则说明该div元素有滚动条
|
|
|
+ return totalHeight > clientHeight;
|
|
|
+ }
|
|
|
+
|
|
|
+ function startScrolling() {
|
|
|
+ clearInterval(scrollingInfo.interval)
|
|
|
+ const el = infoEl.value!
|
|
|
+
|
|
|
+ if (!el) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!hasScrollDiv(el)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ scrollingInfo.interval = setInterval(() => {
|
|
|
+ const items = el.querySelectorAll('.board_patient-card')
|
|
|
+ const item = items[scrollingInfo.currentIndex * scrollingInfo.rowCount];
|
|
|
+ scrollingInfo.currentIndex++
|
|
|
+ if (item) {
|
|
|
+ item.scrollIntoView({
|
|
|
+ block: 'start',
|
|
|
+ inline: 'nearest',
|
|
|
+ behavior: 'smooth'
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ el.scrollBy({
|
|
|
+ top: 0
|
|
|
+ })
|
|
|
+ scrollingInfo.currentIndex = 0
|
|
|
+ }
|
|
|
+ }, speedBarDisplay.value * 1000)
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ function setElementHeight(el: HTMLDivElement, index) {
|
|
|
+ if (!el) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (index + 1 === data.value.length) {
|
|
|
+ startScrolling()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function changeInterval() {
|
|
|
+ startScrolling()
|
|
|
+ router.replace({
|
|
|
+ query: {...router.currentRoute.value.query, speedBarDisplay: speedBarDisplay.value}
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ onMounted(async () => {
|
|
|
+ const query = router.currentRoute.value.query
|
|
|
+ speedBarDisplay.value = XEUtils.toNumber(XEUtils.get(query, 'speedBarDisplay', 3))
|
|
|
+ allWards.value = await getAllWards() as any
|
|
|
+ await sleep(500)
|
|
|
+ const ward = XEUtils.get(query, 'ward', '') as string
|
|
|
+ handleWardChange(ward)
|
|
|
+ })
|
|
|
+
|
|
|
+ return {
|
|
|
+ current,
|
|
|
+ data,
|
|
|
+ allWards,
|
|
|
+ setData,
|
|
|
+ huliData,
|
|
|
+ handleWardChange,
|
|
|
+ selectRef,
|
|
|
+ time,
|
|
|
+ infoEl,
|
|
|
+ setElementHeight,
|
|
|
+ speedBarDisplay,
|
|
|
+ dvTableData,
|
|
|
+ changeInterval
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+class InpatientBoardClass {
|
|
|
+ Return = useInpatientBoard()
|
|
|
+}
|
|
|
+
|
|
|
+export type InpatientBoardType = InpatientBoardClass['Return']
|
|
|
+
|
|
|
+interface Key {
|
|
|
+ store: InpatientBoardType
|
|
|
+}
|
|
|
+
|
|
|
+export const InpatientBoardKey: InjectionKey<Key> =
|
|
|
+ Symbol('systemConfigKey')
|