@uxda/appkit 4.3.6 → 4.3.8

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.
Files changed (135) hide show
  1. package/.eslintrc.mjs +7 -7
  2. package/COMPONENT_USAGE.md +1523 -1523
  3. package/PROJECT_DOCS.md +142 -142
  4. package/README.md +187 -187
  5. package/babel.config.js +12 -12
  6. package/dist/appkit.css +15 -63
  7. package/dist/assets/asset-DcH8Kg-2 +1 -0
  8. package/dist/index.js +259 -806
  9. package/package.json +79 -79
  10. package/project.config.json +15 -15
  11. package/project.tt.json +13 -13
  12. package/rollup.config.mjs +78 -78
  13. package/src/Appkit.ts +72 -72
  14. package/src/balance/api/endpoints.ts +133 -133
  15. package/src/balance/api/index.ts +118 -118
  16. package/src/balance/components/AccountView.vue +770 -770
  17. package/src/balance/components/BalanceCard.vue +210 -210
  18. package/src/balance/components/BalanceReminder.vue +84 -84
  19. package/src/balance/components/ConsumptionFilter.vue +218 -218
  20. package/src/balance/components/ConsumptionRules.vue +68 -68
  21. package/src/balance/components/DateFilter.vue +259 -259
  22. package/src/balance/components/DateRange.vue +111 -111
  23. package/src/balance/components/ListFilter.vue +62 -62
  24. package/src/balance/components/ListFilterPicker.vue +191 -191
  25. package/src/balance/components/PromoterCard.vue +307 -308
  26. package/src/balance/components/SecondBalance.vue +77 -77
  27. package/src/balance/components/Tip.vue +45 -45
  28. package/src/balance/components/index.ts +8 -8
  29. package/src/balance/types.ts +99 -99
  30. package/src/components/bt-cropper/index.vue +730 -730
  31. package/src/components/bt-cropper/utils/calcCropper.js +42 -42
  32. package/src/components/bt-cropper/utils/calcImagePosition.js +23 -23
  33. package/src/components/bt-cropper/utils/calcImageSize.js +37 -37
  34. package/src/components/bt-cropper/utils/calcPointDistance.js +12 -12
  35. package/src/components/bt-cropper/utils/calcRightAndBottom.js +7 -7
  36. package/src/components/bt-cropper/utils/ratio.js +3 -3
  37. package/src/components/bt-cropper/utils/tools.js +25 -25
  38. package/src/components/dd-area/index.vue +225 -225
  39. package/src/components/dd-icon/doc.md +21 -21
  40. package/src/components/dd-icon/index.vue +23 -23
  41. package/src/components/dd-notice-bar/index.vue +78 -78
  42. package/src/components/dd-search/doc.md +34 -34
  43. package/src/components/dd-search/index.vue +168 -168
  44. package/src/components/dd-selector/index.vue +124 -124
  45. package/src/components/dd-skeleton/doc.md +19 -19
  46. package/src/components/dd-skeleton/index.vue +36 -36
  47. package/src/global.ts +6 -6
  48. package/src/index.ts +101 -101
  49. package/src/main.scss +1 -1
  50. package/src/notice/api/endpoints.ts +54 -54
  51. package/src/notice/api/index.ts +121 -121
  52. package/src/notice/components/NoticeBanner.vue +247 -247
  53. package/src/notice/components/NoticeEntry.vue +99 -99
  54. package/src/notice/components/NoticeList.vue +311 -311
  55. package/src/notice/components/NoticeList2.vue +400 -399
  56. package/src/notice/components/NoticePopup.vue +163 -163
  57. package/src/notice/components/index.ts +6 -6
  58. package/src/notice/components/useCommonList.ts +86 -87
  59. package/src/notice/components/useNotice.ts +35 -35
  60. package/src/notice/index.ts +1 -1
  61. package/src/notice/types.ts +25 -25
  62. package/src/payment/api/config.ts +7 -7
  63. package/src/payment/api/endpoints.ts +96 -98
  64. package/src/payment/api/index.ts +107 -108
  65. package/src/payment/components/AmountPicker.vue +90 -90
  66. package/src/payment/components/RechargeResult.vue +69 -68
  67. package/src/payment/components/RechargeView.vue +191 -191
  68. package/src/payment/components/RightsPicker.vue +105 -105
  69. package/src/payment/components/TradeView.vue +363 -571
  70. package/src/payment/components/UserAgreement.vue +234 -234
  71. package/src/payment/components/index.ts +22 -22
  72. package/src/payment/index.ts +5 -5
  73. package/src/payment/services/index.ts +16 -16
  74. package/src/payment/services/invoke-recharge.ts +25 -25
  75. package/src/payment/services/request-payment.ts +130 -132
  76. package/src/payment/types.ts +33 -34
  77. package/src/register/components/SelfRegistration.vue +233 -233
  78. package/src/register/components/index.ts +2 -2
  79. package/src/scenarios/components/SharePoster.vue +364 -364
  80. package/src/scenarios/components/index.ts +2 -2
  81. package/src/scenarios/components/poster-paste.vue +93 -93
  82. package/src/scenarios/components/share-poster.md +273 -273
  83. package/src/shared/components/AppDrawer.vue +53 -53
  84. package/src/shared/components/AppVerify.vue +128 -137
  85. package/src/shared/components/DeviceVersion.vue +78 -78
  86. package/src/shared/components/EmptyView.vue +33 -33
  87. package/src/shared/components/OcrBusinessLicense.vue +137 -120
  88. package/src/shared/components/OcrIcon.vue +229 -267
  89. package/src/shared/components/PageHeader.vue +84 -84
  90. package/src/shared/components/index.ts +8 -10
  91. package/src/shared/composables/index.ts +9 -10
  92. package/src/shared/composables/useAmount.ts +46 -46
  93. package/src/shared/composables/useCountdown.ts +46 -46
  94. package/src/shared/composables/useCrypto.ts +76 -76
  95. package/src/shared/composables/useDeviceEnv.ts +26 -26
  96. package/src/shared/composables/useDragBox.ts +97 -97
  97. package/src/shared/composables/useEncode.ts +43 -43
  98. package/src/shared/composables/useLogger.ts +144 -144
  99. package/src/shared/composables/useSafeArea.ts +46 -46
  100. package/src/shared/composables/useTabbar.ts +24 -24
  101. package/src/shared/composables/useUpload.ts +61 -106
  102. package/src/shared/composables/useValidator.ts +32 -32
  103. package/src/shared/composables/useWxAuth.ts +48 -48
  104. package/src/shared/http/Http.ts +148 -149
  105. package/src/shared/http/index.ts +1 -1
  106. package/src/shared/http/types.ts +163 -163
  107. package/src/shared/index.ts +9 -9
  108. package/src/shared/tracking/directives/index.ts +40 -40
  109. package/src/shared/tracking/examples/page-tracking-template.vue +27 -27
  110. package/src/shared/tracking/tracking-sdk.ts +1 -0
  111. package/src/shared/weixin/index.ts +9 -9
  112. package/src/shared/weixin/jssdk.ts +103 -104
  113. package/src/shared/weixin/payment.ts +38 -38
  114. package/src/styles/vars.scss +3 -3
  115. package/src/user/api/endpoints.ts +17 -17
  116. package/src/user/api/index.ts +123 -123
  117. package/src/user/components/LoginSetting.vue +114 -114
  118. package/src/user/components/UserAuth.vue +218 -218
  119. package/src/user/components/UserBinding.vue +277 -277
  120. package/src/user/components/UserBindingSuccess.vue +80 -80
  121. package/src/user/components/UserEntry.vue +139 -139
  122. package/src/user/components/UserFeedback.vue +427 -428
  123. package/src/user/components/UserFeedbackEntry.vue +175 -175
  124. package/src/user/components/UserHeadCrop.vue +65 -65
  125. package/src/user/components/UserInfo.vue +709 -711
  126. package/src/user/components/UserResourceEmpty.vue +75 -75
  127. package/src/user/components/index.ts +23 -23
  128. package/src/user/index.ts +1 -1
  129. package/src/utils/utils.ts +33 -33
  130. package/tsconfig.json +30 -30
  131. package/types/global.d.ts +22 -24
  132. package/types/vue.d.ts +10 -10
  133. package/src/shared/components/OcrBank.vue +0 -202
  134. package/src/shared/components/OcrInvoice.vue +0 -218
  135. package/src/shared/composables/useCompress.ts +0 -64
