ts-glitter 21.0.4 → 21.0.5

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 (159) hide show
  1. package/lowcode/Entry.js +1 -1
  2. package/lowcode/Entry.ts +1 -1
  3. package/lowcode/backend-manager/bg-blog.js +22 -37
  4. package/lowcode/backend-manager/bg-blog.ts +45 -34
  5. package/lowcode/backend-manager/bg-list-component.js +2 -2
  6. package/lowcode/backend-manager/bg-list-component.ts +2 -2
  7. package/lowcode/backend-manager/bg-widget.js +21 -0
  8. package/lowcode/backend-manager/bg-widget.ts +21 -0
  9. package/lowcode/cms-plugin/filter-options.js +3 -3
  10. package/lowcode/cms-plugin/filter-options.ts +1 -1
  11. package/lowcode/cms-plugin/shopping-finance-setting.js +251 -6
  12. package/lowcode/cms-plugin/shopping-finance-setting.ts +291 -6
  13. package/lowcode/cms-plugin/shopping-order-manager.js +56 -46
  14. package/lowcode/cms-plugin/shopping-order-manager.ts +59 -47
  15. package/lowcode/cms-plugin/shopping-product-setting.js +10 -5
  16. package/lowcode/cms-plugin/shopping-product-setting.ts +14 -6
  17. package/lowcode/cms-plugin/shopping-setting-advance.js +21 -72
  18. package/lowcode/cms-plugin/shopping-setting-advance.ts +31 -98
  19. package/lowcode/css/editor.css +48 -16
  20. package/lowcode/css/front-end.css +16 -17
  21. package/lowcode/glitter-base/global/language.js +2 -0
  22. package/lowcode/glitter-base/global/language.ts +3 -0
  23. package/lowcode/glitter-base/global/shipment-config.js +4 -4
  24. package/lowcode/glitter-base/global/shipment-config.ts +1 -1
  25. package/lowcode/glitter-base/route/shopping.js +11 -0
  26. package/lowcode/glitter-base/route/shopping.ts +12 -0
  27. package/lowcode/official_view_component/form-widget/input-custom.js +0 -1
  28. package/lowcode/official_view_component/form-widget/input-custom.ts +0 -1
  29. package/lowcode/public-components/checkout/index.js +578 -780
  30. package/lowcode/public-components/checkout/index.ts +2457 -2652
  31. package/lowcode/public-components/headers/header-class.js +252 -324
  32. package/lowcode/public-components/headers/header-class.ts +389 -480
  33. package/lowcode/public-components/modules/cart-module.js +433 -0
  34. package/lowcode/public-components/modules/cart-module.ts +491 -0
  35. package/lowcode/public-components/modules/product-module.js +45 -0
  36. package/lowcode/public-components/modules/product-module.ts +58 -0
  37. package/lowcode/public-components/product/product-detail.js +178 -184
  38. package/lowcode/public-components/product/product-detail.ts +564 -579
  39. package/lowcode/public-components/user-manager/um-order.js +162 -32
  40. package/lowcode/public-components/user-manager/um-order.ts +181 -46
  41. package/lowcode/public-models/product.ts +1 -0
  42. package/package.json +1 -1
  43. package/src/Language.js +1 -0
  44. package/src/Language.js.map +1 -1
  45. package/src/Language.ts +3 -0
  46. package/src/api-public/controllers/article.js +33 -29
  47. package/src/api-public/controllers/article.js.map +1 -1
  48. package/src/api-public/controllers/article.ts +152 -146
  49. package/src/api-public/controllers/index.js +2 -0
  50. package/src/api-public/controllers/index.js.map +1 -1
  51. package/src/api-public/controllers/index.ts +2 -0
  52. package/src/api-public/controllers/shop.js +125 -47
  53. package/src/api-public/controllers/shop.js.map +1 -1
  54. package/src/api-public/controllers/shop.ts +148 -61
  55. package/src/api-public/controllers/user.js +51 -52
  56. package/src/api-public/controllers/user.js.map +1 -1
  57. package/src/api-public/controllers/user.ts +63 -52
  58. package/src/api-public/models/glitter-finance.js +2 -1
  59. package/src/api-public/models/glitter-finance.js.map +5 -1
  60. package/src/api-public/services/checkout-event.d.ts +1 -0
  61. package/src/api-public/services/checkout-event.js +18 -10
  62. package/src/api-public/services/checkout-event.js.map +1 -1
  63. package/src/api-public/services/checkout-event.ts +18 -7
  64. package/src/api-public/services/factories/payment-strategy-factory.d.ts +6 -0
  65. package/src/api-public/services/factories/payment-strategy-factory.js +49 -0
  66. package/src/api-public/services/factories/payment-strategy-factory.js.map +1 -0
  67. package/src/api-public/services/factories/payment-strategy-factory.ts +71 -0
  68. package/src/api-public/services/fb-service.js +4 -4
  69. package/src/api-public/services/fb-service.js.map +1 -1
  70. package/src/api-public/services/financial-service.d.ts +2 -1
  71. package/src/api-public/services/financial-service.js +48 -53
  72. package/src/api-public/services/financial-service.js.map +1 -1
  73. package/src/api-public/services/financial-service.ts +29 -38
  74. package/src/api-public/services/financial-serviceV2.d.ts +298 -0
  75. package/src/api-public/services/financial-serviceV2.js +1158 -0
  76. package/src/api-public/services/financial-serviceV2.js.map +1 -0
  77. package/src/api-public/services/financial-serviceV2.ts +1518 -0
  78. package/src/api-public/services/interface/payment-keys-interface.d.ts +37 -0
  79. package/src/api-public/services/interface/payment-keys-interface.js +3 -0
  80. package/src/api-public/services/interface/payment-keys-interface.js.map +1 -0
  81. package/src/api-public/services/interface/payment-keys-interface.ts +46 -0
  82. package/src/api-public/services/interface/payment-strategy-interface.d.ts +17 -0
  83. package/src/api-public/services/interface/payment-strategy-interface.js +3 -0
  84. package/src/api-public/services/interface/payment-strategy-interface.js.map +1 -0
  85. package/src/api-public/services/interface/payment-strategy-interface.ts +48 -0
  86. package/src/api-public/services/migrate-event/public-user-config.d.ts +5 -0
  87. package/src/api-public/services/migrate-event/public-user-config.js +81 -0
  88. package/src/api-public/services/migrate-event/public-user-config.js.map +1 -0
  89. package/src/api-public/services/migrate-event/public-user-config.ts +106 -0
  90. package/src/api-public/services/model/handlePaymentTransaction.js +0 -68
  91. package/src/api-public/services/model/handlePaymentTransaction.js.map +1 -1
  92. package/src/api-public/services/model/handlePaymentTransaction.ts +62 -54
  93. package/src/api-public/services/monitor.d.ts +1 -0
  94. package/src/api-public/services/payment-service.d.ts +12 -0
  95. package/src/api-public/services/payment-service.js +83 -0
  96. package/src/api-public/services/payment-service.js.map +1 -0
  97. package/src/api-public/services/payment-service.ts +112 -0
  98. package/src/api-public/services/shopping.d.ts +2 -1
  99. package/src/api-public/services/shopping.js +60 -23
  100. package/src/api-public/services/shopping.js.map +1 -1
  101. package/src/api-public/services/shopping.ts +88 -16
  102. package/src/api-public/services/strategies/ecpay-strategy.d.ts +8 -0
  103. package/src/api-public/services/strategies/ecpay-strategy.js +26 -0
  104. package/src/api-public/services/strategies/ecpay-strategy.js.map +1 -0
  105. package/src/api-public/services/strategies/ecpay-strategy.ts +30 -0
  106. package/src/api-public/services/strategies/ezpay-strategy.d.ts +8 -0
  107. package/src/api-public/services/strategies/ezpay-strategy.js +26 -0
  108. package/src/api-public/services/strategies/ezpay-strategy.js.map +1 -0
  109. package/src/api-public/services/strategies/ezpay-strategy.ts +31 -0
  110. package/src/api-public/services/strategies/jkopay-strategy.d.ts +8 -0
  111. package/src/api-public/services/strategies/jkopay-strategy.js +32 -0
  112. package/src/api-public/services/strategies/jkopay-strategy.js.map +1 -0
  113. package/src/api-public/services/strategies/jkopay-strategy.ts +36 -0
  114. package/src/api-public/services/strategies/linepay-strategy.d.ts +8 -0
  115. package/src/api-public/services/strategies/linepay-strategy.js +32 -0
  116. package/src/api-public/services/strategies/linepay-strategy.js.map +1 -0
  117. package/src/api-public/services/strategies/linepay-strategy.ts +35 -0
  118. package/src/api-public/services/strategies/paynow-strategy.d.ts +8 -0
  119. package/src/api-public/services/strategies/paynow-strategy.js +26 -0
  120. package/src/api-public/services/strategies/paynow-strategy.js.map +1 -0
  121. package/src/api-public/services/strategies/paynow-strategy.ts +29 -0
  122. package/src/api-public/services/strategies/paypal-strategy.d.ts +8 -0
  123. package/src/api-public/services/strategies/paypal-strategy.js +28 -0
  124. package/src/api-public/services/strategies/paypal-strategy.js.map +1 -0
  125. package/src/api-public/services/strategies/paypal-strategy.ts +31 -0
  126. package/src/api-public/services/updated-table-checked.d.ts +1 -0
  127. package/src/api-public/services/updated-table-checked.js +37 -15
  128. package/src/api-public/services/updated-table-checked.js.map +1 -1
  129. package/src/api-public/services/updated-table-checked.ts +56 -36
  130. package/src/api-public/utils/ut-permission.d.ts +1 -0
  131. package/src/app-project/serverless/src/index.js +17 -7
  132. package/src/app-project/serverless/src/index.js.map +1 -1
  133. package/src/app-project/serverless/src/modules/CryptoJS.js +17 -7
  134. package/src/app-project/serverless/src/modules/CryptoJS.js.map +1 -1
  135. package/src/app-project/serverless/src/modules/ssh.js +17 -7
  136. package/src/app-project/serverless/src/modules/ssh.js.map +1 -1
  137. package/src/config.d.ts +1 -1
  138. package/src/modules/AWSLib.js +3 -2
  139. package/src/modules/AWSLib.js.map +1 -1
  140. package/src/modules/CryptoJS.js +17 -7
  141. package/src/modules/CryptoJS.js.map +1 -1
  142. package/src/modules/database.d.ts +1 -1
  143. package/src/modules/redis.d.ts +1 -1
  144. package/src/modules/ssh.js +17 -7
  145. package/src/modules/ssh.js.map +1 -1
  146. package/src/modules/tool.d.ts +4 -4
  147. package/src/modules/tool.js +2 -1
  148. package/src/modules/tool.js.map +1 -1
  149. package/src/run.js +2 -1
  150. package/src/run.js.map +1 -1
  151. package/src/services/create-instance.js +4 -3
  152. package/src/services/create-instance.js.map +1 -1
  153. package/src/services/saas-table-check.js +2 -2
  154. package/src/services/saas-table-check.js.map +5 -1
  155. package/src/services/tool.js +3 -2
  156. package/src/services/tool.js.map +1 -1
  157. package/vp00rqhw1r.json +1 -0
  158. package/src/api-public/services/product-migrate.d.ts +0 -8
  159. package/src/api-public/services/product-migrate.js.map +0 -1
