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.
- package/lowcode/Entry.js +18 -18
- package/lowcode/Entry.ts +18 -19
- package/lowcode/backend-manager/bg-product.js +8 -6
- package/lowcode/backend-manager/bg-product.ts +17 -15
- package/lowcode/backend-manager/bg-recommend.js +16 -5
- package/lowcode/backend-manager/bg-recommend.ts +15 -5
- package/lowcode/backend-manager/bg-widget.js +160 -160
- package/lowcode/backend-manager/bg-widget.ts +169 -166
- package/lowcode/cms-plugin/POS-setting.js +75 -23
- package/lowcode/cms-plugin/POS-setting.ts +87 -30
- package/lowcode/cms-plugin/menus-setting.js +165 -37
- package/lowcode/cms-plugin/menus-setting.ts +144 -21
- package/lowcode/cms-plugin/module/order-excel.js +8 -8
- package/lowcode/cms-plugin/module/order-excel.ts +10 -10
- package/lowcode/cms-plugin/module/stock-excel.js +184 -0
- package/lowcode/cms-plugin/module/stock-excel.ts +205 -0
- package/lowcode/cms-plugin/module/vendor-excel.js +375 -0
- package/lowcode/cms-plugin/module/vendor-excel.ts +450 -0
- package/lowcode/cms-plugin/order/order-module.js +6 -4
- package/lowcode/cms-plugin/order/order-module.ts +16 -14
- package/lowcode/cms-plugin/pos-pages/models.ts +6 -2
- package/lowcode/cms-plugin/pos-pages/products-page.js +589 -469
- package/lowcode/cms-plugin/pos-pages/products-page.ts +657 -491
- package/lowcode/cms-plugin/shopping-product-setting.js +7 -10
- package/lowcode/cms-plugin/shopping-product-setting.ts +12 -10
- package/lowcode/cms-plugin/shopping-setting-basic.js +2 -5
- package/lowcode/cms-plugin/shopping-setting-basic.ts +2 -5
- package/lowcode/cms-plugin/stock-history.js +39 -26
- package/lowcode/cms-plugin/stock-history.ts +58 -49
- package/lowcode/cms-plugin/stock-vendors.js +18 -13
- package/lowcode/cms-plugin/stock-vendors.ts +31 -16
- package/lowcode/glitterBundle/html-component/global-widget.js +162 -136
- package/lowcode/glitterBundle/html-component/global-widget.ts +430 -382
- package/lowcode/public-components/blogs/blogs-01.js +22 -9
- package/lowcode/public-components/blogs/blogs-01.ts +28 -14
- package/package.json +1 -1
- package/src/api-public/services/schedule.js +6 -1
- package/src/api-public/services/schedule.js.map +1 -1
- package/src/api-public/services/schedule.ts +4 -1
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { GVC } from '../../glitterBundle/GVController.js';
|
|
2
|
+
import { ShareDialog } from '../../glitterBundle/dialog/ShareDialog.js';
|
|
3
|
+
import { BgWidget } from '../../backend-manager/bg-widget.js';
|
|
4
|
+
import { Excel } from './excel.js';
|
|
5
|
+
import { ContentProduct } from '../../glitter-base/route/stock.js';
|
|
6
|
+
|
|
7
|
+
const html = String.raw;
|
|
8
|
+
|
|
9
|
+
export class StockExcel {
|
|
10
|
+
// 盤點單匯入方法
|
|
11
|
+
static async checkingImport(
|
|
12
|
+
gvc: GVC,
|
|
13
|
+
dataList: ContentProduct[],
|
|
14
|
+
target: HTMLInputElement,
|
|
15
|
+
callback: (updateList: ContentProduct[]) => void
|
|
16
|
+
) {
|
|
17
|
+
const dialog = new ShareDialog(gvc.glitter);
|
|
18
|
+
|
|
19
|
+
if (target.files?.length) {
|
|
20
|
+
try {
|
|
21
|
+
const jsonData = await Excel.parseExcelToJson(gvc, target.files[0]);
|
|
22
|
+
|
|
23
|
+
for (let i = 0; i < jsonData.length; i++) {
|
|
24
|
+
const content = jsonData[i];
|
|
25
|
+
|
|
26
|
+
const contentData = {
|
|
27
|
+
title: content['商品'],
|
|
28
|
+
spec: content['規格'],
|
|
29
|
+
sku: content['SKU'] ?? '',
|
|
30
|
+
barcode: content['商品條碼'],
|
|
31
|
+
transfer_count: content['庫存數量'] ?? '',
|
|
32
|
+
recent_count: content['盤點數量'] ?? '',
|
|
33
|
+
note: content['備註'] ?? '',
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
jsonData[i] = contentData;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
dialog.checkYesOrNot({
|
|
40
|
+
text: '確定要匯入嗎?',
|
|
41
|
+
callback: bool => {
|
|
42
|
+
if (bool) {
|
|
43
|
+
const jsonDataMap: Map<string, ContentProduct> = new Map(
|
|
44
|
+
jsonData.map(data => [`${data.title}-${data.spec}`, data])
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
for (const data of dataList) {
|
|
48
|
+
const titleSpec = `${data.title}-${data.spec}`;
|
|
49
|
+
const replaceData = jsonDataMap.get(titleSpec);
|
|
50
|
+
|
|
51
|
+
if (replaceData) {
|
|
52
|
+
data.recent_count = replaceData.recent_count;
|
|
53
|
+
data.note = replaceData.note;
|
|
54
|
+
} else {
|
|
55
|
+
dialog.errorMessage({ text: html`有遺失商品名稱與規格<br />(${titleSpec})` });
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
callback(dataList);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
} catch (error) {
|
|
65
|
+
console.error('Stock Excel 解析失敗:', error);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// 匯入檔案彈出視窗
|
|
71
|
+
static importDialog(gvc: GVC, dataList: ContentProduct[], callback: (updateList: ContentProduct[]) => void) {
|
|
72
|
+
const dialog = new ShareDialog(gvc.glitter);
|
|
73
|
+
const vm = {
|
|
74
|
+
id: 'importDialog',
|
|
75
|
+
fileInput: {} as HTMLInputElement,
|
|
76
|
+
type: '',
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
gvc.glitter.innerDialog((gvc: GVC) => {
|
|
80
|
+
return gvc.bindView({
|
|
81
|
+
bind: vm.id,
|
|
82
|
+
view: () => {
|
|
83
|
+
const viewData = {
|
|
84
|
+
title: '匯入盤點單',
|
|
85
|
+
category: {
|
|
86
|
+
title: '匯入盤點單類型',
|
|
87
|
+
options: [],
|
|
88
|
+
},
|
|
89
|
+
example: {
|
|
90
|
+
event: () => {},
|
|
91
|
+
},
|
|
92
|
+
import: {
|
|
93
|
+
event: () =>
|
|
94
|
+
this.checkingImport(gvc, structuredClone(dataList), vm.fileInput, (updateList: ContentProduct[]) => {
|
|
95
|
+
gvc.glitter.closeDiaLog();
|
|
96
|
+
callback(updateList);
|
|
97
|
+
}),
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
return html`
|
|
102
|
+
<div
|
|
103
|
+
class="d-flex align-items-center w-100 tx_700"
|
|
104
|
+
style="padding: 12px 0 12px 20px; align-items: center; border-radius: 10px 10px 0px 0px; background: #F2F2F2;"
|
|
105
|
+
>
|
|
106
|
+
${viewData.title}
|
|
107
|
+
</div>
|
|
108
|
+
<div style="padding: 20px 20px 0px;">
|
|
109
|
+
<div class="d-flex flex-column align-items-start gap-1">
|
|
110
|
+
${BgWidget.warningInsignia('・匯入的資料僅修正「盤點數量」與「備註」欄位')}
|
|
111
|
+
${BgWidget.warningInsignia('・若匯入失敗,請再次確認「商品名稱」與「規格」是否與匯出的欄位相同')}
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
<div class="d-flex flex-column w-100 align-items-start gap-3" style="padding: 20px">
|
|
115
|
+
<input
|
|
116
|
+
class="d-none"
|
|
117
|
+
type="file"
|
|
118
|
+
id="upload-excel"
|
|
119
|
+
onchange="${gvc.event((_, event) => {
|
|
120
|
+
vm.fileInput = event.target;
|
|
121
|
+
gvc.notifyDataChange(vm.id);
|
|
122
|
+
})}"
|
|
123
|
+
/>
|
|
124
|
+
<div
|
|
125
|
+
class="d-flex flex-column w-100 justify-content-center align-items-center gap-3"
|
|
126
|
+
style="border: 1px solid #DDD; border-radius: 10px; min-height: 180px;"
|
|
127
|
+
>
|
|
128
|
+
${(() => {
|
|
129
|
+
if (vm.fileInput.files && vm.fileInput.files.length > 0) {
|
|
130
|
+
return html`
|
|
131
|
+
${BgWidget.customButton({
|
|
132
|
+
button: { color: 'snow', size: 'md' },
|
|
133
|
+
text: { name: '更換檔案' },
|
|
134
|
+
event: gvc.event(() => {
|
|
135
|
+
(document.querySelector('#upload-excel') as HTMLInputElement)!.click();
|
|
136
|
+
}),
|
|
137
|
+
})}
|
|
138
|
+
${BgWidget.grayNote(vm.fileInput.files[0].name)}
|
|
139
|
+
`;
|
|
140
|
+
} else {
|
|
141
|
+
return BgWidget.customButton({
|
|
142
|
+
button: { color: 'snow', size: 'md' },
|
|
143
|
+
text: { name: '新增檔案' },
|
|
144
|
+
event: gvc.event(() => {
|
|
145
|
+
(document.querySelector('#upload-excel') as HTMLInputElement)!.click();
|
|
146
|
+
}),
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
})()}
|
|
150
|
+
</div>
|
|
151
|
+
</div>
|
|
152
|
+
<div class="d-flex justify-content-end gap-3" style="padding-right: 20px; padding-bottom: 20px;">
|
|
153
|
+
${BgWidget.cancel(
|
|
154
|
+
gvc.event(() => {
|
|
155
|
+
gvc.glitter.closeDiaLog();
|
|
156
|
+
})
|
|
157
|
+
)}
|
|
158
|
+
${BgWidget.save(
|
|
159
|
+
gvc.event(() => {
|
|
160
|
+
if (vm.fileInput.files && vm.fileInput.files.length > 0) {
|
|
161
|
+
viewData.import.event();
|
|
162
|
+
} else {
|
|
163
|
+
dialog.infoMessage({ text: '尚未上傳檔案' });
|
|
164
|
+
}
|
|
165
|
+
}),
|
|
166
|
+
'匯入'
|
|
167
|
+
)}
|
|
168
|
+
</div>
|
|
169
|
+
`;
|
|
170
|
+
},
|
|
171
|
+
divCreate: {
|
|
172
|
+
style: 'border-radius: 10px; background: #FFF; width: 570px; min-height: 360px; max-width: 90%;',
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
}, vm.id);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
static exportChecking(gvc: GVC, order_id: string, dataList: ContentProduct[]) {
|
|
179
|
+
// 處理 JSON, 判斷欄位是否顯示
|
|
180
|
+
const formatJSON = (obj: Record<string, any>) => Object.fromEntries(Object.entries(obj));
|
|
181
|
+
|
|
182
|
+
// 盤點單基本欄位物件
|
|
183
|
+
const getBasicJSON = (product: ContentProduct) => {
|
|
184
|
+
return formatJSON({
|
|
185
|
+
商品: product.title,
|
|
186
|
+
規格: product.spec,
|
|
187
|
+
SKU: product.sku || '-',
|
|
188
|
+
商品條碼: product.barcode || '-',
|
|
189
|
+
庫存數量: product.transfer_count,
|
|
190
|
+
盤點數量: product.recent_count,
|
|
191
|
+
備註: product.note,
|
|
192
|
+
});
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
function exportDataToExcel(dataArray: ContentProduct[]) {
|
|
196
|
+
const printArray = dataArray.flatMap(product => {
|
|
197
|
+
return [getBasicJSON(product)];
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
Excel.downloadExcel(gvc, printArray, `盤點單_${order_id}.xlsx`, `盤點單編號-${order_id}`);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
exportDataToExcel(dataList);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
@@ -0,0 +1,375 @@
|
|
|
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 { ApiUser } from '../../glitter-base/route/user.js';
|
|
13
|
+
import { Tool } from '../../modules/tool.js';
|
|
14
|
+
import { Excel } from './excel.js';
|
|
15
|
+
import { CheckInput } from '../../modules/checkInput.js';
|
|
16
|
+
const html = String.raw;
|
|
17
|
+
export class VendorExcel {
|
|
18
|
+
static getNewID(list) {
|
|
19
|
+
let newId;
|
|
20
|
+
do {
|
|
21
|
+
newId = `vendor_${Tool.randomString(6)}`;
|
|
22
|
+
} while (list.some((item) => item.id === newId));
|
|
23
|
+
return newId;
|
|
24
|
+
}
|
|
25
|
+
static optionsView(gvc, callback) {
|
|
26
|
+
let columnList = new Set();
|
|
27
|
+
const randomString = BgWidget.getCheckedClass(gvc);
|
|
28
|
+
const checkbox = (checked, name, toggle) => html `
|
|
29
|
+
<div class="form-check">
|
|
30
|
+
<input
|
|
31
|
+
class="form-check-input cursor_pointer ${randomString}"
|
|
32
|
+
type="checkbox"
|
|
33
|
+
id="${name}"
|
|
34
|
+
style="margin-top: 0.35rem;"
|
|
35
|
+
${checked ? 'checked' : ''}
|
|
36
|
+
onclick="${gvc.event(toggle)}"
|
|
37
|
+
/>
|
|
38
|
+
<label
|
|
39
|
+
class="form-check-label cursor_pointer"
|
|
40
|
+
for="${name}"
|
|
41
|
+
style="padding-top: 2px; font-size: 16px; color: #393939;"
|
|
42
|
+
>
|
|
43
|
+
${name}
|
|
44
|
+
</label>
|
|
45
|
+
</div>
|
|
46
|
+
`;
|
|
47
|
+
const checkboxContainer = (items) => html `
|
|
48
|
+
<div class="row w-100">
|
|
49
|
+
${Object.entries(items)
|
|
50
|
+
.map(([category, fields]) => {
|
|
51
|
+
const bindId = Tool.randomString(5);
|
|
52
|
+
return gvc.bindView({
|
|
53
|
+
bind: bindId,
|
|
54
|
+
view: () => {
|
|
55
|
+
const allChecked = fields.every(item => columnList.has(item));
|
|
56
|
+
return html `
|
|
57
|
+
${checkbox(allChecked, category, () => {
|
|
58
|
+
if (allChecked) {
|
|
59
|
+
fields.forEach(item => columnList.delete(item));
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
fields.forEach(item => columnList.add(item));
|
|
63
|
+
}
|
|
64
|
+
callback(Array.from(columnList));
|
|
65
|
+
gvc.notifyDataChange(bindId);
|
|
66
|
+
})}
|
|
67
|
+
<div class="d-flex position-relative my-2">
|
|
68
|
+
${BgWidget.leftLineBar()}
|
|
69
|
+
<div class="ms-4 w-100 flex-fill">
|
|
70
|
+
${fields
|
|
71
|
+
.map(item => checkbox(columnList.has(item), item, () => {
|
|
72
|
+
columnList.has(item) ? columnList.delete(item) : columnList.add(item);
|
|
73
|
+
callback(Array.from(columnList));
|
|
74
|
+
gvc.notifyDataChange(bindId);
|
|
75
|
+
}))
|
|
76
|
+
.join('')}
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
`;
|
|
80
|
+
},
|
|
81
|
+
divCreate: { class: 'col-12 col-md-4 mb-3' },
|
|
82
|
+
});
|
|
83
|
+
})
|
|
84
|
+
.join('')}
|
|
85
|
+
</div>
|
|
86
|
+
`;
|
|
87
|
+
return checkboxContainer(this.headerColumn);
|
|
88
|
+
}
|
|
89
|
+
static export(gvc, apiJSON, column) {
|
|
90
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
91
|
+
const dialog = new ShareDialog(gvc.glitter);
|
|
92
|
+
if (column.length === 0) {
|
|
93
|
+
dialog.infoMessage({ text: '請至少勾選一個匯出欄位' });
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const formatJSON = (obj) => Object.fromEntries(Object.entries(obj).filter(([key]) => column.includes(key)));
|
|
97
|
+
const getBasicJSON = (vendor) => {
|
|
98
|
+
return formatJSON({
|
|
99
|
+
供應商名稱: vendor.name,
|
|
100
|
+
供應商地址: vendor.address,
|
|
101
|
+
聯絡人姓名: vendor.manager_name,
|
|
102
|
+
電話: vendor.manager_phone,
|
|
103
|
+
備註: vendor.note,
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
function exportDataToExcel(dataArray) {
|
|
107
|
+
if (dataArray.length === 0) {
|
|
108
|
+
dialog.errorMessage({ text: '無供應商資料可以匯出' });
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const printArray = dataArray.flatMap(vendor => {
|
|
112
|
+
return [getBasicJSON(vendor)];
|
|
113
|
+
});
|
|
114
|
+
Excel.downloadExcel(gvc, printArray, `供應商列表_${gvc.glitter.ut.dateFormat(new Date(), 'yyyyMMddhhmmss')}.xlsx`, '供應商列表');
|
|
115
|
+
}
|
|
116
|
+
function fetchVendors() {
|
|
117
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
118
|
+
dialog.dataLoading({ visible: true });
|
|
119
|
+
try {
|
|
120
|
+
const vendors = yield ApiUser.getPublicConfig('vendor_manager', 'manager').then((dd) => {
|
|
121
|
+
var _a, _b;
|
|
122
|
+
if (dd.result && dd.response.value) {
|
|
123
|
+
return (_b = (_a = dd.response.value) === null || _a === void 0 ? void 0 : _a.list) !== null && _b !== void 0 ? _b : [];
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
dialog.dataLoading({ visible: false });
|
|
130
|
+
if (vendors.length > 0) {
|
|
131
|
+
exportDataToExcel(vendors);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
dialog.errorMessage({ text: '目前無供應商資料' });
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
dialog.dataLoading({ visible: false });
|
|
139
|
+
dialog.errorMessage({ text: '匯出檔案發生錯誤' });
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
dialog.checkYesOrNot({
|
|
144
|
+
text: '系統將會依條件匯出資料,確定要匯出嗎?',
|
|
145
|
+
callback: bool => bool && fetchVendors(),
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
static exportDialog(gvc) {
|
|
150
|
+
const vm = {
|
|
151
|
+
select: 'all',
|
|
152
|
+
column: [],
|
|
153
|
+
};
|
|
154
|
+
BgWidget.settingDialog({
|
|
155
|
+
gvc,
|
|
156
|
+
title: '匯出供應商',
|
|
157
|
+
width: 700,
|
|
158
|
+
innerHTML: gvc2 => {
|
|
159
|
+
return html `<div class="d-flex flex-column align-items-start gap-2">
|
|
160
|
+
<div class="tx_700 mb-2">匯出範圍</div>
|
|
161
|
+
${BgWidget.multiCheckboxContainer(gvc2, [{ key: 'all', name: '全部供應商' }], [vm.select], res => {
|
|
162
|
+
vm.select = res[0];
|
|
163
|
+
}, { single: true })}
|
|
164
|
+
<div class="tx_700 mb-2">匯出欄位</div>
|
|
165
|
+
${this.optionsView(gvc2, cols => {
|
|
166
|
+
vm.column = cols;
|
|
167
|
+
})}
|
|
168
|
+
</div>`;
|
|
169
|
+
},
|
|
170
|
+
footer_html: gvc2 => {
|
|
171
|
+
return [
|
|
172
|
+
BgWidget.cancel(gvc2.event(() => {
|
|
173
|
+
gvc2.glitter.closeDiaLog();
|
|
174
|
+
})),
|
|
175
|
+
BgWidget.save(gvc2.event(() => {
|
|
176
|
+
this.export(gvc, {}, vm.column);
|
|
177
|
+
}), '匯出'),
|
|
178
|
+
].join('');
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
static import(gvc, target, callback) {
|
|
183
|
+
var _a, _b, _c;
|
|
184
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
185
|
+
const dialog = new ShareDialog(gvc.glitter);
|
|
186
|
+
if ((_a = target.files) === null || _a === void 0 ? void 0 : _a.length) {
|
|
187
|
+
try {
|
|
188
|
+
dialog.dataLoading({ visible: true, text: '上傳檔案中' });
|
|
189
|
+
const jsonData = yield Excel.parseExcelToJson(gvc, target.files[0]);
|
|
190
|
+
dialog.dataLoading({ visible: false });
|
|
191
|
+
const vendors = yield ApiUser.getPublicConfig('vendor_manager', 'manager').then((dd) => {
|
|
192
|
+
var _a, _b;
|
|
193
|
+
if (dd.result && dd.response.value) {
|
|
194
|
+
return (_b = (_a = dd.response.value) === null || _a === void 0 ? void 0 : _a.list) !== null && _b !== void 0 ? _b : [];
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
return [];
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
for (let i = 0; i < jsonData.length; i++) {
|
|
201
|
+
const vendor = jsonData[i];
|
|
202
|
+
const vendorData = {
|
|
203
|
+
id: this.getNewID(vendors),
|
|
204
|
+
name: vendor['供應商名稱'],
|
|
205
|
+
address: vendor['供應商地址'],
|
|
206
|
+
manager_name: (_b = vendor['聯絡人姓名']) !== null && _b !== void 0 ? _b : '',
|
|
207
|
+
manager_phone: vendor['電話'],
|
|
208
|
+
note: (_c = vendor['備註']) !== null && _c !== void 0 ? _c : '',
|
|
209
|
+
is_shop: false,
|
|
210
|
+
};
|
|
211
|
+
if (CheckInput.isEmpty(vendorData.name)) {
|
|
212
|
+
dialog.infoMessage({ text: `供應商名稱不得為空白(資料列第 ${i + 1} 筆)` });
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
if (CheckInput.isEmpty(vendorData.address)) {
|
|
216
|
+
dialog.infoMessage({ text: `地址不得為空白(資料列第 ${i + 1} 筆)` });
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (!CheckInput.isTaiwanPhone(vendorData.manager_phone)) {
|
|
220
|
+
dialog.infoMessage({ text: BgWidget.taiwanPhoneAlert() + `(資料列第 ${i + 1} 筆)` });
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
jsonData[i] = vendorData;
|
|
224
|
+
}
|
|
225
|
+
const vendorMap = new Map(vendors.map((vendor) => [vendor.name, vendor]));
|
|
226
|
+
jsonData.map((new_vendor) => {
|
|
227
|
+
vendorMap.set(new_vendor.name, new_vendor);
|
|
228
|
+
});
|
|
229
|
+
dialog.checkYesOrNot({
|
|
230
|
+
text: '若有相同名稱的供應商,將會覆蓋並更新其資料,<br/>確定要匯入嗎?',
|
|
231
|
+
callback: bool => {
|
|
232
|
+
if (bool) {
|
|
233
|
+
dialog.dataLoading({ visible: true });
|
|
234
|
+
ApiUser.setPublicConfig({
|
|
235
|
+
key: 'vendor_manager',
|
|
236
|
+
value: {
|
|
237
|
+
list: [...vendorMap.values()],
|
|
238
|
+
},
|
|
239
|
+
user_id: 'manager',
|
|
240
|
+
}).then(() => {
|
|
241
|
+
dialog.dataLoading({ visible: false });
|
|
242
|
+
dialog.successMessage({ text: '匯入成功' });
|
|
243
|
+
callback();
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
console.error('Vendor Excel 解析失敗:', error);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
static importDialog(gvc, callback) {
|
|
256
|
+
const dialog = new ShareDialog(gvc.glitter);
|
|
257
|
+
const vm = {
|
|
258
|
+
id: 'importDialog',
|
|
259
|
+
fileInput: {},
|
|
260
|
+
type: '',
|
|
261
|
+
};
|
|
262
|
+
gvc.glitter.innerDialog((gvc) => {
|
|
263
|
+
return gvc.bindView({
|
|
264
|
+
bind: vm.id,
|
|
265
|
+
view: () => {
|
|
266
|
+
const viewData = {
|
|
267
|
+
title: '匯入供應商',
|
|
268
|
+
category: {
|
|
269
|
+
title: '匯入供應商類型',
|
|
270
|
+
options: [],
|
|
271
|
+
},
|
|
272
|
+
example: {
|
|
273
|
+
event: () => {
|
|
274
|
+
Excel.downloadExcel(gvc, VendorExcel.importExampleData, `範例_供應商列表_${gvc.glitter.ut.dateFormat(new Date(), 'yyyyMMddhhmmss')}.xlsx`, '範例供應商列表');
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
import: {
|
|
278
|
+
event: () => this.import(gvc, vm.fileInput, () => {
|
|
279
|
+
gvc.glitter.closeDiaLog();
|
|
280
|
+
callback();
|
|
281
|
+
}),
|
|
282
|
+
},
|
|
283
|
+
};
|
|
284
|
+
return html `
|
|
285
|
+
<div
|
|
286
|
+
class="d-flex align-items-center w-100 tx_700"
|
|
287
|
+
style="padding: 12px 0 12px 20px; align-items: center; border-radius: 10px 10px 0px 0px; background: #F2F2F2;"
|
|
288
|
+
>
|
|
289
|
+
${viewData.title}
|
|
290
|
+
</div>
|
|
291
|
+
${viewData.category.options.length > 0
|
|
292
|
+
? html `<div class="d-flex flex-column align-items-start gap-2" style="padding: 20px 20px 0px;">
|
|
293
|
+
<div class="tx_700">${viewData.category.title}</div>
|
|
294
|
+
${BgWidget.multiCheckboxContainer(gvc, viewData.category.options, [vm.type], res => {
|
|
295
|
+
vm.type = res[0];
|
|
296
|
+
}, { single: true })}
|
|
297
|
+
</div>`
|
|
298
|
+
: ''}
|
|
299
|
+
<div class="d-flex flex-column w-100 align-items-start gap-3" style="padding: 20px">
|
|
300
|
+
<div class="d-flex align-items-center gap-2">
|
|
301
|
+
<div class="tx_700">透過XLSX檔案匯入供應商</div>
|
|
302
|
+
${BgWidget.blueNote('下載範例', gvc.event(viewData.example.event))}
|
|
303
|
+
</div>
|
|
304
|
+
<input
|
|
305
|
+
class="d-none"
|
|
306
|
+
type="file"
|
|
307
|
+
id="upload-excel"
|
|
308
|
+
onchange="${gvc.event((_, event) => {
|
|
309
|
+
vm.fileInput = event.target;
|
|
310
|
+
gvc.notifyDataChange(vm.id);
|
|
311
|
+
})}"
|
|
312
|
+
/>
|
|
313
|
+
<div
|
|
314
|
+
class="d-flex flex-column w-100 justify-content-center align-items-center gap-3"
|
|
315
|
+
style="border: 1px solid #DDD; border-radius: 10px; min-height: 180px;"
|
|
316
|
+
>
|
|
317
|
+
${(() => {
|
|
318
|
+
if (vm.fileInput.files && vm.fileInput.files.length > 0) {
|
|
319
|
+
return html `
|
|
320
|
+
${BgWidget.customButton({
|
|
321
|
+
button: { color: 'snow', size: 'md' },
|
|
322
|
+
text: { name: '更換檔案' },
|
|
323
|
+
event: gvc.event(() => {
|
|
324
|
+
document.querySelector('#upload-excel').click();
|
|
325
|
+
}),
|
|
326
|
+
})}
|
|
327
|
+
${BgWidget.grayNote(vm.fileInput.files[0].name)}
|
|
328
|
+
`;
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
return BgWidget.customButton({
|
|
332
|
+
button: { color: 'snow', size: 'md' },
|
|
333
|
+
text: { name: '新增檔案' },
|
|
334
|
+
event: gvc.event(() => {
|
|
335
|
+
document.querySelector('#upload-excel').click();
|
|
336
|
+
}),
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
})()}
|
|
340
|
+
</div>
|
|
341
|
+
</div>
|
|
342
|
+
<div class="d-flex justify-content-end gap-3" style="padding-right: 20px; padding-bottom: 20px;">
|
|
343
|
+
${BgWidget.cancel(gvc.event(() => {
|
|
344
|
+
gvc.glitter.closeDiaLog();
|
|
345
|
+
}))}
|
|
346
|
+
${BgWidget.save(gvc.event(() => {
|
|
347
|
+
if (vm.fileInput.files && vm.fileInput.files.length > 0) {
|
|
348
|
+
viewData.import.event();
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
dialog.infoMessage({ text: '尚未上傳檔案' });
|
|
352
|
+
}
|
|
353
|
+
}), '匯入')}
|
|
354
|
+
</div>
|
|
355
|
+
`;
|
|
356
|
+
},
|
|
357
|
+
divCreate: {
|
|
358
|
+
style: 'border-radius: 10px; background: #FFF; width: 570px; min-height: 360px; max-width: 90%;',
|
|
359
|
+
},
|
|
360
|
+
});
|
|
361
|
+
}, vm.id);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
VendorExcel.importExampleData = [
|
|
365
|
+
{
|
|
366
|
+
供應商名稱: '範例供應商',
|
|
367
|
+
供應商地址: '台北市信義區中山路一號',
|
|
368
|
+
聯絡人姓名: '黃先生',
|
|
369
|
+
電話: '0919334556',
|
|
370
|
+
備註: '',
|
|
371
|
+
},
|
|
372
|
+
];
|
|
373
|
+
VendorExcel.headerColumn = {
|
|
374
|
+
基本資料: ['供應商名稱', '供應商地址', '聯絡人姓名', '電話', '備註'],
|
|
375
|
+
};
|