单应用项目,可以创建很多独立工具类页面 ,不用登录 初始化的页面
zhangchen
2025-07-24 9135933a27832ec2234b5e074d88192fb4bf52d1
ID1825-治疗中暂存
2个文件已修改
4个文件已添加
1419 ■■■■■ 已修改文件
src/img/add.png 补丁 | 查看 | 原始文档 | blame | 历史
src/store/type/bedsideAuxiliaryScreen.type.ts 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mobile/bedsideAuxiliaryScreen/components/DoctorAdvice/index.vue 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mobile/bedsideAuxiliaryScreen/components/DoctorAdvice/type.ts 375 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mobile/bedsideAuxiliaryScreen/components/ProgressBar.vue 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mobile/bedsideAuxiliaryScreen/pages/UnderTreatment.vue 691 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/img/add.png
src/store/type/bedsideAuxiliaryScreen.type.ts
@@ -32,6 +32,11 @@
type PushType = "床旁血压计" | "中央监控大屏信息";
export interface KtvItem {
  时间: string;
  ktv: string;
}
export interface DialysisStatus {
  clientCode: string;
  deviceHospitalCode: string;
@@ -39,9 +44,11 @@
  iot_当前脱水量: number | null;
  iot_脱水目标量: number | null;
  iot_脱水速率: number | null;
  iot_透析液流速: number | null;
  iot_跨膜压: number | null;
  iot_透析时间: number | null;
  iot_静脉压: number | null;
  iot_血流量: number | null;
  sortOrder: number | null;
  txTime: number | null;
  上次透后称重: number | null;
@@ -50,7 +57,7 @@
  分区编号: string;
  处方脱水量: number | null;
  实时ktv: string;
  实时ktv计算结果列表: null | string[];
  实时ktv计算结果列表: null | { realTimeKtvCalcDetailResultInfo: KtvItem[], 透析单编号: string };
  实时脱水量: number | null;
  干体重: number | null;
  年龄: number | null;
@@ -109,6 +116,8 @@
  透析液列表: any[];
  透析状态: string; // '0.0'这种格式的,得格式化一下
  透析结束时间: number | null;
  透析处方备注: string;
  最近最大脱水量透析时长: string
}
export interface VascularAccess {
@@ -314,9 +323,9 @@
  monitoringRecord: MonitoringRecord[]; // 监测记录列表
  doctorAdvice: any[]; // 透析单医嘱列表
  bloodFlow: string; // 血流量
  bloodVolumeMonitoring: string; // 血容量监测
  dialysisFluidFlowRate: string; // 透析液流速
  ktvList: string[]; // 实时ktv计算结果列表
  bloodVolumeMonitoring: number | null; // 血容量监测
  dialysisFluidFlowRate: number | null; // 透析液流量
  ktvList: KtvItem[]; // 实时ktv计算结果列表
}
interface MonitoringRecord {
@@ -350,8 +359,8 @@
    monitoringRecord: [],
    doctorAdvice: [],
    bloodFlow: "",
    bloodVolumeMonitoring: "",
    dialysisFluidFlowRate: "",
    bloodVolumeMonitoring: null,
    dialysisFluidFlowRate: null,
    ktvList: [],
  };
};
@@ -395,7 +404,7 @@
    if (seeMsg.透析状态 === null || !seeMsg.透析状态) {
      result.pageType = EPageType.UNPLANNED_SCHEDULE;
      result.consumablesCollection =
        seeMsg?.使用耗材字典 || defaultconsumablesCollection();
        seeMsg?.使用耗材字典 ?? defaultconsumablesCollection();
    } else {
      const treatmentStatus = tryConvertToInt(
        seeMsg.透析状态?.透析状态
@@ -416,14 +425,14 @@
      if (treatmentStatus === EMedStatus.NOT_CHECKED_IN) {
        result.pageType = EPageType.NOT_SIGNED_IN;
        const notSignedIn = defalutNotSignedIn();
        notSignedIn.dialysisMode = seeMsg.透析状态?.透析方案 || "";
        notSignedIn.dialyzerList = seeMsg.透析状态?.透析器列表 || [];
        notSignedIn.pipingList = seeMsg.透析状态?.管路列表 || [];
        notSignedIn.dialysateList = seeMsg.透析状态?.透析液列表 || [];
        notSignedIn.carePackage = seeMsg.透析状态?.护理包列表 || [];
        notSignedIn.punctureNeedle = seeMsg.透析状态?.穿刺针列表 || [];
        notSignedIn.vascularAccess = seeMsg.透析状态?.血管通路列表 || [];
        notSignedIn.anticoagulant = seeMsg.透析状态?.抗凝剂列表 || [];
        notSignedIn.dialysisMode = seeMsg.透析状态?.透析方案 ?? "";
        notSignedIn.dialyzerList = seeMsg.透析状态?.透析器列表 ?? [];
        notSignedIn.pipingList = seeMsg.透析状态?.管路列表 ?? [];
        notSignedIn.dialysateList = seeMsg.透析状态?.透析液列表 ?? [];
        notSignedIn.carePackage = seeMsg.透析状态?.护理包列表 ?? [];
        notSignedIn.punctureNeedle = seeMsg.透析状态?.穿刺针列表 ?? [];
        notSignedIn.vascularAccess = seeMsg.透析状态?.血管通路列表 ?? [];
        notSignedIn.anticoagulant = seeMsg.透析状态?.抗凝剂列表 ?? [];
        result.notSignedIn = notSignedIn;
      }
@@ -431,21 +440,21 @@
      else if (treatmentStatus === EMedStatus.SIGNED_IN) {
        result.pageType = EPageType.SIGNED_IN;
        const signedIn = defaultSignedIn();
        signedIn.abnormalItems = seeMsg.透析状态?.异常检验指标 || [];
        signedIn.dialysisPlan = seeMsg.透析状态?.透析方案 || "";
        signedIn.abnormalItems = seeMsg.透析状态?.异常检验指标 ?? [];
        signedIn.dialysisPlan = seeMsg.透析状态?.透析方案 ?? "";
        signedIn.prescriptionDehydrationVolume =
          seeMsg.透析状态?.处方脱水量 || null;
        signedIn.dialyzer = seeMsg.透析状态?.透析器 || "";
        signedIn.averageDehydrationRate = seeMsg.透析状态?.最近平均脱水量 || "";
          seeMsg.透析状态?.处方脱水量 ?? null;
        signedIn.dialyzer = seeMsg.透析状态?.透析器 ?? "";
        signedIn.averageDehydrationRate = seeMsg.透析状态?.最近平均脱水量 ?? "";
        signedIn.maximumDehydrationCapacity =
          seeMsg.透析状态?.最近最大脱水量 || "";
          seeMsg.透析状态?.最近最大脱水量 ?? "";
        signedIn.maximumDehydrationCapacityDate =
          seeMsg.透析状态?.最近最大脱水量日期 || "";
        signedIn.dryWeight = seeMsg.透析状态?.干体重 || null;
        signedIn.preDialysisWeight = seeMsg.透析状态?.透前称重 || null;
        signedIn.weightAfterLastDialysis = seeMsg.透析状态?.上次透后称重 || null;
        signedIn.weightIncrease = seeMsg.透析状态?.体重增加 || null;
        signedIn.weightIncreaseRate = seeMsg.透析状态?.体重增长率 || null;
          seeMsg.透析状态?.最近最大脱水量日期 ?? "";
        signedIn.dryWeight = seeMsg.透析状态?.干体重 ?? null;
        signedIn.preDialysisWeight = seeMsg.透析状态?.透前称重 ?? null;
        signedIn.weightAfterLastDialysis = seeMsg.透析状态?.上次透后称重 ?? null;
        signedIn.weightIncrease = seeMsg.透析状态?.体重增加 ?? null;
        signedIn.weightIncreaseRate = seeMsg.透析状态?.体重增长率 ?? null;
        result.signedIn = signedIn;
      }
@@ -453,42 +462,43 @@
      else {
        result.pageType = EPageType.DURING_DIALYSIS;
        const underTreatment = defaultUnderTreatment();
        underTreatment.substituteMode = seeMsg.透析状态?.置换方式 || "";
        underTreatment.dialysisPlan = seeMsg.透析状态?.透析方案 || "";
        underTreatment.dialyzer = seeMsg.透析状态?.透析器 || "";
        underTreatment.substituteMode = seeMsg.透析状态?.置换方式 ?? "";
        underTreatment.dialysisPlan = seeMsg.透析状态?.透析方案 ?? "";
        underTreatment.dialyzer = seeMsg.透析状态?.透析器 ?? "";
        underTreatment.averageDehydrationRate =
          seeMsg.透析状态?.最近平均脱水量 || "";
          seeMsg.透析状态?.最近平均脱水量 ?? "";
        underTreatment.maximumDehydrationCapacity =
          seeMsg.透析状态?.最近最大脱水量 || "";
          seeMsg.透析状态?.最近最大脱水量 ?? "";
        underTreatment.maximumDehydrationCapacityDate =
          seeMsg.透析状态?.最近最大脱水量日期 || "";
        underTreatment.maximumDehydrationDuration = "";
        underTreatment.prescriptionRemarks = seeMsg.透析状态?.处方备注 || "";
        underTreatment.abnormalItems = seeMsg.透析状态?.异常检验指标 || [];
          seeMsg.透析状态?.最近最大脱水量日期 ?? "";
        underTreatment.maximumDehydrationDuration = seeMsg.透析状态?.最近最大脱水量透析时长 ?? "";
        underTreatment.prescriptionRemarks = seeMsg.透析状态?.透析处方备注 ?? "";
        underTreatment.abnormalItems = seeMsg.透析状态?.异常检验指标 ?? [];
        underTreatment.prescriptionDialysisDuration =
          seeMsg.透析状态?.透析处方的时长_小时 || "";
          seeMsg.透析状态?.透析处方的时长_小时 ?? "";
        underTreatment.dialysisStartTime =
          seeMsg.透析状态?.透析开始时间 || null;
        underTreatment.dialysisEndTime = seeMsg.透析状态?.透析结束时间 || null;
        underTreatment.dialysisDuration = seeMsg.透析状态?.iot_透析时间 || null;
          seeMsg.透析状态?.透析开始时间 ?? null;
        underTreatment.dialysisEndTime = seeMsg.透析状态?.透析结束时间 ?? null;
        underTreatment.dialysisDuration = seeMsg.透析状态?.iot_透析时间 ?? null;
        underTreatment.prescriptionDehydrationVolume =
          seeMsg.透析状态?.处方脱水量 || null;
          seeMsg.透析状态?.处方脱水量 ?? null;
        underTreatment.currentDehydrationVolume =
          seeMsg.透析状态?.实时脱水量 || null;
          seeMsg.透析状态?.实时脱水量 ?? null;
        underTreatment.currentUltrafiltrationRate =
          seeMsg.透析状态?.iot_脱水速率 || null;
          seeMsg.透析状态?.iot_脱水速率 ?? null;
        underTreatment.currentBloodTemperature =
          seeMsg.透析状态?.当前血温 || null;
        underTreatment.venousPressure = seeMsg.透析状态?.iot_静脉压 || null;
          seeMsg.透析状态?.当前血温 ?? null;
        underTreatment.venousPressure = seeMsg.透析状态?.iot_静脉压 ?? null;
        underTreatment.transmembranePressure =
          seeMsg.透析状态?.iot_跨膜压 || null;
        underTreatment.ktv = seeMsg.透析状态?.实时ktv || "";
        underTreatment.monitoringRecord = seeMsg.透析状态?.监测记录列表 || [];
        underTreatment.doctorAdvice = seeMsg.透析状态?.透析单医嘱列表 || [];
          seeMsg.透析状态?.iot_跨膜压 ?? null;
        underTreatment.ktv = seeMsg.透析状态?.实时ktv ?? "";
        underTreatment.monitoringRecord = seeMsg.透析状态?.监测记录列表 ?? [];
        underTreatment.doctorAdvice = seeMsg.透析状态?.透析单医嘱列表 ?? [];
        underTreatment.bloodFlow = "";
        underTreatment.dialysisFluidFlowRate = "";
        underTreatment.bloodVolumeMonitoring = "";
        underTreatment.ktvList = seeMsg.透析状态?.实时ktv计算结果列表 || [];
        underTreatment.dialysisFluidFlowRate = seeMsg.透析状态?.iot_血流量 ?? null;
        underTreatment.bloodVolumeMonitoring = seeMsg.透析状态?.iot_透析液流速 ?? null;
        underTreatment.ktvList = seeMsg.透析状态?.实时ktv计算结果列表?.realTimeKtvCalcDetailResultInfo ?? [];
        result.underTreatment = underTreatment;
      }
    }
  }
