ts-glitter 22.4.6 → 22.4.9

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 (100) hide show
  1. package/lib/glitterBundle/Glitter.css +74 -62
  2. package/lowcode/Entry.js +1 -1
  3. package/lowcode/Entry.ts +1 -1
  4. package/lowcode/backend-manager/bg-product.js +49 -32
  5. package/lowcode/backend-manager/bg-product.ts +57 -39
  6. package/lowcode/backend-manager/bg-widget.js +17 -0
  7. package/lowcode/backend-manager/bg-widget.ts +18 -0
  8. package/lowcode/cms-plugin/information/information-module.js +5 -5
  9. package/lowcode/cms-plugin/information/information-module.ts +9 -5
  10. package/lowcode/cms-plugin/menus-setting.js +69 -55
  11. package/lowcode/cms-plugin/menus-setting.ts +77 -61
  12. package/lowcode/cms-plugin/module/form-module.js +109 -89
  13. package/lowcode/cms-plugin/module/form-module.ts +680 -650
  14. package/lowcode/cms-plugin/module/product-excel.js +1 -0
  15. package/lowcode/cms-plugin/module/product-excel.ts +2 -0
  16. package/lowcode/cms-plugin/pos-pages/payment-page.js +28 -10
  17. package/lowcode/cms-plugin/pos-pages/payment-page.ts +29 -10
  18. package/lowcode/cms-plugin/shopping-allowance-manager.js +0 -1
  19. package/lowcode/cms-plugin/shopping-allowance-manager.ts +0 -1
  20. package/lowcode/cms-plugin/shopping-collections.js +367 -193
  21. package/lowcode/cms-plugin/shopping-collections.ts +664 -243
  22. package/lowcode/cms-plugin/shopping-information.js +392 -38
  23. package/lowcode/cms-plugin/shopping-information.ts +479 -87
  24. package/lowcode/cms-plugin/shopping-product-setting.js +2 -2
  25. package/lowcode/cms-plugin/shopping-product-setting.ts +2 -2
  26. package/lowcode/cms-plugin/shopping-setting-advance.js +906 -766
  27. package/lowcode/cms-plugin/shopping-setting-advance.ts +977 -841
  28. package/lowcode/cms-plugin/shopping-setting-basic.js +1547 -1285
  29. package/lowcode/cms-plugin/shopping-setting-basic.ts +1742 -1466
  30. package/lowcode/cms-plugin/stock-stores.js +1 -0
  31. package/lowcode/cms-plugin/stock-stores.ts +1 -0
  32. package/lowcode/cms-plugin/user-list.js +47 -12
  33. package/lowcode/cms-plugin/user-list.ts +52 -14
  34. package/lowcode/css/editor.css +6 -0
  35. package/lowcode/glitterBundle/Glitter.css +74 -62
  36. package/lowcode/jslib/nestable/index.html +317 -0
  37. package/lowcode/jslib/nestable/jquery.nestable.js +484 -0
  38. package/lowcode/official_view_component/form-widget/input-custom.js +98 -6
  39. package/lowcode/official_view_component/form-widget/input-custom.ts +121 -16
  40. package/lowcode/public-components/headers/header-class.js +63 -0
  41. package/lowcode/public-components/headers/header-class.ts +65 -0
  42. package/lowcode/public-components/headers/sy-02.js +386 -400
  43. package/lowcode/public-components/headers/sy-02.ts +482 -492
  44. package/lowcode/public-components/headers/sy-03.js +42 -43
  45. package/lowcode/public-components/headers/sy-03.ts +46 -43
  46. package/lowcode/public-components/headers/sy-04.js +43 -41
  47. package/lowcode/public-components/headers/sy-04.ts +48 -41
  48. package/lowcode/public-components/headers/sy-05.js +30 -27
  49. package/lowcode/public-components/headers/sy-05.ts +33 -27
  50. package/lowcode/public-components/product/product-list.js +160 -148
  51. package/lowcode/public-components/product/product-list.ts +186 -165
  52. package/lowcode/public-models/product.ts +26 -1
  53. package/lowcode/src/glitterBundle/Glitter.css +74 -62
  54. package/package.json +1 -1
  55. package/rxmnt81tnk.json +1 -0
  56. package/src/api-public/controllers/shop.js +10 -4
  57. package/src/api-public/controllers/shop.js.map +1 -1
  58. package/src/api-public/controllers/shop.ts +14 -9
  59. package/src/api-public/services/ezpay/tool.d.ts +1 -0
  60. package/src/api-public/services/mail.js +1 -1
  61. package/src/api-public/services/mail.js.map +1 -1
  62. package/src/api-public/services/mail.ts +1 -1
  63. package/src/api-public/services/monitor.js.map +1 -1
  64. package/src/api-public/services/monitor.ts +2 -0
  65. package/src/api-public/services/schedule.d.ts +0 -1
  66. package/src/api-public/services/schedule.js +12 -35
  67. package/src/api-public/services/schedule.js.map +1 -1
  68. package/src/api-public/services/schedule.ts +15 -39
  69. package/src/api-public/services/shopee.js +7 -17
  70. package/src/api-public/services/shopping.d.ts +27 -6
  71. package/src/api-public/services/shopping.js +364 -85
  72. package/src/api-public/services/shopping.js.map +1 -1
  73. package/src/api-public/services/shopping.ts +510 -101
  74. package/src/api-public/services/updated-table-checked.js +58 -1
  75. package/src/api-public/services/updated-table-checked.js.map +1 -1
  76. package/src/api-public/services/updated-table-checked.ts +62 -1
  77. package/src/api-public/services/user-update.js +14 -0
  78. package/src/api-public/services/user-update.js.map +1 -1
  79. package/src/api-public/services/user-update.ts +15 -0
  80. package/src/api-public/services/user.js +1 -1
  81. package/src/api-public/services/user.js.map +1 -1
  82. package/src/api-public/services/user.ts +1 -1
  83. package/src/app-project/serverless/src/modules/database.d.ts +1 -1
  84. package/src/app-project/serverless/src/modules/redis.d.ts +1 -1
  85. package/src/helper/glitter-util.d.ts +1 -0
  86. package/src/index.js +7 -4
  87. package/src/index.js.map +1 -1
  88. package/src/index.ts +45 -36
  89. package/src/modules/firebase.js +1 -0
  90. package/src/modules/firebase.js.map +1 -1
  91. package/src/modules/firebase.ts +1 -0
  92. package/src/seo-config.d.ts +2 -1
  93. package/src/seo-config.js +28 -22
  94. package/src/seo-config.js.map +1 -1
  95. package/src/seo-config.ts +33 -26
  96. package/src/services/saas-table-check.js.map +1 -1
  97. package/src/services/ses.js +4 -3
  98. package/src/services/ses.js.map +1 -1
  99. package/src/services/system-schedule.js.map +1 -1
  100. package/src/services/system-schedule.ts +1 -0
