ts-glitter 21.4.4 → 21.4.6

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 (39) hide show
  1. package/lowcode/Entry.js +18 -18
  2. package/lowcode/Entry.ts +18 -19
  3. package/lowcode/backend-manager/bg-product.js +8 -6
  4. package/lowcode/backend-manager/bg-product.ts +17 -15
  5. package/lowcode/backend-manager/bg-recommend.js +16 -5
  6. package/lowcode/backend-manager/bg-recommend.ts +15 -5
  7. package/lowcode/backend-manager/bg-widget.js +160 -160
  8. package/lowcode/backend-manager/bg-widget.ts +169 -166
  9. package/lowcode/cms-plugin/POS-setting.js +75 -23
  10. package/lowcode/cms-plugin/POS-setting.ts +87 -30
  11. package/lowcode/cms-plugin/menus-setting.js +165 -37
  12. package/lowcode/cms-plugin/menus-setting.ts +144 -21
  13. package/lowcode/cms-plugin/module/order-excel.js +8 -8
  14. package/lowcode/cms-plugin/module/order-excel.ts +10 -10
  15. package/lowcode/cms-plugin/module/stock-excel.js +184 -0
  16. package/lowcode/cms-plugin/module/stock-excel.ts +205 -0
  17. package/lowcode/cms-plugin/module/vendor-excel.js +375 -0
  18. package/lowcode/cms-plugin/module/vendor-excel.ts +450 -0
  19. package/lowcode/cms-plugin/order/order-module.js +6 -4
  20. package/lowcode/cms-plugin/order/order-module.ts +16 -14
  21. package/lowcode/cms-plugin/pos-pages/models.ts +6 -2
  22. package/lowcode/cms-plugin/pos-pages/products-page.js +589 -469
  23. package/lowcode/cms-plugin/pos-pages/products-page.ts +657 -491
  24. package/lowcode/cms-plugin/shopping-product-setting.js +7 -10
  25. package/lowcode/cms-plugin/shopping-product-setting.ts +12 -10
  26. package/lowcode/cms-plugin/shopping-setting-basic.js +2 -5
  27. package/lowcode/cms-plugin/shopping-setting-basic.ts +2 -5
  28. package/lowcode/cms-plugin/stock-history.js +39 -26
  29. package/lowcode/cms-plugin/stock-history.ts +58 -49
  30. package/lowcode/cms-plugin/stock-vendors.js +18 -13
  31. package/lowcode/cms-plugin/stock-vendors.ts +31 -16
  32. package/lowcode/glitterBundle/html-component/global-widget.js +162 -136
  33. package/lowcode/glitterBundle/html-component/global-widget.ts +430 -382
  34. package/lowcode/public-components/blogs/blogs-01.js +22 -9
  35. package/lowcode/public-components/blogs/blogs-01.ts +28 -14
  36. package/package.json +1 -1
  37. package/src/api-public/services/schedule.js +6 -1
  38. package/src/api-public/services/schedule.js.map +1 -1
  39. package/src/api-public/services/schedule.ts +4 -1
@@ -4,6 +4,8 @@ import { ApiUser } from '../glitter-base/route/user.js';
4
4
  import { EditorElem } from '../glitterBundle/plugins/editor-elem.js';
5
5
  import { LanguageLocation } from '../glitter-base/global/language.js';
6
6
  import { LanguageBackend } from './language-backend.js';
7
+ import { ShareDialog } from '../glitterBundle/dialog/ShareDialog.js';
8
+ import { AiChat } from '../glitter-base/route/ai-chat.js';
7
9
 
8
10
  const html = String.raw;
9
11
 
@@ -23,13 +25,15 @@ export class MenusSetting {
23
25
  index: number;
24
26
  dataList: any;
25
27
  query?: string;
28
+ select:{title:string,tag:string}
26
29
  tab:'menu'|'footer'
27
30
  } = {
28
31
  type: 'list',
29
32
  index: 0,
30
33
  dataList: undefined,
31
34
  query: '',
32
- tab:'menu'
35
+ tab:'menu',
36
+ select:{title:'',tag:''}
33
37
  };
