ts-glitter 22.5.2 → 22.5.3

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 (33) hide show
  1. package/collection.json +398 -0
  2. package/lowcode/Entry.js +1 -1
  3. package/lowcode/Entry.ts +1 -1
  4. package/lowcode/backend-manager/bg-product.js +3 -0
  5. package/lowcode/backend-manager/bg-product.ts +3 -0
  6. package/lowcode/cms-plugin/shopping-collections.js +851 -831
  7. package/lowcode/cms-plugin/shopping-collections.ts +909 -1156
  8. package/lowcode/cms-plugin/shopping-setting-basic.js +1 -0
  9. package/lowcode/cms-plugin/shopping-setting-basic.ts +1 -0
  10. package/lowcode/glitter-base/route/public-config.js +1 -1
  11. package/lowcode/glitter-base/route/public-config.ts +1 -1
  12. package/lowcode/public-components/product/pd-card-03.ts +1 -0
  13. package/lowcode/public-components/product/product-list.js +8 -4
  14. package/lowcode/public-components/product/product-list.ts +6 -5
  15. package/package.json +1 -1
  16. package/src/api-public/services/collection.d.ts +3 -0
  17. package/src/api-public/services/collection.js +100 -0
  18. package/src/api-public/services/collection.js.map +1 -0
  19. package/src/api-public/services/collection.ts +98 -0
  20. package/src/api-public/services/data-analyze.d.ts +1 -1
  21. package/src/api-public/services/manager.d.ts +2 -1
  22. package/src/api-public/services/manager.js +67 -13
  23. package/src/api-public/services/manager.js.map +1 -1
  24. package/src/api-public/services/manager.ts +86 -14
  25. package/src/api-public/services/public-table-check.js +14 -1
  26. package/src/api-public/services/public-table-check.js.map +1 -1
  27. package/src/api-public/services/public-table-check.ts +14 -1
  28. package/src/api-public/services/shopping.js +16 -8
  29. package/src/api-public/services/shopping.js.map +1 -1
  30. package/src/api-public/services/shopping.ts +19 -10
  31. package/src/api-public/services/updated-table-checked.js +43 -0
  32. package/src/api-public/services/updated-table-checked.js.map +1 -1
  33. package/src/api-public/services/updated-table-checked.ts +49 -0
@@ -6,6 +6,8 @@ import { EditorElem } from '../glitterBundle/plugins/editor-elem.js';
6
6
  import { ShareDialog } from '../glitterBundle/dialog/ShareDialog.js';
7
7
  import { CheckInput } from '../modules/checkInput.js';
8
8
  import { Language, LanguageLocation } from '../glitter-base/global/language.js';
9
+ import { PublicConfig } from '../glitter-base/route/public-config.js';
10
+
9
11
 
10
12
  const html = String.raw;
11
13
 
@@ -137,7 +139,7 @@ export class ShoppingCollections {
137
139
  checked: false,
138
140
  parentTitles: parentTitles.length ? [...parentTitles] : [],
139
141
  allCollections: parentTitles.length ? [...topLevelCollections] : [],
140
- subCollections: array.map(subCol => subCol.title),
142
+ subCollections: (array ?? []).map(subCol => subCol.title),
141
143
  hidden: Boolean(col.hidden),
142
144
  };