@@ -383,17 +383,15 @@ class Shopping {
383
383
  return dd.content;
384
384
  })
385
385
  .map((product) => {
386
- var _a;
386
+ var _a, _b;
387
387
  product.content.designated_logistics = (_a = product.content.designated_logistics) !== null && _a !== void 0 ? _a : { list: [], type: 'all' };
388
388
  if (product.content.designated_logistics.group === '' && !product.content.designated_logistics.type) {
389
389
  product.content.designated_logistics = { list: [], type: 'all' };
390
390
  }
391
- product.content.collection = Array.from(new Set((() => {
392
- var _a;
393
- return ((_a = product.content.collection) !== null && _a !== void 0 ? _a : []).map((dd) => {
394
- return dd.replace(' / ', '/').replace(' /', '/').replace('/ ', '/').replace('/', ' / ');
395
- });
396
- })()));
391
+ product.content.collection = Array.from(new Set(((_b = product.content.collection) !== null && _b !== void 0 ? _b : []).map((path) => path
392
+ .split('/')
393
+ .map(segment => segment.trim())
394
+ .join(' / '))));
397
395
  return new Promise(async (resolve) => {
398
396
  var _a, _b, _c;
399
397
  if (product) {
@@ -2792,6 +2790,7 @@ class Shopping {
2792
2790
  else {
2793
2791
  sql = `${baseSelect} \`${this.app}\`.t_checkout o ${joinClause} ${whereClause} ${orderString}`;
2794
2792
  }
2793
+ console.log(`query-sql====>${sql}`);
2795
2794
  if (query.returnSearch == 'true') {
2796
2795
  const data = await database_js_1.default.query(`SELECT *
2797
2796
  FROM \`${this.app}\`.t_checkout
@@ -2846,61 +2845,63 @@ class Shopping {
2846
2845
  }))[0].value;
2847
2846
  await Promise.all(obMap
2848
2847
  .map(async (order) => {
2849
- try {
2850
- if (order.orderData.customer_info.payment_select === 'ecPay') {
2851
- order.orderData.cash_flow = await new financial_service_js_1.EcPay(this.app).checkPaymentStatus(order.cart_token);
2852
- }
2853
- if (order.orderData.customer_info.payment_select === 'paynow') {
2854
- try {
2855
- order.orderData.cash_flow = (await new financial_service_js_1.PayNow(this.app, keyData['paynow']).confirmAndCaptureOrder(order.orderData.paynow_id)).result;
2848
+ if (obMap.length === 1) {
2849
+ try {
2850
+ if (order.orderData.customer_info.payment_select === 'ecPay') {
2851
+ order.orderData.cash_flow = await new financial_service_js_1.EcPay(this.app).checkPaymentStatus(order.cart_token);
2856
2852
  }
2857
- catch (e) { }
2858
- }
2859
- if (order.orderData.user_info.shipment_refer === 'paynow') {
2860
- const pay_now = new paynow_logistics_js_1.PayNowLogistics(this.app);
2861
- order.orderData.user_info.shipment_detail = await pay_now.getOrderInfo(order.cart_token);
2862
- const status = (() => {
2863
- switch (order.orderData.user_info.shipment_detail.PayNowLogisticCode) {
2864
- case '0000':
2865
- case '7101':
2866
- case '7201':
2867
- return 'wait';
2868
- case '0101':
2869
- case '4000':
2870
- case '4019':
2871
- case '0102':
2872
- case '9411':
2873
- return 'shipping';
2874
- case '0103':
2875
- case '4033':
2876
- case '4031':
2877
- case '4032':
2878
- case '4036':
2879
- case '4040':
2880
- case '5001':
2881
- case '8100':
2882
- case '8110':
2883
- case '8120':
2884
- return 'returns';
2885
- case '5000':
2886
- return 'arrived';
2887
- case '8000':
2888
- case '8010':
2889
- case '8020':
2890
- return 'finish';
2853
+ if (order.orderData.customer_info.payment_select === 'paynow') {
2854
+ try {
2855
+ order.orderData.cash_flow = (await new financial_service_js_1.PayNow(this.app, keyData['paynow']).confirmAndCaptureOrder(order.orderData.paynow_id)).result;
2856
+ }
2857
+ catch (e) { }
2858
+ }
2859
+ if (order.orderData.user_info.shipment_refer === 'paynow') {
2860
+ const pay_now = new paynow_logistics_js_1.PayNowLogistics(this.app);
2861
+ order.orderData.user_info.shipment_detail = await pay_now.getOrderInfo(order.cart_token);
2862
+ const status = (() => {
2863
+ switch (order.orderData.user_info.shipment_detail.PayNowLogisticCode) {
2864
+ case '0000':
2865
+ case '7101':
2866
+ case '7201':
2867
+ return 'wait';
2868
+ case '0101':
2869
+ case '4000':
2870
+ case '4019':
2871
+ case '0102':
2872
+ case '9411':
2873
+ return 'shipping';
2874
+ case '0103':
2875
+ case '4033':
2876
+ case '4031':
2877
+ case '4032':
2878
+ case '4036':
2879
+ case '4040':
2880
+ case '5001':
2881
+ case '8100':
2882
+ case '8110':
2883
+ case '8120':
2884
+ return 'returns';
2885
+ case '5000':
2886
+ return 'arrived';
2887
+ case '8000':
2888
+ case '8010':
2889
+ case '8020':
2890
+ return 'finish';
2891
+ }
2892
+ })();
2893
+ if (status && order.orderData.progress !== status) {
2894
+ order.orderData.progress = status;
2895
+ await this.putOrder({
2896
+ status: undefined,
2897
+ orderData: order.orderData,
2898
+ id: order.id,
2899
+ });
2891
2900
  }
2892
- })();
2893
- if (status && order.orderData.progress !== status) {
2894
- order.orderData.progress = status;
2895
- await this.putOrder({
2896
- status: undefined,
2897
- orderData: order.orderData,
2898
- id: order.id,
2899
- });
2900
2901
  }
2901
2902
  }
2903
+ catch (e) { }
2902
2904
  }
2903
- catch (e) { }
2904
2905
  })
2905
2906
  .concat(obMap.map(async (order) => {
2906
2907
  var _a;
@@ -2911,10 +2912,23 @@ class Shopping {
2911
2912
  searchType: (_a = order.orderData) === null || _a === void 0 ? void 0 : _a.order_number,
2912
2913
  })).data[0];
2913
2914
  order.invoice_number = invoice && invoice.invoice_no;
2914
- }))
2915
- .concat(obMap.map(async (order) => {
2916
- order.user_data = await new user_js_1.User(this.app).getUserData(order.email, 'email_or_phone');
2917
- })));
2915
+ })).concat([
2916
+ new Promise(async (resolve) => {
2917
+ const setEmail = await database_js_1.default.query(`select * from \`${this.app}\`.t_user where (email or phone) in (
2918
+ ${[database_js_1.default.escape('dmle3'),
2919
+ ...Array.from((new Set(obMap.map((order) => {
2920
+ return database_js_1.default.escape(`${order.email}`);
2921
+ }))))].join(',')}
2922
+ )`, []);
2923
+ obMap.map((order) => {
2924
+ const find = setEmail.find((d1) => {
2925
+ return (d1.email == order.email) || (d1.phone == order.email);
2926
+ });
2927
+ order.user_data = find && find.userData;
2928
+ });
2929
+ resolve(true);
2930
+ })
2931
+ ]));
2918
2932
  timer.checkPoint('finish-query-all');
2919
2933
  return response_data;
2920
2934
  }
@@ -3124,15 +3138,13 @@ class Shopping {
3124
3138
  throw exception_js_1.default.BadRequestError('BAD_REQUEST', 'insertVoucherHistory Error:' + express_1.default, null);
3125
3139
  }
3126
3140
  }
