yxh
2026-10-03 d553a4be94d4f6ee162cc353a28b220403909cfc
src/components/RoomStatus/src/RoomStatus.vue
@@ -1,17 +1,22 @@
<script lang="ts" setup>
import { RoomApi, RoomVO } from '@/api/ecg/room'
import { QueueApi } from '@/api/ecg/queue'
import {PropType} from "vue";
import {DICT_TYPE, getIntDictOptions} from "@/utils/dict";
import {useCheckTypeStore} from "@/store/modules/checkType";
import {getCheckTypeName} from "../../../utils/checkTypeFormatter";
import { PropType } from "vue";
import { DICT_TYPE, getIntDictOptions } from "@/utils/dict";
import { useCheckTypeStore } from "@/store/modules/checkType";
import { getCheckTypeName } from "../../../utils/checkTypeFormatter";
// 动态 :src 不会被 Vite 自动处理,需要显式 import(与 RoomBedSelect 一致)
import closeImg from '@/assets/room/close.jpg'
import openImg from '@/assets/room/open.jpg'
import doctorImg from '@/assets/room/desk-doctor.jpg'
const emit = defineEmits(['refresh'])
defineComponent({
  name: 'RoomStatus'
})
const  props = defineProps({
const props = defineProps({
  title: {
    type: String,
    required: true
@@ -34,6 +39,19 @@
    emit('refresh')
}
/**
 * 工位状态图。与「诊室选择」页 (RoomBedSelect) 用同一套资源与尺寸:
 *   未开放(0)   → close.jpg
 *   已开放(10)  → open.jpg
 *   有医生(20/30) → desk-doctor.jpg
 */
const bedImg = (item: any) => {
  const st = Number(item?.status)
  if (st === 20 || st === 30) return doctorImg
  if (st === 10) return openImg
  return closeImg
}
/** 初始化 **/
onMounted(() => {
})
@@ -41,66 +59,123 @@
</script>
<template>
  <el-card style="width: 200px" shadow="hover" >
    <template #header>{{title}}</template>
    <div v-for="(bedItem, index) in bedList" :key="index">
      <div class="deskwarp">
        <img
            v-if="bedItem.status === 0"
            src="@/assets/room/close.jpg"
            style="width: 100%"
             @click = openBed(bedItem)
            alt="工位已关闭"
        />
        <img
            v-else-if="bedItem.status === 10"
            src="@/assets/room/open.jpg"
            style="width: 100%"
             @click = closeBed(bedItem)
            alt="工位开放中"
        />
        <img v-else-if="bedItem.status === 20 || bedItem.status === 30"
            src="@/assets/room/doctor.png"
            style="width: 100%"
        />
        {{bedItem.bedNo}} {{bedItem.docName}} {{bedItem.status === 30?"-暂停":""}}
        <div v-for="(checkType, subIndex) in bedItem.checkTypes" :key="subIndex">
          {{getCheckTypeName(checkType)}}
        </div>
        <div>
          {{bedItem.opType === 1?"领用":""}}
          {{bedItem.opType === 2?"安装":""}}
        </div>
        <el-divider/>
  <!--
    需求:本页卡片改成与「诊室选择」页一致的样式。
    因此这里的排版/字号/图片尺寸/间距**逐项对齐** components/RoomBedSelect/src/RoomBedSelect.vue:
      · 卡片头:居中、padding 6px 10px、标题 16px/600
      · 卡片体:纵向排列、水平居中、gap 4px、padding 10px
      · 图片:80×64、object-fit contain
      · 主标签(床位号+医生名):15px/600、居中
      · 检查项目等次要信息:14px、次要色、居中、可换行
    区别:诊室选择是"一个工位一张卡片",本页是"一个诊室一张卡片、卡内列出该诊室各工位",
    故卡内每个工位是一个 bed-block;视觉规格与前者保持一致。
  -->
  <el-card class="room-status-card" shadow="hover">
    <template #header>
      <div class="bed-card__title">{{ title }}</div>
    </template>
    <div
      v-for="(bedItem, index) in bedList"
      :key="index"
      class="bed-block"
    >
      <img
        class="bed-card__img"
        :src="bedImg(bedItem)"
        :alt="bedItem.status === 0 ? '工位已关闭' : (bedItem.status === 10 ? '工位开放中' : '有医生')"
        @click="bedItem.status === 0 ? openBed(bedItem) : (bedItem.status === 10 ? closeBed(bedItem) : undefined)"
      />
      <div class="bed-card__label">
        {{ bedItem.bedNo }} {{ bedItem.docName }} {{ bedItem.status === 30 ? "-暂停" : "" }}
      </div>
      <div class="bed-card__meta">
        <span v-for="(checkType, subIndex) in bedItem.checkTypes" :key="subIndex">
          {{ getCheckTypeName(checkType) }}
        </span>
        <span v-if="bedItem.opType === 1">领用</span>
        <span v-if="bedItem.opType === 2">安装</span>
      </div>
    </div>
  </el-card>
</template>
<style scoped lang="scss">
.card-title {
  font-size: 14px;
  font-weight: 600;
/* 卡片本体:与 RoomBedSelect 的 .bed-card 对齐(只是宽度按本页需要略窄) */
.room-status-card {
  display: flex;
  flex-direction: column;
  width: 168px;
  margin: 0 6px 6px 0;
  overflow: hidden;
  &::before {
    position: relative;
    top: 8px;
    left: -5px;
    display: inline-block;
    width: 3px;
    height: 14px;
    //background-color: #105cfb;
    background: var(--el-color-primary);
    border-radius: 5px;
    content: '';
    transform: translateY(-50%);
  // 卡片头(诊室名)
  :deep(.el-card__header) {
    flex: none;
    padding: 6px 10px;
    text-align: center;
  }
  // 卡片体:纵向排列、水平居中
  // 注意:这里**不用** flex:1 —— RoomBedSelect 是在等高网格里才需要它撑满;
  // 本页卡片高度由工位数决定,若撑满会把内容顶到上方、留下大片空白。
  :deep(.el-card__body) {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: 10px;
  }
}
.deskwarp {
/* 卡内单个工位:与 RoomBedSelect 卡片体的排布一致 */
.bed-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  width: 100%;
  padding-bottom: 6px;
  border-bottom: 1px dashed var(--el-border-color-lighter);
  &:last-child {
    padding-bottom: 0;
    border-bottom: none;
  }
}
.bed-card__title {
  font-size: 16px;
  font-weight: 600;
  line-height: 1.2;
}
/* 图片固定小尺寸,不随卡片宽度放大(与 RoomBedSelect 相同) */
.bed-card__img {
  flex: none;
  width: 80px;
  height: 64px;
  object-fit: contain;
  cursor: pointer;
}
.bed-card__label {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.3;
  text-align: center;
}
.bed-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0 5px;
  justify-content: center;
  font-size: 14px;
  line-height: 1.3;
  color: var(--el-text-color-secondary);
  text-align: center;
}
</style>