@@ -542,3 +552,13 @@
    return "";
  }
};
export const formatSubstituteMode = (mode: string) => {
  let result = "";
  if (mode === '前置换') {
    result = '前'
  } else if (mode === '后置换') {
    result = '后'
  }
  return result;
}
src/views/mobile/bedsideAuxiliaryScreen/components/DoctorAdvice/index.vue
New file
@@ -0,0 +1,184 @@
<template>
  <div class="doctor_advice_container" :style="{ height: height }">
    <div class="doctor_advice_list">
      <div
        v-for="(item, index) in drugOrders"
        :key="index"
        class="doctor_advice_item"
      >
        <div class="doctor_advice_item_name">{{ item.name }}</div>
        <template v-if="item?.children && item.children.length > 0">
          <div
            v-for="(child, childIndex) in item.children"
            :key="childIndex"
            class="doctor_advice_item_sub"
          >
            <img :src="trunImgSrc" alt="" />
            <span>{{ child }}</span>
          </div>
        </template>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
import { PropType, computed } from "vue";
import type { Order } from "./type"
import trunImgSrc from "@/assets/turn.png";
export default {
  name: "DoctorAdvice",
  props: {
    // 容器的高度
    height: {
      type: String,
      default: '100%',
      required: false,
    },
    // 医嘱列表
    list: {
      type: Array as PropType<Order[]>,
      default: () => [],
    },
  },
  setup(props) {
    const drugOrders = computed(() => {
      // 格式化主医嘱数据(浅拷贝)
      const formatList = props.list
        .filter((e) => e.orderIsSub !== 1)
        .map((e) => ({ ...e }));
      // 处理子医嘱并挂载到对应主医嘱上
      props.list.forEach((e) => {
        if (e.orderIsSub === 1) {
          const i = formatList.findIndex((v) => v.code === e.orderMainCode);
          if (i !== -1) {
            if (!formatList[i].subDrugOrders) {
              formatList[i].subDrugOrders = [];
            }
            formatList[i].subDrugOrders.push(e);
          }
        }
      });
      // 构建显示用的 name 和子医嘱 children
      return formatList.map((order) => {
        let name = "";
        if (order.orderNameInfo) {
          name = order.orderNameInfo.itemName || "";
          const drugSpec = order.orderNameInfo.feeDrugInfo?.drugSpec;
          if (drugSpec) {
            name += ` (${drugSpec})`;
          }
        }
        if (order.orderUsage && order.orderUsage !== 0) {
          name += ` ${order.orderUsage}${
            order.orderNameInfo?.feeDrugInfo?.drugUnitName || ""
          }`;
        }
        if (order.orderCount) {
          name += ` ${order.orderCount}`;
          const pkgUnit = order.orderNameInfo?.feeDrugInfo?.drugPackageUnitName;
          if (pkgUnit) {
            name += pkgUnit;
          }
        }
        if (order.orderFromInfo?.dictText) {
          name += ` ${order.orderFromInfo.dictText}`;
        }
        if (order.orderFreqInfo?.dictText) {
          name += ` ${order.orderFreqInfo.dictText}`;
        }
        const children: string[] = [];
        if (order.subDrugOrders?.length) {
          order.subDrugOrders.forEach((child: any) => {
            let subName = child.orderNameInfo?.itemName || "";
            const childSpec = child.orderNameInfo?.feeDrugInfo?.drugSpec;
            if (childSpec) {
              subName += ` (${childSpec})`;
            }
            if (child.orderUsage) {
              const unit = child.orderNameInfo?.feeDrugInfo?.drugUnitName || "";
              subName += ` ${child.orderUsage}${unit}`;
            }
            if (child.orderCount) {
              const pkgUnit =
                child.orderNameInfo?.feeDrugInfo?.drugPackageUnitName;
              if (pkgUnit) {
                subName += ` ${child.orderCount}${pkgUnit}`;
              }
            }
            children.push(subName);
          });
        }
        return {
          name,
          children,
        };
      });
    });
    return {
      drugOrders,
      trunImgSrc,
    };
  },
};
</script>
<style scoped>
.doctor_advice_container {
  box-sizing: border-box;
}
.doctor_advice_container .doctor_advice_list {
  box-sizing: border-box;
  height: 100%;
  background: #ffffff;
  overflow: hidden;
  overflow-y: auto;
}
.doctor_advice_container .doctor_advice_item {
  box-sizing: border-box;
  border-bottom: 1px solid #e6e5e5;
}
.doctor_advice_container .doctor_advice_item:last-child {
  /* box-sizing: border-box;
  border-bottom: none; */
}
.doctor_advice_container .doctor_advice_item .doctor_advice_item_name {
  box-sizing: border-box;
  font-weight: 400;
  font-size: 5px;
  color: #333333;
  line-height: 12px;
  text-align: left;
  font-style: normal;
}
.doctor_advice_container .doctor_advice_item_sub {
  padding-left: 1px;
  font-weight: 400;
  font-size: 5px;
  color: #777777;
  line-height: 12px;
  text-align: left;
  font-style: normal;
}
.doctor_advice_container .doctor_advice_item_sub img {
  width: 7px;
  height: 7px;
  margin-right: 2px;
}
</style>
src/views/mobile/bedsideAuxiliaryScreen/components/DoctorAdvice/type.ts
New file
@@ -0,0 +1,375 @@
export interface Order {
    orderType: number;
    code: string;
    orderFreq: string;
    orderDoctor: string;
    confirmUserInfo: any | null;
    remark: string | null;
    isConfirm: number;
    isDeleted: number;
    orderExecuteCheckUser: any | null;
    orderIsSub: number;
    orderExecuteTime: any | null;
    id: number;
    recordCode: string;
    deletedTime: any | null;
    orderExecutePatient: any | null;
    orderExecuteUser: any | null;
    orderName: string;
    orderExecuteCheckUserInfo: any | null;
    subDrugOrders: any | null;
    orderSort: number;
    orderCount: number;
    hisOrderNo: string | null;
    updateUser: any | null;
    confirmTime: any | null;
    confirmUser: any | null;
    updateTime: number;
    orderDoctorInfo: UserDoctorInfo;
    orderMainCode: string | null;
    createTime: number;
    orderFreqInfo: OrderFreqInfo;
    orderNameInfo: OrderNameInfo;
    createUser: any | null;
    orderFrom: string;
    orderUsage: number;
    orderIsSpin: number;
    orderExecuteUserInfo: any | null;
    orderFromInfo: OrderFromInfo;
    orderStartTime: number;
}
interface UserDoctorInfo {
    isRecvAlarmEmail: number;
    prepareWorkMedicineStat: any | null;
    userDegree: any | null;
    isRecvAlarmWechat: number;
    listReadyRows: any | null;
    selectedFieldsInInventory2OutPage: any | null;
    currentClientInfo: any | null;
    signedInCountByDa: any | null;
    selectFieldsInShangjiCanshuPage: any | null;
    relatedClients: any | null;
    userWorkState: any | null;
    userIdentityCode: any | null;
    clientInfos: any | null;
    userMobile: string;
    id: number;
    loginWechatMpId: any | null;
    userIsTongluDoctor: number;
    canModifyHistoryHms: boolean;
    是否自动出库至二级默认仓库: any | null;
    userGoDepartment: any | null;
    userRfid: any | null;
    userGraduateTime: any | null;
    管理员能看到的客户列表: any | null;
    userSortOrder: number;
    userCustomSetting: string;
    hisCode: any | null;
    isRecvAlarm: any | null;
    selectedFieldsInCleanStatPage: any | null;
    排班时段选择项: any | null;
    userVsRoleList: any | null;
    userPassword: string;
    code: string;
    userSignPicUrl: any | null;
    userFromDepartment: any | null;
    roles: any | null;
    userAvatar: any | null;
    userNo: string;
    admin: boolean;
    remark: string;
    userAdmin: boolean;
    checkVersionCode: string;
    selectedFieldsInMedStat2: any | null;
    userTitle: string;
    isDeleted: number;
    nurse: boolean;
    canDeleteHistoryHms: boolean;
    userEmail: string;
    deletedTime: any | null;
    userWorkTimeFrom: any | null;
    prepareWorkMedicine: any | null;
    clientVsUserList: any | null;
    isValid: number;
    teamState: any | null;
    updateUser: number;
    updateTime: number;
    隐藏自备药: any | null;
    userName: string;
    selectFieldsInTodayOrderPage: any | null;
    isShow: number;
    doctor: boolean;
    isValidForClient: number;
    loginWechatUnionId: any | null;
    userGoDate: any | null;
    createTime: number;
    userInDate: any | null;
    clientCode: any | null;
    selectedFieldsInInventory2QueryPage: any | null;
    signedInCountByStatistics: any | null;
    createUser: number;
    userGender: number;
    userPinyin: string;
    listStatInfo: any | null;
}
interface OrderFreqInfo {
    code: string;
    dictIsCustom: number;
    updateUser: any | null;
    remark: any | null;
    updateTime: number;
    dictNo: string;
    dictType: string;
    dictIsEnable: number;
    isDeleted: number;
    createTime: number;
    hisCode: any | null;
    sortOrder: number;
    createUser: number;
    id: number;
    deletedTime: any | null;
    dictText: string;
}
interface OrderNameInfo {
    itemAgent: any | null;
    itemPermissionCode: any | null;
    inventoryItemTypeInfo: InventoryItemTypeInfo;
    itemIsUse: number;
    itemIsRestrictUse: number;
    itemCode: string;
    itemHisType: any | null;
    itemUnit: any | null;
    suntopItemCode: any | null;
    itemOutPrice: number;
    itemFactoryInfo: any | null;
    itemName: string;
    itemCommonUseInBothSide: any | null;
    id: number;
    当前使用量: any | null;
    剩余总量: any | null;
    storageCode: any | null;
    入库总量: any | null;
    透析器国网上报: DialyzerReport;
    hisCode: any | null;
    itemIsOutToPatient: number;
    itemSalePrice: number;
    itemIsReUse: number;
    itemPackageUnit: any | null;
    inStorageCountInfo: any | null;
    itemPackageUnitName: string;
    itemIsFavor: number;
    itemSpec: string;
    itemYibaoPrice: any | null;
    inventoryTypeCode: string;
    code: string;
    itemLicenseCode: any | null;
    itemAgentInfo: any | null;
    itemOperator: any | null;
    remark: any | null;
    批号对象列表: any | null;
    isDeleted: number;
    itemIsEnableManage: number;
    deletedTime: any | null;
    itemIsUseAsXt: number;
    itemName2: string;
    inventoryItemType: number;
    itemMoMaterial: any | null;
    itemMoArea: number;
    itemPinyin: string;
    itemTxqCleanRate: any | null;
    inventoryTypeName: any | null;
    itemSortOrder: number;
    updateUser: any | null;
    updateTime: number;
    结存: any | null;
    isShow: number;
    itemFactory: any | null;
    feeDrugInfo: FeeDrugInfo;
    itemOperatorInfo: any | null;
    itemPackageCount: any | null;
    createTime: number;
    clientCode: string;
    itemExtendJson: string;
    itemPeriodAlarmDays: number;
    itemRestrictUseRemark: any | null;
    createUser: number;
    itemUnitInfo: any | null;
    itemInPrice: number;
    itemInventoryAlarmCount: number;
    itemYibaoCode: any | null;
}
interface InventoryItemTypeInfo {
    code: string;
    typeName: string;
    updateUser: any | null;
    remark: any | null;
    updateTime: number;
    typeCategory: number;
    isShow: boolean;
    isDeleted: number;
    isEditable: number;
    createTime: number;
    clientCode: any | null;
    sortOrder: number;
    createUser: any | null;
    id: number;
    deletedTime: any | null;
}
interface DialyzerReport {
    eSA_促红素种类: string;
    抗凝剂_低分子肝素首剂量_IU: string;
    抗凝剂_总剂量: string;
    透析器透析膜: string;
    铁剂_其它静脉种类: string;
    eSA_用药方式: any[]; // 根据实际元素类型替换 any
    eSA_静脉剂量单位: string;
    铁剂_静脉剂量周: string;
    抗凝剂_枸橼酸钠速率每小时_ml: string;
    抗凝剂_阿加曲班追加速率_IU每小时: string;
    抗凝剂_肝素追加速率_mg每小时: string;
    透析器使用: string;
    抗凝剂_低分子肝素单位: string;
    抗凝剂_肝素首剂量_mg: string;
    抗凝剂_枸橼酸钠_其它钠浓度: string;
    抗凝剂_追加剂量: string;
    抗凝剂_其它抗凝剂: string;
    透析器类型: string;
    抗凝剂_阿加曲班_追加时间小时: string;
    抗凝剂_阿加曲班追加速率_mg每小时: string;
    抗凝剂_低分子肝素首剂量_mg: string;
    抗凝剂_阿加曲班首剂量_mg: string;
    透析器通量: string;
    抗凝剂_肝素首剂量_IU: string;
    铁剂_静脉种类: string;
    药品类型: string;
    eSA_皮下剂量: string;
    铁剂_口服剂量日: string;
    eSA_静脉剂量: string;
    抗凝剂_种类: string;
    抗凝剂_阿加曲班_追加时间分钟: string;
    eSA_促红素名称: string;
    抗凝剂_低分子肝素类型: string;
    铁剂_给药方式: string;
    抗凝剂_首剂量: string;
    抗凝剂_低分子肝素总剂量: string;
    抗凝剂_低分子肝素追加时间: string;
    抗凝剂_低分子肝素追加剂量_mg: string;
    抗凝剂_肝素_追加时间小时: string;
    铁剂_其它口服种类: string;
    抗凝剂_阿加曲班首剂量_IU: string;
    抗凝剂_枸橼酸钠_使用时间小时: string;
    抗凝剂_肝素_追加时间分钟: string;
    抗凝剂_枸橼酸钠浓度百分比: string;
    抗凝剂_肝素单位: string;
    抗凝剂_阿加曲班单位: string;
    eSA_皮下剂量单位: string;
    抗高血压药_分类: any[];
    抗凝剂_枸橼酸钠_使用时间分钟: string;
    抗凝剂_肝素追加速率_IU每小时: string;
    铁剂_口服种类: string;
    透析器膜面积: string;
    抗凝剂_是否使用华法林: string;
    抗凝剂_低分子肝素追加剂量_IU: string;
    eSA_其它促红素说明: string;
    铁剂_口服剂量单位: string;
    铁剂_静脉剂量单位: string;
}
interface FeeDrugInfo {
    drugBarcode: string;
    drugIsNeedTest: number;
    drugUsePeriodName: string;
    drugProduceLocation: string;
    drugPriceYibao: number;
    drugUseTypeName: string;
    drugPermissionCode: string;
    drugCategory: number;
    drugPackageType: number;
    drugPackageUnitAlias: string;
    drugSpec: string;
    drugAntibioticLevel: number;
    drugJixing: string;
    drugHisCode: any | null;
    drugInventoryPackageTypeName: any | null;
    drugBenweiCode: string;
    id: number;
    drugUseMethodName: string;
    drugIsFavor: number;
    drugPackageUnitName: string;
    drugPackageSum: number;
    drugSortOrder: number;
    drugYibaoCode: string;
    inventoryItemDetailCode: string;
    drugName2: string;
    drugUseUnitName: string;
    drugUnit: string;
    drugUsePeriod: string;
    drugInventoryPackageCount: number;
    drugUseMethod: string;
    drugName: string;
    drugUseUnit: string;
    drugInventoryPackageType: string;
    drugUseOnetime: string;
    code: string;
    drugCode: string;
    drugPackageUnit: string;
    drugProduceFactoryName: any | null;
    drugYlCode: string;
    remark: string;
    drugLimitUseText: string;
    drugProduceFactory: string;
    drugUnitName: string;
    isDeleted: number;
    drugInventoryAlertDays: number;
    drugPriceIn: number;
    drugStatus: number;
    drugPriceCategory: number;
    drugVsDiagnoseName: any | null;
    drugSyncPrice: number;
    deletedTime: any | null;
    drugPackageUnitAliasName: string;
    drugPinyin: string;
    drugVsDiagnose: string;
    drugGansuUseLimit: any | null;
    drugProperty: string;
    drugJixingName: string;
    drugPriceSale: number;
    updateUser: any | null;
    drugTransfer1: any | null;
    updateTime: number;
    drugTransfer2: any | null;
    drugUseType: string;
    drugLimitUseType: number;
    drugInventoryAlertValidDays: number;
    createTime: number;
    createUser: any | null;
    drugMonitorCode: string;
    drugPlusPercent: number;
    drugInHospitalUseType: number;
    drugSpecialProperty: number;
    drugBaseType: number;
}
interface OrderFromInfo {
    code: string;
    dictIsCustom: number;
    updateUser: any | null;
    remark: any | null;
    updateTime: number;
    dictNo: string;
    dictType: string;
    dictIsEnable: number;
    isDeleted: number;
    createTime: number;
    hisCode: any | null;
    sortOrder: number;
    createUser: any | null;
    id: number;
    deletedTime: any | null;
    dictText: string;
}
src/views/mobile/bedsideAuxiliaryScreen/components/ProgressBar.vue
New file
@@ -0,0 +1,45 @@
<template>
  <div class="progress-container" :style="{ backgroundColor: props.backgroundColor || '#d6def1' }">
    <div
      class="progress-bar"
      :style="{
        width: computedWidth,
        backgroundColor: color,
        borderRadius: '0 999px 999px 0',
      }"
    ></div>
  </div>
