ts-glitter 14.2.5 → 14.2.7

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 (54) hide show
  1. package/hwq81jngms.json +1 -0
  2. package/lhygmbqjwr.json +1 -0
  3. package/lowcode/Entry.js +1 -1
  4. package/lowcode/Entry.ts +1 -1
  5. package/lowcode/cms-plugin/filter-options.js +1 -3
  6. package/lowcode/cms-plugin/filter-options.ts +1 -3
  7. package/lowcode/cms-plugin/module/product-excel.js +537 -0
  8. package/lowcode/cms-plugin/module/product-excel.ts +652 -0
  9. package/lowcode/cms-plugin/shopping-allowance-manager.js +12 -5
  10. package/lowcode/cms-plugin/shopping-allowance-manager.ts +12 -5
  11. package/lowcode/cms-plugin/shopping-finance-setting.js +0 -7
  12. package/lowcode/cms-plugin/shopping-finance-setting.ts +8 -8
  13. package/lowcode/cms-plugin/shopping-invoice-manager.js +5 -1
  14. package/lowcode/cms-plugin/shopping-invoice-manager.ts +5 -2
  15. package/lowcode/cms-plugin/shopping-order-manager.js +8 -0
  16. package/lowcode/cms-plugin/shopping-order-manager.ts +8 -0
  17. package/lowcode/cms-plugin/shopping-product-setting.js +61 -638
  18. package/lowcode/cms-plugin/shopping-product-setting.ts +67 -790
  19. package/lowcode/jspage/main.ts +0 -1
  20. package/lowcode/public-components/checkout/index.js +62 -21
  21. package/lowcode/public-components/checkout/index.ts +64 -21
  22. package/lowcode/public-components/checkout/index_.js +1724 -412
  23. package/lowcode/public-components/checkout/index_.ts +2032 -704
  24. package/lowcode/public-components/product/pd-class.js +51 -1
  25. package/lowcode/public-components/product/pd-class.ts +55 -2
  26. package/lowcode/public-components/product/product-detail.js +1 -1
  27. package/lowcode/public-components/product/product-detail.ts +7 -3
  28. package/lowcode/public-components/product/product-list.js +55 -0
  29. package/lowcode/public-components/product/product-list.ts +62 -1
  30. package/lowcode/public-components/public/ad.js +14 -0
  31. package/lowcode/public-components/public/ad.ts +15 -0
  32. package/nmj1s3fc0x.json +1 -0
  33. package/package.json +7 -4
  34. package/src/api-public/controllers/shop.js +16 -0
  35. package/src/api-public/controllers/shop.js.map +1 -1
  36. package/src/api-public/controllers/shop.ts +27 -3
  37. package/src/api-public/services/EcInvoice.js +18 -12
  38. package/src/api-public/services/EcInvoice.js.map +1 -1
  39. package/src/api-public/services/EcInvoice.ts +19 -14
  40. package/src/api-public/services/financial-service.d.ts +49 -1
  41. package/src/api-public/services/financial-service.js +226 -1
  42. package/src/api-public/services/financial-service.js.map +1 -1
  43. package/src/api-public/services/financial-service.ts +282 -1
  44. package/src/api-public/services/shopping.d.ts +2 -2
  45. package/src/api-public/services/shopping.js +9 -9
  46. package/src/api-public/services/shopping.js.map +1 -1
  47. package/src/api-public/services/shopping.ts +28 -28
  48. package/src/helper/glitter-util.d.ts +0 -1
  49. package/src/helper/glitter-util.js.map +1 -5
  50. package/src/index.js +108 -89
  51. package/src/index.js.map +1 -1
  52. package/src/index.ts +424 -397
  53. package/y7x8oegu36.json +1 -0
  54. package/zgp27fxdah.json +1 -0
@@ -1,12 +1,19 @@
1
- import {GVC} from '../../glitterBundle/GVController.js';
2
- import {ApiShop} from '../../glitter-base/route/shopping.js';
3
- import {GlobalUser} from '../../glitter-base/global/global-user.js';
4
- import {CheckInput} from '../../modules/checkInput.js';
5
- import {Tool} from '../../modules/tool.js';
6
- import {ApiCart, CartItem} from '../../glitter-base/route/api-cart.js';
7
- import {ApiDelivery} from "../../glitter-base/route/delivery.js";
8
- import {Voucher as OriginVoucher,VoucherContent} from '../user-manager/um-voucher.js'
9
- import {ShareDialog} from "../../glitterBundle/dialog/ShareDialog.js";
1
+ import { GVC } from '../../glitterBundle/GVController.js';
2
+ import { ApiShop } from '../../glitter-base/route/shopping.js';
3
+ import { GlobalUser } from '../../glitter-base/global/global-user.js';
4
+ import { CheckInput } from '../../modules/checkInput.js';
5
+ import { Tool } from '../../modules/tool.js';
6
+ import { ApiCart, CartItem } from '../../glitter-base/route/api-cart.js';
7
+ import { ApiDelivery } from '../../glitter-base/route/delivery.js';
8
+ import { ApiUser } from '../../glitter-base/route/user.js';
9
+ import { FormWidget } from '../../official_view_component/official/form.js';
10
+ import { ShareDialog } from '../../glitterBundle/dialog/ShareDialog.js';
11
+ import { Voucher as OriginVoucher, VoucherContent } from '../user-manager/um-voucher.js';
12
+ import { Ad } from '../public/ad.js';
13
+
14
+ /*
15
+ * Page: sy01_checkout_detail
16
+ */
10
17
 
11
18
  const html = String.raw;
12
19
  const css = String.raw;
@@ -18,7 +25,6 @@ interface Voucher extends OriginVoucher {
18
25
  content: UserVoucher;
19
26
  }
20
27
 
