ts-glitter 22.5.7 → 22.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/lowcode/Entry.js +1 -1
  2. package/lowcode/Entry.ts +1 -1
  3. package/lowcode/backend-manager/bg-product.js +13 -13
  4. package/lowcode/backend-manager/bg-product.ts +13 -13
  5. package/lowcode/backend-manager/bg-shopping.js +8 -13
  6. package/lowcode/backend-manager/bg-shopping.ts +8 -15
  7. package/lowcode/backend-manager/bg-widget.js +62 -49
  8. package/lowcode/backend-manager/bg-widget.ts +129 -93
  9. package/lowcode/cms-plugin/POS-setting.js +30 -9
  10. package/lowcode/cms-plugin/POS-setting.ts +49 -16
  11. package/lowcode/cms-plugin/cms-router.js +27 -21
  12. package/lowcode/cms-plugin/cms-router.ts +116 -101
  13. package/lowcode/cms-plugin/filter-options.js +25 -17
  14. package/lowcode/cms-plugin/filter-options.ts +27 -17
  15. package/lowcode/cms-plugin/module/product-excel.js +2 -0
  16. package/lowcode/cms-plugin/module/product-excel.ts +2 -0
  17. package/lowcode/cms-plugin/module/product-setting.js +13 -12
  18. package/lowcode/cms-plugin/module/product-setting.ts +26 -23
  19. package/lowcode/cms-plugin/order/order-module.js +91 -68
  20. package/lowcode/cms-plugin/order/order-module.ts +105 -73
  21. package/lowcode/cms-plugin/pos-checkout-setting.js +46 -39
  22. package/lowcode/cms-plugin/pos-checkout-setting.ts +237 -227
  23. package/lowcode/cms-plugin/pos-config-setting.js +25 -23
  24. package/lowcode/cms-plugin/pos-config-setting.ts +35 -32
  25. package/lowcode/cms-plugin/pos-pages/payment-function.js +253 -139
  26. package/lowcode/cms-plugin/pos-pages/payment-function.ts +405 -279
  27. package/lowcode/cms-plugin/pos-pages/payment-page.js +348 -267
  28. package/lowcode/cms-plugin/pos-pages/payment-page.ts +378 -296
  29. package/lowcode/cms-plugin/pos-pages/pos-function.js +76 -19
  30. package/lowcode/cms-plugin/pos-pages/pos-function.ts +84 -19
  31. package/lowcode/cms-plugin/shopping-discount-setting.js +2 -2
  32. package/lowcode/cms-plugin/shopping-discount-setting.ts +2 -2
  33. package/lowcode/cms-plugin/shopping-finance-setting.js +1590 -1701
  34. package/lowcode/cms-plugin/shopping-finance-setting.ts +1967 -2011
  35. package/lowcode/cms-plugin/shopping-order-manager.js +74 -62
  36. package/lowcode/cms-plugin/shopping-order-manager.ts +119 -85
  37. package/lowcode/cms-plugin/shopping-product-text.js +874 -531
  38. package/lowcode/cms-plugin/shopping-product-text.ts +1656 -1305
  39. package/lowcode/cms-plugin/shopping-setting-basic.js +152 -124
  40. package/lowcode/cms-plugin/shopping-setting-basic.ts +315 -247
  41. package/lowcode/css/editor.css +3 -2
  42. package/lowcode/glitter-base/global/language.js +5 -3
  43. package/lowcode/glitter-base/global/language.ts +8 -6
  44. package/lowcode/glitter-base/global/payment-config.js +6 -0
  45. package/lowcode/glitter-base/global/payment-config.ts +6 -3
  46. package/lowcode/public-components/product/pd-class.js +1 -3
  47. package/lowcode/public-components/product/pd-class.ts +1 -3
  48. package/lowcode/public-components/user-manager/um-order.js +2 -1
  49. package/lowcode/public-components/user-manager/um-order.ts +2 -1
  50. package/package.json +1 -1
  51. package/src/api-public/controllers/index.js +14 -3
  52. package/src/api-public/controllers/index.js.map +1 -1
  53. package/src/api-public/controllers/index.ts +16 -3
  54. package/src/api-public/controllers/shop.js +14 -7
  55. package/src/api-public/controllers/shop.js.map +1 -1
  56. package/src/api-public/controllers/shop.ts +14 -8
  57. package/src/api-public/services/data-analyze.d.ts +1 -1
  58. package/src/api-public/services/ezpay/tool.d.ts +0 -1
  59. package/src/api-public/services/financial-serviceV2.js +7 -17
  60. package/src/api-public/services/financial-serviceV2.js.map +1 -1
  61. package/src/api-public/services/shopee.js.map +1 -1
  62. package/src/api-public/services/updated-table-checked.js +20 -0
  63. package/src/api-public/services/updated-table-checked.js.map +1 -1
  64. package/src/api-public/services/updated-table-checked.ts +21 -0
  65. package/src/app-project/serverless/src/modules/database.d.ts +1 -1
  66. package/src/app-project/serverless/src/modules/redis.d.ts +1 -1
  67. package/src/helper/glitter-util.d.ts +0 -1
  68. package/src/index.js +3 -3
  69. package/src/index.js.map +13 -1
  70. package/src/modules/tool.d.ts +2 -0
  71. package/src/modules/tool.js +7 -0
  72. package/src/modules/tool.js.map +1 -1
  73. package/src/modules/tool.ts +7 -0
  74. package/src/seo-config.js +3 -3
  75. package/src/seo-config.js.map +9 -1
  76. package/src/services/private_config.js +11 -0
  77. package/src/services/private_config.js.map +1 -1
  78. package/src/services/private_config.ts +11 -0
  79. package/src/services/saas-table-check.js +12 -0
  80. package/src/services/saas-table-check.js.map +1 -1
  81. package/src/services/saas-table-check.ts +12 -0
  82. package/src/services/ses.js +3 -4
  83. package/src/services/ses.js.map +1 -1
@@ -1,7 +1,7 @@
1
1
  import { GVC } from '../glitterBundle/GVController.js';
2
2
  import { EditorElem } from '../glitterBundle/plugins/editor-elem.js';
3
3
  import { ShareDialog } from '../glitterBundle/dialog/ShareDialog.js';
4
- import { BgWidget } from '../backend-manager/bg-widget.js';
4
+ import { BgWidget, CustomButtonObject } from '../backend-manager/bg-widget.js';
5
5
  import { CheckInput } from '../modules/checkInput.js';
6
6
  import { Tool } from '../modules/tool.js';
7
7
  import { imageLibrary } from '../modules/image-library.js';
@@ -20,6 +20,7 @@ type CustomFinance = {
20
20
  id: string;
21
21
  text: string;
22
22
  shipmentSupport: string[];
23
+ type?: 'pos';
23
24
  };
24
25
 
