ts-glitter 21.8.2 → 21.8.4

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 (42) hide show
  1. package/lowcode/Entry.js +1 -1
  2. package/lowcode/Entry.ts +1 -1
  3. package/lowcode/backend-manager/bg-dialog.js +342 -100
  4. package/lowcode/backend-manager/bg-dialog.ts +432 -145
  5. package/lowcode/backend-manager/bg-widget.js +4 -4
  6. package/lowcode/backend-manager/bg-widget.ts +5 -5
  7. package/lowcode/cms-plugin/shopping-discount-setting.js +148 -92
  8. package/lowcode/cms-plugin/shopping-discount-setting.ts +162 -111
  9. package/lowcode/cms-plugin/shopping-product-stock.js +58 -45
  10. package/lowcode/cms-plugin/shopping-product-stock.ts +66 -49
  11. package/lowcode/css/editor.css +8 -9
  12. package/lowcode/editor/basic-component.js +0 -5
  13. package/lowcode/editor/basic-component.ts +1 -6
  14. package/lowcode/glitter-base/route/article.js +50 -51
  15. package/lowcode/glitter-base/route/article.ts +102 -103
  16. package/lowcode/glitter-base/route/recommend.js +1 -0
  17. package/lowcode/glitter-base/route/recommend.ts +141 -123
  18. package/lowcode/modules/image-library-clone.ts +2 -0
  19. package/lowcode/modules/image-library.js +118 -155
  20. package/lowcode/modules/image-library.ts +134 -197
  21. package/lowcode/public-components/layout-plugin/social-links-01.js +23 -44
  22. package/lowcode/public-components/layout-plugin/social-links-01.ts +23 -48
  23. package/package.json +1 -1
  24. package/src/api-public/controllers/article.js +11 -0
  25. package/src/api-public/controllers/article.js.map +1 -1
  26. package/src/api-public/controllers/article.ts +13 -0
  27. package/src/api-public/controllers/recommend.js +1 -0
  28. package/src/api-public/controllers/recommend.js.map +1 -1
  29. package/src/api-public/controllers/recommend.ts +99 -89
  30. package/src/api-public/services/checkout-event.js +4 -3
  31. package/src/api-public/services/checkout-event.js.map +1 -1
  32. package/src/api-public/services/checkout-event.ts +11 -7
  33. package/src/api-public/services/post.js +7 -17
  34. package/src/api-public/services/post.js.map +1 -1
  35. package/src/api-public/services/recommend.d.ts +1 -0
  36. package/src/api-public/services/recommend.js +12 -2
  37. package/src/api-public/services/recommend.js.map +1 -1
  38. package/src/api-public/services/recommend.ts +375 -354
  39. package/src/api-public/services/shopping.d.ts +1 -0
  40. package/src/api-public/services/shopping.js +4 -2
  41. package/src/api-public/services/shopping.js.map +1 -1
  42. package/src/api-public/services/shopping.ts +7 -2
package/lowcode/Entry.js CHANGED
@@ -146,7 +146,7 @@ export class Entry {
146
146
  }
147
147
  window.renderClock = (_b = window.renderClock) !== null && _b !== void 0 ? _b : createClock();
148
148
  console.log(`Entry-time:`, window.renderClock.stop());
149
- glitter.share.editerVersion = 'V_21.8.2';
149
+ glitter.share.editerVersion = 'V_21.8.4';
150
150
  glitter.share.start = new Date();
151
151
  const vm = { appConfig: [] };