21
-
22
28
  export class CheckoutIndex {
23
29
  static main(gvc: GVC, widget: any, subData: any) {
24
30
  const glitter = gvc.glitter;
@@ -34,40 +40,56 @@ export class CheckoutIndex {
34
40
  customer_info: {},
35
41
  lineItems: [
36
42
  {
37
- spec: ['黑色', '小號'],
38
- id: 710,
43
+ spec: ['黃色', 'L'],
44
+ id: 715,
39
45
  count: 1,
40
- preview_image:
41
- 'https://d3jnmi1tfjgtti.cloudfront.net/file/122538856/DALL·E2024-11-0514.20.13-AsophisticatedWindermerecoffeetablewithamodernyetclassicdesign.Thetablefeaturesasolidwoodconstructionwithasmooth,polishedsurfa.webp',
42
- title: '溫德米爾 茶几',
43
- sale_price: 1800,
44
- collection: ['折扣專區'],
46
+ preview_image: 'https://d3jnmi1tfjgtti.cloudfront.net/file/122538856/size1440_s*px$_sfs0s0s4s5s7sds6_AI助手.png',
47
+ title: 'Adidas衣服',
48
+ sale_price: 1000,
49
+ collection: [],
45
50
  sku: '',
46
51
  shipment_obj: {
47
52
  type: 'weight',
48
53
  value: 1,
49
54
  },
50
- discount_price: 0,
55
+ discount_price: 188,
51
56
  rebate: 0,
52
57
  },
53
58
  ],
54
- total: 1800,
55
- email: 'daniel.lin@ncdesign.info',
59
+ total: 812,
60
+ email: 'sam38124@gmail.com',
56
61
  user_info: {
57
- shipment: '',
62
+ shipment: 'sescsbsfs4s2s4sf',
63
+ invoice_type: 'me',
64
+ send_type: 'email',
65
+ custom_form_delivery: {
66
+ '1732152125723': 'A司機',
67
+ },
68
+ name: '王建智',
69
+ phone: '0978028730',
70
+ email: 'sam38124@gmail.com',
71
+ note: 'kldskds',
58
72
  },
59
73
  shipment_fee: 0,
60
74
  rebate: 0,
61
75
  use_rebate: 0,
62
- orderID: '1732015169389',
63
- shipment_support: ['OKMARTC2C', 'shop', 'FAMIC2C', 'UNIMARTC2C'],
76
+ orderID: '1732683468622',
77
+ shipment_support: ['OKMARTC2C', 'shop', 'FAMIC2C', 'UNIMARTC2C', 'sescsbsfs4s2s4sf', 'normal', 'HILIFEC2C'],
64
78
  shipment_info:
65
79
  '<p style=\'box-sizing: border-box; margin: 0px; text-align: left; font-size: 14px; font-weight: 700; letter-spacing: 1.2px; color: rgb(254, 85, 65); font-family: "Open Sans", sans-serif; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;\' id="isPasted">感謝您在 SHOPNEX 購買商品,商品的包裝與配送</p><p style=\'box-sizing: border-box; margin: 0px; text-align: left; font-size: 14px; font-weight: 700; letter-spacing: 1.2px; color: rgb(254, 85, 65); font-family: "Open Sans", sans-serif; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;\'>預計花費約 3 到 6 週,煩請耐心等候!</p><p style=\'box-sizing: border-box; margin: 0px; text-align: left; font-size: 14px; font-weight: 700; letter-spacing: 1.2px; color: rgb(254, 85, 65); font-family: "Open Sans", sans-serif; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;\'>若約定配送日當天未能聯繫到你,因而無法完成配送</p><p style=\'box-sizing: border-box; margin: 0px; text-align: left; font-size: 14px; font-weight: 700; letter-spacing: 1.2px; color: rgb(254, 85, 65); font-family: "Open Sans", sans-serif; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;\'>商家會約定再次配送的時間,您將支付額外的運費。</p>',
66
80
  shipment_selector: [
81
+ {
82
+ name: '一般宅配',
83
+ value: 'normal',
84
+ },
67
85
  {
68
86
  name: '全家店到店',
69
87
  value: 'FAMIC2C',
70
88
  },
89
+ {
90
+ name: '萊爾富店到店',
91
+ value: 'HILIFEC2C',
92
+ },
71
93
  {
72
94
  name: 'OK超商店到店',
73
95
  value: 'OKMARTC2C',
@@ -80,20 +102,193 @@ export class CheckoutIndex {
80
102
  name: '實體門市取貨',
81
103
  value: 'shop',
82
104
  },
105
+ {
106
+ form: [
107
+ {
108
+ col: '12',
109
+ key: '1732152125723',
110
+ page: 'form-select',
111
+ type: 'form_plugin_v2',
112
+ group: '',
113
+ title: '物流司機',
114
+ col_sm: '12',
115
+ toggle: true,
116
+ appName: 'cms_system',
117
+ require: 'true',
118
+ readonly: 'write',
119
+ formFormat: '{}',
120
+ moduleName: '下拉選單',
121
+ style_data: {
122
+ input: {
123
+ list: [],
124
+ class: '',
125
+ style: '',
126
+ version: 'v2',
127
+ },
128
+ label: {
129
+ list: [],
130
+ class: 'form-label fs-base ',
131
+ style: '',
132
+ version: 'v2',
133
+ },
134
+ container: {
135
+ list: [],
136
+ class: '',
137
+ style: '',
138
+ version: 'v2',
139
+ },
140
+ },
141
+ form_config: {
142
+ type: 'name',
143
+ title: '',
144
+ option: [
145
+ {
146
+ name: 'A司機',
147
+ index: 0,
148
+ value: 'A司機',
149
+ },
150
+ {
151
+ name: 'B司機',
152
+ index: 0,
153
+ value: 'B司機',
154
+ },
155
+ {
156
+ name: 'C司機',
157
+ index: 0,
158
+ value: 'C司機',
159
+ },
160
+ ],
161
+ input_style: {},
162
+ title_style: {},
163
+ place_holder: '',
164
+ },
165
+ },
166
+ ],
167
+ name: '小榮物流',
168
+ value: 'sescsbsfs4s2s4sf',
169
+ },
83
170
  ],
84
171
  use_wallet: 0,
85
- user_email: 'daniel.lin@ncdesign.info',
172
+ user_email: 'sam38124@gmail.com',
86
173
  useRebateInfo: {
87
174
  point: 0,
88
175
  },
89
176
  orderSource: '',
90
177
  code_array: [],
91
178
  give_away: [],
92
- user_rebate_sum: 0,
93
- voucherList: [],
94
- discount: 0,
179
+ user_rebate_sum: 39807,
180
+ code: 'J3IXLO',
181
+ voucherList: [
182
+ {
183
+ id: 677,
184
+ for: 'all',
185
+ code: 'J3IXLO',
186
+ rule: 'min_count',
187
+ type: 'voucher',
188
+ title: '示範優惠券1011',
189
+ value: '100',
190
+ device: ['normal', 'pos'],
191
+ forKey: [],
192
+ method: 'fixed',
193
+ status: 1,
194
+ target: 'all',
195
+ userID: 122538856,
196
+ endDate: '2024-11-28',
197
+ endTime: '00:13',
198
+ overlay: false,
199
+ trigger: 'code',
200
+ counting: 'single',
201
+ ruleValue: 0,
202
+ startDate: '2024-10-11',
203
+ startTime: '17:00',
204
+ reBackType: 'discount',
205
+ targetList: ['neverBuying'],
206
+ end_ISO_Date: '2024-11-27T16:13:00.000Z',
207
+ macroLimited: 0,
208
+ microLimited: 0,
209
+ rebateEndDay: '30',
210
+ conditionType: 'order',
211
+ start_ISO_Date: '2024-10-11T09:00:00.000Z',
212
+ bind: [
213
+ {
214
+ spec: ['黃色', 'L'],
215
+ id: 715,
216
+ count: 1,
217
+ preview_image: 'https://d3jnmi1tfjgtti.cloudfront.net/file/122538856/size1440_s*px$_sfs0s0s4s5s7sds6_AI助手.png',
218
+ title: 'Adidas衣服',
219
+ sale_price: 1000,
220
+ collection: [],
221
+ sku: '',
222
+ shipment_obj: {
223
+ type: 'weight',
224
+ value: 1,
225
+ },
226
+ discount_price: 188,
227
+ rebate: 0,
228
+ },
229
+ ],
230
+ times: 1,
231
+ bind_subtotal: 1000,
232
+ discount_total: 100,
233
+ rebate_total: 0,
234
+ },
235
+ {
236
+ id: 718,
237
+ for: 'all',
238
+ code: '',
239
+ rule: 'min_price',
240
+ type: 'voucher',
241
+ title: '示範優惠券1121全館',
242
+ value: '88',
243
+ device: ['normal'],
244
+ forKey: [],
245
+ method: 'fixed',
246
+ status: 1,
247
+ target: 'all',
248
+ userID: 122538856,
249
+ endDate: '2024-11-28',
250
+ endTime: '02:00',
251
+ overlay: true,
252
+ trigger: 'auto',
253
+ counting: 'single',
254
+ ruleValue: 100,
255
+ startDate: '2024-11-21',
256
+ startTime: '02:00',
257
+ reBackType: 'discount',
258
+ targetList: [],
259
+ end_ISO_Date: '2024-11-27T18:00:00.000Z',
260
+ macroLimited: 0,
261
+ microLimited: 0,
262
+ rebateEndDay: '30',
263
+ conditionType: 'order',
264
+ start_ISO_Date: '2024-11-20T18:00:00.000Z',
265
+ bind: [
266
+ {
267
+ spec: ['黃色', 'L'],
268
+ id: 715,
269
+ count: 1,
270
+ preview_image: 'https://d3jnmi1tfjgtti.cloudfront.net/file/122538856/size1440_s*px$_sfs0s0s4s5s7sds6_AI助手.png',
271
+ title: 'Adidas衣服',
272
+ sale_price: 1000,
273
+ collection: [],
274
+ sku: '',
275
+ shipment_obj: {
276
+ type: 'weight',
277
+ value: 1,
278
+ },
279
+ discount_price: 188,
280
+ rebate: 0,
281
+ },
282
+ ],
283
+ times: 1,
284
+ bind_subtotal: 1000,
285
+ discount_total: 88,
286
+ rebate_total: 0,
287
+ },
288
+ ],
289
+ discount: 188,
95
290
  payment_setting: {
96
- TYPE: 'newWebPay',
291
+ TYPE: 'ecPay',
97
292
  },
98
293
  off_line_support: {
99
294
  atm: true,
@@ -145,17 +340,14 @@ export class CheckoutIndex {
145
340
  visible: obj?.text?.visible === false ? false : true,
146
341
  fontSize: obj?.text?.fontSize ?? 16,
147
342
  };
148
- return html`
149
- <div class="d-flex align-items-center justify-content-center flex-column w-100 mx-auto ${container.class}"
150
- style="${container.style}">
151
- <div
152
- class="spinner-border ${circleAttr.visible ? '' : 'd-none'}"
153
- style="font-size: ${circleAttr.borderSize}px; width: ${circleAttr.width}px; height: ${circleAttr.width}px;"
154
- role="status"
155
- ></div>
156
- <span class="mt-3 ${textAttr.visible ? '' : 'd-none'}"
157
- style="font-size: ${textAttr.fontSize}px;">${textAttr.value}</span>
158
- </div>`;
343
+ return html` <div class="d-flex align-items-center justify-content-center flex-column w-100 mx-auto ${container.class}" style="${container.style}">
344
+ <div
345
+ class="spinner-border ${circleAttr.visible ? '' : 'd-none'}"
346
+ style="font-size: ${circleAttr.borderSize}px; width: ${circleAttr.width}px; height: ${circleAttr.width}px;"
347
+ role="status"
348
+ ></div>
349
+ <span class="mt-3 ${textAttr.visible ? '' : 'd-none'}" style="font-size: ${textAttr.fontSize}px;">${textAttr.value}</span>
350
+ </div>`;
159
351
  }
160
352
 
161
353
  function isImageUrlValid(url: string): Promise<boolean> {
@@ -167,14 +359,7 @@ export class CheckoutIndex {
167
359
  });
168
360
  }
169
361
 
170
- function validImageBox(obj: {
171
- gvc: GVC;
172
- image: string;
173
- width: number;
174
- height?: number;
175
- class?: string;
176
- style?: string
177
- }) {
362
+ function validImageBox(obj: { gvc: GVC; image: string; width: number; height?: number; class?: string; style?: string }) {
178
363
  const imageVM = {
179
364
  id: obj.gvc.glitter.getUUID(),
180
365
  loading: true,
@@ -200,8 +385,8 @@ export class CheckoutIndex {
200
385
  bind: obj.gvc.glitter.getUUID(),
201
386
  view: () => {
202
387
  return spinner({
203
- container: {class: 'mt-0'},
204
- text: {visible: false},
388
+ container: { class: 'mt-0' },
389
+ text: { visible: false },
205
390
  });
206
391
  },
207
392
  divCreate: {
@@ -254,10 +439,9 @@ export class CheckoutIndex {
254
439
  }
255
440
 
256
441
  function addItemBadge() {
257
- return html`
258
- <div class="${gClass('add-item-badge')}">
259
- <div class="${gClass('add-item-text')}">加購品</div>
260
- </div>`;
442
+ return html` <div class="${gClass('add-item-badge')}">
443
+ <div class="${gClass('add-item-text')}">加購品</div>
444
+ </div>`;
261
445
  }
262
446
 
263
447
  function addStyle() {
@@ -336,7 +520,7 @@ export class CheckoutIndex {
336
520
  border: 0;
337
521
  border-radius: 0.375rem;
338
522
  height: 40px;
339
- background: #DDDDDD;
523
+ background: #dddddd;
340
524
  padding: 0 24px;
341
525
  margin: 18px 0;
342
526
  }
@@ -375,15 +559,21 @@ export class CheckoutIndex {
375
559
  }
376
560
 
377
561
  .${classPrefix}-group-input {
378
- border:none;
379
- background:none;
380
- text-align: start;
381
- color: #393939;
382
- font-size: 16px;
383
- font-weight: 400;
562
+ border: none;
563
+ background: none;
564
+ text-align: start;
565
+ color: #393939;
566
+ font-size: 16px;
567
+ font-weight: 400;
384
568
  word-wrap: break-word;
385
569
  padding-left: 12px;
386
570
  }
571
+ .${classPrefix}-first-td {
572
+ display: flex;
573
+ align-items: center;
574
+ justify-content: center;
575
+ width: 30%;
576
+ }
387
577
 
388
578
  .${classPrefix}-group-input:focus {
389
579
  outline: 0;
@@ -462,13 +652,147 @@ export class CheckoutIndex {
462
652
  word-wrap: break-word;
463
653
  }
464
654
  `);
655
+ gvc.addStyle(css`
656
+ @media (max-width: 768px) {
657
+ .${classPrefix}-container {
658
+ max-width: 100% !important;
659
+ margin: 2.5rem auto !important;
660
+ }
661
+ .${classPrefix}-td {
662
+ display: flex;
663
+ align-items: center;
664
+ justify-content: start;
665
+ width: 100%;
666
+ }
667
+ .${classPrefix}-price-container {
668
+ display: flex;
669
+ flex-direction: column;
670
+ width: 100% !important;
671
+ align-items: center;
672
+ padding: 0;
673
+ gap: 12px;
674
+ margin: 24px 0;
675
+ }
676
+ }
677
+ `);
465
678
  }
466
679
 
467
680
  function refreshCartData() {
468
- loadings.page=true
469
- gvc.notifyDataChange(ids.page)
681
+ const dialog = new ShareDialog(gvc.glitter);
682
+ dialog.dataLoading({ visible: true });
683
+ const beta = true;
684
+ if (!beta) {
685
+ new Promise(async (resolve, reject) => {
686
+ new Promise((resolve, reject) => {
687
+ setTimeout(() => {
688
+ resolve(ApiCart.cart);
689
+ });
690
+ }).then(async (res: any) => {
691
+ const cartData: {
692
+ line_items: {
693
+ sku: string;
694
+ spec: string[];
695
+ stock: number;
696
+ sale_price: number;
697
+ compare_price: number;
698
+ preview_image: string;
699
+ title: string;
700
+ id: number;
701
+ count: number;
702
+ }[];
703
+ total: number;
704
+ user_info: {
705
+ shipment: string;
706
+ };
707
+ } = {
708
+ line_items: [],
709
+ total: 0,
710
+ user_info: {
711
+ shipment: localStorage.getItem('shipment-select') as string,
712
+ },
713
+ };
714
+ if (res.line_items) {
715
+ res.user_info = {
716
+ shipment: localStorage.getItem('shipment-select') as string,
717
+ };
718
+ const cart = res as CartItem;
719
+ ApiShop.getCheckout(cart).then((res) => {
720
+ if (res.result) {
721
+ resolve(res.response.data);
722
+ } else {
723
+ resolve([]);
724
+ }
725
+ });
726
+ } else {
727
+ for (const b of Object.keys(res)) {
728
+ cartData.line_items.push({
729
+ id: b.split('-')[0] as any,
730
+ count: res[b] as number,
731
+ spec: b.split('-').filter((dd, index) => {
732
+ return index !== 0;
733
+ }) as any,
734
+ } as any);
735
+ }
736
+ const voucher = ApiCart.cart.code;
737
+ const rebate = ApiCart.cart.use_rebate || 0;
738
+ const distributionCode = localStorage.getItem('distributionCode') ?? '';
739
+ ApiShop.getCheckout({
740
+ line_items: cartData.line_items.map((dd) => {
741
+ return {
742
+ id: dd.id,
743
+ spec: dd.spec,
744
+ count: dd.count,
745
+ };
746
+ }),
747
+ code: voucher as string,
748
+ use_rebate: GlobalUser.token && rebate ? rebate : undefined,
749
+ distribution_code: distributionCode,
750
+ user_info: {
751
+ shipment: localStorage.getItem('shipment-select'),
752
+ },
753
+ }).then((res) => {
754
+ if (res.result) {
755
+ resolve(res.response.data);
756
+ } else {
757
+ resolve([]);
758
+ }
759
+ });
760
+ }
761
+ });
762
+ }).then((data) => {
763
+ vm.cartData = data;
764
+ gvc.addMtScript(
765
+ [
766
+ {
767
+ src: `https://unpkg.com/@lottiefiles/lottie-player@latest/dist/lottie-player.js`,
768
+ },
769
+ ],
770
+ () => {
771
+ loadings.page = false;
772
+ dialog.dataLoading({ visible: false });
773
+ gvc.notifyDataChange(['js-cart-count', ids.page]);
774
+ },
775
+ () => {}
776
+ );
777
+ });
778
+ } else {
779
+ gvc.addMtScript(
780
+ [
781
+ {
782
+ src: `https://unpkg.com/@lottiefiles/lottie-player@latest/dist/lottie-player.js`,
783
+ },
784
+ ],
785
+ () => {
786
+ loadings.page = false;
787
+ dialog.dataLoading({ visible: false });
788
+ gvc.notifyDataChange(ids.page);
789
+ },
790
+ () => {}
791
+ );
792
+ }
793
+ gvc.glitter.recreateView('.js-cart-count');
470
794
  }
471
-
795
+ refreshCartData();
472
796
  return gvc.bindView(
473
797
  (() => {
474
798
  return {
@@ -479,446 +803,599 @@ export class CheckoutIndex {
479
803
  return spinner();
480
804
  }
481
805
 
482
- this.initial(vm.cartData)
806
+ this.initial(vm.cartData);
483
807
  addStyle();
484
808
  if (vm.cartData.lineItems.length === 0) {
485
809
  return html`
486
- <div class="container ${gClass(['container', 'null-container'])}">
487
- <div class="${gClass('header')}">購物明細</div>
488
- <lottie-player
810
+ <div class="container ${gClass(['container', 'null-container'])}">
811
+ <div class="${gClass('header')}">購物明細</div>
812
+ <lottie-player
489
813
  style="max-width: 100%; width: 300px; height: 300px;"
490
814
  src="https://lottie.host/38ba8340-3414-41b8-b068-bba18d240bb3/h7e1Q29IQJ.json"
491
815
  speed="1"
492
816
  loop=""
493
817
  autoplay=""
494
818
  background="transparent"
495
- ></lottie-player>
496
- <div class="mt-3">購物車是空的,趕快前往挑選您心儀的商品</div>
497
- </div> `;
819
+ ></lottie-player>
820
+ <div class="mt-3 fw-bold">購物車是空的,趕快前往挑選您心儀的商品</div>
821
+ </div>
822
+ `;
498
823
  }
499
- return html`
500
- <div class="container ${gClass('container')}">
824
+ return html` <div class="container ${gClass('container')}">
501
825
  <div class="${gClass('header')}">購物明細</div>
502
826
  ${gvc.bindView(
503
- (() => {
504
- return {
505
- bind: ids.cart,
506
- view: () => {
507
- return html`
508
- <section>
509
- <div class="${gClass('banner-bgr')}">
510
- <span class="${gClass('banner-text')}">購物車</span>
511
- </div>
512
- <div class="d-flex align-items-center p-3 border-bottom">
513
- <div class="${gClass('first-td')}">商品名稱</div>
514
- <div class="${gClass('td')}">規格</div>
515
- <div class="${gClass('td')}">單價</div>
516
- <div class="${gClass('td')}">數量</div>
517
- <div class="${gClass('td')}">小計</div>
518
- </div>
519
- ${gvc.bindView({
520
- bind: glitter.getUUID(),
521
- view: () => {
522
- return vm.cartData.lineItems
523
- .map((item: any) => {
524
- return html`
525
- <div class="d-flex align-items-center p-3 border-bottom"
526
- style="gap: 10px; position: relative;">
527
- <div class="${gClass('first-td')} justify-content-start">
528
- ${validImageBox({
529
- gvc,
530
- image: noImageURL,
531
- width: 100,
532
- })}
533
- <span class="ms-2">${item.title}${item.is_add_on_items ? addItemBadge() : ''}</span>
534
- </div>
535
- <div class="${gClass('td')}">
536
- ${item.spec ? item.spec.join(' / ') : ''}
827
+ (() => {
828
+ return {
829
+ bind: ids.cart,
830
+ view: () => {
831
+ return html` <section>
832
+ <div class="${gClass('banner-bgr')}">
833
+ <span class="${gClass('banner-text')}">購物車</span>
834
+ </div>
835
+ <div class="d-none d-sm-flex align-items-center p-3 border-bottom">
836
+ <div class="${gClass('first-td')} justify-content-start">商品名稱</div>
837
+ <div class="${gClass('td')}">規格</div>
838
+ <div class="${gClass('td')}">單價</div>
839
+ <div class="${gClass('td')}">數量</div>
840
+ <div class="${gClass('td')}">小計</div>
841
+ </div>
842
+ ${gvc.bindView({
843
+ bind: glitter.getUUID(),
844
+ view: () => {
845
+ return vm.cartData.lineItems
846
+ .map((item: any, index: number) => {
847
+ function financial(x: number) {
848
+ const parsed = Number.parseFloat(`${x}`);
849
+
850
+ // 如果數字是整數,直接返回帶千分位的整數
851
+ if (Number.isInteger(parsed)) {
852
+ return parsed.toLocaleString();
853
+ }
854
+
855
+ // 將數字轉換為字串,保留小數點後的原始數字以進行判斷
856
+ const decimalPart = parsed.toString().split('.')[1];
857
+
858
+ // 根據小數位數的不同情況做處理
859
+ if (decimalPart && decimalPart.length > 1) {
860
+ return parsed.toLocaleString(undefined, {
861
+ minimumFractionDigits: 1,
862
+ maximumFractionDigits: 1,
863
+ });
864
+ } else {
865
+ return parsed.toLocaleString(undefined, {
866
+ minimumFractionDigits: 1,
867
+ maximumFractionDigits: 3,
868
+ });
869
+ }
870
+ }
871
+ return html`
872
+ <div class="d-flex flex-column border-bottom p-lg-3 px-1 py-3 gap-3">
873
+ <div class="d-flex w-100 position-relative" style="gap:20px;">
874
+ <div class="${gClass('first-td')} justify-content-start d-sm-none">
875
+ <div
876
+ style="width: 88px;height: 88px;border-radius: 20px;background: 50%/cover url('${item.preview_image}')"
877
+ ></div>
878
+ <span class="ms-2 d-none">${item.title}${item.is_add_on_items ? addItemBadge() : ''}</span>
879
+ </div>
880
+ <div class="d-flex flex-sm-row flex-column w-100 position-relative" style="gap: 10px; position: relative;">
881
+ <div class="${gClass('first-td')} justify-content-start d-none d-sm-flex">
882
+ <div
883
+ style="width: 88px;height: 88px;border-radius: 20px;background: 50%/cover url('${item.preview_image}')"
884
+ ></div>
885
+ <span class="ms-2 ">${item.title}${item.is_add_on_items ? addItemBadge() : ''}</span>
537
886
  </div>
538
- <div class="${gClass('td')}">
539
- <div>
887
+ <div class="${gClass('td')}">${item.spec ? item.spec.join(' / ') : ''}</div>
888
+ <div class="${gClass('td')} d-flex flex-column align-items-start align-items-sm-center" style="gap:10px;">
889
+ <div class="">
540
890
  ${(() => {
541
- function financial(x: number) {
542
- const parsed = Number.parseFloat(`${x}`);
543
-
544
- // 如果數字是整數,直接返回帶千分位的整數
545
- if (Number.isInteger(parsed)) {
546
- return parsed.toLocaleString();
547
- }
548
-
549
- // 將數字轉換為字串,保留小數點後的原始數字以進行判斷
550
- const decimalPart = parsed.toString().split('.')[1];
551
-
552
- // 根據小數位數的不同情況做處理
553
- if (decimalPart && decimalPart.length > 1) {
554
- return parsed.toLocaleString(undefined, {
555
- minimumFractionDigits: 1,
556
- maximumFractionDigits: 1
557
- });
558
- } else {
559
- return parsed.toLocaleString(undefined, {
560
- minimumFractionDigits: 1,
561
- maximumFractionDigits: 3
562
- });
563
- }
564
- }
565
-
566
- return `NT.${financial(subData.sale_price - subData.discount_price)}`;
567
- })()}
568
- </div>
569
- <div>原價: NT.
570
- ${item.sale_price.toLocaleString()}
891
+ return `NT.${parseInt(item.sale_price, 10).toLocaleString()}`;
892
+ })()}
571
893
  </div>
572
894
  </div>
573
895
  <div class="${gClass('td')}">
574
896
  <select
575
- class="${gClass('select')}"
576
- style="width: 100px;"
577
- onchange="${gvc.event((e) => {
578
- item.count = parseInt(e.value, 10);
579
- gvc.notifyDataChange(ids.cart);
580
- })}"
897
+ class="${gClass('select')}"
898
+ style="width: 100px;"
899
+ onchange="${gvc.event((e) => {
900
+ ApiCart.setCart((cartItem) => {
901
+ cartItem.line_items.find((dd) => {
902
+ return dd.id === item.id && item.spec.join('') === dd.spec.join('');
903
+ })!.count = parseInt(e.value, 10);
904
+ refreshCartData();
905
+ });
906
+ })}"
581
907
  >
582
- ${[...new Array(50)].map((_, index) => {
583
- return html`
584
- <option value="${index + 1}">
585
- ${index + 1}
586
- </option>`;
587
- })}
908
+ ${[...new Array(99)].map((_, index) => {
909
+ return html` <option value="${index + 1}" ${index + 1 === item.count ? `selected` : ``}>
910
+ ${index + 1}
911
+ </option>`;
912
+ })}
588
913
  </select>
589
914
  </div>
590
- <div class="${gClass('td')}">
591
- <span>合計 NT. ${(item.sale_price * item.count).toLocaleString()}</span>
592
- <div style="position: absolute; right: 5px; transform: translateY(-50%); top: 50%;">
593
- <i class="fa-solid fa-xmark-large"
594
- style="cursor: pointer;"></i>
915
+ <div class="d-block d-md-none" style="position: absolute; right: 0px; top:0px;">
916
+ <i
917
+ class="fa-solid fa-xmark-large"
918
+ style="cursor: pointer;"
919
+ onclick="${gvc.event(() => {
920
+ ApiCart.setCart((cartItem) => {
921
+ cartItem.line_items = cartItem.line_items.filter((dd) => {
922
+ return !(dd.id === item.id && item.spec.join('') === dd.spec.join(''));
923
+ });
924
+ refreshCartData();
925
+ });
926
+ })}"
927
+ ></i>
928
+ </div>
929
+ <span class="d-block d-md-none" style="position: absolute;bottom:0px;right:0px;"
930
+ >合計 NT.
931
+ ${(item.discount_price
932
+ ? ((item.sale_price - item.discount_price) as any) * item.count
933
+ : item.sale_price * item.count
934
+ ).toLocaleString()}</span
935
+ >
936
+ <div class="${gClass('td')} d-none d-md-flex" style="bottom:0px;right:10px;">
937
+ <span class="d-none d-md-block">合計 NT. ${(item.sale_price * item.count).toLocaleString()}</span>
938
+ <div
939
+ class="d-none d-md-block"
940
+ style="position: absolute; right: -10px; transform: translateY(-50%); top: 50%;"
941
+ >
942
+ <i
943
+ class="fa-solid fa-xmark-large"
944
+ style="cursor: pointer;"
945
+ onclick="${gvc.event(() => {
946
+ ApiCart.setCart((cartItem) => {
947
+ cartItem.line_items = cartItem.line_items.filter((dd) => {
948
+ return !(dd.id === item.id && item.spec.join('') === dd.spec.join(''));
949
+ });
950
+ refreshCartData();
951
+ });
952
+ })}"
953
+ ></i>
595
954
  </div>
596
955
  </div>
597
- </div>`;
598
- })
599
- .join('');
600
- },
601
- })}
602
- </section>
603
- <section class="d-flex">
604
- <div class="flex-fill"></div>
605
- <div class="${gClass('price-container')}">
606
- <div class="${gClass(['price-row', 'text-2'])}">
607
- <div>小計總額(合計)</div>
608
- <div>NT. ${(vm.cartData.total + vm.cartData.discount - vm.cartData.shipment_fee + vm.cartData.use_rebate).toLocaleString()}</div>
609
- </div>
610
- <div class="${gClass(['price-row', 'text-2'])}">
611
- <div>運費</div>
612
- <div>NT. ${vm.cartData.shipment_fee.toLocaleString()}</div>
613
- </div>
614
- <div class="${gClass(['price-row', 'text-2'])}">
615
- <div>優惠代碼</div>
616
- <div style="cursor: pointer; color: #3564c0;" onclick="${gvc.event(()=>{
617
- this.viewDialog({
618
- gvc: gvc,
619
- title: '可使用的優惠券',
620
- tag: '',
621
- innerHTML: (gvc: GVC) => {
622
- return gvc.bindView(
623
- (() => {
624
- const id = glitter.getUUID();
625
- const vmi = {
626
- dataList: [] as Voucher[],
627
- }
628
- const isWebsite = document.body.clientWidth > 768;
629
- let loading = true;
630
- return {
631
- bind: id,
632
- view: () => {
633
- if (loading) {
634
- return html`<div style="height: 400px">${spinner()}</div>`;
635
- } else {
636
- if (vmi.dataList.length === 0) {
637
- return html`<div class="d-flex align-items-center justify-content-center flex-column w-100 mx-auto">
638
- <lottie-player
639
- style="max-width: 100%;width: 300px;"
640
- src="https://assets10.lottiefiles.com/packages/lf20_rc6CDU.json"
641
- speed="1"
642
- loop="true"
643
- background="transparent"
644
- ></lottie-player>
645
- <span class="mb-5 fs-5">目前沒有任何優惠券呦</span>
646
- </div>`;
647
- }
956
+ </div>
957
+ </div>
958
+ <div>
959
+ ${vm.cartData.voucherList
960
+ .filter((dd: any) => {
961
+ return dd.bind.find((d2: any) => {
962
+ return d2.id === item.id;
963
+ });
964
+ })
965
+ .map((dd: any) => {
966
+ return `<div class="fs-6 w-100 " ><i class="fa-solid fa-tickets-perforated me-2"></i>${dd.title}</div>`;
967
+ })
968
+ .join('<div class="my-1"></div>')}
969
+ </div>
970
+ </div>
971
+ `;
972
+ })
973
+ .join('');
974
+ },
975
+ })}
976
+ </section>
977
+ <section class="d-flex">
978
+ <div class="flex-fill"></div>
979
+ <div class="${gClass('price-container')}">
980
+ <div class="${gClass(['price-row', 'text-2'])}">
981
+ <div>商品總計</div>
982
+ <div>NT. ${(vm.cartData.total + vm.cartData.discount - vm.cartData.shipment_fee + vm.cartData.use_rebate).toLocaleString()}</div>
983
+ </div>
984
+ <div class="${gClass(['price-row', 'text-2'])}">
985
+ <div>運費</div>
986
+ <div>NT. ${vm.cartData.shipment_fee.toLocaleString()}</div>
987
+ </div>
988
+ <div class="${gClass(['price-row', 'text-2'])}">
989
+ <div>優惠券折抵</div>
990
+ <div>- NT. ${vm.cartData.discount.toLocaleString()}</div>
991
+ </div>
992
+ <div class="${gClass(['price-row', 'text-2'])}">
993
+ <div>優惠代碼</div>
994
+ <div
995
+ style="cursor: pointer; color: #3564c0;"
996
+ onclick="${gvc.event(() => {
997
+ this.viewDialog({
998
+ gvc: gvc,
999
+ title: '可使用的優惠券',
1000
+ tag: '',
1001
+ innerHTML: (gvc: GVC) => {
1002
+ return gvc.bindView(
1003
+ (() => {
1004
+ const id = glitter.getUUID();
1005
+ const vmi = {
1006
+ dataList: [] as Voucher[],
1007
+ };
1008
+ const isWebsite = document.body.clientWidth > 768;
1009
+ let loading = true;
1010
+ return {
1011
+ bind: id,
1012
+ view: () => {
1013
+ if (loading) {
1014
+ return html`<div style="height: 400px">${spinner()}</div>`;
1015
+ } else {
1016
+ // if (vmi.dataList.length === 0) {
1017
+ // return html`<div class="d-flex align-items-center justify-content-center flex-column w-100 mx-auto">
1018
+ // <lottie-player
1019
+ // style="max-width: 100%;width: 300px;"
1020
+ // src="https://assets10.lottiefiles.com/packages/lf20_rc6CDU.json"
1021
+ // speed="1"
1022
+ // loop="true"
1023
+ // background="transparent"
1024
+ // ></lottie-player>
1025
+ // <span class="mb-5 fs-5">目前沒有任何優惠券呦</span>
1026
+ // </div>`;
1027
+ // }
648
1028
 
649
- const header = [
650
- {
651
- title: '優惠券名稱',
652
- },
653
- {
654
- title: '優惠券代碼',
655
- },
656
- {
657
- title: '使用期限',
658
- },
659
- {
660
- title: '',
661
- },
662
- ];
1029
+ const header = [
1030
+ {
1031
+ title: '優惠券名稱',
1032
+ },
1033
+ {
1034
+ title: '優惠券代碼',
1035
+ },
1036
+ {
1037
+ title: '使用期限',
1038
+ },
1039
+ {
1040
+ title: '',
1041
+ },
1042
+ ];
663
1043
 
664
-
665
- function formatText(item: UserVoucher) {
666
- return [
667
- item.title,
668
- item.code,
669
- (() => {
670
- const endText = item.end_ISO_Date ? glitter.ut.dateFormat(new Date(item.end_ISO_Date), 'yyyy/MM/dd') : '無使用期限';
671
- return `${glitter.ut.dateFormat(new Date(item.start_ISO_Date), 'yyyy/MM/dd')} ~ ${endText}`;
672
- })(),
673
- item.usePass ? html`<button
674
- class="${gClass('button-bgr')} my-2"
675
- style="max-width: 150px;"
676
- onclick="${gvc.event(() => {
677
- vm.cartData.code =item.code
678
- refreshCartData();
679
- gvc.closeDialog();
680
- })}"
681
- >
682
- <span
683
- class="${gClass('button-text')}">選擇使用</span>
684
- </button>` :
685
- html`<button
686
- class="${gClass('button-bgr-disable')} my-2"
687
- style="max-width: 150px; cursor: not-allowed"
688
- >
689
- <span
690
- class="${gClass('button-text')}">未達使用標準</span>
691
- </button>` ,
692
- ];
693
- }
1044
+ function formatText(item: UserVoucher) {
1045
+ return [
1046
+ item.title,
1047
+ item.code,
1048
+ (() => {
1049
+ const endText = item.end_ISO_Date
1050
+ ? glitter.ut.dateFormat(new Date(item.end_ISO_Date), 'yyyy/MM/dd')
1051
+ : '無使用期限';
1052
+ return `${glitter.ut.dateFormat(
1053
+ new Date(item.start_ISO_Date),
1054
+ 'yyyy/MM/dd'
1055
+ )} ~ ${endText}`;
1056
+ })(),
1057
+ item.usePass
1058
+ ? html`<button
1059
+ class="${gClass('button-bgr')} my-2"
1060
+ style="max-width: 150px;"
1061
+ onclick="${gvc.event(() => {
1062
+ ApiCart.setCart((cartItem) => {
1063
+ cartItem.code = item.code;
1064
+ refreshCartData();
1065
+ gvc.closeDialog();
1066
+ });
1067
+ })}"
1068
+ >
1069
+ <span class="${gClass('button-text')}">選擇使用</span>
1070
+ </button>`
1071
+ : html`<button
1072
+ class="${gClass('button-bgr-disable')} my-2"
1073
+ style="max-width: 150px; cursor: not-allowed"
1074
+ >
1075
+ <span class="${gClass('button-text')}">未達使用標準</span>
1076
+ </button>`,
1077
+ ];
1078
+ }
694
1079
 
695
- const dialog = new ShareDialog(gvc.glitter);
696
-
697
- const cloneCart = JSON.parse(JSON.stringify(vm.cartData))
698
-
699
- function checkCodeValue(code:string){
700
- cloneCart.code = code
701
- cloneCart.line_items = cloneCart.lineItems
702
- dialog.dataLoading({visible: true});
703
- ApiShop.getCheckout(cloneCart).then((r) => {
704
- dialog.dataLoading({visible: false});
705
- if(r.result && r.response.data && r.response.data.voucherList.length > 0){
706
- vm.cartData.code =code
707
- refreshCartData();
708
- gvc.closeDialog();
709
- }else{
710
- dialog.errorMessage({
711
- text: '此代碼無法使用'
712
- });
713
- }
714
-
715
- });
716
- }
1080
+ const dialog = new ShareDialog(gvc.glitter);
717
1081
 
718
- if (isWebsite) {
719
- const flexList = [1.2, 1, 1.5, 1.5];
1082
+ const cloneCart = JSON.parse(JSON.stringify(vm.cartData));
720
1083
 
721
- return html`
722
- <div>
723
- <div class="d-flex align-items-center mb-2">
724
- <label class="${gClass('label')} mb-0" style="min-width: 80px;">輸入代碼</label>
725
- <input class="${gClass('input')}" type="text" onchange="${gvc.event((e)=>{
726
- checkCodeValue(e.value)
727
- })}"/>
728
- </div>
729
- </div>
730
- <div class="w-100 d-sm-flex py-4 um-th-bar">
731
- ${header
732
- .map((item, index) => {
733
- return html`<div class="um-th" style="flex: ${flexList[index]};">${item.title}</div>`;
734
- })
735
- .join('')}
736
- </div>
737
- ${vmi.dataList
738
- .map((item, t1) => {
739
- const fText = formatText(item.content)
740
- return html`<div class="w-100 d-sm-flex py-1 align-items-center">
741
- ${fText
742
- .map((dd, t2) => {
743
- return html`<div class="um-td ${t2 === fText.length - 1 ? 'text-center':''}" style="flex: ${flexList[t2]}">${dd}</div>`;
744
- })
745
- .join('')}
746
- </div>`;
747
- })
748
- .join('')}
749
- `;
750
- }
1084
+ function checkCodeValue(code: string) {
1085
+ cloneCart.code = code;
1086
+ cloneCart.line_items = cloneCart.lineItems;
1087
+ dialog.dataLoading({ visible: true });
1088
+ ApiShop.getCheckout(cloneCart).then((r) => {
1089
+ dialog.dataLoading({ visible: false });
1090
+ if (
1091
+ r.result &&
1092
+ r.response.data &&
1093
+ r.response.data.voucherList.some((dd: any) => {
1094
+ return dd.code === code;
1095
+ })
1096
+ ) {
1097
+ ApiCart.setCart((cartItem) => {
1098
+ cartItem.code = code;
1099
+ refreshCartData();
1100
+ gvc.closeDialog();
1101
+ });
1102
+ } else {
1103
+ dialog.errorMessage({
1104
+ text: '此代碼無法使用',
1105
+ });
1106
+ }
1107
+ });
1108
+ }
751
1109
 
752
- return html`<div>
753
- <div class="d-flex">
754
- <label class="${gClass('label')}">輸入代碼</label>
755
- <input class="${gClass('input')}" type="text" />
756
- <button class="${gClass('button-bgr')}" onclick="${gvc.event((e)=>{
757
- checkCodeValue(e.value)
758
- })}">
759
- <span class="${gClass('button-text')}">確認</span>
760
- </button>
761
- </div>
762
- <div class="w-100 d-sm-none mb-3 s162413">
763
- ${vmi.dataList
764
- .map((item) => {
765
- return html`<div class="um-mobile-area">
766
- ${formatText(item.content)
767
- .map((dd, index) => {
768
- if (header[index].title === '') {
769
- return dd;
770
- }
771
- return html`<div class="um-mobile-text">${header[index].title}: ${dd}</div>`;
772
- })
773
- .join('')}
774
- </div>`;
775
- })
776
- .join('')}
777
- </div>
778
- </div>`;
779
- }
780
- },
781
- divCreate: {},
782
- onCreate: () => {
783
- if (loading) {
784
- function isNowBetweenDates(startIso: string, endIso: string): boolean {
785
- const now = new Date();
786
- const startDate = new Date(startIso);
787
- const endDate = new Date(endIso);
788
-
789
- // 確保 `startIso` 和 `endIso` 是有效的日期
790
- if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
791
- return true
792
- }
793
-
794
- // 判斷現在時間是否在範圍內
795
- return now >= startDate && now <= endDate;
796
- }
1110
+ if (isWebsite) {
1111
+ const flexList = [1.2, 1, 1.5, 1.5];
797
1112
 
798
- gvc.addMtScript(
799
- [{ src: `https://unpkg.com/@lottiefiles/lottie-player@latest/dist/lottie-player.js` }],
800
- () => {
801
- ApiShop.getVoucher({
802
- page: 0,
803
- limit: 10000,
804
- data_from: 'user',
805
- }).then(async (res) => {
806
- if (res.result && res.response.data) {
807
- vmi.dataList = res.response.data.filter((item: Voucher) => {
808
- return item.content.trigger === 'code' && isNowBetweenDates(item.content.start_ISO_Date, item.content.end_ISO_Date)
809
- });
810
- } else {
811
- vmi.dataList = [];
812
- }
813
- const cloneCart = JSON.parse(JSON.stringify(vm.cartData))
814
- Promise.all(vmi.dataList.map((voucher,index) => {
815
- return new Promise<{ code:string, response:any }>((resolve) => {
816
- const code = voucher.content.code
817
- cloneCart.code = code
818
- cloneCart.line_items = cloneCart.lineItems
819
- ApiShop.getCheckout(cloneCart).then((response) => {
820
- resolve({
821
- code,
822
- response
823
- });
824
- });
825
- })
826
- })).then( (resolveArray: { code:string, response:any }[]) =>{
827
- vmi.dataList = vmi.dataList.map((item) => {
828
- const f = resolveArray.find(res => {
829
- return item.content.code === res.code;
830
- })
831
- if(f){
832
- const r = f.response
833
- if(r.result && r.response.data){
834
- item.content.usePass = r.response.data.voucherList.length > 0
835
- }
836
- }
837
- return item
838
- })
839
- loading = false;
840
- gvc.notifyDataChange(id);
841
- })
842
- });
843
- },
844
- () => {}
845
- );
846
- }
847
- },
848
- };
849
- })()
850
- )
851
- }
852
- }
853
- )
854
- })}">${vm.cartData.code ?? '新增'}</div>
855
- </div>
856
- <div class="${gClass(['price-row', 'text-2'])}">
857
- <div>購物金折抵</div>
858
- <div>- NT. ${vm.cartData.discount.toLocaleString()}</div>
859
- </div>
860
- <div class="${gClass(['price-row', 'text-2'])}">
861
- <div
862
- style=" justify-content: flex-start; align-items: center; display: inline-flex;border:1px solid #EAEAEA;border-radius: 10px;overflow: hidden; ${document
863
- .body.clientWidth > 768
864
- ? 'gap: 18px; '
865
- : 'flex-direction: column; gap: 0px; '}"
866
- class="w-100"
867
- >
868
- <input
869
- class="flex-fill ${gClass('group-input')}"
870
- placeholder="請輸入購物金"
871
- value="${vm.cartData.use_rebate || ''}"
872
- />
873
- <div class="${gClass('group-button')}" >
874
- <div class="${gClass('button-text')}"
875
- onclick="${gvc.event((e) => {
876
- let text = e.value;
877
- const dialog = new ShareDialog(gvc.glitter);
878
- const textNumber = parseInt(text, 10);
879
- const subtotal = vm.cartData.total - vm.cartData.shipment_fee + vm.cartData.use_rebate;
880
- if (!CheckInput.isNumberString(text)) {
881
- dialog.infoMessage({text: '僅限輸入數字'});
882
- } if(textNumber){
883
- dialog.errorMessage({text: `請輸入 0 到 ${ Math.min(textNumber, subtotal) } 的數值` })
884
- } else {
885
- vm.cartData.use_rebate = text;
886
- refreshCartData()
887
- }
888
- })}">
889
- 套用
890
- </div>
891
- </div>
892
- </div>
893
- </div>
894
- <div class="${gClass(['price-row', 'text-2'])}">
1113
+ return html`
1114
+ <div>
1115
+ <div class="d-flex align-items-center mb-2">
1116
+ <label class="${gClass('label')} mb-0" style="min-width: 80px;">輸入代碼</label>
1117
+ <input
1118
+ class="${gClass('input')}"
1119
+ type="text"
1120
+ onchange="${gvc.event((e) => {
1121
+ checkCodeValue(e.value);
1122
+ })}"
1123
+ />
1124
+ </div>
1125
+ </div>
1126
+ <div class="w-100 d-sm-flex py-4 um-th-bar">
1127
+ ${header
1128
+ .map((item, index) => {
1129
+ return html`<div class="um-th" style="flex: ${flexList[index]};">
1130
+ ${item.title}
1131
+ </div>`;
1132
+ })
1133
+ .join('')}
1134
+ </div>
1135
+ ${vmi.dataList
1136
+ .map((item, t1) => {
1137
+ const fText = formatText(item.content);
1138
+ return html`<div class="w-100 d-sm-flex py-1 align-items-center">
1139
+ ${fText
1140
+ .map((dd, t2) => {
1141
+ return html`<div
1142
+ class="um-td ${t2 === fText.length - 1 ? 'text-center' : ''}"
1143
+ style="flex: ${flexList[t2]}"
1144
+ >
1145
+ ${dd}
1146
+ </div>`;
1147
+ })
1148
+ .join('')}
1149
+ </div>`;
1150
+ })
1151
+ .join('')}
1152
+ `;
1153
+ }
895
1154
 
896
- ${(()=>{
897
- const sum = vm.cartData.user_rebate_sum || 0
898
-
899
- if(!vm.cartData.useRebateInfo){
900
- return '';
901
- }
902
-
903
- const info = vm.cartData.useRebateInfo;
904
- if(info.condition){
905
- return `還差$ ${info.condition.toLocaleString()} 即可使用購物金折抵`
906
- }
907
-
908
- if(info.limit){
909
- return `您目前剩餘 ${sum || 0} 點購物金<br />此份訂單最多可折抵 ${info.limit.toLocaleString()} 點購物金`
910
- }else{
911
- return `您目前剩餘 ${sum || 0} 點購物金`
912
- }
913
-
914
- })()}
1155
+ return html` <div>
1156
+ <div class="d-flex flex-column flex-sm-row align-items-center ">
1157
+ <div class="d-flex align-items-center">
1158
+ <input
1159
+ class="${gClass('input')}"
1160
+ type="text"
1161
+ style="border-top-right-radius: 0;border-bottom-right-radius: 0px;"
1162
+ placeholder="請輸入優惠代碼"
1163
+ />
1164
+ <button
1165
+ class="${gClass('button-bgr')}"
1166
+ style="width:100px;border-top-left-radius: 0;border-bottom-left-radius: 0px;"
1167
+ onclick="${gvc.event((e) => {
1168
+ checkCodeValue(e.value);
1169
+ })}"
1170
+ >
1171
+ <span class="${gClass('button-text')}" style="">確認</span>
1172
+ </button>
1173
+ </div>
1174
+ </div>
1175
+ <div class="w-100 d-sm-none mb-3 s162413">
1176
+ ${vmi.dataList
1177
+ .map((item) => {
1178
+ return html` <div class="um-mobile-area">
1179
+ ${formatText(item.content)
1180
+ .map((dd, index) => {
1181
+ if (header[index].title === '') {
1182
+ return dd;
1183
+ }
1184
+ return html` <div class="um-mobile-text">
1185
+ ${header[index].title}: ${dd}
1186
+ </div>`;
1187
+ })
1188
+ .join('')}
1189
+ </div>`;
1190
+ })
1191
+ .join('')}
1192
+ </div>
1193
+ </div>`;
1194
+ }
1195
+ },
1196
+ divCreate: {},
1197
+ onCreate: () => {
1198
+ if (loading) {
1199
+ function isNowBetweenDates(startIso: string, endIso: string): boolean {
1200
+ const now = new Date();
1201
+ const startDate = new Date(startIso);
1202
+ const endDate = new Date(endIso);
1203
+
1204
+ // 確保 `startIso` 和 `endIso` 是有效的日期
1205
+ if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
1206
+ return true;
1207
+ }
1208
+
1209
+ // 判斷現在時間是否在範圍內
1210
+ return now >= startDate && now <= endDate;
1211
+ }
1212
+
1213
+ gvc.addMtScript(
1214
+ [{ src: `https://unpkg.com/@lottiefiles/lottie-player@latest/dist/lottie-player.js` }],
1215
+ () => {
1216
+ ApiShop.getVoucher({
1217
+ page: 0,
1218
+ limit: 10000,
1219
+ data_from: 'user',
1220
+ }).then(async (res) => {
1221
+ if (res.result && res.response.data) {
1222
+ vmi.dataList = res.response.data.filter((item: Voucher) => {
1223
+ return (
1224
+ item.content.trigger === 'code' &&
1225
+ isNowBetweenDates(item.content.start_ISO_Date, item.content.end_ISO_Date)
1226
+ );
1227
+ });
1228
+ } else {
1229
+ vmi.dataList = [];
1230
+ }
1231
+ const cloneCart = JSON.parse(JSON.stringify(vm.cartData));
1232
+ Promise.all(
1233
+ vmi.dataList.map((voucher, index) => {
1234
+ return new Promise<{ code: string; response: any }>((resolve) => {
1235
+ const code = voucher.content.code;
1236
+ cloneCart.code = code;
1237
+ cloneCart.line_items = cloneCart.lineItems;
1238
+ ApiShop.getCheckout(cloneCart).then((response) => {
1239
+ resolve({
1240
+ code,
1241
+ response,
1242
+ });
1243
+ });
1244
+ });
1245
+ })
1246
+ ).then((resolveArray: { code: string; response: any }[]) => {
1247
+ vmi.dataList = vmi.dataList.map((item) => {
1248
+ const f = resolveArray.find((res) => {
1249
+ return item.content.code === res.code;
1250
+ });
1251
+ if (f) {
1252
+ const r = f.response;
1253
+ if (r.result && r.response.data) {
1254
+ item.content.usePass = r.response.data.voucherList.some((dd: any) => {
1255
+ return dd.code === f.code;
1256
+ });
1257
+ }
1258
+ }
1259
+ return item;
1260
+ });
1261
+ loading = false;
1262
+ gvc.notifyDataChange(id);
1263
+ });
1264
+ });
1265
+ },
1266
+ () => {}
1267
+ );
1268
+ }
1269
+ },
1270
+ };
1271
+ })()
1272
+ );
1273
+ },
1274
+ });
1275
+ })}"
1276
+ >
1277
+ ${vm.cartData.code
1278
+ ? html`${vm.cartData.code}<i
1279
+ class="fa-solid fa-xmark-large ms-2"
1280
+ style="cursor: pointer;"
1281
+ onclick="${gvc.event((e, event) => {
1282
+ event.stopPropagation();
1283
+ ApiCart.setCart((cartItem) => {
1284
+ cartItem.code = '';
1285
+ refreshCartData();
1286
+ });
1287
+ })}"
1288
+ ></i>`
1289
+ : '新增'}
915
1290
  </div>