@@ -1,571 +1,363 @@
1
- <template>
2
- <view class="view recharge-view2">
3
- <view class="flex-grow">
4
- <rights-picker
5
- :items="amounts"
6
- :selected="state.selected"
7
- @change="onAmountSelect"
8
- />
9
- <div class="bean-buy" v-if="amounts[state.selected]">
10
- <div class="left">
11
- <div class="title">使用云豆支付</div>
12
- <div class="amount" v-if="!selectBean || isCombinedPayment">
13
- 余额 {{ formatAmount(balance || 0) }}
14
- </div>
15
- <div class="amount" v-else>
16
- 扣减后余额
17
- {{ formatAmount(balance - amounts[state.selected].paymentAmount) }}
18
- </div>
19
- </div>
20
- <div class="right" @click="selectBean = !selectBean">
21
- <div class="amount">
22
- -{{ formatAmount(amounts[state.selected].paymentAmount || 0) }}
23
- </div>
24
- <img
25
- class="icon"
26
- :src="
27
- selectBean
28
- ? 'https://cdn.ddjf.com/static/images/appkit/select.svg'
29
- : 'https://cdn.ddjf.com/static/images/appkit/not-select.svg'
30
- "
31
- />
32
- </div>
33
-
34
- <div class="balance-warning" v-if="isCombinedPayment">
35
- 云豆余额不足,还需额外支付{{ formatAmount(extraPaymentAmount) }}元
36
- </div>
37
- </div>
38
-
39
- <div class="balance-warning-tip" v-if="isCombinedPayment">
40
- 请在支付完成前确保元豆余额不被消耗,否则本次权益可能购买失败
41
- </div>
42
-
43
- <slot name="banner"></slot>
44
- </view>
45
-
46
- <view class="amount-footer">
47
- <view class="agreement" v-if="!selectBean || isCombinedPayment">
48
- <nut-checkbox v-model="state.agreed"
49
- >我已阅读并同意<a
50
- v-track-click
51
- class="link inline"
52
- @click="onAgreementLinkClick"
53
- >《大道云平台云豆充值服务协议》</a
54
- ></nut-checkbox
55
- >
56
- </view>
57
- <div class="buy-amount">
58
- <div class="left">
59
- 待支付:
60
- <span class="amount">
61
- <i>¥</i>{{ formatAmount(currentAmount) }}
62
- </span>
63
- </div>
64
- <nut-button
65
- block
66
- shape="square"
67
- :loading="state.buttonLoading"
68
- v-track-click
69
- @click="onPayClick"
70
- class="recharge-button"
71
- >购买</nut-button
72
- >
73
- </div>
74
- </view>
75
- <nut-dialog
76
- title="确认购买"
77
- custom-class="trade-dialog"
78
- v-model:visible="showDialog"
79
- @cancel="showDialog = !showDialog"
80
- @ok="beanPay"
81
- >
82
- <template v-if="amounts[state.selected]">
83
- <div class="item">
84
- 云豆扣减:{{
85
- formatAmount(amounts[state.selected].paymentAmount || 0)
86
- }}
87
- </div>
88
- <div class="item">
89
- 权益增加:{{
90
- formatAmount(amounts[state.selected].priceRightNum || 0)
91
- }}笔
92
- </div>
93
- <div class="item">
94
- 扣减后云豆余额:{{
95
- formatAmount(balance - amounts[state.selected].paymentAmount)
96
- }}
97
- </div>
98
- </template>
99
- </nut-dialog>
100
- </view>
101
- </template>
102
-
103
- <script lang="ts" setup>
104
- import { computed, onMounted, reactive, ref } from "vue";
105
- import RightsPicker, { Amount } from "./RightsPicker.vue";
106
- import { endpoints, useHttp } from "../api";
107
- import { endpoints as balanceEndpoints } from "../../balance/api";
108
- import { requestBrandWCPayByBean, requestPaymentByBean } from "../services";
109
- import Taro, { showToast, useRouter, showModal } from "@tarojs/taro";
110
- import { useAmount } from "../../shared/composables/useAmount";
111
- import { isWechat } from "../../shared/composables/useDeviceEnv";
112
-
113
- // 充值用户界面
114
- // 配置了必须的属性后
115
- // 自动获取支付套餐包列表
116
- // 并发起微信支付
117
- export interface RechargeViewProps {
118
- /**
119
- * header头中的appcode,一般情况下与app参数一致,当无应用权限时,此参数未空
120
- **/
121
- headerApp: string;
122
- /**
123
- * 应用
124
- **/
125
- app: string;
126
- /**
127
- * 充值场景
128
- */
129
- // stage?: string, // 这个参数暂时不用
130
- /**
131
- * 租户
132
- */
133
- tenant: string;
134
- /**
135
- * h5支付完成后跳转地址
136
- */
137
- payFinishJumpUrl?: "";
138
- /**
139
- * 所有应用
140
- **/
141
- apps?: string;
142
- }
143
-
144
- const props = defineProps<RechargeViewProps>();
145
- const { formatAmount } = useAmount();
146
- const { params } = useRouter();
147
-
148
- const emit = defineEmits<{
149
- (event: "complete", value: { result: boolean; type: string }): void;
150
- (event: "agree"): void;
151
- }>();
152
-
153
- const state = reactive({
154
- agreed: false,
155
- selected: 0,
156
- // agreementOpen: false,
157
- buttonLoading: false,
158
- });
159
-
160
- const balance = ref<number>(0);
161
- const amounts = ref<Amount[]>([]);
162
- const selectBean = ref<boolean>(false);
163
-
164
- const onAgreementLinkClick = (e) => {
165
- e.preventDefault();
166
- e.stopImmediatePropagation();
167
- emit("agree");
168
- // state.agreementOpen = true
169
- };
170
-
171
- const onAmountSelect = (selected: number) => {
172
- state.selected = selected;
173
- selectBean.value = false;
174
- };
175
-
176
- // 计算额外支付金额(当云豆余额不足时)
177
- const extraPaymentAmount = computed(() => {
178
- if (!selectBean.value || !amounts.value[state.selected]) {
179
- return 0;
180
- }
181
- const paymentAmount = amounts.value[state.selected].paymentAmount || 0;
182
- const currentBalance = balance.value || 0;
183
- return Math.max(0, paymentAmount - currentBalance);
184
- });
185
-
186
- // 计算待支付金额
187
- const currentAmount = computed(() => {
188
- if (!amounts.value[state.selected]) {
189
- return 0;
190
- }
191
-
192
- // 如果选择了云豆支付
193
- if (selectBean.value) {
194
- // 如果余额不足,返回额外需要支付的金额
195
- if (balance.value < amounts.value[state.selected].paymentAmount) {
196
- return extraPaymentAmount.value;
197
- }
198
- // 如果余额充足,返回0(全部用云豆支付)
199
- return 0;
200
- }
201
-
202
- // 如果没有选择云豆支付,返回全额
203
- return amounts.value[state.selected].paymentAmount || 0;
204
- });
205
-
206
- // 判断是否为组合支付
207
- const isCombinedPayment = computed(() => {
208
- return (
209
- selectBean.value &&
210
- amounts.value[state.selected] &&
211
- balance.value < amounts.value[state.selected].paymentAmount
212
- );
213
- });
214
-
215
- onMounted(() => {
216
- const $http = useHttp({ Appcode: props.headerApp, Tenant: props.tenant });
217
- $http
218
- .get<any[]>(endpoints.获取增值权益类目, {
219
- rightCode:
220
- props.app === "corporateStar" ? "riskQueryCompany" : "riskQueryMulti",
221
- })
222
- .then((res: any) => {
223
- balance.value = res.balance;
224
- amounts.value = res.paymentCaseConfigVOS;
225
- });
226
- });
227
-
228
- // 云豆支付对话框
229
- const showDialog = ref<boolean>(false);
230
-
231
- // 处理确认支付(纯云豆支付)
232
- async function beanPay() {
233
- const $http = useHttp({ Appcode: props.headerApp, Tenant: props.tenant });
234
- try {
235
- const response: any = await $http.post(
236
- `/payment/paymentCaseConfig/purchase/${amounts.value[state.selected].id}`
237
- );
238
- if (response) {
239
- showDialog.value = false;
240
- emit("complete", { result: response, type: "bean" });
241
- } else {
242
- showToast({
243
- title: (response as any)?.message || "支付失败",
244
- icon: "none",
245
- });
246
- }
247
- } catch (error: any) {
248
- showToast({
249
- title: error?.message || "支付失败",
250
- icon: "none",
251
- });
252
- }
253
- }
254
-
255
- // 执行微信支付(用于组合支付或纯微信支付)
256
- function proceedWechatPayment() {
257
- if (!state.agreed) {
258
- showToast({
259
- title: "请勾选《大道云平台云豆充值协议》",
260
- icon: "none",
261
- });
262
- return false;
263
- }
264
-
265
- state.buttonLoading = true;
266
-
267
- if (Taro.getEnv() === "WEB") {
268
- if (!isWechat()) {
269
- showToast({
270
- title: "请使用微信浏览器打开",
271
- icon: "none",
272
- });
273
- state.buttonLoading = false;
274
- return false;
275
- }
276
- // 组合支付或纯微信支付:传递caseConfigId和amount,后端会自动处理云豆扣减
277
- requestBrandWCPayByBean({
278
- caseConfigId: amounts.value[state.selected].id,
279
- amount: currentAmount.value,
280
- app: "loankitMp",
281
- tenant: props.tenant,
282
- accountAuthFlag: false,
283
- channelCode: "centergzh",
284
- payFinishJumpUrl: props.payFinishJumpUrl,
285
- fromMini: !!params.from,
286
- useCloudBean: isCombinedPayment.value
287
- })
288
- .then((result) => {
289
- state.buttonLoading = false;
290
- if (typeof result === "boolean" && result) {
291
- window.location.href = props.payFinishJumpUrl as string;
292
- } else {
293
- emit("complete", {
294
- result,
295
- type: isCombinedPayment.value ? "combined" : "wePay",
296
- });
297
- }
298
- })
299
- .catch((error) => {
300
- state.buttonLoading = false;
301
- showToast({
302
- title: error.message || "支付失败",
303
- icon: "none",
304
- });
305
- });
306
- } else {
307
- wx.login({
308
- success({ code }: { code: string }) {
309
- requestPaymentByBean(
310
- {
311
- caseConfigId: amounts.value[state.selected].id,
312
- amount: currentAmount.value,
313
- app: props.app,
314
- tenant: props.tenant,
315
- user: code,
316
- },
317
- props.headerApp
318
- )
319
- .then((result) => {
320
- state.buttonLoading = false;
321
- if (result) {
322
- emit("complete", {
323
- result: true,
324
- type: isCombinedPayment.value ? "combined" : "wePay",
325
- });
326
- }
327
- })
328
- .catch((error) => {
329
- state.buttonLoading = false;
330
- showToast({
331
- title: error.message || "支付失败",
332
- icon: "none",
333
- });
334
- });
335
- },
336
- fail() {
337
- state.buttonLoading = false;
338
- showToast({
339
- title: "登录失败,请重试",
340
- icon: "none",
341
- });
342
- },
343
- });
344
- }
345
- }
346
-
347
- const onPayClick = async () => {
348
- // 用云豆支付(纯云豆支付)
349
- if (selectBean.value && !isCombinedPayment.value) {
350
- showDialog.value = true;
351
- return;
352
- }
353
-
354
- if (isCombinedPayment.value) {
355
- // 检验云豆是否已经改变,改变则刷新选择
356
- const res = await checkBalance()
357
- if (!res) return
358
- }
359
-
360
- // 纯微信支付
361
- proceedWechatPayment();
362
- }
363
-
364
- /**
365
- * 校验余额是否充足
366
- */
367
- async function checkBalance() {
368
- const $http = useHttp()
369
- return new Promise((resolve, reject) => {
370
- state.buttonLoading = true;
371
- $http
372
- .get<any>(balanceEndpoints.获取余额明细, {
373
- app: props.apps,
374
- })
375
- .then((data) => {
376
- state.buttonLoading = false;
377
- if (data.commonAccount < balance.value) {
378
- showModal({
379
- title: '温馨提示',
380
- content: '云豆不足,请刷新后再次确认',
381
- showCancel: false,
382
- confirmText: '刷新',
383
- confirmColor: '#017fff',
384
- success: () => {
385
- balance.value = data.commonAccount;
386
- }
387
- })
388
- resolve(false)
389
-
390
- } else {
391
- resolve(true)
392
- }
393
- }).catch((error) => {
394
- state.buttonLoading = false;
395
- resolve(false)
396
- })
397
- })
398
- }
399
-
400
- </script>
401
-
402
- <style lang="scss">
403
- .recharge-view2 {
404
- height: 100%;
405
- display: flex;
406
- flex-direction: column;
407
- --nut-primary-color: #017fff;
408
-
409
- .flex-grow {
410
- flex-grow: 1;
411
- }
412
-
413
- .bean-buy {
414
- margin: 0 15px;
415
- padding: 10px;
416
- background: #fffbf3;
417
- border-radius: 5px;
418
- display: flex;
419
- justify-content: space-between;
420
- align-items: center;
421
- flex-wrap: wrap;
422
-
423
- .left {
424
- .title {
425
- color: #fd6701;
426
- font-size: 14px;
427
- font-weight: 600;
428
- line-height: 20px;
429
- margin-bottom: 6px;
430
- }
431
-
432
- .amount {
433
- color: #353535;
434
- font-size: 13px;
435
- line-height: 16px;
436
- background-image: url("https://cdn.ddjf.com/static/images/appkit/yundou.png");
437
- background-repeat: no-repeat;
438
- background-size: 16px 16px;
439
- padding-left: 24px;
440
- }
441
- }
442
-
443
- .right {
444
- display: flex;
445
- align-items: center;
446
-
447
- .amount {
448
- color: #353535;
449
- font-size: 15px;
450
- line-height: 20px;
451
- margin-right: 10px;
452
- }
453
-
454
- .icon {
455
- display: block;
456
- width: 16px;
457
- height: 16px;
458
- font-size: 0;
459
- }
460
- }
461
- }
462
-
463
- .balance-warning {
464
- width: 100%;
465
- padding: 8px 10px;
466
- margin-top: 10px;
467
- background: #fdefe6;
468
- border-radius: 5px;
469
- color: #fd6701;
470
- font-size: 12px;
471
-
472
- &-tip {
473
- margin: 10px 26px 0;
474
- color: #666666;
475
- font-size: 10px;
476
- }
477
- }
478
-
479
- .amount-footer {
480
- padding: 10px 0;
481
-
482
- .agreement {
483
- font-size: 12px;
484
- display: flex;
485
- justify-content: center;
486
- align-items: cebter;
487
- height: 40px;
488
- }
489
-
490
- .buy-amount {
491
- display: flex;
492
- justify-content: space-between;
493
- align-items: center;
494
- padding: 0 10px;
495
- border-radius: 0px;
496
- box-shadow: 0px -5px 14px -5px rgba(0, 0, 0, 0.1);
497
-
498
- /* 上边框阴影 */
499
- .left {
500
- width: 70%;
501
- color: #353535;
502
- font-size: 13px;
503
-
504
- .amount {
505
- color: #fd6701;
506
- font-size: 20px;
507
- font-weight: 600;
508
-
509
- i {
510
- font-size: 14px;
511
- font-style: normal;
512
- }
513
- }
514
- }
515
-
516
- .recharge-button {
517
- background: linear-gradient(
518
- 90deg,
519
- #ffebc1 0%,
520
- #ffd7a7 52.29%,
521
- #ffb875 100%
522
- );
523
- color: #353535;
524
- margin: 12px 0;
525
- border: 0;
526
- border-radius: 8px;
527
- flex: 1;
528
- }
529
- }
530
-
531
- .nut-checkbox {
532
- line-height: 40px;
533
- }
534
-
535
- .nut-checkbox__label {
536
- margin-left: 8px;
537
- flex: flex;
538
- font-size: 12px;
539
- }
540
-
541
- .link {
542
- display: inline;
543
- color: #fd6701;
544
- }
545
- }
546
- }
547
-
548
- .trade-dialog {
549
- .nut-dialog__header {
550
- font-size: 16px;
551
- color: #262626;
552
- }
553
-
554
- .item {
555
- font-size: 14px;
556
- color: #666666;
557
- line-height: 21px;
558
- }
559
-
560
- .nut-dialog__footer-cancel {
561
- color: #353535 !important;
562
- border-color: #cccccc !important;
563
- }
564
-
565
- .nut-dialog__footer-ok {
566
- border: none;
567
- color: #353535;
568
- background: linear-gradient(90deg, #ffebc1 0%, #ffb875 100%);
569
- }
570
- }
571
- </style>
1
+ <template>
2
+ <view class="view recharge-view2">
3
+ <view class="flex-grow">
4
+ <rights-picker :items="amounts" :selected="state.selected" @change="onAmountSelect" />
5
+ <div class="bean-buy" v-if="amounts[state.selected]">
6
+ <div class="left">
7
+ <div class="title">使用云豆支付</div>
8
+ <div class="amount" v-if="!selectBean">余额 {{ formatAmount(balance || 0) }}</div>
9
+ <div class="amount" v-else>扣减后余额 {{ formatAmount(balance - amounts[state.selected].paymentAmount) }}</div>
10
+ </div>
11
+ <div class="right" v-if="balance >= amounts[state.selected].paymentAmount" @click="selectBean = !selectBean">
12
+ <div class="amount">-{{ formatAmount(amounts[state.selected].paymentAmount || 0) }}</div>
13
+ <img class="icon"
14
+ :src="selectBean ? 'https://cdn.ddjf.com/static/images/appkit/select.svg' : 'https://cdn.ddjf.com/static/images/appkit/not-select.svg'" />
15
+ </div>
16
+ </div>
17
+
18
+
19
+ <slot name="banner"></slot>
20
+ </view>
21
+
22
+ <view class="amount-footer">
23
+ <view class="agreement" v-if="!selectBean">
24
+ <nut-checkbox v-model="state.agreed">我已阅读并同意<a v-track-click class="link inline"
25
+ @click="onAgreementLinkClick">《大道云平台云豆充值服务协议》</a></nut-checkbox>
26
+ </view>
27
+ <div class="buy-amount">
28
+ <div class="left">
29
+ 待支付:
30
+ <span class="amount">
31
+ <i>¥</i>{{ formatAmount(currentAmount) }}
32
+ </span>
33
+ </div>
34
+ <nut-button block shape="square" :loading="state.buttonLoading" v-track-click @click="onPayClick"
35
+ class="recharge-button">购买</nut-button>
36
+ </div>
37
+ </view>
38
+ <nut-dialog title="确认购买" custom-class="trade-dialog" v-model:visible="showDialog" @cancel="showDialog = !showDialog"
39
+ @ok="beanPay">
40
+ <template v-if="amounts[state.selected]">
41
+ <div class="item">云豆扣减:{{ formatAmount(amounts[state.selected].paymentAmount || 0) }}</div>
42
+ <div class="item">权益增加:{{ formatAmount(amounts[state.selected].priceRightNum || 0) }}笔</div>
43
+ <div class="item">扣减后云豆余额:{{ formatAmount(balance - amounts[state.selected].paymentAmount) }}</div>
44
+ </template>
45
+ </nut-dialog>
46
+ </view>
47
+ </template>
48
+
49
+ <script lang="ts" setup>
50
+ import { computed, onMounted, reactive, ref } from 'vue'
51
+ import RightsPicker, { Amount } from './RightsPicker.vue'
52
+ import { endpoints, useHttp } from '../api'
53
+ import { requestBrandWCPayByBean, requestPaymentByBean } from '../services'
54
+ import Taro, { showToast, useRouter } from '@tarojs/taro'
55
+ import { useAmount } from '../../shared/composables/useAmount'
56
+ import { isWechat } from '../../shared/composables/useDeviceEnv'
57
+
58
+ // 充值用户界面
59
+ // 配置了必须的属性后
60
+ // 自动获取支付套餐包列表
61
+ // 并发起微信支付
62
+ export interface RechargeViewProps {
63
+ /**
64
+ * header头中的appcode,一般情况下与app参数一致,当无应用权限时,此参数未空
65
+ **/
66
+ headerApp: string,
67
+ /**
68
+ * 应用
69
+ **/
70
+ app: string,
71
+ /**
72
+ * 充值场景
73
+ */
74
+ // stage?: string, // 这个参数暂时不用
75
+ /**
76
+ * 租户
77
+ */
78
+ tenant: string,
79
+ /**
80
+ * h5支付完成后跳转地址
81
+ */
82
+ payFinishJumpUrl?: ''
83
+ }
84
+
85
+ const props = defineProps<RechargeViewProps>()
86
+ const { formatAmount } = useAmount()
87
+ const { params } = useRouter()
88
+
89
+ const emit = defineEmits<{
90
+ (event: 'complete', value: { result: boolean, type: string }): void,
91
+ (event: 'agree'): void,
92
+ }>()
93
+
94
+ const state = reactive({
95
+ agreed: false,
96
+ selected: 0,
97
+ // agreementOpen: false,
98
+ buttonLoading: false,
99
+ })
100
+
101
+
102
+ const balance = ref<number>(0)
103
+ const amounts = ref<Amount[]>([])
104
+ const selectBean = ref<boolean>(false)
105
+
106
+ const onAgreementLinkClick = (e) => {
107
+ e.preventDefault()
108
+ e.stopImmediatePropagation()
109
+ emit('agree')
110
+ // state.agreementOpen = true
111
+ }
112
+
113
+ const onAmountSelect = (selected: number) => {
114
+ state.selected = selected
115
+ selectBean.value = false
116
+ }
117
+
118
+ const currentAmount = computed(() => {
119
+ return amounts.value[state.selected] && !selectBean.value ? amounts.value[state.selected].paymentAmount : 0
120
+ })
121
+
122
+ onMounted(() => {
123
+ const $http = useHttp({ Appcode: props.headerApp, Tenant: props.tenant })
124
+ $http.get<any[]>(endpoints.获取增值权益类目, {
125
+ rightCode: props.app === 'corporateStar' ? 'riskQueryCompany' : 'riskQueryMulti',
126
+ }).then((res: any) => {
127
+ balance.value = res.balance
128
+ amounts.value = res.paymentCaseConfigVOS
129
+ })
130
+ })
131
+
132
+ // 云豆支付
133
+ const showDialog = ref<boolean>(false)
134
+ async function beanPay() {
135
+ const $http = useHttp({ Appcode: props.headerApp, Tenant: props.tenant })
136
+ $http.post(`/payment/paymentCaseConfig/purchase/${amounts.value[state.selected].id}`).then((response: any) => {
137
+ if (response) {
138
+ showDialog.value = false
139
+ emit('complete', { result: response, type: 'bean' })
140
+ } else {
141
+ showToast({
142
+ title: response.message,
143
+ icon: 'none',
144
+ })
145
+ }
146
+ })
147
+ }
148
+
149
+
150
+ const onPayClick = () => {
151
+ // 用云豆支付
152
+ if (selectBean.value) {
153
+ showDialog.value = true
154
+ return
155
+ }
156
+
157
+ // 微信支付
158
+ if (!selectBean.value && !state.agreed) {
159
+ showToast({
160
+ title: '请勾选《大道云平台云豆充值协议》',
161
+ icon: 'none',
162
+ })
163
+ return false
164
+ }
165
+ state.buttonLoading = true
166
+
167
+ if (Taro.getEnv() === 'WEB') {
168
+ if (!isWechat()) {
169
+ showToast({
170
+ title: '请使用微信浏览器打开',
171
+ icon: 'none',
172
+ })
173
+ state.buttonLoading = false
174
+ return false
175
+ }
176
+ requestBrandWCPayByBean({
177
+ caseConfigId: amounts.value[state.selected].id,
178
+ amount: amounts.value[state.selected].paymentAmount,
179
+ app: 'loankitMp',
180
+ tenant: props.tenant,
181
+ accountAuthFlag: false,
182
+ channelCode: 'centergzh',
183
+ payFinishJumpUrl: props.payFinishJumpUrl,
184
+ fromMini: !!params.from
185
+ }).then(result => {
186
+ console.log(result, '------requestBrandWCPay')
187
+ state.buttonLoading = false
188
+ if (typeof result === 'boolean' && result) {
189
+ window.location.href = props.payFinishJumpUrl as string
190
+ } else {
191
+ emit('complete', { result, type: 'wePay' })
192
+ }
193
+ })
194
+ } else {
195
+ wx.login({
196
+ success({ code }: { code: string }) {
197
+ requestPaymentByBean({
198
+ caseConfigId: amounts.value[state.selected].id,
199
+ amount: amounts.value[state.selected].paymentAmount,
200
+ app: props.app,
201
+ tenant: props.tenant,
202
+ user: code,
203
+ }, props.headerApp).then(result => {
204
+ state.buttonLoading = false
205
+ if (result) {
206
+ emit('complete', { result: true, type: 'wePay' })
207
+ }
208
+ })
209
+ }
210
+ })
211
+ }
212
+ }
213
+ </script>
214
+
215
+ <style lang="scss">
216
+ .recharge-view2 {
217
+ height: 100%;
218
+ display: flex;
219
+ flex-direction: column;
220
+ --nut-primary-color: #017fff;
221
+
222
+ .flex-grow {
223
+ flex-grow: 1;
224
+ }
225
+
226
+ .bean-buy {
227
+ margin: 0 15px;
228
+ padding: 10px;
229
+ background: #FFFBF3;
230
+ border-radius: 5px;
231
+ display: flex;
232
+ justify-content: space-between;
233
+ align-items: center;
234
+
235
+ .left {
236
+ .title {
237
+ color: #FD6701;
238
+ font-size: 14px;
239
+ font-weight: 600;
240
+ line-height: 20px;
241
+ margin-bottom: 6px;
242
+ }
243
+
244
+ .amount {
245
+ color: #353535;
246
+ font-size: 13px;
247
+ line-height: 16px;
248
+ background-image: url('https://cdn.ddjf.com/static/images/appkit/yundou.png');
249
+ background-repeat: no-repeat;
250
+ background-size: 16px 16px;
251
+ padding-left: 24px;
252
+ }
253
+ }
254
+
255
+ .right {
256
+ display: flex;
257
+ align-items: center;
258
+
259
+ .amount {
260
+ color: #353535;
261
+ font-size: 15px;
262
+ line-height: 20px;
263
+ margin-right: 10px;
264
+ }
265
+
266
+ .icon {
267
+ display: block;
268
+ width: 16px;
269
+ height: 16px;
270
+ font-size: 0;
271
+ }
272
+ }
273
+ }
274
+
275
+ .amount-footer {
276
+ padding: 10px 0;
277
+ padding-bottom: 20px;
278
+
279
+ .agreement {
280
+ font-size: 12px;
281
+ display: flex;
282
+ justify-content: center;
283
+ align-items: cebter;
284
+ height: 40px;
285
+ }
286
+
287
+ .buy-amount {
288
+ display: flex;
289
+ justify-content: space-between;
290
+ align-items: center;
291
+ padding: 0 10px;
292
+ border-radius: 0px;
293
+ box-shadow: 0px -5px 14px -5px rgba(0, 0, 0, 0.1);
294
+
295
+ /* 上边框阴影 */
296
+ .left {
297
+ width: 70%;
298
+ color: #353535;
299
+ font-size: 13px;
300
+
301
+ .amount {
302
+ color: #FD6701;
303
+ font-size: 20px;
304
+ font-weight: 600;
305
+
306
+ i {
307
+ font-size: 14px;
308
+ font-style: normal;
309
+ }
310
+ }
311
+ }
312
+
313
+ .recharge-button {
314
+ background: linear-gradient(90deg, #FFEBC1 0%, #FFD7A7 52.29%, #FFB875 100%);
315
+ color: #353535;
316
+ margin: 12px 0;
317
+ border: 0;
318
+ border-radius: 8px;
319
+ flex: 1;
320
+ }
321
+ }
322
+
323
+ .nut-checkbox {
324
+ line-height: 40px;
325
+ }
326
+
327
+ .nut-checkbox__label {
328
+ margin-left: 8px;
329
+ flex: flex;
330
+ font-size: 12px;
331
+ }
332
+
333
+ .link {
334
+ display: inline;
335
+ color: #FD6701;
336
+ }
337
+ }
338
+ }
339
+
340
+ .trade-dialog {
341
+ .nut-dialog__header {
342
+ font-size: 16px;
343
+ color: #262626
344
+ }
345
+
346
+ .item {
347
+ font-size: 14px;
348
+ color: #666666;
349
+ line-height: 21px;
350
+ }
351
+
352
+ .nut-dialog__footer-cancel {
353
+ color: #353535 !important;
354
+ border-color: #CCCCCC !important;
355
+ }
356
+
357
+ .nut-dialog__footer-ok {
358
+ border: none;
359
+ color: #353535;
360
+ background: linear-gradient(90deg, #FFEBC1 0%, #FFB875 100%);
361
+ }
362
+ }
363
+ </style>