152
152
  window.saasConfig = {
package/lowcode/Entry.ts CHANGED
@@ -150,7 +150,7 @@ export class Entry {
150
150
  }
151
151
  (window as any).renderClock = (window as any).renderClock ?? createClock();
152
152
  console.log(`Entry-time:`, (window as any).renderClock.stop());
153
- glitter.share.editerVersion = 'V_21.8.2';
153
+ glitter.share.editerVersion = 'V_21.8.4';
154
154
  glitter.share.start = new Date();
155
155
  const vm = { appConfig: [] };
156
156
  (window as any).saasConfig = {
@@ -1,5 +1,9 @@
1
+ import { ShareDialog } from '../glitterBundle/dialog/ShareDialog.js';
1
2
  import { Tool } from '../modules/tool.js';
3
+ import { BgWidget } from './bg-widget.js';
2
4
  import { Animation } from '../glitterBundle/module/Animation.js';
5
+ import { Article } from '../glitter-base/route/article.js';
6
+ import { ApiRecommend } from '../glitter-base/route/recommend.js';
3
7
  const html = String.raw;
4
8
  const css = String.raw;
5
9
  export class BgDialog {
@@ -11,13 +15,19 @@ export class BgDialog {
11
15
  this.init();
12
16
  }
13
17
  init() {
14
- this.gvc.addStyle(css `
18
+ this.gvc.addStyle(`
15
19
  .${this.prefix}_body {
16
20
  border-radius: 10px;
17
21
  background: #fff;
18
22
  overflow-y: auto;
19
- min-width: calc(100vw - 180px);
20
- max-width: calc(100vw - 20px);
23
+ ${this.isMobile
24
+ ? `
25
+ width: calc(100vw - 20px);
26
+ `
27
+ : `
28
+ min-width: calc(100vw - 40%);
29
+ max-width: calc(100vw - 20px);
30
+ `}
21
31
  }
22
32
 
23
33
  .${this.prefix}_header {
@@ -28,21 +38,29 @@ export class BgDialog {
28
38
  padding: 12px 20px;
29
39
  }
30
40
 
31
- .${this.prefix}_btn {
41
+ .${this.prefix}_main {
42
+ max-height: 540px;
43
+ border: 20px solid #fff;
44
+ gap: 0;
45
+ position: relative;
46
+ }
47
+
48
+ .${this.prefix}_triple_bar {
32
49
  display: flex;
33
- padding: 3.25px 18px;
34
- align-items: center;
35
- gap: 8px;
36
- border-radius: 10px;
50
+ flex-direction: column;
51
+ position: sticky;
52
+ top: 0;
53
+ background-color: #fff;
37
54
  }
38
55
 
39
- .${this.prefix}_save {
40
- background: #393939;
56
+ .${this.prefix}_param_bar {
57
+ display: flex;
58
+ margin-top: 8px;
59
+ gap: 10px;
41
60
  }
42
61
 
43
- .${this.prefix}_cancel {
44
- background: #fff;
45
- border: 1px solid #ddd;
62
+ .${this.prefix}_checkbox_container {
63
+ min-height: 353px;
46
64
  }
47
65
 
48
66
  .${this.prefix}_footer {
@@ -62,115 +80,339 @@ export class BgDialog {
62
80
  display: flex;
63
81
  align-items: center;
64
82
  justify-content: end;
65
- gap: 14px;
83
+ gap: ${this.isMobile ? 8 : 14}px;
84
+ }
85
+
86
+ .${this.prefix}_view_all {
87
+ color: #4d86db;
88
+ font-size: 16px;
89
+ font-weight: 400;
90
+ cursor: pointer;
91
+ overflow-wrap: break-word;
92
+ }
93
+
94
+ .${this.prefix}_clear_all {
95
+ margin-right: 8px;
96
+ font-size: 16px;
97
+ text-decoration: underline;
98
+ cursor: pointer;
99
+ }
100
+
101
+ .${this.prefix}_icon {
102
+ width: 16px;
103
+ height: 16px;
104
+ margin-right: 8px;
105
+ text-align: center;
66
106
  }
67
107
  `);
68
108
  }
69
- static select(obj) {
70
- return html ` <select
71
- class="c_select c_select_w_100"
72
- onchange="${obj.gvc.event(e => {
73
- return obj.callback(e.value);
74
- })}"
75
- >
76
- ${obj.options
77
- .map(opt => {
78
- return html ` <option class="c_select_option" value="${opt.key}" ${obj.default === opt.key ? 'selected' : ''}>
79
- ${opt.value}
80
- </option>`;
81
- })
82
- .join('')}
83
- ${obj.options.find(opt => obj.default === opt.key)
84
- ? ''
85
- : html `<option class="d-none" selected>請選擇項目</option>`}
86
- </select>`;
87
- }
88
- save(event, text = '完成') {
89
- return html ` <button class="btn ${this.prefix}_btn ${this.prefix}_save" type="button" onclick="${event}">
90
- <span class="tx_700_white">${text}</span>
91
- </button>`;
92
- }
93
- cancal(event, text = '取消') {
94
- return html ` <button class="btn ${this.prefix}_btn ${this.prefix}_cancel" type="button" onclick="${event}">
95
- <span class="tx_700">${text}</span>
96
- </button>`;
97
- }
98
- viewAllSelect(event, text = '檢視已選取項目') {
99
- return html `<span
100
- style="color: #4D86DB; font-size: 16px; font-weight: 400; cursor:pointer; overflow-wrap: break-word;"
101
- onclick="${event}"
102
- >${text}</span
103
- >`;
109
+ viewAll(event, text = '檢視已選取項目') {
110
+ return html `<span class="${this.prefix}_view_all" onclick="${event}">${text}</span>`;
104
111
  }
105
112
  clearAll(event, text = '清除全部') {
106
- return html `<span style="margin-right: 8px; font-size: 16px; text-decoration: underline;" onclick="${event}"
107
- >${text}</span
108
- >`;
113
+ return html `<span class="${this.prefix}_clear_all" onclick="${event}">${text}</span>`;
109
114
  }
110
- marketShop() {
115
+ shopTypeRecord() {
116
+ return {
117
+ hidden: {
118
+ key: 'hidden',
119
+ icon: html `<i class="fa-solid fa-face-dotted ${this.prefix}_icon"></i>`,
120
+ title: '隱形賣場',
121
+ },
122
+ onepage: {
123
+ key: 'onepage',
124
+ icon: html `<i class="fa-regular fa-file ${this.prefix}_icon"></i>`,
125
+ title: '一頁商店',
126
+ },
127
+ group: {
128
+ key: 'group',
129
+ icon: html `<i class="fa-regular fa-puzzle-piece ${this.prefix}_icon"></i>`,
130
+ title: '拼團賣場',
131
+ },
132
+ recommend: {
133
+ key: 'recommend',
134
+ icon: html `<i class="fa-regular fa-share-nodes ${this.prefix}_icon"></i>`,
135
+ title: '分銷連結',
136
+ },
137
+ };
138
+ }
139
+ marketShop(args) {
111
140
  const gvc = this.gvc;
112
141
  const glitter = this.glitter;
113
- const marketOptions = [
114
- { key: 'hidden', value: '隱形賣場' },
115
- { key: 'onepage', value: '一頁商店' },
116
- { key: 'group', value: '拼團賣場' },
117
- { key: 'recommend', value: '分銷連結' },
118
- ];
119
- return glitter.innerDialog((gvc) => {
120
- const vm = {
121
- id: gvc.glitter.getUUID(),
122
- loading: false,
142
+ const dialog = new ShareDialog(glitter);
143
+ const vm = {
144
+ controllerId: glitter.getUUID(),
145
+ control: 'view',
146
+ mainId: glitter.getUUID(),
147
+ selectedId: glitter.getUUID(),
148
+ loading: true,
149
+ pageType: 'hidden',
150
+ searchType: 'title',
151
+ search: '',
152
+ orderString: '',
153
+ dataList: [],
154
+ filterList: [],
155
+ postData: args.def,
156
+ filterData: [],
157
+ };
158
+ const marketOptions = Object.values(this.shopTypeRecord())
159
+ .filter(item => item.key !== 'group')
160
+ .map(item => {
161
+ return {
162
+ key: item.key,
163
+ value: item.title,
123
164
  };
124
- return html ` <div class="${this.prefix}_body">
125
- ${gvc.bindView({
126
- bind: vm.id,
165
+ });
166
+ const searchTypeOptions = [{ key: 'title', value: '賣場名稱' }];
167
+ const resetPostData = () => {
168
+ vm.postData = [
169
+ ...new Set(vm.postData
170
+ .filter(key => {
171
+ return !vm.filterList.some(item => item.key === key);
172
+ })
173
+ .concat(vm.filterData)),
174
+ ];
175
+ };
176
+ const selectedView = (gvc) => {
177
+ const selectedList = vm.dataList.filter(item => vm.postData.includes(item.key));
178
+ const bindView = gvc.bindView({
179
+ bind: vm.selectedId,
127
180
  view: () => {
128
- if (vm.loading) {
129
- return 'Loading';
130
- }
131
181
  return html ` <div class="${this.prefix}_header">
132
- <div class="tx_700">產品列表</div>
133
- <div class="flex-fill"></div>
182
+ <div class="tx_700">賣場列表</div>
183
+ <div class="flex-fill"></div>
184
+ </div>
185
+ <div class="c_dialog">
186
+ <div class="c_dialog_body">
187
+ <div class="c_dialog_main ${this.prefix}_main">
188
+ <div class="${this.prefix}_triple_bar">
189
+ ${[
190
+ BgWidget.tripletCheckboxContainer(gvc, '賣場名稱', (() => {
191
+ if (vm.postData.length === 0)
192
+ return -1;
193
+ return vm.postData.length === selectedList.length ? 1 : 0;
194
+ })(), r => {
195
+ vm.postData = r === 1 ? selectedList.map(({ key }) => key) : [];
196
+ gvc.notifyDataChange(vm.selectedId);
197
+ }),
198
+ BgWidget.horizontalLine({ margin: 0.5 }),
199
+ ].join('')}
200
+ </div>
201
+ <div class="${this.prefix}_checkbox_container">
202
+ ${BgWidget.multiCheckboxContainer(gvc, selectedList, vm.postData, text => {
203
+ vm.postData = text;
204
+ gvc.notifyDataChange(vm.selectedId);
205
+ })}
206
+ </div>
207
+ </div>
208
+ <div class="${this.prefix}_footer">
209
+ <div class="${this.prefix}_footer_left">
210
+ ${this.viewAll(gvc.event(() => {
211
+ gvc.closeDialog();
212
+ vm.control = 'view';
213
+ }), '繼續選擇')}
214
+ </div>
215
+ <div class="${this.prefix}_footer_right">
216
+ ${[
217
+ this.clearAll(gvc.event(() => {
218
+ if (vm.postData.length > 0) {
219
+ dialog.checkYesOrNot({
220
+ text: '確定要清除所有已選取的選項嗎?',
221
+ callback: bool => {
222
+ if (bool) {
223
+ vm.postData = [];
224
+ gvc.notifyDataChange(vm.selectedId);
225
+ }
226
+ },
227
+ });
228
+ }
229
+ }), this.isMobile ? '全刪' : '清除全部'),
230
+ BgWidget.cancel(gvc.event(() => {
231
+ gvc.closeDialog();
232
+ })),
233
+ BgWidget.save(gvc.event(() => {
234
+ args.callback(vm.postData);
235
+ gvc.closeDialog();
236
+ }), '完成'),
237
+ ].join('')}
238
+ </div>
134
239
  </div>
135
- <div class="c_dialog">
136
- <div class="c_dialog_body">
137
- <div class="c_dialog_main" style="height: auto; max-height: 500px; gap: 24px;">
138
- ${BgDialog.select({
240
+ </div>
241
+ </div>`;
242
+ },
243
+ });
244
+ return html `<div class="${this.prefix}_body">${bindView}</div>`;
245
+ };
246
+ const dialogView = (gvc) => {
247
+ const bindView = gvc.bindView({
248
+ bind: vm.mainId,
249
+ view: () => {
250
+ if (vm.loading) {
251
+ return html `<div class="my-4">${BgWidget.spinner()}</div>`;
252
+ }
253
+ vm.filterList = vm.dataList.filter(item => item.key.includes(vm.pageType) && item.realname.includes(vm.search));
254
+ vm.filterData = vm.postData.filter(key => vm.filterList.find(item => item.key === key));
255
+ const pageTypeSelect = BgWidget.select({
139
256
  gvc,
140
- default: marketOptions[0].key,
257
+ default: vm.pageType,
141
258
  options: marketOptions,
142
259
  callback: value => {
143
- console.log(value);
260
+ vm.pageType = value;
261
+ vm.search = '';
262
+ gvc.notifyDataChange(vm.mainId);
263
+ },
264
+ });
265
+ const searchTypeSelect = BgWidget.select({
266
+ gvc,
267
+ default: vm.searchType,
268
+ options: searchTypeOptions,
269
+ callback: value => {
270
+ vm.searchType = value;
271
+ gvc.notifyDataChange(vm.mainId);
144
272
  },
273
+ style: 'max-width: 120px;',
274
+ });
275
+ const searchPlace = BgWidget.searchPlace(gvc.event(e => {
276
+ vm.search = e.value;
277
+ gvc.notifyDataChange(vm.mainId);
278
+ }), vm.search || '', '搜尋賣場名稱', '0', '0');
279
+ return html ` <div class="${this.prefix}_header">
280
+ <div class="tx_700">賣場列表</div>
281
+ <div class="flex-fill"></div>
282
+ </div>
283
+ <div class="c_dialog">
284
+ <div class="c_dialog_body">
285
+ <div class="c_dialog_main ${this.prefix}_main">
286
+ <div class="${this.prefix}_triple_bar">
287
+ ${this.isMobile
288
+ ? html ` <div class="${this.prefix}_param_bar">${[pageTypeSelect, searchTypeSelect].join('')}</div>
289
+ <div class="w-100 mt-2">${searchPlace}</div>`
290
+ : html `${pageTypeSelect}
291
+ <div class="${this.prefix}_param_bar">
292
+ ${[searchTypeSelect, html `<div class="w-100">${searchPlace}</div>`].join('')}
293
+ </div>`}
294
+ ${[
295
+ BgWidget.mbContainer(12),
296
+ BgWidget.tripletCheckboxContainer(gvc, '賣場名稱', (() => {
297
+ if (vm.filterData.length === 0)
298
+ return -1;
299
+ return vm.filterData.length === vm.filterList.length ? 1 : 0;
300
+ })(), r => {
301
+ vm.filterData = r === 1 ? vm.filterList.map(({ key }) => key) : [];
302
+ resetPostData();
303
+ gvc.notifyDataChange(vm.mainId);
304
+ }),
305
+ BgWidget.horizontalLine({ margin: 0.5 }),
306
+ ].join('')}
307
+ </div>
308
+ <div class="${this.prefix}_checkbox_container">
309
+ ${BgWidget.multiCheckboxContainer(gvc, vm.filterList, vm.filterData, text => {
310
+ vm.filterData = text;
311
+ resetPostData();
312
+ gvc.notifyDataChange(vm.mainId);
145
313
  })}
146
- </div>
147
- <div class="${this.prefix}_footer">
148
- <div class="${this.prefix}_footer_left">
149
- ${this.viewAllSelect(gvc.event(() => {
150
- console.log('viewAllSelect');
151
- }), '檢視已選商品(12)')}
152
- </div>
153
- <div class="${this.prefix}_footer_right">
154
- ${[
314
+ </div>
315
+ </div>
316
+ <div class="${this.prefix}_footer">
317
+ <div class="${this.prefix}_footer_left">
318
+ ${this.viewAll(gvc.event(() => {
319
+ if (vm.postData.length > 0) {
320
+ gvc.closeDialog();
321
+ vm.control = 'selected';
322
+ }
323
+ }), this.isMobile ? `檢視(${vm.postData.length})` : `檢視已選賣場(${vm.postData.length})`)}
324
+ </div>
325
+ <div class="${this.prefix}_footer_right">
326
+ ${[
155
327
  this.clearAll(gvc.event(() => {
156
- console.log('clearAll');
157
- })),
158
- this.cancal(gvc.event(() => {
159
- console.log('cancal');
160
- })),
161
- this.save(gvc.event(() => {
162
- console.log('save');
328
+ if (vm.postData.length > 0) {
329
+ dialog.checkYesOrNot({
330
+ text: '確定要清除所有已選取的選項嗎?',
331
+ callback: bool => {
332
+ if (bool) {
333
+ vm.postData = [];
334
+ gvc.notifyDataChange(vm.mainId);
335
+ }
336
+ },
337
+ });
338
+ }
339
+ }), this.isMobile ? '全刪' : '清除全部'),
340
+ BgWidget.cancel(gvc.event(() => {
341
+ gvc.closeDialog();
163
342
  })),
343
+ BgWidget.save(gvc.event(() => {
344
+ args.callback(vm.postData);
345
+ gvc.closeDialog();
346
+ }), '完成'),
164
347
  ].join('')}
165
- </div>
166
- </div>
167
348
  </div>
168
- </div>`;
349
+ </div>
350
+ </div>
351
+ </div>`;
352
+ },
353
+ onCreate: () => {
354
+ if (vm.loading) {
355
+ vm.dataList = [];
356
+ Promise.all([
357
+ Article.get({
358
+ page: 0,
359
+ limit: 9999,
360
+ search: vm.search || undefined,
361
+ status: '0,1',
362
+ }),
363
+ ApiRecommend.getList({
364
+ page: 0,
365
+ limit: 9999,
366
+ data: {},
367
+ token: window.parent.config.token,
368
+ }),
369
+ ]).then(dataArray => {
370
+ var _a, _b;
371
+ const [article, recommend] = dataArray;
372
+ const shopTypeRecord = this.shopTypeRecord();
373
+ if (Array.isArray((_a = article.response) === null || _a === void 0 ? void 0 : _a.data)) {
374
+ article.response.data.map((item) => {
375
+ if (['hidden', 'shopping'].includes(item.content.page_type)) {
376
+ const pageType = item.content.page_type === 'hidden' ? 'hidden' : 'onepage';
377
+ vm.dataList.push({
378
+ key: `${pageType}-${item.id}`,
379
+ name: `${shopTypeRecord[pageType].icon}${item.content.name}`,
380
+ realname: item.content.name,
381
+ });
382
+ }
383
+ });
384
+ }
385
+ if (Array.isArray((_b = recommend.response) === null || _b === void 0 ? void 0 : _b.data)) {
386
+ recommend.response.data.map((item) => {
387
+ vm.dataList.push({
388
+ key: `recommend-${item.id}`,
389
+ name: `${shopTypeRecord.recommend.icon}${item.content.title}`,
390
+ realname: item.content.title,
391
+ });
392
+ });
393
+ }
394
+ vm.loading = false;
395
+ gvc.notifyDataChange(vm.mainId);
396
+ });
397
+ }
169
398
  },
170
- })}
171
- </div>`;
172
- }, gvc.glitter.getUUID(), {
173
- animation: Animation.fade,
399
+ });
400
+ return html `<div class="${this.prefix}_body">${bindView}</div>`;
401
+ };
402
+ return gvc.bindView({
403
+ bind: vm.controllerId,
404
+ dataList: [{ obj: vm, key: 'control' }],
405
+ view: () => {
406
+ switch (vm.control) {
407
+ case 'selected':
408
+ glitter.innerDialog(selectedView, glitter.getUUID(), { animation: Animation.fade });
409
+ break;
410
+ case 'view':
411
+ glitter.innerDialog(dialogView, glitter.getUUID(), { animation: Animation.fade });
412
+ break;
413
+ }
414
+ return '';
415
+ },
174
416
  });
175
417
  }
176
418
  }