916
1291
  </div>
917
- </section>`;
918
- },
919
- };
920
- })()
921
- )}
1292
+ ${(() => {
1293
+ if (!GlobalUser.token) {
1294
+ return ``;
1295
+ } else {
1296
+ return html`${(() => {
1297
+ let tempRebate: number = 0;
1298
+ const dialog = new ShareDialog(gvc.glitter);
1299
+ return html`<div class="${gClass(['price-row', 'text-2'])}">
1300
+ <div>購物金折抵</div>
1301
+ <div>- NT. ${vm.cartData.use_rebate.toLocaleString()}</div>
1302
+ </div>
1303
+
1304
+ <div class="${gClass(['price-row', 'text-2'])}">
1305
+ <div
1306
+ style="justify-content: flex-start; align-items: center; display: inline-flex;border:1px solid #EAEAEA;border-radius: 10px;overflow: hidden; ${document
1307
+ .body.clientWidth > 768
1308
+ ? 'gap: 18px; '
1309
+ : ' gap: 0px; '}"
1310
+ class="w-100"
1311
+ >
1312
+ <input
1313
+ class="flex-fill ${gClass('group-input')}"
1314
+ placeholder="請輸入購物金"
1315
+ style="${document.body.clientWidth < 800 ? `width:calc(100% - 150px) !important;` : ``}"
1316
+ value="${vm.cartData.use_rebate || ''}"
1317
+ onchange="${gvc.event((e, event) => {
1318
+ if (CheckInput.isNumberString(e.value)) {
1319
+ tempRebate = parseInt(e.value, 10);
1320
+ } else {
1321
+ dialog.errorMessage({ text: `請輸入數值` });
1322
+ gvc.notifyDataChange(ids.page);
1323
+ }
1324
+ })}"
1325
+ />
1326
+ <div class="${gClass('group-button')}">
1327
+ <div
1328
+ class="${gClass('button-text')}"
1329
+ onclick="${gvc.event(async (e) => {
1330
+ const sum: number = await new Promise((resolve, reject) => {
1331
+ ApiShop.getRebate({}).then(async (res) => {
1332
+ if (res.result && res.response.sum) {
1333
+ resolve(res.response.sum);
1334
+ } else {
1335
+ resolve(0);
1336
+ }
1337
+ });
1338
+ });
1339
+ const limit = vm.cartData.total - vm.cartData.shipment_fee + vm.cartData.use_rebate;
1340
+ if (tempRebate > Math.min(sum, limit)) {
1341
+ dialog.errorMessage({ text: `請輸入 0 到 ${Math.min(sum, limit)} 的數值` });
1342
+ } else {
1343
+ ApiCart.setCart((cartItem) => {
1344
+ cartItem.use_rebate = tempRebate;
1345
+ refreshCartData();
1346
+ });
1347
+ }
1348
+ })}"
1349
+ >
1350
+ 套用
1351
+ </div>
1352
+ </div>
1353
+ </div>
1354
+ </div>`;
1355
+ })()}
1356
+ <div class="${gClass(['price-row', 'text-2'])}">
1357
+ ${(() => {
1358
+ return gvc.bindView(() => {
1359
+ return {
1360
+ bind: gvc.glitter.getUUID(),
1361
+ view: async () => {
1362
+ const sum = await new Promise((resolve, reject) => {
1363
+ ApiShop.getRebate({}).then(async (res) => {
1364
+ if (res.result && res.response.sum) {
1365
+ resolve(res.response.sum);
1366
+ } else {
1367
+ resolve(0);
1368
+ }
1369
+ });
1370
+ });
1371
+ if (!vm.cartData.useRebateInfo) {
1372
+ return '';
1373
+ }
1374
+
1375
+ const info = vm.cartData.useRebateInfo;
1376
+ if (info.condition) {
1377
+ return `還差$ ${info.condition.toLocaleString()} 即可使用購物金折抵`;
1378
+ }
1379
+ if (info.limit) {
1380
+ return `您目前剩餘 ${
1381
+ sum || 0
1382
+ } 點購物金<br />此份訂單最多可折抵 ${info.limit.toLocaleString()} 點購物金`;
1383
+ } else {
1384
+ return `您目前剩餘 ${sum || 0} 點購物金`;
1385
+ }
1386
+ },
1387
+ };
1388
+ });
1389
+ })()}
1390
+ </div>`;
1391
+ }
1392
+ })()}
1393
+ </div>
1394
+ </section>`;
1395
+ },
1396
+ };
1397
+ })()
1398
+ )}
922
1399
  <section class="border-bottom"></section>
