单应用项目,可以创建很多独立工具类页面 ,不用登录 初始化的页面
zhangchen
2025-08-04 2a122106c080eb0a8b0ec82903e785087c6d3b49
src/views/mobile/bedsideAuxiliaryScreen/components/Header.vue
@@ -2,7 +2,9 @@
  <div class="bedside-auxiliary-screen-header">
    <div class="header-left">
      <!-- 没有设备编号 -->
      <span v-if="pageType === pageTypeEnum.NOT_INIT" class="info-text">未绑定设备</span>
      <span v-if="pageType === pageTypeEnum.NOT_INIT" class="info-text"
        >未绑定设备</span
      >
      <template v-else>
        <!-- 设备号 -->
        <span class="info-text">{{
@@ -13,7 +15,11 @@
          >页面初始化中,请耐心等待!</span
        >
        <!-- 未排班 -->
        <span v-else-if="pageType === pageTypeEnum.UNPLANNED_SCHEDULE" class="info-text">当前尚未排班</span>
        <span
          v-else-if="pageType === pageTypeEnum.UNPLANNED_SCHEDULE"
          class="info-text"
          >当前尚未排班</span
        >
        <!-- 有排班 -->
        <template v-else>
          <span class="info-text">{{ patientInfo.patientName }}</span>
@@ -22,14 +28,30 @@
          <span v-if="patientInfo.patFormNumber" class="info-text">
            {{ patientInfo.patForm }}:{{ patientInfo.patFormNumber }}</span
          >
          <span v-if="pageType === pageTypeEnum.DURING_DIALYSIS && patientInfo.dialysisAge" class="info-text">
            透析龄: {{ patientInfo.dialysisAge?.years }}年{{ patientInfo.dialysisAge?.months }}月
          <span
            v-if="
              pageType === pageTypeEnum.DURING_DIALYSIS &&
              patientInfo.dialysisAge
            "
            class="info-text"
          >
            透析龄: {{ patientInfo.dialysisAge?.years }}年{{
              patientInfo.dialysisAge?.months
            }}月
          </span>
        </template>
        {{ taskCountdown }}
      </template>
    </div>
    <div class="header-right">
      <span
        v-if="
          bedsideAuxiliaryScreenStore.taskData &&
          bedsideAuxiliaryScreenStore.taskData.length > 0
        "
        class="countdown"
      >
        {{ formattedCountdown }}
      </span>
      <img
        :src="atRegularTimeImg"
        class="btn-img"
@@ -49,6 +71,8 @@
  <SettingDeviceDialog ref="settingDeviceDialogRef" />
  <!-- 定时任务组件 -->
  <ScheduledTaskDialog ref="scheduledTaskDialogRef" />
  <!-- 定时任务提醒组件 -->
  <TaskAlert ref="taskAlertRef" @close="taskAlaetClose" />
</template>
<script lang="ts" setup name="Header">
@@ -68,6 +92,8 @@
const ScheduledTaskDialog = defineAsyncComponent(
  () => import("./ScheduledTask.vue")
);
const TaskAlert = defineAsyncComponent(() => import("./TaskAlart.vue"));
import atRegularTimeImg from "../../../../img/dingshi.png";
import setUpImg from "../../../../img/shezhi.png";
import userImg from "../../../../img/user.png";
@@ -75,23 +101,28 @@
import { useBedsideAuxiliaryScreenStore } from "@/store/bedsideAuxiliaryScreen";
import { EPatForm, EPageType } from "@/store/type/bedsideAuxiliaryScreen.type";
import { ElMessage } from "element-plus";
import { maskName } from '@/utils/utils';
const bedsideAuxiliaryScreenStore = useBedsideAuxiliaryScreenStore();
let timer: number;
let timer: ReturnType<typeof setInterval> | null = null;
const pageTypeEnum = ref(EPageType);
const settingDeviceDialogRef = ref<any>(null);
const scheduledTaskDialogRef = ref<any>(null);
const taskCountdown = ref(""); // 定时任务倒计时文本
const taskAlertRef = ref<any>(null);
const countdown = ref(null); // 定时任务的倒计时
const isTaskAlartIsOpen = ref(false); // 定时任务的提醒弹框是否显示
const pageType = computed(() => {
  return bedsideAuxiliaryScreenStore.deviceData.pageType;
});
const patientInfo = computed(() => {
  return {
    patientName: bedsideAuxiliaryScreenStore.deviceData.patientName,
    patientName: bedsideAuxiliaryScreenStore.deviceData.customConfiguration.患者信息是否加密显示 === 1 ? maskName(bedsideAuxiliaryScreenStore.deviceData.patientName) :  bedsideAuxiliaryScreenStore.deviceData.patientName,
    patientPhone: bedsideAuxiliaryScreenStore.deviceData.patientPhone,
    age: bedsideAuxiliaryScreenStore.deviceData.age,
    gender: bedsideAuxiliaryScreenStore.deviceData.gender,
@@ -101,39 +132,98 @@
        ? "门诊号"
        : "住院号",
    patFormNumber: bedsideAuxiliaryScreenStore.deviceData.patFormNumber,
    dialysisAge: bedsideAuxiliaryScreenStore.deviceData.underTreatment.dialysisAge ? convertMonths(bedsideAuxiliaryScreenStore.deviceData.underTreatment.dialysisAge) : null ,
    dialysisAge: bedsideAuxiliaryScreenStore.deviceData.underTreatment
      .dialysisAge
      ? convertMonths(
          bedsideAuxiliaryScreenStore.deviceData.underTreatment.dialysisAge
        )
      : null,
  };
});
// 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 formattedCountdown = computed(() => {
  if (countdown.value == null || countdown.value <= 0) return "0s";
  const minutes = Math.floor(countdown.value / 60);
  const seconds = countdown.value % 60;
  if (minutes > 0) {
    return `${minutes}m ${seconds}s`;
  } else {
    return `${seconds}s`;
  }
});
watch(
  () => bedsideAuxiliaryScreenStore.taskData?.[0]?.countdown,
  (val) => {
    if (typeof val === "number") {
      startCountdown(val);
    } else {
      clearTimer();
    }
  },
  { immediate: true }
);
watch(countdown, (newVal) => {
  if (newVal <= 0 && !isTaskAlartIsOpen.value) {
    isTaskAlartIsOpen.value = true;
    showTaskAlart();
  }
});
// 清除定时器函数
function clearTimer() {
  if (timer) {
    clearInterval(timer);
    timer = null;
  }
}
// 启动新的倒计时
function startCountdown(seconds: number) {
  clearTimer();
  countdown.value = seconds;
  timer = setInterval(() => {
    if (countdown.value > 0) {
      countdown.value -= 1;
    } else {
      clearTimer();
    }
  }, 1000);
}
const convertMonths = (months: number): { years: number; months: number } => {
  const years = Math.floor(months / 12);
  const remainingMonths = months % 12;
  return { years, months: remainingMonths };
}
};
const showTaskAlart = () => {
  clearTimer();
  taskAlertRef.value.openDialog(
    bedsideAuxiliaryScreenStore.taskData?.[0]?.taskName
  );
};
const taskAlaetClose = () => {
  clearTimer();
  bedsideAuxiliaryScreenStore.clearTask();
  isTaskAlartIsOpen.value = false;
};
const openSettingDeviceDialog = () => {
  settingDeviceDialogRef.value?.openDialog();
};
const openScheduledTaskDialog = () => {
  if (!bedsideAuxiliaryScreenStore.deviceCode || !bedsideAuxiliaryScreenStore.deviceData.deviceCode) return ElMessage.warning('未初始化或正在进行初始化操作中');
  if (
    !bedsideAuxiliaryScreenStore.deviceCode ||
    !bedsideAuxiliaryScreenStore.deviceData.deviceCode
  )
    return ElMessage.warning("未初始化或正在进行初始化操作中");
  scheduledTaskDialogRef.value?.openDialog();
};
@@ -144,36 +234,8 @@
  });
};
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);
  clearTimer();
});
</script>
@@ -192,12 +254,12 @@
    .info-text {
      font-family: PingFangSC, PingFang SC;
      font-weight: 600;
      font-size: 11px;
      font-size: 9px;
      color: #ffffff;
      text-align: left;
      font-style: normal;
      &:not(:first-child) {
        margin-left: 6px;
        margin-left: 4px;
      }
    }
  }
@@ -218,6 +280,15 @@
      transition: all 0.2s;
    }
    .countdown {
      font-family: PingFangSC, PingFang SC;
      font-weight: 600;
      font-size: 9px;
      color: #bb3e3e;
      line-height: 15rpx;
      text-align: left;
      font-style: normal;
    }
  }
}
</style>