单应用项目,可以创建很多独立工具类页面 ,不用登录 初始化的页面
zhangchen
2025-07-25 17bf58ac59f5cb3e01ac028cdbc37a3c7c6737ed
src/views/mobile/bedsideAuxiliaryScreen/pages/UnderTreatment.vue
@@ -105,10 +105,15 @@
          title="血压脉搏趋势图"
          :icon="xinLv2Img"
          background-color="#ffffff"
          class="mini-card left-row2-col3"
          class="mini-card ktv-card left-row2-col3"
          header-class-name="mini-header"
        >
          <div class=""></div>
          <div style="height: 100%">
            <div
              ref="bloodPressureAndPulseEchartRef"
              style="width: 100%; height: 100%"
            ></div>
          </div>
        </Card>
      </div>
      <div class="left-row3">
@@ -225,8 +230,22 @@
          class="mini-card right-box-row2-item"
          header-class-name="mini-header"
        >
          <div class="item-box">
            <div class="item-num"></div>
          <div class="progress-box">
            <div class="item-num">
              {{ jgTime4(pageData.dialysisDuration) }}/{{
                pageData.prescriptionDialysisDuration
              }}:{{ pageData.prescriptionDialysisDurationMin }}
            </div>
            <ProgressBar
              :percent="
                (Number(pageData.dialysisDuration) /
                  (Number(pageData.prescriptionDialysisDuration) * 60)) *
                100
              "
              color="#70A3DD"
              backgroundColor="#D6DEF1"
              borderRadius="50%"
            />
          </div>
        </Card>
        <Card
@@ -245,7 +264,7 @@
            <ProgressBar
              :percent="
                (pageData.currentDehydrationVolume /
                  pageData.currentDehydrationVolume) *
                  pageData.prescriptionDehydrationVolume) *
                100
              "
              color="#70CAAE"
@@ -289,8 +308,9 @@
          class="btn"
        />
        <BlockBotttom
          v-if="!whetherDialysisHasBeenEnded"
          :icon="kaiShiImg"
          text="j结束透析"
          text="结束透析"
          backgroundColor="#E6A23C"
          @click="() => onEndClick()"
          class="btn"
@@ -300,8 +320,10 @@
  </div>