923
1400
  <section class="d-flex">
924
1401
  <div class="flex-fill"></div>
@@ -933,228 +1410,1080 @@ this.viewDialog({
933
1410
  <div class="${gClass('banner-bgr')}">
934
1411
  <span class="${gClass('banner-text')}">付款及配送方式</span>
935
1412
  </div>
1413
+ ${vm.cartData.shipment_info ? `<div class="pt-2 mx-2 mx-sm-3">${vm.cartData.shipment_info}</div>` : ''}
936
1414
  <div class="row m-0 my-md-3">
937
- <div class="col-12 col-md-6">
1415
+ <div class="col-12 col-md-6 mb-2 mb-sm-0">
938
1416
  <label class="${gClass('label')}">付款方式</label>
939
1417
  <div>
940
- <select class="w-100 ${gClass('select')}"
941
- onchange="${gvc.event((e, event) => {
942
- vm.cartData.customer_info.payment_select = e.value;
943
- this.storeLocalData(vm.cartData)
944
- refreshCartData()
945
- })}">
1418
+ <select
1419
+ class="w-100 ${gClass('select')}"
1420
+ onchange="${gvc.event((e, event) => {
1421
+ vm.cartData.customer_info.payment_select = e.value;
1422
+ this.storeLocalData(vm.cartData);
1423
+ refreshCartData();
1424
+ })}"
1425
+ >
946
1426
  ${(() => {
947
- return this.getPaymentMethod(vm.cartData).map((dd: {
948
- name: string,
949
- value: string
950
- }) => {
951
- return `<option value="${dd.value}" ${(localStorage.getItem('checkout-payment') === dd.value) ? `selected` : ``}>${dd.name}</option>`
952
- }).join('')
953
- })()}
1427
+ return this.getPaymentMethod(vm.cartData)
1428
+ .map((dd: { name: string; value: string }) => {
1429
+ return `<option value="${dd.value}" ${localStorage.getItem('checkout-payment') === dd.value ? `selected` : ``}>${dd.name}</option>`;
1430
+ })
1431
+ .join('');
1432
+ })()}
954
1433
  </select>