3127
- async resetVoucherHistory() {
3141
+ async resetVoucherHistory(order_id) {
3128
3142
  try {
3129
- const resetMins = 10;
3130
- const now = (0, moment_1.default)().tz('Asia/Taipei').format('YYYY-MM-DD HH:mm:ss');
3131
3143
  await database_js_1.default.query(`
3132
3144
  UPDATE \`${this.app}\`.t_voucher_history
3133
3145
  SET status = 0
3134
3146
  WHERE status = 2
3135
- AND updated_at < DATE_SUB('${now}', INTERVAL ${resetMins} MINUTE);`, []);
3147
+ AND order_id = ?;`, [order_id]);
3136
3148
  }
3137
3149
  catch (error) {
3138
3150
  throw exception_js_1.default.BadRequestError('BAD_REQUEST', 'insertVoucherHistory Error:' + express_1.default, null);
@@ -3419,7 +3431,7 @@ class Shopping {
3419
3431
  FROM \`${this.app}\`.public_config
3420
3432
  WHERE \`key\` = 'collection';`, []))[0]) !== null && _a !== void 0 ? _a : {};
3421
3433
  config.value = config.value || [];
3422
- if (replace.parentTitles[0] === '(無)') {
3434
+ if (replace.parentTitles[0] === '請選擇項目') {
3423
3435
  replace.parentTitles = [];
3424
3436
  }
3425
3437
  replace.title = replace.title.replace(/[\s,\/\\]+/g, '');
@@ -3504,10 +3516,8 @@ class Shopping {
3504
3516
  return ((_a = replace.product_id) !== null && _a !== void 0 ? _a : []).findIndex(rid => rid === oid) === -1;
3505
3517
  });
