vue2-client 1.16.38 → 1.16.39
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/assets/img/paymentMethod/icon1.png +0 -0
- package/src/assets/img/paymentMethod/icon2.png +0 -0
- package/src/assets/img/paymentMethod/icon3.png +0 -0
- package/src/assets/img/paymentMethod/icon4.png +0 -0
- package/src/assets/img/paymentMethod/icon5.png +0 -0
- package/src/assets/img/paymentMethod/icon6.png +0 -0
- package/src/base-client/components/common/HIS/HButtons/HButtons.vue +0 -2
- package/src/base-client/components/common/XReport/XReport.vue +18 -9
- package/src/base-client/components/common/XReport/XReportHospitalizationDemo.vue +45 -0
- package/src/base-client/components/his/XCharge/testConfig.js +149 -0
- package/src/base-client/components/his/XHDescriptions/XHDescriptions.vue +61 -19
- package/src/base-client/components/his/XList/XList.vue +117 -5
- package/src/router/async/router.map.js +4 -1
- package/src/services/api/common.js +1 -0
package/package.json
CHANGED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -328,8 +328,11 @@ export default {
|
|
328
328
|
value = config.data[cell.dataIndex]
|
329
329
|
}
|
330
330
|
|
331
|
-
//
|
332
|
-
|
331
|
+
// 检查值是否为空(允许 0 和 false)
|
332
|
+
const isEmptyString = typeof value === 'string' && value.trim() === ''
|
333
|
+
const isEmptyArray = Array.isArray(value) && value.length === 0
|
334
|
+
const isNullish = value === null || value === undefined
|
335
|
+
if (isNullish || isEmptyString || isEmptyArray) {
|
333
336
|
const message = cell.requiredMessage || this.getDefaultRequiredMessage(cell.type)
|
334
337
|
errors.push({
|
335
338
|
dataIndex: cell.dataIndex,
|
@@ -819,12 +822,18 @@ export default {
|
|
819
822
|
this.getConfigAndJoin(this.config, lock)
|
820
823
|
|
821
824
|
// 用定时器循环查看锁状态
|
825
|
+
// 先清理可能存在的旧轮询,避免重复打印与重复初始化
|
826
|
+
if (this.timer) {
|
827
|
+
clearInterval(this.timer)
|
828
|
+
this.timer = undefined
|
829
|
+
}
|
822
830
|
this.timer = setInterval(() => {
|
823
831
|
if (!lock.status) {
|
824
832
|
clearInterval(this.timer)
|
833
|
+
this.timer = undefined
|
825
834
|
console.log('拼接完成', this.config)
|
826
835
|
// 将初始化好的配置拷贝一份留存
|
827
|
-
this.originalConfig =
|
836
|
+
this.originalConfig = JSON.parse(JSON.stringify(this.config))
|
828
837
|
if (!this.dontFormat) {
|
829
838
|
// 扫描配置文件中有没有rowSpan,进行格式化调整
|
830
839
|
this.formatConfigRow(this.config)
|
@@ -864,8 +873,8 @@ export default {
|
|
864
873
|
if (this.configData === undefined) {
|
865
874
|
console.error('未找到数据!')
|
866
875
|
} else {
|
867
|
-
this.originalConfig =
|
868
|
-
this.originalConfig.data = Object.assign(this.originalConfig.data, JSON.parse(JSON.stringify(this.configData)))
|
876
|
+
this.originalConfig = JSON.parse(JSON.stringify(this.config))
|
877
|
+
this.originalConfig.data = Object.assign({}, this.originalConfig.data, JSON.parse(JSON.stringify(this.configData)))
|
869
878
|
this.type = 'display'
|
870
879
|
// this.onlyDisplay = true
|
871
880
|
this.showSkeleton = false
|
@@ -879,12 +888,12 @@ export default {
|
|
879
888
|
this.config = res
|
880
889
|
if (this.config.designMode === 'json') {
|
881
890
|
if (this.configData !== undefined) {
|
882
|
-
this.config.data = Object.assign({}, this.config.data, this.configData)
|
891
|
+
this.config.data = Object.assign({}, this.config.data, JSON.parse(JSON.stringify(this.configData)))
|
883
892
|
}
|
884
893
|
this.jsonConfigInit()
|
885
894
|
} else {
|
886
895
|
if (this.configData !== undefined) {
|
887
|
-
this.config.data = Object.assign(this.config.data, this.configData)
|
896
|
+
this.config.data = Object.assign({}, this.config.data, JSON.parse(JSON.stringify(this.configData)))
|
888
897
|
}
|
889
898
|
if (this.config.data.images === undefined) {
|
890
899
|
this.config.data.images = {}
|
@@ -917,14 +926,14 @@ export default {
|
|
917
926
|
if (this.localConfig.designMode === 'json') {
|
918
927
|
this.config = this.localConfig
|
919
928
|
if (this.configData !== undefined) {
|
920
|
-
this.config.data = Object.assign(this.config.data, this.configData)
|
929
|
+
this.config.data = Object.assign({}, this.config.data, JSON.parse(JSON.stringify(this.configData)))
|
921
930
|
}
|
922
931
|
this.jsonConfigInit()
|
923
932
|
} else {
|
924
933
|
// 如果配置是普通渲染器
|
925
934
|
this.config = this.localConfig
|
926
935
|
if (this.configData !== undefined) {
|
927
|
-
this.config.data = Object.assign(this.config.data, this.configData)
|
936
|
+
this.config.data = Object.assign({}, this.config.data, JSON.parse(JSON.stringify(this.configData)))
|
928
937
|
}
|
929
938
|
if (this.config.data.images === undefined) {
|
930
939
|
this.config.data.images = {}
|
@@ -0,0 +1,45 @@
|
|
1
|
+
<template>
|
2
|
+
<div id="xreport-hosp-demo">
|
3
|
+
<a-space style="margin-bottom: 12px;">
|
4
|
+
<a-button type="primary" @click="doInit">手动初始化</a-button>
|
5
|
+
</a-space>
|
6
|
+
<XReport
|
7
|
+
ref="reportRef"
|
8
|
+
:edit-mode="true"
|
9
|
+
:show-save-button="true"
|
10
|
+
:show-img-in-cell="false"
|
11
|
+
:use-oss-for-img="false"
|
12
|
+
server-name="af-his"
|
13
|
+
@updateImg="onUpdateImg"/>
|
14
|
+
</div>
|
15
|
+
</template>
|
16
|
+
|
17
|
+
<script setup>
|
18
|
+
import { ref } from 'vue'
|
19
|
+
import XReport from '@vue2-client/base-client/components/common/XReport'
|
20
|
+
|
21
|
+
const reportRef = ref(null)
|
22
|
+
|
23
|
+
const payload = {
|
24
|
+
arr: [
|
25
|
+
{ BQ: '病房区', RY: 0, CY: 0, CW: 0, SW: 0, SS: 0, ZC: 0, ZR: 0, ZY: 0 },
|
26
|
+
{ BQ: '感染科', RY: 0, CY: 0, CW: 0, SW: 0, SS: 0, ZC: 0, ZR: 0, ZY: 0 },
|
27
|
+
{ BQ: '骨科病区', RY: 0, CY: 0, CW: 0, SW: 0, SS: 0, ZC: 0, ZR: 0, ZY: 0 },
|
28
|
+
{ BQ: '呼吸科病区', RY: 0, CY: 0, CW: 0, SW: 0, SS: 0, ZC: 0, ZR: 0, ZY: 0 },
|
29
|
+
{ BQ: '急症科病区', RY: 0, CY: 0, CW: 0, SW: 0, SS: 0, ZC: 0, ZR: 0, ZY: 0 },
|
30
|
+
{ BQ: '内科二病区', RY: 0, CY: 0, CW: 0, SW: 0, SS: 0, ZC: 0, ZR: 0, ZY: 0 }
|
31
|
+
]
|
32
|
+
}
|
33
|
+
|
34
|
+
const doInit = async () => {
|
35
|
+
if (!reportRef.value || !reportRef.value.init) return
|
36
|
+
await reportRef.value.init({
|
37
|
+
configName: 'hospitalizationStatsReport',
|
38
|
+
configData: payload
|
39
|
+
})
|
40
|
+
}
|
41
|
+
|
42
|
+
const onUpdateImg = data => {
|
43
|
+
console.warn('updateImg:', data)
|
44
|
+
}
|
45
|
+
</script>
|
@@ -0,0 +1,149 @@
|
|
1
|
+
// 测试配置 - 用于演示混合支付功能
|
2
|
+
export const testChargeConfig = {
|
3
|
+
"amountFields": [
|
4
|
+
{
|
5
|
+
"field": 'f_amount',
|
6
|
+
"disabled": false,
|
7
|
+
"label": '费用总额'
|
8
|
+
},
|
9
|
+
{
|
10
|
+
"field": 'f_insurance_amount',
|
11
|
+
"disabled": true,
|
12
|
+
"label": '医保支付'
|
13
|
+
},
|
14
|
+
{
|
15
|
+
"field": 'f_self_amount',
|
16
|
+
"disabled": true,
|
17
|
+
"label": '自费金额'
|
18
|
+
},
|
19
|
+
{
|
20
|
+
"field": 'out_of_pocket_amount',
|
21
|
+
"disabled": true,
|
22
|
+
"label": '自付金额'
|
23
|
+
},
|
24
|
+
{
|
25
|
+
"field": 'biscount_amount',
|
26
|
+
"disabled": true,
|
27
|
+
"label": '折扣金额'
|
28
|
+
},
|
29
|
+
{
|
30
|
+
"field": 'billing_amount',
|
31
|
+
"disabled": true,
|
32
|
+
"label": '记账金额'
|
33
|
+
}
|
34
|
+
],
|
35
|
+
"paymentMethods": [
|
36
|
+
{
|
37
|
+
"key": '医保卡',
|
38
|
+
"label": '医保卡'
|
39
|
+
},
|
40
|
+
{
|
41
|
+
"key": '微信/支付宝',
|
42
|
+
"label": '微信/支付宝'
|
43
|
+
},
|
44
|
+
{
|
45
|
+
"key": '银行卡',
|
46
|
+
"label": '银行卡'
|
47
|
+
},
|
48
|
+
{
|
49
|
+
"key": '现金',
|
50
|
+
"label": '现金'
|
51
|
+
}
|
52
|
+
],
|
53
|
+
"bottomFields": [
|
54
|
+
{
|
55
|
+
"field": 'f_balance',
|
56
|
+
"label": '账户余额',
|
57
|
+
"disabled": false
|
58
|
+
},
|
59
|
+
{
|
60
|
+
"field": 'received',
|
61
|
+
"label": '实收',
|
62
|
+
"disabled": false
|
63
|
+
},
|
64
|
+
{
|
65
|
+
"field": 'change',
|
66
|
+
"label": '找零',
|
67
|
+
"disabled": false
|
68
|
+
}
|
69
|
+
],
|
70
|
+
"actionButtons": [
|
71
|
+
{
|
72
|
+
"key": 'charge',
|
73
|
+
"label": '收费',
|
74
|
+
"icon": 'check'
|
75
|
+
},
|
76
|
+
{
|
77
|
+
"key": 'refund',
|
78
|
+
"label": '退费',
|
79
|
+
"icon": 'undo'
|
80
|
+
},
|
81
|
+
{
|
82
|
+
"key": 'print',
|
83
|
+
"label": '打印',
|
84
|
+
"icon": 'printer'
|
85
|
+
}
|
86
|
+
],
|
87
|
+
"enableMixedPayment": true, // 启用混合支付
|
88
|
+
// 可配置事件名,参考 fronImport 风格
|
89
|
+
"eventNames": {
|
90
|
+
"method": 'method',
|
91
|
+
"methods": 'methods',
|
92
|
+
"totalPaymentAmount": 'totalPaymentAmount',
|
93
|
+
"action": 'action'
|
94
|
+
},
|
95
|
+
"dataSourceConfig": 'testChargeLogic'
|
96
|
+
}
|
97
|
+
|
98
|
+
// 单选模式测试配置
|
99
|
+
export const testSingleChargeConfig = {
|
100
|
+
"amountFields": [
|
101
|
+
{
|
102
|
+
"field": 'f_amount',
|
103
|
+
"disabled": false,
|
104
|
+
"label": '费用总额'
|
105
|
+
},
|
106
|
+
{
|
107
|
+
"field": 'f_insurance_amount',
|
108
|
+
"disabled": true,
|
109
|
+
"label": '医保支付'
|
110
|
+
}
|
111
|
+
],
|
112
|
+
"paymentMethods": [
|
113
|
+
{
|
114
|
+
"key": '医保卡',
|
115
|
+
"label": '医保卡'
|
116
|
+
},
|
117
|
+
{
|
118
|
+
"key": '现金',
|
119
|
+
"label": '现金'
|
120
|
+
}
|
121
|
+
],
|
122
|
+
"bottomFields": [
|
123
|
+
{
|
124
|
+
"field": 'received',
|
125
|
+
"label": '实收',
|
126
|
+
"disabled": false
|
127
|
+
},
|
128
|
+
{
|
129
|
+
"field": 'change',
|
130
|
+
"label": '找零',
|
131
|
+
"disabled": false
|
132
|
+
}
|
133
|
+
],
|
134
|
+
"actionButtons": [
|
135
|
+
{
|
136
|
+
"key": 'charge',
|
137
|
+
"label": '收费',
|
138
|
+
"icon": 'check'
|
139
|
+
}
|
140
|
+
],
|
141
|
+
"enableMixedPayment": false, // 禁用混合支付(单选模式)
|
142
|
+
"eventNames": {
|
143
|
+
"method": 'method',
|
144
|
+
"methods": 'methods',
|
145
|
+
"totalPaymentAmount": 'totalPaymentAmount',
|
146
|
+
"action": 'action'
|
147
|
+
},
|
148
|
+
"dataSourceConfig": 'testChargeLogic'
|
149
|
+
}
|
@@ -1,23 +1,23 @@
|
|
1
1
|
<template>
|
2
|
-
<div class="patient-info-descriptions">
|
2
|
+
<div class="patient-info-descriptions" :class="wrapperClassObject">
|
3
3
|
<div class="descriptions-container">
|
4
4
|
<!-- 详情/收起按钮 -->
|
5
5
|
<div v-if="hasMoreItems" class="detail-button-wrapper">
|
6
6
|
<a-button
|
7
|
-
:type="config
|
7
|
+
:type="(config && config.detailsConfig && config.detailsConfig.buttonType) || 'link'"
|
8
8
|
@click="toggleDetails"
|
9
9
|
>
|
10
10
|
<a-icon :type="showAllItems ? 'up' : 'down'" />
|
11
|
-
{{ showAllItems ? '收起' : (config
|
11
|
+
{{ showAllItems ? '收起' : ((config && config.detailsConfig && config.detailsConfig.buttonText) || '详情') }}
|
12
12
|
</a-button>
|
13
13
|
</div>
|
14
14
|
|
15
15
|
<!-- 当有 layout 配置时使用 a-descriptions -->
|
16
|
-
<template v-if="config
|
16
|
+
<template v-if="config && config.layout">
|
17
17
|
<a-descriptions
|
18
18
|
:column="config.layout"
|
19
|
-
:size="config
|
20
|
-
:bordered="config
|
19
|
+
:size="(config && config.style && config.style.size)"
|
20
|
+
:bordered="(config && config.style && config.style.bordered)"
|
21
21
|
layout="horizontal">
|
22
22
|
<template v-if="data">
|
23
23
|
<!-- 显示前N个标签 -->
|
@@ -151,14 +151,34 @@ export default {
|
|
151
151
|
}
|
152
152
|
},
|
153
153
|
computed: {
|
154
|
+
// 动态样式开关(与 HForm 思路一致):布尔开关 + size 派生类
|
155
|
+
wrapperClassObject () {
|
156
|
+
const attrs = this.$attrs || {}
|
157
|
+
const classes = {}
|
158
|
+
|
159
|
+
const booleanStyleKeys = [
|
160
|
+
'query-conditions',
|
161
|
+
'padding-50',
|
162
|
+
'label-text-horizontal',
|
163
|
+
'description'
|
164
|
+
]
|
165
|
+
booleanStyleKeys.forEach(key => {
|
166
|
+
const val = attrs[key]
|
167
|
+
const truthy = val === true || val === '' || val === 'true'
|
168
|
+
if (truthy) classes[`xhdesc-${key}`] = true
|
169
|
+
})
|
170
|
+
const size = attrs.size
|
171
|
+
if (size && typeof size === 'string') classes[`xhdesc-size-${size}`] = true
|
172
|
+
return classes
|
173
|
+
},
|
154
174
|
// 获取详情按钮应该显示在第几个标签后
|
155
175
|
detailsAfterIndex () {
|
156
|
-
return this.config
|
176
|
+
return (this.config && this.config.detailsConfig && this.config.detailsConfig.showAfterIndex) || 999
|
157
177
|
},
|
158
178
|
// 判断是否有更多标签需要显示
|
159
179
|
hasMoreItems () {
|
160
|
-
if (!this.config
|
161
|
-
if (!this.data || !this.config
|
180
|
+
if (!(this.config && this.config.detailsConfig)) return false
|
181
|
+
if (!this.data || !(this.config && this.config.items) || !Array.isArray(this.config.items)) return false
|
162
182
|
const hiddenStartIndex = this.detailsAfterIndex || 0
|
163
183
|
if (hiddenStartIndex >= this.config.items.length) return false
|
164
184
|
for (let i = hiddenStartIndex; i < this.config.items.length; i++) {
|
@@ -171,15 +191,15 @@ export default {
|
|
171
191
|
},
|
172
192
|
// 获取应该显示的标签
|
173
193
|
visibleItems () {
|
174
|
-
if (!this.config
|
175
|
-
if (!this.config
|
194
|
+
if (!(this.config && this.config.items)) return []
|
195
|
+
if (!(this.config && this.config.detailsConfig)) return this.config.items
|
176
196
|
if (this.showAllItems) return this.config.items.slice(0, this.detailsAfterIndex)
|
177
197
|
return this.config.items.slice(0, this.detailsAfterIndex)
|
178
198
|
},
|
179
199
|
// 获取隐藏的标签(保持原有逻辑)
|
180
200
|
hiddenItems () {
|
181
|
-
if (!this.config
|
182
|
-
if (!this.config
|
201
|
+
if (!(this.config && this.config.items)) return []
|
202
|
+
if (!(this.config && this.config.detailsConfig)) return []
|
183
203
|
return this.config.items.slice(this.detailsAfterIndex)
|
184
204
|
}
|
185
205
|
},
|
@@ -192,7 +212,7 @@ export default {
|
|
192
212
|
this.showAllItems = false
|
193
213
|
getConfigByName(data, 'af-his', res => {
|
194
214
|
this.config = res
|
195
|
-
const hiddenConfig = this.config
|
215
|
+
const hiddenConfig = (this.config && this.config.hiddenConfig) || (0 === 1)
|
196
216
|
const parameter = { ...res.parameter, ...this.parameter, ...parameterData }
|
197
217
|
runLogic(res.logicName, parameter, 'af-his').then(result => {
|
198
218
|
if (hiddenConfig) {
|
@@ -272,7 +292,7 @@ export default {
|
|
272
292
|
align-items: center;
|
273
293
|
gap: 8px;
|
274
294
|
color: rgba(0, 0, 0, 0.65);
|
275
|
-
font-size: v-bind('config
|
295
|
+
font-size: v-bind('(config && config.style && config.style.fontSize) || "14px"');
|
276
296
|
white-space: nowrap;
|
277
297
|
}
|
278
298
|
|
@@ -288,7 +308,7 @@ export default {
|
|
288
308
|
display: inline-flex;
|
289
309
|
align-items: center;
|
290
310
|
margin-left: 4px;
|
291
|
-
font-size: v-bind('config
|
311
|
+
font-size: v-bind('(config && config.style && config.style.fontSize) || "14px"');
|
292
312
|
color: rgba(0, 0, 0, 0.85);
|
293
313
|
max-width: 300px;
|
294
314
|
overflow: hidden;
|
@@ -336,17 +356,17 @@ export default {
|
|
336
356
|
color: rgba(0, 0, 0, 0.65);
|
337
357
|
padding: 0 !important;
|
338
358
|
margin: 0 !important;
|
339
|
-
font-size: v-bind('config
|
359
|
+
font-size: v-bind('(config && config.style && config.style.fontSize) || "14px"');
|
340
360
|
display: inline-flex !important;
|
341
361
|
align-items: center !important;
|
342
362
|
white-space: nowrap !important;
|
343
|
-
min-width: v-bind('config
|
363
|
+
min-width: v-bind('(config && config.style && config.style.labelWidth) || "80px"');
|
344
364
|
justify-content: flex-start;
|
345
365
|
padding-right: 2px !important;
|
346
366
|
}
|
347
367
|
|
348
368
|
:deep(.ant-descriptions-item-content) {
|
349
|
-
font-size: v-bind('config
|
369
|
+
font-size: v-bind('(config && config.style && config.style.fontSize) || "14px"');
|
350
370
|
display: inline-flex !important;
|
351
371
|
align-items: center !important;
|
352
372
|
padding: 0 !important;
|
@@ -426,4 +446,26 @@ export default {
|
|
426
446
|
height: 0;
|
427
447
|
border-bottom: 1px dashed rgba(0, 0, 0, 0.15);
|
428
448
|
}
|
449
|
+
/* 加边框 */
|
450
|
+
.xhdesc-description {
|
451
|
+
padding: 4px 4px 4px 4px;
|
452
|
+
|
453
|
+
/* 作用域内 *patient-info-descriptions */
|
454
|
+
&.patient-info-descriptions,
|
455
|
+
.patient-info-descriptions {
|
456
|
+
border: 1px solid #E5E9F0;
|
457
|
+
border-radius: 6px;
|
458
|
+
padding: 6.5px 12px;
|
459
|
+
|
460
|
+
/* *ant-btn-link */
|
461
|
+
:deep(.ant-btn-link) {
|
462
|
+
border: none;
|
463
|
+
}
|
464
|
+
|
465
|
+
/* *ant-descriptions-item-content */
|
466
|
+
:deep(.ant-descriptions-item-content) {
|
467
|
+
font-weight: bold;
|
468
|
+
}
|
469
|
+
}
|
470
|
+
}
|
429
471
|
</style>
|
@@ -1,15 +1,16 @@
|
|
1
1
|
<template>
|
2
2
|
<!-- 列表卡片模式 listMode: card -->
|
3
3
|
<div
|
4
|
+
class="x-list-wrapper"
|
5
|
+
:class="wrapperClassObject"
|
4
6
|
v-if="listMode"
|
5
|
-
class="demo-infinite-container"
|
6
7
|
ref="listRef"
|
7
8
|
@scroll="handleInfiniteOnLoad">
|
8
9
|
<a-list
|
9
10
|
:grid="{ gutter: 16, xs: 1, sm: 2, md: 2, lg: 3, xl: 3, xxl: 4 }"
|
10
11
|
:data-source="localData">
|
11
12
|
<a-list-item slot="renderItem" slot-scope="item, index">
|
12
|
-
<div class="card-a-col">
|
13
|
+
<div class="card-a-col" :class="{ 'selected-active': enableSelectRow && currentSelectedIndex === index }" @click="handleCardClick(index)">
|
13
14
|
<a-row class="card-row">
|
14
15
|
<a-col class="id-a-col" :span="4" v-for="(detail,idx) in item.filter(d => d.label == label)" :key="idx">
|
15
16
|
{{ detail.value }}<span style="font-size: 16px;font-weight: 400 !important;">床</span>
|
@@ -59,7 +60,7 @@
|
|
59
60
|
</div>
|
60
61
|
|
61
62
|
<!-- 默认标签模式 -->
|
62
|
-
<div class="list-wrapper" v-else>
|
63
|
+
<div class="list-wrapper x-list-wrapper" :class="wrapperClassObject" v-else>
|
63
64
|
<a-list size="large" :data-source="data" itemLayout="horizontal" class="list-container" ref="listRef">
|
64
65
|
<a-list-item
|
65
66
|
slot="renderItem"
|
@@ -68,7 +69,7 @@
|
|
68
69
|
@click="handleClick(index)"
|
69
70
|
@mouseenter="enableHoverOptions && handleMouseEnter(index)"
|
70
71
|
@mouseleave="handleMouseLeave"
|
71
|
-
:class="{ 'hover-active': enableHoverOptions && hoveredIndex === index }">
|
72
|
+
:class="{ 'hover-active': enableHoverOptions && hoveredIndex === index, 'selected-active': enableSelectRow && currentSelectedIndex === index }">
|
72
73
|
<i
|
73
74
|
v-if="icon"
|
74
75
|
class="icon-menu"
|
@@ -143,6 +144,16 @@ export default {
|
|
143
144
|
serviceName: {
|
144
145
|
type: String,
|
145
146
|
default: 'af-his'
|
147
|
+
},
|
148
|
+
// 点击是否触发选中(默认不通过点击选中,仅手动控制)
|
149
|
+
selectOnClick: {
|
150
|
+
type: Boolean,
|
151
|
+
default: false
|
152
|
+
},
|
153
|
+
// 受控选中索引;不传则内部维护
|
154
|
+
selectedIndex: {
|
155
|
+
type: Number,
|
156
|
+
default: undefined
|
146
157
|
}
|
147
158
|
},
|
148
159
|
inject: ['getComponentByName'],
|
@@ -167,7 +178,9 @@ export default {
|
|
167
178
|
pageSize: 12,
|
168
179
|
allLoaded: false,
|
169
180
|
label: 'id',
|
170
|
-
scrollTimer: null
|
181
|
+
scrollTimer: null,
|
182
|
+
// 内部选中索引(非受控时使用)
|
183
|
+
localSelectedIndex: -1
|
171
184
|
}
|
172
185
|
},
|
173
186
|
created () {
|
@@ -175,6 +188,30 @@ export default {
|
|
175
188
|
},
|
176
189
|
mounted () {},
|
177
190
|
computed: {
|
191
|
+
// 参考 HForm 的 wrapperClassObject 规则,支持通过组件属性动态控制样式
|
192
|
+
wrapperClassObject () {
|
193
|
+
const a = this.$attrs || {}
|
194
|
+
const classes = {}
|
195
|
+
// 多个布尔型样式开关(存在且为真则生效)
|
196
|
+
const booleanStyleKeys = [
|
197
|
+
''
|
198
|
+
]
|
199
|
+
booleanStyleKeys.forEach(key => {
|
200
|
+
const val = a[key]
|
201
|
+
const truthy = val === true || val === '' || val === 'true'
|
202
|
+
if (truthy) classes[`x-list-${key}`] = true
|
203
|
+
})
|
204
|
+
return classes
|
205
|
+
},
|
206
|
+
// 选择控制:受控优先
|
207
|
+
currentSelectedIndex () {
|
208
|
+
return typeof this.selectedIndex === 'number' ? this.selectedIndex : this.localSelectedIndex
|
209
|
+
},
|
210
|
+
enableSelectRow () {
|
211
|
+
const a = this.$attrs || {}
|
212
|
+
const val = a.enableSelection
|
213
|
+
return val === true || val === '' || val === 'true'
|
214
|
+
},
|
178
215
|
forwardAllEvents () {
|
179
216
|
return {
|
180
217
|
// 监听所有事件并转发给父组件
|
@@ -239,14 +276,62 @@ export default {
|
|
239
276
|
},
|
240
277
|
// 点击列表项
|
241
278
|
handleClick (index) {
|
279
|
+
if (this.enableSelectRow && this.selectOnClick) this.setSelectedIndex(index)
|
242
280
|
this.$emit('listClick', this.data[index])
|
243
281
|
},
|
282
|
+
// 卡片模式点击卡片
|
283
|
+
handleCardClick (index) {
|
284
|
+
if (this.enableSelectRow && this.selectOnClick) this.setSelectedIndex(index)
|
285
|
+
this.$emit('listClick', this.localData[index])
|
286
|
+
},
|
287
|
+
// 外部可调用:设置选中索引
|
288
|
+
setSelectedIndex (index) {
|
289
|
+
const next = typeof index === 'number' ? index : -1
|
290
|
+
if (typeof this.selectedIndex === 'number') {
|
291
|
+
// 受控:仅派发事件
|
292
|
+
this.$emit('update:selectedIndex', next)
|
293
|
+
} else {
|
294
|
+
// 非受控:更新内部并派发事件
|
295
|
+
this.localSelectedIndex = next
|
296
|
+
this.$emit('update:selectedIndex', next)
|
297
|
+
}
|
298
|
+
},
|
299
|
+
// 外部可调用:清空选中
|
300
|
+
clearSelected () { this.setSelectedIndex(-1) },
|
244
301
|
refreshList (param) {
|
245
302
|
this.getData(this.queryParamsName, param)
|
246
303
|
},
|
247
304
|
click (index, buttonIndex) {
|
248
305
|
this.$emit('click', { data: this.data[index], name: this.buttonNames[buttonIndex] })
|
249
306
|
},
|
307
|
+
// 根据对象字段匹配选中(默认按 id 字段)
|
308
|
+
setSelectedById (id, field = 'id') {
|
309
|
+
const list = this.listMode ? this.localData : this.data
|
310
|
+
if (!Array.isArray(list)) return
|
311
|
+
const index = list.findIndex(item => {
|
312
|
+
if (Array.isArray(item)) {
|
313
|
+
const f = item.find(d => d && d.label === field)
|
314
|
+
return f && f.value === id
|
315
|
+
}
|
316
|
+
return item && item[field] === id
|
317
|
+
})
|
318
|
+
if (index >= 0) this.setSelectedIndex(index)
|
319
|
+
},
|
320
|
+
// 根据 label/value(卡片数组数据场景)匹配选中
|
321
|
+
setSelectedByLabelValue (label, value) {
|
322
|
+
const list = this.listMode ? this.localData : this.data
|
323
|
+
if (!Array.isArray(list)) return
|
324
|
+
const index = list.findIndex(item => Array.isArray(item) && item.some(d => d && d.label === label && d.value === value))
|
325
|
+
if (index >= 0) this.setSelectedIndex(index)
|
326
|
+
},
|
327
|
+
// 通用:传入谓词函数决定选中项
|
328
|
+
setSelectedBy (predicate) {
|
329
|
+
if (typeof predicate !== 'function') return
|
330
|
+
const list = this.listMode ? this.localData : this.data
|
331
|
+
if (!Array.isArray(list)) return
|
332
|
+
const index = list.findIndex(predicate)
|
333
|
+
if (index >= 0) this.setSelectedIndex(index)
|
334
|
+
},
|
250
335
|
getIconStyle (item) {
|
251
336
|
return item.picture
|
252
337
|
? { backgroundImage: `url(${item.picture})` }
|
@@ -301,6 +386,13 @@ export default {
|
|
301
386
|
}
|
302
387
|
},
|
303
388
|
watch: {
|
389
|
+
// 同步受控值变化
|
390
|
+
selectedIndex (val) {
|
391
|
+
if (typeof val === 'number') {
|
392
|
+
// 允许受控值影响内部显示
|
393
|
+
this.localSelectedIndex = val
|
394
|
+
}
|
395
|
+
},
|
304
396
|
fixedQueryForm: {
|
305
397
|
deep: true,
|
306
398
|
handler (val) {
|
@@ -400,6 +492,26 @@ export default {
|
|
400
492
|
border: 1px solid black;
|
401
493
|
}
|
402
494
|
|
495
|
+
/* 选中态样式(通过 selectRow 开启) */
|
496
|
+
.selected-active { color: white; }
|
497
|
+
.list-item.selected-active {
|
498
|
+
background-color: #0057FE !important;
|
499
|
+
color: white;
|
500
|
+
border: none !important;
|
501
|
+
}
|
502
|
+
.list-item.selected-active .confirm-btn,
|
503
|
+
.list-item.selected-active .confirm-btn span,
|
504
|
+
.list-item.selected-active .ant-btn,
|
505
|
+
.list-item.selected-active .ant-btn > span { color: #ffffff !important; }
|
506
|
+
.card-a-col.selected-active {
|
507
|
+
background-color: #0057FE !important;
|
508
|
+
color: white;
|
509
|
+
border: none !important;
|
510
|
+
}
|
511
|
+
.card-a-col.selected-active .button-a-col,
|
512
|
+
.card-a-col.selected-active .button-a-col .ant-btn,
|
513
|
+
.card-a-col.selected-active .button-a-col .ant-btn > span { color: #ffffff !important; }
|
514
|
+
|
403
515
|
.hover-options {
|
404
516
|
position: absolute;
|
405
517
|
left: 0;
|
@@ -60,12 +60,15 @@ path: 'example',
|
|
60
60
|
// component: () => import('@vue2-client/base-client/components/common/XAddNativeForm/demo.vue'),
|
61
61
|
// component: () => import('@vue2-client/base-client/components/common/XFormGroup/demo.vue'),
|
62
62
|
// component: () => import('@vue2-client/base-client/components/common/XReport/XReportDemo.vue'),
|
63
|
-
component: () => import('@vue2-client/base-client/components/common/HIS/demo.vue'),
|
63
|
+
// component: () => import('@vue2-client/base-client/components/common/HIS/demo.vue'),
|
64
|
+
// component: () => import('@vue2-client/base-client/components/common/XFormTable/demo.vue'),
|
64
65
|
// component: () => import('@vue2-client/base-client/components/common/XDatePicker/demo.vue'),
|
65
66
|
// component: () => import('@vue2-client/base-client/components/common/XTab/XTabDemo.vue'),
|
66
67
|
// component: () => import('@vue2-client/base-client/components/common/XRate/demo.vue'),
|
68
|
+
component: () => import('@vue2-client/base-client/components/common/XReport/XReportHospitalizationDemo.vue'),
|
67
69
|
// component: () => import('@vue2-client/base-client/components/common/XForm/demo.vue'),
|
68
70
|
// component: () => import('@vue2-client/base-client/components/his/XTimeSelect/XTimeSelectDemo.vue'),
|
71
|
+
// component: () => import('@vue2-client/base-client/components/his/XCharge/XChargeDemo.vue'),
|
69
72
|
// component: () => import('@vue2-client/base-client/components/his/XImportExcelButton/XFrontImportExcelDemo.vue'),
|
70
73
|
// component: () => import('@vue2-client/pages/WorkflowDetail/WorkFlowDemo.vue'),
|
71
74
|
// component: () => import('@vue2-client/pages/WorkflowDetail/WorkFlowDemo.vue'),
|
@@ -83,6 +83,7 @@ export function getConfig (content, configName, serviceName = process.env.VUE_AP
|
|
83
83
|
apiPre = '/devApi/'
|
84
84
|
}
|
85
85
|
const getConfigUrl = apiPre + serviceName + '/' + commonApi.getConfig
|
86
|
+
console.log('getConfigUrl', getConfigUrl)
|
86
87
|
indexedDB.getByWeb(configName, getConfigUrl, { configName: configName }, callback)
|
87
88
|
}
|
88
89
|
|