955
1434
  </div>
956
1435
  </div>
957
- <div class="col-12 col-md-6">
1436
+ <div class="col-12 col-md-6 mb-2">
958
1437
  <label class="${gClass('label')}">配送方式</label>
959
1438
  <div>
960
- <select class="w-100 ${gClass('select')}"
961
- onchange="${gvc.event((e, event) => {
962
- vm.cartData.user_info.shipment = e.value;
963
- this.storeLocalData(vm.cartData)
964
- refreshCartData()
965
- })}">
1439
+ <select
1440
+ class="w-100 ${gClass('select')}"
1441
+ onchange="${gvc.event((e, event) => {
1442
+ [
1443
+ 'CVSStoreName',
1444
+ 'MerchantTradeNo',
1445
+ 'LogisticsSubType',
1446
+ 'CVSStoreID',
1447
+ 'CVSStoreName',
1448
+ 'CVSTelephone',
1449
+ 'CVSOutSide',
1450
+ 'ExtraData',
1451
+ 'CVSAddress',
1452
+ ].map((dd) => {
1453
+ gvc.glitter.setUrlParameter(dd);
1454
+ });
1455
+ vm.cartData.user_info.shipment = e.value;
1456
+ this.storeLocalData(vm.cartData);
1457
+ refreshCartData();
1458
+ })}"
1459
+ >
966
1460
  ${(() => {
967
- return this.getShipmentMethod(vm.cartData).map((dd: {
968
- name: string,
969
- value: string
970
- }) => {
971
- return `<option value="${dd.value}" ${(vm.cartData.user_info.shipment === dd.value) ? `selected` : ``}>${dd.name}</option>`
972
- }).join('')
973
- })()}
1461
+ return this.getShipmentMethod(vm.cartData)
1462
+ .map((dd: { name: string; value: string }) => {
1463
+ return `<option value="${dd.value}" ${vm.cartData.user_info.shipment === dd.value ? `selected` : ``}>${dd.name}</option>`;
1464
+ })
1465
+ .join('');
1466
+ })()}
974
1467
  </select>
975
1468
  </div>
976
1469
  </div>
1470
+ ${vm.cartData.user_info.shipment === 'normal'
1471
+ ? `<div class="col-12 col-md-6 mb-2">
1472
+ <label class="${gClass('label')}">配送地址</label>
1473
+ <input class="${gClass('input')}" type="address" placeholder="請輸入配送地址" value="${
1474
+ vm.cartData.user_info.address || ''
1475
+ }" onchange="${gvc.event((e, event) => {
1476
+ vm.cartData.user_info.address = e.value;
1477
+ this.storeLocalData(vm.cartData);
1478
+ })}">
1479
+ </div>`
1480
+ : ``}
977
1481
  <div class="col-12 ${['UNIMARTC2C', 'FAMIC2C', 'HILIFEC2C', 'OKMARTC2C'].includes(vm.cartData.user_info.shipment) ? `` : `d-none`}">
978
- <button class="${gClass('button-bgr')}" onclick="${gvc.event(() => {
979
- ApiDelivery.storeMaps({
980
- returnURL: location.href,
981
- logistics: vm.cartData.user_info.shipment,
982
- }).then(async (res) => {
983
- $('body').html(res.response.form);
984
- (document.querySelector('#submit') as any).click();
985
- })
986
- })}">
987
- <span class="${gClass('button-text')}">${(() => {
988
- let cvs = glitter.getUrlParameter('CVSStoreName')
989
- if (decodeURIComponent(cvs)) {
990
- return `${decodeURIComponent(cvs)} 『 點擊重選門市 』`
991
- } else {
992
- return `選擇配送門市`
993
- }
994
- })()}</span>
1482
+ <button
1483
+ class="${gClass('button-bgr')}"
1484
+ onclick="${gvc.event(() => {
1485
+ ApiDelivery.storeMaps({
1486
+ returnURL: location.href,
1487
+ logistics: vm.cartData.user_info.shipment,
1488
+ }).then(async (res) => {
1489
+ $('body').html(res.response.form);
1490
+ (document.querySelector('#submit') as any).click();
1491
+ });
1492
+ })}"
1493
+ >
1494
+ <span class="${gClass('button-text')}"
1495
+ >${(() => {
1496
+ let cvs = glitter.getUrlParameter('CVSStoreName') || '';
1497
+ if (decodeURIComponent(cvs)) {
1498
+ return `${decodeURIComponent(cvs)} 『 點擊重選門市 』`;
1499
+ } else {
1500
+ return `選擇配送門市`;
1501
+ }
1502
+ })()}</span
1503
+ >
995
1504
  </button>
996
1505
  </div>
1506
+ ${(() => {
1507
+ try {
1508
+ vm.cartData.user_info.custom_form_delivery = vm.cartData.user_info.custom_form_delivery ?? {};
1509
+ const form_array = JSON.parse(
1510
+ JSON.stringify(
1511
+ this.getShipmentMethod(vm.cartData).find((dd: any) => {
1512
+ return vm.cartData.user_info.shipment === dd.value;
1513
+ }).form
1514
+ )
1515
+ );
1516
+ form_array.map((dd: any) => {
1517
+ dd.col = '4';
1518
+ dd.form_config.title_style = {
1519
+ list: [
1520
+ {
1521
+ class: gClass('label') + ' mb-2',
1522
+ style: 'return `color:${glitter.share.globalValue[`theme_color.0.title`]} !important;font-size:16px !important;`',
1523
+ stylist: [],
1524
+ dataType: 'code',
1525
+ style_from: 'code',
1526
+ classDataType: 'static',
1527
+ },
1528
+ ],
1529
+ class: 'form-label',
1530
+ style: 'font-size: 20px;font-style: normal;font-weight: 400;line-height: 140%; color:#393939 !important;',
1531
+ stylist: [],
1532
+ version: 'v2',
1533
+ dataType: 'static',
1534
+ style_from: 'code',
1535
+ classDataType: 'static',
1536
+ };
1537
+ dd.form_config.input_style = {
1538
+ list: [
1539
+ {
1540
+ class: gClass('input'),
1541
+ style: 'return `border-radius: ${widget.formData.radius}px !important;`',
1542
+ stylist: [],
1543
+ dataType: 'code',
1544
+ style_from: 'code',
1545
+ classDataType: 'static',
1546
+ },
1547
+ ],
1548
+ class: ' mb-3',
1549
+ style: 'background: #FFF;',
1550
+ stylist: [],
1551
+ version: 'v2',
1552
+ dataType: 'static',
1553
+ style_from: 'code',
1554
+ classDataType: 'static',
1555
+ };
1556
+ });
1557
+ return [
1558
+ FormWidget.editorView({
1559
+ gvc: gvc,
1560
+ array: form_array,
1561
+ refresh: () => {
1562
+ this.storeLocalData(vm.cartData);
1563
+ },
1564
+ formData: vm.cartData.user_info.custom_form_delivery,
1565
+ }),
1566
+ ].join('');
1567
+ } catch (e) {
1568
+ console.error(e);
1569
+ return ``;
1570
+ }
1571
+ })()}
997
1572
  </div>
998
1573
  </section>
999
- <section>
1574
+ <section class="${['UNIMARTC2C', 'FAMIC2C', 'HILIFEC2C', 'OKMARTC2C'].includes(vm.cartData.user_info.shipment) ? `` : `mt-4`}">
1000
1575
  <div class="${gClass('banner-bgr')}">
1001
1576
  <span class="${gClass('banner-text')}">顧客資料</span>
1002
1577
  </div>