3506
3518
  if (delete_id_list.length > 0) {
3507
- const products_sql = `SELECT *
3508
- FROM \`${this.app}\`.t_manager_post
3509
- WHERE id in (${delete_id_list.join(',')});`;
3510
- const delete_product_list = await database_js_1.default.query(products_sql, []);
3519
+ const delete_product_list = await database_js_1.default.query(` SELECT * FROM \`${this.app}\`.t_manager_post WHERE id IN (${delete_id_list.join(',')});
3520
+ `, []);
3511
3521
  for (const product of delete_product_list) {
3512
3522
  product.content.collection = product.content.collection.filter((str) => {
3513
3523
  if (original.parentTitles[0]) {
@@ -3584,14 +3594,195 @@ class Shopping {
3584
3594
  throw exception_js_1.default.BadRequestError('BAD_REQUEST', 'putCollection Error:' + e, null);
3585
3595
  }
3586
3596
  }
3597
+ async putCollectionV2(replace, original) {
3598
+ var _a, _b, _c, _d;
3599
+ try {
3600
+ const removeCollection = (config, target) => {
3601
+ const path = target.parentTitles;
3602
+ let currentLevel = config;
3603
+ for (let i = 0; i < path.length; i++) {
3604
+ const found = currentLevel.find(c => c.title === path[i]);
3605
+ if (!found) {
3606
+ console.warn(`putCollectionV2 無法找到原本的父類別:${path[i]},略過刪除`);
3607
+ return -1;
3608
+ }
3609
+ currentLevel = found.array;
3610
+ }
3611
+ const index = currentLevel.findIndex(c => c.title === target.title);
3612
+ if (index !== -1) {
3613
+ if (Array.isArray(currentLevel[index].array)) {
3614
+ const currentLevelArray = currentLevel[index].array.filter(item => {
3615
+ return replace.subCollections.includes(item.title);
3616
+ });
3617
+ formatData.array = currentLevelArray;
3618
+ }
3619
+ else {
3620
+ formatData.array = [];
3621
+ }
3622
+ currentLevel.splice(index, 1);
3623
+ return index;
3624
+ }
3625
+ else {
3626
+ console.warn(`putCollectionV2 找不到原始項目:${target.title},略過刪除`);
3627
+ return -1;
3628
+ }
3629
+ };
3630
+ function setHiddenStatus(parentCollection) {
3631
+ for (const collection of parentCollection.array) {
3632
+ collection.hidden = Boolean(parentCollection.hidden || collection.hidden);
3633
+ if (collection.array.length > 0) {
3634
+ setHiddenStatus(collection);
3635
+ }
3636
+ }
3637
+ }
3638
+ function insertIntoConfig(config, replace, originIndex) {
3639
+ if (replace.parentTitles.length === 0 || replace.parentTitles[0] === '無') {
3640
+ const start = originIndex > -1 ? originIndex : config.length;
3641
+ config.splice(start, 0, formatData);
3642
+ return;
3643
+ }
3644
+ const copyParentTitles = replace.parentTitles.slice();
3645
+ for (let i = 0; i < copyParentTitles.length; i++) {
3646
+ if (copyParentTitles[i] === '請選擇項目') {
3647
+ replace.parentTitles = copyParentTitles.slice(0, i);
3648
+ }
3649
+ }
3650
+ let currentLevel = config;
3651
+ for (let i = 0; i < replace.parentTitles.length; i++) {
3652
+ const title = replace.parentTitles[i];
3653
+ const found = currentLevel.find(c => c.title === title);
3654
+ if (!found) {
3655
+ throw new Error(`找不到父類別:${title}`);
3656
+ }
3657
+ if (i === replace.parentTitles.length - 1) {
3658
+ const start = originIndex > -1 ? originIndex : found.array.length;
3659
+ found.array.splice(start, 0, formatData);
3660
+ }
3661
+ else {
3662
+ currentLevel = found.array;
3663
+ }
3664
+ }
3665
+ }
3666
+ function analyzeIdLists(leftIds, rightIds) {
3667
+ const leftSet = new Set(leftIds);
3668
+ const rightSet = new Set(rightIds);
3669
+ return {
3670
+ left_only: leftIds.filter(id => !rightSet.has(id)),
3671
+ intersection: leftIds.filter(id => rightSet.has(id)),
3672
+ right_only: rightIds.filter(id => !leftSet.has(id)),
3673
+ all_set: [...new Set([...leftSet, ...rightSet])],
3674
+ };
3675
+ }
3676
+ function buildStringMapFromConfig(config, original, replace) {
3677
+ var _a;
3678
+ const targetDepth = ((_a = original.parentTitles) !== null && _a !== void 0 ? _a : []).length;
3679
+ const stringMap = [];
3680
+ const originalTitle = original.title;
3681
+ const replaceTitle = replace.title;
3682
+ const replaceParentPath = [...replace.parentTitles, replace.title];
3683
+ const findAllPaths = (item, parentPath = []) => {
3684
+ var _a;
3685
+ const currentPath = [...parentPath, item.title];
3686
+ const fullPath = currentPath.join(' / ');
3687
+ if (currentPath[targetDepth] === originalTitle) {
3688
+ const newPathParts = [...currentPath];
3689
+ newPathParts[targetDepth] = replaceTitle;
3690
+ let newFullPath = newPathParts.join(' / ');
3691
+ if (fullPath.startsWith(replaceParentPath.join(' / '))) {
3692
+ const isRemoveCol = replace.subCollections.some(sub => {
3693
+ return !fullPath.startsWith([...replaceParentPath, sub].join(' / '));
3694
+ });
3695
+ if (isRemoveCol) {
3696
+ newFullPath = '';
3697
+ }
3698
+ }
3699
+ stringMap.push({
3700
+ old: fullPath,
3701
+ new: newFullPath,
3702
+ });
3703
+ }
3704
+ ((_a = item.array) !== null && _a !== void 0 ? _a : []).forEach(child => {
3705
+ findAllPaths(child, currentPath);
3706
+ });
3707
+ };
3708
+ for (const item of config) {
3709
+ findAllPaths(item);
3710
+ }
3711
+ return stringMap;
3712
+ }
3713
+ function main(config, original, replace) {
3714
+ const originIndex = removeCollection(config, original);
3715
+ insertIntoConfig(config, replace, originIndex);
3716
+ for (const col of config) {
3717
+ setHiddenStatus(col);
3718
+ }
3719
+ return config;
3720
+ }
3721
+ const configData = (await database_js_1.default.query(`SELECT * FROM \`${this.app}\`.public_config WHERE \`key\` = 'collection';
3722
+ `, []))[0];
3723
+ const config = configData.value || [];
3724
+ replace.title = replace.title.replace(/[\s,\/\\]+/g, '');
3725
+ const formatData = {
3726
+ array: [],
3727
+ code: replace.code,
3728
+ title: replace.title,
3729
+ seo_title: replace.seo_title,
3730
+ seo_content: replace.seo_content,
3731
+ seo_image: replace.seo_image,
3732
+ language_data: replace.language_data,
3733
+ hidden: Boolean(replace.hidden),
3734
+ };
3735
+ const id_container = analyzeIdLists((_a = original.product_id) !== null && _a !== void 0 ? _a : [], (_b = replace.product_id) !== null && _b !== void 0 ? _b : []);
3736
+ const update_path_array = buildStringMapFromConfig(config, original, replace);
3737
+ main(config, original, replace);
3738
+ if (id_container.all_set.length > 0) {
3739
+ const product_list = await database_js_1.default.query(`SELECT * FROM \`${this.app}\`.t_manager_post WHERE id IN (${id_container.all_set.join(',')});`, []);
3740
+ for (const product of product_list) {
3741
+ const currentPaths = (_c = product.content.collection) !== null && _c !== void 0 ? _c : [];
3742
+ const isLeftOnly = id_container.left_only.includes(product.id);
3743
+ const isRightOnly = id_container.right_only.includes(product.id);
3744
+ const isIntersection = id_container.intersection.includes(product.id);
3745
+ let pathsAfterRemoval = currentPaths;
3746
+ if (isLeftOnly) {
3747
+ for (const { old } of update_path_array) {
3748
+ pathsAfterRemoval = pathsAfterRemoval.filter((path) => path !== old);
3749
+ }
3750
+ }
3751
+ let pathsAfterUpdate = pathsAfterRemoval;
3752
+ if (isIntersection) {
3753
+ for (const { old, new: newVal } of update_path_array) {
3754
+ const index = pathsAfterUpdate.findIndex((p) => p === old);
3755
+ if (index !== -1) {
3756
+ pathsAfterUpdate[index] = newVal;
3757
+ }
3758
+ }
3759
+ }
3760
+ const newPath = replace.title ? [...((_d = replace.parentTitles) !== null && _d !== void 0 ? _d : []), replace.title] : [];
3761
+ const newMap = newPath.map((path, i) => [...newPath.slice(0, i), path].join(' / '));
3762
+ let finalPaths = pathsAfterUpdate;
3763
+ if (isRightOnly || isIntersection) {
3764
+ finalPaths = [...new Set([...pathsAfterUpdate, ...newMap])];
3765
+ }
3766
+ product.content.collection = finalPaths.filter((path) => path.length > 0);
3767
+ await this.updateProductCollection(product.content, product.id);
3768
+ }
3769
+ }
3770
+ await database_js_1.default.execute(`UPDATE \`${this.app}\`.public_config SET value = ? WHERE \`key\` = 'collection';
3771
+ `, [config]);
3772
+ return { result: true };
3773
+ }
3774
+ catch (e) {
3775
+ console.error(e);
3776
+ throw exception_js_1.default.BadRequestError('BAD_REQUEST', 'putCollection Error:' + e, null);
3777
+ }
3778
+ }
3587
3779
  async sortCollection(data) {
3588
3780
  var _a, _b;
3589
3781
  try {
3590
3782
  if (data && data[0]) {
3591
3783
  const parentTitle = (_a = data[0].parentTitles[0]) !== null && _a !== void 0 ? _a : '';
3592
- const config = (_b = (await database_js_1.default.query(`SELECT *
3593
- FROM \`${this.app}\`.public_config
3594
- WHERE \`key\` = 'collection';`, []))[0]) !== null && _b !== void 0 ? _b : {};
3784
+ const config = (_b = (await database_js_1.default.query(`SELECT * FROM \`${this.app}\`.public_config WHERE \`key\` = 'collection';
3785
+ `, []))[0]) !== null && _b !== void 0 ? _b : {};
3595
3786
  config.value = config.value || [];
3596
3787
  if (parentTitle === '') {
3597
3788
  config.value = data.map(item => {
@@ -3608,9 +3799,7 @@ class Shopping {
3608
3799
  });
3609
3800
  config.value[index].array = sortList;
3610
3801
  }
3611
- await database_js_1.default.execute(`UPDATE \`${this.app}\`.public_config
3612
- SET value = ?
3613
- WHERE \`key\` = 'collection';
3802
+ await database_js_1.default.execute(`UPDATE \`${this.app}\`.public_config SET value = ? WHERE \`key\` = 'collection';
3614
3803
  `, [config.value]);
3615
3804
  return true;
3616
3805
  }
@@ -3621,6 +3810,41 @@ class Shopping {
3621
3810
  throw exception_js_1.default.BadRequestError('BAD_REQUEST', 'sortCollection Error:' + e, null);
3622
3811
  }
3623
3812
  }
3813
+ async sortCollectionV2(dataArray) {
3814
+ var _a, _b;
3815
+ try {
3816
+ if (!Array.isArray(dataArray) || !dataArray.length)
3817
+ return false;
3818
+ const configRow = await database_js_1.default.query(`SELECT * FROM \`${this.app}\`.public_config WHERE \`key\` = 'collection';`, []);
3819
+ const originConfig = (_b = (_a = configRow[0]) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : [];
3820
+ function isSameStructure(origin, target) {
3821
+ const getMapByTitle = (list) => new Map(list.map(item => [item.title, item]));
3822
+ const originMap = getMapByTitle(origin);
3823
+ const targetMap = getMapByTitle(target);
3824
+ if (originMap.size !== targetMap.size)
3825
+ return false;
3826
+ for (const [title, a] of originMap) {
3827
+ const b = targetMap.get(title);
3828
+ if (!b)
3829
+ return false;
3830
+ const aChildren = Array.isArray(a.array) ? a.array : [];
3831
+ const bChildren = Array.isArray(b.array) ? b.array : [];
3832
+ if (!isSameStructure(aChildren, bChildren))
3833
+ return false;
3834
+ }
3835
+ return true;
3836
+ }
3837
+ if (!isSameStructure(originConfig, dataArray)) {
3838
+ throw exception_js_1.default.BadRequestError('BAD_REQUEST', '僅允許更動排序,不可新增、刪除或修改分類結構。', null);
3839
+ }
3840
+ await database_js_1.default.execute(`UPDATE \`${this.app}\`.public_config SET value = ? WHERE \`key\` = 'collection';`, [dataArray]);
3841
+ return true;
3842
+ }
3843
+ catch (e) {
3844
+ console.error(e);
3845
+ throw exception_js_1.default.BadRequestError('BAD_REQUEST', 'sortCollection Error: ' + e, null);
3846
+ }
3847
+ }
3624
3848
  checkVariantDataType(variants) {
3625
3849
  const propertiesToParse = ['stock', 'product_id', 'sale_price', 'compare_price', 'shipment_weight'];
3626
3850
  variants.forEach(variant => {
@@ -3990,14 +4214,71 @@ class Shopping {
3990
4214
  const find_collection = deleteList.find(obj => obj.parent === index);
3991
4215
  return !(find_collection && find_collection.child[0] === -1);
3992
4216
  });
3993
- const update_col_sql = `UPDATE \`${this.app}\`.public_config
3994
- SET value = ?
3995
- WHERE \`key\` = 'collection';`;
3996
- await database_js_1.default.execute(update_col_sql, [config.value]);
4217
+ await database_js_1.default.execute(`UPDATE \`${this.app}\`.public_config SET value = ? WHERE \`key\` = 'collection';
4218
+ `, [config.value]);
3997
4219
  return { result: true };
3998
4220
  }
3999
4221
  catch (e) {
4000
- throw exception_js_1.default.BadRequestError('BAD_REQUEST', 'getCollectionProducts Error:' + e, null);
4222
+ throw exception_js_1.default.BadRequestError('BAD_REQUEST', 'deleteCollection Error:' + e, null);
4223
+ }
4224
+ }
4225
+ async deleteCollectionV2(dataArray) {
4226
+ try {
4227
+ const configData = (await database_js_1.default.query(`SELECT * FROM \`${this.app}\`.public_config WHERE \`key\` = 'collection';
4228
+ `, []))[0];
4229
+ const config = configData.value || [];
4230
+ const containsAnyTagSQL = (tags) => {
4231
+ const conditions = tags.map(tag => `JSON_CONTAINS(content, '["${tag}"]', '$.collection')`).join(' OR ');
4232
+ return `SELECT * FROM \`${this.app}\`.t_manager_post WHERE ${conditions}`;
4233
+ };
4234
+ const removeCollection = async (config, target) => {
4235
+ var _a, _b;
4236
+ const path = (_a = target.parentTitles) !== null && _a !== void 0 ? _a : [];
4237
+ let currentLevel = config;
4238
+ for (let i = 0; i < path.length; i++) {
4239
+ const found = currentLevel.find(c => c.title === path[i]);
4240
+ if (!found) {
4241
+ console.warn(`deleteCollectionV2 無法找到原本的父類別:${path[i]},略過刪除`);
4242
+ return;
4243
+ }
4244
+ currentLevel = found.array;
4245
+ }
4246
+ const index = currentLevel.findIndex(c => c.title === target.title);
4247
+ if (index === -1) {
4248
+ console.warn(`deleteCollectionV2 找不到原始項目:${target.title},略過刪除`);
4249
+ return;
4250
+ }
4251
+ const removed = currentLevel.splice(index, 1)[0];
4252
+ if (!removed)
4253
+ return;
4254
+ const tagToDelete = [];
4255
+ function gatherAllPaths(node, currentPath) {
4256
+ var _a;
4257
+ const full = [...currentPath, node.title].join(' / ');
4258
+ tagToDelete.push(full);
4259
+ if (((_a = node.array) === null || _a === void 0 ? void 0 : _a.length) > 0) {
4260
+ for (const child of node.array) {
4261
+ gatherAllPaths(child, [...currentPath, node.title]);
4262
+ }
4263
+ }
4264
+ }
4265
+ gatherAllPaths(removed, path);
4266
+ const productList = await database_js_1.default.query(containsAnyTagSQL(tagToDelete), []);
4267
+ for (const product of productList) {
4268
+ const before = (_b = product.content.collection) !== null && _b !== void 0 ? _b : [];
4269
+ product.content.collection = before.filter((c) => !tagToDelete.includes(c));
4270
+ await this.updateProductCollection(product.content, product.id);
4271
+ }
4272
+ };
4273
+ for (const data of dataArray) {
4274
+ removeCollection(config, data);
4275
+ }
4276
+ await database_js_1.default.execute(`UPDATE \`${this.app}\`.public_config SET value = ? WHERE \`key\` = 'collection';
4277
+ `, [config]);
4278
+ return { result: true };
4279
+ }
4280
+ catch (e) {
4281
+ throw exception_js_1.default.BadRequestError('BAD_REQUEST', 'deleteCollection Error:' + e, null);
4001
4282
  }
4002
4283
  }
4003
4284
  async deleteCollectionProduct(parent_name, children_list) {
@@ -4054,10 +4335,8 @@ class Shopping {
4054
4335
  }
4055
4336
  async updateProductCollection(content, id) {
4056
4337
  try {
4057
- const updateProdSQL = `UPDATE \`${this.app}\`.t_manager_post
4058
- SET content = ?
4059
- WHERE \`id\` = ?;`;
4060
- await database_js_1.default.execute(updateProdSQL, [content, id]);
4338
+ await database_js_1.default.execute(`UPDATE \`${this.app}\`.t_manager_post SET content = ? WHERE \`id\` = ?;
4339
+ `, [content, id]);
4061
4340
  }
4062
4341
  catch (error) {
4063
4342
  throw exception_js_1.default.BadRequestError('BAD_REQUEST', 'updateProductCollection Error:' + express_1.default, null);