yxh
yxh
7 天以前 09dc74e264b6262cbe41c9c8476e24705871d4a6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<!--
  设备信息展示块(需求:设备领用 / 装机 / 拆机 页面的额外内容)
 
  统一展示以下设备相关字段(**一行四列**,与 PatientInfoBlock 的栅格一致):
    设备编号、设备描述、领用时间、装机时间、拆机时间、干扰数、脱落、基线粗、备注
 
  设计要点:
    1) **时间标签按页面自适应**:同一列 `rent_time` 在"设备领用"页是「领用时间」、
       在"装机/拆机"页是「装机时间」;`return_time` 在拆机页是「拆机时间」。
       由 `timeLabelMode` 决定,避免各页面各写一套标签而口径不一。
    2) **设备描述取值兼容两种来源**:
        · `device` —— 通过 DeviceApi 查到的设备对象(含 category/brand/model/state)
        · 数据对象上的 `brand/model/devState` —— DevRentRespVO 已带上(拆机页用这个)
    3) 设备编号/时间/质量字段**可能需要录入**,故提供具名插槽:
        `devId` / `rentTime` / `returnTime` / `entryTime` / `interference` / `detachment` / `baseline` / `remark`
       父页面不传插槽时按**只读文本**渲染。
-->
<script setup lang="ts">
import { computed } from 'vue'
import { formatDateTime } from '@/utils/patientInfo'
import { tranlateDevState } from '@/utils/statusFormatter'
 
const props = defineProps<{
  /** 数据对象(DevRentVO / 表单 formData),字段名与后端 DevRentRespVO 一致 */
  data: any
  /** 通过设备接口查到的设备对象(可选;提供时优先用于「设备描述」) */
  device?: any
  /**
   * 时间字段的标签模式:
   *   'ready'    —— 设备领用页(rentTime=领用时间)
   *   'install'  —— 装机页(rentTime=装机时间)
   *   'dismantle'—— 拆机页(rentTime=装机时间、returnTime=拆机时间)
   */
  timeLabelMode?: 'ready' | 'install' | 'dismantle'
  /** 每列栅格宽度(默认 6 = 一行四列) */
  span?: number
}>()
 
const d = computed(() => props.data || {})
const colSpan = computed(() => props.span ?? 6)
const mode = computed(() => props.timeLabelMode ?? 'install')
 
/** 领用时间的标签 */
const rentTimeLabel = computed(() => (mode.value === 'ready' ? '领用时间' : '装机时间'))
/** 归还时间的标签(拆机页才有意义) */
const returnTimeLabel = computed(() => (mode.value === 'dismantle' ? '拆机时间' : '拆机时间'))
 
/** 设备描述:优先用设备接口对象,其次用数据对象自带的 brand/model/devState */
const deviceDesc = computed(() => {
  const src = props.device ?? d.value
  const parts = [src?.brand, src?.model].filter((v: any) => v !== undefined && v !== null && v !== '')
  const stateText = tranlateDevState(src?.state ?? d.value?.devState)
  const text = parts.join(' ')
  if (!text && !stateText) return '-'
  return `${text}${text && stateText ? ' ' : ''}${stateText ?? ''}`.trim() || '-'
})
 
/** 取第一个有值的候选,空则返回 '-' */
function pick(...vals: any[]): any {
  for (const v of vals) {
    if (v !== undefined && v !== null && v !== '') return v
  }
  return '-'
}
 
const devId = computed(() => pick(d.value.devId))
const interference = computed(() => pick(d.value.interference))
const detachment = computed(() => pick(d.value.detachment))
const baseline = computed(() => pick(d.value.baseline))
const remark = computed(() => pick(d.value.remark))
const rentTime = computed(() => formatDateTime(d.value.rentTime) || '-')
const returnTime = computed(() => formatDateTime(d.value.returnTime) || '-')
const entryTime = computed(() => formatDateTime(d.value.entryTime) || '-')
 
/** 布尔类字段(脱落/基线粗)显示为 是/否;其它值原样显示 */
function yesNo(v: any): string {
  if (v === '-' || v === undefined || v === null || v === '') return '-'
  const s = String(v).trim()
  if (s === '1' || s === 'true') return '是'
  if (s === '0' || s === 'false') return '否'
  return s
}
</script>
 
<template>
  <el-row :gutter="20">
    <!-- 设备编号(可编辑时由父页面通过插槽覆盖) -->
    <el-col :span="colSpan">
      <el-form-item label="设备编号">
        <slot name="devId">{{ devId }}</slot>
      </el-form-item>
    </el-col>
 
    <el-col :span="colSpan">
      <el-form-item label="设备描述">
        {{ deviceDesc }}
      </el-form-item>
    </el-col>
 
    <el-col :span="colSpan">
      <el-form-item :label="rentTimeLabel">
        <slot name="rentTime">{{ rentTime }}</slot>
      </el-form-item>
    </el-col>
 
    <el-col :span="colSpan">
      <el-form-item label="登记时间">
        <slot name="entryTime">{{ entryTime }}</slot>
      </el-form-item>
    </el-col>
 
    <el-col :span="colSpan">
      <el-form-item :label="returnTimeLabel">
        <slot name="returnTime">{{ returnTime }}</slot>
      </el-form-item>
    </el-col>
 
    <el-col :span="colSpan">
      <el-form-item label="干扰数">
        <slot name="interference">{{ interference }}</slot>
      </el-form-item>
    </el-col>
 
    <el-col :span="colSpan">
      <el-form-item label="脱落">
        <slot name="detachment">{{ yesNo(detachment) }}</slot>
      </el-form-item>
    </el-col>
 
    <el-col :span="colSpan">
      <el-form-item label="基线粗">
        <slot name="baseline">{{ yesNo(baseline) }}</slot>
      </el-form-item>
    </el-col>
 
    <el-col :span="24">
      <el-form-item label="备注">
        <slot name="remark">{{ remark }}</slot>
      </el-form-item>
    </el-col>
  </el-row>
</template>
 
<style scoped lang="scss">
/* 与 PatientInfoBlock 保持一致:压缩行间距,避免表单挤占下方 el-table
   (Element Plus 默认 el-form-item margin-bottom 为 18px) */
.el-form-item,
:deep(.el-form-item) {
  margin-bottom: 4px;
}
</style>