1003
- <div class="row m-0 my-md-3">
1004
- ${[{
1005
- name:'姓名',
1006
- key:'name'
1007
- },{
1008
- name:'聯絡電話',
1009
- key:'phone'
1010
- },{
1011
- name:'電子信箱',
1012
- key:'email'
1013
- }].map((dd)=>{
1014
-
1015
- return `<div class="col-12 col-md-6">
1016
- <label class="${gClass('label')}">${dd.name}</label>
1017
- <input class="${gClass('input')}" type="${dd.key}" onclick="${gvc.event((e,event)=>{
1018
- vm.cartData.customer_info[dd.key]=e.value
1019
- this.storeLocalData(vm.cartData)
1020
- })}"/>
1021
- </div>`
1022
- }).join('')}
1578
+ <div class="row m-0 mt-3 mb-2">
1579
+ ${[
1580
+ {
1581
+ name: '姓名',
1582
+ key: 'name',
1583
+ },
1584
+ {
1585
+ name: '聯絡電話',
1586
+ key: 'phone',
1587
+ },
1588
+ {
1589
+ name: '電子信箱',
1590
+ key: 'email',
1591
+ },
1592
+ ]
1593
+ .map((dd) => {
1594
+ return html` <div class="col-12 col-md-4 mb-2">
1595
+ <label class="${gClass('label')}">${dd.name}</label>
1596
+ <input
1597
+ class="${gClass('input')}"
1598
+ type="${dd.key}"
1599
+ value="${vm.cartData.customer_info[dd.key] || ''}"
1600
+ onchange="${gvc.event((e, event) => {
1601
+ vm.cartData.customer_info[dd.key] = e.value;
1602
+ this.storeLocalData(vm.cartData);
1603
+ })}"
1604
+ />
1605
+ </div>`;
1606
+ })
1607
+ .join('')}
1023
1608
  </div>
1609
+ ${gvc.bindView(() => {
1610
+ const id = gvc.glitter.getUUID();
1611
+ const vm_info: {
1612
+ loading: boolean;
1613
+ list: any[];
1614
+ login_config: any;
1615
+ } = {
1616
+ loading: true,
1617
+ list: [],
1618
+ login_config: {},
1619
+ };
1620
+ ApiUser.getPublicConfig('custom_form_checkout', 'manager').then((res) => {
1621
+ vm_info.list = (res.response.value ?? { list: [] }).list;
1622
+ vm.cartData.custom_form_format = vm_info.list;
1623
+ gvc.notifyDataChange(id);
1624
+ });
1625
+ return {
1626
+ bind: id,
1627
+ view: () => {
1628
+ const form_array = JSON.parse(JSON.stringify(vm_info.list));
1629
+ form_array.map((dd: any) => {
1630
+ dd.col = '4';
1631
+ dd.form_config.title_style = {
1632
+ list: [
1633
+ {
1634
+ class: gClass('label') + ' mb-2',
1635
+ style: 'return `color:${glitter.share.globalValue[`theme_color.0.title`]} !important;font-size:16px !important;`',
1636
+ stylist: [],
1637
+ dataType: 'code',
1638
+ style_from: 'code',
1639
+ classDataType: 'static',
1640
+ },
1641
+ ],
1642
+ class: 'form-label',
1643
+ style: 'font-size: 20px;font-style: normal;font-weight: 400;line-height: 140%; color:#393939 !important;',
1644
+ stylist: [],
1645
+ version: 'v2',
1646
+ dataType: 'static',
1647
+ style_from: 'code',
1648
+ classDataType: 'static',
1649
+ };
1650
+ dd.form_config.input_style = {
1651
+ list: [
1652
+ {
1653
+ class: gClass('input'),
1654
+ style: 'return `border-radius: ${widget.formData.radius}px !important;`',
1655
+ stylist: [],
1656
+ dataType: 'code',
1657
+ style_from: 'code',
1658
+ classDataType: 'static',
1659
+ },
1660
+ ],
1661
+ class: ' mb-3',
1662
+ style: 'background: #FFF;',
1663
+ stylist: [],
1664
+ version: 'v2',
1665
+ dataType: 'static',
1666
+ style_from: 'code',
1667
+ classDataType: 'static',
1668
+ };
1669
+ });
1670
+ return [
1671
+ FormWidget.editorView({
1672
+ gvc: gvc,
1673
+ array: form_array,
1674
+ refresh: () => {
1675
+ this.storeLocalData(vm.cartData);
1676
+ },
1677
+ formData: vm.cartData.custom_form_data,
1678
+ }),
1679
+ ].join('');
1680
+ },
1681
+ divCreate: {
1682
+ class: `w-100 `,
1683
+ },
1684
+ };
1685
+ })}
1024
1686
  </section>
1025
1687
  <section>
1026
1688
  <div class="${gClass('banner-bgr')}">
1027
1689
  <span class="${gClass('banner-text')}">收件人資料</span>
1028
1690
  </div>