143
145
  if (
@@ -177,6 +179,34 @@ export class ShoppingCollections {
177
179
  return flattenCollections(data.collections, [], topLevelCollections);
178
180
  };
179
181
 
182
+ async function saveEvent(){
183
+
184
+ return new Promise(async (resolve, reject)=>{
185
+ function checkPass(array:any[]):boolean{
186
+ if(Array.from(new Set((array ?? []).map((dd:any)=>{return dd.title}))).length!==array.length){
187
+ return false
188
+ }
189
+ return !array.find((dd)=>{
190
+ return dd.array && !checkPass(dd.array)
191
+ })
192
+ }
193
+ const data=getSaveData()
194
+ if(!checkPass(data)){
195
+ dialog.errorMessage({text:"同層級不可以有相同的分類標籤!!"})
196
+ resolve(false)
197
+ return
198
+ }
199
+ dialog.dataLoading({visible:true})
200
+ await PublicConfig.set('collection',data );
201
+
202
+ dialog.dataLoading({visible:false})
203
+ dialog.successMessage({text:'儲存成功'})
204
+ gvc.recreateView()
205
+ resolve(true)
206
+ })
207
+ }
208
+ //取得要儲存的資料
209
+ let getSaveData: any = () => {};
180
210
  return gvc.bindView(() => {
181
211
  return {
182
212
  bind: vm.id,
@@ -189,204 +219,6 @@ export class ShoppingCollections {
189
219
  <div class="title-container">
190
220
  ${BgWidget.title('商品分類')}
191
221
  <div class="flex-fill"></div>
192
- <div class="d-flex gap-2">
193
- ${BgWidget.grayButton(
194
- '編輯順序',
195
- gvc.event(() => {
196
- const cloneCollectionList = vm.collectionList.slice();
197
-
198
- return BgWidget.settingDialog({
199
- gvc,
200
- title: '編輯順序',
201
- width: 700,
202
- innerHTML: (iGVC: GVC) => {
203
- const id = glitter.getUUID();
204
- let loading = true;
205
- this.addStyle(iGVC);
206
-
207
- return iGVC.bindView({
208
- bind: id,
209
- view: () => {
210
- if (loading) {
211
- return BgWidget.spinner();
212
- }
213
-
214
- return html`
215
- <div class="p-2">
216
- ${BgWidget.grayNote('提示:左鍵拖曳可排列順序,點擊可顯示向下一層分類')}
217
- <div class="d-flex justify-content-start mt-3">
218
- <div class="layer-container">
219
- ${[0, 1, 2]
220
- .map(depth => {
221
- const title = ['第一層分類', '第二層分類', '第三層分類'][depth];
222
- return html` <div class="flex-1 layer-block">
223
- <div class="tx_700 fs-4 text-center mb-2">${title}</div>
224
- <ul class="ul-style" id="layer-list-${depth}"></ul>
225
- </div>`;
226
- })
227
- .join('')}
228
- </div>
229
- </div>
230
- </div>
231
- `;
232
- },
233
- onCreate: () => {
234
- if (loading) {
235
- iGVC.addMtScript(
236
- [{ src: 'https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js' }],
237
- () => {
238
- const si = setInterval(() => {
239
- if ((window.parent as any).Sortable !== undefined) {
240
- loading = false;
241
- clearInterval(si);
242
- iGVC.notifyDataChange(id);
243
- }
244
- }, 300);
245
- },
246
- () => {}
247
- );
248
- } else {
249
- const document = window.parent.document;
250
-
251
- function createListItem(item: Collection, index: number): HTMLLIElement {
252
- const li = document.createElement('li');
253
- li.className = 'li-style';
254
- li.setAttribute('data-index', index.toString());
255
- li.setAttribute('data-path', [...(item.parentTitles ?? []), item.title].join(' / '));
256
- li.innerHTML = `<span class="drag-icon"></span><span class="tx_normal">${item.title}</span>`;
257
-
258
- li.addEventListener('click', (e: MouseEvent) => {
259
- const target = e.currentTarget as HTMLElement;
260
-
261
- // 取得最近的 ul 並取得其 id
262
- const ul = target.closest('ul');
263
-
264
- // 取代 root(靜態 ID)為動態找到的 ul
265
- if (ul) {
266
- Array.from(ul.children).forEach((element: Element) => {
267
- (element as HTMLElement).style.backgroundColor = '#dddddd';
268
- });
269
- }
270
-
271
- // 設定被點擊的項目背景色
272
- target.style.backgroundColor = '#d8ecda';
273
-
274
- // 呼叫對應層級的載入方法
275
- loadChildLayer([...(item.parentTitles ?? []), item.title]);
276
- });
277
-
278
- return li;
279
- }
280
-
281
- function initSortable(containerId: string) {
282
- const el = document.getElementById(containerId) as HTMLElement;
283
- (window.parent as any).Sortable.create(el, {
284
- animation: 200,
285
- scroll: true,
286
- onEnd: () => {
287
- const items = [...el.children].map(
288
- child => vm.dataList?.[parseInt(child.getAttribute('data-index') as string)]
289
- ) as Collection[];
290
-
291
- vm.collectionList = ShoppingCollections.sortedCollectionConfig(
292
- vm.collectionList,
293
- items
294
- );
295
- },
296
- });
297
- }
298
-
299
- function loadChildLayer(parentPath: string[]) {
300
- const nextDepth = parentPath.length;
301
- const nextId = `layer-list-${nextDepth}`;
302
- for (let i = nextDepth; i < 3; i++) {
303
- const el = document.getElementById(`layer-list-${i}`);
304
- if (el) el.innerHTML = '';
305
- }
306
- const container = document.getElementById(nextId) as HTMLElement;
307
- container.innerHTML = '';
308
- vm.dataList?.forEach((item, index) => {
309
- const path = item.parentTitles ?? [];
310
- if (
311
- path.length === parentPath.length &&
312
- path.every((p, i) => p === parentPath[i])
313
- ) {
314
- container.appendChild(createListItem(item, index));
315
- }
316
- });
317
- initSortable(nextId);
318
- }
319
-
320
- const root = document.getElementById('layer-list-0') as HTMLElement;
321
- root.innerHTML = '';
322
-
323
- vm.dataList?.forEach((item, index) => {
324
- if ((item.parentTitles ?? []).length === 0) {
325
- root.appendChild(createListItem(item, index));
326
- }
327
- });
328
- initSortable('layer-list-0');
329
- }
330
- },
331
- });
332
- },
333
- footer_html: (fGVC: GVC) => {
334
- return [
335
- BgWidget.cancel(
336
- fGVC.event(() => {
337
- vm.collectionList = cloneCollectionList;
338
- fGVC.closeDialog();
339
- })
340
- ),
341
- BgWidget.save(
342
- fGVC.event(() => {
343
- dialog.dataLoading({ visible: true });
344
-
345
- ApiShop.sortCollections({
346
- data: { list: vm.collectionList },
347
- token: (window.parent as any).config.token,
348
- }).then(res => {
349
- dialog.dataLoading({ visible: false });
350
- if (res.result && !res.response) {
351
- dialog.errorMessage({ text: '更改順序失敗' });
352
- } else {
353
- dialog.successMessage({ text: '更改順序成功' });
354
- fGVC.closeDialog();
355
- gvc.notifyDataChange(vm.id);
356
- }
357
- });
358
- })
359
- ),
360
- ].join('');
361
- },
362
- });
363
- })
364
- )}
365
- ${BgWidget.darkButton(
366
- '新增',
367
- gvc.event(() => {
368
- vm.data = {
369
- title: '',
370
- array: [],
371
- product_id: [],
372
- parentTitles: [],
373
- subCollections: [],
374
- checked: false,
375
- seo_title: '',
376
- seo_content: '',
377
- language_data: {
378
- 'zh-CN': getEmptyLanguageData(),
379
- 'zh-TW': getEmptyLanguageData(),
380
- 'en-US': getEmptyLanguageData(),
381
- },
382
- seo_image: '',
383
- code: '',
384
- allCollections: vm.allParents,
385
- };
386
- vm.type = 'add';
387
- })
388
- )}
389
- </div>
390
222
  </div>
391
223
  ${BgWidget.container(
392
224
  BgWidget.mainCard(
@@ -399,349 +231,543 @@ export class ShoppingCollections {
399
231
  vm.query || '',
400
232
  '搜尋分類'
401
233
  ),
402
- // gvc.bindView(() => {
403
- // const vm = {
404
- // id: gvc.glitter.getUUID(),
405
- // loading: true,
406
- // data: [],
407
- // };
408
- //
409
- // async function loading() {
410
- // const collection = await ApiShop.getCollection();
411
- // vm.data = collection.response.value ?? [];
412
- // vm.loading = false;
413
- // gvc.notifyDataChange(vm.id);
414
- // }
415
- //
416
- // loading();
417
- // return {
418
- // bind: vm.id,
419
- // view: () => {
420
- // if (vm.loading) {
421
- // return BgWidget.spinner();
422
- // }
423
- //
424
- // function loop(array: any[], index: string): string {
425
- // return html`
426
- // <ol class="dd-list">
427
- // ${array.map((dd, index) => {
428
- // return html` <li class="dd-item" data-id="${index}-${index}">
429
- // <div class="dd-handle">${dd.title}</div>
430
- // ${dd.array && dd.array.length ? loop(dd.array, `${index}-${index}`) : []}
431
- // </li>`;
432
- // }).join('')}
433
- // </ol>
434
- // `;
435
- // }
436
- //
437
- // return html` <div class="dd" id="nestable">${loop(vm.data, '0')}</div>`;
438
- // },
439
- // divCreate: {
440
- // class: `px-lg-3 px-1`,
441
- // },
442
- // onCreate: () => {
443
- // ApiShop.putCollections
444
- // gvc.glitter.addStyle(`
445
- // .cf:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; }
446
- // *:first-child+html .cf { zoom: 1; }
447
- //
448
- // h1 { font-size: 1.75em; margin: 0 0 0.6em 0; }
449
- //
450
- // a { color: #2996cc; }
451
- // a:hover { text-decoration: none; }
452
- //
453
- // p { line-height: 1.5em; }
454
- // .small { color: #666; font-size: 0.875em; }
455
- // .large { font-size: 1.25em; }
456
- //
457
- // /**
458
- // * Nestable
459
- // */
460
- //
461
- // .dd { position: relative; display: block; margin: 0; padding: 0; list-style: none; font-size: 13px; line-height: 20px; }
462
- //
463
- // .dd-list { display: block; position: relative; margin: 0; padding: 0; list-style: none; }
464
- // .dd-list .dd-list { padding-left: 30px; }
465
- // .dd-collapsed .dd-list { display: none; }
466
- //
467
- // .dd-item,
468
- // .dd-empty,
469
- // .dd-placeholder { display: block; position: relative; margin: 0; padding: 0; min-height: 20px; font-size: 13px; line-height: 20px; }
470
- //
471
- // .dd-handle { display: block; height: 30px; margin: 5px 0; padding: 5px 10px; color: #333; text-decoration: none; font-weight: bold; border: 1px solid #ccc;
472
- // background: #fafafa;
473
- // background: -webkit-linear-gradient(top, #fafafa 0%, #eee 100%);
474
- // background: -moz-linear-gradient(top, #fafafa 0%, #eee 100%);
475
- // background: linear-gradient(top, #fafafa 0%, #eee 100%);
476
- // -webkit-border-radius: 3px;
477
- // border-radius: 3px;
478
- // box-sizing: border-box; -moz-box-sizing: border-box;
479
- // }
480
- // .dd-handle:hover { color: #2ea8e5; background: #fff; }
481
- //
482
- // .dd-item > button { display: block; position: relative; cursor: pointer; float: left; width: 25px; height: 20px; margin: 5px 0; padding: 0; text-indent: 100%; white-space: nowrap; overflow: hidden; border: 0; background: transparent; font-size: 12px; line-height: 1; text-align: center; font-weight: bold; }
483
- // .dd-item > button:before { content: '+'; display: block; position: absolute; width: 100%; text-align: center; text-indent: 0; }
484
- // .dd-item > button[data-action="collapse"]:before { content: '-'; }
485
- //
486
- // .dd-placeholder,
487
- // .dd-empty { margin: 5px 0; padding: 0; min-height: 30px; background: #f2fbff; border: 1px dashed #b6bcbf; box-sizing: border-box; -moz-box-sizing: border-box; }
488
- // .dd-empty { border: 1px dashed #bbb; min-height: 100px; background-color: #e5e5e5;
489
- // background-image: -webkit-linear-gradient(45deg, #fff 25%, transparent 25%, transparent 75%, #fff 75%, #fff),
490
- // -webkit-linear-gradient(45deg, #fff 25%, transparent 25%, transparent 75%, #fff 75%, #fff);
491
- // background-image: -moz-linear-gradient(45deg, #fff 25%, transparent 25%, transparent 75%, #fff 75%, #fff),
492
- // -moz-linear-gradient(45deg, #fff 25%, transparent 25%, transparent 75%, #fff 75%, #fff);
493
- // background-image: linear-gradient(45deg, #fff 25%, transparent 25%, transparent 75%, #fff 75%, #fff),
494
- // linear-gradient(45deg, #fff 25%, transparent 25%, transparent 75%, #fff 75%, #fff);
495
- // background-size: 60px 60px;
496
- // background-position: 0 0, 30px 30px;
497
- // }
498
- //
499
- // .dd-dragel { position: absolute; pointer-events: none; z-index: 9999; }
500
- // .dd-dragel > .dd-item .dd-handle { margin-top: 0; }
501
- // .dd-dragel .dd-handle {
502
- // -webkit-box-shadow: 2px 4px 6px 0 rgba(0,0,0,.1);
503
- // box-shadow: 2px 4px 6px 0 rgba(0,0,0,.1);
504
- // }
505
- //
506
- // /**
507
- // * Nestable Extras
508
- // */
509
- //
510
- // .nestable-lists { display: block; clear: both; padding: 30px 0; width: 100%; border: 0; border-top: 2px solid #ddd; border-bottom: 2px solid #ddd; }
511
- //
512
- // #nestable-menu { padding: 0; margin: 20px 0; }
513
- //
514
- // #nestable-output,
515
- // #nestable2-output { width: 100%; height: 7em; font-size: 0.75em; line-height: 1.333333em; font-family: Consolas, monospace; padding: 5px; box-sizing: border-box; -moz-box-sizing: border-box; }
516
- //
517
- // #nestable2 .dd-handle {
518
- // color: #fff;
519
- // border: 1px solid #999;
520
- // background: #bbb;
521
- // background: -webkit-linear-gradient(top, #bbb 0%, #999 100%);
522
- // background: -moz-linear-gradient(top, #bbb 0%, #999 100%);
523
- // background: linear-gradient(top, #bbb 0%, #999 100%);
524
- // }
525
- // #nestable2 .dd-handle:hover { background: #bbb; }
526
- // #nestable2 .dd-item > button:before { color: #fff; }
527
- //
528
- // @media only screen and (min-width: 700px) {
529
- //
530
- // .dd { width: 100%; }
531
- // .dd + .dd { margin-left: 2%; }
532
- //
533
- // }
534
- //
535
- // .dd-hover > .dd-handle { background: #2ea8e5 !important; }
536
- //
537
- // /**
538
- // * Nestable Draggable Handles
539
- // */
540
- //
541
- // .dd3-content { display: block; height: 30px; margin: 5px 0; padding: 5px 10px 5px 40px; color: #333; text-decoration: none; font-weight: bold; border: 1px solid #ccc;
542
- // background: #fafafa;
543
- // background: -webkit-linear-gradient(top, #fafafa 0%, #eee 100%);
544
- // background: -moz-linear-gradient(top, #fafafa 0%, #eee 100%);
545
- // background: linear-gradient(top, #fafafa 0%, #eee 100%);
546
- // -webkit-border-radius: 3px;
547
- // border-radius: 3px;
548
- // box-sizing: border-box; -moz-box-sizing: border-box;
549
- // }
550
- // .dd3-content:hover { color: #2ea8e5; background: #fff; }
551
- //
552
- // .dd-dragel > .dd3-item > .dd3-content { margin: 0; }
553
- //
554
- // .dd3-item > button { margin-left: 30px; }
555
- //
556
- // .dd3-handle { position: absolute; margin: 0; left: 0; top: 0; cursor: pointer; width: 30px; text-indent: 100%; white-space: nowrap; overflow: hidden;
557
- // border: 1px solid #aaa;
558
- // background: #ddd;
559
- // background: -webkit-linear-gradient(top, #ddd 0%, #bbb 100%);
560
- // background: -moz-linear-gradient(top, #ddd 0%, #bbb 100%);
561
- // background: linear-gradient(top, #ddd 0%, #bbb 100%);
562
- // border-top-right-radius: 0;
563
- // border-bottom-right-radius: 0;
564
- // }
565
- // .dd3-handle:before { content: '≡'; display: block; position: absolute; left: 0; top: 3px; width: 100%; text-align: center; text-indent: 0; color: #fff; font-size: 20px; font-weight: normal; }
566
- // .dd3-handle:hover { background: #ddd; }
567
- //
568
- // /**
569
- // * Socialite
570
- // */
571
- //
572
- // .socialite { display: block; float: left; height: 35px; }
573
- // `);
574
- // gvc.glitter.addMtScript(
575
- // [`${gvc.glitter.root_path}/jslib/nestable/jquery.nestable.js`],
576
- // () => {
577
- // const updateOutput = function (e: any) {
578
- // const list = e.length ? e : $(e.target),
579
- // output = list.data('output');
580
- // console.log(`output-data`, window.JSON.stringify(list.nestable('serialize')));
581
- // };
582
- //
583
- // //@ts-ignore
584
- // $('#nestable')
585
- // //@ts-ignore
586
- // .nestable({
587
- // group: 1,
588
- // })
589
- // .on('change', updateOutput);
590
- // },
591
- // () => {}
592
- // );
593
- // },
594
- // };
595
- // }),
596
- BgWidget.tableV3({
597
- gvc: gvc,
598
- getData: vmi => {
599
- ApiShop.getProduct({
600
- page: 0,
601
- limit: 999999,
602
- }).then(d => {
603
- if (d.result) {
604
- const products: Product[] = d.response.data;
605
-
606
- ApiShop.getCollection().then(data => {
607
- if (data.result && data.response.value.length > 0) {
608
- vm.collectionList = data.response.value;
609
-
610
- vm.allParents = [this.undefinedOption].concat(
611
- data.response.value.map((item: { title: string }) => item.title)
612
- );
234
+ gvc.bindView(() => {
235
+ const vm_2 = {
236
+ id: gvc.glitter.getUUID(),
237
+ loading: true,
238
+ data: [],
239
+ };
613
240
 
614
- const collections = updateCollections({
615
- products,
616
- collections: data.response.value,
617
- });
618
-
619
- const collectionsMap = new Map(collections.map(col => [col.title, col]));
620
-
621
- function getDatalist() {
622
- return collections.map(dd => {
623
- const original = structuredClone(dd);
624
- const isChildren = dd.parentTitles && dd.parentTitles.length > 0;
625
-
626
- // 更新分類顯示資料
627
- function triggerHidden() {
628
- dd.hidden = !Boolean(dd.hidden);
629
-
630
- dialog.dataLoading({ visible: true });
631
- ApiShop.putCollections({
632
- data: { replace: dd, original },
633
- token: (window.parent as any).config.token,
634
- }).then(() => {
635
- dialog.dataLoading({ visible: false });
636
- gvc.notifyDataChange(vm.id);
637
- });
638
- }
241
+ async function loading() {
242
+ const collection = await ApiShop.getCollection();
243
+ vm_2.data = collection.response.value ?? [];
244
+ vm_2.loading = false;
245
+ gvc.notifyDataChange(vm_2.id);
246
+ }
639
247
 
640
- // 是否顯示點擊事件
641
- function setHiddenEvent() {
642
- if (isChildren) {
643
- const parent = collectionsMap.get(dd.parentTitles[0]);
644
- if (parent?.hidden && dd.hidden) {
645
- dialog.infoMessage({ text: '請先開啟顯示第一層分類' });
646
- } else {
647
- triggerHidden();
648
- }
649
- } else {
650
- if (dd.hidden) {
651
- triggerHidden();
652
- } else {
653
- dialog.checkYesOrNot({
654
- text: '若關閉顯示該層分類,子層分類也將會關閉顯示,是否確定要執行?',
655
- callback: bool => bool && triggerHidden(),
656
- });
657
- }
658
- }
659
- }
248
+ const sharedData: any = {};
249
+ loading();
250
+ function refresh(){
251
+ gvc.notifyDataChange(vm_2.id);
252
+ }
253
+ return {
254
+ bind: vm_2.id,
255
+ view: () => {
256
+ if (vm_2.loading) {
257
+ return BgWidget.spinner();
258
+ }
660
259
 
661
- return [
662
- {
663
- key: '標題',
664
- value: html`<div
665
- class="fs-7"
666
- style="min-width: ${document.body.clientWidth > 768
667
- ? 400
668
- : 225}px; padding-left: ${4 + dd.parentTitles.length * 12}px"
669
- >
670
- ${dd.parentTitles.length > 0
671
- ? html`<i class="fa-solid fa-arrow-turn-down-right me-1"></i>`
672
- : ''}
673
- ${dd.title}
674
- </div>`,
675
- },
676
- {
677
- key: '商品數量',
678
- value: html`<span class="fs-7"
679
- >${dd.product_id ? dd.product_id.length : 0}</span
680
- >`,
681
- },
682
- {
683
- key: '是否顯示',
684
- value: html`<i
685
- class="${dd.hidden ? 'fa-solid fa-eye-slash' : 'fa-solid fa-eye'}"
686
- style="cursor: pointer;"
687
- onclick="${gvc.event(() => setHiddenEvent())}"
688
- ></i>`,
689
- stopClick: true,
690
- },
691
- ];
260
+ function loop(root:boolean,array: any[], og_path: string): string {
261
+ function plus(array2:any[]=array){
262
+ const refer = {
263
+ title: '',
264
+ array: [],
265
+ product_id: [],
266
+ parentTitles: [],
267
+ subCollections: [],
268
+ checked: false,
269
+ seo_title: '',
270
+ seo_content: '',
271
+ language_data: {
272
+ 'zh-CN': getEmptyLanguageData(),
273
+ 'zh-TW': getEmptyLanguageData(),
274
+ 'en-US': getEmptyLanguageData(),
275
+ },
276
+ seo_image: '',
277
+ code: '',
278
+ allCollections: vm.allParents,
279
+ };
280
+ BgWidget.settingDialog({
281
+ gvc: gvc,
282
+ title: html` <div class="d-flex align-items-center" style="gap:10px;">
283
+ 新增分類
284
+ <div id="language_btn_place" class=""></div>
285
+ </div>`,
286
+ width: 720,
287
+ height: 720,
288
+ innerHTML: gvc => {
289
+ return ShoppingCollections.editorDetail({
290
+ vm: {
291
+ data: refer,
292
+ } as any,
293
+ type: 'add',
294
+ gvc: gvc,
692
295
  });
693
- }
296
+ },
297
+ footer_html: gvc => {
298
+ return html` <div class="d-flex align-items-center w-100">
299
+ <div class="flex-fill"></div>
300
+ ${[
301
+ BgWidget.cancel(
302
+ gvc.event(() => {
303
+ gvc.closeDialog();
304
+ })
305
+ ),
306
+ BgWidget.save(
307
+ gvc.event(() => {
308
+ console.log(JSON.stringify(refer))
309
+ if(array2.find(dd => dd.title === refer.title)){
310
+ dialog.errorMessage({text:'此分類標籤已存在'})
311
+ }else if(!refer.title){
312
+ dialog.errorMessage({text:'請輸入分類標籤'})
313
+ }else{
314
+ array2.push(refer);
315
+ refresh()
316
+ gvc.closeDialog();
317
+ }
694
318
 
695
- vm.dataList = collections;
696
- vmi.tableData = getDatalist();
697
- } else {
698
- vm.dataList = [];
699
- vmi.tableData = [];
700
- }
701
- vmi.pageSize = 1;
702
- vmi.originalData = vm.dataList;
703
- vmi.loading = false;
704
- vmi.callback();
705
- });
319
+ // array[index] = refer;
320
+ // sharedData[id] = refer;
321
+ // dd = refer;
322
+ // refresh();
323
+
324
+ })
325
+ ),
326
+ ].join('<div class="mx-2"></div>')}
327
+ </div>`;
328
+ },
329
+ });
330
+ }
331
+ return html`
332
+ <ol class="dd-list">
333
+ ${array
334
+ .map((dd, index) => {
335
+ dd.og_path = [og_path, dd.title]
336
+ .filter(dd => {
337
+ return dd;
338
+ })
339
+ .join(' / ');
340
+ const id = gvc.glitter.getUUID();
341
+ sharedData[id] = dd;
342
+
343
+ return html` <li class="dd-item" data-id="${id}" id="${id}">
344
+ ${gvc.bindView(() => {
345
+ const c_vm = {
346
+ id: gvc.glitter.getUUID(),
347
+ };
348
+
349
+ function refresh() {
350
+ gvc.notifyDataChange(c_vm.id);
351
+ }
352
+
353
+ return {
354
+ bind: c_vm.id,
355
+ view: () => {
356
+ return ` ${dd.title}
357
+ <div class="flex-fill"></div>
358
+ ${[
359
+ (() => {
360
+ if(dd.og_path.split(' / ').length===3){
361
+ return ``
362
+ }
363
+ return `<div
364
+ style="cursor: pointer;"
365
+ class="border d-flex align-items-center justify-content-center rounded-3 p-2"
366
+ onclick="${gvc.event((e, event) => {
367
+ event.stopPropagation();
368
+ event.preventDefault();
369
+ dd.array=dd.array || []
370
+ plus(dd.array)
371
+ // vm.data = dd;
372
+ // vm.type = 'replace';
373
+ })}"
374
+ onmousedown="${gvc.event((e, event) => {
375
+ event.stopPropagation();
376
+ event.preventDefault();
377
+ })}"
378
+ ontouchstart="${gvc.event((e, event) => {
379
+ event.stopPropagation();
380
+ event.preventDefault();
381
+ dd.array=dd.array || []
382
+ plus(dd.array)
383
+ })}"
384
+ >
385
+ <i class="fa-regular fa-circle-plus fs-6"></i>
386
+ </div>`;
387
+ })(),
388
+ (() => {
389
+ function next() {
390
+ const refer = JSON.parse(JSON.stringify(dd));
391
+ BgWidget.settingDialog({
392
+ gvc: gvc,
393
+ title: html` <div class="d-flex align-items-center" style="gap:10px;">
394
+ 編輯分類
395
+ <div id="language_btn_place" class=""></div>
396
+ </div>`,
397
+ width: 720,
398
+ height: 720,
399
+ innerHTML: gvc => {
400
+ return ShoppingCollections.editorDetail({
401
+ vm: {
402
+ data: refer,
403
+ } as any,
404
+ type: 'replace',
405
+ gvc: gvc,
406
+ });
407
+ },
408
+ footer_html: gvc => {
409
+ return html` <div class="d-flex align-items-center w-100">
410
+ <div class="flex-fill"></div>
411
+ ${[
412
+ BgWidget.cancel(
413
+ gvc.event(() => {
414
+ gvc.closeDialog();
415
+ })
416
+ ),
417
+ BgWidget.save(
418
+ gvc.event(() => {
419
+ if(array.find(dd => dd.title === refer.title)){
420
+ dialog.errorMessage({text:'此分類標籤已存在'})
421
+ }else if(!refer.title){
422
+ dialog.errorMessage({text:'請輸入分類標籤'})
423
+ }else{
424
+ array[index] = refer;
425
+ sharedData[id] = refer;
426
+ dd = refer;
427
+ saveEvent().then((res)=>{
428
+ if(res){
429
+ gvc.closeDialog();
430
+ }
431
+ });
432
+ }
433
+ })
434
+ ),
435
+ ].join('<div class="mx-2"></div>')}
436
+ </div>`;
437
+ },
438
+ });
439
+ }
440
+
441
+ return `<div
442
+ style="cursor: pointer;"
443
+ class="border d-flex align-items-center justify-content-center rounded-3 p-2"
444
+ onclick="${gvc.event((e, event) => {
445
+ event.stopPropagation();
446
+ event.preventDefault();
447
+ next();
448
+ // vm.data = dd;
449
+ // vm.type = 'replace';
450
+ })}"
451
+ onmousedown="${gvc.event((e, event) => {
452
+ event.stopPropagation();
453
+ event.preventDefault();
454
+ })}"
455
+ ontouchstart="${gvc.event((e, event) => {
456
+ event.stopPropagation();
457
+ event.preventDefault();
458
+ next();
459
+ })}"
460
+ >
461
+ <i class="fa-solid fa-pencil fs-6 "></i>
462
+ </div>`;
463
+ })(),
464
+ gvc.bindView(() => {
465
+ const b_id = gvc.glitter.getUUID();
466
+
467
+ function next() {
468
+ dd.hidden = !dd.hidden;
469
+ gvc.notifyDataChange(b_id);
470
+ }
471
+
472
+ return {
473
+ bind: b_id,
474
+ view: () => {
475
+ return ` <i class="${dd.hidden ? 'fa-solid fa-eye-slash' : 'fa-solid fa-eye'} fs-6 "></i>`;
476
+ },
477
+ divCreate: {
478
+ style: `cursor: pointer;`,
479
+ class: `border d-flex align-items-center justify-content-center rounded-3 p-2`,
480
+ option: [
481
+ {
482
+ key: 'onclick',
483
+ value: gvc.event((e, event) => {
484
+ event.stopPropagation();
485
+ event.preventDefault();
486
+ next();
487
+ }),
488
+ },
489
+ {
490
+ key: 'onmousedown',
491
+ value: gvc.event((e, event) => {
492
+ event.stopPropagation();
493
+ event.preventDefault();
494
+ }),
495
+ },
496
+ {
497
+ key: 'ontouchstart',
498
+ value: gvc.event((e, event) => {
499
+ event.stopPropagation();
500
+ event.preventDefault();
501
+ next();
502
+ }),
503
+ },
504
+ ],
505
+ },
506
+ };
507
+ }),
508
+ (() => {
509
+ function next() {
510
+ dialog.checkYesOrNot({
511
+ text: '是否確認刪除分類?',
512
+ callback: response => {
513
+ if (response) {
514
+ dd.deleted = true;
515
+ document.getElementById(`${id}`)!!.classList.add(`d-none`);
516
+ saveEvent();
517
+ }
518
+ },
519
+ });
520
+ }
521
+
522
+ return ` <div
523
+ style="cursor: pointer;"
524
+ class="border d-flex align-items-center justify-content-center rounded-3 p-2"
525
+ onclick="${gvc.event((e, event) => {
526
+ event.stopPropagation();
527
+ event.preventDefault();
528
+ next();
529
+ })}"
530
+ onmousedown="${gvc.event((e, event) => {
531
+ event.stopPropagation();
532
+ event.preventDefault();
533
+ })}"
534
+ ontouchstart="${gvc.event((e, event) => {
535
+ event.stopPropagation();
536
+ event.preventDefault();
537
+ next();
538
+ })}"
539
+ >
540
+ <i class="fa-regular fa-trash fs-6 text-black-50"></i>
541
+ </div>`;
542
+ })(),
543
+ ].filter((dd)=>{
544
+ return dd
545
+ }).join(` <div class="mx-1"></div>`)}`;
546
+ },
547
+ divCreate: {
548
+ class: `dd-handle d-flex align-items-center`,
549
+ },
550
+ };
551
+ })}
552
+ ${dd.array && dd.array.length ? loop(false,dd.array, `${dd.og_path}`) : []}
553
+ </li>`;
554
+ })
555
+ .join('')}
556
+ <div
557
+ class="${root ? ``:`d-none`}"
558
+ style="cursor:pointer;align-self: stretch; height: 50px; flex-direction: column; justify-content: flex-start; align-items: flex-start; gap: 10px; display: flex"
559
+ onclick="${gvc.event(() => {
560
+ plus()
561
+ })}"
562
+ >
563
+ <div
564
+ style="align-self: stretch; height: 40px; border-radius: 2px; border: 1px #DDDDDD solid; justify-content: center; align-items: center; gap: 6px; display: inline-flex"
565
+ >
566
+ <i class="fa-solid fa-plus" style="color: #3366BB;font-size: 16px; "></i>
567
+ <div
568
+ style="color: #3366BB; font-size: 16px; font-family: Noto Sans; font-weight: 400; word-wrap: break-word"
569
+ >
570
+ 新增主分類
571
+ </div>
572
+ </div>
573
+ </div>
574
+ </ol>
575
+ `;
706
576
  }
