vue2-client 1.18.45 → 1.18.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/base-client/components/common/ImagePreviewModal/ImagePreviewModal.vue +227 -136
- package/src/base-client/components/common/ImagePreviewModal/demo.vue +154 -0
- package/src/base-client/components/his/XList/XList.vue +228 -149
- package/src/base-client/components/his/XQuestionnaire/XQuestionnaireItem.vue +1 -1
- package/src/base-client/components/his/XTreeRows/XTreeRows.vue +34 -40
- package/src/pages/userInfoDetailManage/uploadFilesHistory/index.vue +19 -12
- package/src/router/async/router.map.js +2 -1
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<!-- 列表卡片模式 listMode: card -->
|
|
3
|
-
<div
|
|
4
|
-
|
|
5
|
-
:class="wrapperClassObject"
|
|
6
|
-
v-if="listMode"
|
|
7
|
-
ref="listRef"
|
|
8
|
-
@scroll="handleInfiniteOnLoad">
|
|
9
|
-
<a-list
|
|
10
|
-
:grid="{ gutter: 16, xs: 1, sm: 2, md: 2, lg: 3, xl: 3, xxl: 4 }"
|
|
11
|
-
:data-source="localData">
|
|
3
|
+
<div class="x-list-wrapper" :class="wrapperClassObject" v-if="listMode" ref="listRef" @scroll="handleInfiniteOnLoad">
|
|
4
|
+
<a-list :grid="{ gutter: 16, xs: 1, sm: 2, md: 2, lg: 3, xl: 3, xxl: 4 }" :data-source="localData">
|
|
12
5
|
<a-list-item slot="renderItem" slot-scope="item, index">
|
|
13
|
-
<div
|
|
6
|
+
<div
|
|
7
|
+
class="card-a-col"
|
|
8
|
+
:class="{ 'selected-active': enableSelectRow && currentSelectedIndex === index }"
|
|
9
|
+
:style="getCardStyle(currentTitleValue(index))"
|
|
10
|
+
@click="handleCardClick(index)"
|
|
11
|
+
>
|
|
14
12
|
<a-row class="card-row">
|
|
15
|
-
<a-col class="id-a-col" :span="4" v-for="(detail,idx) in item.filter(d => d.label == label)" :key="idx">
|
|
13
|
+
<a-col class="id-a-col" :span="4" v-for="(detail, idx) in item.filter(d => d.label == label)" :key="idx">
|
|
16
14
|
{{ detail.value }}
|
|
17
15
|
<div class="gender-icon" v-if="getHasPatient(item) && getGender(item)">
|
|
18
|
-
<img
|
|
16
|
+
<img
|
|
17
|
+
:src="getGender(item) === '男' ? maleIcon : femaleIcon"
|
|
18
|
+
:alt="getGender(item)"
|
|
19
|
+
class="gender-img"
|
|
20
|
+
/>
|
|
19
21
|
</div>
|
|
20
22
|
</a-col>
|
|
21
23
|
<a-col :span="20" class="id-a-col-2">
|
|
22
|
-
<template v-for="(detail,idx) in item">
|
|
24
|
+
<template v-for="(detail, idx) in item">
|
|
23
25
|
<div :key="`title_${idx}`" class="title-row" v-if="detail.type == 'title'">
|
|
24
26
|
<a-tooltip :title="detail.value" placement="topLeft">
|
|
25
|
-
<span class="describe-list-a-col" :class="{name: detail.bold}">{{ detail.value }}</span>
|
|
27
|
+
<span class="describe-list-a-col" :class="{ name: detail.bold }">{{ detail.value }}</span>
|
|
26
28
|
</a-tooltip>
|
|
27
29
|
<div class="title-actions" v-if="getTitleOptions && getTitleOptions.length">
|
|
28
30
|
<span class="title-select-label">{{ getDisplayTitleLabel(index) }}</span>
|
|
@@ -30,36 +32,54 @@
|
|
|
30
32
|
<a class="arrow-btn" @click.prevent>
|
|
31
33
|
<a-icon type="down" />
|
|
32
34
|
</a>
|
|
33
|
-
<a-menu
|
|
34
|
-
|
|
35
|
+
<a-menu
|
|
36
|
+
slot="overlay"
|
|
37
|
+
:selectedKeys="[String(currentTitleValue(index))]"
|
|
38
|
+
@click="info => handleTitleMenuClick(info, index)"
|
|
39
|
+
>
|
|
40
|
+
<a-menu-item
|
|
41
|
+
v-for="opt in getTitleOptions"
|
|
42
|
+
:key="String(opt && opt.value !== undefined ? opt.value : opt)"
|
|
43
|
+
>
|
|
35
44
|
{{ opt && opt.label !== undefined ? opt.label : opt }}
|
|
36
45
|
</a-menu-item>
|
|
37
46
|
</a-menu>
|
|
38
47
|
</a-dropdown>
|
|
39
48
|
</div>
|
|
40
49
|
</div>
|
|
41
|
-
<span
|
|
50
|
+
<span
|
|
51
|
+
:key="idx"
|
|
52
|
+
class="component-a-col"
|
|
53
|
+
v-else-if="getHasPatient(item) && detail.type == 'component' && detail.label != label"
|
|
54
|
+
>
|
|
42
55
|
<a-tooltip :title="detail.label" placement="topLeft">
|
|
43
56
|
<span class="label-text">{{ `${detail.label}:` }}</span>
|
|
44
57
|
</a-tooltip>
|
|
45
58
|
<component
|
|
46
59
|
:is="detail.slotType"
|
|
47
60
|
:key="idx"
|
|
48
|
-
:ref="`dynamicComponent_${
|
|
61
|
+
:ref="`dynamicComponent_${idx.slotType || idx}_${idx}`"
|
|
49
62
|
:serviceName="serviceName"
|
|
50
63
|
v-on="forwardAllEvents"
|
|
51
64
|
:queryParamsName="detail.value"
|
|
52
65
|
:countVisible="false"
|
|
53
66
|
/>
|
|
54
67
|
</span>
|
|
55
|
-
<span :key="idx" class="component-a-col" v-else-if="getHasPatient(item) && detail.type == 'date'">
|
|
68
|
+
<span :key="`${idx}-date`" class="component-a-col" v-else-if="getHasPatient(item) && detail.type == 'date'">
|
|
56
69
|
<a-tooltip :title="detail.label" placement="topLeft">
|
|
57
70
|
<span class="label-text">{{ `${detail.label}:` }}</span>
|
|
58
71
|
</a-tooltip>
|
|
59
72
|
<a-date-picker @change="onChange" />
|
|
60
73
|
</span>
|
|
61
|
-
<a-tooltip
|
|
62
|
-
|
|
74
|
+
<a-tooltip
|
|
75
|
+
:key="`${idx}-tooltip`"
|
|
76
|
+
:title="`${detail.label}:${detail.value}`"
|
|
77
|
+
placement="topLeft"
|
|
78
|
+
v-else-if="getHasPatient(item) && detail.label != label"
|
|
79
|
+
>
|
|
80
|
+
<span class="describe-list-a-col" :class="{ name: detail.bold }">
|
|
81
|
+
{{ `${detail.label}:${detail.value}` }}
|
|
82
|
+
</span>
|
|
63
83
|
</a-tooltip>
|
|
64
84
|
</template>
|
|
65
85
|
<a-button
|
|
@@ -68,7 +88,8 @@
|
|
|
68
88
|
:key="i"
|
|
69
89
|
icon="search"
|
|
70
90
|
class="button-a-col"
|
|
71
|
-
@click.stop="click(item, index)"
|
|
91
|
+
@click.stop="click(item, index)"
|
|
92
|
+
>
|
|
72
93
|
{{ btn }}
|
|
73
94
|
</a-button>
|
|
74
95
|
</a-col>
|
|
@@ -79,9 +100,7 @@
|
|
|
79
100
|
<a-spin />
|
|
80
101
|
</div>
|
|
81
102
|
<div v-if="allLoaded">
|
|
82
|
-
<div class="demo-infinite-list-bottom">
|
|
83
|
-
已经显示全部数据
|
|
84
|
-
</div>
|
|
103
|
+
<div class="demo-infinite-list-bottom">已经显示全部数据</div>
|
|
85
104
|
</div>
|
|
86
105
|
</a-list>
|
|
87
106
|
</div>
|
|
@@ -96,16 +115,17 @@
|
|
|
96
115
|
@click="handleClick(index)"
|
|
97
116
|
@mouseenter="enableHoverOptions && handleMouseEnter(index)"
|
|
98
117
|
@mouseleave="handleMouseLeave"
|
|
99
|
-
:class="{
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
118
|
+
:class="{
|
|
119
|
+
'hover-active': enableHoverOptions && hoveredIndex === index,
|
|
120
|
+
'selected-active': enableSelectRow && currentSelectedIndex === index
|
|
121
|
+
}"
|
|
122
|
+
>
|
|
123
|
+
<i v-if="icon" class="icon-menu" :style="getIconStyle(item)"></i>
|
|
105
124
|
<span
|
|
106
125
|
class="item-text"
|
|
107
126
|
:class="{ 'text-truncated': enableHoverOptions && hoveredIndex === index }"
|
|
108
|
-
:style="getTextStyle(index)"
|
|
127
|
+
:style="getTextStyle(index)"
|
|
128
|
+
>
|
|
109
129
|
{{ item.number }} {{ item.name }}
|
|
110
130
|
</span>
|
|
111
131
|
|
|
@@ -115,7 +135,8 @@
|
|
|
115
135
|
:key="idx"
|
|
116
136
|
type="link"
|
|
117
137
|
:class="['confirm-btn', buttonMode ? 'hover-btn' : '']"
|
|
118
|
-
@click.stop="click(index, idx)"
|
|
138
|
+
@click.stop="click(index, idx)"
|
|
139
|
+
>
|
|
119
140
|
<span :class="{ 'hover-active': enableHoverOptions && hoveredIndex === index }">{{ name }}</span>
|
|
120
141
|
</a-button>
|
|
121
142
|
</div>
|
|
@@ -125,13 +146,15 @@
|
|
|
125
146
|
v-show="enableHoverOptions && hoveredIndex === index"
|
|
126
147
|
class="hover-options"
|
|
127
148
|
@mouseenter="handleOptionsEnter"
|
|
128
|
-
@mouseleave="handleOptionsLeave"
|
|
149
|
+
@mouseleave="handleOptionsLeave"
|
|
150
|
+
>
|
|
129
151
|
<div class="hover-options-content">
|
|
130
152
|
<div
|
|
131
153
|
v-for="(Item, idx) in select_options"
|
|
132
154
|
:key="idx"
|
|
133
155
|
class="option-item"
|
|
134
|
-
@click="handleOptionClick(index, Item)"
|
|
156
|
+
@click="handleOptionClick(index, Item)"
|
|
157
|
+
>
|
|
135
158
|
{{ Item }}
|
|
136
159
|
</div>
|
|
137
160
|
</div>
|
|
@@ -142,7 +165,6 @@
|
|
|
142
165
|
</template>
|
|
143
166
|
|
|
144
167
|
<script>
|
|
145
|
-
|
|
146
168
|
import { getConfigByName, runLogic } from '@vue2-client/services/api/common'
|
|
147
169
|
|
|
148
170
|
export default {
|
|
@@ -164,7 +186,9 @@ export default {
|
|
|
164
186
|
},
|
|
165
187
|
fixedQueryForm: {
|
|
166
188
|
type: Object,
|
|
167
|
-
default:
|
|
189
|
+
default: () => {
|
|
190
|
+
return { condition: '1=1' }
|
|
191
|
+
}
|
|
168
192
|
},
|
|
169
193
|
enableHoverOptions: {
|
|
170
194
|
type: Boolean,
|
|
@@ -197,9 +221,9 @@ export default {
|
|
|
197
221
|
titleSelectValue: {
|
|
198
222
|
type: [String, Number],
|
|
199
223
|
default: undefined
|
|
200
|
-
}
|
|
224
|
+
}
|
|
201
225
|
},
|
|
202
|
-
data
|
|
226
|
+
data() {
|
|
203
227
|
return {
|
|
204
228
|
data: [], // 数据源
|
|
205
229
|
localData: [], // 本地数据源
|
|
@@ -234,19 +258,17 @@ export default {
|
|
|
234
258
|
},
|
|
235
259
|
inject: ['getComponentByName'],
|
|
236
260
|
|
|
237
|
-
created
|
|
261
|
+
created() {
|
|
238
262
|
this.getData(this.queryParamsName, this.fixedQueryForm)
|
|
239
263
|
},
|
|
240
|
-
mounted
|
|
264
|
+
mounted() {},
|
|
241
265
|
computed: {
|
|
242
266
|
// 参考 HForm 的 wrapperClassObject 规则,支持通过组件属性动态控制样式
|
|
243
|
-
wrapperClassObject
|
|
267
|
+
wrapperClassObject() {
|
|
244
268
|
const a = this.$attrs || {}
|
|
245
269
|
const classes = {}
|
|
246
270
|
// 多个布尔型样式开关(存在且为真则生效)
|
|
247
|
-
const booleanStyleKeys = [
|
|
248
|
-
'enableNewListStyle'
|
|
249
|
-
]
|
|
271
|
+
const booleanStyleKeys = ['enableNewListStyle']
|
|
250
272
|
booleanStyleKeys.forEach(key => {
|
|
251
273
|
const val = a[key]
|
|
252
274
|
const truthy = val === true || val === '' || val === 'true'
|
|
@@ -255,12 +277,12 @@ export default {
|
|
|
255
277
|
return classes
|
|
256
278
|
},
|
|
257
279
|
// 标题下拉:优先使用外部 props,否则使用内部配置
|
|
258
|
-
getTitleOptions
|
|
280
|
+
getTitleOptions() {
|
|
259
281
|
if (Array.isArray(this.titleSelectOptions) && this.titleSelectOptions.length) return this.titleSelectOptions
|
|
260
282
|
return this.internalTitleOptions
|
|
261
283
|
},
|
|
262
|
-
currentTitleValue
|
|
263
|
-
return
|
|
284
|
+
currentTitleValue() {
|
|
285
|
+
return index => {
|
|
264
286
|
if (this.titleSelectValue !== undefined) return this.titleSelectValue
|
|
265
287
|
const local = this.titleValueByIndex[index]
|
|
266
288
|
if (local !== undefined) return local
|
|
@@ -271,20 +293,25 @@ export default {
|
|
|
271
293
|
if (title && title.titleRightValue !== undefined) return title.titleRightValue
|
|
272
294
|
}
|
|
273
295
|
// 最终回退:使用 options 的第一个
|
|
274
|
-
const def =
|
|
296
|
+
const def =
|
|
297
|
+
this.internalTitleOptions && this.internalTitleOptions.length
|
|
298
|
+
? this.internalTitleOptions[0].value !== undefined
|
|
299
|
+
? this.internalTitleOptions[0].value
|
|
300
|
+
: this.internalTitleOptions[0]
|
|
301
|
+
: undefined
|
|
275
302
|
return def
|
|
276
303
|
}
|
|
277
304
|
},
|
|
278
305
|
// 选择控制:受控优先
|
|
279
|
-
currentSelectedIndex
|
|
306
|
+
currentSelectedIndex() {
|
|
280
307
|
return typeof this.selectedIndex === 'number' ? this.selectedIndex : this.localSelectedIndex
|
|
281
308
|
},
|
|
282
|
-
enableSelectRow
|
|
309
|
+
enableSelectRow() {
|
|
283
310
|
const a = this.$attrs || {}
|
|
284
311
|
const val = a.enableSelection
|
|
285
312
|
return val === true || val === '' || val === 'true'
|
|
286
313
|
},
|
|
287
|
-
forwardAllEvents
|
|
314
|
+
forwardAllEvents() {
|
|
288
315
|
return {
|
|
289
316
|
// 监听所有事件并转发给父组件
|
|
290
317
|
'*': (eventName, ...payload) => {
|
|
@@ -294,10 +321,10 @@ export default {
|
|
|
294
321
|
}
|
|
295
322
|
},
|
|
296
323
|
methods: {
|
|
297
|
-
onChange
|
|
324
|
+
onChange(date, dateString) {
|
|
298
325
|
this.$emit('dateChange', date, dateString)
|
|
299
326
|
},
|
|
300
|
-
handleInfiniteOnLoad
|
|
327
|
+
handleInfiniteOnLoad(event) {
|
|
301
328
|
if (this.busy || this.allLoaded) return // 防止重复加载
|
|
302
329
|
if (this.scrollTimer) clearTimeout(this.scrollTimer)
|
|
303
330
|
this.scrollTimer = setTimeout(() => {
|
|
@@ -311,31 +338,34 @@ export default {
|
|
|
311
338
|
this.loading = true
|
|
312
339
|
this.nowPage = this.nowPage + this.pageSize
|
|
313
340
|
this.fixedQueryForm.condition = `Limit ${this.nowPage}, ${this.pageSize}`
|
|
314
|
-
runLogic(this.logicName, this.fixedQueryForm, 'af-his')
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
this.
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
341
|
+
runLogic(this.logicName, this.fixedQueryForm, 'af-his')
|
|
342
|
+
.then(async res => {
|
|
343
|
+
this.localData = [...this.localData, ...res]
|
|
344
|
+
if (res.length < this.pageSize) {
|
|
345
|
+
this.allLoaded = true
|
|
346
|
+
}
|
|
347
|
+
})
|
|
348
|
+
.catch(e => {
|
|
349
|
+
this.$message.error(e.message)
|
|
350
|
+
})
|
|
351
|
+
.finally(() => {
|
|
352
|
+
this.loading = false
|
|
353
|
+
this.busy = false
|
|
354
|
+
})
|
|
325
355
|
}
|
|
326
356
|
}, 100)
|
|
327
357
|
},
|
|
328
|
-
async getData
|
|
358
|
+
async getData(config, param) {
|
|
329
359
|
const that = this
|
|
330
|
-
getConfigByName(config, 'af-his', async
|
|
331
|
-
that.listMode = await res.listMode == 'card'
|
|
360
|
+
getConfigByName(config, 'af-his', async res => {
|
|
361
|
+
that.listMode = (await res.listMode) == 'card'
|
|
332
362
|
that.logicName = await res.data
|
|
333
363
|
that.button = await res.button // 按钮
|
|
334
364
|
that.icon = await res.icon // 图标
|
|
335
365
|
that.label = await res.label // 标签
|
|
336
|
-
that.buttonNames = await res.buttonNames || []// 按钮文本
|
|
337
|
-
that.buttonMode = await res.buttonMode || false// 按钮模式
|
|
338
|
-
that.cardButtonsVisible = await res.cardButtonsVisible || false// 卡片按钮
|
|
366
|
+
that.buttonNames = (await res.buttonNames) || [] // 按钮文本
|
|
367
|
+
that.buttonMode = (await res.buttonMode) || false // 按钮模式
|
|
368
|
+
that.cardButtonsVisible = (await res.cardButtonsVisible) || false // 卡片按钮
|
|
339
369
|
// 标题下拉:从配置拿 options: [{label,value,color}]
|
|
340
370
|
if (Array.isArray(res.titleOptions)) {
|
|
341
371
|
this.internalTitleOptions = res.titleOptions
|
|
@@ -344,14 +374,18 @@ export default {
|
|
|
344
374
|
this.titleValueByIndex = {}
|
|
345
375
|
}
|
|
346
376
|
}
|
|
347
|
-
this.enableHoverOptions = await res.enableHoverOptions || false// 悬浮选项框
|
|
377
|
+
this.enableHoverOptions = (await res.enableHoverOptions) || false // 悬浮选项框
|
|
348
378
|
if (this.enableHoverOptions) {
|
|
349
379
|
this.select_options = await res.select_options
|
|
350
380
|
}
|
|
351
|
-
if (that.listMode) {
|
|
381
|
+
if (that.listMode) {
|
|
382
|
+
param.condition = `Limit ${that.nowPage}, ${that.pageSize}`
|
|
383
|
+
}
|
|
352
384
|
runLogic(res.data, param, 'af-his').then(result => {
|
|
353
385
|
that.data = result
|
|
354
|
-
if (that.nowPage === 0) {
|
|
386
|
+
if (that.nowPage === 0) {
|
|
387
|
+
this.localData = result
|
|
388
|
+
}
|
|
355
389
|
// 初始化每张卡片的 title 选中值:优先读取模板 titleRightValue,否则使用配置默认或第一项
|
|
356
390
|
if (Array.isArray(this.localData)) {
|
|
357
391
|
this.localData.forEach((row, idx) => {
|
|
@@ -364,9 +398,12 @@ export default {
|
|
|
364
398
|
}
|
|
365
399
|
}
|
|
366
400
|
// fallback:配置默认或第一项
|
|
367
|
-
const def =
|
|
368
|
-
|
|
369
|
-
|
|
401
|
+
const def =
|
|
402
|
+
this.internalTitleOptions && this.internalTitleOptions.length
|
|
403
|
+
? this.internalTitleOptions[0].value !== undefined
|
|
404
|
+
? this.internalTitleOptions[0].value
|
|
405
|
+
: this.internalTitleOptions[0]
|
|
406
|
+
: undefined
|
|
370
407
|
if (def !== undefined) this.$set(this.titleValueByIndex, idx, def)
|
|
371
408
|
})
|
|
372
409
|
}
|
|
@@ -374,7 +411,7 @@ export default {
|
|
|
374
411
|
})
|
|
375
412
|
},
|
|
376
413
|
// 提取性别:从数组数据中查找 label 含“性别”的项
|
|
377
|
-
getGender
|
|
414
|
+
getGender(item) {
|
|
378
415
|
if (!Array.isArray(item)) return null
|
|
379
416
|
const g = item.find(d => d && typeof d.label === 'string' && d.label.indexOf('性别') > -1)
|
|
380
417
|
const val = g && (g.value || g.text)
|
|
@@ -384,14 +421,14 @@ export default {
|
|
|
384
421
|
return null
|
|
385
422
|
},
|
|
386
423
|
// 读取标题项上的 hasPatient 布尔值
|
|
387
|
-
getHasPatient
|
|
424
|
+
getHasPatient(item) {
|
|
388
425
|
if (!Array.isArray(item)) return true
|
|
389
426
|
const title = item.find(d => d && d.type === 'title')
|
|
390
427
|
if (!title || typeof title.hasPatient === 'undefined') return true
|
|
391
428
|
return !!title.hasPatient
|
|
392
429
|
},
|
|
393
430
|
// 标题右侧下拉选择
|
|
394
|
-
handleTitleSelectChange
|
|
431
|
+
handleTitleSelectChange(val, index) {
|
|
395
432
|
// 重复值拦截:若值未变化则直接返回
|
|
396
433
|
const prev = this.normalizeValue(this.currentTitleValue(index))
|
|
397
434
|
const next = this.normalizeValue(val)
|
|
@@ -408,31 +445,37 @@ export default {
|
|
|
408
445
|
}, 200)
|
|
409
446
|
},
|
|
410
447
|
// 读取标题项中额外需要传递的参数(可选),例如 { inpatientNo: row.t_id }
|
|
411
|
-
getTitleExtraParams
|
|
448
|
+
getTitleExtraParams(index) {
|
|
412
449
|
const row = Array.isArray(this.localData) ? this.localData[index] : null
|
|
413
450
|
if (!Array.isArray(row)) return {}
|
|
414
451
|
const title = row.find(d => d && d.type === 'title') || {}
|
|
415
452
|
if (title && title.extraParams && typeof title.extraParams === 'object') return title.extraParams
|
|
416
453
|
return {}
|
|
417
454
|
},
|
|
418
|
-
handleTitleMenuClick
|
|
455
|
+
handleTitleMenuClick({ key }, index) {
|
|
419
456
|
const v = isNaN(Number(key)) ? key : Number(key)
|
|
420
457
|
this.handleTitleSelectChange(v, index)
|
|
421
458
|
},
|
|
422
459
|
// 根据当前选择项的 color 设置卡片背景色
|
|
423
|
-
normalizeValue
|
|
424
|
-
|
|
460
|
+
normalizeValue(v) {
|
|
461
|
+
return String(v)
|
|
462
|
+
},
|
|
463
|
+
getCardStyle(val) {
|
|
425
464
|
const target = this.normalizeValue(val)
|
|
426
|
-
const opt = (this.getTitleOptions || []).find(
|
|
465
|
+
const opt = (this.getTitleOptions || []).find(
|
|
466
|
+
o => this.normalizeValue(o && (o.value !== undefined ? o.value : o)) === target
|
|
467
|
+
)
|
|
427
468
|
const color = opt && (opt.color || (opt.style && opt.style.background))
|
|
428
469
|
return color ? { backgroundColor: color } : {}
|
|
429
470
|
},
|
|
430
|
-
getTitleLabel
|
|
471
|
+
getTitleLabel(val) {
|
|
431
472
|
const target = this.normalizeValue(val)
|
|
432
|
-
const opt = (this.getTitleOptions || []).find(
|
|
473
|
+
const opt = (this.getTitleOptions || []).find(
|
|
474
|
+
o => this.normalizeValue(o && (o.value !== undefined ? o.value : o)) === target
|
|
475
|
+
)
|
|
433
476
|
return opt && (opt.label !== undefined ? opt.label : opt)
|
|
434
477
|
},
|
|
435
|
-
getDisplayTitleLabel
|
|
478
|
+
getDisplayTitleLabel(index) {
|
|
436
479
|
// 优先展示“当前选中值”的 label,未选中再回退到模板提供的 titleRightLabel
|
|
437
480
|
const current = this.getTitleLabel(this.currentTitleValue(index))
|
|
438
481
|
if (current) return current
|
|
@@ -442,17 +485,17 @@ export default {
|
|
|
442
485
|
return title && title.titleRightLabel ? title.titleRightLabel : ''
|
|
443
486
|
},
|
|
444
487
|
// 点击列表项
|
|
445
|
-
handleClick
|
|
488
|
+
handleClick(index) {
|
|
446
489
|
if (this.enableSelectRow && this.selectOnClick) this.setSelectedIndex(index)
|
|
447
490
|
this.$emit('listClick', this.data[index])
|
|
448
491
|
},
|
|
449
492
|
// 卡片模式点击卡片
|
|
450
|
-
handleCardClick
|
|
493
|
+
handleCardClick(index) {
|
|
451
494
|
if (this.enableSelectRow && this.selectOnClick) this.setSelectedIndex(index)
|
|
452
495
|
this.$emit('listClick', this.localData[index])
|
|
453
496
|
},
|
|
454
497
|
// 外部可调用:设置选中索引
|
|
455
|
-
setSelectedIndex
|
|
498
|
+
setSelectedIndex(index) {
|
|
456
499
|
const next = typeof index === 'number' ? index : -1
|
|
457
500
|
if (typeof this.selectedIndex === 'number') {
|
|
458
501
|
// 受控:仅派发事件
|
|
@@ -464,15 +507,17 @@ export default {
|
|
|
464
507
|
}
|
|
465
508
|
},
|
|
466
509
|
// 外部可调用:清空选中
|
|
467
|
-
clearSelected
|
|
468
|
-
|
|
510
|
+
clearSelected() {
|
|
511
|
+
this.setSelectedIndex(-1)
|
|
512
|
+
},
|
|
513
|
+
refreshList(param) {
|
|
469
514
|
this.getData(this.queryParamsName, param)
|
|
470
515
|
},
|
|
471
|
-
click
|
|
516
|
+
click(index, buttonIndex) {
|
|
472
517
|
this.$emit('click', { data: this.data[index], name: this.buttonNames[buttonIndex] })
|
|
473
518
|
},
|
|
474
519
|
// 根据对象字段匹配选中(默认按 id 字段)
|
|
475
|
-
setSelectedById
|
|
520
|
+
setSelectedById(id, field = 'id') {
|
|
476
521
|
const list = this.listMode ? this.localData : this.data
|
|
477
522
|
if (!Array.isArray(list)) return
|
|
478
523
|
const index = list.findIndex(item => {
|
|
@@ -485,38 +530,38 @@ export default {
|
|
|
485
530
|
if (index >= 0) this.setSelectedIndex(index)
|
|
486
531
|
},
|
|
487
532
|
// 根据 label/value(卡片数组数据场景)匹配选中
|
|
488
|
-
setSelectedByLabelValue
|
|
533
|
+
setSelectedByLabelValue(label, value) {
|
|
489
534
|
const list = this.listMode ? this.localData : this.data
|
|
490
535
|
if (!Array.isArray(list)) return
|
|
491
|
-
const index = list.findIndex(
|
|
536
|
+
const index = list.findIndex(
|
|
537
|
+
item => Array.isArray(item) && item.some(d => d && d.label === label && d.value === value)
|
|
538
|
+
)
|
|
492
539
|
if (index >= 0) this.setSelectedIndex(index)
|
|
493
540
|
},
|
|
494
541
|
// 通用:传入谓词函数决定选中项
|
|
495
|
-
setSelectedBy
|
|
542
|
+
setSelectedBy(predicate) {
|
|
496
543
|
if (typeof predicate !== 'function') return
|
|
497
544
|
const list = this.listMode ? this.localData : this.data
|
|
498
545
|
if (!Array.isArray(list)) return
|
|
499
546
|
const index = list.findIndex(predicate)
|
|
500
547
|
if (index >= 0) this.setSelectedIndex(index)
|
|
501
548
|
},
|
|
502
|
-
getIconStyle
|
|
503
|
-
return item.picture
|
|
504
|
-
? { backgroundImage: `url(${item.picture})` }
|
|
505
|
-
: {}
|
|
549
|
+
getIconStyle(item) {
|
|
550
|
+
return item.picture ? { backgroundImage: `url(${item.picture})` } : {}
|
|
506
551
|
},
|
|
507
|
-
filterData
|
|
552
|
+
filterData(par) {
|
|
508
553
|
runLogic(this.queryParamsName, par, 'af-his').then(res => {
|
|
509
554
|
this.data = res.data
|
|
510
555
|
})
|
|
511
556
|
},
|
|
512
557
|
// 鼠标进入列表项
|
|
513
|
-
handleMouseEnter
|
|
558
|
+
handleMouseEnter(index) {
|
|
514
559
|
this.clearAllTimers()
|
|
515
560
|
this.hoveredIndex = index
|
|
516
561
|
this.isOptionsHovered = true
|
|
517
562
|
},
|
|
518
563
|
// 鼠标离开列表项
|
|
519
|
-
handleMouseLeave
|
|
564
|
+
handleMouseLeave() {
|
|
520
565
|
this.clearAllTimers()
|
|
521
566
|
this.leaveTimer = setTimeout(() => {
|
|
522
567
|
this.isOptionsHovered = false
|
|
@@ -524,12 +569,12 @@ export default {
|
|
|
524
569
|
}, 100)
|
|
525
570
|
},
|
|
526
571
|
// 鼠标进入悬浮选项框
|
|
527
|
-
handleOptionsEnter
|
|
572
|
+
handleOptionsEnter() {
|
|
528
573
|
this.clearAllTimers()
|
|
529
574
|
this.isOptionsHovered = true
|
|
530
575
|
},
|
|
531
576
|
// 鼠标离开悬浮选项框
|
|
532
|
-
handleOptionsLeave
|
|
577
|
+
handleOptionsLeave() {
|
|
533
578
|
this.clearAllTimers()
|
|
534
579
|
this.leaveTimer = setTimeout(() => {
|
|
535
580
|
this.isOptionsHovered = false
|
|
@@ -537,7 +582,7 @@ export default {
|
|
|
537
582
|
}, 100)
|
|
538
583
|
},
|
|
539
584
|
// 清除所有定时器
|
|
540
|
-
clearAllTimers
|
|
585
|
+
clearAllTimers() {
|
|
541
586
|
if (this.hoverTimer) {
|
|
542
587
|
clearTimeout(this.hoverTimer)
|
|
543
588
|
this.hoverTimer = null
|
|
@@ -548,17 +593,17 @@ export default {
|
|
|
548
593
|
}
|
|
549
594
|
},
|
|
550
595
|
// 选项框点击
|
|
551
|
-
handleOptionClick
|
|
596
|
+
handleOptionClick(index, action) {
|
|
552
597
|
this.$emit('optionClick', { data: this.data[index], action })
|
|
553
598
|
},
|
|
554
599
|
// 获取文本样式(简化版本,主要依赖CSS类控制)
|
|
555
|
-
getTextStyle
|
|
600
|
+
getTextStyle(index) {
|
|
556
601
|
return {}
|
|
557
|
-
}
|
|
602
|
+
}
|
|
558
603
|
},
|
|
559
604
|
watch: {
|
|
560
605
|
// 同步受控值变化
|
|
561
|
-
selectedIndex
|
|
606
|
+
selectedIndex(val) {
|
|
562
607
|
if (typeof val === 'number') {
|
|
563
608
|
// 允许受控值影响内部显示
|
|
564
609
|
this.localSelectedIndex = val
|
|
@@ -566,12 +611,12 @@ export default {
|
|
|
566
611
|
},
|
|
567
612
|
fixedQueryForm: {
|
|
568
613
|
deep: true,
|
|
569
|
-
handler
|
|
614
|
+
handler(val) {
|
|
570
615
|
this.refreshList(val)
|
|
571
616
|
}
|
|
572
|
-
}
|
|
617
|
+
}
|
|
573
618
|
},
|
|
574
|
-
beforeDestroy
|
|
619
|
+
beforeDestroy() {
|
|
575
620
|
const ref = this.$refs.listRef
|
|
576
621
|
if (ref && ref.removeEventListener) {
|
|
577
622
|
ref.removeEventListener('scroll', this.handleInfiniteOnLoad)
|
|
@@ -595,13 +640,13 @@ export default {
|
|
|
595
640
|
.list-item {
|
|
596
641
|
height: 35px;
|
|
597
642
|
border-radius: 6px;
|
|
598
|
-
background-color: #
|
|
643
|
+
background-color: #f4f4f4;
|
|
599
644
|
padding: 8px 15px;
|
|
600
645
|
font-size: 16px;
|
|
601
646
|
display: flex;
|
|
602
647
|
align-items: center;
|
|
603
648
|
width: 100%;
|
|
604
|
-
border: 1px solid #
|
|
649
|
+
border: 1px solid #d9d9d9;
|
|
605
650
|
box-sizing: border-box;
|
|
606
651
|
margin-bottom: 8px !important;
|
|
607
652
|
position: relative;
|
|
@@ -664,24 +709,30 @@ export default {
|
|
|
664
709
|
}
|
|
665
710
|
|
|
666
711
|
/* 选中态样式(通过 selectRow 开启) */
|
|
667
|
-
.selected-active {
|
|
712
|
+
.selected-active {
|
|
713
|
+
color: white;
|
|
714
|
+
}
|
|
668
715
|
.list-item.selected-active {
|
|
669
|
-
background-color: #
|
|
716
|
+
background-color: #0057fe !important;
|
|
670
717
|
color: white;
|
|
671
718
|
border: none !important;
|
|
672
719
|
}
|
|
673
720
|
.list-item.selected-active .confirm-btn,
|
|
674
721
|
.list-item.selected-active .confirm-btn span,
|
|
675
722
|
.list-item.selected-active .ant-btn,
|
|
676
|
-
.list-item.selected-active .ant-btn > span {
|
|
723
|
+
.list-item.selected-active .ant-btn > span {
|
|
724
|
+
color: #ffffff !important;
|
|
725
|
+
}
|
|
677
726
|
.card-a-col.selected-active {
|
|
678
|
-
background-color: #
|
|
727
|
+
background-color: #0057fe !important;
|
|
679
728
|
color: white;
|
|
680
729
|
border: none !important;
|
|
681
730
|
}
|
|
682
731
|
.card-a-col.selected-active .button-a-col,
|
|
683
732
|
.card-a-col.selected-active .button-a-col .ant-btn,
|
|
684
|
-
.card-a-col.selected-active .button-a-col .ant-btn > span {
|
|
733
|
+
.card-a-col.selected-active .button-a-col .ant-btn > span {
|
|
734
|
+
color: #ffffff !important;
|
|
735
|
+
}
|
|
685
736
|
|
|
686
737
|
.hover-options {
|
|
687
738
|
position: absolute;
|
|
@@ -732,18 +783,18 @@ export default {
|
|
|
732
783
|
text-align: center;
|
|
733
784
|
}
|
|
734
785
|
|
|
735
|
-
.demo-infinite-container{
|
|
786
|
+
.demo-infinite-container {
|
|
736
787
|
overflow-x: hidden;
|
|
737
788
|
overflow-y: auto;
|
|
738
789
|
height: 85vh;
|
|
739
790
|
}
|
|
740
|
-
.card-row{
|
|
791
|
+
.card-row {
|
|
741
792
|
height: 100%;
|
|
742
793
|
width: 100%;
|
|
743
794
|
border-radius: 6px;
|
|
744
795
|
padding: 6px;
|
|
745
796
|
}
|
|
746
|
-
.id-a-col{
|
|
797
|
+
.id-a-col {
|
|
747
798
|
font-size: 22px;
|
|
748
799
|
font-weight: 700;
|
|
749
800
|
display: flex;
|
|
@@ -752,7 +803,7 @@ export default {
|
|
|
752
803
|
justify-content: center;
|
|
753
804
|
gap: 4px;
|
|
754
805
|
}
|
|
755
|
-
.id-a-col-2{
|
|
806
|
+
.id-a-col-2 {
|
|
756
807
|
padding: 8px;
|
|
757
808
|
height: 100%;
|
|
758
809
|
overflow: hidden;
|
|
@@ -760,7 +811,7 @@ export default {
|
|
|
760
811
|
flex-direction: column;
|
|
761
812
|
justify-content: space-between;
|
|
762
813
|
}
|
|
763
|
-
.describe-list-a-col{
|
|
814
|
+
.describe-list-a-col {
|
|
764
815
|
display: block;
|
|
765
816
|
font-family: Source Han Sans;
|
|
766
817
|
font-size: 16px;
|
|
@@ -771,62 +822,90 @@ export default {
|
|
|
771
822
|
white-space: nowrap;
|
|
772
823
|
max-width: 100%;
|
|
773
824
|
}
|
|
774
|
-
.name{
|
|
825
|
+
.name {
|
|
775
826
|
font-family: Source Han Sans;
|
|
776
827
|
font-size: 22px;
|
|
777
828
|
font-weight: bold;
|
|
778
829
|
line-height: normal;
|
|
779
830
|
}
|
|
780
|
-
.component-a-col{
|
|
831
|
+
.component-a-col {
|
|
781
832
|
display: flex;
|
|
782
833
|
align-items: center;
|
|
783
834
|
overflow: hidden;
|
|
784
835
|
}
|
|
785
|
-
.label-text{
|
|
836
|
+
.label-text {
|
|
786
837
|
overflow: hidden;
|
|
787
838
|
text-overflow: ellipsis;
|
|
788
839
|
white-space: nowrap;
|
|
789
840
|
max-width: 120px;
|
|
790
841
|
display: inline-block;
|
|
791
842
|
}
|
|
792
|
-
.gender-icon{
|
|
843
|
+
.gender-icon {
|
|
793
844
|
margin-top: 2px;
|
|
794
845
|
}
|
|
795
|
-
.gender-icon .male{
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
846
|
+
.gender-icon .male {
|
|
847
|
+
color: #2f54eb;
|
|
848
|
+
font-size: 14px;
|
|
849
|
+
}
|
|
850
|
+
.gender-icon .female {
|
|
851
|
+
color: #eb2f96;
|
|
852
|
+
font-size: 14px;
|
|
853
|
+
}
|
|
854
|
+
.gender-img {
|
|
855
|
+
width: 100%;
|
|
856
|
+
height: 100%;
|
|
857
|
+
opacity: 1;
|
|
858
|
+
display: inline-block;
|
|
859
|
+
}
|
|
860
|
+
.title-row {
|
|
799
861
|
display: flex;
|
|
800
862
|
align-items: center;
|
|
801
863
|
justify-content: space-between;
|
|
802
864
|
gap: 8px;
|
|
803
865
|
}
|
|
804
866
|
/* 标题文本占满剩余空间,确保箭头贴右 */
|
|
805
|
-
.title-row .describe-list-a-col{
|
|
806
|
-
|
|
807
|
-
|
|
867
|
+
.title-row .describe-list-a-col {
|
|
868
|
+
flex: 1;
|
|
869
|
+
}
|
|
870
|
+
.title-actions {
|
|
871
|
+
display: inline-flex;
|
|
872
|
+
align-items: center;
|
|
873
|
+
gap: 6px;
|
|
874
|
+
}
|
|
875
|
+
.title-select-label {
|
|
808
876
|
font-family: Source Han Sans;
|
|
809
877
|
font-size: 16px;
|
|
810
878
|
font-weight: normal;
|
|
811
879
|
line-height: normal;
|
|
812
880
|
color: #595959;
|
|
813
881
|
}
|
|
814
|
-
.title-select{
|
|
815
|
-
|
|
816
|
-
|
|
882
|
+
.title-select {
|
|
883
|
+
min-width: 96px;
|
|
884
|
+
}
|
|
885
|
+
.arrow-btn {
|
|
886
|
+
display: inline-flex;
|
|
887
|
+
align-items: center;
|
|
888
|
+
color: #8c8c8c;
|
|
889
|
+
}
|
|
890
|
+
.arrow-btn .anticon {
|
|
891
|
+
font-size: 18px;
|
|
892
|
+
}
|
|
817
893
|
/* 放大下拉箭头的 svg 尺寸以符合 UI(scoped 深度选择) */
|
|
818
|
-
::v-deep .arrow-btn .anticon svg{
|
|
819
|
-
|
|
894
|
+
::v-deep .arrow-btn .anticon svg {
|
|
895
|
+
width: 2em;
|
|
896
|
+
height: 2em;
|
|
897
|
+
}
|
|
898
|
+
.button-a-col {
|
|
820
899
|
position: absolute;
|
|
821
900
|
top: 245px;
|
|
822
901
|
left: 225px;
|
|
823
902
|
}
|
|
824
|
-
.card-a-col{
|
|
903
|
+
.card-a-col {
|
|
825
904
|
background-color: rgba(247, 249, 252);
|
|
826
905
|
height: 297px;
|
|
827
906
|
width: auto;
|
|
828
907
|
border-radius: 6px;
|
|
829
|
-
border: 1px solid #
|
|
908
|
+
border: 1px solid #e5e9f0;
|
|
830
909
|
overflow: hidden;
|
|
831
910
|
position: relative;
|
|
832
911
|
box-sizing: border-box;
|
|
@@ -848,7 +927,7 @@ export default {
|
|
|
848
927
|
height: 35px;
|
|
849
928
|
border-radius: 6px;
|
|
850
929
|
opacity: 1;
|
|
851
|
-
background: #
|
|
930
|
+
background: #f4f4f4;
|
|
852
931
|
padding: 8px 12px;
|
|
853
932
|
margin-bottom: 8px !important;
|
|
854
933
|
display: flex;
|
|
@@ -871,7 +950,7 @@ export default {
|
|
|
871
950
|
font-weight: normal;
|
|
872
951
|
line-height: normal;
|
|
873
952
|
letter-spacing: 0em;
|
|
874
|
-
font-feature-settings:
|
|
953
|
+
font-feature-settings: 'kern' on;
|
|
875
954
|
color: #313131;
|
|
876
955
|
flex: 1; /* 占据剩余空间 */
|
|
877
956
|
margin-right: 1px; /* 与按钮组保持8px间距 */
|
|
@@ -902,7 +981,7 @@ export default {
|
|
|
902
981
|
font-weight: normal;
|
|
903
982
|
line-height: normal;
|
|
904
983
|
letter-spacing: 0em;
|
|
905
|
-
font-feature-settings:
|
|
984
|
+
font-feature-settings: 'kern' on;
|
|
906
985
|
/* 移除固定颜色,继承默认颜色 */
|
|
907
986
|
padding: 0; /* 清除内边距 */
|
|
908
987
|
margin-left: 0; /* 移除左边距,使用 gap 控制间距 */
|
|
@@ -915,7 +994,7 @@ export default {
|
|
|
915
994
|
font-weight: normal;
|
|
916
995
|
line-height: normal;
|
|
917
996
|
letter-spacing: 0em;
|
|
918
|
-
font-feature-settings:
|
|
997
|
+
font-feature-settings: 'kern' on;
|
|
919
998
|
/* 移除固定颜色,继承默认颜色 */
|
|
920
999
|
}
|
|
921
1000
|
}
|