1029
- <div class="row m-0 my-md-3">
1030
- <div class="col-12 col-md-6">
1031
- <label class="${gClass('label')}">電子信箱</label>
1032
- <input class="${gClass('input')}" type="email"/>
1033
- </div>
1691
+
1692
+ ${gvc.bindView(() => {
1693
+ const id = 'invoice_place';
1694
+ const vm_info: {
1695
+ loading: boolean;
1696
+ list: any[];
1697
+ login_config: any;
1698
+ } = {
1699
+ loading: true,
1700
+ list: [],
1701
+ login_config: {},
1702
+ };
1703
+ //nouse
1704
+ let method = '';
1705
+ ApiShop.getInvoiceType().then((response: any) => {
1706
+ method = response.method;
1707
+ vm_info.loading = false;
1708
+ gvc.notifyDataChange(id);
1709
+ });
1710
+ const checkbox = this.getCheckedClass(gvc, '#393939');
1711
+ return {
1712
+ bind: id,
1713
+ view: () => {
1714
+ if (vm_info.loading) {
1715
+ return ``;
1716
+ }
1717
+ vm_info.list = [
1718
+ {
1719
+ col: '3',
1720
+ key: 'name',
1721
+ page: 'input',
1722
+ type: 'form_plugin_v2',
1723
+ group: '',
1724
+ title: '姓名',
1725
+ col_sm: '12',
1726
+ appName: 'cms_system',
1727
+ require: 'true',
1728
+ readonly: 'write',
1729
+ formFormat: '{}',
1730
+ moduleName: '輸入框',
1731
+ style_data: {
1732
+ input: {
1733
+ list: [],
1734
+ class: '',
1735
+ style: '',
1736
+ version: 'v2',
1737
+ },
1738
+ label: {
1739
+ list: [],
1740
+ class: 'form-label fs-base ',
1741
+ style: '',
1742
+ version: 'v2',
1743
+ },
1744
+ container: {
1745
+ list: [],
1746
+ class: '',
1747
+ style: '',
1748
+ version: 'v2',
1749
+ },
1750
+ },
1751
+ form_config: {
1752
+ type: 'name',
1753
+ title: '',
1754
+ input_style: { list: [], version: 'v2' },
1755
+ title_style: { list: [], version: 'v2' },
1756
+ place_holder: '請輸入姓名',
1757
+ },
1758
+ hidden_code: '',
1759
+ },
1760
+ {
1761
+ col: '3',
1762
+ key: 'phone',
1763
+ page: 'input',
1764
+ type: 'form_plugin_v2',
1765
+ group: '',
1766
+ title: '聯絡電話',
1767
+ col_sm: '12',
1768
+ appName: 'cms_system',
1769
+ require: 'true',
1770
+ readonly: 'write',
1771
+ formFormat: '{}',
1772
+ moduleName: '輸入框',
1773
+ style_data: {
1774
+ input: {
1775
+ list: [],
1776
+ class: '',
1777
+ style: '',
1778
+ version: 'v2',
1779
+ },
1780
+ label: {
1781
+ list: [],
1782
+ class: 'form-label fs-base ',
1783
+ style: '',
1784
+ version: 'v2',
1785
+ },
1786
+ container: {
1787
+ list: [],
1788
+ class: '',
1789
+ style: '',
1790
+ version: 'v2',
1791
+ },
1792
+ },
1793
+ form_config: {
1794
+ type: 'phone',
1795
+ title: '',
1796
+ input_style: { list: [], version: 'v2' },
1797
+ title_style: { list: [], version: 'v2' },
1798
+ place_holder: '請輸入聯絡電話',
1799
+ },
1800
+ hidden_code: '',
1801
+ },
1802
+ {
1803
+ col: '6',
1804
+ key: 'email',
1805
+ page: 'input',
1806
+ type: 'form_plugin_v2',
1807
+ group: '',
1808
+ title: '電子信箱',
1809
+ col_sm: '12',
1810
+ appName: 'cms_system',
1811
+ require: 'true',
1812
+ readonly: 'write',
1813
+ formFormat: '{}',
1814
+ moduleName: '輸入框',
1815
+ style_data: {
1816
+ input: {
1817
+ list: [],
1818
+ class: '',
1819
+ style: '',
1820
+ version: 'v2',
1821
+ },
1822
+ label: {
1823
+ list: [],
1824
+ class: 'form-label fs-base ',
1825
+ style: '',
1826
+ version: 'v2',
1827
+ },
1828
+ container: {
1829
+ list: [],
1830
+ class: '',
1831
+ style: '',
1832
+ version: 'v2',
1833
+ },
1834
+ },
1835
+ form_config: {
1836
+ type: 'email',
1837
+ title: '',
1838
+ input_style: { list: [], version: 'v2' },
1839
+ title_style: { list: [], version: 'v2' },
1840
+ place_holder: '請輸入電子信箱',
1841
+ },
1842
+ hidden_code: '',
1843
+ },
1844
+ {
1845
+ col: '6',
1846
+ key: 'invoice_type',
1847
+ page: 'form-select',
1848
+ type: 'form_plugin_v2',
1849
+ group: '',
1850
+ title: '發票開立對象',
1851
+ col_sm: '12',
1852
+ appName: 'cms_system',
1853
+ require: 'true',
1854
+ readonly: 'write',
1855
+ formFormat: '{}',
1856
+ moduleName: '下拉選單',
1857
+ style_data: {
1858
+ input: {
1859
+ list: [],
1860
+ class: '',
1861
+ style: '',
1862
+ version: 'v2',
1863
+ },
1864
+ label: {
1865
+ list: [],
1866
+ class: 'form-label fs-base ',
1867
+ style: '',
1868
+ version: 'v2',
1869
+ },
1870
+ container: {
1871
+ list: [],
1872
+ class: '',
1873
+ style: '',
1874
+ version: 'v2',
1875
+ },
1876
+ },
1877
+ form_config: {
1878
+ type: 'name',
1879
+ title: '',
1880
+ option: [
1881
+ { name: '個人', index: 0, value: 'me' },
1882
+ { name: '公司', index: 1, value: 'company' },
1883
+ { name: '捐贈發票', index: 2, value: 'donate' },
1884
+ ],
1885
+ input_style: { list: [], version: 'v2' },
1886
+ title_style: { list: [], version: 'v2' },
1887
+ place_holder: '',
1888
+ },
1889
+ hidden_code: "return (form_data['invoice_method']==='nouse')",
1890
+ },
1891
+ {
1892
+ col: '6',
1893
+ key: 'send_type',
1894
+ page: 'form-select',
1895
+ type: 'form_plugin_v2',
1896
+ group: '',
1897
+ title: '開立方式',
1898
+ col_sm: '12',
1899
+ appName: 'cms_system',
1900
+ require: 'true',
1901
+ readonly: 'write',
1902
+ formFormat: '{}',
1903
+ moduleName: '下拉選單',
1904
+ style_data: {
1905
+ input: {
1906
+ list: [],
1907
+ class: '',
1908
+ style: '',
1909
+ version: 'v2',
1910
+ },
1911
+ label: {
1912
+ list: [],
1913
+ class: 'form-label fs-base ',
1914
+ style: '',
1915
+ version: 'v2',
1916
+ },
1917
+ container: {
1918
+ list: [],
1919
+ class: '',
1920
+ style: '',
1921
+ version: 'v2',
1922
+ },
1923
+ },
1924
+ form_config: {
1925
+ type: 'name',
1926
+ title: '',
1927
+ option: [
1928
+ {
1929
+ name: '傳送至用戶信箱',
1930
+ index: 0,
1931
+ value: 'email',
1932
+ },
1933
+ {
1934
+ name: '手機條碼載具',
1935
+ index: 1,
1936
+ value: 'carrier',
1937
+ },
1938
+ ],
1939
+ input_style: { list: [], version: 'v2' },
1940
+ title_style: { list: [], version: 'v2' },
1941
+ place_holder: '',
1942
+ },
1943
+ hidden_code:
1944
+ " if(form_data['invoice_type']!=='me' || (form_data['invoice_method']==='nouse') || (form_data['invoice_method']==='off_line')){\n form_data[form_key]=undefined\nreturn true\n }else{\n return false\n }",
1945
+ },
1946
+ {
1947
+ key: 'carrier_num',
1948
+ page: 'input',
1949
+ type: 'form_plugin_v2',
1950
+ group: '',
1951
+ title: '載具號碼',
1952
+ appName: 'cms_system',
1953
+ require: 'false',
1954
+ readonly: 'write',
1955
+ formFormat: '{}',
1956
+ moduleName: '輸入框',
1957
+ col: '3',
1958
+ col_sm: '12',
1959
+ style_data: {
1960
+ input: {
1961
+ list: [],
1962
+ class: '',
1963
+ style: '',
1964
+ version: 'v2',
1965
+ },
1966
+ label: {
1967
+ list: [],
1968
+ class: 'form-label fs-base ',
1969
+ style: '',
1970
+ version: 'v2',
1971
+ },
1972
+ container: {
1973
+ list: [],
1974
+ class: '',
1975
+ style: '',
1976
+ version: 'v2',
1977
+ },
1978
+ },
1979
+ form_config: {
1980
+ type: 'name',
1981
+ title: '',
1982
+ input_style: { list: [], version: 'v2' },
1983
+ title_style: { list: [], version: 'v2' },
1984
+ place_holder: '請輸入載具號碼',
1985
+ },
1986
+ hidden_code:
1987
+ " \n if(form_data['invoice_type']!=='me' || form_data['send_type']!=='carrier'){\n form_data[form_key]=undefined\nreturn true\n }else{\n return false\n }",
1988
+ },
1989
+ {
1990
+ key: 'company',
1991
+ page: 'input',
1992
+ type: 'form_plugin_v2',
1993
+ group: '',
1994
+ title: '公司名稱',
1995
+ appName: 'cms_system',
1996
+ require: 'false',
1997
+ readonly: 'write',
1998
+ formFormat: '{}',
1999
+ moduleName: '輸入框',
2000
+ col: '3',
2001
+ col_sm: '12',
2002
+ style_data: {
2003
+ input: {
2004
+ list: [],
2005
+ class: '',
2006
+ style: '',
2007
+ version: 'v2',
2008
+ },
2009
+ label: {
2010
+ list: [],
2011
+ class: 'form-label fs-base ',
2012
+ style: '',
2013
+ version: 'v2',
2014
+ },
2015
+ container: {
2016
+ list: [],
2017
+ class: '',
2018
+ style: '',
2019
+ version: 'v2',
2020
+ },
2021
+ },
2022
+ form_config: {
2023
+ type: 'name',
2024
+ title: '',
2025
+ input_style: { list: [], version: 'v2' },
2026
+ title_style: { list: [], version: 'v2' },
2027
+ place_holder: '請輸入公司名稱',
2028
+ },
2029
+ hidden_code:
2030
+ " if(form_data['invoice_type']!=='company' || (form_data['invoice_method']==='nouse')){\n form_data[form_key]=undefined\nreturn true\n }else{\n return false\n }",
2031
+ },
2032
+ {
2033
+ key: 'gui_number',
2034
+ page: 'input',
2035
+ type: 'form_plugin_v2',
2036
+ group: '',
2037
+ title: '公司統一編號',
2038
+ col: '3',
2039
+ col_sm: '12',
2040
+ appName: 'cms_system',
2041
+ require: 'false',
2042
+ readonly: 'write',
2043
+ formFormat: '{}',
2044
+ moduleName: '輸入框',
2045
+ style_data: {
2046
+ input: {
2047
+ list: [],
2048
+ class: '',
2049
+ style: '',
2050
+ version: 'v2',
2051
+ },
2052
+ label: {
2053
+ list: [],
2054
+ class: 'form-label fs-base ',
2055
+ style: '',
2056
+ version: 'v2',
2057
+ },
2058
+ container: {
2059
+ list: [],
2060
+ class: '',
2061
+ style: '',
2062
+ version: 'v2',
2063
+ },
2064
+ },
2065
+ form_config: {
2066
+ type: 'name',
2067
+ title: '',
2068
+ input_style: { list: [], version: 'v2' },
2069
+ title_style: { list: [], version: 'v2' },
2070
+ place_holder: '請輸入公司統一編號',
2071
+ },
2072
+ hidden_code:
2073
+ " if(form_data['invoice_type']!=='company'){\n form_data[form_key]=undefined\nreturn true\n }else{\n return false\n }",
2074
+ },
2075
+ {
2076
+ col: '6',
2077
+ key: 'love_code',
2078
+ page: 'input',
2079
+ type: 'form_plugin_v2',
2080
+ group: '',
2081
+ title: '捐贈碼',
2082
+ col_sm: '12',
2083
+ appName: 'cms_system',
2084
+ require: 'false',
2085
+ readonly: 'write',
2086
+ formFormat: '{}',
2087
+ moduleName: '輸入框',
2088
+ style_data: {
2089
+ input: {
2090
+ list: [],
2091
+ class: '',
2092
+ style: '',
2093
+ version: 'v2',
2094
+ },
2095
+ label: {
2096
+ list: [],
2097
+ class: 'form-label fs-base ',
2098
+ style: '',
2099
+ version: 'v2',
2100
+ },
2101
+ container: {
2102
+ list: [],
2103
+ class: '',
2104
+ style: '',
2105
+ version: 'v2',
2106
+ },
2107
+ },
2108
+ form_config: {
2109
+ type: 'name',
2110
+ title: '',
2111
+ input_style: { list: [], version: 'v2' },
2112
+ title_style: { list: [], version: 'v2' },
2113
+ place_holder: '請輸入捐贈碼',
2114
+ },
2115
+ hidden_code:
2116
+ " if(form_data['invoice_type']!=='donate' || (form_data['invoice_method']==='nouse')){\n form_data[form_key]=undefined\nreturn true\n }else{\n return false\n }",
2117
+ },
2118
+ {
2119
+ col: '12',
2120
+ key: 'note',
2121
+ page: 'multiple_line_text',
2122
+ type: 'form_plugin_v2',
2123
+ group: '',
2124
+ title: '送貨備註',
2125
+ col_sm: '12',
2126
+ appName: 'cms_system',
2127
+ require: 'false',
2128
+ readonly: 'write',
2129
+ formFormat: '{}',
2130
+ moduleName: '多行文字區塊',
2131
+ style_data: {
2132
+ input: {
2133
+ list: [],
2134
+ class: '',
2135
+ style: '',
2136
+ version: 'v2',
2137
+ },
2138
+ label: {
2139
+ list: [],
2140
+ class: 'form-label fs-base ',
2141
+ style: '',
2142
+ version: 'v2',
2143
+ },
2144
+ container: {
2145
+ list: [],
2146
+ class: '',
2147
+ style: '',
2148
+ version: 'v2',
2149
+ },
2150
+ },
2151
+ form_config: {
2152
+ type: 'text',
2153
+ title: '',
2154
+ title_style: { list: [], version: 'v2' },
2155
+ place_holder: '請輸入送貨備註',
2156
+ },
2157
+ hidden_code: 'return false',
2158
+ },
2159
+ ].filter((dd) => {
2160
+ return (dd.key !== 'name' && dd.key !== 'phone' && dd.key !== 'email') || !vm.cartData.user_info_same;
2161
+ });
2162
+ vm.cartData.user_info.invoice_method = method;
2163
+ vm.cartData.user_info.invoice_type = vm.cartData.user_info.invoice_type || 'me';
2164
+ vm.cartData.user_info.send_type = vm.cartData.user_info.send_type || 'email';
2165
+ const form_array = JSON.parse(JSON.stringify(vm_info.list));
2166
+
2167
+ form_array
2168
+ .map((dd: any) => {
2169
+ if (dd.key === 'send_type' && vm.cartData.user_info.send_type === 'carrier') {
2170
+ dd.col = 3;
2171
+ }
2172
+ dd.form_config.title_style = {
2173
+ list: [
2174
+ {
2175
+ class: ['company', 'gui_number', 'carrier_num'].includes(dd.key) ? gClass('label') + ' mt-2' : gClass('label') + ' mb-2',
2176
+ style: 'return `color:${glitter.share.globalValue[`theme_color.0.title`]} !important;font-size:16px !important;`',
2177
+ stylist: [],
2178
+ dataType: 'code',
2179
+ style_from: 'code',
2180
+ classDataType: 'static',
2181
+ },
2182
+ ],
2183
+ class: 'form-label',
2184
+ style: 'font-size: 20px;font-style: normal;font-weight: 400;line-height: 140%; color:#393939 !important;',
2185
+ stylist: [],
2186
+ version: 'v2',
2187
+ dataType: 'static',
2188
+ style_from: 'code',
2189
+ classDataType: 'static',
2190
+ };
2191
+ dd.form_config.input_style = {
2192
+ list: [
2193
+ {
2194
+ class: gClass('input'),
2195
+ style: 'return `border-radius: ${widget.formData.radius}px !important;`',
2196
+ stylist: [],
2197
+ dataType: 'code',
2198
+ style_from: 'code',
2199
+ classDataType: 'static',
2200
+ },
2201
+ ],
2202
+ class: ' mb-3',
2203
+ style: 'background: #FFF;',
2204
+ stylist: [],
2205
+ version: 'v2',
2206
+ dataType: 'static',
2207
+ style_from: 'code',
2208
+ classDataType: 'static',
2209
+ };
2210
+ })
2211
+ .filter((dd: any) => {
2212
+ return !(method === 'nouse' && ['invoice_type', 'send_type', 'carrier_num', 'company', 'gui_number', 'love_code'].includes(dd.key));
2213
+ });
2214
+ return [
2215
+ html` <div
2216
+ class="d-flex ms-2 my-3"
2217
+ style="gap:10px;cursor:pointer;"
2218
+ onclick="${gvc.event(() => {
2219
+ vm.cartData.user_info_same = !vm.cartData.user_info_same;
2220
+ if (vm.cartData.user_info_same) {
2221
+ vm.cartData.user_info.name = vm.cartData.customer_info.name;
2222
+ vm.cartData.user_info.phone = vm.cartData.customer_info.phone;
2223
+ vm.cartData.user_info.email = vm.cartData.customer_info.email;
2224
+ }
2225
+ gvc.notifyDataChange(id);
2226
+ })}"
2227
+ >
2228
+ <input class="form-check-input form-checkbox ${checkbox}" type="checkbox" ${vm.cartData.user_info_same ? `checked` : ''} />
2229
+ 收件人同購買人資料
2230
+ </div>`,
2231
+ FormWidget.editorView({
2232
+ gvc: gvc,
2233
+ array: form_array,
2234
+ refresh: () => {
2235
+ this.storeLocalData(vm.cartData);
2236
+ gvc.notifyDataChange(id);
2237
+ },
2238
+ formData: vm.cartData.user_info,
2239
+ }),
2240
+ ].join('<div class="my-2"></div>');
2241
+ },
2242
+ divCreate: {
2243
+ class: `w-100 mt-2`,
2244
+ },
2245
+ };
2246
+ })}
2247
+ <div class="w-100 d-flex align-items-center justify-content-end px-2 mt-3">
2248
+ <button
2249
+ class="${gClass('button-bgr')}"
2250
+ onclick="${gvc.event(async () => {
2251
+ if (!(await this.checkFormData(vm.cartData, widget))) {
2252
+ return;
2253
+ }
2254
+ ['MerchantTradeNo', 'LogisticsSubType', 'CVSStoreID', 'CVSStoreName', 'CVSTelephone', 'CVSOutSide', 'ExtraData', 'CVSAddress'].map((dd) => {
2255
+ if (gvc.glitter.getUrlParameter(dd)) {
2256
+ vm.cartData.user_info[dd] = decodeURI(glitter.getUrlParameter(dd));
2257
+ }
2258
+ });
2259
+
2260
+ const dialog = new ShareDialog(gvc.glitter);
2261
+ dialog.dataLoading({ visible: true });
2262
+ ApiShop.toCheckout({
2263
+ line_items: vm.cartData.lineItems.map((dd: any) => {
2264
+ return {
2265
+ id: dd.id,
2266
+ spec: dd.spec,
2267
+ count: dd.count,
2268
+ };
2269
+ }),
2270
+ customer_info: vm.cartData.customer_info,
2271
+ return_url: (() => {
2272
+ const originalUrl = glitter.root_path + 'order_detail' + location.search;
2273
+ const urlObject = new URL(originalUrl);
2274
+ urlObject.searchParams.set('EndCheckout', '1');
2275
+ const newUrl = urlObject.toString();
2276
+ return newUrl;
2277
+ })(),
2278
+ user_info: vm.cartData.user_info,
2279
+ code: ApiCart.cart.code,
2280
+ use_rebate: ApiCart.cart.use_rebate,
2281
+ custom_form_format: vm.cartData.custom_form_format,
2282
+ custom_form_data: vm.cartData.custom_form_data,
2283
+ distribution_code: ApiCart.cart.distribution_code,
2284
+ give_away: ApiCart.cart.give_away,
2285
+ }).then((res) => {
2286
+ if (res.response.off_line || res.response.is_free) {
2287
+ ApiCart.clearCart();
2288
+ location.href = res.response.return_url;
2289
+ } else {
2290
+ const id = gvc.glitter.getUUID();
2291
+ $('body').append(`<div id="${id}" style="display: none;">${res.response.form}</div>`);
2292
+ (document.querySelector(`#${id} #submit`) as any).click();
2293
+ ApiCart.clearCart();
2294
+ }
2295
+ });
2296
+ })}"
2297
+ style="width:200px;"
2298
+ >
2299
+ <span class="${gClass('button-text')}">下一步</span>
2300
+ </button>
1034
2301
  </div>
1035
2302
  </section>
1036
2303
  </div>`;
1037
- }catch (e) {
1038
- console.error(e)
1039
- return ``
2304
+ } catch (e) {
2305
+ console.error(e);
2306
+ return ``;
1040
2307
  }
1041
2308
  },
1042
2309
  divCreate: {},
1043
2310
  onCreate: () => {
1044
- if (loadings.page) {
1045
- new Promise(async (resolve, reject) => {
1046
- new Promise((resolve, reject) => {
1047
- setTimeout(() => {
1048
- resolve(ApiCart.cart);
1049
- });
1050
- }).then(async (res: any) => {
1051
- const cartData: {
1052
- line_items: {
1053
- sku: string;
1054
- spec: string[];
1055
- stock: number;
1056
- sale_price: number;
1057
- compare_price: number;
1058
- preview_image: string;
1059
- title: string;
1060
- id: number;
1061
- count: number;
1062
- }[];
1063
- total: number;
1064
- user_info: {
1065
- shipment: string;
1066
- };
1067
- } = {
1068
- line_items: [],
1069
- total: 0,
1070
- user_info: {
1071
- shipment: localStorage.getItem('checkout-logistics') as string,
1072
- },
1073
- };
1074
- if (res.line_items) {
1075
- res.user_info = {
1076
- shipment: localStorage.getItem('checkout-logistics') as string,
1077
- };
1078
- const cart = res as CartItem;
1079
- ApiShop.getCheckout(cart).then((res) => {
1080
- if (res.result) {
1081
- resolve(res.response.data);
1082
- } else {
1083
- resolve([]);
1084
- }
1085
- });
1086
- } else {
1087
- for (const b of Object.keys(res)) {
1088
- cartData.line_items.push({
1089
- id: b.split('-')[0] as any,
1090
- count: res[b] as number,
1091
- spec: b.split('-').filter((dd, index) => {
1092
- return index !== 0;
1093
- }) as any,
1094
- } as any);
1095
- }
1096
- const voucher = ApiCart.cart.code;
1097
- const rebate = ApiCart.cart.use_rebate || 0;
1098
- const distributionCode = localStorage.getItem('distributionCode') ?? '';
1099
- ApiShop.getCheckout({
1100
- line_items: cartData.line_items.map((dd) => {
1101
- return {
1102
- id: dd.id,
1103
- spec: dd.spec,
1104
- count: dd.count,
1105
- };
1106
- }),
1107
- code: voucher as string,
1108
- use_rebate: GlobalUser.token && rebate ? rebate : undefined,
1109
- distribution_code: distributionCode,
1110
- user_info: {
1111
- shipment: localStorage.getItem('checkout-logistics'),
1112
- },
1113
- }).then((res) => {
1114
- if (res.result) {
1115
- resolve(res.response.data);
1116
- } else {
1117
- resolve([]);
1118
- }
1119
- });
1120
- }
1121
- });
1122
- }).then((data) => {
1123
- vm.cartData = data;
1124
- gvc.addMtScript(
1125
- [
1126
- {
1127
- src: `https://unpkg.com/@lottiefiles/lottie-player@latest/dist/lottie-player.js`,
1128
- },
1129
- ],
1130
- () => {
1131
- loadings.page = false;
1132
- gvc.notifyDataChange(ids.page);
1133
- },
1134
- () => {}
1135
- );
1136
- });
1137
-
1138
- // gvc.addMtScript(
1139
- // [
1140
- // {
1141
- // src: `https://unpkg.com/@lottiefiles/lottie-player@latest/dist/lottie-player.js`,
1142
- // },
1143
- // ],
1144
- // () => {
1145
- // loadings.page = false;
1146
- // gvc.notifyDataChange(ids.page);
1147
- // },
1148
- // () => {
1149
- // }
1150
- // );
1151
- }
2311
+ Ad.gtagEvent('view_cart', {
2312
+ currency: 'TWD',
2313
+ value: vm.cartData.total,
2314
+ items: vm.cartData.lineItems.map((item: any) => {
2315
+ return {
2316
+ item_id: item.id,
2317
+ item_name: item.title,
2318
+ item_variant: item.spec.join('-'),
2319
+ price: item.sale_price,
2320
+ quantity: item.count,
2321
+ discount: item.discount_price,
2322
+ };
2323
+ }),
2324
+ });
2325
+ Ad.fbqEvent('AddPaymentInfo', {
2326
+ value: vm.cartData.total,
2327
+ currency: 'TWD',
2328
+ contents: vm.cartData.lineItems.map((item: any) => {
2329
+ return {
2330
+ id: item.id,
2331
+ quantity: item.count,
2332
+ };
2333
+ }),
2334
+ content_ids: vm.cartData.lineItems.map((item: any) => item.id),
2335
+ });
1152
2336
  },