707
- });
708
- },
709
- rowClick: (_, index) => {
710
- if (vm.dataList) {
711
- vm.data = vm.dataList[index];
712
- }
713
- vm.type = 'replace';
714
- },
715
- filter: [
716
- {
717
- name: '批量移除',
718
- event: () => {
719
- dialog.checkYesOrNot({
720
- text: '確定要刪除商品分類嗎?<br/>(若包含子分類,也將一併刪除)',
721
- callback: response => {
722
- if (response) {
723
- dialog.dataLoading({ visible: true });
724
- ApiShop.deleteCollections({
725
- data: { data: vm.dataList?.filter(dd => dd.checked) },
726
- token: (window.parent as any).config.token,
727
- }).then(res => {
728
- dialog.dataLoading({ visible: false });
729
- if (res.result) {
730
- vm.query = '';
731
- vm.dataList = undefined;
732
- gvc.notifyDataChange(vm.id);
733
- } else {
734
- dialog.errorMessage({ text: '刪除失敗' });
577
+
578
+ return html` <div class="dd" id="nestable">${loop(true,vm_2.data, '')}</div>`;
579
+ },
580
+ divCreate: {
581
+ class: `px-lg-3 px-1`,
582
+ },
583
+ onCreate: () => {
584
+ gvc.glitter.addStyle(`
585
+ .cf:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; }
586
+ *:first-child+html .cf { zoom: 1; }
587
+
588
+ h1 { font-size: 1.75em; margin: 0 0 0.6em 0; }
589
+
590
+ a { color: #2996cc; }
591
+ a:hover { text-decoration: none; }
592
+
593
+ p { line-height: 1.5em; }
594
+ .small { color: #666; font-size: 0.875em; }
595
+ .large { font-size: 1.25em; }
596
+
597
+ /**
598
+ * Nestable
599
+ */
600
+
601
+ .dd { position: relative; display: block; margin: 0; padding: 0; list-style: none; font-size: 13px; line-height: 20px; }
602
+
603
+ .dd-list { display: block; position: relative; margin: 0; padding: 0; list-style: none; }
604
+ .dd-list .dd-list { padding-left: 30px; }
605
+ .dd-collapsed .dd-list { display: none; }
606
+
607
+ .dd-item,
608
+ .dd-empty,
609
+ .dd-placeholder { display: block; position: relative; margin: 0; padding: 0; min-height: 20px; font-size: 13px; line-height: 20px; }
610
+
611
+ .dd-handle { display: block; height: 40px; margin: 5px 0; padding: 5px 10px; color: #333; text-decoration: none; font-weight: bold; border: 1px solid #ccc;
612
+ background: #fafafa;
613
+ background: -webkit-linear-gradient(top, #fafafa 0%, #eee 100%);
614
+ background: -moz-linear-gradient(top, #fafafa 0%, #eee 100%);
615
+ background: linear-gradient(top, #fafafa 0%, #eee 100%);
616
+ -webkit-border-radius: 3px;
617
+ border-radius: 3px;
618
+ box-sizing: border-box; -moz-box-sizing: border-box;
619
+ }
620
+ .dd-handle:hover { color: #2ea8e5; background: #fff; }
621
+
622
+ .dd-item > button { display: block; position: relative; cursor: pointer; float: left; width: 25px; height: 30px; margin: 5px 0; padding: 0; text-indent: 100%; white-space: nowrap; overflow: hidden; border: 0; background: transparent; font-size: 20px; line-height: 1; text-align: center; font-weight: bold; }
623
+ .dd-item > button:before { content: '+'; display: block; position: absolute; width: 100%; text-align: center; text-indent: 0; }
624
+ .dd-item > button[data-action="collapse"]:before { content: '-'; }
625
+
626
+ .dd-placeholder,
627
+ .dd-empty { margin: 5px 0; padding: 0; min-height: 30px; background: #f2fbff; border: 1px dashed #b6bcbf; box-sizing: border-box; -moz-box-sizing: border-box; }
628
+ .dd-empty { border: 1px dashed #bbb; min-height: 100px; background-color: #e5e5e5;
629
+ background-image: -webkit-linear-gradient(45deg, #fff 25%, transparent 25%, transparent 75%, #fff 75%, #fff),
630
+ -webkit-linear-gradient(45deg, #fff 25%, transparent 25%, transparent 75%, #fff 75%, #fff);
631
+ background-image: -moz-linear-gradient(45deg, #fff 25%, transparent 25%, transparent 75%, #fff 75%, #fff),
632
+ -moz-linear-gradient(45deg, #fff 25%, transparent 25%, transparent 75%, #fff 75%, #fff);
633
+ background-image: linear-gradient(45deg, #fff 25%, transparent 25%, transparent 75%, #fff 75%, #fff),
634
+ linear-gradient(45deg, #fff 25%, transparent 25%, transparent 75%, #fff 75%, #fff);
635
+ background-size: 60px 60px;
636
+ background-position: 0 0, 30px 30px;
637
+ }
638
+
639
+ .dd-dragel { position: absolute; pointer-events: none; z-index: 9999; }
640
+ .dd-dragel > .dd-item .dd-handle { margin-top: 0; }
641
+ .dd-dragel .dd-handle {
642
+ -webkit-box-shadow: 2px 4px 6px 0 rgba(0,0,0,.1);
643
+ box-shadow: 2px 4px 6px 0 rgba(0,0,0,.1);
644
+ }
645
+
646
+ /**
647
+ * Nestable Extras
648
+ */
649
+
650
+ .nestable-lists { display: block; clear: both; padding: 30px 0; width: 100%; border: 0; border-top: 2px solid #ddd; border-bottom: 2px solid #ddd; }
651
+
652
+ #nestable-menu { padding: 0; margin: 20px 0; }
653
+
654
+ #nestable-output,
655
+ #nestable2-output { width: 100%; height: 7em; font-size: 0.75em; line-height: 1.333333em; font-family: Consolas, monospace; padding: 5px; box-sizing: border-box; -moz-box-sizing: border-box; }
656
+
657
+ #nestable2 .dd-handle {
658
+ color: #fff;
659
+ border: 1px solid #999;
660
+ background: #bbb;
661
+ background: -webkit-linear-gradient(top, #bbb 0%, #999 100%);
662
+ background: -moz-linear-gradient(top, #bbb 0%, #999 100%);
663
+ background: linear-gradient(top, #bbb 0%, #999 100%);
664
+ }
665
+ #nestable2 .dd-handle:hover { background: #bbb; }
666
+ #nestable2 .dd-item > button:before { color: #fff; }
667
+
668
+ @media only screen and (min-width: 700px) {
669
+
670
+ .dd { width: 100%; }
671
+ .dd + .dd { margin-left: 2%; }
672
+
673
+ }
674
+
675
+ .dd-hover > .dd-handle { background: #2ea8e5 !important; }
676
+
677
+ /**
678
+ * Nestable Draggable Handles
679
+ */
680
+
681
+ .dd3-content { display: block; height: 30px; margin: 5px 0; padding: 5px 10px 5px 40px; color: #333; text-decoration: none; font-weight: bold; border: 1px solid #ccc;
682
+ background: #fafafa;
683
+ background: -webkit-linear-gradient(top, #fafafa 0%, #eee 100%);
684
+ background: -moz-linear-gradient(top, #fafafa 0%, #eee 100%);
685
+ background: linear-gradient(top, #fafafa 0%, #eee 100%);
686
+ -webkit-border-radius: 3px;
687
+ border-radius: 3px;
688
+ box-sizing: border-box; -moz-box-sizing: border-box;
689
+ }
690
+ .dd3-content:hover { color: #2ea8e5; background: #fff; }
691
+
692
+ .dd-dragel > .dd3-item > .dd3-content { margin: 0; }
693
+
694
+ .dd3-item > button { margin-left: 30px; }
695
+
696
+ .dd3-handle { position: absolute; margin: 0; left: 0; top: 0; cursor: pointer; width: 30px; text-indent: 100%; white-space: nowrap; overflow: hidden;
697
+ border: 1px solid #aaa;
698
+ background: #ddd;
699
+ background: -webkit-linear-gradient(top, #ddd 0%, #bbb 100%);
700
+ background: -moz-linear-gradient(top, #ddd 0%, #bbb 100%);
701
+ background: linear-gradient(top, #ddd 0%, #bbb 100%);
702
+ border-top-right-radius: 0;
703
+ border-bottom-right-radius: 0;
704
+ }
705
+ .dd3-handle:before { content: '≡'; display: block; position: absolute; left: 0; top: 3px; width: 100%; text-align: center; text-indent: 0; color: #fff; font-size: 20px; font-weight: normal; }
706
+ .dd3-handle:hover { background: #ddd; }
707
+
708
+ /**
709
+ * Socialite
710
+ */
711
+
712
+ .socialite { display: block; float: left; height: 35px; }
713
+ `);
714
+ gvc.glitter.addMtScript(
715
+ [`${gvc.glitter.root_path}/jslib/nestable/jquery.nestable.js`],
716
+ () => {
717
+ const updateOutput = function () {
718
+ const outPutJson = ($('#nestable') as any).nestable('serialize');
719
+
720
+ function loop(array: any[], new_path: string) {
721
+ return (array ?? []).map(dd => {
722
+ const og = sharedData[dd.id];
723
+ og.new_path = [new_path, og.title]
724
+ .filter(dd => {
725
+ return dd;
726
+ })
727
+ .join(' / ');
728
+ if (dd.children) {
729
+ dd.children = loop(dd.children, og.new_path);
735
730
  }
731
+ og.array = dd.children;
732
+
733
+ return og;
736
734
  });
737
735
  }
738
- },
739
- });
740
- },
736
+
737
+ const op = loop(outPutJson, '');
738
+ console.log(`output-data`, op);
739
+ return op;
740
+ };
741
+ getSaveData = updateOutput;
742
+ //@ts-ignore
743
+ $('#nestable')
744
+ //@ts-ignore
745
+ .nestable({
746
+ group: 1,
747
+ maxDepth: 3
748
+ })
749
+ .on('change', updateOutput);
750
+ },
751
+ () => {}
752
+ );
741
753
  },
742
- ],
743
- hiddenPageSplit: true,
754
+ };
744
755
  }),
756
+ `<div class="update-bar-container">
757
+ ${BgWidget.save(
758
+ gvc.event(() => {
759
+ const dialog = new ShareDialog(gvc.glitter);
760
+ dialog.checkYesOrNot({
761
+ text: '是否確認儲存?',
762
+ callback: async response => {
763
+ if (response) {
764
+ await saveEvent()
765
+ }
766
+ },
767
+ });
768
+ })
769
+ )}
770
+ </div>`,
745
771
  ].join('')