</template>
<script setup lang="ts">
import { computed } from "vue";
interface Props {
  percent: number; // 0 ~ 100
  color?: string;
  backgroundColor?: string;
  borderRadius?: string;
}
const props = defineProps<Props>();
const computedWidth = computed(
  () => Math.min(Math.max(props.percent, 0), 100) + "%"
);
</script>
<style scoped>
.progress-container {
  width: 46px;
  height: 6px;
  background: #d6def1;
  border-radius: 999px;
  overflow: hidden;
}
.progress-bar {
  height: 100%;
  transition: width 0.3s ease;
  border-radius: 0 999px 999px 0;
}
</style>
src/views/mobile/bedsideAuxiliaryScreen/pages/UnderTreatment.vue
@@ -12,21 +12,318 @@
            </template>
          </el-image>
        </div>
        <div class="left-row1-col2"></div>
        <div class="left-row1-col3"></div>
        <div class="left-row1-col2">
          <Card
            title="治疗模式"
            :icon="zlmsImg"
            background-color="#ffffff"
            class="mini-card left-row1-col2-row1"
            header-class-name="mihi-header"
          >
            <div class="item-box dialysis-mode-content">
              <div class="dialysis-mode-content-box">
                <span class="mini-text">{{
                  formatSubstituteMode(pageData.substituteMode)
                }}</span>
                <span class="text">{{ pageData.dialysisPlan }}</span>
              </div>
            </div>
          </Card>
          <Card
            title="处方备注"
            :icon="zlmsImg"
            background-color="#ffffff"
            class="mini-card left-row1-col2-item-row2"
            header-class-name="mihi-header"
          >
            <div class="prescription-remarks">
              {{ pageData.prescriptionRemarks }}
            </div>
          </Card>
        </div>
        <div class="left-row1-col3">
          <Card
            title="透析器"
            :icon="zlmsImg"
            background-color="#ffffff"
            class="mini-card left-row1-col3-row1"
            header-class-name="mihi-header"
          >
            <div class="item-box prescription-ehydration-olume">
              <span class="text">{{ pageData.dialyzer }}</span>
            </div>
          </Card>
          <Card
            title="异常指标"
            :icon="zlmsImg"
            background-color="#ffffff"
            class="mini-card left-row1-col3-row2"
            header-class-name="mihi-header"
          >
            <div class="dialysis-mode-content">
              <span
                v-for="(item, index) in pageData.abnormalItems"
                :key="index"
                class="abnormal-indicator"
                :style="{ color: formatTestColr(item.结果标记) }"
              >
                {{ getItemName(item.项目名称) }}
                {{ formatTestFlag(item.结果标记) }}
              </span>
            </div>
          </Card>
        </div>
      </div>
      <div class="left-row2"></div>
      <div class="left-row3"></div>
      <div class="left-row4"></div>
      <div class="left-row2">
        <Card
          title="血温监测"
          :icon="zlmsImg"
          background-color="#ffffff"
          class="mini-card left-row2-col1"
          header-class-name="mihi-header"
        >
          <div class="item-box current-lood0emperature">
            <span class="text">{{ pageData.currentBloodTemperature }}</span>
          </div>
        </Card>
        <Card
          title="血压监测"
          :icon="zlmsImg"
          background-color="#ffffff"
          class="mini-card left-row2-col2"
          header-class-name="mihi-header"
        >
          <div class="item-box venous-pressure">
            <span class="text"
              >{{ pageData.venousPressure }}/{{
                pageData.transmembranePressure
              }}</span
            >
          </div>
        </Card>
        <Card
          title="血压脉搏趋势图"
          :icon="zlmsImg"
          background-color="#ffffff"
          class="mini-card left-row2-col3"
          header-class-name="mihi-header"
        >
          <div class=""></div>
        </Card>
      </div>
      <div class="left-row3">
        <Card
          title="血容量监测"
          :icon="zlmsImg"
          background-color="#ffffff"
          class="mini-card left-row3-col1"
          header-class-name="mihi-header"
        >
          <div class="item-box current-lood0emperature">
            <span class="text">{{ pageData.bloodVolumeMonitoring }}</span>
          </div>
        </Card>
        <Card
          title="KTV监测"
          :icon="zlmsImg"
          background-color="#ffffff"
          class="mini-card left-row3-col2"
          header-class-name="mihi-header"
        >
          <div class="item-box venous-pressure">
            <span class="text">{{ pageData.ktv }}</span>
          </div>
        </Card>
        <Card
          title="KTV趋势图"
          :icon="zlmsImg"
          background-color="#ffffff"
          class="mini-card ktv-card left-row3-col3"
          header-class-name="mihi-header"
        >
          <div style="height: 100%">
            <div ref="ktvListEchartRef" style="width: 100%; height: 100%"></div>
          </div>
        </Card>
      </div>
      <div class="left-row4">
        <Card
          title="血流量"
          :icon="zlmsImg"
          background-color="#ffffff"
          class="mini-card left-row4-col"
          header-class-name="mihi-header"
        >
          <div class="item-box current-lood0emperature">
            <span class="text">{{ pageData.bloodFlow }}</span>
          </div>
        </Card>
        <Card
          title="透析液流量"
          :icon="zlmsImg"
          background-color="#ffffff"
          class="mini-card left-row4-col"
          header-class-name="mihi-header"
        >
          <div class="item-box current-lood0emperature">
            <span class="text">{{ pageData.dialysisFluidFlowRate }}</span>
          </div>
        </Card>
      </div>
    </div>
    <div class="right-box"></div>
    <div class="right-box">
      <div class="right-box-row1">
        <Card
          title="治疗状态"
          :icon="zlmsImg"
          background-color="#ffffff"
          class="mini-card right-box-row1-col1"
          header-class-name="mini-header"
        >
          <div class="item-box treatment-status">
            <span class="text">{{ treatmentStatusText }}</span>
          </div>
        </Card>
        <Card
          title="脱水量详情"
          :icon="zlmsImg"
          background-color="#ffffff"
          class="mini-card right-box-row1-col2"
          header-class-name="mini-header"
        >
          <div class="dehydrated-level">
            <div class="dehydrated-level-item">
              <span class="item-left"
                >平均脱水量:{{ pageData.averageDehydrationRate }} L</span
              >
              <span class="item-right">(最近3周9次)</span>
            </div>
            <div class="dehydrated-level-item">
              <div class="item-left">
                <span
                  >最大脱水量:{{ pageData.maximumDehydrationCapacity }} L</span
                >
                <template v-if="pageData.maximumDehydrationDuration"
                  >/
                  <span class="level-dete">{{
                    pageData.maximumDehydrationDuration
                  }}</span>
                </template>
              </div>
              <span class="item-right"
                >({{ pageData.maximumDehydrationCapacityDate }})</span
              >
            </div>
          </div>
        </Card>
      </div>
      <div class="right-box-row2">
        <Card
          title="时间进度"
          :icon="zlmsImg"
          background-color="#ffffff"
          class="mini-card right-box-row2-item"
          header-class-name="mini-header"
        >
          <div class="item-box">
            <div class="item-num"></div>
          </div>
        </Card>
        <Card
          title="超滤进度"
          :icon="zlmsImg"
          background-color="#ffffff"
          class="mini-card right-box-row2-item"
          header-class-name="mini-header"
        >
          <div class="progress-box">
            <div class="item-num">
              {{ pageData.currentDehydrationVolume }}/{{
                pageData.currentDehydrationVolume
              }}({{ pageData.currentUltrafiltrationRate }})
            </div>
            <ProgressBar
              :percent="
                (pageData.currentDehydrationVolume /
                  pageData.currentDehydrationVolume) *
                100
              "
              color="#70CAAE"
              backgroundColor="#D6DEF1"
              borderRadius="50%"
            />
          </div>
        </Card>
      </div>
      <div class="right-box-row3">
        <Card
          title="临时医嘱"
          :icon="zlmsImg"
          background-color="#ffffff"
          class="mini-card right-box-row2-item"
          header-class-name="mini-header"
        >
          <DoctorAdvice :list="pageData.doctorAdvice" />
        </Card>
      </div>
      <div class="right-box-row4">
        <BlockBotttom
          :icon="dingShiImg"
          text="定时任务"
          backgroundColor="#20C6B6"
          @click="() => onScheduledTasksClick()"
          class="btn"
        />
        <BlockBotttom
          :icon="jiaoHaoImg"
          text="叫号"
          backgroundColor="#20C6B6"
          @click="() => onCallBumberClick()"
          class="btn"
        />
        <BlockBotttom
          :icon="addImg"
          text="添加记录"
          backgroundColor="#409EFF"
          @click="() => onAddRecordClick()"
          class="btn"
        />
        <BlockBotttom
          :icon="kaiShiImg"
          text="j结束透析"
          backgroundColor="#E6A23C"
          @click="() => onEndClick()"
          class="btn"
        />
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup name="UnderTreatment">
import { computed } from "vue";
import { computed, ref, onMounted, onBeforeUnmount } from "vue";
import * as echarts from "echarts";
// @ts-ignore
import Card from "../components/Card.vue";
// @ts-ignore
import ProgressBar from "../components/ProgressBar.vue";
import DoctorAdvice from "../components/DoctorAdvice/index.vue";
// @ts-ignore
import BlockBotttom from "../components/BlockBotttom.vue";
import { useBedsideAuxiliaryScreenStore } from "@/store/bedsideAuxiliaryScreen";
import {
  formatSubstituteMode,
  formatTestColr,
  getItemName,
  formatTestFlag,
  EMedStatus,
} from "@/store/type/bedsideAuxiliaryScreen.type";
import type { KtvItem } from "@/store/type/bedsideAuxiliaryScreen.type";
import { formatDate } from "@/utils/formatTime";
import zlmsImg from "@/img/zlms.png";
import dingShiImg from "@/img/dingshi2.png";
import jiaoHaoImg from "@/img/jiaoHao.png";
import kaiShiImg from "@/img/kaiShi.png";
import addImg from "@/img/add.png";
interface Props {
  height: number;
@@ -35,10 +332,109 @@
const bedsideAuxiliaryScreenStore = useBedsideAuxiliaryScreenStore();
// ktv趋势图的
const ktvListEchartRef = ref<HTMLElement | null>(null);
const pageData = computed(() => {
  return Object.assign(bedsideAuxiliaryScreenStore.deviceData.underTreatment, {
    patientPhone: bedsideAuxiliaryScreenStore.deviceData.patientPhone,
  });
});
const treatmentStatusText = computed(() => {
  const status = bedsideAuxiliaryScreenStore.deviceData.treatmentStatus;
  if (status === EMedStatus.NOT_CHECKED_IN) return "未签到";
  if (status === EMedStatus.SIGNED_IN) return "已签到";
  if (status === EMedStatus.DURING_DIALYSIS) return "透析中";
  if (status === EMedStatus.END) return "已结束";
  if (status === EMedStatus.CHECKED) return "已检查";
  if (status === EMedStatus.ARCHIVED) return "已归档";
  return "未知状态";
});
// const;
/** 生成ktv趋势图 */
const generateKtvListEchart = (ktvList: KtvItem[]) => {
  if (!ktvListEchartRef.value) return;
  if (!ktvList || ktvList.length === 0) return;
  // 检查是否已经有实例
  let chart = echarts.getInstanceByDom(ktvListEchartRef.value);
  if (!chart) {
    chart = echarts.init(ktvListEchartRef.value);
  }
  const option = {
    xAxis: {
      type: "category",
      data: ktvList.map((item) => formatDate(new Date(item.时间), "HH:mm")),
      axisLine: { show: true },
      axisTick: { show: true },
      // axisLabel: {
      //   margin: 5, // 控制文字与轴的距离,尽量小
      //   fontSize: 12,
      // },
    },
    yAxis: {
      type: "value",
      axisLine: { show: true },
      axisTick: { show: true },
      // axisLabel: {
      //   margin: 5,
      //   fontSize: 12,
      // },
      splitLine: { show: true },
    },
    series: [
      {
        data: ktvList.map((item) => item.ktv),
        type: "line",
        smooth: false,
        symbol: "circle",
        symbolSize: 6,
        lineStyle: {
          width: 2,
          color: "#70CAAE",
        },
        itemStyle: {
          color: "#70CAAE",
        },
      },
    ],
    tooltip: {
      trigger: "axis",
    },
  };
  chart.setOption(option, true); // 第二个参数为 true 表示全量更新
};
/** 定时任务 */
const onScheduledTasksClick = () => {};
/** 叫号 */
const onCallBumberClick = () => {};
/** 添加记录 */
const onAddRecordClick = () => {};
/** 结束透析 */
const onEndClick = () => {};
onMounted(() => {
  // 生成ktv趋势图
  generateKtvListEchart(pageData.value.ktvList);
});
onBeforeUnmount(() => {
  // 销毁图表实例
  if (ktvListEchartRef.value) {
    const chart = echarts.getInstanceByDom(ktvListEchartRef.value);
    if (chart) {
      chart.dispose();
    }
  }
});
</script>
@@ -55,48 +451,287 @@
  padding-bottom: 2px;
  overflow: hidden;
  .left-box {
    flex: 0 0 58.25%;
    height: calc(100% - 12px);
    width: 58.25%;
    height: 100%;
    display: flex;
    align-items: flex-start;
    flex-direction: column;
    gap: 4px;
    div {
      width: 100%;
    }
    .left-row1 {
      flex: 0 0 41.99%;
      // width: calc(100% - 8px);
      gap: 4px;
      width: 100%;
      height: 38.97%;
      display: flex;
      background: blue;
      gap: 4px;
      .left-row1-col1,
      .left-row1-col2,
      .left-row1-col3 {
        height: 100%;
      }
      .left-row1-col1 {
        flex: 0 0 26.94%;
        width: 26.94%;
        border-radius: 2px;
        overflow: hidden;
      }
      .left-row1-col2 {
        flex: 0 0 26.42%;
        width: 26.43%;
        display: flex;
        flex-direction: column;
        gap: 4px;
        .left-row1-col2-row1 {
          height: 36.62%;
        }
        .left-row1-col2-item-row2 {
          height: 63.38%;
        }
      }
      .left-row1-col3 {
        flex: 0 0 46.63%;
        width: 46.63%;
        display: flex;
        flex-direction: column;
        gap: 4px;
        .left-row1-col3-row1 {
          height: 36.62%;
        }
        .left-row1-col3-row2 {
          height: 63.38%;
          .dialysis-mode-content {
            height: 100%;
            .abnormal-indicator {
              display: inline-block;
              margin-right: 6px;
              margin-bottom: 4px;
              font-family: PingFangSC, PingFang SC;
              font-weight: 600;
              font-size: 5px;
              line-height: 6px;
              text-align: left;
              font-style: normal;
            }
          }
        }
      }
    }
    .left-row2 {
      flex: 0 0 22.65%;
      background: yellow;
      width: 100%;
      height: 21.03%;
      display: flex;
      gap: 4px;
      .left-row2-col1 {
        width: 26.94%;
      }
      .left-row2-col2 {
        width: 26.43%;
      }
      .left-row2-col3 {
        width: 46.62%;
      }
    }
    .left-row3 {
      flex: 0 0 22.65%;
      background: orange;
      width: 100%;
      height: 21.03%;
      display: flex;
      gap: 4px;
      .left-row3-col1 {
        width: 26.94%;
      }
      .left-row3-col2 {
        width: 26.43%;
      }
      .left-row3-col3 {
        width: 46.62%;
      }
    }
    .left-row4 {
      flex: 0 0 12.71%;
      background: purple;
      width: 100%;
      height: 11.79%;
      display: flex;
      gap: 4px;
      .left-row4-col {
        width: 50%;
      }
    }
  }
  .right-box {
    flex: 0 0 41.75%;
    width: 41.75%;
    height: 100%;
    background: green;
    display: flex;
    flex-direction: column;
    gap: 4px;
    .right-box-row1,
    .right-box-row2,
    .right-box-row3 .right-box-row4 {
      width: 100%;
    }
    .right-box-row1 {
      height: 14.44%;
      display: flex;
      gap: 4px;
      .right-box-row1-col1 {
        width: 36.17%;
      }
      .right-box-row1-col2 {
        width: 63.83%;
      }
    }
    .right-box-row2 {
      height: 25%;
      display: flex;
      gap: 4px;
      .right-box-row2-item {
        width: 50%;
      }
    }
    .right-box-row3 {
      height: 47.78%;
    }
    .right-box-row4 {
      height: 12.78%;
      background: #ffffff;
      border-radius: 2px;
      display: flex;
      align-items: center;
      justify-content: flex-end;
      padding-right: 13px;
      .btn {
        margin-left: 9px;
      }
    }
  }
  .progress-box {
    display: flex;
    align-items: center;
    flex-direction: column;
    .item-num {
      margin-bottom: 4px;
      font-family: PingFangSC, PingFang SC;
      font-weight: 600;
      font-size: 8px;
      color: #333333;
      text-align: left;
      font-style: normal;
    }
  }
  .item-box {
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: PingFangSC, PingFang SC;
    font-weight: 600;
    font-size: 8px;
    color: #70a3dd;
    text-align: center;
    font-style: normal;
    &.dialysis-mode-content {
      color: #d58e56;
      display: flex;
      align-items: center;
      // align-items: baseline;
      .dialysis-mode-content-box {
        display: flex;
        align-items: flex-end;
        line-height: 1;
        .mini-text {
          margin-right: 1px;
          font-size: 5px;
          color: #c9a589;
        }
      }
    }
    &.treatment-status {
      color: #70a3dd;
    }
    &.prescription-ehydration-olume {
      color: #8079cb;
    }
    &.current-lood0emperature {
      color: #70a3dd;
      font-size: 9px;
    }
    &.venous-pressure {
      color: #70a3dd;
      font-size: 9px;
    }
  }
  .prescription-remarks {
    font-family: PingFangSC, PingFang SC;
    font-weight: 500;
    font-size: 5px;
    color: #d58e56;
    line-height: 7px;
    text-align: left;
    font-style: normal;
  }
  .dehydrated-level {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
    .dehydrated-level-item {
      width: 100%;
      display: flex;
      align-items: center;
      .item-left {
        flex: 1;
        font-family: PingFangSC, PingFang SC;
        font-weight: 600;
        font-size: 4px;
        color: #333333;
        line-height: 6px;
        font-style: normal;
        .level-dete {
          font-family: PingFangSC, PingFang SC;
          font-weight: 600;
          font-size: 4px;
          color: #d58e56;
          text-align: left;
          font-style: normal;
        }
      }
      .item-right {
        font-family: PingFangSC, PingFang SC;
        font-weight: 600;
        font-size: 4px;
        color: #777777;
        line-height: 6px;
        font-style: normal;
      }
    }
  }
  // card header class
  .mini-card {
    padding: 2px;
  }
  .ktv-card {
    .card-header {
      margin-bottom: 0px;
    }
  }
  :deep(.mihi-header) {
    flex: 0 0 4px;
    .card-icon {
      width: 4px;
      height: 4px;
    }
    .card-title {
      font-size: 4px;
    }
  }
  :deep(.big-header) {
    flex: 0 0 9px;
    .card-icon {
      width: 9px;
      height: 9px;
    }
    .card-title {
      font-size: 5px;
    }
  }
}
</style>