1153
2337
  };
1154
2338
  })()
1155
2339
  );
1156
2340
  }
2341
+ //檢查資料
2342
+ public static checkFormData(cartData: any, widget: any) {
2343
+ function checkEmailPattern(input: any) {
2344
+ const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
2345
+ return emailPattern.test(input);
2346
+ }
2347
+
2348
+ function checkPhonePattern(input: any) {
2349
+ const phonePattern = /^09\d{8}$/;
2350
+ return phonePattern.test(input);
2351
+ }
2352
+
2353
+ function checkReceiverPattern(input: any) {
2354
+ const receiverPattern = /^[\u4e00-\u9fa5]{2,5}|[a-zA-Z]{4,10}$/;
2355
+ return receiverPattern.test(input);
2356
+ }
2357
+
2358
+ function checkAddressPattern(input: any) {
2359
+ const addressPattern = /^.{6,60}$/;
2360
+ return addressPattern.test(input);
2361
+ }
2362
+
2363
+ return new Promise((resolve) => {
2364
+ let pass = true;
2365
+ const userData = cartData.customer_info;
2366
+ const subData = cartData.user_info;
2367
+ function checkString(text: any, errorMessage: any, type = '') {
2368
+ if ((pass && !text) || text === '') {
2369
+ pass = false;
2370
+ widget.event('error', { title: `請輸入「${errorMessage}」` });
2371
+ }
2372
+ if (pass && type === 'email' && !checkEmailPattern(text)) {
2373
+ pass = false;
2374
+ widget.event('error', { title: `「${errorMessage}」格式錯誤` });
2375
+ }
2376
+ if (pass && type === 'phone' && !checkPhonePattern(text)) {
2377
+ pass = false;
2378
+ widget.event('error', { title: `<div class="text-center">「${errorMessage}」格式錯誤<br/>請輸入 09 開頭的手機格式</div>` });
2379
+ }
2380
+ if (pass && type === 'name' && !checkReceiverPattern(text)) {
2381
+ pass = false;
2382
+ widget.event('error', { title: '姓名請設定為4~10字元(中文2~5個字, 英文4~10個字, 不得含指定特殊符號)' });
2383
+ }
2384
+ }
1157
2385
 
2386
+ if (subData['shipment'] === 'normal' && (!subData['address'] || subData['address'] === '')) {
2387
+ widget.event('error', { title: '請輸入「配送地址」' });
2388
+ } else if (subData['shipment'] === 'normal' && !checkAddressPattern(subData['address'])) {
2389
+ widget.event('error', { title: '地址長度需大於6個字元,且不可超過60個字元' });
2390
+ } else if (['UNIMARTC2C', 'FAMIC2C', 'HILIFEC2C', 'OKMARTC2C'].includes(subData['shipment']) && (!subData['CVSStoreName'] || subData['CVSStoreName'] === '')) {
2391
+ widget.event('error', { title: '請選擇「配送門市」' });
2392
+ } else if (
2393
+ (() => {
2394
+ const form = this.getShipmentMethod(cartData).find((dd: any) => {
2395
+ return dd.value === subData['shipment'];
2396
+ }).form;
2397
+ return FormWidget.checkLeakData(form, subData.custom_form_delivery);
2398
+ })()
2399
+ ) {
2400
+ const form = this.getShipmentMethod(cartData).find((dd: any) => {
2401
+ return dd.value === subData['shipment'];
2402
+ }).form;
2403
+ widget.event('error', { title: `請輸入「${FormWidget.checkLeakData(form, subData)}」` });
2404
+ } else if (
2405
+ (() => {
2406
+ return FormWidget.checkLeakData(cartData.custom_form_format, cartData.custom_form_data);
2407
+ })()
2408
+ ) {
2409
+ widget.event('error', { title: `請輸入「${FormWidget.checkLeakData(cartData.custom_form_format, cartData.custom_form_data)}」` });
2410
+ } else if (
2411
+ cartData.voucherList
2412
+ .filter((dd: any) => {
2413
+ return dd.reBackType === 'giveaway';
2414
+ })
2415
+ .find((dd: any) => {
2416
+ return !dd.select_gif.id;
2417
+ })
2418
+ ) {
2419
+ widget.event('error', { title: '請選擇「贈品」' });
2420
+ } else {
2421
+ checkString(userData.name, '顧客姓名', 'name');
2422
+ checkString(userData.phone, '顧客電話', 'phone');
2423
+ checkString(userData.email, '顧客信箱', 'email');
2424
+ checkString(subData.name, '收件人姓名', 'name');
2425
+ checkString(subData.phone, '收件人電話', 'phone');
2426
+ checkString(subData.email, '收件人信箱', 'email');
2427
+ if (pass) {
2428
+ Ad.gtagEvent('begin_checkout', {
2429
+ currency: 'TWD',
2430
+ value: cartData.total,
2431
+ coupon: cartData.code ?? '',
2432
+ items: cartData.lineItems.map((item: any) => {
2433
+ return {
2434
+ item_id: item.id,
2435
+ item_name: item.title,
2436
+ item_variant: item.spec.join('-'),
2437
+ price: item.sale_price,
2438
+ quantity: item.count,
2439
+ discount: item.discount_price,
2440
+ };
2441
+ }),
2442
+ });
2443
+ Ad.fbqEvent('Purchase', {
2444
+ value: cartData.total,
2445
+ currency: 'TWD',
2446
+ contents: cartData.lineItems.map((item: any) => {
2447
+ return {
2448
+ id: item.id,
2449
+ quantity: item.count,
2450
+ };
2451
+ }),
2452
+ content_type: 'product',
2453
+ });
2454
+ resolve(subData);
2455
+ }
2456
+ }
2457
+ });
2458
+ }
2459
+ //彈出視窗
2460
+ public static viewDialog(obj: { gvc: GVC; tag: string; title?: string; innerHTML: (gvc: GVC) => string }) {
2461
+ return obj.gvc.glitter.innerDialog((gvc: GVC) => {
2462
+ return html` <div
2463
+ class="bg-white shadow rounded-3"
2464
+ style="overflow-y: auto; ${document.body.clientWidth > 768 ? `min-width: 600px; width: 700px;` : 'min-width: 90vw; max-width: 92.5vw;'}"
2465
+ >
2466
+ <div class="bg-white shadow rounded-3" style="width: 100%; overflow-y: auto; position: relative;">
2467
+ <div class="w-100 d-flex align-items-center p-3 border-bottom" style="position: sticky; top: 0; background: #fff;">
2468
+ <div style="font-size: 16px; font-weight: 700; color: #292218;">${obj.title ?? ''}</div>
2469
+ <div class="flex-fill"></div>
2470
+ <i
2471
+ class="fa-regular fa-circle-xmark fs-5 text-dark"
2472
+ style="cursor: pointer"
2473
+ onclick="${gvc.event(() => {
2474
+ gvc.closeDialog();
2475
+ })}"
2476
+ ></i>
2477
+ </div>
2478
+ <div class="c_dialog">
2479
+ <div class="c_dialog_body">
2480
+ <div class="c_dialog_main" style="gap: 24px; height: auto; max-height: 500px; padding: 12px 20px;">${obj.innerHTML(gvc)}</div>
2481
+ </div>
2482
+ </div>
2483
+ </div>
2484
+ </div>`;
2485
+ }, obj.tag);
2486
+ }
1158
2487
 
1159
2488
  //取得付款方式
1160
2489
  public static getPaymentMethod(cartData: any) {
@@ -1175,20 +2504,20 @@ this.viewDialog({
1175
2504
  }
1176
2505
  cartData.off_line_support = cartData.off_line_support ?? {};
1177
2506
  cartData.off_line_support.atm &&
1178
- array.push({
1179
- name: '銀行轉帳',
1180
- value: 'atm',
1181
- });
2507
+ array.push({
2508
+ name: '銀行轉帳',
2509
+ value: 'atm',
2510
+ });
1182
2511
  cartData.off_line_support.line &&
1183
- array.push({
1184
- name: 'Line Pay 付款',
1185
- value: 'line',
1186
- });
2512
+ array.push({
2513
+ name: 'Line Pay 付款',
2514
+ value: 'line',
2515
+ });
1187
2516
  cartData.off_line_support.cash_on_delivery &&
1188
- array.push({
1189
- name: '貨到付款',
1190
- value: 'cash_on_delivery',
1191
- });
2517
+ array.push({
2518
+ name: '貨到付款',
2519
+ value: 'cash_on_delivery',
2520
+ });
1192
2521
  //當沒有找到付款方式實則重新inital
1193
2522
  if (
1194
2523
  !array.find((dd) => {
@@ -1203,61 +2532,60 @@ this.viewDialog({
1203
2532
 
1204
2533
  //取得配送方式
1205
2534
  public static getShipmentMethod(cartData: any) {
1206
- if (!cartData.shipment_selector.find((dd: any) => {
1207
- return dd.value === localStorage.getItem('shipment-select')
1208
- })) {
2535
+ if (
2536
+ !cartData.shipment_selector.find((dd: any) => {
2537
+ return dd.value === localStorage.getItem('shipment-select');
2538
+ })
2539
+ ) {
1209
2540
  localStorage.setItem('shipment-select', cartData.shipment_selector[0].value);
1210
2541
  }
1211
2542
 
1212
2543
  cartData.user_info.shipment = localStorage.getItem('shipment-select');
1213
- return cartData.shipment_selector
2544
+ return cartData.shipment_selector;
1214
2545
  }
1215
2546
 
1216
2547
  //儲存本地資料
1217
- public static storeLocalData(cartData:any) {
2548
+ public static storeLocalData(cartData: any) {
1218
2549
  //設定顧客
1219
- localStorage.setItem('cart_customer_info',JSON.stringify(cartData.customer_info))
2550
+ localStorage.setItem('cart_customer_info', JSON.stringify(cartData.customer_info));
1220
2551
  //設定配送
1221
- localStorage.setItem('shipment-select',cartData.user_info.shipment)
2552
+ localStorage.setItem('shipment-select', cartData.user_info.shipment);
1222
2553
  //設定付款
1223
2554
  localStorage.setItem('checkout-payment', cartData.customer_info.payment_select);
2555
+ //設定自訂表單
2556
+ localStorage.setItem('custom_form_data', JSON.stringify(cartData.custom_form_data));
2557
+ //設定配送資訊
2558
+ localStorage.setItem('custom_user_info', JSON.stringify(cartData.user_info));
1224
2559
  }
1225
2560
 
1226
- //彈出視窗
1227
- public static viewDialog(obj: { gvc: GVC; tag: string; title?: string; innerHTML: (gvc: GVC) => string }) {
1228
- return obj.gvc.glitter.innerDialog((gvc: GVC) => {
1229
- return html` <div
1230
- class="bg-white shadow rounded-3"
1231
- style="overflow-y: auto; ${document.body.clientWidth > 768 ? `min-width: 600px; width: 700px;` : 'min-width: 90vw; max-width: 92.5vw;'}"
1232
- >
1233
- <div class="bg-white shadow rounded-3" style="width: 100%; overflow-y: auto; position: relative;">
1234
- <div class="w-100 d-flex align-items-center p-3 border-bottom" style="position: sticky; top: 0; background: #fff;">
1235
- <div style="font-size: 16px; font-weight: 700; color: #292218;">${obj.title ?? ''}</div>
1236
- <div class="flex-fill"></div>
1237
- <i
1238
- class="fa-regular fa-circle-xmark fs-5 text-dark"
1239
- style="cursor: pointer"
1240
- onclick="${gvc.event(() => {
1241
- gvc.closeDialog();
1242
- })}"
1243
- ></i>
1244
- </div>
1245
- <div class="c_dialog">
1246
- <div class="c_dialog_body">
1247
- <div class="c_dialog_main" style="gap: 24px; height: auto; max-height: 500px; padding: 12px 20px;">${obj.innerHTML(gvc)}</div>
1248
- </div>
1249
- </div>
1250
- </div>
1251
- </div>`;
1252
- }, obj.tag);
1253
- }
2561
+ public static initial(cartData: any) {
2562
+ cartData.customer_info = JSON.parse(localStorage.getItem('cart_customer_info') || '{}');
2563
+ cartData.custom_form_data = JSON.parse(localStorage.getItem('custom_form_data') || '{}');
2564
+ cartData.user_info = JSON.parse(localStorage.getItem('custom_user_info') || '{}');
1254
2565
 
1255
- public static initial(cartData: any){
1256
- cartData.customer_info=JSON.parse(localStorage.getItem('cart_customer_info') || "{}")
1257
- this.getPaymentMethod(cartData)
1258
- this.getShipmentMethod(cartData)
2566
+ this.getPaymentMethod(cartData);
2567
+ this.getShipmentMethod(cartData);
2568
+ }
2569
+ static getCheckedClass(gvc: GVC, color?: string) {
2570
+ const className = Tool.randomString(6);
2571
+ gvc.addStyle(`
2572
+ .${className} {
2573
+ min-width: 1rem;
2574
+ min-height: 1rem;
2575
+ }
2576
+ .${className}:checked[type='checkbox'] {
2577
+ border: 2px solid ${color ?? '#000'};
2578
+ background-color: #fff;
2579
+ background-image: url(${this.checkedDataImage(color ?? '#000')});
2580
+ background-position: center center;
2581
+ }
2582
+ `);
2583
+ return className;
2584
+ }
2585
+ static checkedDataImage(color: string): string {
2586
+ color = color.replace('#', '%23');
2587
+ return `"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='${color}' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e"`;
1259
2588
  }
1260
-
1261
2589
  }
1262
2590
 
1263
2591
  (window as any).glitter.setModule(import.meta.url, CheckoutIndex);