34
38
  const filterID = gvc.glitter.getUUID();
35
39
  let vmi: any = undefined;
@@ -56,19 +60,65 @@ export class MenusSetting {
56
60
  dataList: [{ obj: vm, key: 'type' }],
57
61
  view: () => {
58
62
  if (vm.type === 'list') {
63
+
59
64
  return BgWidget.container(html`
60
65
  <div class="title-container">
61
66
  ${BgWidget.title('選單管理')}
62
67
  <div class="flex-fill"></div>
63
- ${false
64
- ? BgWidget.darkButton(
65
- '新增',
66
- gvc.event(() => {
67
- vm.type = 'add';
68
- gvc.notifyDataChange(id);
69
- })
70
- )
71
- : ''}
68
+ ${BgWidget.darkButton(
69
+ `新增${vm.tab==='menu' ? `頁首選單`:`頁腳選單`}`,
70
+ gvc.event(async () => {
71
+ let title=''
72
+ async function next(){
73
+ const dialog=new ShareDialog(gvc.glitter)
74
+ dialog.dataLoading({visible:true})
75
+ const tab=vm.tab==='menu' ? `頁首選單`:`頁腳選單`
76
+ let menu_all=(await ApiUser.getPublicConfig('menu-setting-list','manager')).response.value;
77
+ menu_all.list=menu_all.list ?? [];
78
+ menu_all.list=[
79
+ {
80
+ tag:gvc.glitter.getUUID(),
81
+ title:[tab,`${menu_all.list.length+1}`].join(''),
82
+ tab:vm.tab==='menu' ? 'menu-setting':'footer-setting'
83
+ }
84
+ ].concat(menu_all.list);
85
+ await ApiUser.setPublicConfig({
86
+ key:'menu-setting-list',
87
+ value:menu_all,
88
+ user_id:'manager'
89
+ });
90
+ dialog.dataLoading({visible:false});
91
+ gvc.notifyDataChange(id)
92
+ }
93
+ BgWidget.settingDialog({
94
+ gvc: gvc,
95
+ title: '選單名稱',
96
+ innerHTML: (gvc: GVC) => {
97
+ return [
98
+ BgWidget.editeInput({
99
+ title:'',
100
+ callback:(text)=>{
101
+ title=text
102
+ },
103
+ default:title,
104
+ gvc:gvc,
105
+ placeHolder:'請輸入選單名稱'
106
+ })
107
+ ].join('')
108
+ },
109
+ footer_html: (gvc: GVC) => {
110
+ return BgWidget.save(gvc.event(()=>{
111
+ next()
112
+ gvc.closeDialog()
113
+ }),'儲存')
114
+ },
115
+ width: 300
116
+ })
117
+
118
+ // vm.index = index;
119
+ // vm.type = 'replace';
120
+ })
121
+ )}
72
122
  </div>
73
123
  ${BgWidget.tab(
74
124
  [
@@ -81,18 +131,26 @@ export class MenusSetting {
81
131
  vm.tab=text as any
82
132
  gvc.notifyDataChange(id);
83
133
  },
84
- `margin-bottom:0px !important;`
134
+ `${document.body.clientWidth<800 ? ``:`margin-bottom:0px !important;`}
135
+ `
85
136
  )}
86
137
  ${BgWidget.container(
87
138
  BgWidget.mainCard(
88
139
  BgWidget.tableV3({
89
140
  gvc: gvc,
90
- getData: vmi => {
141
+ getData: async (vmi) => {
142
+ const tag=vm.tab==='menu' ? 'menu-setting':'footer-setting'
143
+ let menu_all= (await ApiUser.getPublicConfig('menu-setting-list','manager')).response.value;
144
+ menu_all.list = menu_all.list ?? [];
91
145
  vm.dataList = [
92
- { tag: vm.tab==='menu' ? 'menu-setting':'footer-setting', title: `
146
+ { tag: tag, title: `
93
147
  <div> ${vm.tab==='menu' ? `頁首選單`:`頁腳選單`} <span style="font-size:12px;color:#36B;">系統預設</span></div>
94
- ` }
148
+ ` },
149
+ ...menu_all.list.filter((d1:any)=>{
150
+ return d1.tab===tag
151
+ })
95
152
  ];
153
+
96
154
  vmi.pageSize = 1;
97
155
  vmi.originalData = vm.dataList;
98
156
  vmi.tableData = getDatalist();
@@ -100,7 +158,7 @@ export class MenusSetting {
100
158
  vmi.callback();
101
159
  },
102
160
  rowClick: (data, index) => {
103
- vm.index = index;
161
+ vm.select=vm.dataList[index]
104
162
  vm.type = 'replace';
105
163
  },
106
164
  filter: [],
@@ -123,8 +181,8 @@ export class MenusSetting {
123
181
  this.setMenu({
124
182
  gvc: gvc,
125
183
  widget: widget,
126
- key: vm.dataList[vm.index].tag,
127
- title: vm.dataList[vm.index].title,
184
+ key: vm.select.tag as any,
185
+ title: vm.select.title,
128
186
  goBack: () => {
129
187
  vm.type = 'list';
130
188
  gvc.notifyDataChange(id);
@@ -145,7 +203,7 @@ export class MenusSetting {
145
203
  goBack: () => void;
146
204
  gvc: GVC;
147
205
  widget: any;
148
- key: 'menu-setting' | 'footer-setting' | 'text-manager';
206
+ key: string;
149
207
  title: string;
150
208
  }) {
151
209
  const vm: {
@@ -157,7 +215,7 @@ export class MenusSetting {
157
215
  };
158
216
  loading: boolean;
159
217
  selected: boolean;
160
- language: LanguageLocation;
218
+ language: LanguageLocation
161
219
  } = {
162
220
  id: cf.gvc.glitter.getUUID(),
163
221
  link: {
@@ -167,7 +225,7 @@ export class MenusSetting {
167
225
  },
168
226
  selected: false,
169
227
  loading: true,
170
- language: (window.parent as any).store_info.language_setting.def,
228
+ language: (window.parent as any).store_info.language_setting.def
171
229
  };
172
230
 
173
231
  ApiUser.getPublicConfig(cf.key, 'manager').then((data: any) => {
@@ -183,14 +241,24 @@ export class MenusSetting {
183
241
  clearNoNeedData(dd.items || []);
184
242
  });
185
243
  }
186
- function save() {
244
+ async function save() {
187
245
  for (const a of ['en-US', 'zh-CN', 'zh-TW']) {
246
+ (vm.link as any)[a]=(vm.link as any)[a]??[]
188
247
  clearNoNeedData((vm.link as any)[a]);
189
248
  }
190
249
 
191
250
  cf.widget.event('loading', {
192
251
  title: '儲存中...',
193
252
  });
253
+ let menu_all=(await ApiUser.getPublicConfig('menu-setting-list','manager')).response.value;
254
+ menu_all.list=menu_all.list ?? []
255
+ const find_=menu_all.list.find((d1:any)=>{return d1.tag===cf.key});
256
+ find_ &&( find_.title=cf.title)
257
+ await ApiUser.setPublicConfig({
258
+ key:'menu-setting-list',
259
+ value:menu_all,
260
+ user_id:'manager'
261
+ });
194
262
  ApiUser.setPublicConfig({
195
263
  key: cf.key,
196
264
  value: vm.link,
@@ -252,14 +320,46 @@ export class MenusSetting {
252
320
  return {
253
321
  bind: vm.id,
254
322
  view: () => {
323
+ vm.link[vm.language]=vm.link[vm.language] ?? []
255
324
  const link = vm.link[vm.language];
325
+
256
326
  return html`<div class="title-container" style="width: 100%; max-width: 100%;">
257
327
  ${BgWidget.goBack(
258
328
  cf.gvc.event(() => {
259
329
  cf.goBack();
260
330
  })
261
331
  )}${BgWidget.title(cf.title ?? '選單設定')}
332
+ <div class="mx-2 ${ ['menu-setting' , 'footer-setting' , 'text-manager'].includes(cf.key) ? `d-none`:``}">
333
+ ${BgWidget.grayButton('重新命名',gvc.event(()=>{
334
+ BgWidget.settingDialog({
335
+ gvc: gvc,
336
+ title: '重新命名',
337
+ innerHTML: (gvc: GVC) => {
338
+ return [
339
+ BgWidget.editeInput({
340
+ title:'',
341
+ callback:(text)=>{
342
+ cf.title=text
343
+ },
344
+ default:cf.title,
345
+ gvc:gvc,
346
+ placeHolder:''
347
+ })
348
+ ].join('')
349
+ },
350
+ footer_html: (gvc: GVC) => {
351
+ return BgWidget.save(gvc.event(()=>{
352
+ gvc.closeDialog()
353
+ refresh()
354
+ }),'儲存')
355
+ },
356
+ width: 500
357
+ })
358
+ }))}
359
+ </div>
360
+
262
361
  <div class="flex-fill"></div>
362
+
263
363
  ${LanguageBackend.switchBtn({
264
364
  gvc: gvc,
265
365
  language: vm.language,
@@ -565,6 +665,29 @@ export class MenusSetting {
565
665
  </div>`
566
666
  )}
567
667
  <div class="update-bar-container">
668
+ ${
669
+ ['menu-setting' , 'footer-setting' , 'text-manager'].includes(cf.key) ? ``:BgWidget.danger(gvc.event(async () => {
670
+ const dialog=new ShareDialog(gvc.glitter);
671
+ dialog.checkYesOrNot({
672
+ text:'是否確認刪除?',
673
+ callback:async (response)=>{
674
+ if(response){
675
+ dialog.dataLoading({visible:true});
676
+ let menu_all=(await ApiUser.getPublicConfig('menu-setting-list','manager')).response.value;
677
+ menu_all.list=menu_all.list.filter((d1:any)=>d1.tag!=cf.key);
678
+ await ApiUser.setPublicConfig({
679
+ key:'menu-setting-list',
680
+ value:menu_all,
681
+ user_id:'manager'
682
+ });
683
+ dialog.dataLoading({visible:false});
684
+ cf.goBack();
685
+ }
686
+ }
687
+ })
688
+
689
+ }))
690
+ }
568
691
  ${BgWidget.cancel(
569
692
  gvc.event(() => {
570
693
  cf.goBack();
@@ -887,13 +887,13 @@ OrderExcel.getCustomizeMap = (order) => __awaiter(void 0, void 0, void 0, functi
887
887
  ['電話', 'phone'],
888
888
  ['信箱', 'email'],
889
889
  ];
890
- receipt.list.map((d1) => {
891
- var _b;
892
- if (!viewModel.find(dd => {
893
- return dd[1] === d1.key;
894
- })) {
895
- customizeMap.set(`收件人資訊 - ${d1.title}`, order ? ((_b = order.orderData.user_info[d1.key]) !== null && _b !== void 0 ? _b : '-') : '-');
896
- }
897
- });
890
+ if (receipt === null || receipt === void 0 ? void 0 : receipt.list) {
891
+ receipt.list.map((d1) => {
892
+ var _b;
893
+ if (!viewModel.find(dd => dd[1] === d1.key)) {
894
+ customizeMap.set(`收件人資訊 - ${d1.title}`, order ? ((_b = order.orderData.user_info[d1.key]) !== null && _b !== void 0 ? _b : '-') : '-');
895
+ }
896
+ });
897
+ }
898
898
  return customizeMap;
899
899
  });
@@ -476,15 +476,15 @@ export class OrderExcel {
476
476
  ['電話', 'phone'],
477
477
  ['信箱', 'email'],
478
478
  ];
479
- receipt.list.map((d1: any) => {
480
- if (
481
- !viewModel.find(dd => {
482
- return dd[1] === d1.key;
483
- })
484
- ) {
485
- customizeMap.set(`收件人資訊 - ${d1.title}`, order ? (order.orderData.user_info[d1.key] ?? '-') : '-');
486
- }
487
- });
479
+
480
+ if (receipt?.list) {
481
+ receipt.list.map((d1: any) => {
482
+ if (!viewModel.find(dd => dd[1] === d1.key)) {
483
+ customizeMap.set(`收件人資訊 - ${d1.title}`, order ? (order.orderData.user_info[d1.key] ?? '-') : '-');
484
+ }
485
+ });
486
+ }
487
+
488
488
  return customizeMap;
489
489
  };
490
490
 
@@ -1039,7 +1039,7 @@ export class OrderExcel {
1039
1039
  await ApiUser.getPublicConfig('customer_form_user_setting', 'manager').then(r => {
1040
1040
  return Array.isArray(r.response.value.list) ? r.response.value.list : [];
1041
1041
  }),
1042
- //收件人資料
1042
+ // 收件人資料
1043
1043
  (await ApiUser.getPublicConfig('custom_form_checkout_recipient', 'manager')).response.value,
1044
1044
  ]);
1045
1045
 
@@ -0,0 +1,184 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { ShareDialog } from '../../glitterBundle/dialog/ShareDialog.js';
11
+ import { BgWidget } from '../../backend-manager/bg-widget.js';
12
+ import { Excel } from './excel.js';
13
+ const html = String.raw;
14
+ export class StockExcel {
15
+ static checkingImport(gvc, dataList, target, callback) {
16
+ var _a, _b, _c, _d, _e;
17
+ return __awaiter(this, void 0, void 0, function* () {
18
+ const dialog = new ShareDialog(gvc.glitter);
19
+ if ((_a = target.files) === null || _a === void 0 ? void 0 : _a.length) {
20
+ try {
21
+ const jsonData = yield Excel.parseExcelToJson(gvc, target.files[0]);
22
+ for (let i = 0; i < jsonData.length; i++) {
23
+ const content = jsonData[i];
24
+ const contentData = {
25
+ title: content['商品'],
26
+ spec: content['規格'],
27
+ sku: (_b = content['SKU']) !== null && _b !== void 0 ? _b : '',
28
+ barcode: content['商品條碼'],
29
+ transfer_count: (_c = content['庫存數量']) !== null && _c !== void 0 ? _c : '',
30
+ recent_count: (_d = content['盤點數量']) !== null && _d !== void 0 ? _d : '',
31
+ note: (_e = content['備註']) !== null && _e !== void 0 ? _e : '',
32
+ };
33
+ jsonData[i] = contentData;
34
+ }
35
+ dialog.checkYesOrNot({
36
+ text: '確定要匯入嗎?',
37
+ callback: bool => {
38
+ if (bool) {
39
+ const jsonDataMap = new Map(jsonData.map(data => [`${data.title}-${data.spec}`, data]));
40
+ for (const data of dataList) {
41
+ const titleSpec = `${data.title}-${data.spec}`;
42
+ const replaceData = jsonDataMap.get(titleSpec);
43
+ if (replaceData) {
44
+ data.recent_count = replaceData.recent_count;
45
+ data.note = replaceData.note;
46
+ }
47
+ else {
48
+ dialog.errorMessage({ text: html `有遺失商品名稱與規格<br />(${titleSpec})` });
49
+ return;
50
+ }
51
+ }
52
+ callback(dataList);
53
+ }
54
+ },
55
+ });
56
+ }
57
+ catch (error) {
58
+ console.error('Stock Excel 解析失敗:', error);
59
+ }
60
+ }
61
+ });
62
+ }
63
+ static importDialog(gvc, dataList, callback) {
64
+ const dialog = new ShareDialog(gvc.glitter);
65
+ const vm = {
66
+ id: 'importDialog',
67
+ fileInput: {},
68
+ type: '',
69
+ };
70
+ gvc.glitter.innerDialog((gvc) => {
71
+ return gvc.bindView({
72
+ bind: vm.id,
73
+ view: () => {
74
+ const viewData = {
75
+ title: '匯入盤點單',
76
+ category: {
77
+ title: '匯入盤點單類型',
78
+ options: [],
79
+ },
80
+ example: {
81
+ event: () => { },
82
+ },
83
+ import: {
84
+ event: () => this.checkingImport(gvc, structuredClone(dataList), vm.fileInput, (updateList) => {
85
+ gvc.glitter.closeDiaLog();
86
+ callback(updateList);
87
+ }),
88
+ },
89
+ };
90
+ return html `
91
+ <div
92
+ class="d-flex align-items-center w-100 tx_700"
93
+ style="padding: 12px 0 12px 20px; align-items: center; border-radius: 10px 10px 0px 0px; background: #F2F2F2;"
94
+ >
95
+ ${viewData.title}
96
+ </div>
97
+ <div style="padding: 20px 20px 0px;">
98
+ <div class="d-flex flex-column align-items-start gap-1">
99
+ ${BgWidget.warningInsignia('・匯入的資料僅修正「盤點數量」與「備註」欄位')}
100
+ ${BgWidget.warningInsignia('・若匯入失敗,請再次確認「商品名稱」與「規格」是否與匯出的欄位相同')}
101
+ </div>
102
+ </div>
103
+ <div class="d-flex flex-column w-100 align-items-start gap-3" style="padding: 20px">
104
+ <input
105
+ class="d-none"
106
+ type="file"
107
+ id="upload-excel"
108
+ onchange="${gvc.event((_, event) => {
109
+ vm.fileInput = event.target;
110
+ gvc.notifyDataChange(vm.id);
111
+ })}"
112
+ />
113
+ <div
114
+ class="d-flex flex-column w-100 justify-content-center align-items-center gap-3"
115
+ style="border: 1px solid #DDD; border-radius: 10px; min-height: 180px;"
116
+ >
117
+ ${(() => {
118
+ if (vm.fileInput.files && vm.fileInput.files.length > 0) {
119
+ return html `
120
+ ${BgWidget.customButton({
121
+ button: { color: 'snow', size: 'md' },
122
+ text: { name: '更換檔案' },
123
+ event: gvc.event(() => {
124
+ document.querySelector('#upload-excel').click();
125
+ }),
126
+ })}
127
+ ${BgWidget.grayNote(vm.fileInput.files[0].name)}
128
+ `;
129
+ }
130
+ else {
131
+ return BgWidget.customButton({
132
+ button: { color: 'snow', size: 'md' },
133
+ text: { name: '新增檔案' },
134
+ event: gvc.event(() => {
135
+ document.querySelector('#upload-excel').click();
136
+ }),
137
+ });
138
+ }
139
+ })()}
140
+ </div>
141
+ </div>
142
+ <div class="d-flex justify-content-end gap-3" style="padding-right: 20px; padding-bottom: 20px;">
143
+ ${BgWidget.cancel(gvc.event(() => {
144
+ gvc.glitter.closeDiaLog();
145
+ }))}
146
+ ${BgWidget.save(gvc.event(() => {
147
+ if (vm.fileInput.files && vm.fileInput.files.length > 0) {
148
+ viewData.import.event();
149
+ }
150
+ else {
151
+ dialog.infoMessage({ text: '尚未上傳檔案' });
152
+ }
153
+ }), '匯入')}
154
+ </div>
155
+ `;
156
+ },
157
+ divCreate: {
158
+ style: 'border-radius: 10px; background: #FFF; width: 570px; min-height: 360px; max-width: 90%;',
159
+ },
160
+ });
161
+ }, vm.id);
162
+ }
163
+ static exportChecking(gvc, order_id, dataList) {
164
+ const formatJSON = (obj) => Object.fromEntries(Object.entries(obj));
165
+ const getBasicJSON = (product) => {
166
+ return formatJSON({
167
+ 商品: product.title,
168
+ 規格: product.spec,
169
+ SKU: product.sku || '-',
170
+ 商品條碼: product.barcode || '-',
171
+ 庫存數量: product.transfer_count,
172
+ 盤點數量: product.recent_count,
173
+ 備註: product.note,
174
+ });
175
+ };
176
+ function exportDataToExcel(dataArray) {
177
+ const printArray = dataArray.flatMap(product => {
178
+ return [getBasicJSON(product)];
179
+ });
180
+ Excel.downloadExcel(gvc, printArray, `盤點單_${order_id}.xlsx`, `盤點單編號-${order_id}`);
181
+ }
182
+ exportDataToExcel(dataList);
183
+ }
184
+ }