25
26
  type ShipmentGroupData = {
@@ -28,45 +29,48 @@ type ShipmentGroupData = {
28
29
  list: string[];
29
30
  };
30
31
 
32
+ type EditCustomFinance = {
33
+ function: 'replace' | 'plus';
34
+ data?: CustomFinance;
35
+ };
36
+
31
37
  const html = String.raw;
32
38
 
33
39
  export class ShoppingFinanceSetting {
40
+ static gvc: GVC | null = null;
41
+ static id = '';
42
+ static loading = true;
43
+ static saasConfig = (window.parent as any).saasConfig;
44
+
45
+ // *金流設定頁
34
46
  static main(gvc: GVC, pos?: boolean) {
47
+ this.gvc = gvc;
48
+ this.id = 'shopping-finance-setting-main';
49
+ this.loading = true;
50
+
35
51
  pos = `${pos}` === 'true';
36
- const dialog = new ShareDialog(gvc.glitter);
37
- const saasConfig: { config: any; api: any } = (window.parent as any).saasConfig;
52
+ let keyData: any = { payment_info_custom: [] };
38
53
 
39
54
  const vm: {
40
55
  id: string;
41
56
  onBoxId: string;
42
57
  posBoxId: string;
43
58
  offBoxId: string;
44
- loading: boolean;
45
59
  page: 'online' | 'offline' | 'pos';
46
60
  } = {
47
- id: gvc.glitter.getUUID(),
61
+ id: this.id,
48
62
  onBoxId: gvc.glitter.getUUID(),
49
63
  posBoxId: gvc.glitter.getUUID(),
50
64
  offBoxId: gvc.glitter.getUUID(),
51
- loading: true,
52
65
  page: pos ? 'pos' : 'online',
53
66
  };
67
+ const dialog = new ShareDialog(gvc.glitter);
68
+ const saasConfig = this.saasConfig;
69
+ const saveData = () => {
70
+ saasConfig.api.setPrivateConfig(saasConfig.config.appName, 'glitter_finance', keyData).then(() => this.refresh());
71
+ };
54
72
 
55
- let keyData: any = { payment_info_custom: [] };
56
-
57
- function refresh() {
58
- gvc.notifyDataChange(vm.id);
59
- }
60
-
61
- function saveData() {
62
- saasConfig.api.setPrivateConfig(saasConfig.config.appName, 'glitter_finance', keyData).then(() => {
63
- vm.loading = true;
64
- refresh();
65
- });
66
- }
67
-
68
- // 自訂金流設定
69
- function updateCustomFinance(obj: { function: 'replace' | 'plus'; data?: CustomFinance }) {
73
+ const customFinance = (obj: EditCustomFinance): CustomButtonObject[] => {
70
74
  const custom_finance: CustomFinance = structuredClone(
71
75
  obj.data || {
72
76
  id: gvc.glitter.getUUID(),
@@ -75,902 +79,495 @@ export class ShoppingFinanceSetting {
75
79
  shipmentSupport: [],
76
80
  }
77
81
  );
78
- let form: any = undefined;
79
-
80
- BgWidget.settingDialog({
81
- gvc: gvc,
82
- title: obj.function === 'replace' ? '修改金流設定' : '新增自訂金流',
83
- width: 800,
84
- innerHTML: gvc => {
85
- const id = gvc.glitter.getUUID();
86
- form = BgWidget.customForm(gvc, [
87
- {
88
- title: html` <div class="tx_normal fw-bolder mt-2 d-flex flex-column" style="margin-bottom: 12px;">
89
- 自訂線下金流表單
90
- <span style="color: #8D8D8D; font-size: 12px;">當客戶選擇此付款方式時,所需上傳的付款證明</span>
91
- </div>`,
92
- key: `form_finance_${custom_finance.id}`,
93
- no_padding: true,
94
- },
95
- ]);
96
-
97
- return gvc.bindView({
98
- bind: id,
99
- view: () => {
100
- const setting = {
101
- title: '金流設定',
102
- key: 'setting',
103
- html: [
104
- BgWidget.editeInput({
105
- gvc: gvc,
106
- title: '自訂金流名稱',
107
- default: custom_finance.name,
108
- callback: text => {
109
- custom_finance.name = text;
110
- },
111
- placeHolder: '請輸入自訂金流名稱',
112
- global_language: true,
113
- }),
114
- form.view,
115
- ].join(''),
116
- };
117
82
 
118
- const note = {
119
- title: '付款說明',
120
- key: 'note',
121
- html: [
122
- html` <div class="d-flex justify-content-between mb-3">
123
- <div class="tx_normal">付款說明</div>
124
- </div>`,
125
- BgWidget.richTextEditor({
126
- gvc: gvc,
127
- content: custom_finance.text,
128
- callback: content => {
129
- custom_finance.text = content;
130
- },
131
- title: '付款說明',
132
- }),
133
- ].join(''),
134
- };
83
+ const form: any = BgWidget.customForm(gvc, [
84
+ {
85
+ title: html` <div class="tx_normal fw-bolder mt-2 d-flex flex-column" style="margin-bottom: 12px;">
86
+ 自訂線下金流表單
87
+ <span style="color: #8D8D8D; font-size: 12px;">當客戶選擇此付款方式時,所需上傳的付款證明</span>
88
+ </div>`,
89
+ key: `form_finance_${custom_finance.id}`,
90
+ no_padding: true,
91
+ },
92
+ ]);
135
93
 
136
- const shipment = {
137
- key: 'shipment',
138
- title: '指定物流',
139
- html: gvc.bindView({
140
- bind: gvc.glitter.getUUID(),
141
- view: () => ShoppingFinanceSetting.setShipmentSupport(gvc, custom_finance),
142
- }),
143
- };
94
+ const setting = {
95
+ title: '金流設定',
96
+ key: 'setting',
97
+ html: (gvc: GVC) => {
98
+ return [
99
+ BgWidget.editeInput({
100
+ gvc: gvc,
101
+ title: '自訂金流名稱',
102
+ default: custom_finance.name,
103
+ callback: text => {
104
+ custom_finance.name = text;
105
+ },
106
+ placeHolder: '請輸入自訂金流名稱',
107
+ global_language: true,
108
+ }),
109
+ form.view,
110
+ ].join('');
111
+ },
112
+ };
144
113
 
145
- const cartSetting = {
146
- key: 'cartSetting',
147
- title: '購物車設定',
148
- html: gvc.bindView({
149
- bind: gvc.glitter.getUUID(),
150
- view: () => ShoppingFinanceSetting.setCartSetting(gvc, custom_finance),
151
- }),
152
- };
114
+ const note = {
115
+ title: '付款說明',
116
+ key: 'note',
117
+ html: (gvc: GVC) => {
118
+ return [
119
+ html` <div class="d-flex justify-content-between mb-3">
120
+ <div class="tx_normal">付款說明</div>
121
+ </div>`,
122
+ BgWidget.richTextEditor({
123
+ gvc: gvc,
124
+ content: custom_finance.text,
125
+ callback: content => {
126
+ custom_finance.text = content;
127
+ },
128
+ title: '付款說明',
129
+ }),
130
+ ].join('');
131
+ },
132
+ };
153
133
 
154
- return ShoppingFinanceSetting.tabView(gvc, [setting, note, shipment, cartSetting]);
155
- },
134
+ const shipment = {
135
+ key: 'shipment',
136
+ title: '指定物流',
137
+ html: (gvc: GVC) => {
138
+ return gvc.bindView({
139
+ bind: gvc.glitter.getUUID(),
140
+ view: () => ShoppingFinanceSetting.setShipmentSupport(gvc, custom_finance),
156
141
  });
157
142
  },
158
- footer_html: gvc => {
159
- const saveButton = BgWidget.save(
160
- gvc.event(() => {
161
- return new Promise<boolean>(async () => {
162
- if (!custom_finance.name) {
163
- dialog.errorMessage({ text: '請輸入金流名稱' });
164
- return;
165
- }
143
+ };
166
144
 
167
- keyData.payment_info_custom = keyData.payment_info_custom ?? [];
168
-
169
- if (obj.function === 'plus') {
170
- const newFinance = JSON.parse(JSON.stringify(custom_finance));
171
- keyData.payment_info_custom.push(newFinance);
172
- } else {
173
- const index = keyData.payment_info_custom.findIndex((d1: any) => d1.id === custom_finance.id);
174
- if (index !== -1) {
175
- keyData.payment_info_custom[index] = custom_finance;
176
- } else {
177
- console.error('找不到對應的金流設定 ID:', custom_finance.id);
178
- return;
179
- }
180
- }
145
+ const cartSetting = {
146
+ key: 'cartSetting',
147
+ title: '購物車設定',
148
+ html: (gvc: GVC) => {
149
+ return gvc.bindView({
150
+ bind: gvc.glitter.getUUID(),
151
+ view: () => ShoppingFinanceSetting.setCartSetting(gvc, custom_finance),
152
+ });
153
+ },
154
+ };
181
155
 
182
- dialog.dataLoading({ visible: true });
156
+ return (obj.function === 'plus' ? [setting] : [setting, note, shipment, cartSetting]).map(item => {
157
+ return {
158
+ button: { color: 'gray', size: 'sm' },
159
+ text: { name: item.title },
160
+ event: gvc.event(async () => {
161
+ this.settingDialog(
162
+ gvc,
163
+ item.title,
164
+ gvc => html`<div>${item.html(gvc)}</div>`,
165
+ gvc => {
166
+ return BgWidget.save(
167
+ gvc.event(async () => {
168
+ if (!custom_finance.name) {
169
+ dialog.errorMessage({ text: '請輸入金流名稱' });
170
+ return;
171
+ }
183
172
 
184
- try {
185
- await form.save();
186
- await saasConfig.api.setPrivateConfig(saasConfig.config.appName, 'glitter_finance', keyData);
173
+ if (vm.page === 'pos') {
174
+ custom_finance.type = 'pos';
175
+ }
187
176
 
188
- dialog.successMessage({ text: '設定成功' });
189
- } catch (error) {
190
- console.error('更新金流設定失敗:', error);
191
- dialog.errorMessage({ text: '設定失敗,請稍後再試' });
192
- } finally {
193
- dialog.dataLoading({ visible: false });
194
- }
177
+ keyData.payment_info_custom = keyData.payment_info_custom ?? [];
178
+
179
+ if (obj.function === 'plus') {
180
+ const newFinance = JSON.parse(JSON.stringify(custom_finance));
181
+ keyData.payment_info_custom.push(newFinance);
182
+ } else {
183
+ const index = keyData.payment_info_custom.findIndex((d1: any) => d1.id === custom_finance.id);
184
+ if (index !== -1) {
185
+ keyData.payment_info_custom[index] = custom_finance;
186
+ } else {
187
+ console.error('找不到對應的金流設定 ID:', custom_finance.id);
188
+ return;
189
+ }
190
+ }
195
191
 
196
- gvc.closeDialog();
197
- refresh();
198
- });
199
- })
200
- );
192
+ dialog.dataLoading({ visible: true });
201
193
 
202
- if (obj.function === 'plus') {
203
- return saveButton;
204
- }
205
-
206
- return [
207
- BgWidget.danger(
208
- gvc.event(() => {
209
- dialog.checkYesOrNot({
210
- text: '是否確認刪除?',
211
- callback: response => {
212
- if (response) {
213
- keyData.payment_info_custom = keyData.payment_info_custom.filter((d1: any) => {
214
- return obj.data!.id !== d1.id;
215
- });
216
- dialog.dataLoading({ visible: true });
217
- saasConfig.api.setPrivateConfig(saasConfig.config.appName, 'glitter_finance', keyData);
194
+ try {
195
+ await form.save();
196
+ await saasConfig.api.setPrivateConfig(saasConfig.config.appName, 'glitter_finance', keyData);
197
+ dialog.successMessage({ text: '設定成功' });
198
+ } catch (error) {
199
+ console.error('更新金流設定失敗:', error);
200
+ dialog.errorMessage({ text: '設定失敗,請稍後再試' });
201
+ } finally {
218
202
  dialog.dataLoading({ visible: false });
219
- gvc.closeDialog();
220
- refresh();
221
203
  }
222
- },
223
- });
224
- })
225
- ),
226
- saveButton,
227
- ].join('');
228
- },
204
+
205
+ this.refresh(gvc);
206
+ })
207
+ );
208
+ },
209
+ () => this.refresh(gvc)
210
+ );
211
+ }),
212
+ };
229
213
  });
230
- }
214
+ };
231
215
 
232
216
  return BgWidget.container(
233
- html`
234
- ${[
235
- html` <div class="title-container ${pos ? `d-none` : ''}">
236
- ${BgWidget.title('金流設定')}
237
- <div class="flex-fill"></div>
238
- </div>`,
239
- gvc.bindView({
240
- bind: vm.id,
241
- view: () => {
242
- if (vm.loading) {
243
- return BgWidget.spinner();
244
- }
217
+ [
218
+ html` <div class="title-container ${pos ? 'd-none' : ''}">
219
+ ${BgWidget.title('金流設定')}
220
+ <div class="flex-fill"></div>
221
+ </div>`,
222
+ gvc.bindView({
223
+ bind: vm.id,
224
+ view: () => {
225
+ if (this.loading) {
226
+ return BgWidget.spinner();
227
+ }
245
228
 
246
- try {
247
- keyData.off_line_support = keyData.off_line_support ?? {
248
- line: false,
249
- atm: false,
250
- cash_on_delivery: false,
251
- ...keyData.payment_info_custom.map((dd: any) => {
252
- return {
253
- [dd.id]: false,
254
- };
255
- }),
256
- };
229
+ try {
230
+ // 初始化離線支付選項
231
+ this.initOfflineSupport(keyData);
232
+
233
+ // 清理不必要的離線支付選項
234
+ this.cleanupOfflineSupport(keyData);
235
+
236
+ return [
237
+ // 只有在非POS模式下才顯示頁籤
238
+ pos ? '' : this.renderTabs(gvc, vm),
239
+ // 根據當前頁面渲染相應內容
240
+ this.renderPageContent(gvc, vm, keyData, saveData, customFinance),
241
+ ].join('');
242
+ } catch (e) {
243
+ console.error(e);
244
+ return '發生錯誤';
245
+ }
246
+ },
247
+ onCreate: () => {
248
+ if (this.loading) {
249
+ return new Promise<void>(async resolve => {
250
+ const data = await saasConfig.api.getPrivateConfig(saasConfig.config.appName, 'glitter_finance');
251
+ if (data.response.result[0]) {
252
+ keyData = {
253
+ ...keyData,
254
+ ...data.response.result[0].value,
255
+ };
256
+ }
257
+ resolve();
258
+ }).then(() => {
259
+ this.loading = false;
260
+ gvc.notifyDataChange(vm.id);
261
+ });
262
+ } else {
263
+ const handleBeforeUnload = (e: any) => {
264
+ e.preventDefault();
265
+ e.returnValue = '您確定要離開金流設定嗎?您將會失去未儲存的更改';
266
+ };
267
+ (window.parent as any).document.addEventListener('beforeunload', handleBeforeUnload);
268
+ }
269
+ },
270
+ }),
271
+ pos ? '' : BgWidget.mbContainer(240),
272
+ ].join(''),
273
+ {
274
+ style: pos ? 'margin-top: 0px !important;' : '',
275
+ }
276
+ );
277
+ }
278
+
279
+ // 金物流頁面重新整理
280
+ static refresh = (dialogGVC?: GVC) => {
281
+ this.loading = true;
257
282
 
258
- Object.keys(keyData.off_line_support).map(key => {
259
- if (
260
- ['line', 'atm', 'cash_on_delivery'].includes(key) ||
261
- keyData.payment_info_custom.some((item: any) => item.id === key)
262
- ) {
263
- return;
264
- }
265
- delete keyData.off_line_support[key];
283
+ if (dialogGVC) {
284
+ dialogGVC.closeDialog();
285
+ }
286
+
287
+ if (this.gvc === null) {
288
+ console.error('Refresh GVC 並不存在');
289
+ return;
290
+ }
291
+
292
+ const pageGVC = this.gvc;
293
+ pageGVC.closeDialog();
294
+ setTimeout(() => pageGVC.notifyDataChange(this.id), 300);
295
+ };
296
+
297
+ // 初始化離線支付選項
298
+ private static initOfflineSupport(keyData: any): void {
299
+ keyData.off_line_support = keyData.off_line_support ?? {
300
+ line: false,
301
+ atm: false,
302
+ cash_on_delivery: false,
303
+ ...keyData.payment_info_custom.map((dd: any) => ({
304
+ [dd.id]: false,
305
+ })),
306
+ };
307
+ }
308
+
309
+ // 清理不必要的離線支付選項
310
+ private static cleanupOfflineSupport(keyData: any): void {
311
+ Object.keys(keyData.off_line_support).forEach(key => {
312
+ const isValidKey =
313
+ ['line', 'atm', 'cash_on_delivery'].includes(key) ||
314
+ keyData.payment_info_custom.some((item: any) => item.id === key);
315
+
316
+ if (!isValidKey) {
317
+ delete keyData.off_line_support[key];
318
+ }
319
+ });
320
+ }
321
+
322
+ // 渲染頁籤
323
+ private static renderTabs(gvc: any, vm: any): string {
324
+ return BgWidget.tab(
325
+ [
326
+ { key: 'online', title: '線上金流' },
327
+ { key: 'offline', title: '線下金流' },
328
+ ],
329
+ gvc,
330
+ vm.page,
331
+ (key: any) => {
332
+ vm.page = key;
333
+ gvc.notifyDataChange(vm.id);
334
+ }
335
+ );
336
+ }
337
+
338
+ // 根據當前頁面渲染相應內容
339
+ private static renderPageContent(gvc: any, vm: any, keyData: any, saveData: any, setCustomFinance: any): string {
340
+ switch (vm.page) {
341
+ case 'online':
342
+ return this.onlinePayment(gvc, keyData, saveData);
343
+ case 'offline':
344
+ return this.offlinePayment(gvc, keyData, saveData, setCustomFinance);
345
+ case 'pos':
346
+ return this.posPayment(gvc, keyData, saveData, setCustomFinance);
347
+ default:
348
+ return '';
349
+ }
350
+ }
351
+
352
+ // 線上金流卡片
353
+ static onlinePayment(gvc: GVC, keyData: any, saveData: () => void) {
354
+ return html` <div class="px-md-0 px-2 mb-2">
355
+ ${BgWidget.normalInsignia('透過線上金流,消費者可於線上進行結帳付款')}
356
+ </div>
357
+ <div class="row m-0">
358
+ ${PaymentConfig.onlinePay
359
+ .filter(item => item.type !== 'pos')
360
+ .map(dd => {
361
+ keyData[dd.key] = keyData[dd.key] ?? {};
362
+
363
+ return this.card({
364
+ title: dd.name,
365
+ img: html`<img src="${dd.img || BgWidget.noImageURL}" />`,
366
+ toggle: keyData[dd.key].toggle,
367
+ toggleEvent: gvc.event(() => {
368
+ keyData[dd.key].toggle = !keyData[dd.key].toggle;
369
+ saveData();
370
+ }),
371
+ buttonAction: this.formatOnlinePayList(gvc, dd.key, keyData[dd.key]) || [],
372
+ });
373
+ })
374
+ .join('')}
375
+ </div>`;
376
+ }
377
+
378
+ // 線下金流卡片
379
+ static offlinePayment(
380
+ gvc: GVC,
381
+ keyData: any,
382
+ saveData: () => void,
383
+ offlineCustomFinance: (obj: EditCustomFinance) => CustomButtonObject[]
384
+ ) {
385
+ const dialog = new ShareDialog(gvc.glitter);
386
+ const saasConfig = this.saasConfig;
387
+ const offlinePayArray = [
388
+ // 系統線下金流
389
+ ...PaymentConfig.defalutOfflinePay,
390
+ // 自訂線下金流
391
+ ...keyData.payment_info_custom
392
+ .filter((dd: any) => {
393
+ return dd.type !== 'pos';
394
+ })
395
+ .map((dd: any) => {
396
+ return {
397
+ key: dd.id,
398
+ name: html`${Language.getLanguageCustomText(dd.name)}`,
399
+ custom: true,
400
+ };
401
+ }),
402
+ ];
403
+
404
+ // 刪除自訂金流事件
405
+ const deleteEvent = (key: string) =>
406
+ gvc.event(() => {
407
+ dialog.checkYesOrNot({
408
+ text: '是否確認刪除此金流?',
409
+ callback: async response => {
410
+ if (response) {
411
+ const data = await saasConfig.api.getPrivateConfig(saasConfig.config.appName, 'glitter_finance');
412
+ if (data.response.result[0]) {
413
+ const keyData = data.response.result[0].value;
414
+
415
+ keyData.payment_info_custom = keyData.payment_info_custom.filter((d1: any) => {
416
+ return key !== d1.id;
266
417
  });
267
418
 
268
- let h = '';
269
- const cloneData = structuredClone(keyData);
419
+ dialog.dataLoading({ visible: true });
420
+ saasConfig.api.setPrivateConfig(saasConfig.config.appName, 'glitter_finance', keyData);
270
421
 
271
- // 線上金流
272
- if (vm.page === 'online') {
273
- h = html` <div class="px-md-0 px-2 mb-2">
274
- ${BgWidget.normalInsignia('透過線上金流,消費者可於線上進行結帳付款')}
275
- </div>
276
- <div class="row m-0">
277
- ${PaymentConfig.onlinePay
278
- .filter(item => item.type !== 'pos')
279
- .map(dd => {
280
- keyData[dd.key] = keyData[dd.key] ?? {};
281
- return html` <div class="col-12 col-lg-3 col-md-4 p-0 p-md-2">
282
- <div
283
- class="w-100 position-relative main-card"
284
- style=" background: white; overflow: hidden; flex-direction: column; justify-content: flex-start; align-items: flex-start; gap: 10px; display: inline-flex;"
285
- >
286
- <div
287
- class="pt-4"
288
- style="align-self: stretch; justify-content: flex-start; align-items: center; gap: 28px; display: inline-flex"
289
- >
290
- <div style="min-width: 46px;max-width: 46px;">
291
- <img src="${dd.img || BgWidget.noImageURL}" />
292
- </div>
293
- <div
294
- style="flex-direction: column; justify-content: center; align-items: flex-start; gap: 4px; display: inline-flex"
295
- >
296
- <div class="tx_normal">${dd.name}</div>
297
- <div class="d-flex align-items-center" style="gap:4px;">
298
- <div class="tx_normal">${keyData[dd.key].toggle ? `開啟` : `關閉`}</div>
299
- <div class="cursor_pointer form-check form-switch" style="margin-top: 10px;">
300
- <input
301
- class="form-check-input"
302
- type="checkbox"
303
- onchange="${gvc.event((e, event) => {
304
- keyData[dd.key].toggle = !keyData[dd.key].toggle;
305
- saveData();
306
- })}"
307
- ${keyData[dd.key].toggle ? `checked` : ''}
308
- />
309
- </div>
310
- </div>
311
- </div>
312
- </div>
313
- <div class="position-absolute " style="right:10px;top:10px;">
314
- ${BgWidget.customButton({
315
- button: {
316
- color: 'gray',
317
- size: 'sm',
318
- },
319
- text: {
320
- name: '金流設定',
321
- },
322
- event: gvc.event(() => {
323
- const payData = dd;
324
- const key_d = structuredClone(keyData[payData.key]);
325
-
326
- BgWidget.settingDialog({
327
- gvc: gvc,
328
- title: '金流設定',
329
- width: 800,
330
- innerHTML: (gvc: GVC) => {
331
- try {
332
- const setting = {
333
- key: 'setting',
334
- title: '基本設定',
335
- html: html` ${BgWidget.editeInput({
336
- gvc: gvc,
337
- title: html`<div>
338
- 自訂金流名稱 ${BgWidget.grayNote('未輸入則參照預設')}
339
- </div>`,
340
- default: key_d.custome_name,
341
- callback: text => {
342
- key_d.custome_name = text;
343
- },
344
- placeHolder: '請輸入自訂顯示名稱',
345
- global_language: true,
346
- })}
347
- <div style="margin-top: 8px;">
348
- ${(() => {
349
- switch (payData.key) {
350
- case 'newWebPay':
351
- case 'ecPay':
352
- return [
353
- BgWidget.inlineCheckBox({
354
- title: '串接路徑',
355
- gvc: gvc,
356
- def: key_d.ActionURL,
357
- array: (() => {
358
- if (payData.key === 'newWebPay') {
359
- return [
360
- {
361
- title: '正式站',
362
- value: 'https://core.newebpay.com/MPG/mpg_gateway',
363
- },
364
- {
365
- title: '測試站',
366
- value: 'https://ccore.newebpay.com/MPG/mpg_gateway',
367
- },
368
- ];
369
- } else {
370
- return [
371
- {
372
- title: '正式站',
373
- value:
374
- 'https://payment.ecpay.com.tw/Cashier/AioCheckOut/V5',
375
- },
376
- {
377
- title: '測試站',
378
- value:
379
- 'https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5',
380
- },
381
- ];
382
- }
383
- })(),
384
- callback: (text: any) => {
385
- key_d.ActionURL = text;
386
- },
387
- }),
388
- BgWidget.inlineCheckBox({
389
- title: '開通付款方式',
390
- gvc: gvc,
391
- def: [
392
- 'credit',
393
- 'atm',
394
- 'web_atm',
395
- 'c_code',
396
- 'c_bar_code',
397
- ].filter(dd => {
398
- return (key_d as any)[dd];
399
- }),
400
- array: [
401
- {
402
- title: '信用卡',
403
- value: 'credit',
404
- },
405
- {
406
- title: '一般 ATM',
407
- value: 'atm',
408
- },
409
- {
410
- title: '網路 ATM',
411
- value: 'web_atm',
412
- },
413
- {
414
- title: '超商代碼',
415
- value: 'c_code',
416
- },
417
- {
418
- title: '超商條碼',
419
- value: 'c_bar_code',
420
- },
421
- ],
422
- callback: (array: any) => {
423
- ['credit', 'atm', 'web_atm', 'c_code', 'c_bar_code'].map(
424
- dd => {
425
- (key_d as any)[dd] = !!array.find((d1: string) => {
426
- return d1 === dd;
427
- });
428
- }
429
- );
430
- },
431
- type: 'multiple',
432
- }),
433
- BgWidget.editeInput({
434
- gvc: gvc,
435
- title: '特店編號',
436
- default: key_d.MERCHANT_ID,
437
- callback: text => {
438
- key_d.MERCHANT_ID = text;
439
- },
440
- placeHolder: '請輸入特店編號',
441
- }),
442
- BgWidget.editeInput({
443
- gvc: gvc,
444
- title: 'HASH_KEY',
445
- default: key_d.HASH_KEY,
446
- callback: text => {
447
- key_d.HASH_KEY = text;
448
- },
449
- placeHolder: '請輸入HASH_KEY',
450
- }),
451
- BgWidget.editeInput({
452
- gvc: gvc,
453
- title: 'HASH_IV',
454
- default: key_d.HASH_IV,
455
- callback: text => {
456
- key_d.HASH_IV = text;
457
- },
458
- placeHolder: '請輸入HASH_IV',
459
- }),
460
- BgWidget.editeInput({
461
- gvc: gvc,
462
- title: '信用卡授權檢查碼',
463
- default: key_d.CreditCheckCode,
464
- callback: text => {
465
- key_d.CreditCheckCode = text;
466
- },
467
- placeHolder: '請輸入信用卡檢查碼',
468
- }),
469
- ].join('');
470
- case 'paypal':
471
- return [
472
- BgWidget.inlineCheckBox({
473
- title: '串接路徑',
474
- gvc: gvc,
475
- def: `${key_d.BETA}`,
476
- array: [
477
- {
478
- title: '正式站',
479
- value: `false`,
480
- },
481
- {
482
- title: '測試站',
483
- value: `true`,
484
- },
485
- ],
486
- callback: (text: any) => {
487
- key_d.BETA = text;
488
- },
489
- }),
490
- BgWidget.editeInput({
491
- gvc: gvc,
492
- title: 'CLIENT_ID',
493
- default: key_d.PAYPAL_CLIENT_ID,
494
- callback: text => {
495
- key_d.PAYPAL_CLIENT_ID = text;
496
- },
497
- placeHolder: '請輸入CLIENT_ID',
498
- }),
499
- BgWidget.editeInput({
500
- gvc: gvc,
501
- title: 'SECRET',
502
- default: key_d.PAYPAL_SECRET,
503
- callback: text => {
504
- key_d.PAYPAL_SECRET = text;
505
- },
506
- placeHolder: '請輸入SECRET',
507
- }),
508
- ].join('');
509
- case 'line_pay':
510
- return [
511
- BgWidget.inlineCheckBox({
512
- title: '串接路徑',
513
- gvc: gvc,
514
- def: `${key_d.BETA}`,
515
- array: [
516
- {
517
- title: '正式站',
518
- value: `false`,
519
- },
520
- {
521
- title: '測試站',
522
- value: `true`,
523
- },
524
- ],
525
- callback: (text: any) => {
526
- key_d.BETA = text;
527
- },
528
- }),
529
- BgWidget.editeInput({
530
- gvc: gvc,
531
- title: 'CLIENT_ID',
532
- default: key_d.CLIENT_ID,
533
- callback: text => {
534
- key_d.CLIENT_ID = text;
535
- },
536
- placeHolder: '請輸入CLIENT_ID',
537
- }),
538
- BgWidget.editeInput({
539
- gvc: gvc,
540
- title: 'SECRET',
541
- default: key_d.SECRET,
542
- callback: text => {
543
- key_d.SECRET = text;
544
- },
545
- placeHolder: '請輸入SECRET',
546
- }),
547
- ].join('');
548
- case 'jkopay':
549
- return [
550
- BgWidget.editeInput({
551
- gvc: gvc,
552
- title: 'STORE_ID',
553
- default: key_d.STORE_ID,
554
- callback: text => {
555
- key_d.STORE_ID = text;
556
- },
557
- placeHolder: '請輸入STORE_ID',
558
- }),
559
- ].join('');
560
- case 'paynow':
561
- return [
562
- BgWidget.inlineCheckBox({
563
- title: '串接路徑',
564
- gvc: gvc,
565
- def: `${key_d.BETA}`,
566
- array: [
567
- {
568
- title: '正式站',
569
- value: `false`,
570
- },
571
- {
572
- title: '測試站',
573
- value: `true`,
574
- },
575
- ],
576
- callback: (text: any) => {
577
- key_d.BETA = text;
578
- },
579
- }),
580
- BgWidget.editeInput({
581
- gvc: gvc,
582
- title: '串接帳號',
583
- default: key_d.account,
584
- callback: text => {
585
- key_d.account = text;
586
- },
587
- placeHolder: '請輸入串接帳號',
588
- }),
589
- BgWidget.editeInput({
590
- gvc: gvc,
591
- title: '串接密碼',
592
- default: key_d.pwd,
593
- callback: text => {
594
- key_d.pwd = text;
595
- },
596
- placeHolder: '請輸入串接密碼',
597
- }),
598
- ].join('');
599
- }
600
- return '';
601
- })()}
602
- </div>`,
603
- };
604
-
605
- const shipment = {
606
- key: 'shipment',
607
- title: '指定物流',
608
- html: gvc.bindView({
609
- bind: gvc.glitter.getUUID(),
610
- view: () => ShoppingFinanceSetting.setShipmentSupport(gvc, key_d),
611
- }),
612
- };
613
-
614
- const cartSetting = {
615
- key: 'cartSetting',
616
- title: '購物車設定',
617
- html: gvc.bindView({
618
- bind: gvc.glitter.getUUID(),
619
- view: () => ShoppingFinanceSetting.setCartSetting(gvc, key_d),
620
- }),
621
- };
422
+ dialog.dataLoading({ visible: false });
423
+ this.refresh();
424
+ }
425
+ }
426
+ },
427
+ });
428
+ });
622
429
 
623
- return ShoppingFinanceSetting.tabView(gvc, [setting, shipment, cartSetting]);
624
- } catch (e) {
625
- console.error(e);
626
- return `${e}`;
627
- }
628
- },
629
- footer_html: gvc => {
630
- return [
631
- BgWidget.cancel(
632
- gvc.event(() => {
633
- keyData = cloneData;
634
- gvc.closeDialog();
635
- })
636
- ),
637
- BgWidget.save(
638
- gvc.event(() => {
639
- //綠界支付的測試版切換
640
- if (
641
- payData.key == 'ecPay' &&
642
- key_d.ActionURL ==
643
- 'https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5'
644
- ) {
645
- key_d.MERCHANT_ID = '3002607';
646
- key_d.HASH_KEY = 'pwFHCqoQZGmho4w6';
647
- key_d.HASH_IV = 'EkRm7iFT261dpevs';
648
- }
649
- keyData[payData.key] = key_d;
650
- saveData();
651
- gvc.closeDialog();
652
- })
653
- ),
654
- ].join('');
655
- },
656
- closeCallback: () => {
657
- keyData = cloneData;
658
- },
659
- });
660
- }),
661
- })}
662
- </div>
663
- </div>
664
- </div>`;
665
- })
666
- .join('')}
667
- </div>`;
668
- }
430
+ // 預設的金流按鈕列表
431
+ const keyMap: (key: string) => string[] = key => {
432
+ const maps: Record<string, string[]> = {
433
+ atm: this.atm(gvc, key, keyData),
434
+ line: this.lineIPassMoney(gvc, key, keyData),
435
+ cash_on_delivery: this.cashOnDelivery(gvc, key, keyData),
436
+ };
669
437
 
670
- // 線下金流
671
- if (vm.page === 'offline') {
672
- const offlinePayArray = [
673
- // 系統線下金流
674
- ...PaymentConfig.defalutOfflinePay,
675
- // 自訂線下金流
676
- ...keyData.payment_info_custom.map((dd: any) => {
677
- return {
678
- key: dd.id,
679
- name: html`${Language.getLanguageCustomText(dd.name)}`,
680
- custom: true,
681
- };
682
- }),
683
- ];
684
-
685
- h = html` <div class="px-md-0 px-2 mb-2">
686
- ${BgWidget.normalInsignia(
687
- '透過設定線下金流,結帳後訂單將進入手動核款的流程,亦可使用超商取貨付款'
688
- )}
689
- </div>
690
- <div class="row m-0">
691
- ${offlinePayArray
692
- .map((dd: any) => {
693
- return html` <div class="col-12 col-lg-3 col-md-4 p-0 p-md-2">
694
- <div
695
- class="w-100 position-relative main-card "
696
- style=" background: white; overflow: hidden; flex-direction: column; justify-content: flex-start; align-items: flex-start;gap:10px; display: inline-flex;"
697
- >
698
- <div
699
- class="pt-4"
700
- style="align-self: stretch; justify-content: flex-start; align-items: center; gap: 28px; display: inline-flex"
701
- >
702
- <div style="min-width: 46px;max-width: 46px;">
703
- ${dd.img
704
- ? html`<img class="rounded-2" src="${dd.img}" />`
705
- : html`<i class="fa-regular fa-puzzle-piece-simple fs-4" aria-hidden="true"></i>`}
706
- </div>
707
- <div
708
- style="flex-direction: column; justify-content: center; align-items: flex-start; gap: 4px; display: inline-flex"
709
- >
710
- <div class="tx_normal">${dd.name}</div>
711
- <div class="d-flex align-items-center" style="gap:4px;">
712
- <div class="tx_normal">
713
- ${(keyData.off_line_support as any)[dd.key] ? `開啟` : `關閉`}
714
- </div>
715
- <div class="cursor_pointer form-check form-switch" style="margin-top: 10px;">
716
- <input
717
- class="form-check-input"
718
- type="checkbox"
719
- onchange="${gvc.event((e, event) => {
720
- (keyData.off_line_support as any)[dd.key] = !(
721
- keyData.off_line_support as any
722
- )[dd.key];
723
- saveData();
724
- })}"
725
- ${(keyData.off_line_support as any)[dd.key] ? `checked` : ''}
726
- />
727
- </div>
728
- </div>
729
- </div>
730
- </div>
731
- <div
732
- class=" position-absolute ${dd.hide_setting ? `d-none` : ''}"
733
- style="right:10px;top:10px;"
734
- >
735
- ${BgWidget.customButton({
736
- button: {
737
- color: 'gray',
738
- size: 'sm',
739
- },
740
- text: {
741
- name: '金流設定',
742
- },
743
- event: gvc.event(() => {
744
- if (dd.custom) {
745
- updateCustomFinance({
746
- function: 'replace',
747
- data: keyData.payment_info_custom.find((d1: any) => dd.key === d1.id),
748
- });
749
- return;
750
- }
438
+ return maps[key] || [];
439
+ };
751
440
 
752
- BgWidget.settingDialog({
753
- gvc: gvc,
754
- title: '金流設定',
755
- width: 800,
756
- innerHTML: gvc => {
757
- const keyMap: Record<string, string> = {
758
- atm: this.atm(gvc, keyData),
759
- line: this.lineIPassMoney(gvc, keyData),
760
- cash_on_delivery: this.cashOnDelivery(gvc, keyData),
761
- };
762
- return html`<div>${keyMap[dd.key] || ''}</div>`;
763
- },
764
- footer_html: gvc => {
765
- return [
766
- BgWidget.cancel(
767
- gvc.event(() => {
768
- keyData = cloneData;
769
- gvc.closeDialog();
770
- })
771
- ),
772
- BgWidget.save(
773
- gvc.event(() => {
774
- saveData();
775
- gvc.closeDialog();
776
- })
777
- ),
778
- ].join('');
779
- },
780
- closeCallback: () => {
781
- keyData = cloneData;
782
- },
783
- });
784
- }),
785
- })}
786
- </div>
787
- </div>
788
- </div>`;
789
- })
790
- .join('')}
791
- <div
792
- class="col-12 col-lg-3 col-md-4 p-0 p-md-2"
793
- style="cursor: pointer;"
794
- onclick="${gvc.event(() => {
795
- updateCustomFinance({ function: 'plus' });
796
- })}"
797
- >
798
- <div
799
- class="w-100 main-card"
800
- style="min-height:119.09px;padding: 24px; background: white; overflow: hidden; flex-direction: column; justify-content: center; align-items: center; gap: 18px; display: inline-flex"
801
- >
802
- <div
803
- class="fw-bold"
804
- style="align-self: stretch; justify-content: center; align-items: center; gap: 14px; display: inline-flex;color:#4D86DB;"
805
- >
806
- <i class="fa-regular fa-circle-plus fs-5"></i>
807
- <div class="fs-5">新增自訂付款</div>
808
- </div>
809
- </div>
810
- </div>
811
- </div>`;
812
- }
441
+ return html` <div class="px-md-0 px-2 mb-2">
442
+ ${BgWidget.normalInsignia('透過設定線下金流,結帳後訂單將進入手動核款的流程,亦可使用超商取貨付款')}
443
+ </div>
444
+ <div class="row m-0">
445
+ ${offlinePayArray
446
+ .map((dd: any) => {
447
+ keyData[dd.key] = keyData[dd.key] ?? {};
448
+
449
+ const button_action = dd.custom
450
+ ? offlineCustomFinance({
451
+ function: 'replace',
452
+ data: keyData.payment_info_custom.find((d1: any) => dd.key === d1.id),
453
+ }).map(item => {
454
+ return BgWidget.customButton(item);
455
+ })
456
+ : keyMap(dd.key) || [];
457
+
458
+ return this.card({
459
+ title: dd.name,
460
+ img: dd.img
461
+ ? html`<img class="rounded-2" src="${dd.img}" />`
462
+ : html`<i class="fa-regular fa-puzzle-piece-simple fs-4" aria-hidden="true"></i>`,
463
+ toggle: keyData.off_line_support[dd.key],
464
+ toggleEvent: gvc.event(() => {
465
+ keyData.off_line_support[dd.key] = !keyData.off_line_support[dd.key];
466
+ saveData();
467
+ }),
468
+ buttonAction: button_action,
469
+ deleteEvent: dd.custom ? deleteEvent(dd.key) : undefined,
470
+ });
471
+ })
472
+ .join('')}
473
+ ${this.addCard('新增自訂付款', offlineCustomFinance({ function: 'plus' })[0].event)}
474
+ </div>`;
475
+ }
813
476
 
814
- // POS
815
- if (vm.page === 'pos') {
816
- h = html`<div class="px-md-0 px-2 mb-2">
817
- ${BgWidget.normalInsignia('設定實體店面所需串接的付款方式')}
818
- </div>
819
- <div class="row m-0">
820
- ${PaymentConfig.onlinePay
821
- .filter(item => item.type === 'pos')
822
- .map(dd => {
823
- return html` <div class="col-12 col-lg-3 col-md-4 p-0 p-md-2">
824
- <div
825
- class="w-100 position-relative main-card"
826
- style=" background: white; overflow: hidden; flex-direction: column; justify-content: flex-start; align-items: flex-start; gap: 10px; display: inline-flex;"
827
- >
828
- <div
829
- class="pt-4"
830
- style="align-self: stretch; justify-content: flex-start; align-items: center; gap: 28px; display: inline-flex"
831
- >
832
- <div style="min-width: 46px;max-width: 46px;">
833
- <img src="${dd.img || BgWidget.noImageURL}" />
834
- </div>
835
- <div
836
- style="flex-direction: column; justify-content: center; align-items: flex-start; gap: 4px; display: inline-flex"
837
- >
838
- <div class="tx_normal">${dd.name}</div>
839
- <div class="d-flex align-items-center" style="gap:4px;">
840
- <div class="tx_normal">${keyData[dd.key].toggle ? `開啟` : `關閉`}</div>
841
- <div class="cursor_pointer form-check form-switch" style="margin-top: 10px;">
842
- <input
843
- class="form-check-input"
844
- type="checkbox"
845
- onchange="${gvc.event(() => {
846
- keyData[dd.key].toggle = !keyData[dd.key].toggle;
847
- saveData();
848
- })}"
849
- ${keyData[dd.key].toggle ? `checked` : ''}
850
- />
851
- </div>
852
- </div>
853
- </div>
854
- </div>
477
+ // POS 金流卡片
478
+ static posPayment(
479
+ gvc: GVC,
480
+ keyData: any,
481
+ saveData: () => void,
482
+ posCustomFinance: (obj: EditCustomFinance) => CustomButtonObject[]
483
+ ) {
484
+ const dialog = new ShareDialog(gvc.glitter);
485
+ const saasConfig = this.saasConfig;
486
+
487
+ const posCashflow = [
488
+ // 系統 POS 金流
489
+ ...PaymentConfig.onlinePay.filter(item => item.type === 'pos'),
490
+ // 自訂 POS 金流
491
+ ...keyData.payment_info_custom
492
+ .filter((dd: any) => {
493
+ return dd.type === 'pos';
494
+ })
495
+ .map((dd: any) => {
496
+ return {
497
+ key: dd.id,
498
+ name: dd.name,
499
+ type: 'pos',
500
+ custom: true,
501
+ img: html`<i class="fa-regular fa-puzzle-piece-simple fs-4"></i>`,
502
+ };
503
+ }),
504
+ ];
505
+
506
+ const deleteEvent = (key: string) =>
507
+ gvc.event(() => {
508
+ dialog.checkYesOrNot({
509
+ text: '是否確認刪除此金流?',
510
+ callback: async response => {
511
+ if (response) {
512
+ const data = await saasConfig.api.getPrivateConfig(saasConfig.config.appName, 'glitter_finance');
513
+ if (data.response.result[0]) {
514
+ const keyData = data.response.result[0].value;
515
+
516
+ keyData.payment_info_custom = keyData.payment_info_custom.filter((d1: any) => {
517
+ return key !== d1.id;
518
+ });
855
519
 
856
- <div class="position-absolute" style="right:10px;top:10px;">
857
- ${BgWidget.customButton({
858
- button: {
859
- color: 'gray',
860
- size: 'sm',
861
- },
862
- text: {
863
- name: '金流設定',
864
- },
865
- event: gvc.event(() => {
866
- const payData = dd;
867
- const key_d = structuredClone(keyData[payData.key]);
868
- BgWidget.settingDialog({
869
- gvc: gvc,
870
- title: '金流設定',
871
- width: 800,
872
- innerHTML: (gvc: GVC) => {
873
- try {
874
- return html`<div>
875
- ${(() => {
876
- switch (payData.key) {
877
- case 'line_pay_scan':
878
- return this.linePayScan(gvc, key_d);
879
- case 'ut_credit_card':
880
- return this.utCreditCard(gvc, key_d);
881
- }
882
- return '';
883
- })()}
884
- </div>`;
885
- } catch (error) {
886
- console.error(error);
887
- return '';
888
- }
889
- },
890
- footer_html: gvc => {
891
- return [
892
- BgWidget.cancel(
893
- gvc.event(() => {
894
- keyData = cloneData;
895
- gvc.closeDialog();
896
- })
897
- ),
898
- BgWidget.save(
899
- gvc.event(() => {
900
- keyData[payData.key] = key_d;
901
- saveData();
902
- gvc.closeDialog();
903
- })
904
- ),
905
- ].join('');
906
- },
907
- closeCallback: () => {
908
- keyData = cloneData;
909
- },
910
- });
911
- }),
912
- })}
913
- </div>
914
- </div>
915
- </div>`;
916
- })
917
- .join('')}
918
- </div>`;
919
- }
520
+ dialog.dataLoading({ visible: true });
521
+ saasConfig.api.setPrivateConfig(saasConfig.config.appName, 'glitter_finance', keyData);
920
522
 
921
- return [
922
- pos
923
- ? ''
924
- : BgWidget.tab(
925
- [
926
- { key: 'online', title: '線上金流' },
927
- { key: 'offline', title: '線下金流' },
928
- ],
929
- gvc,
930
- vm.page,
931
- (key: any) => {
932
- vm.page = key;
933
- gvc.notifyDataChange(vm.id);
934
- }
935
- ),
936
- h,
937
- ].join('');
938
- } catch (e) {
939
- console.error(e);
940
- return `${e}`;
523
+ dialog.dataLoading({ visible: false });
524
+ this.refresh();
941
525
  }
942
- },
943
- onCreate: () => {
944
- if (vm.loading) {
945
- return new Promise<void>(async resolve => {
946
- const data = await saasConfig.api.getPrivateConfig(saasConfig.config.appName, 'glitter_finance');
947
- if (data.response.result[0]) {
948
- keyData = {
949
- ...keyData,
950
- ...data.response.result[0].value,
951
- };
952
- }
953
- resolve();
954
- }).then(() => {
955
- vm.loading = false;
956
- gvc.notifyDataChange(vm.id);
526
+ }
527
+ },
528
+ });
529
+ });
530
+
531
+ return html`<div class="px-md-0 px-2 mb-2">${BgWidget.normalInsignia('設定實體店面所需串接的付款方式')}</div>
532
+ <div class="row m-0">
533
+ ${posCashflow
534
+ .map(dd => {
535
+ keyData[dd.key] = keyData[dd.key] ?? {};
536
+
537
+ const data = structuredClone(keyData[dd.key]);
538
+ const button_action: string[] = (() => {
539
+ if (dd.custom) {
540
+ return posCustomFinance({
541
+ function: 'replace',
542
+ data: keyData.payment_info_custom.find((d1: any) => dd.key === d1.id),
543
+ }).map(item => {
544
+ return BgWidget.customButton(item);
957
545
  });
958
- } else {
959
- const handleBeforeUnload = (e: any) => {
960
- e.preventDefault();
961
- e.returnValue = '您確定要離開金流設定嗎?您將會失去未儲存的更改';
962
- };
963
- (window.parent as any).document.addEventListener('beforeunload', handleBeforeUnload);
964
546
  }
965
- },
966
- }),
967
- ].join('')}
968
- ${pos ? '' : BgWidget.mbContainer(240)}
969
- `,
970
- {
971
- style: pos ? `margin-top: 0px !important;` : '',
972
- }
973
- );
547
+ if (dd.key === 'line_pay_scan') {
548
+ return this.linePayScan(gvc, dd.key, data);
549
+ }
550
+ if (dd.key === 'ut_credit_card') {
551
+ return this.utCreditCard(gvc, dd.key, data);
552
+ }
553
+ return [];
554
+ })();
555
+
556
+ return this.card({
557
+ title: dd.name,
558
+ img: dd.img.includes('fa-puzzle-piece') ? dd.img : html`<img src="${dd.img || BgWidget.noImageURL}" />`,
559
+ toggle: keyData[dd.key].toggle,
560
+ toggleEvent: gvc.event(() => {
561
+ keyData[dd.key].toggle = !keyData[dd.key].toggle;
562
+ saveData();
563
+ }),
564
+ buttonAction: button_action,
565
+ deleteEvent: dd.custom ? deleteEvent(dd.key) : undefined,
566
+ });
567
+ })
568
+ .join('')}
569
+ ${this.addCard('新增自訂付款', posCustomFinance({ function: 'plus' })[0].event)}
570
+ </div>`;
974
571
  }
975
572
 
976
573
  // 分頁模組
@@ -1001,12 +598,73 @@ export class ShoppingFinanceSetting {
1001
598
  });
1002
599
  }
1003
600
 
601
+ // 金物流 Dialog
602
+ static settingDialog(
603
+ gvc: GVC,
604
+ title: string,
605
+ innerHTML: (gvc: GVC) => string,
606
+ footerHTML: (gvc: GVC) => string,
607
+ closeCallback: () => void
608
+ ) {
609
+ return BgWidget.settingDialog({
610
+ gvc,
611
+ title,
612
+ innerHTML: gvc => innerHTML(gvc),
613
+ footer_html: gvc => footerHTML(gvc),
614
+ closeCallback: closeCallback,
615
+ });
616
+ }
617
+
618
+ // 系統預設按鈕條列
619
+ static buttonListView(
620
+ gvc: GVC,
621
+ key: string,
622
+ keyData: any,
623
+ viewList: { key: string; title: string; html: (gvc: GVC) => string }[]
624
+ ) {
625
+ return viewList.map(item => {
626
+ return BgWidget.customButton({
627
+ button: { color: 'gray', size: 'sm' },
628
+ text: { name: item.title },
629
+ event: gvc.event(async () => {
630
+ this.settingDialog(
631
+ gvc,
632
+ item.title,
633
+ gvc => html`<div>${item.html(gvc)}</div>`,
634
+ gvc => {
635
+ return [
636
+ BgWidget.cancel(gvc.event(() => this.refresh(gvc))),
637
+ BgWidget.save(
638
+ gvc.event(async () => {
639
+ try {
640
+ const saasConfig = this.saasConfig;
641
+ const data = await saasConfig.api.getPrivateConfig(saasConfig.config.appName, 'glitter_finance');
642
+
643
+ data.response.result[0].value[key] = keyData;
644
+ saasConfig.api
645
+ .setPrivateConfig(saasConfig.config.appName, 'glitter_finance', data.response.result[0].value)
646
+ .then(() => this.refresh(gvc));
647
+ } catch (error) {
648
+ console.error(error);
649
+ gvc.closeDialog();
650
+ }
651
+ })
652
+ ),
653
+ ].join('');
654
+ },
655
+ () => this.refresh(gvc)
656
+ );
657
+ }),
658
+ });
659
+ });
660
+ }
661
+
1004
662
  // 自訂物流設定
1005
663
  static async setShipmentSupport(gvc: GVC, data: Record<string, any>) {
1006
664
  const id = gvc.glitter.getUUID();
1007
-
1008
- const saasConfig: { config: any; api: any } = (window.parent as any).saasConfig;
665
+ const saasConfig = this.saasConfig;
1009
666
  const logiData = await saasConfig.api.getPrivateConfig(saasConfig.config.appName, 'logistics_setting');
667
+
1010
668
  const custom_delivery: any[] = (() => {
1011
669
  try {
1012
670
  return logiData?.response?.result[0]?.value?.custom_delivery || [];
@@ -1031,26 +689,16 @@ export class ShoppingFinanceSetting {
1031
689
  return html`<div class="w-100">
1032
690
  <div class="d-flex align-items-center mt-2 gap-2">
1033
691
  ${BgWidget.customButton({
1034
- button: {
1035
- color: 'snow',
1036
- size: 'sm',
1037
- },
1038
- text: {
1039
- name: '全部開啟',
1040
- },
692
+ button: { color: 'snow', size: 'sm' },
693
+ text: { name: '全部開啟' },
1041
694
  event: gvc.event(() => {
1042
695
  data.shipmentSupport = allDelivery.map(d => d.value);
1043
696
  gvc.notifyDataChange(id);
1044
697
  }),
1045
698
  })}
1046
699
  ${BgWidget.customButton({
1047
- button: {
1048
- color: 'snow',
1049
- size: 'sm',
1050
- },
1051
- text: {
1052
- name: '全部關閉',
1053
- },
700
+ button: { color: 'snow', size: 'sm' },
701
+ text: { name: '全部關閉' },
1054
702
  event: gvc.event(() => {
1055
703
  data.shipmentSupport = [];
1056
704
  gvc.notifyDataChange(id);
@@ -1096,7 +744,7 @@ export class ShoppingFinanceSetting {
1096
744
  style="flex-direction: column; justify-content: center; align-items: flex-start; gap: 4px; display: inline-flex"
1097
745
  >
1098
746
  <div class="tx_normal">${dd.title}</div>
1099
- <div class="d-flex align-items-center" style="gap:4px;">
747
+ <div class="d-flex align-items-center" style="gap: 4px;">
1100
748
  <div class="tx_normal">${trigger ? '開啟' : '關閉'}</div>
1101
749
  <div class="cursor_pointer form-check form-switch" style="margin-top: 10px;">
1102
750
  <input
@@ -1193,52 +841,56 @@ export class ShoppingFinanceSetting {
1193
841
  bind: id,
1194
842
  view: () => {
1195
843
  return [
1196
- html`<div class="d-flex align-items-center mt-2 gap-2 mb-2">
1197
- <div class="tx_700">是否啟用此${t}流的計算公式包含</div>
1198
- ${questionDialog(
1199
- html`<div style="white-space: normal;">
1200
- 訂單總金額的公式為:<br />
1201
- 「總金額(T) = 所有商品小計(A) - 購物金折抵(B) - 優惠券折抵(C) + 運費(D)」
1202
- </div>
1203
- ${BgWidget.mbContainer(12)}
1204
- <div style="white-space: normal;">勾選的項目會列為「限制使用此${t}流」的公式判斷</div>
1205
- ${BgWidget.mbContainer(12)}
1206
- <div style="white-space: normal;">
1207
- 範例:僅勾選「運費」,顧客購物車消費的總金額依然是 A-B-C+D<br />
1208
- 但此${t}流是否能使用的公式會是 A+D
1209
- </div>
1210
- ${BgWidget.mbContainer(12)}
1211
- <div style="white-space: normal;">
1212
- A+D 有在最低和最高消費金額的區間內<br />
1213
- 則顧客可以使用此${t}流進行結帳
1214
- </div>`
1215
- )}
1216
- </div>`,
1217
- BgWidget.multiCheckboxContainer(
1218
- gvc,
1219
- [
1220
- {
1221
- key: 'use_rebate',
1222
- name: '購物金折抵',
1223
- },
1224
- {
1225
- key: 'discount',
1226
- name: '優惠券折抵',
1227
- },
1228
- {
1229
- key: 'shipment_fee',
1230
- name: '運費',
844
+ [
845
+ html`<div class="d-flex align-items-center gap-2">
846
+ <div class="tx_700">金額計算規則</div>
847
+ ${questionDialog(
848
+ html`<div style="white-space: normal;">
849
+ 訂單總金額的公式為:<br />
850
+ 「總金額(T) = 所有商品小計(A) - 購物金折抵(B) - 優惠券折抵(C) + 運費(D)」
851
+ </div>
852
+ ${BgWidget.mbContainer(12)}
853
+ <div style="white-space: normal;">勾選的項目會列為「限制使用此${t}流」的公式判斷</div>
854
+ ${BgWidget.mbContainer(12)}
855
+ <div style="white-space: normal;">
856
+ 範例:僅勾選「運費」,顧客購物車消費的總金額依然是 A-B-C+D<br />
857
+ 但此${t}流是否能使用的公式會是 A+D
858
+ </div>
859
+ ${BgWidget.mbContainer(12)}
860
+ <div style="white-space: normal;">
861
+ 若 A+D 有在最低和最高消費金額的區間內<br />
862
+ 則顧客可以使用此${t}流進行結帳
863
+ </div>`
864
+ )}
865
+ </div>`,
866
+ BgWidget.grayNote('系統會依據您選擇的規則計算訂單金額,再判斷是否達到以下門檻'),
867
+ BgWidget.mbContainer(8),
868
+ BgWidget.multiCheckboxContainer(
869
+ gvc,
870
+ [
871
+ {
872
+ key: 'use_rebate',
873
+ name: '含購物金折抵',
874
+ },
875
+ {
876
+ key: 'discount',
877
+ name: '含優惠券折抵',
878
+ },
879
+ {
880
+ key: 'shipment_fee',
881
+ name: '含運費',
882
+ },
883
+ ],
884
+ data.cartSetting.orderFormula,
885
+ result => {
886
+ data.cartSetting.orderFormula = result;
1231
887
  },
1232
- ],
1233
- data.cartSetting.orderFormula,
1234
- result => {
1235
- data.cartSetting.orderFormula = result;
1236
- },
1237
- { single: false }
1238
- ),
888
+ { single: false }
889
+ ),
890
+ ].join(''),
1239
891
  BgWidget.editeInput({
1240
892
  gvc: gvc,
1241
- title: html`<div class="d-flex align-items-center mt-3 gap-2">最低消費金額(輸入 0 則沒有限制)</div>
893
+ title: html`<div class="tx_700">最低消費門檻 (輸入 0 則沒有限制)</div>
1242
894
  ${BgWidget.grayNote(`購物車需達到此金額,才可使用此${t}流`)}`,
1243
895
  default: `${data.cartSetting.minimumTotal}`,
1244
896
  type: 'number',
@@ -1249,7 +901,7 @@ export class ShoppingFinanceSetting {
1249
901
  }),
1250
902
  BgWidget.editeInput({
1251
903
  gvc: gvc,
1252
- title: html`<div class="d-flex align-items-center mt-3 gap-2">最高消費金額(輸入 0 則沒有限制)</div>
904
+ title: html`<div class="tx_700">最高消費門檻 (輸入 0 則沒有限制)</div>
1253
905
  ${BgWidget.grayNote(`購物車需低於此金額,才可使用此${t}流`)}`,
1254
906
  default: `${data.cartSetting.maximumTotal}`,
1255
907
  type: 'number',
@@ -1261,124 +913,453 @@ export class ShoppingFinanceSetting {
1261
913
  BgWidget.horizontalLine({ margin: 1.5 }),
1262
914
  BgWidget.editeInput({
1263
915
  gvc: gvc,
1264
- title: html`<div class="mt-3" style="white-space: break-spaces;">滿額免運(輸入 0 則不啟用)</div>
1265
- ${BgWidget.grayNote('購物車達到此金額即享有免運優惠')}`,
1266
- default: `${data.cartSetting.freeShipmnetTarget}`,
1267
- type: 'number',
916
+ title: html`<div class="tx_700">滿額免運 (輸入 0 則不啟用)</div>
917
+ ${BgWidget.grayNote('購物車達到此金額即享有免運優惠')}`,
918
+ default: `${data.cartSetting.freeShipmnetTarget}`,
919
+ type: 'number',
920
+ callback: text => {
921
+ checkTotalNumber(text, 'freeShipmnet');
922
+ },
923
+ placeHolder: '請輸入金額',
924
+ }),
925
+ ].join(BgWidget.mbContainer(18));
926
+ },
927
+ });
928
+ }
929
+
930
+ // 藍新 & 綠界表單
931
+ static ePayForm(gvc: GVC, key_d: any, brand: 'newWebPay' | 'ecPay') {
932
+ return [
933
+ BgWidget.inlineCheckBox({
934
+ title: '串接路徑',
935
+ gvc: gvc,
936
+ def: key_d.ActionURL,
937
+ array: (() => {
938
+ if (brand === 'newWebPay') {
939
+ return [
940
+ {
941
+ title: '正式站',
942
+ value: 'https://core.newebpay.com/MPG/mpg_gateway',
943
+ },
944
+ {
945
+ title: '測試站',
946
+ value: 'https://ccore.newebpay.com/MPG/mpg_gateway',
947
+ },
948
+ ];
949
+ } else {
950
+ return [
951
+ {
952
+ title: '正式站',
953
+ value: 'https://payment.ecpay.com.tw/Cashier/AioCheckOut/V5',
954
+ },
955
+ {
956
+ title: '測試站',
957
+ value: 'https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5',
958
+ },
959
+ ];
960
+ }
961
+ })(),
962
+ callback: (text: any) => {
963
+ key_d.ActionURL = text;
964
+ },
965
+ }),
966
+ BgWidget.inlineCheckBox({
967
+ title: '開通付款方式',
968
+ gvc: gvc,
969
+ def: ['credit', 'atm', 'web_atm', 'c_code', 'c_bar_code'].filter(dd => {
970
+ return (key_d as any)[dd];
971
+ }),
972
+ array: [
973
+ {
974
+ title: '信用卡',
975
+ value: 'credit',
976
+ },
977
+ {
978
+ title: '一般 ATM',
979
+ value: 'atm',
980
+ },
981
+ {
982
+ title: '網路 ATM',
983
+ value: 'web_atm',
984
+ },
985
+ {
986
+ title: '超商代碼',
987
+ value: 'c_code',
988
+ },
989
+ {
990
+ title: '超商條碼',
991
+ value: 'c_bar_code',
992
+ },
993
+ ],
994
+ callback: (array: any) => {
995
+ ['credit', 'atm', 'web_atm', 'c_code', 'c_bar_code'].map(dd => {
996
+ (key_d as any)[dd] = !!array.find((d1: string) => {
997
+ return d1 === dd;
998
+ });
999
+ });
1000
+ },
1001
+ type: 'multiple',
1002
+ }),
1003
+ BgWidget.editeInput({
1004
+ gvc: gvc,
1005
+ title: '商店代號',
1006
+ default: key_d.MERCHANT_ID,
1007
+ callback: text => {
1008
+ key_d.MERCHANT_ID = text;
1009
+ },
1010
+ placeHolder: '請輸入商店代號',
1011
+ }),
1012
+ BgWidget.editeInput({
1013
+ gvc: gvc,
1014
+ title: 'HASH_KEY',
1015
+ default: key_d.HASH_KEY,
1016
+ callback: text => {
1017
+ key_d.HASH_KEY = text;
1018
+ },
1019
+ placeHolder: '請輸入HASH_KEY',
1020
+ }),
1021
+ BgWidget.editeInput({
1022
+ gvc: gvc,
1023
+ title: 'HASH_IV',
1024
+ default: key_d.HASH_IV,
1025
+ callback: text => {
1026
+ key_d.HASH_IV = text;
1027
+ },
1028
+ placeHolder: '請輸入HASH_IV',
1029
+ }),
1030
+ BgWidget.editeInput({
1031
+ gvc: gvc,
1032
+ title: '信用卡授權檢查碼',
1033
+ default: key_d.CreditCheckCode,
1034
+ callback: text => {
1035
+ key_d.CreditCheckCode = text;
1036
+ },
1037
+ placeHolder: '請輸入信用卡檢查碼',
1038
+ }),
1039
+ ].join('');
1040
+ }
1041
+
1042
+ // Paypal 表單
1043
+ static paypalForm(gvc: GVC, key_d: any) {
1044
+ return [
1045
+ BgWidget.inlineCheckBox({
1046
+ title: '串接路徑',
1047
+ gvc: gvc,
1048
+ def: `${key_d.BETA}`,
1049
+ array: [
1050
+ {
1051
+ title: '正式站',
1052
+ value: `false`,
1053
+ },
1054
+ {
1055
+ title: '測試站',
1056
+ value: `true`,
1057
+ },
1058
+ ],
1059
+ callback: (text: any) => {
1060
+ key_d.BETA = text;
1061
+ },
1062
+ }),
1063
+ BgWidget.editeInput({
1064
+ gvc: gvc,
1065
+ title: 'CLIENT_ID',
1066
+ default: key_d.PAYPAL_CLIENT_ID,
1067
+ callback: text => {
1068
+ key_d.PAYPAL_CLIENT_ID = text;
1069
+ },
1070
+ placeHolder: '請輸入CLIENT_ID',
1071
+ }),
1072
+ BgWidget.editeInput({
1073
+ gvc: gvc,
1074
+ title: 'SECRET',
1075
+ default: key_d.PAYPAL_SECRET,
1076
+ callback: text => {
1077
+ key_d.PAYPAL_SECRET = text;
1078
+ },
1079
+ placeHolder: '請輸入SECRET',
1080
+ }),
1081
+ ].join('');
1082
+ }
1083
+
1084
+ // Line Pay 表單
1085
+ static linepayForm(gvc: GVC, key_d: any) {
1086
+ return [
1087
+ BgWidget.inlineCheckBox({
1088
+ title: '串接路徑',
1089
+ gvc: gvc,
1090
+ def: `${key_d.BETA}`,
1091
+ array: [
1092
+ {
1093
+ title: '正式站',
1094
+ value: `false`,
1095
+ },
1096
+ {
1097
+ title: '測試站',
1098
+ value: `true`,
1099
+ },
1100
+ ],
1101
+ callback: (text: any) => {
1102
+ key_d.BETA = text;
1103
+ },
1104
+ }),
1105
+ BgWidget.editeInput({
1106
+ gvc: gvc,
1107
+ title: 'CLIENT_ID',
1108
+ default: key_d.CLIENT_ID,
1109
+ callback: text => {
1110
+ key_d.CLIENT_ID = text;
1111
+ },
1112
+ placeHolder: '請輸入CLIENT_ID',
1113
+ }),
1114
+ BgWidget.editeInput({
1115
+ gvc: gvc,
1116
+ title: 'SECRET',
1117
+ default: key_d.SECRET,
1118
+ callback: text => {
1119
+ key_d.SECRET = text;
1120
+ },
1121
+ placeHolder: '請輸入SECRET',
1122
+ }),
1123
+ ].join('');
1124
+ }
1125
+
1126
+ // 街口表單
1127
+ static jkopayForm(gvc: GVC, key_d: any) {
1128
+ return [
1129
+ BgWidget.editeInput({
1130
+ gvc: gvc,
1131
+ title: 'STORE_ID',
1132
+ default: key_d.STORE_ID,
1133
+ callback: text => {
1134
+ key_d.STORE_ID = text;
1135
+ },
1136
+ placeHolder: '請輸入STORE_ID',
1137
+ }),
1138
+ ].join('');
1139
+ }
1140
+
1141
+ // Paynow 表單
1142
+ static paynowForm(gvc: GVC, key_d: any) {
1143
+ return [
1144
+ BgWidget.inlineCheckBox({
1145
+ title: '串接路徑',
1146
+ gvc: gvc,
1147
+ def: `${key_d.BETA}`,
1148
+ array: [
1149
+ {
1150
+ title: '正式站',
1151
+ value: `false`,
1152
+ },
1153
+ {
1154
+ title: '測試站',
1155
+ value: `true`,
1156
+ },
1157
+ ],
1158
+ callback: (text: any) => {
1159
+ key_d.BETA = text;
1160
+ },
1161
+ }),
1162
+ BgWidget.editeInput({
1163
+ gvc: gvc,
1164
+ title: '串接帳號',
1165
+ default: key_d.account,
1166
+ callback: text => {
1167
+ key_d.account = text;
1168
+ },
1169
+ placeHolder: '請輸入串接帳號',
1170
+ }),
1171
+ BgWidget.editeInput({
1172
+ gvc: gvc,
1173
+ title: '串接密碼',
1174
+ default: key_d.pwd,
1175
+ callback: text => {
1176
+ key_d.pwd = text;
1177
+ },
1178
+ placeHolder: '請輸入串接密碼',
1179
+ }),
1180
+ ].join('');
1181
+ }
1182
+
1183
+ // 彈窗: 線上付款
1184
+ static formatOnlinePayList(gvc: GVC, key: string, key_d: any) {
1185
+ const setting = {
1186
+ key: 'setting',
1187
+ title: '基本設定',
1188
+ html: (gvc: GVC) => {
1189
+ return html` ${BgWidget.editeInput({
1190
+ gvc: gvc,
1191
+ title: html`<div>自訂金流名稱 ${BgWidget.grayNote('未輸入則參照預設')}</div>`,
1192
+ default: key_d.custome_name,
1268
1193
  callback: text => {
1269
- checkTotalNumber(text, 'freeShipmnet');
1194
+ key_d.custome_name = text;
1270
1195
  },
1271
- placeHolder: '請輸入金額',
1272
- }),
1273
- ].join('');
1196
+ placeHolder: '請輸入自訂顯示名稱',
1197
+ global_language: true,
1198
+ })}
1199
+ <div style="margin-top: 8px;">
1200
+ ${(() => {
1201
+ switch (key) {
1202
+ case 'newWebPay':
1203
+ case 'ecPay':
1204
+ return this.ePayForm(gvc, key_d, key);
1205
+ case 'paypal':
1206
+ return this.paypalForm(gvc, key_d);
1207
+ case 'line_pay':
1208
+ return this.linepayForm(gvc, key_d);
1209
+ case 'jkopay':
1210
+ return this.jkopayForm(gvc, key_d);
1211
+ case 'paynow':
1212
+ return this.paynowForm(gvc, key_d);
1213
+ }
1214
+ return '';
1215
+ })()}
1216
+ </div>`;
1274
1217
  },
1275
- });
1218
+ };
1219
+
1220
+ const shipment = {
1221
+ key: 'shipment',
1222
+ title: '指定物流',
1223
+ html: (gvc: GVC) => {
1224
+ return gvc.bindView({
1225
+ bind: gvc.glitter.getUUID(),
1226
+ view: () => ShoppingFinanceSetting.setShipmentSupport(gvc, key_d),
1227
+ });
1228
+ },
1229
+ };
1230
+
1231
+ const cartSetting = {
1232
+ key: 'cartSetting',
1233
+ title: '購物車設定',
1234
+ html: (gvc: GVC) => {
1235
+ return gvc.bindView({
1236
+ bind: gvc.glitter.getUUID(),
1237
+ view: () => ShoppingFinanceSetting.setCartSetting(gvc, key_d),
1238
+ });
1239
+ },
1240
+ };
1241
+
1242
+ return this.buttonListView(gvc, key, key_d, [setting, shipment, cartSetting]);
1276
1243
  }
1277
1244
 
1278
1245
  // 彈窗: 貨到付款 (線下)
1279
- static cashOnDelivery(gvc: GVC, keyData: any) {
1246
+ static cashOnDelivery(gvc: GVC, key: string, keyData: any) {
1280
1247
  keyData.cash_on_delivery = keyData.cash_on_delivery ?? { shipmentSupport: [] };
1281
1248
 
1282
1249
  const shipment = {
1283
1250
  key: 'shipment',
1284
1251
  title: '指定物流',
1285
- html: gvc.bindView({
1286
- bind: gvc.glitter.getUUID(),
1287
- view: () => ShoppingFinanceSetting.setShipmentSupport(gvc, keyData.cash_on_delivery),
1288
- }),
1252
+ html: (gvc: GVC) => {
1253
+ return gvc.bindView({
1254
+ bind: gvc.glitter.getUUID(),
1255
+ view: () => ShoppingFinanceSetting.setShipmentSupport(gvc, keyData.cash_on_delivery),
1256
+ });
1257
+ },
1289
1258
  };
1290
1259
 
1291
1260
  const cartSetting = {
1292
1261
  key: 'cartSetting',
1293
1262
  title: '購物車設定',
1294
- html: gvc.bindView({
1295
- bind: gvc.glitter.getUUID(),
1296
- view: () => ShoppingFinanceSetting.setCartSetting(gvc, keyData.cash_on_delivery),
1297
- }),
1263
+ html: (gvc: GVC) => {
1264
+ return gvc.bindView({
1265
+ bind: gvc.glitter.getUUID(),
1266
+ view: () => ShoppingFinanceSetting.setCartSetting(gvc, keyData.cash_on_delivery),
1267
+ });
1268
+ },
1298
1269
  };
1299
1270
 
1300
- return this.tabView(gvc, [shipment, cartSetting]);
1271
+ return this.buttonListView(gvc, 'cash_on_delivery', keyData.cash_on_delivery, [shipment, cartSetting]);
1301
1272
  }
1302
1273
 
1303
1274
  // 彈窗: Line Pay 一卡通 (線下)
1304
- static lineIPassMoney(gvc: GVC, keyData: any) {
1275
+ static lineIPassMoney(gvc: GVC, key: string, keyData: any) {
1305
1276
  keyData.payment_info_line_pay = keyData.payment_info_line_pay ?? { text: '' };
1306
1277
 
1307
1278
  const cashflow = {
1308
1279
  key: 'cashflow',
1309
1280
  title: '基本設定',
1310
- html: (() => {
1311
- const id = gvc.glitter.getUUID();
1312
- const defText = html`<p>
1313
- 您選擇了線下Line
1314
- Pay付款。請完成付款後,提供證明截圖(圖一),或是照著(圖二)的流程擷取『付款詳細資訊』並上傳,以便我們核款。&nbsp;
1315
- </p>
1316
- <p>
1317
- <br /><img
1318
- src="https://d3jnmi1tfjgtti.cloudfront.net/file/234285319/1722924978722-Frame%205078.png"
1319
- class="fr-fic fr-dii"
1320
- style="width: 215px;"
1321
- />&nbsp;<img
1322
- src="https://d3jnmi1tfjgtti.cloudfront.net/file/234285319/1722924973580-Frame%205058.png"
1323
- class="fr-fic fr-dii"
1324
- style="width: 545px;"
1325
- />
1326
- </p>
1327
- <p>
1328
- <br />
1329
- </p>`;
1281
+ html: (gvc: GVC) => {
1282
+ return (() => {
1283
+ const id = gvc.glitter.getUUID();
1284
+ const defText = html`<p>
1285
+ 您選擇了線下Line
1286
+ Pay付款。請完成付款後,提供證明截圖(圖一),或是照著(圖二)的流程擷取『付款詳細資訊』並上傳,以便我們核款。&nbsp;
1287
+ </p>
1288
+ <p>
1289
+ <br /><img
1290
+ src="https://d3jnmi1tfjgtti.cloudfront.net/file/234285319/1722924978722-Frame%205078.png"
1291
+ class="fr-fic fr-dii"
1292
+ style="width: 215px;"
1293
+ />&nbsp;<img
1294
+ src="https://d3jnmi1tfjgtti.cloudfront.net/file/234285319/1722924973580-Frame%205058.png"
1295
+ class="fr-fic fr-dii"
1296
+ style="width: 545px;"
1297
+ />
1298
+ </p>
1299
+ <p>
1300
+ <br />
1301
+ </p>`;
1330
1302
 
1331
- return gvc.bindView({
1332
- bind: id,
1333
- view: () => {
1334
- return [
1335
- html` <div class="d-flex justify-content-between mb-3">
1336
- <div class="tx_normal">付款說明</div>
1337
- ${BgWidget.blueNote(
1338
- '返回預設',
1339
- gvc.event(() => {
1340
- keyData.payment_info_line_pay.text = defText;
1341
- gvc.notifyDataChange(id);
1342
- })
1343
- )}
1344
- </div>`,
1345
- BgWidget.richTextEditor({
1346
- gvc: gvc,
1347
- content: keyData.payment_info_line_pay!.text ?? '',
1348
- callback: content => {
1349
- keyData.payment_info_line_pay!.text = content;
1350
- },
1351
- title: '付款說明',
1352
- }),
1353
- ].join('');
1354
- },
1355
- });
1356
- })(),
1303
+ return gvc.bindView({
1304
+ bind: id,
1305
+ view: () => {
1306
+ return [
1307
+ html` <div class="d-flex justify-content-between mb-3">
1308
+ <div class="tx_normal">付款說明</div>
1309
+ ${BgWidget.blueNote(
1310
+ '返回預設',
1311
+ gvc.event(() => {
1312
+ keyData.payment_info_line_pay.text = defText;
1313
+ gvc.notifyDataChange(id);
1314
+ })
1315
+ )}
1316
+ </div>`,
1317
+ BgWidget.richTextEditor({
1318
+ gvc: gvc,
1319
+ content: keyData.payment_info_line_pay!.text ?? '',
1320
+ callback: content => {
1321
+ keyData.payment_info_line_pay!.text = content;
1322
+ },
1323
+ title: '付款說明',
1324
+ }),
1325
+ ].join('');
1326
+ },
1327
+ });
1328
+ })();
1329
+ },
1357
1330
  };
1358
1331
 
1359
1332
  const shipment = {
1360
1333
  key: 'shipment',
1361
1334
  title: '指定物流',
1362
- html: gvc.bindView({
1363
- bind: gvc.glitter.getUUID(),
1364
- view: () => ShoppingFinanceSetting.setShipmentSupport(gvc, keyData.payment_info_line_pay),
1365
- }),
1335
+ html: (gvc: GVC) => {
1336
+ return gvc.bindView({
1337
+ bind: gvc.glitter.getUUID(),
1338
+ view: () => ShoppingFinanceSetting.setShipmentSupport(gvc, keyData.payment_info_line_pay),
1339
+ });
1340
+ },
1366
1341
  };
1367
1342
 
1368
1343
  const cartSetting = {
1369
1344
  key: 'cartSetting',
1370
1345
  title: '購物車設定',
1371
- html: gvc.bindView({
1372
- bind: gvc.glitter.getUUID(),
1373
- view: () => ShoppingFinanceSetting.setCartSetting(gvc, keyData.payment_info_line_pay),
1374
- }),
1346
+ html: (gvc: GVC) => {
1347
+ return gvc.bindView({
1348
+ bind: gvc.glitter.getUUID(),
1349
+ view: () => ShoppingFinanceSetting.setCartSetting(gvc, keyData.payment_info_line_pay),
1350
+ });
1351
+ },
1375
1352
  };
1376
1353
 
1377
- return this.tabView(gvc, [cashflow, shipment, cartSetting]);
1354
+ return this.buttonListView(gvc, 'payment_info_line_pay', keyData.payment_info_line_pay, [
1355
+ cashflow,
1356
+ shipment,
1357
+ cartSetting,
1358
+ ]);
1378
1359
  }
1379
1360
 
1380
1361
  // 彈窗: ATM 轉帳 (線下)
1381
- static atm(gvc: GVC, keyData: any) {
1362
+ static atm(gvc: GVC, key: string, keyData: any) {
1382
1363
  keyData.payment_info_atm = keyData.payment_info_atm ?? {
1383
1364
  bank_account: '',
1384
1365
  bank_code: '',
@@ -1389,208 +1370,226 @@ export class ShoppingFinanceSetting {
1389
1370
  const cashflow = {
1390
1371
  key: 'cashflow',
1391
1372
  title: '基本設定',
1392
- html: (() => {
1393
- const id = gvc.glitter.getUUID();
1394
- const defText = html`<p>當日下單匯款,隔日出貨,後天到貨。</p>
1395
- <p>若有需要統一編號 請提早告知</p>
1396
- <p>------------------------------------------------------------------</p>
1397
- <p>*採臨櫃匯款者,電匯單上匯款人姓名與聯絡電話請務必填寫。</p> `;
1373
+ html: (gvc: GVC) => {
1374
+ return (() => {
1375
+ const id = gvc.glitter.getUUID();
1376
+ const defText = html`<p>當日下單匯款,隔日出貨,後天到貨。</p>
1377
+ <p>若有需要統一編號 請提早告知</p>
1378
+ <p>------------------------------------------------------------------</p>
1379
+ <p>*採臨櫃匯款者,電匯單上匯款人姓名與聯絡電話請務必填寫。</p> `;
1398
1380
 
1399
- return gvc.bindView({
1400
- bind: id,
1401
- view: () => {
1402
- return [
1403
- html` <div class="row w-100">
1404
- ${[
1405
- {
1406
- key: 'bank_code',
1407
- title: '銀行代號',
1408
- },
1409
- {
1410
- key: 'bank_name',
1411
- title: '銀行名稱',
1412
- },
1413
- {
1414
- key: 'bank_user',
1415
- title: '銀行戶名',
1416
- },
1417
- {
1418
- key: 'bank_account',
1419
- title: '銀行帳號',
1420
- },
1421
- ]
1422
- .map(dd => {
1423
- return html` <div class="col-12 col-md-6 mb-2 pe-0 pe-md-2">
1424
- <div class="w-100 mb-1">
1425
- <span
1426
- style="color: #393939; font-size: 16px; font-family: Noto Sans; font-weight: 400; word-wrap: break-word"
1427
- >${dd.title}</span
1428
- >
1429
- <span
1430
- style="color: #E80000; font-size: 16px; font-family: Noto Sans; font-weight: 400; word-wrap: break-word"
1431
- >*</span
1432
- >
1433
- </div>
1434
- <input
1435
- class="form-control w-100"
1436
- placeholder="請輸入${dd.title}"
1437
- value="${keyData.payment_info_atm[dd.key]}"
1438
- onchange="${gvc.event(e => {
1439
- keyData.payment_info_atm[dd.key] = e.value;
1440
- })}"
1441
- />
1442
- </div>`;
1443
- })
1444
- .join('')}
1445
- </div>`,
1446
- html` <div class="my-2 px-1" style="display:flex;justify-content: space-between;">
1447
- <div class="tx_normal">付款說明</div>
1448
- ${BgWidget.blueNote(
1449
- '返回預設',
1450
- gvc.event(() => {
1451
- keyData.payment_info_atm.text = defText;
1381
+ return gvc.bindView({
1382
+ bind: id,
1383
+ view: () => {
1384
+ return [
1385
+ html` <div class="row w-100">
1386
+ ${[
1387
+ {
1388
+ key: 'bank_code',
1389
+ title: '銀行代號',
1390
+ },
1391
+ {
1392
+ key: 'bank_name',
1393
+ title: '銀行名稱',
1394
+ },
1395
+ {
1396
+ key: 'bank_user',
1397
+ title: '銀行戶名',
1398
+ },
1399
+ {
1400
+ key: 'bank_account',
1401
+ title: '銀行帳號',
1402
+ },
1403
+ ]
1404
+ .map(dd => {
1405
+ return html` <div class="col-12 col-md-6 mb-2 pe-0 pe-md-2">
1406
+ <div class="w-100 mb-1">
1407
+ <span
1408
+ style="color: #393939; font-size: 16px; font-family: Noto Sans; font-weight: 400; word-wrap: break-word"
1409
+ >${dd.title}</span
1410
+ >
1411
+ <span
1412
+ style="color: #E80000; font-size: 16px; font-family: Noto Sans; font-weight: 400; word-wrap: break-word"
1413
+ >*</span
1414
+ >
1415
+ </div>
1416
+ <input
1417
+ class="form-control w-100"
1418
+ placeholder="請輸入${dd.title}"
1419
+ value="${keyData.payment_info_atm[dd.key]}"
1420
+ onchange="${gvc.event(e => {
1421
+ keyData.payment_info_atm[dd.key] = e.value;
1422
+ })}"
1423
+ />
1424
+ </div>`;
1425
+ })
1426
+ .join('')}
1427
+ </div>`,
1428
+ html` <div class="my-2 px-1" style="display:flex;justify-content: space-between;">
1429
+ <div class="tx_normal">付款說明</div>
1430
+ ${BgWidget.blueNote(
1431
+ '返回預設',
1432
+ gvc.event(() => {
1433
+ keyData.payment_info_atm.text = defText;
1434
+ gvc.notifyDataChange(id);
1435
+ })
1436
+ )}
1437
+ </div>`,
1438
+ BgWidget.richTextEditor({
1439
+ gvc: gvc,
1440
+ content: keyData.payment_info_atm?.text ?? '',
1441
+ callback: content => {
1442
+ keyData.payment_info_atm!.text = content;
1452
1443
  gvc.notifyDataChange(id);
1453
- })
1454
- )}
1455
- </div>`,
1456
- BgWidget.richTextEditor({
1457
- gvc: gvc,
1458
- content: keyData.payment_info_atm?.text ?? '',
1459
- callback: content => {
1460
- keyData.payment_info_atm!.text = content;
1461
- gvc.notifyDataChange(id);
1462
- },
1463
- title: '付款說明',
1464
- }),
1465
- ].join('');
1466
- },
1467
- divCreate: { class: 'guide2-5' },
1468
- });
1469
- })(),
1444
+ },
1445
+ title: '付款說明',
1446
+ }),
1447
+ ].join('');
1448
+ },
1449
+ divCreate: { class: 'guide2-5' },
1450
+ });
1451
+ })();
1452
+ },
1470
1453
  };
1471
1454
 
1472
1455
  const shipment = {
1473
1456
  key: 'shipment',
1474
1457
  title: '指定物流',
1475
- html: gvc.bindView({
1476
- bind: gvc.glitter.getUUID(),
1477
- view: () => ShoppingFinanceSetting.setShipmentSupport(gvc, keyData.payment_info_atm),
1478
- }),
1458
+ html: (gvc: GVC) => {
1459
+ return gvc.bindView({
1460
+ bind: gvc.glitter.getUUID(),
1461
+ view: () => ShoppingFinanceSetting.setShipmentSupport(gvc, keyData.payment_info_atm),
1462
+ });
1463
+ },
1479
1464
  };
1480
1465
 
1481
1466
  const cartSetting = {
1482
1467
  key: 'cartSetting',
1483
1468
  title: '購物車設定',
1484
- html: gvc.bindView({
1485
- bind: gvc.glitter.getUUID(),
1486
- view: () => ShoppingFinanceSetting.setCartSetting(gvc, keyData.payment_info_atm),
1487
- }),
1469
+ html: (gvc: GVC) => {
1470
+ return gvc.bindView({
1471
+ bind: gvc.glitter.getUUID(),
1472
+ view: () => ShoppingFinanceSetting.setCartSetting(gvc, keyData.payment_info_atm),
1473
+ });
1474
+ },
1488
1475
  };
1489
1476
 
1490
- return this.tabView(gvc, [cashflow, shipment, cartSetting]);
1477
+ return this.buttonListView(gvc, 'payment_info_atm', keyData.payment_info_atm, [cashflow, shipment, cartSetting]);
1491
1478
  }
1492
1479
 
1493
1480
  // 彈窗: Line Pay (POS)
1494
- static linePayScan(gvc: GVC, data: any) {
1481
+ static linePayScan(gvc: GVC, key: string, data: any) {
1495
1482
  const cashflow = {
1496
1483
  key: 'cashflow',
1497
1484
  title: '基本設定',
1498
- html: html` ${[
1499
- BgWidget.inlineCheckBox({
1500
- title: '串接路徑',
1501
- gvc: gvc,
1502
- def: `${data.BETA}`,
1503
- array: [
1504
- {
1505
- title: '正式站',
1506
- value: `false`,
1485
+ html: (gvc: GVC) => {
1486
+ return [
1487
+ BgWidget.inlineCheckBox({
1488
+ title: '串接路徑',
1489
+ gvc: gvc,
1490
+ def: `${data.BETA}`,
1491
+ array: [
1492
+ {
1493
+ title: '正式站',
1494
+ value: `false`,
1495
+ },
1496
+ {
1497
+ title: '測試站',
1498
+ value: `true`,
1499
+ },
1500
+ ],
1501
+ callback: (text: any) => {
1502
+ data.BETA = text;
1503
+ },
1504
+ }),
1505
+ BgWidget.editeInput({
1506
+ gvc: gvc,
1507
+ title: 'CLIENT_ID',
1508
+ default: data.CLIENT_ID,
1509
+ callback: text => {
1510
+ data.CLIENT_ID = text;
1507
1511
  },
1508
- {
1509
- title: '測試站',
1510
- value: `true`,
1512
+ placeHolder: '請輸入CLIENT_ID',
1513
+ }),
1514
+ BgWidget.editeInput({
1515
+ gvc: gvc,
1516
+ title: 'SECRET',
1517
+ default: data.SECRET,
1518
+ callback: text => {
1519
+ data.SECRET = text;
1511
1520
  },
1512
- ],
1513
- callback: (text: any) => {
1514
- data.BETA = text;
1515
- },
1516
- }),
1517
- BgWidget.editeInput({
1518
- gvc: gvc,
1519
- title: 'CLIENT_ID',
1520
- default: data.CLIENT_ID,
1521
- callback: text => {
1522
- data.CLIENT_ID = text;
1523
- },
1524
- placeHolder: '請輸入CLIENT_ID',
1525
- }),
1526
- BgWidget.editeInput({
1527
- gvc: gvc,
1528
- title: 'SECRET',
1529
- default: data.SECRET,
1530
- callback: text => {
1531
- data.SECRET = text;
1532
- },
1533
- placeHolder: '請輸入SECRET',
1534
- }),
1535
- ].join('')}`,
1521
+ placeHolder: '請輸入SECRET',
1522
+ }),
1523
+ ].join('');
1524
+ },
1536
1525
  };
1537
1526
 
1538
1527
  const shipment = {
1539
1528
  key: 'shipment',
1540
1529
  title: '指定物流',
1541
- html: gvc.bindView({
1542
- bind: gvc.glitter.getUUID(),
1543
- view: () => ShoppingFinanceSetting.setShipmentSupport(gvc, data),
1544
- }),
1530
+ html: (gvc: GVC) => {
1531
+ return gvc.bindView({
1532
+ bind: gvc.glitter.getUUID(),
1533
+ view: () => ShoppingFinanceSetting.setShipmentSupport(gvc, data),
1534
+ });
1535
+ },
1545
1536
  };
1546
1537
 
1547
1538
  const cartSetting = {
1548
1539
  key: 'cartSetting',
1549
1540
  title: '購物車設定',
1550
- html: gvc.bindView({
1551
- bind: gvc.glitter.getUUID(),
1552
- view: () => ShoppingFinanceSetting.setCartSetting(gvc, data),
1553
- }),
1541
+ html: (gvc: GVC) => {
1542
+ return gvc.bindView({
1543
+ bind: gvc.glitter.getUUID(),
1544
+ view: () => ShoppingFinanceSetting.setCartSetting(gvc, data),
1545
+ });
1546
+ },
1554
1547
  };
1555
1548
 
1556
- return this.tabView(gvc, [cashflow, shipment, cartSetting]);
1549
+ return this.buttonListView(gvc, key, data, [cashflow, shipment, cartSetting]);
1557
1550
  }
1558
1551
 
1559
1552
  // 彈窗: 聯合信用卡 (POS)
1560
- static utCreditCard(gvc: GVC, data: any) {
1553
+ static utCreditCard(gvc: GVC, key: string, data: any) {
1561
1554
  const cashflow = {
1562
1555
  key: 'cashflow',
1563
1556
  title: '基本設定',
1564
- html: BgWidget.editeInput({
1565
- gvc: gvc,
1566
- title: '商家ID',
1567
- default: data.pwd,
1568
- callback: text => {
1569
- data.pwd = text;
1570
- },
1571
- placeHolder: '請輸入商家ID',
1572
- }),
1557
+ html: (gvc: GVC) => {
1558
+ return BgWidget.editeInput({
1559
+ gvc: gvc,
1560
+ title: '商家ID',
1561
+ default: data.pwd,
1562
+ callback: text => {
1563
+ data.pwd = text;
1564
+ },
1565
+ placeHolder: '請輸入商家ID',
1566
+ });
1567
+ },
1573
1568
  };
1574
1569
 
1575
1570
  const shipment = {
1576
1571
  key: 'shipment',
1577
1572
  title: '指定物流',
1578
- html: gvc.bindView({
1579
- bind: gvc.glitter.getUUID(),
1580
- view: () => ShoppingFinanceSetting.setShipmentSupport(gvc, data),
1581
- }),
1573
+ html: (gvc: GVC) => {
1574
+ return gvc.bindView({
1575
+ bind: gvc.glitter.getUUID(),
1576
+ view: () => ShoppingFinanceSetting.setShipmentSupport(gvc, data),
1577
+ });
1578
+ },
1582
1579
  };
1583
1580
 
1584
1581
  const cartSetting = {
1585
1582
  key: 'cartSetting',
1586
1583
  title: '購物車設定',
1587
- html: gvc.bindView({
1588
- bind: gvc.glitter.getUUID(),
1589
- view: () => ShoppingFinanceSetting.setCartSetting(gvc, data),
1590
- }),
1584
+ html: (gvc: GVC) => {
1585
+ return gvc.bindView({
1586
+ bind: gvc.glitter.getUUID(),
1587
+ view: () => ShoppingFinanceSetting.setCartSetting(gvc, data),
1588
+ });
1589
+ },
1591
1590
  };
1592
1591
 
1593
- return this.tabView(gvc, [cashflow, shipment, cartSetting]);
1592
+ return this.buttonListView(gvc, key, data, [cashflow, shipment, cartSetting]);
1594
1593
  }
1595
1594
 
1596
1595
  // 彈窗: MyPay高鉅科技 (POS)
@@ -1598,38 +1597,45 @@ export class ShoppingFinanceSetting {
1598
1597
  const cashflow = {
1599
1598
  key: 'cashflow',
1600
1599
  title: '基本設定',
1601
- html: BgWidget.editeInput({
1602
- gvc: gvc,
1603
- title: '刷卡機密碼',
1604
- default: data.pwd,
1605
- callback: text => {
1606
- data.pwd = text;
1607
- },
1608
- placeHolder: '請輸入刷卡機密碼',
1609
- }),
1600
+ html: (gvc: GVC) => {
1601
+ return BgWidget.editeInput({
1602
+ gvc: gvc,
1603
+ title: '刷卡機密碼',
1604
+ default: data.pwd,
1605
+ callback: text => {
1606
+ data.pwd = text;
1607
+ },
1608
+ placeHolder: '請輸入刷卡機密碼',
1609
+ });
1610
+ },
1610
1611
  };
1611
1612
 
1612
1613
  const shipment = {
1613
1614
  key: 'shipment',
1614
1615
  title: '指定物流',
1615
- html: gvc.bindView({
1616
- bind: gvc.glitter.getUUID(),
1617
- view: () => ShoppingFinanceSetting.setShipmentSupport(gvc, data),
1618
- }),
1616
+ html: (gvc: GVC) => {
1617
+ return gvc.bindView({
1618
+ bind: gvc.glitter.getUUID(),
1619
+ view: () => ShoppingFinanceSetting.setShipmentSupport(gvc, data),
1620
+ });
1621
+ },
1619
1622
  };
1620
1623
 
1621
1624
  const cartSetting = {
1622
1625
  key: 'cartSetting',
1623
1626
  title: '購物車設定',
1624
- html: gvc.bindView({
1625
- bind: gvc.glitter.getUUID(),
1626
- view: () => ShoppingFinanceSetting.setCartSetting(gvc, data),
1627
- }),
1627
+ html: (gvc: GVC) => {
1628
+ return gvc.bindView({
1629
+ bind: gvc.glitter.getUUID(),
1630
+ view: () => ShoppingFinanceSetting.setCartSetting(gvc, data),
1631
+ });
1632
+ },
1628
1633
  };
1629
1634
 
1630
- return this.tabView(gvc, [cashflow, shipment, cartSetting]);
1635
+ return this.buttonListView(gvc, 'my_pay', data, [cashflow, shipment, cartSetting]);
1631
1636
  }
1632
1637
 
1638
+ // 付款說明元件
1633
1639
  static customerText(gvc: GVC, keyData: any, id: string) {
1634
1640
  const fi_ = keyData.payment_info_custom.find((id_: string) => id_ === id);
1635
1641
  keyData[keyData.findIndex(fi_)] = {
@@ -1659,22 +1665,89 @@ export class ShoppingFinanceSetting {
1659
1665
  });
1660
1666
  }
1661
1667
 
1668
+ // 金物流元件卡
1669
+ static card(obj: {
1670
+ title: string;
1671
+ img: string;
1672
+ toggle: boolean;
1673
+ toggleEvent: string;
1674
+ buttonAction: string[];
1675
+ deleteEvent?: string;
1676
+ }) {
1677
+ return html`<div class="col-12 col-lg-4 col-md-6 p-0 p-md-2">
1678
+ <div
1679
+ class="w-100 position-relative main-card"
1680
+ style="padding: 20px 12px; background: white; overflow: hidden; flex-direction: column; justify-content: flex-start; align-items: flex-start; gap: 18px; display: inline-flex;"
1681
+ >
1682
+ <div
1683
+ style="padding: 9px 12px;align-self: stretch; justify-content: flex-start; align-items: center; gap: 28px; display: inline-flex;"
1684
+ >
1685
+ ${obj.deleteEvent
1686
+ ? html`<div style="position: absolute; top: 10px; right: 20px; font-size: 18px; cursor: pointer;">
1687
+ <i class="fa-regular fa-trash" onclick="${obj.deleteEvent}"></i>
1688
+ </div>`
1689
+ : ''}
1690
+ <div style="min-width: 46px;max-width: 46px; text-align: center;">${obj.img}</div>
1691
+ <div
1692
+ style="flex-direction: column; justify-content: center; align-items: flex-start; gap: 4px; display: inline-flex"
1693
+ >
1694
+ <div class="tx_normal">${obj.title}</div>
1695
+ <div class="d-flex align-items-center" style="gap: 4px;">
1696
+ <div class="tx_normal">${obj.toggle ? '開啟' : '關閉'}</div>
1697
+ <div class="cursor_pointer form-check form-switch" style="margin-top: 10px;">
1698
+ <input
1699
+ class="form-check-input"
1700
+ type="checkbox"
1701
+ onchange="${obj.toggleEvent}"
1702
+ ${obj.toggle ? 'checked' : ''}
1703
+ />
1704
+ </div>
1705
+ </div>
1706
+ </div>
1707
+ </div>
1708
+ <div class="w-100 border-top pt-3 mt-n2">
1709
+ <div class="d-flex flex-wrap justify-content-end gap-1 cursor_pointer">
1710
+ <div class="flex-fill"></div>
1711
+ ${obj.buttonAction.join('')}
1712
+ </div>
1713
+ </div>
1714
+ </div>
1715
+ </div>
1716
+ ${document.body.clientWidth > 768 ? '' : BgWidget.mbContainer(8)}`;
1717
+ }
1718
+
1719
+ // 新增客製元件卡
1720
+ static addCard(title: string, event: string) {
1721
+ return html`<div class="col-12 col-lg-4 col-md-6 p-0 p-md-2" style="cursor: pointer;" onclick="${event}">
1722
+ <div
1723
+ class="w-100 main-card"
1724
+ style="min-height:183.59px;padding: 24px; background: white; overflow: hidden; flex-direction: column; justify-content: center; align-items: center; gap: 18px; display: inline-flex"
1725
+ >
1726
+ <div
1727
+ class="fw-bold"
1728
+ style="align-self: stretch; justify-content: center; align-items: center; gap: 14px; display: inline-flex;color:#4D86DB;"
1729
+ >
1730
+ <i class="fa-regular fa-circle-plus fs-5"></i>
1731
+ <div class="fs-5">${title}</div>
1732
+ </div>
1733
+ </div>
1734
+ </div>`;
1735
+ }
1736
+
1737
+ // *物流設定頁
1662
1738
  static logistics_setting(gvc: GVC, widget: any) {
1739
+ this.id = 'shopping-logistics-setting-main';
1740
+ this.loading = true;
1741
+ this.gvc = gvc;
1742
+
1663
1743
  const dialog = new ShareDialog(gvc.glitter);
1664
- const saasConfig: {
1665
- config: any;
1666
- api: any;
1667
- } = (window.parent as any).saasConfig;
1744
+ const saasConfig = this.saasConfig;
1668
1745
  const vm: {
1669
- id: string;
1670
- loading: boolean;
1671
1746
  data: any;
1672
1747
  delivery: any;
1673
1748
  language: any;
1674
1749
  page: 'delivery_setting' | 'delivery_track' | 'delivery_note';
1675
1750
  } = {
1676
- id: gvc.glitter.getUUID(),
1677
- loading: true,
1678
1751
  data: {},
1679
1752
  delivery: {
1680
1753
  ec_pay: {
@@ -1697,38 +1770,24 @@ export class ShoppingFinanceSetting {
1697
1770
  language: (window.parent as any).store_info.language_setting.def,
1698
1771
  page: 'delivery_setting',
1699
1772
  };
1700
- saasConfig.api
1701
- .getPrivateConfig(saasConfig.config.appName, 'logistics_setting')
1702
- .then((r: { response: any; result: boolean }) => {
1703
- if (r.response.result[0]) {
1704
- vm.data = r.response.result[0].value;
1705
- }
1706
- vm.loading = false;
1707
- if (!vm.data.language_data) {
1708
- vm.data.language_data = {
1709
- 'en-US': { info: '' },
1710
- 'zh-CN': { info: '' },
1711
- 'zh-TW': { info: vm.data.info || '' },
1712
- };
1713
- }
1714
- gvc.notifyDataChange(vm.id);
1715
- });
1716
1773
 
1717
- function save() {
1774
+ const save = () => {
1718
1775
  saasConfig.api.setPrivateConfig(saasConfig.config.appName, 'logistics_setting', vm.data);
1719
- }
1776
+ };
1720
1777
 
1721
1778
  return gvc.bindView(() => {
1722
1779
  return {
1723
- bind: vm.id,
1780
+ bind: this.id,
1724
1781
  view: () => {
1725
- if (vm.loading) {
1782
+ if (this.loading) {
1726
1783
  return BgWidget.spinner();
1727
1784
  }
1728
- vm.data.support = vm.data.support || [];
1785
+
1729
1786
  const language_data = vm.data.language_data[vm.language];
1787
+ vm.data.support = vm.data.support || [];
1730
1788
  vm.data.info = vm.data.info || '';
1731
1789
  vm.data.form = vm.data.form || [];
1790
+
1732
1791
  let view = [
1733
1792
  html`<div class="title-container">
1734
1793
  ${BgWidget.title('物流設定')}
@@ -1745,11 +1804,12 @@ export class ShoppingFinanceSetting {
1745
1804
  vm.page,
1746
1805
  text => {
1747
1806
  vm.page = text as any;
1748
- gvc.notifyDataChange(vm.id);
1807
+ gvc.notifyDataChange(this.id);
1749
1808
  },
1750
1809
  'margin-bottom:0px;'
1751
1810
  ),
1752
1811
  ];
1812
+
1753
1813
  if (vm.page === 'delivery_setting') {
1754
1814
  view = view.concat([
1755
1815
  html`<div class="px-md-0 px-2">
@@ -1757,14 +1817,10 @@ export class ShoppingFinanceSetting {
1757
1817
  '設定支援的配送方式,供消費者於前臺自行選擇合適的物流,另外可於商品頁面設定特定商品支援的配送'
1758
1818
  )}
1759
1819
  </div>`,
1760
- gvc.bindView(() => {
1761
- const id = gvc.glitter.getUUID();
1762
-
1763
- function refresh() {
1764
- gvc.notifyDataChange(id);
1765
- }
1820
+ gvc.bindView(() => {
1821
+ const id = gvc.glitter.getUUID();
1766
1822
 
1767
- //設定自訂物流
1823
+ // 設定自訂物流
1768
1824
  function updateCustomShipment(obj: {
1769
1825
  function: 'replace' | 'plus';
1770
1826
  data?: {
@@ -1786,7 +1842,7 @@ export class ShoppingFinanceSetting {
1786
1842
  let form: any = undefined;
1787
1843
  BgWidget.settingDialog({
1788
1844
  gvc: gvc,
1789
- title: custom_delivery.name ? `「${custom_delivery.name}」自訂表單設定` : '新增自訂物流',
1845
+ title: custom_delivery.name ? `「${custom_delivery.name}」表單設定` : '新增自訂物流',
1790
1846
  innerHTML: gvc => {
1791
1847
  form = BgWidget.customForm(gvc, [
1792
1848
  {
@@ -1850,68 +1906,38 @@ export class ShoppingFinanceSetting {
1850
1906
  );
1851
1907
  },
1852
1908
  footer_html: gvc => {
1853
- let array = [
1854
- BgWidget.save(
1855
- gvc.event(() => {
1856
- return new Promise<boolean>(async () => {
1857
- if (!custom_delivery.name) {
1858
- dialog.errorMessage({ text: `請輸入物流名稱` });
1859
- return;
1860
- }
1861
- vm.data.custom_delivery = vm.data.custom_delivery ?? [];
1862
- if (obj.function === 'plus') {
1863
- vm.data.custom_delivery.push(custom_delivery);
1864
- } else {
1865
- vm.data.custom_delivery[
1866
- vm.data.custom_delivery.findIndex((d1: any) => {
1867
- return d1.id === custom_delivery.id;
1868
- })
1869
- ] = custom_delivery;
1870
- }
1871
-
1872
- dialog.dataLoading({ visible: true });
1873
- await form.save();
1874
- await saasConfig.api.setPrivateConfig(
1875
- saasConfig.config.appName,
1876
- 'logistics_setting',
1877
- vm.data
1878
- );
1879
- dialog.dataLoading({ visible: false });
1880
- dialog.successMessage({ text: '設定成功' });
1881
- gvc.closeDialog();
1882
- refresh();
1883
- });
1884
- })
1885
- ),
1886
- ];
1887
- if (obj.function === 'replace') {
1888
- array = [
1889
- BgWidget.danger(
1890
- gvc.event(() => {
1891
- dialog.checkYesOrNot({
1892
- text: '是否確認刪除?',
1893
- callback: async response => {
1894
- if (response) {
1895
- vm.data.custom_delivery = vm.data.custom_delivery.filter((d1: any) => {
1896
- return obj.data!.id !== d1.id;
1897
- });
1898
- dialog.dataLoading({ visible: true });
1899
- await saasConfig.api.setPrivateConfig(
1900
- saasConfig.config.appName,
1901
- 'logistics_setting',
1902
- vm.data
1903
- );
1904
- dialog.dataLoading({ visible: false });
1905
- refresh();
1906
- gvc.closeDialog();
1907
- }
1908
- },
1909
- });
1910
- })
1911
- ),
1912
- ].concat(array);
1913
- }
1914
- return array.join('');
1909
+ return BgWidget.save(
1910
+ gvc.event(() => {
1911
+ return new Promise<boolean>(async () => {
1912
+ if (!custom_delivery.name) {
1913
+ dialog.errorMessage({ text: `請輸入物流名稱` });
1914
+ return;
1915
+ }
1916
+
1917
+ vm.data.custom_delivery = vm.data.custom_delivery ?? [];
1918
+ if (obj.function === 'plus') {
1919
+ vm.data.custom_delivery.push(custom_delivery);
1920
+ } else {
1921
+ vm.data.custom_delivery[
1922
+ vm.data.custom_delivery.findIndex((d1: any) => {
1923
+ return d1.id === custom_delivery.id;
1924
+ })
1925
+ ] = custom_delivery;
1926
+ }
1927
+
1928
+ dialog.dataLoading({ visible: true });
1929
+ await form.save();
1930
+ await saasConfig.api.setPrivateConfig(
1931
+ saasConfig.config.appName,
1932
+ 'logistics_setting',
1933
+ vm.data
1934
+ );
1935
+ dialog.dataLoading({ visible: false });
1936
+ dialog.successMessage({ text: '設定成功' });
1937
+ ShoppingFinanceSetting.refresh(gvc);
1938
+ });
1939
+ })
1940
+ );
1915
1941
  },
1916
1942
  });
1917
1943
  }
@@ -1932,342 +1958,291 @@ export class ShoppingFinanceSetting {
1932
1958
  })
1933
1959
  )
1934
1960
  .map(dd => {
1935
- return html`
1936
- <div class="col-12 col-lg-4 col-md-6 p-0 p-md-2">
1937
- <div
1938
- class="w-100 position-relative main-card"
1939
- style="padding: 24px; background: white; overflow: hidden; flex-direction: column; justify-content: flex-start; align-items: flex-start; gap: 18px; display: inline-flex;"
1940
- >
1941
- <div
1942
- style="align-self: stretch; justify-content: flex-start; align-items: center; gap: 28px; display: inline-flex;"
1943
- >
1944
- <div style="min-width: 46px;max-width: 46px;">
1945
- ${dd.type === 'font_awesome' ? dd.src : html` <img src="${dd.src}" />`}
1946
- </div>
1947
- <div
1948
- style="flex-direction: column; justify-content: center; align-items: flex-start; gap: 4px; display: inline-flex"
1949
- >
1950
- <div class="tx_normal">${dd.title}</div>
1951
- <div class="d-flex align-items-center" style="gap:4px;">
1952
- <div class="tx_normal">
1953
- ${vm.data.support.find((d1: any) => dd.value === d1) ? `開啟` : `關閉`}
1954
- </div>
1955
- <div class="cursor_pointer form-check form-switch" style="margin-top: 10px;">
1956
- <input
1957
- class="form-check-input"
1958
- type="checkbox"
1959
- onchange="${gvc.event(() => {
1960
- if (
1961
- vm.data.support.find((d1: any) => {
1962
- return dd.value === d1;
1963
- })
1964
- ) {
1965
- vm.data.support = vm.data.support.filter((d1: any) => {
1966
- return dd.value !== d1;
1967
- });
1968
- } else {
1969
- vm.data.support.push(dd.value);
1970
- }
1971
- save();
1972
- gvc.notifyDataChange(id);
1973
- })}"
1974
- ${vm.data.support.find((d1: any) => {
1975
- return dd.value === d1;
1976
- })
1977
- ? `checked`
1978
- : ''}
1979
- />
1980
- </div>
1981
- </div>
1982
- </div>
1983
- </div>
1984
- <div class="w-100 border-top pt-3 mt-n2">
1985
- ${(() => {
1986
- let button_action: string[] = [
1987
- BgWidget.customButton({
1988
- button: {
1989
- color: 'gray',
1990
- size: 'sm',
1991
- },
1992
- text: {
1993
- name: html`<i class="fa-regular fa-gear me-1"></i>配送`,
1994
- },
1995
- event: gvc.event(async () => {
1996
- const log_config = (
1997
- await ApiUser.getPublicConfig(
1998
- 'shipment_config_' + dd.value,
1999
- 'manager',
2000
- saasConfig.config.appName
2001
- )
2002
- ).response.value;
2003
- BgWidget.settingDialog({
2004
- gvc: gvc,
2005
- title: `「${dd.title}」配送設定`,
2006
- innerHTML: gvc => {
2007
- const view: string[] = [];
2008
- if (
2009
- ['UNIMARTC2C', 'UNIMARTFREEZE', 'FAMIC2C', 'FAMIC2CFREEZE'].includes(
2010
- dd.value
2011
- )
2012
- ) {
2013
- view.push(
2014
- html`<div class="d-flex flex-column w-100">
2015
- ${[
2016
- html`<div
2017
- style="flex-direction: column; justify-content: center; align-items: flex-start; gap: 4px; display: inline-flex"
2018
- >
2019
- <div class="tx_normal">大宗配送</div>
2020
- <div class="d-flex align-items-center" style="gap:4px;">
2021
- <div class="tx_normal">
2022
- ${log_config.bulk ? `開啟` : `關閉`}
2023
- </div>
2024
- <div
2025
- class="cursor_pointer form-check form-switch"
2026
- style="margin-top: 10px;"
2027
- >
2028
- <input
2029
- class="form-check-input"
2030
- type="checkbox"
2031
- onchange="${gvc.event(() => {
2032
- log_config.bulk = !log_config.bulk;
2033
- gvc.recreateView();
2034
- })}"
2035
- ${log_config.bulk ? `checked` : ''}
2036
- />
2037
- </div>
2038
- </div>
2039
- </div> `,
2040
- ].join('')}
2041
- </div>`
2042
- );
2043
- }
2044
- view.push(
2045
- html` <div class="d-flex flex-column" style="gap:5px;">
2046
- ${[
2047
- html`<div class="tx_normal">物流配送說明</div>`,
2048
- BgWidget.richTextEditor({
2049
- gvc: gvc,
2050
- content: log_config.content ?? '',
2051
- callback: data => {
2052
- log_config.content = data;
2053
- },
2054
- title: '物流配送說明',
2055
- }),
2056
- ].join('')}
2057
- </div>`
2058
- );
2059
- return html`<div class="w-100 d-flex flex-column" style="gap:5px;">
2060
- ${view.join(html`<div class="w-100 border-bottom my-2"></div>`)}
2061
- </div>`;
2062
- },
2063
- footer_html: gvc => {
2064
- let array = [
2065
- BgWidget.cancel(
2066
- gvc.event(() => {
2067
- gvc.closeDialog();
2068
- })
2069
- ),
2070
- BgWidget.save(
2071
- gvc.event(() => {
2072
- dialog.dataLoading({ visible: true });
2073
- ApiUser.setPublicConfig({
2074
- user_id: 'manager',
2075
- key: 'shipment_config_' + dd.value,
2076
- value: log_config,
2077
- }).then(() => {
2078
- dialog.dataLoading({ visible: false });
2079
- dialog.successMessage({ text: '設定成功' });
2080
- gvc.closeDialog();
2081
- });
2082
- })
2083
- ),
2084
- ];
2085
- return array.join('');
2086
- },
2087
- });
2088
- }),
2089
- }),
2090
- BgWidget.customButton({
2091
- button: {
2092
- color: 'gray',
2093
- size: 'sm',
2094
- },
2095
- text: {
2096
- name: html`<i class="fa-regular fa-gear me-1"></i>購物車`,
2097
- },
2098
- event: gvc.event(async () => {
2099
- const vm = {
2100
- id: gvc.glitter.getUUID(),
2101
- loading: true,
2102
- config: {},
2103
- };
2104
-
2105
- BgWidget.settingDialog({
1961
+ let button_action: string[] = [
1962
+ BgWidget.customButton({
1963
+ button: {
1964
+ color: 'gray',
1965
+ size: 'sm',
1966
+ },
1967
+ text: {
1968
+ name: '配送設定',
1969
+ },
1970
+ event: gvc.event(async () => {
1971
+ const log_config = (
1972
+ await ApiUser.getPublicConfig(
1973
+ 'shipment_config_' + dd.value,
1974
+ 'manager',
1975
+ saasConfig.config.appName
1976
+ )
1977
+ ).response.value;
1978
+ BgWidget.settingDialog({
1979
+ gvc: gvc,
1980
+ title: `「${dd.title}」配送設定`,
1981
+ innerHTML: gvc => {
1982
+ const view: string[] = [];
1983
+ if (['UNIMARTC2C', 'UNIMARTFREEZE', 'FAMIC2C', 'FAMIC2CFREEZE'].includes(dd.value)) {
1984
+ view.push(
1985
+ html`<div class="d-flex flex-column w-100">
1986
+ ${[
1987
+ html`<div
1988
+ style="flex-direction: column; justify-content: center; align-items: flex-start; gap: 4px; display: inline-flex"
1989
+ >
1990
+ <div class="tx_normal">大宗配送</div>
1991
+ <div class="d-flex align-items-center" style="gap: 4px;">
1992
+ <div class="tx_normal">${log_config.bulk ? '開啟' : '關閉'}</div>
1993
+ <div
1994
+ class="cursor_pointer form-check form-switch"
1995
+ style="margin-top: 10px;"
1996
+ >
1997
+ <input
1998
+ class="form-check-input"
1999
+ type="checkbox"
2000
+ onchange="${gvc.event(() => {
2001
+ log_config.bulk = !log_config.bulk;
2002
+ gvc.recreateView();
2003
+ })}"
2004
+ ${log_config.bulk ? `checked` : ''}
2005
+ />
2006
+ </div>
2007
+ </div>
2008
+ </div> `,
2009
+ ].join('')}
2010
+ </div>`
2011
+ );
2012
+ }
2013
+ view.push(
2014
+ html` <div class="d-flex flex-column" style="gap: 4px;">
2015
+ ${[
2016
+ html`<div class="tx_normal">物流配送說明</div>`,
2017
+ BgWidget.richTextEditor({
2106
2018
  gvc: gvc,
2107
- title: `「${dd.title}」購物車設定`,
2108
- innerHTML: gvc => {
2109
- return gvc.bindView({
2110
- bind: id,
2111
- view: () => {
2112
- if (vm.loading) {
2113
- return BgWidget.spinner();
2114
- } else {
2115
- return ShoppingFinanceSetting.setCartSetting(
2116
- gvc,
2117
- vm.config,
2118
- 'shipment'
2119
- );
2120
- }
2121
- },
2122
- onCreate: async () => {
2123
- if (vm.loading) {
2124
- const r = await ApiUser.getPublicConfig(
2125
- 'shipment_config_' + dd.value,
2126
- 'manager',
2127
- saasConfig.config.appName
2128
- );
2129
- vm.config = r.response.value;
2130
- vm.loading = false;
2131
- gvc.notifyDataChange(id);
2132
- }
2133
- },
2134
- });
2135
- },
2136
- footer_html: gvc => {
2137
- return [
2138
- BgWidget.cancel(
2139
- gvc.event(() => {
2140
- gvc.closeDialog();
2141
- })
2142
- ),
2143
- BgWidget.save(
2144
- gvc.event(() => {
2145
- dialog.dataLoading({ visible: true });
2146
- ApiUser.setPublicConfig({
2147
- user_id: 'manager',
2148
- key: 'shipment_config_' + dd.value,
2149
- value: vm.config,
2150
- }).then(() => {
2151
- dialog.dataLoading({ visible: false });
2152
- dialog.successMessage({ text: '設定成功' });
2153
- gvc.closeDialog();
2154
- });
2155
- })
2156
- ),
2157
- ].join('');
2019
+ content: log_config.content ?? '',
2020
+ callback: data => {
2021
+ log_config.content = data;
2158
2022
  },
2023
+ title: '物流配送說明',
2024
+ }),
2025
+ ].join('')}
2026
+ </div>`
2027
+ );
2028
+ return html`<div class="w-100 d-flex flex-column" style="gap: 4px;">
2029
+ ${view.join(html`<div class="w-100 border-bottom my-2"></div>`)}
2030
+ </div>`;
2031
+ },
2032
+ footer_html: gvc => {
2033
+ let array = [
2034
+ BgWidget.cancel(
2035
+ gvc.event(() => {
2036
+ gvc.closeDialog();
2037
+ })
2038
+ ),
2039
+ BgWidget.save(
2040
+ gvc.event(() => {
2041
+ dialog.dataLoading({ visible: true });
2042
+ ApiUser.setPublicConfig({
2043
+ user_id: 'manager',
2044
+ key: 'shipment_config_' + dd.value,
2045
+ value: log_config,
2046
+ }).then(() => {
2047
+ dialog.dataLoading({ visible: false });
2048
+ dialog.successMessage({ text: '設定成功' });
2049
+ gvc.closeDialog();
2159
2050
  });
2160
- }),
2161
- }),
2051
+ })
2052
+ ),
2162
2053
  ];
2054
+ return array.join('');
2055
+ },
2056
+ });
2057
+ }),
2058
+ }),
2059
+ BgWidget.customButton({
2060
+ button: {
2061
+ color: 'gray',
2062
+ size: 'sm',
2063
+ },
2064
+ text: {
2065
+ name: '購物車設定',
2066
+ },
2067
+ event: gvc.event(async () => {
2068
+ const vm = {
2069
+ id: gvc.glitter.getUUID(),
2070
+ loading: true,
2071
+ config: {},
2072
+ };
2073
+
2074
+ BgWidget.settingDialog({
2075
+ gvc: gvc,
2076
+ title: `「${dd.title}」購物車設定`,
2077
+ innerHTML: gvc => {
2078
+ return gvc.bindView({
2079
+ bind: id,
2080
+ view: () => {
2081
+ if (vm.loading) {
2082
+ return BgWidget.spinner();
2083
+ } else {
2084
+ return ShoppingFinanceSetting.setCartSetting(gvc, vm.config, 'shipment');
2085
+ }
2086
+ },
2087
+ onCreate: async () => {
2088
+ if (vm.loading) {
2089
+ const r = await ApiUser.getPublicConfig(
2090
+ 'shipment_config_' + dd.value,
2091
+ 'manager',
2092
+ saasConfig.config.appName
2093
+ );
2094
+ vm.config = r.response.value;
2095
+ vm.loading = false;
2096
+ gvc.notifyDataChange(id);
2097
+ }
2098
+ },
2099
+ });
2100
+ },
2101
+ footer_html: gvc => {
2102
+ return [
2103
+ BgWidget.cancel(
2104
+ gvc.event(() => {
2105
+ gvc.closeDialog();
2106
+ })
2107
+ ),
2108
+ BgWidget.save(
2109
+ gvc.event(() => {
2110
+ dialog.dataLoading({ visible: true });
2111
+ ApiUser.setPublicConfig({
2112
+ user_id: 'manager',
2113
+ key: 'shipment_config_' + dd.value,
2114
+ value: vm.config,
2115
+ }).then(() => {
2116
+ dialog.dataLoading({ visible: false });
2117
+ dialog.successMessage({ text: '設定成功' });
2118
+ gvc.closeDialog();
2119
+ });
2120
+ })
2121
+ ),
2122
+ ].join('');
2123
+ },
2124
+ });
2125
+ }),
2126
+ }),
2127
+ BgWidget.customButton({
2128
+ button: {
2129
+ color: 'gray',
2130
+ size: 'sm',
2131
+ },
2132
+ text: {
2133
+ name: '運費設定',
2134
+ },
2135
+ event: gvc.event(() => {
2136
+ const vm = {
2137
+ gvc: gvc,
2138
+ key: dd.value,
2139
+ save_event: () => {
2140
+ return new Promise(resolve => resolve(true));
2141
+ },
2142
+ };
2143
+ BgWidget.settingDialog({
2144
+ gvc: gvc,
2145
+ width: 1200,
2146
+ height: document.body.clientHeight - 100,
2147
+ title: `「${dd.title}」運費設定`,
2148
+ d_main_style: document.body.clientWidth < 768 ? 'padding:0px !important;' : '',
2149
+ innerHTML: (gvc: GVC) => {
2150
+ vm.gvc = gvc;
2151
+ return ShoppingShipmentSetting.main(vm);
2152
+ },
2153
+ footer_html: gvc => {
2154
+ return [
2155
+ BgWidget.cancel(
2156
+ gvc.event(() => {
2157
+ gvc.closeDialog();
2158
+ })
2159
+ ),
2160
+ BgWidget.save(
2161
+ gvc.event(() => {
2162
+ vm.save_event().then(() => {});
2163
+ })
2164
+ ),
2165
+ ].join('');
2166
+ },
2167
+ });
2168
+ }),
2169
+ }),
2170
+ ];
2171
+
2172
+ if ((dd as any).custom) {
2173
+ button_action = [
2174
+ BgWidget.customButton({
2175
+ button: {
2176
+ color: 'gray',
2177
+ size: 'sm',
2178
+ },
2179
+ text: {
2180
+ name: '表單設定',
2181
+ },
2182
+ event: gvc.event(() => {
2183
+ updateCustomShipment({
2184
+ function: 'replace',
2185
+ data: vm.data.custom_delivery.find((d1: any) => dd.value === d1.id),
2186
+ });
2187
+ }),
2188
+ }),
2189
+ ...button_action,
2190
+ ];
2191
+ }
2163
2192
 
2164
- const shipment_fee = () => {
2165
- return BgWidget.customButton({
2166
- button: {
2167
- color: 'gray',
2168
- size: 'sm',
2169
- },
2170
- text: {
2171
- name: html`<i class="fa-regular fa-gear me-1"></i>運費`,
2172
- },
2173
- event: gvc.event(() => {
2174
- const vm = {
2175
- gvc: gvc,
2176
- key: dd.value,
2177
- save_event: () => {
2178
- return new Promise(resolve => resolve(true));
2179
- },
2180
- };
2181
- BgWidget.settingDialog({
2182
- gvc: gvc,
2183
- width: 1200,
2184
- height: document.body.clientHeight - 100,
2185
- title: `「${dd.title}」運費設定`,
2186
- d_main_style:
2187
- document.body.clientWidth < 768 ? 'padding:0px !important;' : '',
2188
- innerHTML: (gvc: GVC) => {
2189
- vm.gvc = gvc;
2190
- return ShoppingShipmentSetting.main(vm);
2191
- },
2192
- footer_html: gvc => {
2193
- return [
2194
- BgWidget.cancel(
2195
- gvc.event(() => {
2196
- gvc.closeDialog();
2197
- })
2198
- ),
2199
- BgWidget.save(
2200
- gvc.event(() => {
2201
- vm.save_event().then(() => {});
2202
- })
2203
- ),
2204
- ].join('');
2205
- },
2193
+ return this.card({
2194
+ title: dd.title,
2195
+ img: dd.type === 'font_awesome' ? dd.src : html` <img src="${dd.src}" />`,
2196
+ toggle: vm.data.support.some((d1: any) => dd.value === d1),
2197
+ toggleEvent: gvc.event(() => {
2198
+ if (vm.data.support.find((d1: any) => dd.value === d1)) {
2199
+ vm.data.support = vm.data.support.filter((d1: any) => dd.value !== d1);
2200
+ } else {
2201
+ vm.data.support.push(dd.value);
2202
+ }
2203
+ save();
2204
+ gvc.notifyDataChange(id);
2205
+ }),
2206
+ buttonAction: button_action,
2207
+ deleteEvent: (dd as any).custom
2208
+ ? gvc.event(() => {
2209
+ dialog.checkYesOrNot({
2210
+ text: '是否確認刪除此物流?',
2211
+ callback: async response => {
2212
+ if (response) {
2213
+ const data = await saasConfig.api.getPrivateConfig(
2214
+ saasConfig.config.appName,
2215
+ 'logistics_setting'
2216
+ );
2217
+ if (data.response.result[0]) {
2218
+ const keyData = data.response.result[0].value;
2219
+
2220
+ keyData.custom_delivery = keyData.custom_delivery.filter((d1: any) => {
2221
+ return dd.value !== d1.id;
2206
2222
  });
2207
- }),
2208
- });
2209
- };
2210
-
2211
- if ((dd as any).custom) {
2212
- button_action = button_action.concat([
2213
- shipment_fee(),
2214
- BgWidget.customButton({
2215
- button: {
2216
- color: 'gray',
2217
- size: 'sm',
2218
- },
2219
- text: {
2220
- name: html`<i class="fa-regular fa-gear me-1"></i>自訂表單`,
2221
- },
2222
- event: gvc.event(() => {
2223
- updateCustomShipment({
2224
- function: 'replace',
2225
- data: vm.data.custom_delivery.find((d1: any) => dd.value === d1.id),
2226
- });
2227
- }),
2228
- }),
2229
- ]);
2230
- return html`
2231
- <div class="d-flex flex-wrap justify-content-end gap-1 cursor_pointer">
2232
- <div class="flex-fill"></div>
2233
- ${button_action.join('')}
2234
- </div>
2235
- `;
2236
- } else {
2237
- button_action = button_action.concat([shipment_fee()]);
2238
- return html` <div class="d-flex flex-wrap justify-content-end gap-1 cursor_pointer">
2239
- <div class="flex-fill"></div>
2240
- ${button_action.join('')}
2241
- </div>`;
2242
- }
2243
- })()}
2244
- </div>
2245
- </div>
2246
- </div>
2247
- ${document.body.clientWidth > 768 ? '' : BgWidget.mbContainer(8)}
2248
- `;
2223
+
2224
+ dialog.dataLoading({ visible: true });
2225
+ saasConfig.api.setPrivateConfig(
2226
+ saasConfig.config.appName,
2227
+ 'logistics_setting',
2228
+ keyData
2229
+ );
2230
+
2231
+ dialog.dataLoading({ visible: false });
2232
+ this.refresh();
2233
+ }
2234
+ }
2235
+ },
2236
+ });
2237
+ })
2238
+ : undefined,
2239
+ });
2249
2240
  })
2250
2241
  .concat([
2251
- html` <div
2252
- class="col-12 col-lg-4 col-md-6 p-0 p-md-2"
2253
- style="cursor: pointer;"
2254
- onclick="${gvc.event(() => {
2255
- updateCustomShipment({ function: 'plus' });
2256
- })}"
2257
- >
2258
- <div
2259
- class="w-100 main-card"
2260
- style="min-height:173.59px;padding: 24px; background: white; overflow: hidden; flex-direction: column; justify-content: center; align-items: center; gap: 18px; display: inline-flex"
2261
- >
2262
- <div
2263
- class="fw-bold"
2264
- style="align-self: stretch; justify-content: center; align-items: center; gap: 14px; display: inline-flex;color:#4D86DB;"
2265
- >
2266
- <i class="fa-regular fa-circle-plus fs-5"></i>
2267
- <div class="fs-5">新增自訂物流</div>
2268
- </div>
2269
- </div>
2270
- </div>`,
2242
+ this.addCard(
2243
+ '新增自訂物流',
2244
+ gvc.event(() => updateCustomShipment({ function: 'plus' }))
2245
+ ),
2271
2246
  ])
2272
2247
  .join('');
2273
2248
  },
@@ -2296,7 +2271,7 @@ export class ShoppingFinanceSetting {
2296
2271
  language: vm.language,
2297
2272
  callback: language => {
2298
2273
  vm.language = language;
2299
- gvc.notifyDataChange(vm.id);
2274
+ gvc.notifyDataChange(this.id);
2300
2275
  },
2301
2276
  })}
2302
2277
  </div>`,
@@ -2317,7 +2292,7 @@ export class ShoppingFinanceSetting {
2317
2292
  BgWidget.fullDialog({
2318
2293
  gvc: gvc,
2319
2294
  title: gvc2 => {
2320
- return html`<div class="d-flex align-items-center" style="gap:10px;">
2295
+ return html`<div class="d-flex align-items-center" style="gap: 10px;">
2321
2296
  ${'配送資訊' +
2322
2297
  BgWidget.aiChatButton({
2323
2298
  gvc: gvc2,
@@ -2325,7 +2300,7 @@ export class ShoppingFinanceSetting {
2325
2300
  click: () => {
2326
2301
  ProductAi.generateRichText(gvc, text => {
2327
2302
  language_data.info += text;
2328
- gvc.notifyDataChange(vm.id);
2303
+ gvc.notifyDataChange(this.id);
2329
2304
  gvc2.recreateView();
2330
2305
  });
2331
2306
  },
@@ -2488,392 +2463,356 @@ export class ShoppingFinanceSetting {
2488
2463
  },
2489
2464
  ]
2490
2465
  .map(dd => {
2491
- return html`
2492
- <div class="col-12 col-lg-3 col-md-4 p-0 p-md-2">
2493
- <div
2494
- class="w-100 position-relative main-card"
2495
- style="padding: 24px 32px; background: white; overflow: hidden; flex-direction: column; justify-content: flex-start; align-items: flex-start; gap: 18px; display: inline-flex;"
2496
- >
2497
- ${(() => {
2498
- return html` <div
2499
- class="position-absolute fw-500"
2500
- style="cursor:pointer;right:15px;top:15px;"
2501
- >
2502
- ${BgWidget.customButton({
2503
- button: {
2504
- color: 'gray',
2505
- size: 'sm',
2506
- },
2507
- text: {
2508
- name: `串接設定`,
2509
- },
2510
- event: gvc.event(() => {
2511
- if (dd.value === 'ec_pay') {
2512
- BgWidget.dialog({
2513
- gvc: gvc,
2514
- title: '物流追蹤設定',
2515
- innerHTML: (gvc: GVC) => {
2516
- return gvc.bindView(
2517
- (() => {
2518
- const id = gvc.glitter.getUUID();
2519
- return {
2520
- bind: id,
2521
- view: () => {
2522
- return [
2523
- ...(() => {
2524
- let array: any = [
2525
- BgWidget.inlineCheckBox({
2526
- title: '串接路徑',
2527
- gvc: gvc,
2528
- def: vm.delivery[dd.value].Action ?? 'test',
2529
- array: [
2530
- {
2531
- title: '正式站',
2532
- value: 'main',
2533
- },
2534
- {
2535
- title: '測試站',
2536
- value: 'test',
2537
- },
2538
- ],
2539
- callback: (text: any) => {
2540
- vm.delivery[dd.value].Action = text;
2541
- },
2542
- type: 'single',
2543
- }),
2544
- BgWidget.editeInput({
2545
- gvc: gvc,
2546
- title: '寄件人名稱',
2547
- default: vm.delivery[dd.value].SenderName ?? '',
2548
- callback: text => {
2549
- vm.delivery[dd.value].SenderName = text;
2550
- },
2551
- placeHolder: '請輸入寄件人名稱 / 您的商家名稱',
2552
- }),
2553
- BgWidget.editeInput({
2554
- gvc: gvc,
2555
- title: '寄件人手機',
2556
- default: vm.delivery[dd.value].SenderCellPhone ?? '',
2557
- callback: text => {
2558
- vm.delivery[dd.value].SenderCellPhone = text;
2559
- },
2560
- placeHolder: '請輸入寄件人手機 / 您的手機',
2561
- }),
2562
- BgWidget.editeInput({
2563
- gvc: gvc,
2564
- title: '寄件人地址',
2565
- default: vm.delivery[dd.value].SenderAddress ?? '',
2566
- callback: text => {
2567
- vm.delivery[dd.value].SenderAddress = text;
2568
- },
2569
- placeHolder: '請輸入寄件人地址 / 商家地址',
2570
- }),
2571
- BgWidget.editeInput({
2572
- gvc: gvc,
2573
- title: '特店編號',
2574
- default: vm.delivery[dd.value].MERCHANT_ID ?? '',
2575
- callback: text => {
2576
- vm.delivery[dd.value].MERCHANT_ID = text;
2577
- },
2578
- placeHolder: '請輸入特店編號',
2579
- }),
2580
- BgWidget.editeInput({
2581
- gvc: gvc,
2582
- title: 'HASH KEY',
2583
- default: vm.delivery[dd.value].HASH_KEY ?? '',
2584
- callback: text => {
2585
- vm.delivery[dd.value].HASH_KEY = text;
2586
- },
2587
- placeHolder: '請輸入 HASH KEY',
2588
- }),
2589
- BgWidget.editeInput({
2590
- gvc: gvc,
2591
- title: 'HASH IV',
2592
- default: vm.delivery[dd.value].HASH_IV ?? '',
2593
- callback: text => {
2594
- vm.delivery[dd.value].HASH_IV = text;
2595
- },
2596
- placeHolder: '請輸入 HASH IV',
2597
- }),
2598
- ];
2599
- return array;
2600
- })(),
2601
- ].join(BgWidget.mbContainer(12));
2466
+ return this.card({
2467
+ title: dd.title,
2468
+ img: html`<img src="${dd.src || BgWidget.noImageURL}" />`,
2469
+ toggle: vm.delivery[dd.value].toggle,
2470
+ toggleEvent: gvc.event(() => {
2471
+ vm.delivery[dd.value].toggle = !vm.delivery[dd.value].toggle;
2472
+ saveDelivery();
2473
+ gvc.notifyDataChange(id);
2474
+ }),
2475
+ buttonAction: [
2476
+ BgWidget.customButton({
2477
+ button: {
2478
+ color: 'gray',
2479
+ size: 'sm',
2480
+ },
2481
+ text: {
2482
+ name: `串接設定`,
2483
+ },
2484
+ event: gvc.event(() => {
2485
+ if (dd.value === 'ec_pay') {
2486
+ BgWidget.dialog({
2487
+ gvc: gvc,
2488
+ title: '物流追蹤設定',
2489
+ innerHTML: (gvc: GVC) => {
2490
+ const id = gvc.glitter.getUUID();
2491
+
2492
+ return gvc.bindView({
2493
+ bind: id,
2494
+ view: () => {
2495
+ return [
2496
+ ...(() => {
2497
+ let array: any = [
2498
+ BgWidget.inlineCheckBox({
2499
+ title: '串接路徑',
2500
+ gvc: gvc,
2501
+ def: vm.delivery[dd.value].Action ?? 'test',
2502
+ array: [
2503
+ {
2504
+ title: '正式站',
2505
+ value: 'main',
2506
+ },
2507
+ {
2508
+ title: '測試站',
2509
+ value: 'test',
2510
+ },
2511
+ ],
2512
+ callback: (text: any) => {
2513
+ vm.delivery[dd.value].Action = text;
2602
2514
  },
2603
- };
2604
- })()
2605
- );
2606
- },
2607
- save: {
2608
- text: '儲存',
2609
- event: () => {
2610
- return new Promise<boolean>(resolve => {
2611
- function checkSenderPattern(input: string) {
2612
- const senderPattern = /^[\u4e00-\u9fa5]{2,5}|[a-zA-Z]{4,10}$/;
2613
- return senderPattern.test(input);
2614
- }
2515
+ type: 'single',
2516
+ }),
2517
+ BgWidget.editeInput({
2518
+ gvc: gvc,
2519
+ title: '寄件人名稱',
2520
+ default: vm.delivery[dd.value].SenderName ?? '',
2521
+ callback: text => {
2522
+ vm.delivery[dd.value].SenderName = text;
2523
+ },
2524
+ placeHolder: '請輸入寄件人名稱 / 您的商家名稱',
2525
+ }),
2526
+ BgWidget.editeInput({
2527
+ gvc: gvc,
2528
+ title: '寄件人手機',
2529
+ default: vm.delivery[dd.value].SenderCellPhone ?? '',
2530
+ callback: text => {
2531
+ vm.delivery[dd.value].SenderCellPhone = text;
2532
+ },
2533
+ placeHolder: '請輸入寄件人手機 / 您的手機',
2534
+ }),
2535
+ BgWidget.editeInput({
2536
+ gvc: gvc,
2537
+ title: '寄件人地址',
2538
+ default: vm.delivery[dd.value].SenderAddress ?? '',
2539
+ callback: text => {
2540
+ vm.delivery[dd.value].SenderAddress = text;
2541
+ },
2542
+ placeHolder: '請輸入寄件人地址 / 商家地址',
2543
+ }),
2544
+ BgWidget.editeInput({
2545
+ gvc: gvc,
2546
+ title: '商店代號',
2547
+ default: vm.delivery[dd.value].MERCHANT_ID ?? '',
2548
+ callback: text => {
2549
+ vm.delivery[dd.value].MERCHANT_ID = text;
2550
+ },
2551
+ placeHolder: '請輸入商店代號',
2552
+ }),
2553
+ BgWidget.editeInput({
2554
+ gvc: gvc,
2555
+ title: 'HASH KEY',
2556
+ default: vm.delivery[dd.value].HASH_KEY ?? '',
2557
+ callback: text => {
2558
+ vm.delivery[dd.value].HASH_KEY = text;
2559
+ },
2560
+ placeHolder: '請輸入 HASH KEY',
2561
+ }),
2562
+ BgWidget.editeInput({
2563
+ gvc: gvc,
2564
+ title: 'HASH IV',
2565
+ default: vm.delivery[dd.value].HASH_IV ?? '',
2566
+ callback: text => {
2567
+ vm.delivery[dd.value].HASH_IV = text;
2568
+ },
2569
+ placeHolder: '請輸入 HASH IV',
2570
+ }),
2571
+ ];
2572
+ return array;
2573
+ })(),
2574
+ ].join(BgWidget.mbContainer(12));
2575
+ },
2576
+ });
2577
+ },
2578
+ save: {
2579
+ text: '儲存',
2580
+ event: gvc => {
2581
+ return new Promise<boolean>(resolve => {
2582
+ function checkSenderPattern(input: string) {
2583
+ const senderPattern = /^[\u4e00-\u9fa5]{2,5}|[a-zA-Z]{4,10}$/;
2584
+ return senderPattern.test(input);
2585
+ }
2615
2586
 
2616
- function checkPhonePattern(input: string) {
2617
- const phonePattern = /^09\d{8}$/;
2618
- return phonePattern.test(input);
2619
- }
2587
+ function checkPhonePattern(input: string) {
2588
+ const phonePattern = /^09\d{8}$/;
2589
+ return phonePattern.test(input);
2590
+ }
2620
2591
 
2621
- function checkAddressPattern(input: any) {
2622
- const addressPattern = /^.{6,60}$/;
2623
- return addressPattern.test(input);
2624
- }
2592
+ function checkAddressPattern(input: any) {
2593
+ const addressPattern = /^.{6,60}$/;
2594
+ return addressPattern.test(input);
2595
+ }
2625
2596
 
2626
- if (
2627
- CheckInput.isEmpty(vm.delivery[dd.value].SenderName) ||
2628
- !checkSenderPattern(vm.delivery[dd.value].SenderName)
2629
- ) {
2630
- dialog.infoMessage({
2631
- text: html` <div class="text-center">
2632
- 寄件人名稱請設定最多10字元<br />(中文5個字, 英文10個字,<br />不得含指定特殊符號)
2633
- </div>`,
2634
- });
2635
- resolve(false);
2636
- return;
2637
- }
2597
+ if (
2598
+ CheckInput.isEmpty(vm.delivery[dd.value].SenderName) ||
2599
+ !checkSenderPattern(vm.delivery[dd.value].SenderName)
2600
+ ) {
2601
+ dialog.infoMessage({
2602
+ text: html` <div class="text-center">
2603
+ 寄件人名稱請設定最多10字元<br />(中文5個字, 英文10個字,<br />不得含指定特殊符號)
2604
+ </div>`,
2605
+ });
2606
+ resolve(false);
2607
+ return;
2608
+ }
2638
2609
 
2639
- if (
2640
- CheckInput.isEmpty(vm.delivery[dd.value].SenderCellPhone) ||
2641
- !checkPhonePattern(vm.delivery[dd.value].SenderCellPhone)
2642
- ) {
2643
- dialog.infoMessage({ text: '寄件人手機應為09開頭的手機格式' });
2644
- resolve(false);
2645
- return;
2646
- }
2610
+ if (
2611
+ CheckInput.isEmpty(vm.delivery[dd.value].SenderCellPhone) ||
2612
+ !checkPhonePattern(vm.delivery[dd.value].SenderCellPhone)
2613
+ ) {
2614
+ dialog.infoMessage({ text: '寄件人手機應為09開頭的手機格式' });
2615
+ resolve(false);
2616
+ return;
2617
+ }
2647
2618
 
2648
- if (
2649
- !vm.delivery[dd.value].SenderAddress ||
2650
- !checkAddressPattern(vm.delivery[dd.value].SenderAddress)
2651
- ) {
2652
- dialog.infoMessage({
2653
- text: html` <div class="text-center">
2654
- 請輸入正確的寄件人地址<br />(中文6~60個字)
2655
- </div>`,
2656
- });
2657
- resolve(false);
2658
- return;
2659
- }
2619
+ if (
2620
+ !vm.delivery[dd.value].SenderAddress ||
2621
+ !checkAddressPattern(vm.delivery[dd.value].SenderAddress)
2622
+ ) {
2623
+ dialog.infoMessage({
2624
+ text: html` <div class="text-center">
2625
+ 請輸入正確的寄件人地址<br />(中文6~60個字)
2626
+ </div>`,
2627
+ });
2628
+ resolve(false);
2629
+ return;
2630
+ }
2660
2631
 
2661
- ApiPageConfig.setPrivateConfigV2({
2662
- key: 'glitter_delivery',
2663
- value: JSON.stringify(vm.delivery),
2664
- appName: saasConfig.config.appName,
2665
- }).then((r: { response: any; result: boolean }) => {
2666
- dialog.dataLoading({ visible: false });
2667
- if (r.response) {
2668
- dialog.successMessage({ text: '設定成功' });
2669
- } else {
2670
- dialog.errorMessage({ text: '設定失敗' });
2671
- }
2672
- resolve(true);
2673
- });
2674
- });
2675
- },
2676
- },
2677
- cancel: {},
2632
+ ApiPageConfig.setPrivateConfigV2({
2633
+ key: 'glitter_delivery',
2634
+ value: JSON.stringify(vm.delivery),
2635
+ appName: saasConfig.config.appName,
2636
+ }).then((r: { response: any; result: boolean }) => {
2637
+ dialog.dataLoading({ visible: false });
2638
+ if (r.response) {
2639
+ dialog.successMessage({ text: '設定成功' });
2640
+ } else {
2641
+ dialog.errorMessage({ text: '設定失敗' });
2642
+ }
2643
+ this.refresh(gvc);
2644
+ resolve(true);
2645
+ });
2678
2646
  });
2679
- } else if (dd.value === 'pay_now') {
2680
- BgWidget.dialog({
2681
- gvc: gvc,
2682
- title: '物流追蹤設定',
2683
- innerHTML: (gvc: GVC) => {
2684
- return gvc.bindView(
2685
- (() => {
2686
- const id = gvc.glitter.getUUID();
2687
- return {
2688
- bind: id,
2689
- view: () => {
2690
- return [
2691
- BgWidget.openBoxContainer({
2692
- gvc,
2693
- tag: 'delivery_alert_info',
2694
- title: '注意事項',
2695
- insideHTML: html` <div
2696
- class="mt-2"
2697
- style="white-space: normal;"
2698
- >
2699
- ${BgWidget.alertInfo('', [
2700
- '1. 支援四大超商(7-ELEVEN、全家、萊爾富、OK超商)與黑貓',
2701
- '2. 寄件人名稱請設定最多10字元(中文5個字, 英文10個字, 不得含指定特殊符號)',
2702
- '3. 寄件人手機應為09開頭的格式',
2703
- ])}
2704
- </div>`,
2705
- height: document.body.clientWidth > 768 ? 300 : 385,
2706
- }),
2707
- ...(() => {
2708
- let array: any = [
2709
- BgWidget.inlineCheckBox({
2710
- title: '串接路徑',
2711
- gvc: gvc,
2712
- def: vm.delivery[dd.value].Action ?? 'test',
2713
- array: [
2714
- {
2715
- title: '正式站',
2716
- value: 'main',
2717
- },
2718
- {
2719
- title: '測試站',
2720
- value: 'test',
2721
- },
2722
- ],
2723
- callback: (text: any) => {
2724
- vm.delivery[dd.value].Action = text;
2725
- },
2726
- type: 'single',
2727
- }),
2728
- html` <div
2729
- onclick="${gvc.event(() => {
2730
- (window.parent as any).navigator.clipboard.writeText(
2731
- (window.parent as any).saasConfig.config.url +
2732
- `/api-public/v1/delivery/notify?g-app=${(window.parent as any).appName}`
2733
- );
2734
- dialog.successMessage({ text: '已複製至剪貼簿' });
2735
- })}"
2736
- >
2737
- ${BgWidget.editeInput({
2738
- readonly: true,
2739
- gvc: gvc,
2740
- title: html` <div
2741
- class="d-flex flex-column"
2742
- style="gap:5px;"
2743
- >
2744
- 物流追蹤通知
2745
- ${BgWidget.grayNote(
2746
- '點擊複製此連結至PAYNOW後台的貨態回傳網址'
2747
- )}
2748
- </div>`,
2749
- default:
2750
- (window.parent as any).saasConfig.config.url +
2751
- `/api-public/v1/delivery/notify?g-app=${(window.parent as any).appName}`,
2752
- placeHolder: '',
2753
- callback: text => {},
2754
- })}
2755
- </div>`,
2756
- BgWidget.editeInput({
2757
- gvc: gvc,
2758
- title: '串接帳號',
2759
- default: vm.delivery[dd.value].account ?? '',
2760
- callback: text => {
2761
- vm.delivery[dd.value].account = text;
2762
- },
2763
- placeHolder: '請輸入串接帳號',
2764
- }),
2765
- BgWidget.editeInput({
2766
- gvc: gvc,
2767
- title: '串接密碼',
2768
- default: vm.delivery[dd.value].pwd ?? '',
2769
- callback: text => {
2770
- vm.delivery[dd.value].pwd = text;
2771
- },
2772
- placeHolder: '請輸入串接密碼',
2773
- }),
2774
- BgWidget.editeInput({
2775
- gvc: gvc,
2776
- title: '寄件人名稱',
2777
- default: vm.delivery[dd.value].SenderName ?? '',
2778
- callback: text => {
2779
- vm.delivery[dd.value].SenderName = text;
2780
- },
2781
- placeHolder: '請輸入寄件人名稱 / 您的商家名稱',
2782
- }),
2783
- BgWidget.editeInput({
2784
- gvc: gvc,
2785
- title: '寄件人手機',
2786
- default: vm.delivery[dd.value].SenderCellPhone ?? '',
2787
- callback: text => {
2788
- vm.delivery[dd.value].SenderCellPhone = text;
2789
- },
2790
- placeHolder: '請輸入寄件人手機 / 您的手機',
2791
- }),
2792
- BgWidget.editeInput({
2793
- gvc: gvc,
2794
- title: '寄件人地址',
2795
- default: vm.delivery[dd.value].SenderAddress ?? '',
2796
- callback: text => {
2797
- vm.delivery[dd.value].SenderAddress = text;
2798
- },
2799
- placeHolder: '請輸入寄件人地址 / 商家地址',
2800
- }),
2801
- BgWidget.editeInput({
2802
- gvc: gvc,
2803
- title: '寄件人信箱',
2804
- default: vm.delivery[dd.value].SenderEmail ?? '',
2805
- callback: text => {
2806
- vm.delivery[dd.value].SenderEmail = text;
2807
- },
2808
- placeHolder: '請輸入寄件人信箱',
2809
- }),
2810
- ];
2811
- return array;
2812
- })(),
2813
- ].join(BgWidget.mbContainer(12));
2647
+ },
2648
+ },
2649
+ cancel: {
2650
+ text: '取消',
2651
+ event: gvc => new Promise(() => this.refresh(gvc)),
2652
+ },
2653
+ xmark: gvc => new Promise(() => this.refresh(gvc)),
2654
+ });
2655
+ } else if (dd.value === 'pay_now') {
2656
+ BgWidget.dialog({
2657
+ gvc: gvc,
2658
+ title: '物流追蹤設定',
2659
+ innerHTML: (gvc: GVC) => {
2660
+ const id = gvc.glitter.getUUID();
2661
+
2662
+ return gvc.bindView({
2663
+ bind: id,
2664
+ view: () => {
2665
+ return [
2666
+ BgWidget.openBoxContainer({
2667
+ gvc,
2668
+ tag: 'delivery_alert_info',
2669
+ title: '注意事項',
2670
+ insideHTML: html` <div class="mt-2" style="white-space: normal;">
2671
+ ${BgWidget.alertInfo('', [
2672
+ '1. 支援四大超商(7-ELEVEN、全家、萊爾富、OK超商)與黑貓',
2673
+ '2. 寄件人名稱請設定最多10字元(中文5個字, 英文10個字, 不得含指定特殊符號)',
2674
+ '3. 寄件人手機應為09開頭的格式',
2675
+ ])}
2676
+ </div>`,
2677
+ height: document.body.clientWidth > 768 ? 300 : 385,
2678
+ }),
2679
+ ...(() => {
2680
+ let array: any = [
2681
+ BgWidget.inlineCheckBox({
2682
+ title: '串接路徑',
2683
+ gvc: gvc,
2684
+ def: vm.delivery[dd.value].Action ?? 'test',
2685
+ array: [
2686
+ {
2687
+ title: '正式站',
2688
+ value: 'main',
2689
+ },
2690
+ {
2691
+ title: '測試站',
2692
+ value: 'test',
2693
+ },
2694
+ ],
2695
+ callback: (text: any) => {
2696
+ vm.delivery[dd.value].Action = text;
2814
2697
  },
2815
- };
2816
- })()
2817
- );
2818
- },
2819
- save: {
2820
- text: '儲存',
2821
- event: () => {
2822
- return new Promise<boolean>(resolve => {
2823
- ApiPageConfig.setPrivateConfigV2({
2824
- key: 'glitter_delivery',
2825
- value: JSON.stringify(vm.delivery),
2826
- appName: saasConfig.config.appName,
2827
- }).then((r: { response: any; result: boolean }) => {
2828
- dialog.dataLoading({ visible: false });
2829
- if (r.response) {
2830
- dialog.successMessage({ text: '設定成功' });
2831
- } else {
2832
- dialog.errorMessage({ text: '設定失敗' });
2833
- }
2834
- resolve(true);
2835
- });
2836
- });
2837
- },
2838
- },
2839
- cancel: {},
2698
+ type: 'single',
2699
+ }),
2700
+ html` <div
2701
+ onclick="${gvc.event(() => {
2702
+ (window.parent as any).navigator.clipboard.writeText(
2703
+ (window.parent as any).saasConfig.config.url +
2704
+ `/api-public/v1/delivery/notify?g-app=${(window.parent as any).appName}`
2705
+ );
2706
+ dialog.successMessage({ text: '已複製至剪貼簿' });
2707
+ })}"
2708
+ >
2709
+ ${BgWidget.editeInput({
2710
+ readonly: true,
2711
+ gvc: gvc,
2712
+ title: html` <div class="d-flex flex-column" style="gap: 4px;">
2713
+ 物流追蹤通知
2714
+ ${BgWidget.grayNote('點擊複製此連結至PAYNOW後台的貨態回傳網址')}
2715
+ </div>`,
2716
+ default:
2717
+ (window.parent as any).saasConfig.config.url +
2718
+ `/api-public/v1/delivery/notify?g-app=${(window.parent as any).appName}`,
2719
+ placeHolder: '',
2720
+ callback: text => {},
2721
+ })}
2722
+ </div>`,
2723
+ BgWidget.editeInput({
2724
+ gvc: gvc,
2725
+ title: '串接帳號',
2726
+ default: vm.delivery[dd.value].account ?? '',
2727
+ callback: text => {
2728
+ vm.delivery[dd.value].account = text;
2729
+ },
2730
+ placeHolder: '請輸入串接帳號',
2731
+ }),
2732
+ BgWidget.editeInput({
2733
+ gvc: gvc,
2734
+ title: '串接密碼',
2735
+ default: vm.delivery[dd.value].pwd ?? '',
2736
+ callback: text => {
2737
+ vm.delivery[dd.value].pwd = text;
2738
+ },
2739
+ placeHolder: '請輸入串接密碼',
2740
+ }),
2741
+ BgWidget.editeInput({
2742
+ gvc: gvc,
2743
+ title: '寄件人名稱',
2744
+ default: vm.delivery[dd.value].SenderName ?? '',
2745
+ callback: text => {
2746
+ vm.delivery[dd.value].SenderName = text;
2747
+ },
2748
+ placeHolder: '請輸入寄件人名稱 / 您的商家名稱',
2749
+ }),
2750
+ BgWidget.editeInput({
2751
+ gvc: gvc,
2752
+ title: '寄件人手機',
2753
+ default: vm.delivery[dd.value].SenderCellPhone ?? '',
2754
+ callback: text => {
2755
+ vm.delivery[dd.value].SenderCellPhone = text;
2756
+ },
2757
+ placeHolder: '請輸入寄件人手機 / 您的手機',
2758
+ }),
2759
+ BgWidget.editeInput({
2760
+ gvc: gvc,
2761
+ title: '寄件人地址',
2762
+ default: vm.delivery[dd.value].SenderAddress ?? '',
2763
+ callback: text => {
2764
+ vm.delivery[dd.value].SenderAddress = text;
2765
+ },
2766
+ placeHolder: '請輸入寄件人地址 / 商家地址',
2767
+ }),
2768
+ BgWidget.editeInput({
2769
+ gvc: gvc,
2770
+ title: '寄件人信箱',
2771
+ default: vm.delivery[dd.value].SenderEmail ?? '',
2772
+ callback: text => {
2773
+ vm.delivery[dd.value].SenderEmail = text;
2774
+ },
2775
+ placeHolder: '請輸入寄件人信箱',
2776
+ }),
2777
+ ];
2778
+ return array;
2779
+ })(),
2780
+ ].join(BgWidget.mbContainer(12));
2781
+ },
2782
+ });
2783
+ },
2784
+ save: {
2785
+ text: '儲存',
2786
+ event: gvc => {
2787
+ return new Promise<boolean>(resolve => {
2788
+ ApiPageConfig.setPrivateConfigV2({
2789
+ key: 'glitter_delivery',
2790
+ value: JSON.stringify(vm.delivery),
2791
+ appName: saasConfig.config.appName,
2792
+ }).then((r: { response: any; result: boolean }) => {
2793
+ dialog.dataLoading({ visible: false });
2794
+ if (r.response) {
2795
+ dialog.successMessage({ text: '設定成功' });
2796
+ } else {
2797
+ dialog.errorMessage({ text: '設定失敗' });
2798
+ }
2799
+ this.refresh(gvc);
2800
+ resolve(true);
2801
+ });
2840
2802
  });
2841
- }
2842
- }),
2843
- })}
2844
- </div>`;
2845
- })()}
2846
- <div
2847
- style="align-self: stretch; justify-content: flex-start; align-items: center; gap: 28px; display: inline-flex"
2848
- >
2849
- <div style="min-width: 46px;max-width: 46px;">
2850
- <img src="${dd.src}" />
2851
- </div>
2852
- <div
2853
- style="flex-direction: column; justify-content: center; align-items: flex-start; gap: 4px; display: inline-flex"
2854
- >
2855
- <div class="tx_normal">${dd.title}</div>
2856
- <div class="d-flex align-items-center" style="gap:4px;">
2857
- <div class="tx_normal">${vm.delivery[dd.value].toggle ? `開啟` : `關閉`}</div>
2858
- <div class="cursor_pointer form-check form-switch" style="margin-top: 10px;">
2859
- <input
2860
- class="form-check-input"
2861
- type="checkbox"
2862
- onchange="${gvc.event((e, event) => {
2863
- vm.delivery[dd.value].toggle = !vm.delivery[dd.value].toggle;
2864
- saveDelivery();
2865
- gvc.notifyDataChange(id);
2866
- })}"
2867
- ${vm.delivery[dd.value].toggle ? `checked` : ''}
2868
- />
2869
- </div>
2870
- </div>
2871
- </div>
2872
- </div>
2873
- </div>
2874
- </div>
2875
- ${document.body.clientWidth > 768 ? '' : BgWidget.mbContainer(8)}
2876
- `;
2803
+ },
2804
+ },
2805
+ cancel: {
2806
+ text: '取消',
2807
+ event: gvc => new Promise(() => this.refresh(gvc)),
2808
+ },
2809
+ xmark: gvc => new Promise(() => this.refresh(gvc)),
2810
+ });
2811
+ }
2812
+ }),
2813
+ }),
2814
+ ],
2815
+ });
2877
2816
  })
2878
2817
  .join('');
2879
2818
  },
@@ -3161,17 +3100,36 @@ export class ShoppingFinanceSetting {
3161
3100
  divCreate: {
3162
3101
  class: `d-flex justify-content-center w-100 flex-column align-items-center `,
3163
3102
  },
3103
+ onCreate: () => {
3104
+ if (this.loading) {
3105
+ saasConfig.api
3106
+ .getPrivateConfig(saasConfig.config.appName, 'logistics_setting')
3107
+ .then((r: { response: any; result: boolean }) => {
3108
+ if (r.response.result[0]) {
3109
+ vm.data = r.response.result[0].value;
3110
+ }
3111
+ if (!vm.data.language_data) {
3112
+ vm.data.language_data = {
3113
+ 'en-US': { info: '' },
3114
+ 'zh-CN': { info: '' },
3115
+ 'zh-TW': { info: vm.data.info || '' },
3116
+ };
3117
+ }
3118
+ this.loading = false;
3119
+ gvc.notifyDataChange(this.id);
3120
+ });
3121
+ }
3122
+ },
3164
3123
  };
3165
3124
  });
3166
3125
  }
3167
3126
 
3127
+ // *發票設定頁
3168
3128
  static invoice_setting_v2(gvc: GVC, widget: any) {
3169
3129
  const dialog = new ShareDialog(gvc.glitter);
3170
- const saasConfig: {
3171
- config: any;
3172
- api: any;
3173
- } = (window.parent as any).saasConfig;
3174
3130
  const glitter = (window as any).glitter;
3131
+ const saasConfig = this.saasConfig;
3132
+
3175
3133
  const vm: {
3176
3134
  id: string;
3177
3135
  loading: boolean;
@@ -3235,7 +3193,7 @@ export class ShoppingFinanceSetting {
3235
3193
  bind: id,
3236
3194
  view: () => {
3237
3195
  return html`
3238
- <div class="d-flex flex-column" style="gap:18px;">
3196
+ <div class="d-flex flex-column" style="gap: 18px;">
3239
3197
  <div class="tx_normal fw-bold">服務商選擇</div>
3240
3198
  ${[
3241
3199
  // {
@@ -3280,7 +3238,7 @@ export class ShoppingFinanceSetting {
3280
3238
  ${[
3281
3239
  html` <div
3282
3240
  class="d-flex align-items-center cursor_pointer"
3283
- style="gap:8px;"
3241
+ style="gap: 8px;"
3284
3242
  onclick="${gvc.event(() => {
3285
3243
  vm.data.fincial = dd.value;
3286
3244
  gvc.notifyDataChange(id);
@@ -3296,7 +3254,7 @@ export class ShoppingFinanceSetting {
3296
3254
  class="ms-2 border-end position-absolute h-100"
3297
3255
  style="left: 0px;"
3298
3256
  ></div>
3299
- <div class="flex-fill" style="margin-left:30px;max-width: 518px;">
3257
+ <div class="flex-fill" style="margin-left: 30px;max-width: 518px;">
3300
3258
  ${(() => {
3301
3259
  if (
3302
3260
  vm.data.fincial === 'nouse' ||
@@ -3334,10 +3292,10 @@ export class ShoppingFinanceSetting {
3334
3292
  }),
3335
3293
  BgWidget.editeInput({
3336
3294
  gvc: gvc,
3337
- title: '特店編號',
3295
+ title: '商店代號',
3338
3296
  default: vm.data.merchNO ?? '',
3339
3297
  type: 'text',
3340
- placeHolder: '請輸入特店編號',
3298
+ placeHolder: '請輸入商店代號',
3341
3299
  callback: text => {
3342
3300
  vm.data.merchNO = text;
3343
3301
  },
@@ -3394,7 +3352,7 @@ export class ShoppingFinanceSetting {
3394
3352
  },
3395
3353
  divCreate: {
3396
3354
  class: 'd-flex flex-column flex-column-reverse flex-md-row px-0',
3397
- style: 'gap:10px;',
3355
+ style: 'gap: 10px;',
3398
3356
  },
3399
3357
  };
3400
3358
  })
@@ -3403,9 +3361,7 @@ export class ShoppingFinanceSetting {
3403
3361
  html` <div class="update-bar-container">
3404
3362
  ${BgWidget.save(
3405
3363
  gvc.event(() => {
3406
- save(() => {
3407
- dialog.successMessage({ text: '設定成功' });
3408
- });
3364
+ save(() => dialog.successMessage({ text: '設定成功' }));
3409
3365
  })
3410
3366
  )}
3411
3367
  </div>`,