746
772
  )
747
773
  )}
@@ -882,648 +908,375 @@ export class ShoppingCollections {
882
908
  'en-US': getEmptyLanguageData(),
883
909
  };
884
910
  }
885
-
911
+ vm.data.product_id=(vm.data.product_id ?? []).map((dd)=>{
912
+ return parseInt(dd as any,10)
913
+ })
886
914
  const language_data: LanguageData = (vm.data.language_data as any)[select_lan];
887
915
  const prefixURL = `https://${(window.parent as any).glitter.share.editorViewModel.domain}/${Language.getLanguageLinkPrefix(true, select_lan)}collections/`;
888
-
916
+ setTimeout(() => {
917
+ (window.parent as any).document.querySelector('#language_btn_place')!!.innerHTML =
918
+ `<div class="title-container">
919
+ <div class="flex-fill"></div>
920
+ <div class="d-flex align-items-center gap-2">
921
+ ${BgWidget.grayButton(
922
+ html` <div class="d-flex align-items-center gap-2">
923
+ <i class="fa-duotone fa-solid fa-earth-americas"></i>${Language.getLanguageText({
924
+ local: true,
925
+ compare: select_lan,
926
+ })}
927
+ </div>`,
928
+ gvc.event(() => {
929
+ BgWidget.settingDialog({
930
+ gvc: gvc,
931
+ innerHTML: (gvc: GVC) => {
932
+ return gvc.bindView(
933
+ (() => {
934
+ const id = gvc.glitter.getUUID();
935
+ return {
936
+ bind: id,
937
+ view: () => {
938
+ return html` <div
939
+ style="position: relative; word-break: break-all; white-space: normal;"
940
+ >
941
+ ${BgWidget.grayNote('前往商店設定->商店訊息中,設定支援的語言。')}
942
+ ${gvc.bindView(() => {
943
+ return {
944
+ bind: glitter.getUUID(),
945
+ view: () => {
946
+ const sup = [
947
+ {
948
+ key: 'en-US',
949
+ value: '英文',
950
+ },
951
+ {
952
+ key: 'zh-CN',
953
+ value: '簡體中文',
954
+ },
955
+ {
956
+ key: 'zh-TW',
957
+ value: '繁體中文',
958
+ },
959
+ ]
960
+ .filter(dd => {
961
+ return (
962
+ window.parent as any
963
+ ).store_info.language_setting.support.includes(dd.key);
964
+ })
965
+ .sort(dd => {
966
+ return dd.key === select_lan ? -1 : 1;
967
+ });
968
+
969
+ return html` <div
970
+ class="d-flex mt-3 flex-wrap align-items-center justify-content-center"
971
+ style="gap:15px;"
972
+ >
973
+ ${sup
974
+ .map(dd => {
975
+ return html`
976
+ <div
977
+ class="px-3 py-1 text-white position-relative d-flex align-items-center justify-content-center"
978
+ style="border-radius: 20px;background: #393939;cursor: pointer;width:100px;"
979
+ onclick="${gvc.event(() => {
980
+ select_lan = dd.key;
981
+ gvc.closeDialog();
982
+ refresh();
983
+ })}"
984
+ >
985
+ ${dd.value}
986
+ <div
987
+ class="position-absolute text-white rounded-2 px-2 d-flex align-items-center rounded-3 ${dd.key !==
988
+ select_lan
989
+ ? 'd-none'
990
+ : ''}"
991
+ style="top: -12px;right: -10px; height:20px;font-size: 11px;background: #ff6c02;"
992
+ >
993
+ 已選擇
994
+ </div>
995
+ </div>
996
+ `;
997
+ })
998
+ .join('')}
999
+ </div>`;
1000
+ },
1001
+ };
1002
+ })}
1003
+ </div>`;
1004
+ },
1005
+ };
1006
+ })()
1007
+ );
1008
+ },
1009
+ title: '切換語系',
1010
+ footer_html: gvc => {
1011
+ return '';
1012
+ },
1013
+ width: 300,
1014
+ });
1015
+ })
1016
+ )}
1017
+ ${
1018
+ vm.type === 'add'
1019
+ ? BgWidget.grayButton(
1020
+ '代入現有分類',
1021
+ gvc.event(() => {
1022
+ BgProduct.collectionsDialog({
1023
+ gvc: gvc,
1024
+ default: [],
1025
+ callback: value => {
1026
+ const data = vm.dataList?.find(
1027
+ item => [...item.parentTitles, item.title].join(' / ') === value[0]
1028
+ );
1029
+ if (data) {
1030
+ vm.data = data;
1031
+ vm.cloneTarget = structuredClone(data);
1032
+ }
1033
+ gvc.notifyDataChange(viewID);
1034
+ },
1035
+ single: true,
1036
+ });
1037
+ })
1038
+ )
1039
+ : ''
1040
+ }
1041
+ </div>
1042
+ </div>`;
1043
+ }, 100);
889
1044
  return BgWidget.container(
890
1045
  [
891
- // 上層導覽
892
- html` <div class="title-container">
893
- ${BgWidget.goBack(
894
- gvc.event(() => {
895
- vm.type = 'list';
896
- })
897
- )}
898
- ${BgWidget.title(obj.type === 'add' ? '新增分類' : '編輯分類')}
899
- <div class="flex-fill"></div>
900
- <div class="d-flex align-items-center gap-2">
901
- ${BgWidget.grayButton(
902
- html` <div class="d-flex align-items-center gap-2">
903
- <i class="fa-duotone fa-solid fa-earth-americas"></i>${Language.getLanguageText({
904
- local: true,
905
- compare: select_lan,
906
- })}
907
- </div>`,
908
- gvc.event(() => {
909
- BgWidget.settingDialog({
910
- gvc: gvc,
911
- innerHTML: (gvc: GVC) => {
912
- return gvc.bindView(
913
- (() => {
914
- const id = gvc.glitter.getUUID();
915
- return {
916
- bind: id,
917
- view: () => {
918
- return html` <div
919
- style="position: relative; word-break: break-all; white-space: normal;"
920
- >
921
- ${BgWidget.grayNote('前往商店設定->商店訊息中,設定支援的語言。')}
922
- ${gvc.bindView(() => {
923
- return {
924
- bind: glitter.getUUID(),
925
- view: () => {
926
- const sup = [
927
- {
928
- key: 'en-US',
929
- value: '英文',
930
- },
931
- {
932
- key: 'zh-CN',
933
- value: '簡體中文',
934
- },
935
- {
936
- key: 'zh-TW',
937
- value: '繁體中文',
938
- },
939
- ]
940
- .filter(dd => {
941
- return (
942
- window.parent as any
943
- ).store_info.language_setting.support.includes(dd.key);
944
- })
945
- .sort(dd => {
946
- return dd.key === select_lan ? -1 : 1;
947
- });
948
-
949
- return html` <div
950
- class="d-flex mt-3 flex-wrap align-items-center justify-content-center"
951
- style="gap:15px;"
952
- >
953
- ${sup
954
- .map(dd => {
955
- return html`
956
- <div
957
- class="px-3 py-1 text-white position-relative d-flex align-items-center justify-content-center"
958
- style="border-radius: 20px;background: #393939;cursor: pointer;width:100px;"
959
- onclick="${gvc.event(() => {
960
- select_lan = dd.key;
961
- gvc.closeDialog();
962
- refresh();
963
- })}"
964
- >
965
- ${dd.value}
966
- <div
967
- class="position-absolute text-white rounded-2 px-2 d-flex align-items-center rounded-3 ${dd.key !==
968
- select_lan
969
- ? 'd-none'
970
- : ''}"
971
- style="top: -12px;right: -10px; height:20px;font-size: 11px;background: #ff6c02;"
972
- >
973
- 已選擇
974
- </div>
975
- </div>
976
- `;
977
- })
978
- .join('')}
979
- </div>`;
980
- },
981
- };
982
- })}
983
- </div>`;
984
- },
985
- };
986
- })()
987
- );
988
- },
989
- title: '切換語系',
990
- footer_html: gvc => {
991
- return '';
992
- },
993
- width: 300,
994
- });
995
- })
996
- )}
997
- ${vm.type === 'add'
998
- ? BgWidget.grayButton(
999
- '代入現有分類',
1000
- gvc.event(() => {
1001
- BgProduct.collectionsDialog({
1002
- gvc: gvc,
1003
- default: [],
1004
- callback: value => {
1005
- const data = vm.dataList?.find(
1006
- item => [...item.parentTitles, item.title].join(' / ') === value[0]
1007
- );
1008
- if (data) {
1009
- vm.data = data;
1010
- vm.cloneTarget = structuredClone(data);
1011
- }
1012
- gvc.notifyDataChange(viewID);
1013
- },
1014
- single: true,
1015
- });
1016
- })
1017
- )
1018
- : ''}
1019
- </div>
1020
- </div>`,
1021
- // 左右容器
1022
- BgWidget.container1x2(
1023
- {
1024
- // 左容器
1025
- html: [
1026
- BgWidget.mainCard(
1027
- html` <div class="tx_700" style="margin-bottom: 12px">分類標籤 ${BgWidget.requiredStar()}</div>
1028
- ${EditorElem.editeInput({
1029
- gvc: gvc,
1030
- title: '',
1031
- default: vm.data.title,
1032
- placeHolder: '請輸入分類標籤',
1033
- callback: text => {
1034
- vm.data.title = text;
1035
- },
1036
- })}`
1037
- ),
1038
- BgWidget.mainCard(
1039
- html` <div class="d-flex flex-column" style="margin-bottom: 12px; gap:5px;">
1040
- <div class="tx_700">前台分類顯示名稱 ${BgWidget.languageInsignia(select_lan)}</div>
1041
- ${BgWidget.grayNote('未設定則參照分類標籤顯示')}
1042
- </div>
1043
- ${EditorElem.editeInput({
1044
- gvc: gvc,
1045
- title: '',
1046
- default: language_data.title,
1047
- placeHolder: vm.data.title || '預設為「分類標籤」輸入值',
1048
- callback: text => {
1049
- language_data.title = text;
1050
- if (language_data.seo.domain === '') {
1051
- language_data.seo.domain = language_data.title;
1052
- gvc.notifyDataChange(domainID);
1053
- }
1054
- },
1055
- })}`
1056
- ),
1057
- gvc.bindView(() => {
1058
- const viewID = gvc.glitter.getUUID();
1059
- return {
1060
- bind: viewID,
1061
- view: () => {
1062
- return BgWidget.mainCard(
1063
- [
1064
- html` <div class="tx_700 mb-2">
1065
- 連結網址 ${BgWidget.requiredStar()} ${BgWidget.languageInsignia(select_lan)}
1066
- </div>`,
1067
- gvc.bindView({
1068
- bind: domainID,
1069
- view: () => {
1070
- return html` <div
1071
- class="${document.body.clientWidth < 800
1072
- ? 'w-100'
1073
- : ''} justify-content-start justify-content-lg-center"
1074
- style="padding: 9px 18px;background: #EAEAEA; justify-content: center; align-items: center; gap: 5px; display: flex"
1075
- >
1076
- <div
1077
- style="text-align: right; color: #393939; font-size: 16px; font-family: Noto Sans; font-weight: 400; word-wrap: break-word"
1078
- >
1079
- ${prefixURL}
1080
- </div>
1081
- </div>
1082
- <input
1083
- class="flex-fill ${document.body.clientWidth < 800 ? `w-100` : ``}"
1084
- style="border:none;background:none;text-align: start; color: #393939; font-size: 16px; font-family: Noto Sans; font-weight: 400; word-wrap: break-word; ${document
1085
- .body.clientWidth > 768
1086
- ? ''
1087
- : 'padding: 9px 18px;'}"
1088
- placeholder="請輸入連結網址"
1089
- value="${language_data.seo.domain || ''}"
1090
- onchange="${gvc.event(e => {
1091
- let text = e.value;
1092
- if (text.length > 0 && !CheckInput.isChineseEnglishNumberHyphen(text)) {
1093
- dialog.infoMessage({ text: '連結僅限使用中英文數字與連接號' });
1094
- } else {
1095
- language_data.seo.domain = text;
1096
- }
1097
- gvc.notifyDataChange(viewID);
1098
- })}"
1099
- />`;
1100
- },
1101
- divCreate: {
1102
- style: `width: 100%; justify-content: flex-start; align-items: center; display: inline-flex;border:1px solid #EAEAEA;border-radius: 10px;overflow: hidden; ${
1103
- document.body.clientWidth > 768 ? 'gap: 18px;' : 'flex-direction: column; gap: 0px;'
1104
- }`,
1105
- },
1106
- }),
1107
- html` <div class="mt-2 mb-1">
1108
- <span class="tx_normal me-1">網址預覽</span>
1109
- ${BgWidget.greenNote(
1110
- prefixURL + language_data.seo.domain,
1111
- gvc.event(() => {
1112
- gvc.glitter.openNewTab(prefixURL + (language_data.seo.domain ?? ''));
1113
- })
1114
- )}
1115
- </div>`,
1116
- ].join(BgWidget.mbContainer(12))
1117
- );
1118
- },
1119
- divCreate: {
1120
- class: `${gvc.glitter.ut.frSize({ sm: '' }, 'p-0')}`,
1121
- },
1122
- };
1123
- }),
1124
- BgWidget.mainCard(
1125
- (() => {
1126
- const pvm = {
1127
- id: gvc.glitter.getUUID(),
1128
- loading: true,
1129
- dataList: vm.data.product_id,
1130
- productList: [],
1131
- };
1132
- return html`
1133
- <div class="d-flex flex-column">
1134
- <div class="d-flex align-items-center" style="justify-content: space-between;">
1135
- <div class="tx_700" style="margin-bottom: 12px">商品</div>
1136
- ${BgWidget.grayButton(
1137
- '選擇商品',
1138
- gvc.event(() => {
1139
- BgProduct.productsDialog({
1140
- gvc: gvc,
1141
- default: vm.data.product_id,
1142
- callback: value => {
1143
- pvm.dataList = value;
1144
- vm.data.product_id = value;
1145
- pvm.loading = true;
1146
- gvc.notifyDataChange(pvm.id);
1147
- },
1148
- });
1149
- })
1150
- )}
1151
- </div>
1152
- ${gvc.bindView({
1153
- bind: pvm.id,
1154
- view: () => {
1155
- if (pvm.loading) {
1156
- return '資料載入中';
1157
- }
1158
- if (pvm.productList.length === 0) {
1159
- return '目前無選取任何商品';
1160
- }
1161
- return gvc.map(
1162
- pvm.productList.map((opt: OptionsItem, index: number) => {
1163
- return html` <div
1164
- class="form-check-label c_updown_label"
1165
- style="display: flex; align-items: center; min-height: 60px; gap: 8px;"
1166
- >
1167
- <span class="tx_normal" style="min-width: 30px;">${index + 1}.</span>
1168
- ${BgWidget.validImageBox({ gvc, image: opt.image, width: 40 })}
1169
- <span class="tx_normal">${opt.value}</span>
1170
- ${opt.note ? html` <span class="tx_gray_12 ms-2">${opt.note}</span> ` : ''}
1171
- </div>`;
1172
- })
1173
- );
1174
- },
1175
- onCreate: () => {
1176
- if (pvm.loading) {
1177
- if (pvm.dataList.length === 0) {
1178
- pvm.productList = [];
1179
- pvm.loading = false;
1180
- setTimeout(() => gvc.notifyDataChange(pvm.id), 100);
1046
+ [
1047
+ html` <div class="tx_700" style="margin-bottom: 12px">分類標籤 ${BgWidget.requiredStar()}</div>
1048
+ ${EditorElem.editeInput({
1049
+ gvc: gvc,
1050
+ title: '',
1051
+ default: vm.data.title,
1052
+ placeHolder: '請輸入分類標籤',
1053
+ callback: text => {
1054
+ vm.data.title = text;
1055
+ },
1056
+ })}`,
1057
+ html` <div class="d-flex flex-column" style="margin-bottom: 12px; gap:5px;">
1058
+ <div class="tx_700">前台分類顯示名稱 ${BgWidget.languageInsignia(select_lan)}</div>
1059
+ ${BgWidget.grayNote('未設定則參照分類標籤顯示')}
1060
+ </div>
1061
+ ${EditorElem.editeInput({
1062
+ gvc: gvc,
1063
+ title: '',
1064
+ default: language_data.title,
1065
+ placeHolder: vm.data.title || '預設為「分類標籤」輸入值',
1066
+ callback: text => {
1067
+ language_data.title = text;
1068
+ if (language_data.seo.domain === '') {
1069
+ language_data.seo.domain = language_data.title;
1070
+ gvc.notifyDataChange(domainID);
1071
+ }
1072
+ },
1073
+ })}`,
1074
+ gvc.bindView(() => {
1075
+ const viewID = gvc.glitter.getUUID();
1076
+ return {
1077
+ bind: viewID,
1078
+ view: () => {
1079
+ return [
1080
+ html` <div class="tx_700 mb-2">
1081
+ 連結網址 ${BgWidget.requiredStar()} ${BgWidget.languageInsignia(select_lan)}
1082
+ </div>`,
1083
+ gvc.bindView({
1084
+ bind: domainID,
1085
+ view: () => {
1086
+ return html` <div
1087
+ class="${document.body.clientWidth < 800
1088
+ ? 'w-100'
1089
+ : ''} justify-content-start justify-content-lg-center"
1090
+ style="padding: 9px 18px;background: #EAEAEA; justify-content: center; align-items: center; gap: 5px; display: flex"
1091
+ >
1092
+ <div
1093
+ style="text-align: right; color: #393939; font-size: 16px; font-family: Noto Sans; font-weight: 400; word-wrap: break-word"
1094
+ >
1095
+ ${prefixURL}
1096
+ </div>
1097
+ </div>
1098
+ <input
1099
+ class="flex-fill ${document.body.clientWidth < 800 ? `w-100` : ``}"
1100
+ style="border:none;background:none;text-align: start; color: #393939; font-size: 16px; font-family: Noto Sans; font-weight: 400; word-wrap: break-word; ${document
1101
+ .body.clientWidth > 768
1102
+ ? ''
1103
+ : 'padding: 9px 18px;'}"
1104
+ placeholder="請輸入連結網址"
1105
+ value="${language_data.seo.domain || ''}"
1106
+ onchange="${gvc.event(e => {
1107
+ let text = e.value;
1108
+ if (text.length > 0 && !CheckInput.isChineseEnglishNumberHyphen(text)) {
1109
+ dialog.infoMessage({ text: '連結僅限使用中英文數字與連接號' });
1181
1110
  } else {
1182
- ApiShop.getProduct({
1183
- page: 0,
1184
- limit: 99999,
1185
- id_list: pvm.dataList.join(','),
1186
- }).then(data => {
1187
- pvm.productList = data.response.data.map(
1188
- (product: {
1189
- content: {
1190
- id: number;
1191
- title: string;
1192
- preview_image: string[];
1193
- };
1194
- }) => {
1195
- return {
1196
- key: product.content.id,
1197
- value: product.content.title,
1198
- image: product.content.preview_image[0] ?? BgWidget.noImageURL,
1199
- };
1200
- }
1201
- );
1202
- pvm.loading = false;
1203
- gvc.notifyDataChange(pvm.id);
1204
- });
1111
+ language_data.seo.domain = text;
1205
1112
  }
1206
- }
1113
+ gvc.notifyDataChange(viewID);
1114
+ })}"
1115
+ />`;
1116
+ },
1117
+ divCreate: {
1118
+ style: `width: 100%; justify-content: flex-start; align-items: center; display: inline-flex;border:1px solid #EAEAEA;border-radius: 10px;overflow: hidden; ${
1119
+ document.body.clientWidth > 768 ? 'gap: 18px;' : 'flex-direction: column; gap: 0px;'
1120
+ }`,
1121
+ },
1122
+ }),
1123
+ html` <div class="mt-2 mb-1">
1124
+ <span class="tx_normal me-1">網址預覽</span>
1125
+ ${BgWidget.greenNote(
1126
+ prefixURL + language_data.seo.domain,
1127
+ gvc.event(() => {
1128
+ gvc.glitter.openNewTab(prefixURL + (language_data.seo.domain ?? ''));
1129
+ })
1130
+ )}
1131
+ </div>`,
1132
+ ].join(BgWidget.mbContainer(12));
1133
+ },
1134
+ divCreate: {
1135
+ class: `${gvc.glitter.ut.frSize({ sm: '' }, 'p-0')}`,
1136
+ },
1137
+ };
1138
+ }),
1139
+ (() => {
1140
+ const pvm = {
1141
+ id: gvc.glitter.getUUID(),
1142
+ loading: true,
1143
+ dataList: vm.data.product_id,
1144
+ productList: [],
1145
+ };
1146
+ return html`
1147
+ <div class="d-flex flex-column">
1148
+ <div class="d-flex align-items-center" style="justify-content: space-between;">
1149
+ <div class="tx_700" style="margin-bottom: 12px">商品</div>
1150
+ ${BgWidget.grayButton(
1151
+ '選擇商品',
1152
+ gvc.event(() => {
1153
+ BgProduct.productsDialog({
1154
+ gvc: gvc,
1155
+ default: pvm.dataList,
1156
+ callback: value => {
1157
+ pvm.dataList = value;
1158
+ vm.data.product_id = value;
1159
+ pvm.loading = true;
1160
+ gvc.notifyDataChange(pvm.id);
1207
1161
  },
1208
- })}
1209
- </div>
1210
- `;
1211
- })()
1212
- ),
1213
- BgWidget.mainCard(
1214
- [
1215
- html` <div style="font-weight: 700;" class="mb-3">
1216
- 搜尋引擎列表 ${BgWidget.languageInsignia(select_lan, 'margin-left:5px;')}
1217
- </div>
1218
- <div class="tx_normal fw-normal" style="margin: 18px 0 8px;">SEO 標題</div>
1219
- ${EditorElem.editeInput({
1220
- gvc: gvc,
1221
- title: '',
1222
- default: language_data.seo.title ?? '',
1223
- placeHolder: '請輸入 SEO 標題',
1224
- callback: text => {
1225
- language_data.seo.title = text;
1226
- },
1227
- })}`,
1228
- ,
1229
- html` <div class="tx_normal fw-normal">SEO 描述</div>
1230
- ${EditorElem.editeText({
1231
- gvc: gvc,
1232
- title: '',
1233
- default: language_data.seo.content ?? '',
1234
- placeHolder: '請輸入 SEO 描述',
1235
- callback: text => {
1236
- language_data.seo.content = text;
1237
- },
1238
- })}`,
1239
- ,
1240
- html` <div class="tx_normal fw-normal">SEO 圖片</div>
1241
- ${EditorElem.uploadImageContainer({
1242
- gvc: gvc,
1243
- title: '',
1244
- def: vm.data.seo_image ?? '',
1245
- callback: text => {
1246
- vm.data.seo_image = text;
1247
- },
1248
- })}`,
1249
- ,
1250
- ].join(BgWidget.mbContainer(10))
1251
- ),
1252
- ].join(BgWidget.mbContainer(24)),
1253
- ratio: 75,
1254
- },
1255
- {
1256
- // 右容器
1257
- html: gvc.bindView(
1258
- (() => {
1259
- const summaryId = glitter.getUUID();
1260
- return {
1261
- bind: summaryId,
1162
+ });
1163
+ })
1164
+ )}
1165
+ </div>
1166
+ ${gvc.bindView({
1167
+ bind: pvm.id,
1262
1168
  view: () => {
1263
- function isUndefinedOption(key: string) {
1264
- return !key || ShoppingCollections.undefinedOption === key;
1169
+ if (pvm.loading && pvm.dataList && pvm.dataList.length) {
1170
+ return '資料載入中';
1265
1171
  }
1266
-
1267
- function firstParentView() {
1268
- return [
1269
- html` <div class="tx_700">第一層</div>`,
1270
- vm.type === 'add' && isUndefinedOption(vm.data.parentTitles[0])
1271
- ? BgWidget.grayNote('若未選取項目,則為第一層分類')
1272
- : '',
1273
- BgWidget.select({
1274
- gvc: gvc,
1275
- callback: text => {
1276
- vm.data.parentTitles[0] = text;
1277
- gvc.notifyDataChange(summaryId);
1278
- },
1279
- default: vm.data.parentTitles[0] ?? '',
1280
- options: vm.data.allCollections.map((item: string) => {
1281
- return { key: item, value: item };
1282
- }),
1283
- style: 'margin: 8px 0;',
1284
- readonly: vm.type === 'replace',
1285
- }),
1286
- BgWidget.mbContainer(12),
1287
- ].join('');
1172
+ if (pvm.productList.length === 0 || !pvm.dataList.length) {
1173
+ return '目前無選取任何商品';
1288
1174
  }
1289
-
1290
- function secondParentView(subs: string[]) {
1291
- return [
1292
- html` <div class="tx_700">第二層</div>`,
1293
- vm.type === 'add' && isUndefinedOption(vm.data.parentTitles[1])
1294
- ? BgWidget.grayNote('若未選取項目,則為第二層分類')
1295
- : '',
1296
- BgWidget.select({
1297
- gvc: gvc,
1298
- callback: text => {
1299
- vm.data.parentTitles[1] = text;
1300
- gvc.notifyDataChange(summaryId);
1301
- },
1302
- default: vm.data.parentTitles[1] ?? '',
1303
- options: [ShoppingCollections.undefinedOption, ...subs].map((item: string) => {
1304
- return { key: item, value: item };
1305
- }),
1306
- style: 'margin: 8px 0;',
1307
- readonly: vm.type === 'replace',
1308
- }),
1309
- ].join('');
1310
- }
1311
-
1312
- function editSubCollection() {
1313
- const id = gvc.glitter.getUUID();
1314
-
1315
- if (vm.data.parentTitles.length === 2) {
1316
- return '';
1317
- }
1318
-
1319
- return [
1320
- html` <div class="tx_700" style="margin-bottom: 12px">子分類</div>`,
1321
- !vm.data.subCollections || vm.data.subCollections.length === 0
1322
- ? '尚未建立子分類'
1323
- : gvc.bindView({
1324
- bind: id,
1325
- view: () =>
1326
- vm.data.subCollections
1327
- .map((item: string) => {
1328
- return html` <div
1329
- class="d-flex align-items-center justify-content-between mt-2"
1330
- >
1331
- ${item}<i
1332
- class="fa-regular fa-trash cursor_pointer"
1333
- onclick="${gvc.event(() => {
1334
- vm.data.subCollections = vm.data.subCollections.filter(
1335
- (sub: string) => item !== sub
1336
- );
1337
- gvc.notifyDataChange(id);
1338
- })}"
1339
- ></i>
1340
- </div>`;
1341
- })
1342
- .join(''),
1343
- }),
1344
- ].join('');
1345
- }
1346
-
1347
- function levelSetting() {
1348
- const parentTitles = Array.isArray(vm.data.parentTitles) ? vm.data.parentTitles : [];
1349
- const parentTab = vm.dataList?.find(item => item.title === parentTitles[0]);
1350
- const parentSubs =
1351
- parentTab && Array.isArray(parentTab.subCollections) ? parentTab.subCollections : [];
1352
-
1353
- if (vm.type === 'add') {
1354
- return [
1355
- firstParentView(),
1356
- parentSubs.length > 0
1357
- ? secondParentView(parentSubs.filter((item: string) => item !== vm.data.title))
1358
- : '',
1359
- ].join('');
1360
- }
1361
-
1362
- if (vm.type === 'replace' && parentTitles.length > 0) {
1363
- return [
1364
- firstParentView(),
1365
- parentTitles[1] && parentSubs.length > 0 ? secondParentView(parentSubs) : '',
1366
- editSubCollection(),
1367
- ].join('');
1368
- }
1369
-
1370
- return editSubCollection();
1371
- }
1372
-
1373
- return [BgWidget.summaryCard(levelSetting())].join(BgWidget.mbContainer(24));
1175
+ return gvc.map(
1176
+ pvm.productList.map((opt: OptionsItem, index: number) => {
1177
+ return html` <div
1178
+ class="form-check-label c_updown_label"
1179
+ style="display: flex; align-items: center; min-height: 60px; gap: 8px;"
1180
+ >
1181
+ <span class="tx_normal" style="min-width: 30px;">${index + 1}.</span>
1182
+ ${BgWidget.validImageBox({ gvc, image: opt.image, width: 40 })}
1183
+ <span class="tx_normal">${opt.value}</span>
1184
+ ${opt.note ? html` <span class="tx_gray_12 ms-2">${opt.note}</span> ` : ''}
1185
+ </div>`;
1186
+ })
1187
+ );
1374
1188
  },
1375
- };
1376
- })()
1377
- ),
1378
- ratio: 25,
1379
- }
1380
- ),
1381
- // 空白容器
1382
- BgWidget.mbContainer(240),
1383
- // 儲存資料
1384
- html` <div class="update-bar-container">
1385
- ${obj.type === 'replace'
1386
- ? BgWidget.redButton(
1387
- '刪除分類',
1388
- gvc.event(() => {
1389
- dialog.checkYesOrNot({
1390
- text: '確定要刪除商品分類嗎?<br/>(若包含子分類,也將一併刪除)',
1391
- callback: bool => {
1392
- if (bool) {
1393
- dialog.dataLoading({ visible: true });
1394
- ApiShop.deleteCollections({
1395
- data: { data: [vm.data] },
1396
- token: (window.parent as any).config.token,
1397
- }).then(res => {
1398
- dialog.dataLoading({ visible: false });
1399
- if (res.result) {
1400
- vm.type = 'list';
1401
- dialog.successMessage({ text: '更新成功' });
1402
- } else {
1403
- dialog.errorMessage({ text: '更新失敗' });
1404
- }
1189
+ onCreate: () => {
1190
+ if (pvm.loading) {
1191
+ if (pvm.dataList.length === 0) {
1192
+ pvm.productList = [];
1193
+ pvm.loading = false;
1194
+ gvc.notifyDataChange(pvm.id);
1195
+ } else {
1196
+ ApiShop.getProduct({
1197
+ page: 0,
1198
+ limit: 99999,
1199
+ id_list: pvm.dataList.join(','),
1200
+ }).then(data => {
1201
+ pvm.productList = data.response.data.map(
1202
+ (product: {
1203
+ content: {
1204
+ id: number;
1205
+ title: string;
1206
+ preview_image: string[];
1207
+ };
1208
+ }) => {
1209
+ return {
1210
+ key: product.content.id,
1211
+ value: product.content.title,
1212
+ image: product.content.preview_image[0] ?? BgWidget.noImageURL,
1213
+ };
1214
+ }
1215
+ );
1216
+ pvm.loading = false;
1217
+ gvc.notifyDataChange(pvm.id);
1405
1218
  });
1406
1219
  }
1407
- },
1408
- });
1409
- })
1410
- )
1411
- : ''}
1412
- ${BgWidget.cancel(
1413
- gvc.event(() => {
1414
- vm.type = 'list';
1415
- })
1416
- )}
1417
- ${BgWidget.save(
1418
- gvc.event(() => {
1419
- // 驗證分類標籤是否填寫
1420
- if (CheckInput.isEmpty(vm.data.title)) {
1421
- dialog.infoMessage({ text: '請填寫「分類標籤」' });
1422
- return;
1423
- }
1424
-
1425
- // 驗證分類路徑是否已存在
1426
- const updateDataPath = [...vm.data.parentTitles, vm.data.title].join('');
1427
-
1428
- if ([...original.parentTitles, original.title].join('') !== updateDataPath) {
1429
- const somePath = originDataList.some(item => {
1430
- return [...item.parentTitles, item.title].join('') === updateDataPath;
1431
- });
1432
-
1433
- if (somePath) {
1434
- dialog.infoMessage({ text: '此「分類標籤」已存在' });
1435
- return;
1436
- }
1437
- }
1438
-
1439
- // 標題格式化
1440
- const forbiddenRegex = /[,/\\]/;
1441
- if (forbiddenRegex.test(vm.data.title)) {
1442
- dialog.infoMessage({ text: '標題不可包含空白格與以下符號:<br />「 , 」「 / 」「 \\ 」' });
1443
- return;
1444
- }
1445
-
1446
- // 驗證連結網址是否填寫
1447
- const no_fill_language = (window.parent as any).store_info.language_setting.support.find(
1448
- (dd: any) => !(vm.data.language_data as any)[dd].seo.domain
1449
- );
1450
- if (no_fill_language) {
1451
- select_lan = no_fill_language;
1452
- refresh();
1453
- dialog.infoMessage({ text: '請重新填寫「連結網址」' });
1454
- return;
1455
- }
1456
-
1457
- // 連結格式化
1458
- if (
1459
- (window.parent as any).store_info.language_setting.support.find((dd: any) => {
1460
- if (CheckInput.isChineseEnglishNumberHyphen((vm.data.language_data as any)[dd].seo.domain)) {
1461
- return false;
1462
- }
1463
- select_lan = dd;
1464
- return true;
1465
- })
1466
- ) {
1467
- refresh();
1468
- dialog.infoMessage({ text: '連結僅限使用中英文數字與連接號' });
1469
- return;
1470
- }
1471
-
1472
- // 驗證是否有重複使用的 domain
1473
- const validLangDomain = getValidLangDomain();
1474
- if (!validLangDomain.result) {
1475
- refresh();
1476
- dialog.infoMessage({ text: validLangDomain.text });
1477
- return;
1478
- }
1479
-
1480
- // --- 更新分類方法 ---
1481
- function putEvent() {
1482
- dialog.dataLoading({ visible: true });
1483
- ApiShop.putCollections({
1484
- data: { replace: vm.data, original },
1485
- token: (window.parent as any).config.token,
1486
- }).then(res => {
1487
- dialog.dataLoading({ visible: false });
1488
- if (res.result) {
1489
- if (res.response.result) {
1490
- vm.type = 'list';
1491
- dialog.successMessage({ text: '更新成功' });
1492
- } else {
1493
- dialog.errorMessage({ text: res.response.message });
1494
- }
1495
- } else {
1496
- dialog.errorMessage({ text: '更新失敗' });
1497
- }
1498
- });
1499
- }
1500
-
1501
- // --- 取代原有的標籤程序 ---
1502
- if (vm.cloneTarget && vm.cloneTarget.title === vm.data.title) {
1503
- dialog.checkYesOrNot({
1504
- text: ['若移動當前商品分類,<b>附帶的子分類將不會保留</b>,', '確定要執行嗎?'].join('<br/>'),
1505
- callback: bool => {
1506
- if (bool && vm.cloneTarget) {
1507
- ApiShop.deleteCollections({
1508
- data: { data: [vm.cloneTarget] },
1509
- token: (window.parent as any).config.token,
1510
- }).then(() => {
1511
- putEvent();
1512
- });
1513
1220
  }
1514
1221
  },
1515
- });
1516
- return;
1517
- }
1518
-
1519
- // --- 確認更新 ---
1520
- putEvent();
1521
- })
1522
- )}
1523
- </div>`,
1524
- ].join(BgWidget.mbContainer(24))
1222
+ divCreate: {
1223
+ class: `w-100`,
1224
+ style: `overflow-x:hidden;`,
1225
+ },
1226
+ })}
1227
+ </div>
1228
+ `;
1229
+ })(),
1230
+ [
1231
+ html` <div style="font-weight: 700;" class="mb-3">
1232
+ 搜尋引擎列表 ${BgWidget.languageInsignia(select_lan, 'margin-left:5px;')}
1233
+ </div>
1234
+ <div class="tx_normal fw-normal" style="margin: 18px 0 8px;">SEO 標題</div>
1235
+ ${EditorElem.editeInput({
1236
+ gvc: gvc,
1237
+ title: '',
1238
+ default: language_data.seo.title ?? '',
1239
+ placeHolder: '請輸入 SEO 標題',
1240
+ callback: text => {
1241
+ language_data.seo.title = text;
1242
+ },
1243
+ })}`,
1244
+ ,
1245
+ html` <div class="tx_normal fw-normal">SEO 描述</div>
1246
+ ${EditorElem.editeText({
1247
+ gvc: gvc,
1248
+ title: '',
1249
+ default: language_data.seo.content ?? '',
1250
+ placeHolder: '請輸入 SEO 描述',
1251
+ callback: text => {
1252
+ language_data.seo.content = text;
1253
+ },
1254
+ })}`,
1255
+ ,
1256
+ html` <div class="tx_normal fw-normal">SEO 圖片</div>
1257
+ ${EditorElem.uploadImageContainer({
1258
+ gvc: gvc,
1259
+ title: '',
1260
+ def: vm.data.seo_image ?? '',
1261
+ callback: text => {
1262
+ vm.data.seo_image = text;
1263
+ },
1264
+ })}`,
1265
+ ,
1266
+ ].join(BgWidget.mbContainer(10)),
1267
+ ].join(`<div class="mx-n2 border-top my-3"></div>`),
1268
+ // 空白容器
1269
+ BgWidget.mbContainer(240),
1270
+ ].join(BgWidget.mbContainer(24)),
1271
+ {
1272
+ style: `width: 100%;overflow-x:hidden;`,
1273
+ }
1525
1274
  );
1526
1275
  },
1276
+ divCreate: {
1277
+ style: ``,
1278
+ class: `w-100`,
1279
+ },
1527
1280
  };
1528
1281
  });
1529
1282
  }