vue2-client 1.16.54 → 1.16.55
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 +112 -112
- 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/assets/svg/female.svg +1 -1
- package/src/assets/svg/male.svg +1 -1
- package/src/base-client/components/common/HIS/HButtons/HButtons.vue +1 -1
- package/src/base-client/components/common/HIS/HFormGroup/HFormGroup.vue +120 -120
- package/src/base-client/components/common/HIS/HFormGroup/index.js +3 -3
- package/src/base-client/components/common/HIS/HFormTable/HFormTable.vue +379 -379
- package/src/base-client/components/common/HIS/HTab/HTab.vue +29 -2
- package/src/base-client/components/common/HIS/demo.vue +61 -61
- package/src/base-client/components/common/XCollapse/XCollapse.vue +461 -461
- package/src/base-client/components/common/XInput/XInput.vue +147 -147
- package/src/base-client/components/common/XReport/XReportHospitalizationDemo.vue +45 -0
- package/src/base-client/components/common/XReportGrid/XReportTrGroup.vue +824 -824
- package/src/base-client/components/common/XTable/XTable.vue +1610 -1610
- package/src/base-client/components/common/XTimeline/XTimeline.vue +454 -454
- package/src/base-client/components/his/XCharge/XCharge.vue +244 -86
- package/src/base-client/components/his/XCharge/XChargeDemo.vue +99 -3
- package/src/base-client/components/his/XCharge/testConfig.js +439 -0
- package/src/base-client/components/his/XHisEditor/XHisEditor.vue +705 -705
- package/src/base-client/components/his/XList/XList.vue +829 -829
- package/src/base-client/components/his/XTitle/XTitle.vue +16 -0
- package/src/base-client/components/his/threeTestOrders/editor.vue +113 -113
- package/src/pages/userInfoDetailManage/ExceptionRecordQuery/index.vue +45 -45
- package/src/router/async/router.map.js +132 -129
- package/src-base-client/components/his/XCharge/README.md +0 -0
- package/src-base-client/components/his/XCharge/XCharge.vue +0 -0
@@ -1,5 +1,10 @@
|
|
1
1
|
<template>
|
2
2
|
<div class="xcharge-wrapper">
|
3
|
+
<!-- 标题 -->
|
4
|
+
<x-title :title="config.title || '结算-收费方式'" :dot="true" />
|
5
|
+
<!-- 分割线 -->
|
6
|
+
<div class="top-divider"></div>
|
7
|
+
|
3
8
|
<!-- 顶部金额信息区(表单行风格,宽度固定,每行4个) -->
|
4
9
|
<a-row :gutter="0" class="amount-info">
|
5
10
|
<a-col v-for="item in config.amountFields" :key="item.field" :span="6" class="form-row">
|
@@ -13,50 +18,60 @@
|
|
13
18
|
</a-col>
|
14
19
|
</a-row>
|
15
20
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
<div class="
|
21
|
+
<!-- 支付方式选择区和支付详情容器 -->
|
22
|
+
<div class="payment-container">
|
23
|
+
<!-- 支付方式选择区 -->
|
24
|
+
<div class="payment-methods">
|
25
|
+
<div
|
26
|
+
v-for="method in config.paymentMethods"
|
27
|
+
:key="method.key"
|
28
|
+
:class="['payment-option', {
|
29
|
+
active: isMixedPaymentEnabled ? selectedMethods.includes(method.key) : selectedMethod === method.key
|
30
|
+
}]"
|
31
|
+
@click="isMixedPaymentEnabled ? toggleMethod(method.key) : selectMethod(method.key)"
|
32
|
+
>
|
33
|
+
<!-- 图标区域 -->
|
34
|
+
<div class="payment-icon" :class="{ multiple: getMethodIcons(method).length > 1 }">
|
35
|
+
<template v-if="getMethodIcons(method).length">
|
36
|
+
<img
|
37
|
+
v-for="(src, idx) in getMethodIcons(method)"
|
38
|
+
:key="idx"
|
39
|
+
:src="src"
|
40
|
+
:alt="method.label"
|
41
|
+
class="icon-image"
|
42
|
+
/>
|
43
|
+
</template>
|
44
|
+
<div v-else class="icon-placeholder">{{ method.label.charAt(0) }}</div>
|
45
|
+
</div>
|
46
|
+
<!-- 标签区域 -->
|
47
|
+
<div class="payment-label">{{ method.label }}</div>
|
48
|
+
<!-- 选中指示器 -->
|
30
49
|
<div v-if="isMixedPaymentEnabled && selectedMethods.includes(method.key)" class="selected-indicator">✓</div>
|
31
50
|
</div>
|
32
|
-
</
|
33
|
-
</div>
|
51
|
+
</div>
|
34
52
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
/>
|
53
|
+
<!-- 支付详情(同一行展示,仅在混合支付手动模式且选择方式>1时出现) -->
|
54
|
+
<div v-if="isMixedPaymentManualMode && selectedMethods.length > 1" class="mixed-payment-section simple">
|
55
|
+
<div class="payment-operation-row">
|
56
|
+
<div class="payment-inline">
|
57
|
+
<div v-for="method in selectedMethods" :key="method" class="inline-field">
|
58
|
+
<label class="form-label">{{ getAmountLabel(method) }}</label>
|
59
|
+
<a-input
|
60
|
+
v-model="paymentAmounts[method]"
|
61
|
+
type="number"
|
62
|
+
placeholder="请输入金额"
|
63
|
+
class="form-input"
|
64
|
+
@change="updatePaymentAmount(method, $event)"
|
65
|
+
/>
|
66
|
+
</div>
|
50
67
|
</div>
|
51
68
|
</div>
|
52
69
|
</div>
|
53
70
|
</div>
|
54
71
|
|
55
|
-
<a-divider/>
|
56
|
-
|
57
72
|
<!-- 底部金额和操作区(表单行风格,宽度固定) -->
|
58
73
|
<a-row :gutter="0" class="bottom-info">
|
59
|
-
<a-col v-for="item in config.bottomFields" :key="item.field" :span="
|
74
|
+
<a-col v-for="item in config.bottomFields" :key="item.field" :span="6" class="form-row">
|
60
75
|
<label class="form-label">{{ item.label }}</label>
|
61
76
|
<a-input
|
62
77
|
v-model="data[item.field]"
|
@@ -82,9 +97,13 @@
|
|
82
97
|
|
83
98
|
<script>
|
84
99
|
import { getConfigByName, runLogic } from '@vue2-client/services/api/common'
|
100
|
+
import XTitle from '../XTitle/XTitle.vue'
|
85
101
|
|
86
102
|
export default {
|
87
103
|
name: 'XCharge',
|
104
|
+
components: {
|
105
|
+
XTitle
|
106
|
+
},
|
88
107
|
props: {
|
89
108
|
queryParamsName: {
|
90
109
|
type: String,
|
@@ -98,11 +117,13 @@ export default {
|
|
98
117
|
data () {
|
99
118
|
return {
|
100
119
|
config: {
|
120
|
+
title: '', // 标题配置
|
101
121
|
amountFields: [],
|
102
122
|
paymentMethods: [],
|
103
123
|
bottomFields: [],
|
104
|
-
actionButtons: [],
|
105
|
-
enableMixedPayment: false // 默认关闭混合支付
|
124
|
+
actionButtons: [], // 操作按钮
|
125
|
+
enableMixedPayment: false, // 默认关闭混合支付
|
126
|
+
mixedPaymentMode: 'manual' // 混合支付模式:'manual'手动输入,'auto'自动模式
|
106
127
|
},
|
107
128
|
data: {},
|
108
129
|
selectedMethod: '', // 保持向后兼容
|
@@ -110,14 +131,13 @@ export default {
|
|
110
131
|
paymentAmounts: {}, // 各支付方式的金额
|
111
132
|
// 事件名配置(可通过配置覆盖)
|
112
133
|
eventNames: {
|
113
|
-
method: 'method',
|
114
|
-
methods: 'methods',
|
115
|
-
totalPaymentAmount: 'totalPaymentAmount',
|
116
|
-
action: 'action',
|
117
|
-
// 新增:单个支付方式金额变更事件
|
118
|
-
paymentAmountChange: 'paymentAmountChange'
|
134
|
+
method: 'method', // 单选支付方式变更事件
|
135
|
+
methods: 'methods', // 多选支付方式变更事件
|
136
|
+
totalPaymentAmount: 'totalPaymentAmount', // 总支付金额变更事件
|
137
|
+
action: 'action', // 操作按钮点击事件
|
138
|
+
paymentAmountChange: 'paymentAmountChange' // 新增:单个支付方式金额变更事件
|
119
139
|
},
|
120
|
-
hasInitialized: false
|
140
|
+
hasInitialized: false // 是否已初始化
|
121
141
|
}
|
122
142
|
},
|
123
143
|
emits: ['init'],
|
@@ -126,6 +146,14 @@ export default {
|
|
126
146
|
isMixedPaymentEnabled () {
|
127
147
|
return this.config && this.config.enableMixedPayment === true
|
128
148
|
},
|
149
|
+
// 是否为混合支付自动模式
|
150
|
+
isMixedPaymentAutoMode () {
|
151
|
+
return this.isMixedPaymentEnabled && this.config.mixedPaymentMode === 'auto'
|
152
|
+
},
|
153
|
+
// 是否为混合支付手动模式
|
154
|
+
isMixedPaymentManualMode () {
|
155
|
+
return this.isMixedPaymentEnabled && this.config.mixedPaymentMode === 'manual'
|
156
|
+
},
|
129
157
|
// 预计算:金额标签映射(仅基于 paymentMethods 配置)
|
130
158
|
amountLabelMap () {
|
131
159
|
const map = {}
|
@@ -135,7 +163,7 @@ export default {
|
|
135
163
|
const key = m && m.key
|
136
164
|
const label = m && m.label
|
137
165
|
if (!key) return
|
138
|
-
map[key] =
|
166
|
+
map[key] = `${label || key}金额`
|
139
167
|
})
|
140
168
|
return map
|
141
169
|
}
|
@@ -147,6 +175,44 @@ export default {
|
|
147
175
|
if (hasParam) this.hasInitialized = true
|
148
176
|
},
|
149
177
|
methods: {
|
178
|
+
// -------- 金额精度工具:使用「分」进行运算,避免浮点精度问题 --------
|
179
|
+
// 解析金额为分(整数);非法输入按 0 处理
|
180
|
+
parseAmountToCents (value) {
|
181
|
+
if (value === null || value === undefined || value === '') return 0
|
182
|
+
// 允许字符串或数字,移除非数字与小数点字符
|
183
|
+
const str = String(value).replace(/[^0-9.-]/g, '')
|
184
|
+
if (str === '' || str === '-' || isNaN(Number(str))) return 0
|
185
|
+
// 四舍五入到分
|
186
|
+
return Math.round(Number(str) * 100)
|
187
|
+
},
|
188
|
+
// 将分格式化为金额(保留两位小数)
|
189
|
+
formatCentsToAmount (cents) {
|
190
|
+
const v = Number(cents) / 100
|
191
|
+
// 使用 toFixed 返回字符串,再转为数字,避免 0.30000000000004
|
192
|
+
return Number(v.toFixed(2))
|
193
|
+
},
|
194
|
+
// 规范化金额:返回保留两位小数的数字
|
195
|
+
normalizeAmount (value) {
|
196
|
+
return this.formatCentsToAmount(this.parseAmountToCents(value))
|
197
|
+
},
|
198
|
+
// 解析多图标:支持 method.icons 数组;否则回退到单个 icon
|
199
|
+
getMethodIcons (method) {
|
200
|
+
if (!method) return []
|
201
|
+
const icons = Array.isArray(method.icons) ? method.icons : (method.icon ? [method.icon] : [])
|
202
|
+
const resolved = icons.map(n => {
|
203
|
+
if (!n || typeof n !== 'string') return ''
|
204
|
+
if (n.startsWith('/') || n.startsWith('http')) return n
|
205
|
+
const baseName = n.replace(/\.(png|jpg|jpeg|webp|svg)$/i, '')
|
206
|
+
// 仅使用 @vue2-client 资源解析
|
207
|
+
try { return require('@vue2-client/assets/img/paymentMethod/' + baseName + '.png') } catch (e) {}
|
208
|
+
try { return require('@vue2-client/assets/img/paymentMethod/' + baseName + '.jpg') } catch (e) {}
|
209
|
+
try { return require('@vue2-client/assets/img/paymentMethod/' + baseName + '.jpeg') } catch (e) {}
|
210
|
+
try { return require('@vue2-client/assets/img/paymentMethod/' + baseName + '.webp') } catch (e) {}
|
211
|
+
try { return require('@vue2-client/assets/img/paymentMethod/' + baseName + '.svg') } catch (e) {}
|
212
|
+
return ''
|
213
|
+
}).filter(Boolean)
|
214
|
+
return resolved
|
215
|
+
},
|
150
216
|
// 同步 data 中的 selectedMethods / paymentAmounts 到本地状态;并补回缺失的 data 字段
|
151
217
|
hydrateFromData () {
|
152
218
|
const incomingMethods = Array.isArray(this.data && this.data.selectedMethods) ? this.data.selectedMethods : undefined
|
@@ -231,17 +297,16 @@ export default {
|
|
231
297
|
const method = this.config.paymentMethods.find(m => m.key === methodKey)
|
232
298
|
return method ? method.label : methodKey
|
233
299
|
},
|
234
|
-
//
|
300
|
+
// 获取支付金额字段标签(优先使用映射,否则回退为“{label}金额”)
|
235
301
|
getAmountLabel (methodKey) {
|
236
302
|
const mapped = (this.config.paymentAmountLabels && this.config.paymentAmountLabels[methodKey]) || ''
|
237
303
|
if (mapped) return mapped
|
238
304
|
const method = this.config.paymentMethods.find(m => m.key === methodKey)
|
239
|
-
if (method && method.amountLabel) return method.amountLabel
|
240
305
|
return `${method ? method.label : methodKey}金额`
|
241
306
|
},
|
242
307
|
// 新增:更新支付金额
|
243
308
|
updatePaymentAmount (methodKey, event) {
|
244
|
-
const amount =
|
309
|
+
const amount = this.normalizeAmount(event && event.target ? event.target.value : event)
|
245
310
|
this.$set(this.paymentAmounts, methodKey, amount)
|
246
311
|
if (!this.data.paymentAmounts || typeof this.data.paymentAmounts !== 'object') this.$set(this.data, 'paymentAmounts', {})
|
247
312
|
this.$set(this.data.paymentAmounts, methodKey, amount)
|
@@ -251,12 +316,31 @@ export default {
|
|
251
316
|
},
|
252
317
|
// 新增:计算总支付金额
|
253
318
|
calculateTotalPayment () {
|
254
|
-
const
|
255
|
-
return
|
319
|
+
const totalCents = Object.values(this.paymentAmounts).reduce((sumCents, amount) => {
|
320
|
+
return sumCents + this.parseAmountToCents(amount)
|
256
321
|
}, 0)
|
322
|
+
const total = this.formatCentsToAmount(totalCents)
|
257
323
|
this.data.totalPaymentAmount = total
|
258
324
|
this.$emit(this.eventNames.totalPaymentAmount, total)
|
259
325
|
},
|
326
|
+
// 新增:设置支付金额(由外部调用)
|
327
|
+
setPaymentAmounts (amounts) {
|
328
|
+
if (!this.isMixedPaymentEnabled || !amounts || typeof amounts !== 'object') return
|
329
|
+
// 更新本地状态
|
330
|
+
Object.keys(amounts).forEach(method => {
|
331
|
+
const normalized = this.normalizeAmount(amounts[method])
|
332
|
+
this.$set(this.paymentAmounts, method, normalized)
|
333
|
+
})
|
334
|
+
// 更新数据模型
|
335
|
+
if (!this.data.paymentAmounts || typeof this.data.paymentAmounts !== 'object') {
|
336
|
+
this.$set(this.data, 'paymentAmounts', {})
|
337
|
+
}
|
338
|
+
Object.keys(amounts).forEach(method => {
|
339
|
+
const normalized = this.normalizeAmount(amounts[method])
|
340
|
+
this.$set(this.data.paymentAmounts, method, normalized)
|
341
|
+
})
|
342
|
+
this.calculateTotalPayment()
|
343
|
+
},
|
260
344
|
getConfig (configName, param) {
|
261
345
|
if (configName) {
|
262
346
|
console.log('configName', configName)
|
@@ -268,11 +352,13 @@ export default {
|
|
268
352
|
return
|
269
353
|
}
|
270
354
|
this.config = {
|
355
|
+
title: res.title || '', // 标题配置
|
271
356
|
amountFields: res.amountFields || [],
|
272
357
|
paymentMethods: res.paymentMethods || [],
|
273
358
|
bottomFields: res.bottomFields || [],
|
274
359
|
actionButtons: res.actionButtons || [],
|
275
|
-
enableMixedPayment: res.enableMixedPayment === true
|
360
|
+
enableMixedPayment: res.enableMixedPayment === true,
|
361
|
+
mixedPaymentMode: res.mixedPaymentMode || 'manual' // 默认手动模式
|
276
362
|
}
|
277
363
|
// 事件名覆盖(fronImport风格)
|
278
364
|
if (res.eventNames && typeof res.eventNames === 'object') {
|
@@ -340,14 +426,14 @@ export default {
|
|
340
426
|
// 使用默认数据
|
341
427
|
useDefaultData () {
|
342
428
|
this.data = {
|
343
|
-
f_amount:
|
429
|
+
f_amount: 0,
|
344
430
|
f_insurance_amount: 0,
|
345
|
-
f_self_amount:
|
346
|
-
f_balance:
|
431
|
+
f_self_amount: 0,
|
432
|
+
f_balance: 0,
|
347
433
|
out_of_pocket_amount: 0,
|
348
434
|
biscount_amount: 0,
|
349
435
|
billing_amount: 0,
|
350
|
-
received:
|
436
|
+
received: 0,
|
351
437
|
change: 0
|
352
438
|
}
|
353
439
|
},
|
@@ -399,10 +485,14 @@ export default {
|
|
399
485
|
<style scoped>
|
400
486
|
.xcharge-wrapper {
|
401
487
|
background: #fff;
|
402
|
-
padding:
|
488
|
+
padding: 12px;
|
403
489
|
border-radius: 8px;
|
404
490
|
}
|
405
491
|
|
492
|
+
.charge-title {
|
493
|
+
margin-bottom: 16px;
|
494
|
+
}
|
495
|
+
|
406
496
|
.amount-info {
|
407
497
|
margin-bottom: 20px;
|
408
498
|
display: flex;
|
@@ -410,26 +500,34 @@ export default {
|
|
410
500
|
row-gap: 16px;
|
411
501
|
}
|
412
502
|
|
503
|
+
/* 顶部分割线 */
|
504
|
+
.top-divider {
|
505
|
+
height: 2px;
|
506
|
+
opacity: 1;
|
507
|
+
background: #0057FE;
|
508
|
+
margin-top: 8px;
|
509
|
+
margin-bottom: 12px;
|
510
|
+
}
|
511
|
+
|
413
512
|
.form-row {
|
414
513
|
display: flex;
|
415
514
|
align-items: center;
|
416
|
-
margin-bottom: 30px;
|
417
515
|
}
|
418
516
|
|
419
517
|
.form-label {
|
420
518
|
width: 100px;
|
421
|
-
font-size:
|
519
|
+
font-size: 16px;
|
422
520
|
color: #333;
|
423
521
|
font-weight: bold;
|
424
|
-
text-align:
|
522
|
+
text-align: center;
|
425
523
|
letter-spacing: 1px;
|
426
524
|
flex-shrink: 0;
|
427
525
|
}
|
428
526
|
|
429
527
|
.form-input {
|
430
|
-
width:
|
431
|
-
height:
|
432
|
-
font-size:
|
528
|
+
width: 200px;
|
529
|
+
height: 30px;
|
530
|
+
font-size: 16px;
|
433
531
|
border-radius: 8px;
|
434
532
|
border: 1.5px solid #dcdfe6;
|
435
533
|
background: #fff;
|
@@ -442,44 +540,103 @@ export default {
|
|
442
540
|
background: #f5f5f5;
|
443
541
|
}
|
444
542
|
|
543
|
+
/* 支付容器 */
|
544
|
+
.payment-container {
|
545
|
+
border: 1px solid #e4e7ed;
|
546
|
+
border-radius: 8px;
|
547
|
+
margin-bottom: 10px;
|
548
|
+
height: 464px;
|
549
|
+
padding: 112px 31px 0px;
|
550
|
+
}
|
551
|
+
|
445
552
|
.payment-methods {
|
446
553
|
display: flex;
|
447
554
|
justify-content: space-around;
|
448
|
-
margin:
|
555
|
+
margin: 0 0 16px 0;
|
556
|
+
gap: 20px;
|
449
557
|
}
|
450
558
|
|
451
|
-
.payment-
|
452
|
-
width:
|
453
|
-
height:
|
454
|
-
margin: 0 16px;
|
559
|
+
.payment-option {
|
560
|
+
width: 220px;
|
561
|
+
height: 200px;
|
455
562
|
display: flex;
|
563
|
+
flex-direction: column;
|
456
564
|
align-items: center;
|
457
565
|
justify-content: center;
|
458
|
-
background: #f7f8fa;
|
459
566
|
border: 1.5px solid #e4e7ed;
|
460
|
-
color: #333;
|
461
|
-
font-weight: bold;
|
462
|
-
font-size: 24px;
|
463
|
-
transition: all 0.2s;
|
464
|
-
box-shadow: none;
|
465
567
|
border-radius: 12px;
|
568
|
+
cursor: pointer;
|
569
|
+
transition: all 0.2s;
|
570
|
+
position: relative;
|
571
|
+
}
|
572
|
+
|
573
|
+
.payment-option:hover {
|
574
|
+
background: #0057FE;
|
575
|
+
border-color: #0057FE;
|
576
|
+
box-shadow: 0 2px 8px rgba(0, 87, 254, 0.2);
|
577
|
+
}
|
578
|
+
|
579
|
+
.payment-option.active {
|
580
|
+
background: #587EDF;
|
581
|
+
border-color: #587EDF;
|
582
|
+
color: #fff;
|
466
583
|
}
|
467
584
|
|
468
|
-
.payment-
|
469
|
-
background: #409eff;
|
470
|
-
border-color: #409eff;
|
585
|
+
.payment-option:hover .payment-label {
|
471
586
|
color: #fff;
|
472
587
|
}
|
473
588
|
|
474
|
-
.
|
589
|
+
.payment-icon {
|
590
|
+
position: relative;
|
591
|
+
width: 65px;
|
592
|
+
height: 65px;
|
593
|
+
margin-bottom: 12px;
|
594
|
+
display: flex;
|
595
|
+
align-items: center;
|
596
|
+
justify-content: center;
|
597
|
+
}
|
598
|
+
|
599
|
+
.payment-icon.multiple {
|
600
|
+
gap: 12px;
|
601
|
+
}
|
602
|
+
|
603
|
+
.icon-image {
|
604
|
+
width: 65px;
|
605
|
+
height: 65px;
|
606
|
+
object-fit: contain;
|
607
|
+
border-radius: 8px;
|
608
|
+
}
|
609
|
+
|
610
|
+
.icon-placeholder {
|
611
|
+
width: 100%;
|
612
|
+
height: 100%;
|
613
|
+
background: #ddd;
|
614
|
+
border-radius: 8px;
|
615
|
+
display: flex;
|
616
|
+
align-items: center;
|
617
|
+
justify-content: center;
|
475
618
|
font-size: 24px;
|
476
619
|
font-weight: bold;
|
620
|
+
color: #666;
|
621
|
+
}
|
622
|
+
|
623
|
+
/* 移除徽章样式:模板已不再使用 */
|
624
|
+
|
625
|
+
.payment-label {
|
626
|
+
font-size: 36px;
|
627
|
+
font-weight: 500;
|
628
|
+
text-align: center;
|
629
|
+
color: #333;
|
630
|
+
}
|
631
|
+
|
632
|
+
.payment-option.active .payment-label {
|
633
|
+
color: #fff;
|
477
634
|
}
|
478
635
|
|
479
636
|
.selected-indicator {
|
480
637
|
position: absolute;
|
481
|
-
top:
|
482
|
-
right:
|
638
|
+
top: 12px;
|
639
|
+
right: 12px;
|
483
640
|
background: #52c41a;
|
484
641
|
color: #fff;
|
485
642
|
border-radius: 50%;
|
@@ -493,11 +650,10 @@ export default {
|
|
493
650
|
}
|
494
651
|
|
495
652
|
.mixed-payment-section {
|
496
|
-
margin:
|
497
|
-
padding:
|
498
|
-
background:
|
499
|
-
border
|
500
|
-
border: 1px solid #e9ecef;
|
653
|
+
margin: 0;
|
654
|
+
padding: 0;
|
655
|
+
background: transparent;
|
656
|
+
border: none;
|
501
657
|
}
|
502
658
|
|
503
659
|
.mixed-payment-section.simple {
|
@@ -510,7 +666,7 @@ export default {
|
|
510
666
|
border: none;
|
511
667
|
background: transparent;
|
512
668
|
padding: 0;
|
513
|
-
margin
|
669
|
+
margin: 0;
|
514
670
|
}
|
515
671
|
|
516
672
|
.section-title {
|
@@ -560,11 +716,11 @@ export default {
|
|
560
716
|
|
561
717
|
.payment-inline {
|
562
718
|
display: flex;
|
563
|
-
flex-wrap:
|
719
|
+
flex-wrap: wrap;
|
564
720
|
align-items: center;
|
565
721
|
justify-content: center;
|
566
722
|
column-gap: 32px;
|
567
|
-
|
723
|
+
row-gap: 16px;
|
568
724
|
}
|
569
725
|
|
570
726
|
.inline-field {
|
@@ -576,6 +732,7 @@ export default {
|
|
576
732
|
|
577
733
|
.payment-inline .form-label {
|
578
734
|
width: auto;
|
735
|
+
font-size: 16px;
|
579
736
|
}
|
580
737
|
|
581
738
|
.pay-shortcut {
|
@@ -607,4 +764,5 @@ export default {
|
|
607
764
|
height: 38px;
|
608
765
|
min-width: 90px;
|
609
766
|
}
|
767
|
+
|
610
768
|
</style>
|
@@ -10,22 +10,96 @@ export default {
|
|
10
10
|
methods: [],
|
11
11
|
total: 0,
|
12
12
|
lastAmountChange: null,
|
13
|
-
lastAction: null
|
13
|
+
lastAction: null,
|
14
|
+
currentMode: 'manual' // 当前模式:manual, auto, single
|
14
15
|
}
|
15
16
|
},
|
16
17
|
methods: {
|
17
18
|
onMethod (value) { console.log('【事件】单选支付方式(method):', value) },
|
18
|
-
onMethods (values) {
|
19
|
+
onMethods (values) {
|
20
|
+
console.log('【事件】多选支付方式(methods):', values);
|
21
|
+
this.methods = values
|
22
|
+
// 在自动模式下,由外部决定金额分配
|
23
|
+
if (this.currentMode === 'auto') {
|
24
|
+
this.autoDistributeAmounts(values)
|
25
|
+
}
|
26
|
+
},
|
19
27
|
onTotal (total) { console.log('【事件】合计金额变更(totalPaymentAmount):', total); this.total = total },
|
20
28
|
onAmountChange (payload) { console.log('【事件】单个方式金额变更(paymentAmountChange):', payload, '→ 方式:', payload.method, ' 金额:', payload.amount); this.lastAmountChange = payload },
|
21
|
-
onAction (payload) { console.log('【事件】操作(action):', payload); this.lastAction = payload }
|
29
|
+
onAction (payload) { console.log('【事件】操作(action):', payload); this.lastAction = payload },
|
30
|
+
switchMode (mode) {
|
31
|
+
this.currentMode = mode
|
32
|
+
// 根据模式切换配置
|
33
|
+
switch (mode) {
|
34
|
+
case 'manual':
|
35
|
+
this.queryParamsName = 'testChargeConfig'
|
36
|
+
break
|
37
|
+
case 'auto':
|
38
|
+
this.queryParamsName = 'testAutoMixedChargeConfig'
|
39
|
+
break
|
40
|
+
case 'single':
|
41
|
+
this.queryParamsName = 'testSingleChargeConfig'
|
42
|
+
break
|
43
|
+
}
|
44
|
+
},
|
45
|
+
getModeText (mode) {
|
46
|
+
const modeMap = {
|
47
|
+
'manual': '混合支付-手动模式',
|
48
|
+
'auto': '混合支付-自动模式',
|
49
|
+
'single': '单选模式'
|
50
|
+
}
|
51
|
+
return modeMap[mode] || mode
|
52
|
+
},
|
53
|
+
// 外部金额分配逻辑(示例:平均分配)
|
54
|
+
autoDistributeAmounts (selectedMethods) {
|
55
|
+
if (!selectedMethods || selectedMethods.length === 0) return
|
56
|
+
|
57
|
+
// 示例:假设总金额为100,平均分配
|
58
|
+
const totalAmount = 100
|
59
|
+
const amountPerMethod = totalAmount / selectedMethods.length
|
60
|
+
|
61
|
+
const amounts = {}
|
62
|
+
selectedMethods.forEach(method => {
|
63
|
+
amounts[method] = amountPerMethod
|
64
|
+
})
|
65
|
+
|
66
|
+
// 调用组件的setPaymentAmounts方法
|
67
|
+
this.$refs.xCharge.setPaymentAmounts(amounts)
|
68
|
+
}
|
22
69
|
}
|
23
70
|
}
|
24
71
|
</script>
|
25
72
|
|
26
73
|
<template>
|
27
74
|
<div class="demo">
|
75
|
+
<!-- 模式切换按钮 -->
|
76
|
+
<div class="mode-switcher">
|
77
|
+
<h3>XCharge 组件测试 - 混合支付模式切换</h3>
|
78
|
+
<div class="mode-buttons">
|
79
|
+
<a-button
|
80
|
+
:type="currentMode === 'manual' ? 'primary' : 'default'"
|
81
|
+
@click="switchMode('manual')"
|
82
|
+
>
|
83
|
+
混合支付-手动模式
|
84
|
+
</a-button>
|
85
|
+
<a-button
|
86
|
+
:type="currentMode === 'auto' ? 'primary' : 'default'"
|
87
|
+
@click="switchMode('auto')"
|
88
|
+
>
|
89
|
+
混合支付-自动模式
|
90
|
+
</a-button>
|
91
|
+
<a-button
|
92
|
+
:type="currentMode === 'single' ? 'primary' : 'default'"
|
93
|
+
@click="switchMode('single')"
|
94
|
+
>
|
95
|
+
单选模式
|
96
|
+
</a-button>
|
97
|
+
</div>
|
98
|
+
<p class="current-mode">当前模式:{{ getModeText(currentMode) }}</p>
|
99
|
+
</div>
|
100
|
+
|
28
101
|
<x-charge
|
102
|
+
ref="xCharge"
|
29
103
|
:queryParamsName="queryParamsName"
|
30
104
|
@method="onMethod"
|
31
105
|
@methods="onMethods"
|
@@ -44,6 +118,28 @@ export default {
|
|
44
118
|
|
45
119
|
<style scoped>
|
46
120
|
.demo { padding: 16px; }
|
121
|
+
.mode-switcher {
|
122
|
+
margin-bottom: 24px;
|
123
|
+
padding: 16px;
|
124
|
+
background: #f8f9fa;
|
125
|
+
border-radius: 8px;
|
126
|
+
border: 1px solid #e9ecef;
|
127
|
+
}
|
128
|
+
.mode-switcher h3 {
|
129
|
+
margin: 0 0 16px 0;
|
130
|
+
color: #333;
|
131
|
+
font-size: 18px;
|
132
|
+
}
|
133
|
+
.mode-buttons {
|
134
|
+
display: flex;
|
135
|
+
gap: 12px;
|
136
|
+
margin-bottom: 12px;
|
137
|
+
}
|
138
|
+
.current-mode {
|
139
|
+
margin: 0;
|
140
|
+
color: #666;
|
141
|
+
font-weight: 500;
|
142
|
+
}
|
47
143
|
.info { margin-top: 16px; color: #333; }
|
48
144
|
.info p { margin: 6px 0; }
|
49
145
|
</style>
|