</template>
<script lang="ts" setup name="UnderTreatment">
import { computed, ref, onMounted, onBeforeUnmount } from "vue";
import { computed, ref, onMounted, onBeforeUnmount, watch } from "vue";
import * as echarts from "echarts";
import dayjs from "dayjs";
// @ts-ignore
import Card from "../components/Card.vue";
// @ts-ignore
@@ -317,8 +339,11 @@
  formatTestFlag,
  EMedStatus,
} from "@/store/type/bedsideAuxiliaryScreen.type";
import type { KtvItem } from "@/store/type/bedsideAuxiliaryScreen.type";
import { formatDate } from "@/utils/formatTime";
import type {
  KtvItem,
  MonitoringRecord,
} from "@/store/type/bedsideAuxiliaryScreen.type";
import { formatDate, jgTime4, jgTime5 } from "@/utils/formatTime";
import zlmsImg from "@/img/zlms.png";
import dingShiImg from "@/img/dingshi2.png";
import jiaoHaoImg from "@/img/jiaoHao.png";
@@ -331,6 +356,7 @@
import cljdImg from "@/img/cljd.png";
import sjjdImg from "@/img/sjjd.png";
import yizhuImg from "@/img/yizhu.png";
import { ElMessage } from "element-plus";
interface Props {
  height: number;
@@ -341,6 +367,8 @@
// ktv趋势图的
const ktvListEchartRef = ref<HTMLElement | null>(null);
// 血压脉搏趋势图的
const bloodPressureAndPulseEchartRef = ref<HTMLElement | null>(null);
const pageData = computed(() => {
  return Object.assign(bedsideAuxiliaryScreenStore.deviceData.underTreatment, {
@@ -349,7 +377,7 @@
});
const treatmentStatusText = computed(() => {
  const status = bedsideAuxiliaryScreenStore.deviceData.treatmentStatus;
  const status = +bedsideAuxiliaryScreenStore.deviceData.treatmentStatus;
  if (status === EMedStatus.NOT_CHECKED_IN) return "未签到";
  if (status === EMedStatus.SIGNED_IN) return "已签到";
  if (status === EMedStatus.DURING_DIALYSIS) return "透析中";
@@ -359,12 +387,41 @@
  return "未知状态";
});
// const;
/** 是否已结束透析 */
const whetherDialysisHasBeenEnded = computed(() => {
  return (
    +bedsideAuxiliaryScreenStore.deviceData.treatmentStatus >= EMedStatus.END
  );
});
watch(
  () => pageData.value.ktvList,
  (newVal) => {
    generateKtvListEchart(newVal);
  },
  { deep: true }
);
watch(
  () => pageData.value.monitoringRecord,
  (newVal) => {
    generatBloodPressureAndPulseEchart(newVal);
  },
  { deep: true }
);
watch(
  () => props.height,
  () => {
    generateKtvListEchart(pageData.value.ktvList);
    generatBloodPressureAndPulseEchart(pageData.value.monitoringRecord);
  }
);
/** 生成ktv趋势图 */
const generateKtvListEchart = (ktvList: KtvItem[]) => {
  if (!ktvListEchartRef.value) return;
  if (!ktvList || ktvList.length === 0) return;
  // if (!ktvList || ktvList.length === 0) return;
  // 检查是否已经有实例
  let chart = echarts.getInstanceByDom(ktvListEchartRef.value);
@@ -373,25 +430,25 @@
  }
  const option = {
    grid: {
      top: 6,
      bottom: 20,
      right: 20,
    },
    xAxis: {
      type: "category",
      data: ktvList.map((item) => formatDate(new Date(item.时间), "HH:mm")),
      data: ktvList.map((item) => dayjs(item.时间).format("HH:mm")),
      axisLine: { show: true },
      axisTick: { show: true },
      // axisLabel: {
      //   margin: 5, // 控制文字与轴的距离,尽量小
      //   fontSize: 12,
      // },
      splitLine: { show: false },
    },
    yAxis: {
      type: "value",
      axisLine: { show: true },
      axisTick: { show: true },
      // axisLabel: {
      //   margin: 5,
      //   fontSize: 12,
      // },
      splitLine: { show: true },
      splitLine: { show: false },
      splitNumber: 4,
    },
    series: [
      {
@@ -405,7 +462,7 @@
          color: "#70CAAE",
        },
        itemStyle: {
          color: "#70CAAE",
          color: (params: any) => getColor(params.value),
        },
      },
    ],
@@ -417,27 +474,220 @@
  chart.setOption(option, true); // 第二个参数为 true 表示全量更新
};
const getColor = (val: number) => {
  if (val < 1.2) return "#FE0201"; // 红色
  if (val <= 1.6) return "#70CAAE"; // 绿色
  return "#FE6500"; // 橙色
};
/** 生成血压脉搏趋势图 */
const generatBloodPressureAndPulseEchart = (
  bloodPressureAndPulses: MonitoringRecord[]
) => {
  if (!bloodPressureAndPulseEchartRef.value) return;
  let chart = echarts.getInstanceByDom(bloodPressureAndPulseEchartRef.value);
  if (!chart) {
    chart = echarts.init(bloodPressureAndPulseEchartRef.value);
  }
  const telescopicPressureDatas: number[] = []; // 伸缩压
  const diastolicPressureDatas: number[] = []; // 舒张压
  const pulseDatas: number[] = []; // 脉搏
  const xAxisData: string[] = []; // 横坐标
  bloodPressureAndPulses.forEach((item, index) => {
    telescopicPressureDatas.push(+item.伸缩压);
    diastolicPressureDatas.push(+item.舒张压);
    pulseDatas.push(+item.脉搏);
    xAxisData.push(String(index + 1));
  });
  const option = {
    grid: [
      { top: "5%", height: "28%", left: 40, right: 20, containLabel: true },
      { top: "35%", height: "28%", left: 40, right: 20, containLabel: true },
      { top: "65%", height: "28%", left: 40, right: 20, containLabel: true },
    ],
    tooltip: {
      trigger: "axis",
    },
    xAxis: [
      {
        type: "category",
        data: xAxisData,
        boundaryGap: false,
        axisLine: { show: false },
        axisTick: { show: false },
        axisLabel: { show: false },
        splitLine: { show: false },
        gridIndex: 0,
        show: false,
      },
      {
        type: "category",
        data: xAxisData,
        boundaryGap: false,
        axisLine: { show: false },
        axisTick: { show: false },
        axisLabel: { show: false },
        splitLine: { show: false },
        gridIndex: 1,
        show: false,
      },
      {
        type: "category",
        data: xAxisData,
        boundaryGap: false,
        axisLine: { show: false },
        axisTick: { show: false },
        axisLabel: { show: true }, // 最下面一层显示时间轴
        splitLine: { show: false },
        gridIndex: 2,
        show: false,
      },
    ],
    yAxis: [
      {
        type: "value",
        show: false,
        axisLine: { show: false },
        axisTick: { show: false },
        axisLabel: { show: false },
        splitLine: { show: false },
        min: 0,
        max: 300,
        interval: 2,
        gridIndex: 0,
      },
      {
        type: "value",
        show: false,
        axisLine: { show: false },
        axisTick: { show: false },
        axisLabel: { show: false },
        splitLine: { show: false },
        min: 0,
        max: 300,
        interval: 2,
        gridIndex: 1,
      },
      {
        type: "value",
        show: false,
        axisLine: { show: false },
        axisTick: { show: false },
        axisLabel: { show: false },
        splitLine: { show: false },
        min: 0,
        max: 300,
        interval: 2,
        gridIndex: 2,
      },
    ],
    series: [
      {
        name: "伸缩压",
        xAxisIndex: 0,
        yAxisIndex: 0,
        data: wrapData(telescopicPressureDatas),
        type: "line",
        smooth: false,
        symbol: "circle",
        symbolSize: 6,
        lineStyle: { width: 2, color: "#FE0201" },
        itemStyle: { color: "#FE0201" },
        label: { color: "#FE0201" },
      },
      {
        name: "舒张压",
        xAxisIndex: 1,
        yAxisIndex: 1,
        data: wrapData(diastolicPressureDatas),
        type: "line",
        smooth: false,
        symbol: "circle",
        symbolSize: 6,
        lineStyle: { width: 2, color: "#70A3DD" },
        itemStyle: { color: "#70A3DD" },
        label: { color: "#70A3DD" },
      },
      {
        name: "脉搏",
        xAxisIndex: 2,
        yAxisIndex: 2,
        data: wrapData(pulseDatas),
        type: "line",
        smooth: false,
        symbol: "circle",
        symbolSize: 6,
        lineStyle: { width: 2, color: "#8079CB" },
        itemStyle: { color: "#8079CB" },
        label: { color: "#8079CB" },
      },
    ],
  };
  chart.setOption(option);
};
// 给首尾点加上 label
const wrapData = (arr: number[]) => {
  return arr.map((v, i) => ({
    value: v,
    label: {
      show: i === 0 || i === arr.length - 1,
      position: "top",
      fontSize: 12,
    },
  }));
};
/** 定时任务 */
const onScheduledTasksClick = () => {};
/** 叫号 */
const onCallBumberClick = () => {};
const onCallBumberClick = () => {
  ElMessage({
    message: "功能开发中,敬请期待!",
    type: "warning",
  });
};
/** 添加记录 */
const onAddRecordClick = () => {};
const onAddRecordClick = () => {
  ElMessage({
    message: "功能开发中,敬请期待!",
    type: "warning",
  });
};
/** 结束透析 */
const onEndClick = () => {};
const onEndClick = () => {
  ElMessage({
    message: "功能开发中,敬请期待!",
    type: "warning",
  });
};
onMounted(() => {
  // 生成ktv趋势图
  generateKtvListEchart(pageData.value.ktvList);
  generatBloodPressureAndPulseEchart(pageData.value.monitoringRecord);
});
onBeforeUnmount(() => {
  // 销毁图表实例
  if (ktvListEchartRef.value) {
    const chart = echarts.getInstanceByDom(ktvListEchartRef.value);
    if (chart) {
      chart.dispose();
    }
  }
  if (bloodPressureAndPulseEchartRef.value) {
    const chart = echarts.getInstanceByDom(
      bloodPressureAndPulseEchartRef.value
    );
    if (chart) {
      chart.dispose();
    }
@@ -716,9 +966,16 @@
    padding: 2px;
  }
  .ktv-card {
    overflow: visible;
    .card-header {
      margin-bottom: 0px;
    }
    ::v-deep(.card-main) {
      overflow: visible !important;
      div {
        overflow: visible;
      }
    }
  }
  :deep(.mini-header) {
    flex: 0 0 4px;