@@ -5,6 +5,7 @@ import { PdClass, Product_l, FileList } from './pd-class.js';
5
5
  import { Language } from '../../glitter-base/global/language.js';
6
6
  import { UmClass } from '../user-manager/um-class.js';
7
7
  import { ShareDialog } from '../../glitterBundle/dialog/ShareDialog.js';
8
+ import { ProductModule } from '../modules/product-module.js';
8
9
 
9
10
  /*
10
11
  * Page: product_show_widget
@@ -13,611 +14,595 @@ import { ShareDialog } from '../../glitterBundle/dialog/ShareDialog.js';
13
14
  const html = String.raw;
14
15
 
15
16
  export class ProductDetail {
16
- public static titleFontColor: string = '';
17
-
18
- static tab(
19
- data: {
20
- title: string;
21
- key: string;
22
- }[],
23
- gvc: GVC,
24
- select: string,
25
- callback: (key: string) => void,
26
- style?: string
27
- ) {
28
- return html` <div
29
- style="width: 100%; justify-content: center; align-items: flex-start; gap: 22px; display: inline-flex;cursor: pointer;margin-top: 24px;margin-bottom: 24px;font-size: 18px; ${style ?? ''};"
30
- >
31
- ${data
32
- .map((dd) => {
33
- if (select === dd.key) {
34
- return html` <div style="flex-direction: column; justify-content: flex-start; align-items: center; gap: 8px; display: inline-flex">
35
- <div
36
- style="align-self: stretch; text-align: center; color: ${ProductDetail.titleFontColor}; font-family: Noto Sans; font-weight: 700; line-height: 18px; word-wrap: break-word;white-space: nowrap;margin: 0 20px;"
37
- onclick="${gvc.event(() => {
38
- callback(dd.key);
39
- })}"
40
- >
41
- ${dd.title}
42
- </div>
43
- <div style="align-self: stretch; height: 0px; border: 1px ${ProductDetail.titleFontColor} solid"></div>
44
- </div>`;
45
- } else {
46
- return html` <div
47
- style="flex-direction: column; justify-content: flex-start; align-items: center; gap: 8px; display: inline-flex"
48
- onclick="${gvc.event(() => {
49
- callback(dd.key);
50
- })}"
51
- >
52
- <div
53
- style="align-self: stretch; text-align: center; color: #8D8D8D; font-family: Noto Sans; font-weight: 400; line-height: 18px; word-wrap: break-word;white-space: nowrap;margin: 0 20px;"
54
- >
55
- ${dd.title}
56
- </div>
57
- <div style="align-self: stretch; height: 0px"></div>
58
- </div>`;
59
- }
60
- })
61
- .join('')}
62
- </div>`;
17
+ public static main(gvc: GVC, widget: any, subData: any) {
18
+ ProductModule.titleFontColor = gvc.glitter.share.globalValue['theme_color.0.title'] ?? '#333333';
19
+ const css = String.raw;
20
+ const product_id = gvc.glitter.getUrlParameter('product_id');
21
+ // console.log(`tttt->`,gvc.glitter.getUrlParameter('page'))
22
+ //移除所有查詢
23
+ const url = new URL(location.href);
24
+ for (const b of url.searchParams.keys()) {
25
+ if (b !== 'appName') {
26
+ gvc.glitter.setUrlParameter(b, undefined);
27
+ }
63
28
  }
29
+ const glitter = gvc.glitter;
64
30
 
65
- public static main(gvc: GVC, widget: any, subData: any) {
66
- ProductDetail.titleFontColor = gvc.glitter.share.globalValue['theme_color.0.title'] ?? '#333333';
67
- const css = String.raw;
68
- const product_id = gvc.glitter.getUrlParameter('product_id');
69
- // console.log(`tttt->`,gvc.glitter.getUrlParameter('page'))
70
- //移除所有查詢
71
- const url = new URL(location.href);
72
- for (const b of url.searchParams.keys()) {
73
- if (b !== 'appName') {
74
- gvc.glitter.setUrlParameter(b, undefined);
75
- }
76
- }
77
- const glitter = gvc.glitter;
31
+ const vm = {
32
+ data: {} as Product_l,
33
+ content_manager: [] as FileList,
34
+ content_tag: 'default' as string,
35
+ specs: [] as string[],
36
+ wishStatus: false,
37
+ swiper: undefined,
38
+ quantity: '1',
39
+ };
78
40
 
79
- const vm = {
80
- data: {} as Product_l,
81
- content_manager: [] as FileList,
82
- content_tag: 'default' as string,
83
- specs: [] as string[],
84
- wishStatus: false,
85
- swiper: undefined,
86
- quantity: '1',
87
- };
41
+ const ids = {
42
+ page: glitter.getUUID(),
43
+ content: glitter.getUUID(),
44
+ price: glitter.getUUID(),
45
+ wishStatus: glitter.getUUID(),
46
+ addCartButton: glitter.getUUID(),
47
+ };
88
48
 
89
- const ids = {
90
- page: glitter.getUUID(),
91
- content: glitter.getUUID(),
92
- price: glitter.getUUID(),
93
- wishStatus: glitter.getUUID(),
94
- addCartButton: glitter.getUUID(),
95
- };
49
+ const loadings = {
50
+ page: true,
51
+ };
96
52
 
97
- const loadings = {
98
- page: true,
99
- };
53
+ function spinner() {
54
+ return html` <div class="d-flex align-items-center justify-content-center flex-column w-100 mx-auto mt-5">
55
+ <div class="spinner-border" role="status"></div>
56
+ <span class="mt-3">${Language.text('loading')}</span>
57
+ </div>`;
58
+ }
100
59
 
101
- function spinner() {
102
- return html` <div class="d-flex align-items-center justify-content-center flex-column w-100 mx-auto mt-5">
103
- <div class="spinner-border" role="status"></div>
104
- <span class="mt-3">${Language.text('loading')}</span>
105
- </div>`;
60
+ return gvc.bindView({
61
+ bind: ids.page,
62
+ view: async () => {
63
+ if (loadings.page) {
64
+ return spinner();
65
+ }
66
+ if (Object.keys(vm.data).length === 0) {
67
+ return html` <div class="d-flex align-items-center justify-content-center flex-column w-100 mx-auto">
68
+ <lottie-player
69
+ style="max-width: 100%;width: 300px;"
70
+ src="https://assets10.lottiefiles.com/packages/lf20_rc6CDU.json"
71
+ speed="1"
72
+ loop="true"
73
+ background="transparent"
74
+ ></lottie-player>
75
+ <span class="mb-5 fs-5">這個商品目前尚未上架喔!</span>
76
+ </div>`;
106
77
  }
107
78
 
108
- return gvc.bindView({
109
- bind: ids.page,
110
- view: async () => {
111
- if (loadings.page) {
112
- return spinner();
113
- }
114
- if (Object.keys(vm.data).length === 0) {
115
- return html` <div class="d-flex align-items-center justify-content-center flex-column w-100 mx-auto">
116
- <lottie-player
117
- style="max-width: 100%;width: 300px;"
118
- src="https://assets10.lottiefiles.com/packages/lf20_rc6CDU.json"
119
- speed="1"
120
- loop="true"
121
- background="transparent"
122
- ></lottie-player>
123
- <span class="mb-5 fs-5">這個商品目前尚未上架喔!</span>
124
- </div>`;
125
- }
79
+ const prod = vm.data.content;
80
+ PdClass.addSpecStyle(gvc);
81
+ vm.specs =
82
+ vm.specs.length > 0
83
+ ? vm.specs
84
+ : prod.specs.map(spec => {
85
+ return spec.option[0].title;
86
+ });
126
87
 
127
- const prod = vm.data.content;
128
- PdClass.addSpecStyle(gvc);
129
- vm.specs =
130
- vm.specs.length > 0
131
- ? vm.specs
132
- : prod.specs.map((spec) => {
133
- return spec.option[0].title;
134
- });
88
+ const book_mark = [
89
+ {
90
+ title: Language.text('all_products'),
91
+ event: () => {
92
+ gvc.glitter.href = '/all-product';
93
+ },
94
+ },
95
+ ];
96
+ const d_: any = (prod.collection ?? []).sort((a: any, b: any) => {
97
+ // 計算每個字串中 `/` 的數量
98
+ const countSlashes = (str: any) => (str.match(/\//g) || []).length;
99
+ return countSlashes(b) - countSlashes(a);
100
+ });
101
+ const collections = await ApiShop.getCollection();
135
102
 
136
- const book_mark = [
137
- {
138
- title: Language.text('all_products'),
139
- event: () => {
140
- gvc.glitter.href = '/all-product';
141
- },
142
- },
143
- ];
144
- const d_: any = (prod.collection ?? []).sort((a: any, b: any) => {
145
- // 計算每個字串中 `/` 的數量
146
- const countSlashes = (str: any) => (str.match(/\//g) || []).length;
147
- return countSlashes(b) - countSlashes(a);
148
- });
149
- const collections = await ApiShop.getCollection();
103
+ function getCollectionLink(title: string) {
104
+ let domain = '';
150
105
 
151
- function getCollectionLink(title: string) {
152
- let domain = '';
106
+ function loop(array: any) {
107
+ for (const b of array) {
108
+ if (b.title === title) {
109
+ domain =
110
+ (b.language_data &&
111
+ b.language_data[Language.getLanguage()] &&
112
+ b.language_data[Language.getLanguage()].seo.domain) ||
113
+ b.code;
114
+ title =
115
+ (b.language_data &&
116
+ b.language_data[Language.getLanguage()] &&
117
+ b.language_data[Language.getLanguage()].title) ||
118
+ title;
119
+ break;
120
+ } else if (b.array) {
121
+ loop(b.array);
122
+ }
123
+ }
124
+ }
153
125
 
154
- function loop(array: any) {
155
- for (const b of array) {
156
- if (b.title === title) {
157
- domain = (b.language_data && b.language_data[Language.getLanguage()] && b.language_data[Language.getLanguage()].seo.domain) || b.code;
158
- title = (b.language_data && b.language_data[Language.getLanguage()] && b.language_data[Language.getLanguage()].title) || title;
159
- break;
160
- } else if (b.array) {
161
- loop(b.array);
162
- }
163
- }
164
- }
126
+ loop(collections.response.value);
127
+ return {
128
+ title: title,
129
+ event: () => {
130
+ if (domain) {
131
+ gvc.glitter.href = `/collections/${domain}`;
132
+ }
133
+ },
134
+ };
135
+ }
165
136
 
166
- loop(collections.response.value);
167
- return {
168
- title: title,
169
- event: () => {
170
- if (domain) {
171
- gvc.glitter.href = `/collections/${domain}`;
172
- }
173
- },
174
- };
175
- }
137
+ if (d_[0]) {
138
+ d_[0].split(' / ').map((dd: any) => {
139
+ book_mark.push(getCollectionLink(dd));
140
+ });
141
+ }
176
142
 
177
- if (d_[0]) {
178
- d_[0].split(' / ').map((dd: any) => {
179
- book_mark.push(getCollectionLink(dd));
180
- });
181
- }
143
+ return html` <div class="mx-auto pb-5" style="max-width:1100px;word-break: break-all;white-space: normal;">
144
+ <div class="breadcrumb mb-0 d-flex align-items-center py-3" style="cursor:pointer; gap:10px;">
145
+ ${book_mark
146
+ .map(dd => {
147
+ return html` <li
148
+ class="breadcrumb-item "
149
+ style="margin-top: 0px;color:${ProductModule.titleFontColor};"
150
+ onclick="${gvc.event(() => {
151
+ dd.event();
152
+ })}"
153
+ >
154
+ ${dd.title}
155
+ </li>`;
156
+ })
157
+ .join('<i class="fa-solid fa-angle-right"></i>')}
158
+ </div>
159
+ ${PdClass.selectSpec({
160
+ gvc,
161
+ titleFontColor: ProductModule.titleFontColor,
162
+ prod,
163
+ vm,
164
+ preview: true,
165
+ })}
166
+ <div class="d-flex flex-column align-items-center mt-2" style="width:100%;">
167
+ ${gvc.bindView(
168
+ (() => {
169
+ const id = glitter.getUUID();
170
+ const commentCount = vm.data.content.comments?.length ?? 0;
171
+ const maxDisplayCount = Math.min(commentCount, 15);
182
172
 
183
- return html` <div class="mx-auto pb-5" style="max-width:1100px;word-break: break-all;white-space: normal;">
184
- <div class="breadcrumb mb-0 d-flex align-items-center py-3" style="cursor:pointer; gap:10px;">
185
- ${book_mark
186
- .map((dd) => {
187
- return html` <li
188
- class="breadcrumb-item "
189
- style="margin-top: 0px;color:${ProductDetail.titleFontColor};"
190
- onclick="${gvc.event(() => {
191
- dd.event();
192
- })}"
193
- >
194
- ${dd.title}
195
- </li>`;
196
- })
197
- .join('<i class="fa-solid fa-angle-right"></i>')}
198
- </div>
199
- ${PdClass.selectSpec({
173
+ return {
174
+ bind: id,
175
+ view: () => {
176
+ return ProductModule.tab(
177
+ [
178
+ {
179
+ title: Language.text('product_description'),
180
+ key: 'default',
181
+ },
182
+ ...((window as any).store_info.customer_comment
183
+ ? [
184
+ {
185
+ title: `${Language.text('customer_reviews')} (${maxDisplayCount})`,
186
+ key: 'comment',
187
+ },
188
+ ]
189
+ : []),
190
+ ].concat(
191
+ vm.content_manager
192
+ .filter(cont => {
193
+ return prod.content_array.includes(cont.id);
194
+ })
195
+ .map(cont => {
196
+ return {
197
+ title: cont.title,
198
+ key: cont.id,
199
+ };
200
+ })
201
+ ),
202
+ gvc,
203
+ vm.content_tag,
204
+ text => {
205
+ vm.content_tag = text;
206
+ gvc.notifyDataChange(id);
207
+ gvc.notifyDataChange(ids.content);
208
+ },
209
+ `overflow: auto; ${document.body.clientWidth > 768 ? '' : 'justify-content: flex-start;'}`
210
+ );
211
+ },
212
+ divCreate: {
213
+ class: `pt-3 w-100`,
214
+ },
215
+ };
216
+ })()
217
+ )}
218
+ ${gvc.bindView({
219
+ bind: ids.content,
220
+ view: () => {
221
+ if (vm.content_tag === 'default') {
222
+ return prod.content;
223
+ }
224
+ if (vm.content_tag === 'comment') {
225
+ UmClass.addStyle(gvc);
226
+ const addCommentDialog = () => {
227
+ if (!glitter.share.GlobalUser.token) {
228
+ PdClass.jumpAlert({
200
229
  gvc,
201
- titleFontColor: ProductDetail.titleFontColor,
202
- prod,
203
- vm,
204
- preview: true,
205
- })}
206
- <div class="d-flex flex-column align-items-center mt-2" style="width:100%;">
207
- ${gvc.bindView(
208
- (() => {
230
+ text: Language.text('login_required'),
231
+ justify: 'top',
232
+ align: 'center',
233
+ width: 200,
234
+ });
235
+ return;
236
+ }
237
+ return UmClass.dialog({
238
+ gvc,
239
+ tag: '',
240
+ title: '撰寫評論',
241
+ innerHTML: gvcd => {
242
+ const postData = {
243
+ product_id: vm.data.id,
244
+ rate: 5,
245
+ title: '',
246
+ comment: '',
247
+ };
248
+ return html`
249
+ <div class="mt-1">
250
+ <div class="tx_normal fw-normal mb-1">${Language.text('rating')}</div>
251
+ ${gvcd.bindView(
252
+ (() => {
209
253
  const id = glitter.getUUID();
210
- const commentCount = vm.data.content.comments?.length ?? 0;
211
- const maxDisplayCount = Math.min(commentCount, 15);
212
-
213
- return {
214
- bind: id,
215
- view: () => {
216
- return this.tab(
217
- [
218
- {
219
- title: Language.text('product_description'),
220
- key: 'default',
221
- },
222
- ...((window as any).store_info.customer_comment) ? [
223
- {
224
- title: `${Language.text('customer_reviews')} (${maxDisplayCount})`,
225
- key: 'comment',
226
- }
227
- ]:[]
228
- ].concat(
229
- vm.content_manager
230
- .filter((cont) => {
231
- return prod.content_array.includes(cont.id);
232
- })
233
- .map((cont) => {
234
- return {
235
- title: cont.title,
236
- key: cont.id,
237
- };
238
- })
239
- ),
240
- gvc,
241
- vm.content_tag,
242
- (text) => {
243
- vm.content_tag = text;
244
- gvc.notifyDataChange(id);
245
- gvc.notifyDataChange(ids.content);
246
- },
247
- `overflow: auto; ${document.body.clientWidth > 768 ? '' : 'justify-content: flex-start;'}`
248
- );
249
- },
250
- divCreate: {
251
- class: `pt-3 w-100`,
252
- },
253
- };
254
- })()
255
- )}
256
- ${gvc.bindView({
257
- bind: ids.content,
258
- view: () => {
259
- if (vm.content_tag === 'default') {
260
- return prod.content;
254
+ function setRate(rate: number) {
255
+ postData.rate = rate;
256
+ gvcd.notifyDataChange(id);
261
257
  }
262
- if (vm.content_tag === 'comment') {
263
- UmClass.addStyle(gvc);
264
- const addCommentDialog = () => {
265
- if (!glitter.share.GlobalUser.token) {
266
- PdClass.jumpAlert({
267
- gvc,
268
- text: Language.text('login_required'),
269
- justify: 'top',
270
- align: 'center',
271
- width: 200,
272
- });
273
- return;
274
- }
275
- return UmClass.dialog({
276
- gvc,
277
- tag: '',
278
- title: '撰寫評論',
279
- innerHTML: (gvcd) => {
280
- const postData = {
281
- product_id: vm.data.id,
282
- rate: 5,
283
- title: '',
284
- comment: '',
285
- };
286
- return html`
287
- <div class="mt-1">
288
- <div class="tx_normal fw-normal mb-1">${Language.text('rating')}</div>
289
- ${gvcd.bindView(
290
- (() => {
291
- const id = glitter.getUUID();
292
- function setRate(rate: number) {
293
- postData.rate = rate;
294
- gvcd.notifyDataChange(id);
295
- }
296
- return {
297
- bind: id,
298
- view: () => {
299
- return [...new Array(5)]
300
- .fill('')
301
- .map((_, index) => {
302
- return html` <div class="rating-item">
303
- ${postData.rate > index
304
- ? html`<i
305
- class="fa-solid fa-star fs-4"
306
- style="cursor: pointer"
307
- onclick="${gvcd.event(() => {
308
- setRate(index + 1);
309
- })}"
310
- ></i>`
311
- : html`<i
312
- class="fa-regular fa-star fs-4"
313
- style="cursor: pointer"
314
- onclick="${gvcd.event(() => {
315
- setRate(index + 1);
316
- })}"
317
- ></i>`}
318
- </div>`;
319
- })
320
- .join('');
321
- },
322
- divCreate: {
323
- class: 'd-flex mt-1',
324
- },
325
- };
326
- })()
327
- )}
328
- </div>
329
- <div class="mt-2">
330
- <div class="tx_normal fw-normal mb-1">${Language.text('title')}</div>
331
- <input
332
- class="bgw-input"
333
- type="text"
334
- oninput="${gvcd.event((e) => {
335
- postData.title = e.value;
336
- })}"
337
- />
338
- </div>
339
- <div class="mt-2">
340
- <div class="tx_normal fw-normal mb-1">${Language.text('comment')}</div>
341
- <textarea
342
- class="bgw-input"
343
- rows="3"
344
- oninput="${gvcd.event((e) => {
345
- postData.comment = e.value;
346
- })}"
347
- ></textarea>
348
- </div>
349
- <div class="d-flex justify-content-end mt-2 mb-1">
350
- <div
351
- class="um-solid-btn"
352
- onclick="${gvcd.event(() => {
353
- if (postData.title === '' || postData.comment === '') {
354
- PdClass.jumpAlert({
355
- gvc,
356
- text: Language.text('complete_form'),
357
- justify: 'top',
358
- align: 'center',
359
- width: 200,
360
- });
361
- return;
362
- }
363
- const dialog = new ShareDialog(gvc.glitter);
364
- dialog.dataLoading({ visible: true });
365
- ApiShop.postComment(postData).then(() => {
366
- gvcd.closeDialog();
367
- dialog.dataLoading({ visible: false });
368
- loadings.page = true;
369
- gvc.notifyDataChange(ids.page);
370
- });
371
- })}"
372
- >
373
- ${Language.text('submit')}
374
- </div>
375
- </div>
376
- `;
377
- },
378
- });
379
- };
380
- const commentList = () => {
381
- if (!vm.data.content.comments || vm.data.content.comments.length === 0) {
382
- return html`<h3 style="margin: 60px 0;">尚無顧客評論</h3>`;
383
- }
384
- return vm.data.content.comments
385
- .sort((a, b) => {
386
- return a.date > b.date ? -1 : 1;
387
- })
388
- .slice(0, 15)
389
- .map((item) => {
390
- return html`<div style="padding: 20px; min-width: ${document.body.clientWidth > 768 ? '780px' : `calc(${document.body.clientWidth}px - 1.5rem)`};">
391
- <div class="row">
392
- <div class="col-12 col-md">
393
- <div class="row mb-6">
394
- <div class="col-12">
395
- <!-- Rating -->
396
- <div class="rating fs-sm text-dark d-flex">
397
- ${[...new Array(5)]
398
- .fill('')
399
- .map((_, index) => {
400
- return html` <div class="rating-item">
401
- ${item.rate > index ? html`<i class="fa-solid fa-star"></i>` : html`<i class="fa-regular fa-star"></i>`}
402
- </div>`;
403
- })
404
- .join('')}
405
- </div>
406
- </div>
407
- <div class="col-12">
408
- <!-- Time -->
409
- <span class="fs-xs text-muted"> ${item.userName}, <time datetime="${item.date}">${item.date}</time> </span>
410
- </div>
411
- </div>
412
- <!-- Title -->
413
- <p class="mb-2 fs-lg fw-bold">${item.title}</p>
414
- <!-- Text -->
415
- <p class="text-gray-500">${item.comment.replace(/\n/g, '<br/>')}</p>
416
- </div>
417
- </div>
418
- </div>`;
419
- })
420
- .join('');
421
- };
422
- return html` <div class="d-flex justify-content-center">
423
- <div
424
- class="um-solid-btn"
425
- onclick="${gvc.event(() => {
426
- addCommentDialog();
258
+ return {
259
+ bind: id,
260
+ view: () => {
261
+ return [...new Array(5)]
262
+ .fill('')
263
+ .map((_, index) => {
264
+ return html` <div class="rating-item">
265
+ ${postData.rate > index
266
+ ? html`<i
267
+ class="fa-solid fa-star fs-4"
268
+ style="cursor: pointer"
269
+ onclick="${gvcd.event(() => {
270
+ setRate(index + 1);
427
271
  })}"
428
- >
429
- ${Language.text('write_comment')}
430
- </div>
431
- </div>
432
- <div class="d-flex flex-column gap-2">${commentList()}</div>`;
433
- }
434
- const template = vm.content_manager.find((cont) => cont.id === vm.content_tag);
435
- const jsonData = prod.content_json.find((data) => data.id === vm.content_tag);
436
- if (!template) {
437
- return '';
438
- }
439
- let htmlString = template.data.content;
440
- if (jsonData) {
441
- jsonData.list.map((data) => {
442
- const cssStyle = template.data.tags.find((item) => item.key === data.key);
443
- const regex = new RegExp(`@{{${data.key}}}`, 'g');
444
- htmlString = htmlString.replace(
445
- regex,
446
- html`<span
447
- style="font-size: ${cssStyle?.font_size ?? 16}px; color: ${cssStyle?.font_color ?? '${titleFontColor}'}; background: ${cssStyle?.font_bgr ?? '#fff'};"
448
- >${data.value}</span
449
- >`
450
- );
451
- });
452
- }
453
- return htmlString.replace(/@{{[^}]+}}/g, '');
454
- },
455
- divCreate: {
456
- style:
457
- (() => {
458
- if (PdClass.isPad()) {
459
- return 'margin: 0 60px;';
460
- }
461
- if (PdClass.isPhone()) {
462
- return '';
463
- }
464
- return 'margin: 0 10%;';
465
- })() + `max-width:100%;word-break: break-all;white-space: normal;`,
466
- class: `pd_detail_content fr-view`,
467
- },
468
- })}
469
- </div>
470
- <div style="margin-top: 150px;"></div>
471
- ${(prod.relative_product ?? []).length
472
- ? gvc.bindView(() => {
473
- const swipID = gvc.glitter.getUUID();
474
- return {
475
- bind: gvc.glitter.getUUID(),
476
- view: async () => {
477
- return new Promise(async (resolve, reject) => {
478
- const product = (
479
- await ApiShop.getProduct({
480
- limit: 50,
481
- page: 0,
482
- id_list: prod.relative_product.join(','),
483
- })
484
- ).response.data;
485
- setTimeout(() => {
486
- const swiper = new (window as any).Swiper('#' + swipID, {
487
- slidesPerView: glitter.ut.frSize(
488
- {
489
- sm: product.length < 4 ? product.length : 4,
490
- lg: product.length < 6 ? product.length : 6,
491
- },
492
- product.length < 2 ? product.length : 2
493
- ),
494
- spaceBetween: glitter.ut.frSize(
495
- {
496
- sm: 10,
497
- lg: 30,
498
- },
499
- 10
500
- ),
501
- });
502
- }, 100);
503
- if (!product.length) {
504
- return ``;
505
- }
506
- resolve(html`
507
- <div class="w-100 d-flex align-items-center justify-content-center ">
508
- <div class="mx-auto" style="flex-direction: column; justify-content: flex-start; align-items: center; gap: 8px; display: inline-flex">
509
- <div
510
- style="font-size:18px;align-self: stretch; text-align: center; color: ${ProductDetail.titleFontColor}; font-weight: 700; line-height: 18px; word-wrap: break-word;white-space: nowrap;margin: 0 20px;"
511
- >
512
- ${Language.text('related_products')}
513
- </div>
514
- <div style="align-self: stretch; height: 0px; border: 1px ${ProductDetail.titleFontColor} solid"></div>
515
- </div>
516
- </div>
517
- <div class="w-100 row p-0 align-items-center justify-content-center mt-4 mt-lg-4 mx-0">
518
- ${product
519
- .map((dd: any) => {
520
- return html`<div class="col-6 col-sm-4 col-lg-3">
521
- ${glitter.htmlGenerate.renderComponent({
522
- appName: (window as any).appName,
523
- tag: 'product_widget',
524
- gvc: gvc,
525
- subData: dd,
526
- })}
527
- </div>`;
528
- })
529
- .join('')}
530
- </div>
531
- `);
532
- });
272
+ ></i>`
273
+ : html`<i
274
+ class="fa-regular fa-star fs-4"
275
+ style="cursor: pointer"
276
+ onclick="${gvcd.event(() => {
277
+ setRate(index + 1);
278
+ })}"
279
+ ></i>`}
280
+ </div>`;
281
+ })
282
+ .join('');
533
283
  },
534
284
  divCreate: {
535
- class: `w-100`,
285
+ class: 'd-flex mt-1',
536
286
  },
537
- onCreate: () => {},
538
- };
539
- })
540
- : ''}
541
- <div style="margin-top: 100px;"></div>
542
- </div>`;
543
- },
544
- divCreate: {
545
- style: css`min-height: 1000px;word-break: break-all;white-space: normal;`,class:`container`
546
- },
547
- onCreate: () => {
548
- if (loadings.page) {
549
- const title = glitter.getUrlParameter('page').split('products/')[1];
550
- if (title || product_id) {
551
- const inputObj = {
552
- page: 0,
553
- limit: 1,
554
- collection: '',
555
- maxPrice: '',
556
- minPrice: '',
557
- ...(() => {
558
- if (product_id) {
559
- return { id: product_id };
560
- } else {
561
- return { domain: decodeURIComponent(title) };
287
+ };
288
+ })()
289
+ )}
290
+ </div>
291
+ <div class="mt-2">
292
+ <div class="tx_normal fw-normal mb-1">${Language.text('title')}</div>
293
+ <input
294
+ class="bgw-input"
295
+ type="text"
296
+ oninput="${gvcd.event(e => {
297
+ postData.title = e.value;
298
+ })}"
299
+ />
300
+ </div>
301
+ <div class="mt-2">
302
+ <div class="tx_normal fw-normal mb-1">${Language.text('comment')}</div>
303
+ <textarea
304
+ class="bgw-input"
305
+ rows="3"
306
+ oninput="${gvcd.event(e => {
307
+ postData.comment = e.value;
308
+ })}"
309
+ ></textarea>
310
+ </div>
311
+ <div class="d-flex justify-content-end mt-2 mb-1">
312
+ <div
313
+ class="um-solid-btn"
314
+ onclick="${gvcd.event(() => {
315
+ if (postData.title === '' || postData.comment === '') {
316
+ PdClass.jumpAlert({
317
+ gvc,
318
+ text: Language.text('complete_form'),
319
+ justify: 'top',
320
+ align: 'center',
321
+ width: 200,
322
+ });
323
+ return;
562
324
  }
563
- })(),
564
- status: 'inRange',
565
- channel: 'normal',
566
- orderBy: '',
567
- with_hide_index: 'true',
568
- show_hidden: true,
569
- view_source: 'normal',
570
- distribution_code: localStorage.getItem('distributionCode') ?? '',
571
- };
325
+ const dialog = new ShareDialog(gvc.glitter);
326
+ dialog.dataLoading({ visible: true });
327
+ ApiShop.postComment(postData).then(() => {
328
+ gvcd.closeDialog();
329
+ dialog.dataLoading({ visible: false });
330
+ loadings.page = true;
331
+ gvc.notifyDataChange(ids.page);
332
+ });
333
+ })}"
334
+ >
335
+ ${Language.text('submit')}
336
+ </div>
337
+ </div>
338
+ `;
339
+ },
340
+ });
341
+ };
342
+ const commentList = () => {
343
+ if (!vm.data.content.comments || vm.data.content.comments.length === 0) {
344
+ return html`<h3 style="margin: 60px 0;">尚無顧客評論</h3>`;
345
+ }
346
+ return vm.data.content.comments
347
+ .sort((a, b) => {
348
+ return a.date > b.date ? -1 : 1;
349
+ })
350
+ .slice(0, 15)
351
+ .map(item => {
352
+ return html`<div
353
+ style="padding: 20px; min-width: ${document.body.clientWidth > 768
354
+ ? '780px'
355
+ : `calc(${document.body.clientWidth}px - 1.5rem)`};"
356
+ >
357
+ <div class="row">
358
+ <div class="col-12 col-md">
359
+ <div class="row mb-6">
360
+ <div class="col-12">
361
+ <!-- Rating -->
362
+ <div class="rating fs-sm text-dark d-flex">
363
+ ${[...new Array(5)]
364
+ .fill('')
365
+ .map((_, index) => {
366
+ return html` <div class="rating-item">
367
+ ${item.rate > index
368
+ ? html`<i class="fa-solid fa-star"></i>`
369
+ : html`<i class="fa-regular fa-star"></i>`}
370
+ </div>`;
371
+ })
372
+ .join('')}
373
+ </div>
374
+ </div>
375
+ <div class="col-12">
376
+ <!-- Time -->
377
+ <span class="fs-xs text-muted">
378
+ ${item.userName}, <time datetime="${item.date}">${item.date}</time>
379
+ </span>
380
+ </div>
381
+ </div>
382
+ <!-- Title -->
383
+ <p class="mb-2 fs-lg fw-bold">${item.title}</p>
384
+ <!-- Text -->
385
+ <p class="text-gray-500">${item.comment.replace(/\n/g, '<br/>')}</p>
386
+ </div>
387
+ </div>
388
+ </div>`;
389
+ })
390
+ .join('');
391
+ };
392
+ return html` <div class="d-flex justify-content-center">
393
+ <div
394
+ class="um-solid-btn"
395
+ onclick="${gvc.event(() => {
396
+ addCommentDialog();
397
+ })}"
398
+ >
399
+ ${Language.text('write_comment')}
400
+ </div>
401
+ </div>
402
+ <div class="d-flex flex-column gap-2">${commentList()}</div>`;
403
+ }
404
+ const template = vm.content_manager.find(cont => cont.id === vm.content_tag);
405
+ const jsonData = prod.content_json.find(data => data.id === vm.content_tag);
406
+ if (!template) {
407
+ return '';
408
+ }
409
+ let htmlString = template.data.content;
410
+ if (jsonData) {
411
+ jsonData.list.map(data => {
412
+ const cssStyle = template.data.tags.find(item => item.key === data.key);
413
+ const regex = new RegExp(`@{{${data.key}}}`, 'g');
414
+ htmlString = htmlString.replace(
415
+ regex,
416
+ html`<span
417
+ style="font-size: ${cssStyle?.font_size ?? 16}px; color: ${cssStyle?.font_color ??
418
+ '${titleFontColor}'}; background: ${cssStyle?.font_bgr ?? '#fff'};"
419
+ >${data.value}</span
420
+ >`
421
+ );
422
+ });
423
+ }
424
+ return htmlString.replace(/@{{[^}]+}}/g, '');
425
+ },
426
+ divCreate: {
427
+ style:
428
+ (() => {
429
+ if (PdClass.isPad()) {
430
+ return 'margin: 0 60px;';
431
+ }
432
+ if (PdClass.isPhone()) {
433
+ return '';
434
+ }
435
+ return 'margin: 0 10%;';
436
+ })() + `max-width:100%;word-break: break-all;white-space: normal;`,
437
+ class: `pd_detail_content fr-view`,
438
+ },
439
+ })}
440
+ </div>
441
+ <div style="margin-top: 150px;"></div>
442
+ ${(prod.relative_product ?? []).length
443
+ ? gvc.bindView(() => {
444
+ const swipID = gvc.glitter.getUUID();
445
+ return {
446
+ bind: gvc.glitter.getUUID(),
447
+ view: async () => {
448
+ return new Promise(async (resolve, reject) => {
449
+ const product = (
450
+ await ApiShop.getProduct({
451
+ limit: 50,
452
+ page: 0,
453
+ id_list: prod.relative_product.join(','),
454
+ })
455
+ ).response.data;
456
+ setTimeout(() => {
457
+ const swiper = new (window as any).Swiper('#' + swipID, {
458
+ slidesPerView: glitter.ut.frSize(
459
+ {
460
+ sm: product.length < 4 ? product.length : 4,
461
+ lg: product.length < 6 ? product.length : 6,
462
+ },
463
+ product.length < 2 ? product.length : 2
464
+ ),
465
+ spaceBetween: glitter.ut.frSize(
466
+ {
467
+ sm: 10,
468
+ lg: 30,
469
+ },
470
+ 10
471
+ ),
472
+ });
473
+ }, 100);
474
+ if (!product.length) {
475
+ return ``;
476
+ }
477
+ resolve(html`
478
+ <div class="w-100 d-flex align-items-center justify-content-center ">
479
+ <div
480
+ class="mx-auto"
481
+ style="flex-direction: column; justify-content: flex-start; align-items: center; gap: 8px; display: inline-flex"
482
+ >
483
+ <div
484
+ style="font-size:18px;align-self: stretch; text-align: center; color: ${ProductModule.titleFontColor}; font-weight: 700; line-height: 18px; word-wrap: break-word;white-space: nowrap;margin: 0 20px;"
485
+ >
486
+ ${Language.text('related_products')}
487
+ </div>
488
+ <div
489
+ style="align-self: stretch; height: 0px; border: 1px ${ProductModule.titleFontColor} solid"
490
+ ></div>
491
+ </div>
492
+ </div>
493
+ <div class="w-100 row p-0 align-items-center justify-content-center mt-4 mt-lg-4 mx-0">
494
+ ${product
495
+ .map((dd: any) => {
496
+ return html`<div class="col-6 col-sm-4 col-lg-3">
497
+ ${glitter.htmlGenerate.renderComponent({
498
+ appName: (window as any).appName,
499
+ tag: 'product_widget',
500
+ gvc: gvc,
501
+ subData: dd,
502
+ })}
503
+ </div>`;
504
+ })
505
+ .join('')}
506
+ </div>
507
+ `);
508
+ });
509
+ },
510
+ divCreate: {
511
+ class: `w-100`,
512
+ },
513
+ onCreate: () => {},
514
+ };
515
+ })
516
+ : ''}
517
+ <div style="margin-top: 100px;"></div>
518
+ </div>`;
519
+ },
520
+ divCreate: {
521
+ style: css`
522
+ min-height: 1000px;
523
+ word-break: break-all;
524
+ white-space: normal;
525
+ `,
526
+ class: `container`,
527
+ },
528
+ onCreate: () => {
529
+ if (loadings.page) {
530
+ const title = glitter.getUrlParameter('page').split('products/')[1];
531
+ if (title || product_id) {
532
+ const inputObj = {
533
+ page: 0,
534
+ limit: 1,
535
+ collection: '',
536
+ maxPrice: '',
537
+ minPrice: '',
538
+ ...(() => {
539
+ if (product_id) {
540
+ return { id: product_id };
541
+ } else {
542
+ return { domain: decodeURIComponent(title) };
543
+ }
544
+ })(),
545
+ status: 'inRange',
546
+ channel: 'normal',
547
+ orderBy: '',
548
+ with_hide_index: 'true',
549
+ show_hidden: true,
550
+ view_source: 'normal',
551
+ distribution_code: localStorage.getItem('distributionCode') ?? '',
552
+ };
572
553
 
573
- Promise.all([
574
- // 商品描述
575
- ApiUser.getPublicConfig('text-manager', 'manager', (window as any).appName),
576
- // 商品詳細資料
577
- ApiShop.getProduct(inputObj),
578
- // 心願單
579
- ApiShop.getWishList(),
580
- ]).then((results) => {
581
- const [publicConfig, productData, wishListData] = results;
554
+ Promise.all([
555
+ // 商品描述
556
+ ApiUser.getPublicConfig('text-manager', 'manager', (window as any).appName),
557
+ // 商品詳細資料
558
+ ApiShop.getProduct(inputObj),
559
+ // 心願單
560
+ ApiShop.getWishList(),
561
+ ]).then(results => {
562
+ const [publicConfig, productData, wishListData] = results;
582
563
 
583
- if (publicConfig.result && publicConfig.response.value) {
584
- vm.content_manager = publicConfig.response.value;
585
- }
586
- if (productData.result && productData.response.data) {
587
- try {
588
- if (Array.isArray(productData.response.data)) {
589
- vm.data = productData.response.data[0];
590
- } else {
591
- vm.data = productData.response.data;
592
- }
593
- glitter.setUrlParameter(
594
- 'page',
595
- 'products/' + encodeURIComponent(vm.data.content.seo.domain || vm.data.content.title),
596
- [(window as any).home_seo.title_prefix ?? '', vm.data.content.seo.domain || vm.data.content.title, (window as any).home_seo.title_suffix ?? ''].join('')
597
- );
598
- //如有原先的JSON LD
599
- // setTimeout(()=>{
600
- // const json_ld = document.querySelector('script[type="application/ld+json"]');
601
- // if (json_ld) {
602
- // json_ld.remove();
603
- // };
604
- // (document.querySelector('head') as any).innerHTML += (vm.data as any).json_ld;
605
- // },1000)
606
- } catch (e) {
607
- (vm.data as any) = {};
608
- }
609
- }
610
- if (wishListData.result && wishListData.response.data) {
611
- vm.wishStatus = wishListData.response.data.some((item: Product_l) => item.id === vm.data.id);
612
- }
613
- loadings.page = false;
614
- gvc.notifyDataChange(ids.page);
615
- });
616
- }
564
+ if (publicConfig.result && publicConfig.response.value) {
565
+ vm.content_manager = publicConfig.response.value;
566
+ }
567
+ if (productData.result && productData.response.data) {
568
+ try {
569
+ if (Array.isArray(productData.response.data)) {
570
+ vm.data = productData.response.data[0];
571
+ } else {
572
+ vm.data = productData.response.data;
573
+ }
574
+ glitter.setUrlParameter(
575
+ 'page',
576
+ 'products/' + encodeURIComponent(vm.data.content.seo.domain || vm.data.content.title),
577
+ [
578
+ (window as any).home_seo.title_prefix ?? '',
579
+ vm.data.content.seo.domain || vm.data.content.title,
580
+ (window as any).home_seo.title_suffix ?? '',
581
+ ].join('')
582
+ );
583
+ //如有原先的JSON LD
584
+ // setTimeout(()=>{
585
+ // const json_ld = document.querySelector('script[type="application/ld+json"]');
586
+ // if (json_ld) {
587
+ // json_ld.remove();
588
+ // };
589
+ // (document.querySelector('head') as any).innerHTML += (vm.data as any).json_ld;
590
+ // },1000)
591
+ } catch (e) {
592
+ (vm.data as any) = {};
617
593
  }
618
- },
619
- });
620
- }
594
+ }
595
+ if (wishListData.result && wishListData.response.data) {
596
+ vm.wishStatus = wishListData.response.data.some((item: Product_l) => item.id === vm.data.id);
597
+ }
598
+ loadings.page = false;
599
+ gvc.notifyDataChange(ids.page);
600
+ });
601
+ }
602
+ }
603
+ },
604
+ });
605
+ }
621
606
  }
622
607
 
623
608
  (window as any).glitter.setModule(import.meta.url, ProductDetail);