ts-glitter 20.6.7 → 20.6.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lowcode/Entry.js +2 -2
- package/lowcode/Entry.ts +2 -2
- package/lowcode/backend-manager/bg-blog.js +617 -621
- package/lowcode/backend-manager/bg-blog.ts +2323 -2325
- package/lowcode/backend-manager/bg-line.js +5 -4
- package/lowcode/backend-manager/bg-line.ts +5 -4
- package/lowcode/backend-manager/bg-list-component.js +9 -0
- package/lowcode/backend-manager/bg-list-component.ts +15 -1
- package/lowcode/backend-manager/bg-notify.js +6 -4
- package/lowcode/backend-manager/bg-notify.ts +6 -4
- package/lowcode/backend-manager/bg-product.js +145 -0
- package/lowcode/backend-manager/bg-product.ts +153 -0
- package/lowcode/backend-manager/bg-sns.js +5 -3
- package/lowcode/backend-manager/bg-sns.ts +5 -3
- package/lowcode/backend-manager/bg-widget.js +92 -4
- package/lowcode/backend-manager/bg-widget.ts +122 -6
- package/lowcode/backend-manager/splitPage.js +0 -39
- package/lowcode/backend-manager/splitPage.ts +0 -40
- package/lowcode/cms-plugin/auto-fcm-advertise.js +17 -5
- package/lowcode/cms-plugin/auto-fcm-advertise.ts +19 -6
- package/lowcode/cms-plugin/auto-fcm-history.js +2732 -0
- package/lowcode/cms-plugin/auto-fcm-history.ts +2995 -0
- package/lowcode/cms-plugin/cms-router.js +5 -0
- package/lowcode/cms-plugin/cms-router.ts +6 -0
- package/lowcode/cms-plugin/filter-options.js +80 -27
- package/lowcode/cms-plugin/filter-options.ts +83 -27
- package/lowcode/cms-plugin/language-backend.js +50 -39
- package/lowcode/cms-plugin/language-backend.ts +109 -95
- package/lowcode/cms-plugin/menus-setting.js +175 -151
- package/lowcode/cms-plugin/menus-setting.ts +620 -591
- package/lowcode/cms-plugin/model/order.d.ts +1 -0
- package/lowcode/cms-plugin/module/data.js +7 -7
- package/lowcode/cms-plugin/module/data.ts +262 -233
- package/lowcode/cms-plugin/module/delivery-html.js +18 -10
- package/lowcode/cms-plugin/module/delivery-html.ts +26 -10
- package/lowcode/cms-plugin/module/order-setting.js +458 -328
- package/lowcode/cms-plugin/module/order-setting.ts +622 -351
- package/lowcode/cms-plugin/module/product-excel.js +1 -1
- package/lowcode/cms-plugin/module/product-excel.ts +2 -1
- package/lowcode/cms-plugin/order/order-module.js +90 -1
- package/lowcode/cms-plugin/order/order-module.ts +106 -1
- package/lowcode/cms-plugin/pos-pages/payment-page.js +11 -8
- package/lowcode/cms-plugin/pos-pages/payment-page.ts +28 -15
- package/lowcode/cms-plugin/pos-pages/products-page.js +0 -39
- package/lowcode/cms-plugin/pos-pages/products-page.ts +0 -40
- package/lowcode/cms-plugin/shopping-collections.ts +1 -3
- package/lowcode/cms-plugin/shopping-finance-setting.js +19 -80
- package/lowcode/cms-plugin/shopping-finance-setting.ts +19 -87
- package/lowcode/cms-plugin/shopping-order-manager.js +122 -38
- package/lowcode/cms-plugin/shopping-order-manager.ts +160 -58
- package/lowcode/cms-plugin/shopping-product-setting.js +364 -376
- package/lowcode/cms-plugin/shopping-product-setting.ts +406 -415
- package/lowcode/cms-plugin/shopping-setting-advance.js +57 -16
- package/lowcode/cms-plugin/shopping-setting-advance.ts +69 -18
- package/lowcode/cms-plugin/user/user-module.js +2 -43
- package/lowcode/cms-plugin/user/user-module.ts +2 -46
- package/lowcode/cms-plugin/user-list.js +4 -6
- package/lowcode/cms-plugin/user-list.ts +35 -38
- package/lowcode/css/editor.css +42 -3
- package/lowcode/glitter-base/global/language.js +6 -1
- package/lowcode/glitter-base/global/language.ts +10 -4
- package/lowcode/glitter-base/global/payment-config.js +19 -16
- package/lowcode/glitter-base/global/payment-config.ts +22 -16
- package/lowcode/glitter-base/global/shipment-config.js +6 -5
- package/lowcode/glitter-base/global/shipment-config.ts +12 -10
- package/lowcode/glitter-base/route/fcm.js +21 -1
- package/lowcode/glitter-base/route/fcm.ts +22 -2
- package/lowcode/glitter-base/route/shopping.js +8 -32
- package/lowcode/glitter-base/route/shopping.ts +10 -33
- package/lowcode/glitter-base/route/user.js +11 -2
- package/lowcode/glitter-base/route/user.ts +23 -12
- package/lowcode/jspage/function-page/setting_editor.js +9 -0
- package/lowcode/jspage/function-page/setting_editor.ts +9 -0
- package/lowcode/public-components/blogs/list.js +223 -195
- package/lowcode/public-components/blogs/list.ts +383 -352
- package/lowcode/public-components/product/product-list.js +8 -4
- package/lowcode/public-components/product/product-list.ts +9 -4
- package/lowcode/public-components/terms-related/index.js +1 -1
- package/lowcode/public-components/terms-related/index.ts +1 -1
- package/lowcode/public-components/user-manager/um-login.js +1 -1
- package/lowcode/public-components/user-manager/um-login.ts +2 -2
- package/lowcode/public-components/user-manager/um-order.js +41 -5
- package/lowcode/public-components/user-manager/um-order.ts +58 -20
- package/lowcode/public-components/user-manager/um-voucher.ts +2 -2
- package/nhi4veq3gk.json +1 -0
- package/package.json +1 -1
- package/src/Language.d.ts +2 -0
- package/src/Language.js +66 -65
- package/src/Language.js.map +1 -1
- package/src/Language.ts +719 -715
- package/src/api-public/config/shipment-config.js +3 -2
- package/src/api-public/config/shipment-config.js.map +1 -1
- package/src/api-public/config/shipment-config.ts +3 -2
- package/src/api-public/controllers/ai-chat.js.map +1 -1
- package/src/api-public/controllers/ai-chat.ts +1 -2
- package/src/api-public/controllers/fcm.js +23 -58
- package/src/api-public/controllers/fcm.js.map +1 -1
- package/src/api-public/controllers/fcm.ts +28 -56
- package/src/api-public/controllers/shop.js +7 -1
- package/src/api-public/controllers/shop.js.map +1 -1
- package/src/api-public/controllers/shop.ts +17 -10
- package/src/api-public/controllers/user.js +1 -0
- package/src/api-public/controllers/user.js.map +1 -1
- package/src/api-public/controllers/user.ts +2 -0
- package/src/api-public/services/auto-send-email.js +247 -187
- package/src/api-public/services/auto-send-email.js.map +1 -1
- package/src/api-public/services/auto-send-email.ts +568 -505
- package/src/api-public/services/delivery.js +1 -1
- package/src/api-public/services/delivery.js.map +1 -1
- package/src/api-public/services/delivery.ts +6 -5
- package/src/api-public/services/financial-service.js +1 -2
- package/src/api-public/services/financial-service.js.map +1 -1
- package/src/api-public/services/financial-service.ts +4 -6
- package/src/api-public/services/manager.d.ts +4 -3
- package/src/api-public/services/manager.js +8 -12
- package/src/api-public/services/manager.js.map +1 -1
- package/src/api-public/services/manager.ts +57 -59
- package/src/api-public/services/model/handlePaymentTransaction.d.ts +1 -1
- package/src/api-public/services/model/handlePaymentTransaction.js +23 -3
- package/src/api-public/services/model/handlePaymentTransaction.js.map +1 -1
- package/src/api-public/services/model/handlePaymentTransaction.ts +25 -36
- package/src/api-public/services/schedule.d.ts +1 -0
- package/src/api-public/services/schedule.js +27 -0
- package/src/api-public/services/schedule.js.map +1 -1
- package/src/api-public/services/schedule.ts +30 -0
- package/src/api-public/services/shopping.d.ts +22 -2
- package/src/api-public/services/shopping.js +362 -90
- package/src/api-public/services/shopping.js.map +1 -1
- package/src/api-public/services/shopping.ts +481 -134
- package/src/api-public/services/user.d.ts +1 -0
- package/src/api-public/services/user.js +36 -16
- package/src/api-public/services/user.js.map +1 -1
- package/src/api-public/services/user.ts +42 -23
- package/src/api-public/services/workers.js +3 -3
- package/src/api-public/services/workers.js.map +1 -1
- package/src/api-public/services/workers.ts +103 -103
- package/src/app-project/serverless/src/modules/database.js +1 -1
- package/src/app-project/serverless/src/modules/database.js.map +1 -1
- package/src/app-project/serverless/src/modules/database.ts +171 -171
- package/src/controllers/template.d.ts +1 -1
- package/src/controllers/template.js +16 -16
- package/src/controllers/template.js.map +1 -1
- package/src/controllers/template.ts +98 -84
- package/src/modules/database.js +3 -1
- package/src/modules/database.js.map +1 -1
- package/src/modules/database.ts +185 -181
- package/src/modules/firebase.d.ts +17 -0
- package/src/modules/firebase.js +126 -0
- package/src/modules/firebase.js.map +1 -1
- package/src/modules/firebase.ts +169 -0
- package/src/public-config-initial/auto-fcm.js +8 -2
- package/src/public-config-initial/auto-fcm.js.map +1 -1
- package/src/public-config-initial/auto-fcm.ts +15 -6
- package/src/services/app.d.ts +2 -1
- package/src/services/app.js.map +1 -1
- package/src/services/app.ts +2 -1
- package/src/services/template.d.ts +3 -2
- package/src/services/template.js +2 -1
- package/src/services/template.js.map +1 -1
- package/src/services/template.ts +13 -20
|
@@ -34,8 +34,8 @@ import { ProductInitial } from './product-initial.js';
|
|
|
34
34
|
import { UtTimer } from '../utils/ut-timer.js';
|
|
35
35
|
import { AutoFcm } from '../../public-config-initial/auto-fcm.js';
|
|
36
36
|
import PaymentTransaction from './model/handlePaymentTransaction.js';
|
|
37
|
+
import { Language, LanguageLocation } from '../../Language.js';
|
|
37
38
|
import { CartItem, CheckoutEvent } from './checkout-event.js';
|
|
38
|
-
|
|
39
39
|
type BindItem = {
|
|
40
40
|
id: string;
|
|
41
41
|
spec: string[];
|
|
@@ -206,16 +206,17 @@ class OrderDetail {
|
|
|
206
206
|
custom_form_delivery?: any;
|
|
207
207
|
shipment:
|
|
208
208
|
| 'normal'
|
|
209
|
-
| 'FAMIC2C'
|
|
210
209
|
| 'black_cat_freezing'
|
|
211
|
-
| 'UNIMARTC2C'
|
|
212
|
-
| 'HILIFEC2C'
|
|
213
|
-
| 'OKMARTC2C'
|
|
214
210
|
| 'now'
|
|
215
211
|
| 'shop'
|
|
216
212
|
| 'global_express'
|
|
217
213
|
| 'black_cat'
|
|
218
|
-
| '
|
|
214
|
+
| 'UNIMARTC2C'
|
|
215
|
+
| 'FAMIC2C'
|
|
216
|
+
| 'HILIFEC2C'
|
|
217
|
+
| 'OKMARTC2C'
|
|
218
|
+
| 'UNIMARTFREEZE'
|
|
219
|
+
| 'FAMIC2CFREEZE';
|
|
219
220
|
CVSStoreName: string;
|
|
220
221
|
CVSStoreID: string;
|
|
221
222
|
CVSTelephone: string;
|
|
@@ -396,6 +397,8 @@ export class Shopping {
|
|
|
396
397
|
max_price?: string;
|
|
397
398
|
status?: string;
|
|
398
399
|
channel?: string;
|
|
400
|
+
general_tag?: string;
|
|
401
|
+
manager_tag?: string;
|
|
399
402
|
whereStore?: string;
|
|
400
403
|
order_by?: string;
|
|
401
404
|
id_list?: string;
|
|
@@ -424,6 +427,9 @@ export class Shopping {
|
|
|
424
427
|
query.language = query.language ?? store_info.language_setting.def;
|
|
425
428
|
query.show_hidden = query.show_hidden ?? 'true';
|
|
426
429
|
|
|
430
|
+
// 初始化商品與管理員標籤 Config
|
|
431
|
+
// await Promise.all([this.initProductCustomizeTagConifg(), this.initProductGeneralTagConifg()]);
|
|
432
|
+
|
|
427
433
|
const orderMapping: Record<string, string> = {
|
|
428
434
|
title: `ORDER BY JSON_EXTRACT(content, '$.title')`,
|
|
429
435
|
max_price: `ORDER BY CAST(JSON_UNQUOTE(JSON_EXTRACT(content, '$.max_price')) AS SIGNED) DESC , id DESC`,
|
|
@@ -521,12 +527,12 @@ export class Shopping {
|
|
|
521
527
|
// 當非管理員時,檢查是否顯示隱形商品
|
|
522
528
|
if (query.filter_visible) {
|
|
523
529
|
if (query.filter_visible === 'true') {
|
|
524
|
-
querySql.push(`(content->>'$.visible'
|
|
530
|
+
querySql.push(`(content->>'$.visible' IS NULL || content->>'$.visible' = 'true')`);
|
|
525
531
|
} else {
|
|
526
532
|
querySql.push(`(content->>'$.visible' = 'false')`);
|
|
527
533
|
}
|
|
528
534
|
} else if (!query.is_manger && `${query.show_hidden}` !== 'true') {
|
|
529
|
-
querySql.push(`(content->>'$.visible'
|
|
535
|
+
querySql.push(`(content->>'$.visible' IS NULL || content->>'$.visible' = 'true')`);
|
|
530
536
|
}
|
|
531
537
|
|
|
532
538
|
// 判斷有帶入商品類型時,顯示商品類型,反之預設折是一班商品
|
|
@@ -685,6 +691,29 @@ export class Shopping {
|
|
|
685
691
|
}
|
|
686
692
|
}
|
|
687
693
|
|
|
694
|
+
if (query.manager_tag) {
|
|
695
|
+
const tagSplit = query.manager_tag.split(',').map(tag => tag.trim());
|
|
696
|
+
if (tagSplit.length > 0) {
|
|
697
|
+
const tagJoin = tagSplit.map(tag => {
|
|
698
|
+
return `JSON_CONTAINS(content->>'$.product_customize_tag', '"${tag}"')`;
|
|
699
|
+
});
|
|
700
|
+
querySql.push(`(${tagJoin.join(' OR ')})`);
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
if (query.general_tag) {
|
|
705
|
+
const tagSplit = query.general_tag.split(',').map(tag => tag.trim());
|
|
706
|
+
if (tagSplit.length > 0) {
|
|
707
|
+
const tagJoin = tagSplit.map(tag => {
|
|
708
|
+
return `(JSON_CONTAINS(
|
|
709
|
+
JSON_EXTRACT(content, '$.product_tag.language."${query.language ?? 'zh-TW'}"'),
|
|
710
|
+
JSON_QUOTE('${tag}')
|
|
711
|
+
))`;
|
|
712
|
+
});
|
|
713
|
+
querySql.push(`(${tagJoin.join(' OR ')})`);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
|
|
688
717
|
if (query.id_list && idStr) {
|
|
689
718
|
querySql.push(`(id in (${idStr}))`);
|
|
690
719
|
}
|
|
@@ -967,6 +996,7 @@ export class Shopping {
|
|
|
967
996
|
|
|
968
997
|
products.data = foundProduct || products.data[0];
|
|
969
998
|
}
|
|
999
|
+
|
|
970
1000
|
if (query.id && products.data.length > 0) {
|
|
971
1001
|
products.data = products.data[0];
|
|
972
1002
|
}
|
|
@@ -1168,6 +1198,176 @@ export class Shopping {
|
|
|
1168
1198
|
}
|
|
1169
1199
|
}
|
|
1170
1200
|
|
|
1201
|
+
async initProductCustomizeTagConifg() {
|
|
1202
|
+
try {
|
|
1203
|
+
const managerTags = await new User(this.app).getConfigV2({ key: 'product_manager_tags', user_id: 'manager' });
|
|
1204
|
+
console.log(`initProductCustomizeTagConifg=>getData=>`,managerTags)
|
|
1205
|
+
if (managerTags && Array.isArray(managerTags.list)) {
|
|
1206
|
+
return managerTags;
|
|
1207
|
+
}
|
|
1208
|
+
console.log(`query_sql=>`,`SELECT
|
|
1209
|
+
GROUP_CONCAT(DISTINCT JSON_UNQUOTE(JSON_EXTRACT(content, '$.product_customize_tag')) SEPARATOR ',') AS unique_tags
|
|
1210
|
+
FROM \`${this.app}\`.t_manager_post
|
|
1211
|
+
WHERE JSON_UNQUOTE(JSON_EXTRACT(content, '$.type')) = 'product'`)
|
|
1212
|
+
const getData = await db.query(
|
|
1213
|
+
`
|
|
1214
|
+
SELECT
|
|
1215
|
+
GROUP_CONCAT(DISTINCT JSON_UNQUOTE(JSON_EXTRACT(content, '$.product_customize_tag')) SEPARATOR ',') AS unique_tags
|
|
1216
|
+
FROM \`${this.app}\`.t_manager_post
|
|
1217
|
+
WHERE JSON_UNQUOTE(JSON_EXTRACT(content, '$.type')) = 'product'
|
|
1218
|
+
`,
|
|
1219
|
+
[]
|
|
1220
|
+
);
|
|
1221
|
+
|
|
1222
|
+
const unique_tags_string = getData[0]?.unique_tags ?? '';
|
|
1223
|
+
console.log(`JSON_STRING=>`,`[${unique_tags_string}]`)
|
|
1224
|
+
const unique_tags_array = JSON.parse(`[${unique_tags_string}]`);
|
|
1225
|
+
const unique_tags_flot = Array.isArray(unique_tags_array) ? unique_tags_array.flat() : [];
|
|
1226
|
+
const data = { list: [...new Set(unique_tags_flot)] };
|
|
1227
|
+
console.log(`product_manager_tags=>setData=>`,managerTags)
|
|
1228
|
+
await new User(this.app).setConfig({
|
|
1229
|
+
key: 'product_manager_tags',
|
|
1230
|
+
user_id: 'manager',
|
|
1231
|
+
value: data,
|
|
1232
|
+
});
|
|
1233
|
+
|
|
1234
|
+
return data;
|
|
1235
|
+
} catch (error) {
|
|
1236
|
+
throw exception.BadRequestError('BAD_REQUEST', 'Set product customize tag conifg Error:' + error, null);
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
async setProductCustomizeTagConifg(add_tags: string[]) {
|
|
1241
|
+
const tagConfig = await new User(this.app).getConfigV2({ key: 'product_manager_tags', user_id: 'manager' });
|
|
1242
|
+
const tagList = tagConfig?.list ?? [];
|
|
1243
|
+
const data = { list: [...new Set([...tagList, ...add_tags])] };
|
|
1244
|
+
|
|
1245
|
+
await new User(this.app).setConfig({
|
|
1246
|
+
key: 'product_manager_tags',
|
|
1247
|
+
user_id: 'manager',
|
|
1248
|
+
value: data,
|
|
1249
|
+
});
|
|
1250
|
+
|
|
1251
|
+
return data;
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
async initProductGeneralTagConifg() {
|
|
1255
|
+
try {
|
|
1256
|
+
const generalTags = await new User(this.app).getConfigV2({ key: 'product_general_tags', user_id: 'manager' });
|
|
1257
|
+
|
|
1258
|
+
if (generalTags && Array.isArray(generalTags.list)) {
|
|
1259
|
+
return generalTags;
|
|
1260
|
+
}
|
|
1261
|
+
console.log(`initProductCustomizeTagConifg=>getData=>`,generalTags)
|
|
1262
|
+
const getData = await db.query(
|
|
1263
|
+
`
|
|
1264
|
+
SELECT
|
|
1265
|
+
GROUP_CONCAT(DISTINCT JSON_UNQUOTE(JSON_EXTRACT(content, '$.product_tag.language')) SEPARATOR ',') AS unique_tags
|
|
1266
|
+
FROM \`${this.app}\`.t_manager_post
|
|
1267
|
+
WHERE JSON_UNQUOTE(JSON_EXTRACT(content, '$.type')) = 'product'
|
|
1268
|
+
`,
|
|
1269
|
+
[]
|
|
1270
|
+
);
|
|
1271
|
+
const unique_tags_string = getData[0]?.unique_tags ?? '';
|
|
1272
|
+
console.log(`JSON_STRING=>`,`[${unique_tags_string}]`)
|
|
1273
|
+
const unique_tags_array = JSON.parse(`[${unique_tags_string}]`);
|
|
1274
|
+
console.log(`JSON_DATA=>`,unique_tags_array)
|
|
1275
|
+
const unique_tags_flot = Array.isArray(unique_tags_array) ? unique_tags_array.flat() : [];
|
|
1276
|
+
const list: { [k in LanguageLocation]?: string[] } = {};
|
|
1277
|
+
|
|
1278
|
+
unique_tags_flot.map(item => {
|
|
1279
|
+
Language.locationList.map(lang => {
|
|
1280
|
+
list[lang] = [...(list[lang] ?? []), ...item[lang]];
|
|
1281
|
+
});
|
|
1282
|
+
});
|
|
1283
|
+
|
|
1284
|
+
Language.locationList.map(lang => {
|
|
1285
|
+
list[lang] = [...new Set(list[lang])];
|
|
1286
|
+
});
|
|
1287
|
+
|
|
1288
|
+
const data = { list };
|
|
1289
|
+
await new User(this.app).setConfig({
|
|
1290
|
+
key: 'product_general_tags',
|
|
1291
|
+
user_id: 'manager',
|
|
1292
|
+
value: data,
|
|
1293
|
+
});
|
|
1294
|
+
|
|
1295
|
+
return data;
|
|
1296
|
+
} catch (error) {
|
|
1297
|
+
throw exception.BadRequestError('BAD_REQUEST', 'Set product general tag conifg Error:' + error, null);
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
async setProductGeneralTagConifg(add_tags: { [k in LanguageLocation]: string[] }) {
|
|
1302
|
+
const tagConfig =
|
|
1303
|
+
(await new User(this.app).getConfigV2({ key: 'product_general_tags', user_id: 'manager' })) ??
|
|
1304
|
+
(await this.initProductGeneralTagConifg());
|
|
1305
|
+
|
|
1306
|
+
tagConfig.list ??= {};
|
|
1307
|
+
|
|
1308
|
+
Language.locationList.map(lang => {
|
|
1309
|
+
const originList = tagConfig.list[lang] ?? [];
|
|
1310
|
+
const updateList = add_tags[lang];
|
|
1311
|
+
tagConfig.list[lang] = [...new Set([...originList, ...updateList])];
|
|
1312
|
+
});
|
|
1313
|
+
|
|
1314
|
+
await new User(this.app).setConfig({
|
|
1315
|
+
key: 'product_general_tags',
|
|
1316
|
+
user_id: 'manager',
|
|
1317
|
+
value: tagConfig,
|
|
1318
|
+
});
|
|
1319
|
+
|
|
1320
|
+
return tagConfig;
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
async initOrderCustomizeTagConifg() {
|
|
1324
|
+
try {
|
|
1325
|
+
const managerTags = await new User(this.app).getConfigV2({ key: 'order_manager_tags', user_id: 'manager' });
|
|
1326
|
+
|
|
1327
|
+
if (managerTags && Array.isArray(managerTags.list)) {
|
|
1328
|
+
return managerTags;
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
const getData = await db.query(
|
|
1332
|
+
`
|
|
1333
|
+
SELECT
|
|
1334
|
+
GROUP_CONCAT(DISTINCT JSON_UNQUOTE(JSON_EXTRACT(orderData, '$.tags')) SEPARATOR ',') AS unique_tags
|
|
1335
|
+
FROM \`${this.app}\`.t_checkout
|
|
1336
|
+
WHERE JSON_UNQUOTE(JSON_EXTRACT(orderData, '$.tags')) IS NOT NULL
|
|
1337
|
+
`,
|
|
1338
|
+
[]
|
|
1339
|
+
);
|
|
1340
|
+
const unique_tags_string = getData[0]?.unique_tags ?? '';
|
|
1341
|
+
const unique_tags_array = JSON.parse(`[${unique_tags_string}]`);
|
|
1342
|
+
const unique_tags_flot = Array.isArray(unique_tags_array) ? unique_tags_array.flat() : [];
|
|
1343
|
+
const data = { list: [...new Set(unique_tags_flot)] };
|
|
1344
|
+
|
|
1345
|
+
await new User(this.app).setConfig({
|
|
1346
|
+
key: 'order_manager_tags',
|
|
1347
|
+
user_id: 'manager',
|
|
1348
|
+
value: data,
|
|
1349
|
+
});
|
|
1350
|
+
|
|
1351
|
+
return data;
|
|
1352
|
+
} catch (error) {
|
|
1353
|
+
throw exception.BadRequestError('BAD_REQUEST', 'Set order customize tag conifg Error:' + e, null);
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
async setOrderCustomizeTagConifg(add_tags: string[]) {
|
|
1358
|
+
const tagConfig = await new User(this.app).getConfigV2({ key: 'order_manager_tags', user_id: 'manager' });
|
|
1359
|
+
const tagList = tagConfig?.list ?? [];
|
|
1360
|
+
const data = { list: [...new Set([...tagList, ...add_tags])] };
|
|
1361
|
+
|
|
1362
|
+
await new User(this.app).setConfig({
|
|
1363
|
+
key: 'order_manager_tags',
|
|
1364
|
+
user_id: 'manager',
|
|
1365
|
+
value: data,
|
|
1366
|
+
});
|
|
1367
|
+
|
|
1368
|
+
return data;
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1171
1371
|
async getAllUseVoucher(userID: any): Promise<VoucherData[]> {
|
|
1172
1372
|
const now = Date.now();
|
|
1173
1373
|
|
|
@@ -1792,7 +1992,7 @@ export class Shopping {
|
|
|
1792
1992
|
count: number;
|
|
1793
1993
|
voucher_id: string;
|
|
1794
1994
|
}[];
|
|
1795
|
-
language?:
|
|
1995
|
+
language?: LanguageLocation;
|
|
1796
1996
|
pos_info?: any; //POS結帳資訊;
|
|
1797
1997
|
invoice_select?: string;
|
|
1798
1998
|
pre_order?: boolean;
|
|
@@ -1843,8 +2043,11 @@ export class Shopping {
|
|
|
1843
2043
|
ReturnURL: '',
|
|
1844
2044
|
NotifyURL: '',
|
|
1845
2045
|
};
|
|
2046
|
+
//現在是new一個新的版本
|
|
2047
|
+
//todo 新增一個fake單號 直接做付款的動作 同時做訂單上的更新把這個付款單號記錄下來
|
|
1846
2048
|
const newOrderID = Date.now();
|
|
1847
2049
|
const carData: Cart = {
|
|
2050
|
+
orderID: `${newOrderID}`,
|
|
1848
2051
|
discount: orderData.discount ?? 0,
|
|
1849
2052
|
customer_info: orderData.customer_info || {},
|
|
1850
2053
|
lineItems: orderData.lineItems ?? [],
|
|
@@ -1855,7 +2058,6 @@ export class Shopping {
|
|
|
1855
2058
|
rebate: orderData.rebate ?? 0,
|
|
1856
2059
|
goodsWeight: 0,
|
|
1857
2060
|
use_rebate: orderData.use_rebate || 0,
|
|
1858
|
-
orderID: `${newOrderID}`,
|
|
1859
2061
|
shipment_support: shipment_setting.support as any,
|
|
1860
2062
|
shipment_info: shipment_setting.info as any,
|
|
1861
2063
|
shipment_selector: [
|
|
@@ -1890,10 +2092,17 @@ export class Shopping {
|
|
|
1890
2092
|
fbp: sqlData.fbp as string,
|
|
1891
2093
|
editRecord: [],
|
|
1892
2094
|
};
|
|
1893
|
-
|
|
1894
|
-
|
|
2095
|
+
await OrderEvent.insertOrder({
|
|
2096
|
+
cartData: orderData,
|
|
2097
|
+
status: 0,
|
|
2098
|
+
app: this.app,
|
|
2099
|
+
});
|
|
2100
|
+
const result = await new PaymentTransaction(this.app, orderData.customer_info.payment_select).processPayment(
|
|
2101
|
+
carData,
|
|
2102
|
+
return_url
|
|
2103
|
+
);
|
|
1895
2104
|
|
|
1896
|
-
return result
|
|
2105
|
+
return result;
|
|
1897
2106
|
}
|
|
1898
2107
|
|
|
1899
2108
|
// return result
|
|
@@ -1967,7 +2176,7 @@ export class Shopping {
|
|
|
1967
2176
|
if (query.archived === 'true') {
|
|
1968
2177
|
querySql.push(`(archived="${query.archived}")`);
|
|
1969
2178
|
} else if (query.archived === 'false') {
|
|
1970
|
-
querySql.push(`((archived
|
|
2179
|
+
querySql.push(`((archived IS NULL) or (archived!='true'))`);
|
|
1971
2180
|
}
|
|
1972
2181
|
//退貨貨款狀態
|
|
1973
2182
|
query.status && querySql.push(`status IN (${query.status})`);
|
|
@@ -2188,6 +2397,56 @@ export class Shopping {
|
|
|
2188
2397
|
|
|
2189
2398
|
async splitOrder(obj: { orderData: Cart; splitOrderArray: OrderDetail[] }) {
|
|
2190
2399
|
try {
|
|
2400
|
+
async function processCheckoutsStaggered(
|
|
2401
|
+
splitOrderArray: any[],
|
|
2402
|
+
orderData: any,
|
|
2403
|
+
context: any
|
|
2404
|
+
): Promise<boolean | { result: string; reason: any }> {
|
|
2405
|
+
const promises = splitOrderArray.map((order, index) => {
|
|
2406
|
+
// 為每個操作返回一個新的 Promise
|
|
2407
|
+
return new Promise<void>((resolve, reject) => {
|
|
2408
|
+
// 可以定義更精確的 resolve 型別,這裡用 void 示意
|
|
2409
|
+
const delay = 1000 * index; // 計算延遲時間
|
|
2410
|
+
|
|
2411
|
+
setTimeout(() => {
|
|
2412
|
+
// 在 setTimeout 回呼中執行非同步操作
|
|
2413
|
+
const payload = {
|
|
2414
|
+
code_array: [],
|
|
2415
|
+
order_id: orderData?.splitOrders?.[index] ?? '',
|
|
2416
|
+
line_items: order.lineItems as any,
|
|
2417
|
+
customer_info: order.customer_info,
|
|
2418
|
+
return_url: '',
|
|
2419
|
+
user_info: order.user_info,
|
|
2420
|
+
discount: order.discount,
|
|
2421
|
+
voucher: order.voucher,
|
|
2422
|
+
total: order.total,
|
|
2423
|
+
pay_status: Number(order.pay_status),
|
|
2424
|
+
};
|
|
2425
|
+
|
|
2426
|
+
// 假設 context.toCheckout 本身返回一個 Promise
|
|
2427
|
+
context
|
|
2428
|
+
.toCheckout(payload, 'split')
|
|
2429
|
+
.then(() => {
|
|
2430
|
+
resolve(); // 當 toCheckout 成功時,resolve 外層的 Promise
|
|
2431
|
+
})
|
|
2432
|
+
.catch((error: any) => {
|
|
2433
|
+
reject(error); // 當 toCheckout 失敗時,reject 外層的 Promise
|
|
2434
|
+
});
|
|
2435
|
+
}, delay); // 使用計算出的延遲
|
|
2436
|
+
});
|
|
2437
|
+
}); // map 結束
|
|
2438
|
+
|
|
2439
|
+
try {
|
|
2440
|
+
await Promise.all(promises);
|
|
2441
|
+
return true; // 全部成功
|
|
2442
|
+
} catch (e) {
|
|
2443
|
+
console.error('處理拆分訂單結帳時至少發生一個錯誤 (從 Promise.all 捕獲):', e);
|
|
2444
|
+
return {
|
|
2445
|
+
result: 'failure',
|
|
2446
|
+
reason: e, // 返回捕獲到的錯誤
|
|
2447
|
+
};
|
|
2448
|
+
}
|
|
2449
|
+
}
|
|
2191
2450
|
const currentTime = new Date().toISOString();
|
|
2192
2451
|
|
|
2193
2452
|
//給定訂單編號 產生 編號A 編號B... 依此類推
|
|
@@ -2203,8 +2462,7 @@ export class Shopping {
|
|
|
2203
2462
|
|
|
2204
2463
|
return orderIdArray;
|
|
2205
2464
|
}
|
|
2206
|
-
|
|
2207
|
-
//整理原本訂單的總價 優惠卷
|
|
2465
|
+
//整理原本訂單的總價 優惠卷的資訊 方便原本的訂單更新
|
|
2208
2466
|
function refreshOrder(orderData: Cart, splitOrderArray: OrderDetail[]) {
|
|
2209
2467
|
const { newTotal, newDiscount } = splitOrderArray.reduce(
|
|
2210
2468
|
(acc, order) => {
|
|
@@ -2231,37 +2489,7 @@ export class Shopping {
|
|
|
2231
2489
|
cart_token: orderData.orderID,
|
|
2232
2490
|
orderData,
|
|
2233
2491
|
});
|
|
2234
|
-
|
|
2235
|
-
await (new CheckoutEvent(this.app, this.token)).toCheckout(
|
|
2236
|
-
{
|
|
2237
|
-
code_array: [],
|
|
2238
|
-
order_id: orderData?.splitOrders?.[index] ?? '',
|
|
2239
|
-
line_items: order.lineItems as any,
|
|
2240
|
-
customer_info: order.customer_info,
|
|
2241
|
-
return_url: '',
|
|
2242
|
-
user_info: order.user_info,
|
|
2243
|
-
discount: order.discount,
|
|
2244
|
-
voucher: order.voucher,
|
|
2245
|
-
total: order.total,
|
|
2246
|
-
pay_status: Number(order.pay_status),
|
|
2247
|
-
},
|
|
2248
|
-
'split'
|
|
2249
|
-
);
|
|
2250
|
-
}
|
|
2251
|
-
|
|
2252
|
-
// try {
|
|
2253
|
-
// await db.query(
|
|
2254
|
-
// `UPDATE \`${this.app}\`.t_checkout
|
|
2255
|
-
// SET orderData = ?
|
|
2256
|
-
// WHERE cart_token = ?;`,
|
|
2257
|
-
// [JSON.stringify(orderData), orderData.orderID]
|
|
2258
|
-
// );
|
|
2259
|
-
// }catch (e:any){
|
|
2260
|
-
// console.error(e);
|
|
2261
|
-
// throw exception.BadRequestError('BAD_REQUEST', 'putOrder Error:' + e, null);
|
|
2262
|
-
// }
|
|
2263
|
-
|
|
2264
|
-
return true;
|
|
2492
|
+
return await processCheckoutsStaggered(splitOrderArray, orderData, this);
|
|
2265
2493
|
} catch (e) {
|
|
2266
2494
|
throw exception.BadRequestError('BAD_REQUEST', 'splitOrder Error:' + e, null);
|
|
2267
2495
|
}
|
|
@@ -2737,7 +2965,6 @@ export class Shopping {
|
|
|
2737
2965
|
// 恢復取消訂單的庫存
|
|
2738
2966
|
orderData.lineItems = resetLineItems(orderData.lineItems);
|
|
2739
2967
|
origin.orderData.lineItems = resetLineItems(origin.orderData.lineItems);
|
|
2740
|
-
|
|
2741
2968
|
// 釋放優惠券
|
|
2742
2969
|
await this.releaseVoucherHistory(orderData.orderID, orderData.orderStatus === '-1' ? 0 : 1);
|
|
2743
2970
|
|
|
@@ -2783,7 +3010,14 @@ export class Shopping {
|
|
|
2783
3010
|
|
|
2784
3011
|
// 當訂單出貨狀態變更,觸發通知事件
|
|
2785
3012
|
const updateProgress = update.orderData.progress;
|
|
2786
|
-
|
|
3013
|
+
|
|
3014
|
+
if (
|
|
3015
|
+
updateProgress === 'wait' &&
|
|
3016
|
+
update.orderData.user_info.shipment_number &&
|
|
3017
|
+
update.orderData.user_info.shipment_number !== origin.orderData.user_info.shipment_number
|
|
3018
|
+
) {
|
|
3019
|
+
await this.sendNotifications(orderData, 'in_stock');
|
|
3020
|
+
} else if (prevProgress !== updateProgress) {
|
|
2787
3021
|
if (updateProgress === 'shipping') {
|
|
2788
3022
|
await this.sendNotifications(orderData, 'shipment');
|
|
2789
3023
|
} else if (updateProgress === 'arrived') {
|
|
@@ -2812,13 +3046,16 @@ export class Shopping {
|
|
|
2812
3046
|
{}
|
|
2813
3047
|
);
|
|
2814
3048
|
await db.query(
|
|
2815
|
-
`UPDATE \`${this.app}\`.t_checkout
|
|
2816
|
-
SET ?
|
|
2817
|
-
WHERE id = ?;
|
|
3049
|
+
`UPDATE \`${this.app}\`.t_checkout SET ? WHERE id = ?;
|
|
2818
3050
|
`,
|
|
2819
3051
|
[updateData, origin.id]
|
|
2820
3052
|
);
|
|
2821
3053
|
|
|
3054
|
+
// 更新訂單現有標籤
|
|
3055
|
+
if (Array.isArray(update.orderData.tags)) {
|
|
3056
|
+
await this.setOrderCustomizeTagConifg(update.orderData.tags);
|
|
3057
|
+
}
|
|
3058
|
+
|
|
2822
3059
|
// 同步蝦皮商品
|
|
2823
3060
|
await Promise.all(
|
|
2824
3061
|
origin.orderData.lineItems.map(async (lineItem: any) => {
|
|
@@ -2999,12 +3236,13 @@ export class Shopping {
|
|
|
2999
3236
|
/**
|
|
3000
3237
|
* 寄送同時寄送購買人和寄件人
|
|
3001
3238
|
* */
|
|
3002
|
-
private async sendNotifications(orderData: any, type: 'shipment' | 'arrival') {
|
|
3239
|
+
private async sendNotifications(orderData: any, type: 'shipment' | 'arrival' | 'in_stock') {
|
|
3003
3240
|
const { lineID } = orderData.customer_info;
|
|
3004
3241
|
const messages = [];
|
|
3005
3242
|
const typeMap = {
|
|
3006
3243
|
shipment: 'shipment',
|
|
3007
3244
|
arrival: 'shipment-arrival',
|
|
3245
|
+
in_stock: 'in-stock',
|
|
3008
3246
|
};
|
|
3009
3247
|
|
|
3010
3248
|
if (lineID) {
|
|
@@ -3245,12 +3483,19 @@ export class Shopping {
|
|
|
3245
3483
|
payment_select?: string;
|
|
3246
3484
|
is_reconciliation?: boolean;
|
|
3247
3485
|
reconciliation_status?: string[];
|
|
3486
|
+
manager_tag?: string;
|
|
3487
|
+
member_levels?: string;
|
|
3248
3488
|
}) {
|
|
3249
3489
|
try {
|
|
3250
|
-
let querySql = ['1=1'];
|
|
3251
|
-
let orderString = 'order by id desc';
|
|
3252
3490
|
const timer = new UtTimer('get-checkout-info');
|
|
3253
3491
|
timer.checkPoint('start');
|
|
3492
|
+
|
|
3493
|
+
const querySql = ['o.id IS NOT NULL'];
|
|
3494
|
+
let orderString = 'order by created_time desc';
|
|
3495
|
+
|
|
3496
|
+
// 初始化訂單現有標籤
|
|
3497
|
+
await this.initOrderCustomizeTagConifg();
|
|
3498
|
+
|
|
3254
3499
|
if (query.search && query.searchType) {
|
|
3255
3500
|
switch (query.searchType) {
|
|
3256
3501
|
case 'cart_token':
|
|
@@ -3305,7 +3550,7 @@ export class Shopping {
|
|
|
3305
3550
|
let search: string[] = [];
|
|
3306
3551
|
query.reconciliation_status!!.map(status => {
|
|
3307
3552
|
if (status === 'pending_entry') {
|
|
3308
|
-
search.push(`total_received
|
|
3553
|
+
search.push(`total_received IS NULL`);
|
|
3309
3554
|
} else if (status === 'completed_entry') {
|
|
3310
3555
|
search.push(`total_received = total`);
|
|
3311
3556
|
} else if (status === 'refunded') {
|
|
@@ -3313,9 +3558,9 @@ export class Shopping {
|
|
|
3313
3558
|
} else if (status === 'completed_offset') {
|
|
3314
3559
|
search.push(`(total_received < total) && ((total_received + offset_amount) = total)`);
|
|
3315
3560
|
} else if (status === 'pending_offset') {
|
|
3316
|
-
search.push(`(total_received < total) && (offset_amount
|
|
3561
|
+
search.push(`(total_received < total) && (offset_amount IS NULL)`);
|
|
3317
3562
|
} else if (status === 'pending_refund') {
|
|
3318
|
-
search.push(`(total_received > total) && (offset_amount
|
|
3563
|
+
search.push(`(total_received > total) && (offset_amount IS NULL)`);
|
|
3319
3564
|
}
|
|
3320
3565
|
});
|
|
3321
3566
|
querySql.push(
|
|
@@ -3326,6 +3571,7 @@ export class Shopping {
|
|
|
3326
3571
|
.join(' or ')})`
|
|
3327
3572
|
);
|
|
3328
3573
|
}
|
|
3574
|
+
|
|
3329
3575
|
if (query.orderStatus) {
|
|
3330
3576
|
let orderArray = query.orderStatus.split(',');
|
|
3331
3577
|
let temp = '';
|
|
@@ -3341,12 +3587,15 @@ export class Shopping {
|
|
|
3341
3587
|
|
|
3342
3588
|
querySql.push(countingSQL);
|
|
3343
3589
|
}
|
|
3590
|
+
|
|
3344
3591
|
if (query.is_shipment) {
|
|
3345
3592
|
querySql.push(`(shipment_number IS NOT NULL) and (shipment_number != '')`);
|
|
3346
3593
|
}
|
|
3594
|
+
|
|
3347
3595
|
if (query.is_reconciliation) {
|
|
3348
3596
|
querySql.push(`((o.status in (1,-2)) or ((payment_method='cash_on_delivery' and progress='finish') ))`);
|
|
3349
3597
|
}
|
|
3598
|
+
|
|
3350
3599
|
if (query.payment_select) {
|
|
3351
3600
|
querySql.push(
|
|
3352
3601
|
`payment_method in (${query.payment_select
|
|
@@ -3355,13 +3604,14 @@ export class Shopping {
|
|
|
3355
3604
|
.join(',')})`
|
|
3356
3605
|
);
|
|
3357
3606
|
}
|
|
3607
|
+
|
|
3358
3608
|
if (query.progress) {
|
|
3359
3609
|
//備貨中
|
|
3360
3610
|
if (query.progress === 'in_stock') {
|
|
3361
3611
|
query.progress = 'wait';
|
|
3362
3612
|
querySql.push(`shipment_number is NOT null`);
|
|
3363
3613
|
} else if (query.progress === 'wait') {
|
|
3364
|
-
querySql.push(`shipment_number
|
|
3614
|
+
querySql.push(`shipment_number IS NULL`);
|
|
3365
3615
|
}
|
|
3366
3616
|
let newArray = query.progress.split(',');
|
|
3367
3617
|
let temp = '';
|
|
@@ -3371,6 +3621,7 @@ export class Shopping {
|
|
|
3371
3621
|
temp += `progress IN (${newArray.map(status => `"${status}"`).join(',')})`;
|
|
3372
3622
|
querySql.push(`(${temp})`);
|
|
3373
3623
|
}
|
|
3624
|
+
|
|
3374
3625
|
if (query.distribution_code) {
|
|
3375
3626
|
let codes = query.distribution_code.split(',');
|
|
3376
3627
|
let temp = '';
|
|
@@ -3381,8 +3632,9 @@ export class Shopping {
|
|
|
3381
3632
|
if (query.is_pos === 'true') {
|
|
3382
3633
|
querySql.push(`order_source='POS'`);
|
|
3383
3634
|
} else if (query.is_pos === 'false') {
|
|
3384
|
-
querySql.push(`(order_source!='POS' or order_source
|
|
3635
|
+
querySql.push(`(order_source!='POS' or order_source IS NULL)`);
|
|
3385
3636
|
}
|
|
3637
|
+
|
|
3386
3638
|
if (query.shipment) {
|
|
3387
3639
|
let shipment = query.shipment.split(',');
|
|
3388
3640
|
let temp = '';
|
|
@@ -3402,6 +3654,7 @@ export class Shopping {
|
|
|
3402
3654
|
`);
|
|
3403
3655
|
}
|
|
3404
3656
|
}
|
|
3657
|
+
|
|
3405
3658
|
if (query.shipment_time) {
|
|
3406
3659
|
const shipment_time = query.shipment_time.split(',');
|
|
3407
3660
|
if (shipment_time.length > 1) {
|
|
@@ -3428,37 +3681,104 @@ export class Shopping {
|
|
|
3428
3681
|
break;
|
|
3429
3682
|
}
|
|
3430
3683
|
}
|
|
3431
|
-
query.status && querySql.push(`o.status IN (${query.status})`);
|
|
3432
|
-
const orderMath = [];
|
|
3433
3684
|
|
|
3434
|
-
|
|
3685
|
+
if (query.manager_tag) {
|
|
3686
|
+
const tagSplit = query.manager_tag.split(',').map(tag => tag.trim());
|
|
3687
|
+
if (tagSplit.length > 0) {
|
|
3688
|
+
const tagJoin = tagSplit.map(tag => {
|
|
3689
|
+
return `JSON_CONTAINS(orderData->>'$.tags', '"${tag}"')`;
|
|
3690
|
+
});
|
|
3691
|
+
querySql.push(`(${tagJoin.join(' OR ')})`);
|
|
3692
|
+
}
|
|
3693
|
+
}
|
|
3694
|
+
|
|
3695
|
+
if (query.status) {
|
|
3696
|
+
querySql.push(`o.status IN (${query.status})`);
|
|
3697
|
+
}
|
|
3698
|
+
|
|
3699
|
+
const orderMath = [];
|
|
3435
3700
|
query.email && orderMath.push(`(email=${db.escape(query.email)})`);
|
|
3436
3701
|
query.phone && orderMath.push(`(email=${db.escape(query.phone)})`);
|
|
3437
3702
|
if (orderMath.length) {
|
|
3438
|
-
querySql.push(`(${orderMath.join('
|
|
3703
|
+
querySql.push(`(${orderMath.join(' OR ')})`);
|
|
3704
|
+
}
|
|
3705
|
+
|
|
3706
|
+
if (query.member_levels) {
|
|
3707
|
+
let temp: string[] = [];
|
|
3708
|
+
const queryLevel = query.member_levels.split(',');
|
|
3709
|
+
const queryIdLevel = queryLevel.filter(level => level !== 'null');
|
|
3710
|
+
|
|
3711
|
+
if (queryLevel.includes('null')) {
|
|
3712
|
+
temp = [`u.member_level IS NULL`, `u.member_level = ''`];
|
|
3713
|
+
}
|
|
3714
|
+
|
|
3715
|
+
if (queryIdLevel.length > 0) {
|
|
3716
|
+
temp = [
|
|
3717
|
+
...temp,
|
|
3718
|
+
`u.member_level IN (${queryIdLevel
|
|
3719
|
+
.map(level => {
|
|
3720
|
+
return db.escape(level);
|
|
3721
|
+
})
|
|
3722
|
+
.join(',')})`,
|
|
3723
|
+
];
|
|
3724
|
+
}
|
|
3725
|
+
|
|
3726
|
+
if (temp.length > 0) {
|
|
3727
|
+
querySql.push(`(${temp.join(' OR ')})`);
|
|
3728
|
+
}
|
|
3439
3729
|
}
|
|
3440
3730
|
|
|
3441
3731
|
if (query.filter_type === 'true' || query.archived) {
|
|
3442
3732
|
if (query.archived === 'true') {
|
|
3443
|
-
querySql.push(`(archived="${query.archived}")
|
|
3444
|
-
AND (order_status IS NULL OR order_status NOT IN (-99))`);
|
|
3733
|
+
querySql.push(`(archived="${query.archived}") AND (order_status IS NULL OR order_status NOT IN (-99))`);
|
|
3445
3734
|
} else {
|
|
3446
|
-
querySql.push(`((archived="${query.archived}") or (archived
|
|
3735
|
+
querySql.push(`((archived="${query.archived}") or (archived IS NULL))`);
|
|
3447
3736
|
}
|
|
3448
3737
|
} else if (query.filter_type === 'normal') {
|
|
3449
|
-
querySql.push(`((archived
|
|
3738
|
+
querySql.push(`((archived IS NULL) or (archived!='true'))`);
|
|
3450
3739
|
}
|
|
3740
|
+
|
|
3451
3741
|
if (!(query.filter_type === 'true' || query.archived)) {
|
|
3452
|
-
querySql.push(`((order_status
|
|
3453
|
-
}
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3742
|
+
querySql.push(`((order_status IS NULL) or (order_status NOT IN (-99)))`);
|
|
3743
|
+
}
|
|
3744
|
+
|
|
3745
|
+
// 定義基礎查詢結構
|
|
3746
|
+
const baseSelect = `
|
|
3747
|
+
SELECT
|
|
3748
|
+
o.*,
|
|
3749
|
+
i.invoice_no,
|
|
3750
|
+
i.invoice_data,
|
|
3751
|
+
i.\`status\` as invoice_status
|
|
3752
|
+
FROM`;
|
|
3753
|
+
|
|
3754
|
+
const joinClause = `LEFT JOIN \`${this.app}\`.t_invoice_memory i ON o.cart_token = i.order_id AND i.status = 1`;
|
|
3755
|
+
const whereClause = `WHERE ${querySql.join(' AND ')}`;
|
|
3756
|
+
|
|
3757
|
+
let sql: string;
|
|
3758
|
+
|
|
3759
|
+
if (query.member_levels) {
|
|
3760
|
+
// 查詢會員等級資料
|
|
3761
|
+
sql = `
|
|
3762
|
+
(
|
|
3763
|
+
(
|
|
3764
|
+
${baseSelect} \`${this.app}\`.t_user u
|
|
3765
|
+
LEFT JOIN \`${this.app}\`.t_checkout o ON o.email = u.phone
|
|
3766
|
+
${joinClause}
|
|
3767
|
+
${whereClause}
|
|
3768
|
+
)
|
|
3769
|
+
UNION
|
|
3770
|
+
(
|
|
3771
|
+
${baseSelect} \`${this.app}\`.t_user u
|
|
3772
|
+
LEFT JOIN \`${this.app}\`.t_checkout o ON o.email = u.email
|
|
3773
|
+
${joinClause}
|
|
3774
|
+
${whereClause}
|
|
3775
|
+
)
|
|
3776
|
+
) ${orderString}`;
|
|
3777
|
+
} else {
|
|
3778
|
+
// 直接查詢結帳資料
|
|
3779
|
+
sql = `${baseSelect} \`${this.app}\`.t_checkout o ${joinClause} ${whereClause} ${orderString}`;
|
|
3780
|
+
}
|
|
3781
|
+
|
|
3462
3782
|
if (query.returnSearch == 'true') {
|
|
3463
3783
|
const data = await db.query(
|
|
3464
3784
|
`SELECT *
|
|
@@ -3487,43 +3807,35 @@ export class Shopping {
|
|
|
3487
3807
|
}
|
|
3488
3808
|
return data[0];
|
|
3489
3809
|
}
|
|
3490
|
-
|
|
3491
|
-
|
|
3810
|
+
|
|
3811
|
+
const response_data: any = await new Promise(async resolve => {
|
|
3492
3812
|
if (query.id) {
|
|
3493
3813
|
const data = (
|
|
3494
3814
|
await db.query(
|
|
3495
|
-
`SELECT *
|
|
3496
|
-
FROM (${sql}) as subqyery limit ${query.page * query.limit}, ${query.limit}
|
|
3815
|
+
`SELECT * FROM (${sql}) as subqyery limit ${query.page * query.limit}, ${query.limit}
|
|
3497
3816
|
`,
|
|
3498
3817
|
[]
|
|
3499
3818
|
)
|
|
3500
3819
|
)[0];
|
|
3820
|
+
timer.checkPoint('get response_data (has query.id)');
|
|
3501
3821
|
resolve({
|
|
3502
3822
|
data: data,
|
|
3503
3823
|
result: !!data,
|
|
3504
3824
|
});
|
|
3505
3825
|
} else {
|
|
3506
3826
|
const data = await db.query(
|
|
3507
|
-
`SELECT *
|
|
3508
|
-
FROM (${sql}) as subqyery limit ${query.page * query.limit}, ${query.limit}
|
|
3827
|
+
`SELECT * FROM (${sql}) as subqyery limit ${query.page * query.limit}, ${query.limit}
|
|
3509
3828
|
`,
|
|
3510
3829
|
[]
|
|
3511
3830
|
);
|
|
3512
|
-
timer.checkPoint('
|
|
3513
|
-
console.log(sql);
|
|
3831
|
+
timer.checkPoint('get response_data (not query.id)');
|
|
3514
3832
|
resolve({
|
|
3515
3833
|
data: data,
|
|
3516
|
-
total: (
|
|
3517
|
-
await db.query(
|
|
3518
|
-
`SELECT count(1)
|
|
3519
|
-
FROM (${sql}) as subqyery
|
|
3520
|
-
`,
|
|
3521
|
-
[]
|
|
3522
|
-
)
|
|
3523
|
-
)[0]['count(1)'],
|
|
3834
|
+
total: (await db.query(`SELECT count(1) FROM (${sql}) as subqyery`, []))[0]['count(1)'],
|
|
3524
3835
|
});
|
|
3525
3836
|
}
|
|
3526
3837
|
});
|
|
3838
|
+
|
|
3527
3839
|
const obMap = Array.isArray(response_data.data) ? response_data.data : [response_data.data];
|
|
3528
3840
|
const keyData = (
|
|
3529
3841
|
await Private_config.getConfig({
|
|
@@ -3531,6 +3843,7 @@ export class Shopping {
|
|
|
3531
3843
|
key: 'glitter_finance',
|
|
3532
3844
|
})
|
|
3533
3845
|
)[0].value;
|
|
3846
|
+
|
|
3534
3847
|
await Promise.all(
|
|
3535
3848
|
obMap
|
|
3536
3849
|
.map(async (order: any) => {
|
|
@@ -3601,7 +3914,7 @@ export class Shopping {
|
|
|
3601
3914
|
page: 0,
|
|
3602
3915
|
limit: 1,
|
|
3603
3916
|
search: order.cart_token,
|
|
3604
|
-
searchType: order.orderData
|
|
3917
|
+
searchType: order.orderData?.order_number,
|
|
3605
3918
|
})
|
|
3606
3919
|
).data[0];
|
|
3607
3920
|
order.invoice_number = invoice && invoice.invoice_no;
|
|
@@ -3614,7 +3927,9 @@ export class Shopping {
|
|
|
3614
3927
|
})
|
|
3615
3928
|
)
|
|
3616
3929
|
);
|
|
3930
|
+
|
|
3617
3931
|
timer.checkPoint('finish-query-all');
|
|
3932
|
+
|
|
3618
3933
|
return response_data;
|
|
3619
3934
|
} catch (e) {
|
|
3620
3935
|
throw exception.BadRequestError('BAD_REQUEST', 'getCheckOut Error:' + e, null);
|
|
@@ -3969,8 +4284,7 @@ export class Shopping {
|
|
|
3969
4284
|
}
|
|
3970
4285
|
|
|
3971
4286
|
const insertData = await db.query(
|
|
3972
|
-
`INSERT INTO \`${this.app}\`.t_variants
|
|
3973
|
-
SET ?
|
|
4287
|
+
`INSERT INTO \`${this.app}\`.t_variants SET ?
|
|
3974
4288
|
`,
|
|
3975
4289
|
[
|
|
3976
4290
|
{
|
|
@@ -3991,7 +4305,15 @@ export class Shopping {
|
|
|
3991
4305
|
return insertData;
|
|
3992
4306
|
});
|
|
3993
4307
|
|
|
3994
|
-
|
|
4308
|
+
const chunk = 10;
|
|
4309
|
+
const chunkLength = Math.ceil(insertPromises.length / chunk);
|
|
4310
|
+
|
|
4311
|
+
for (let i = 0; i < chunkLength; i++) {
|
|
4312
|
+
const promisesArray = insertPromises.slice(i * chunk, (i + 1) * chunk);
|
|
4313
|
+
setTimeout(async () => {
|
|
4314
|
+
await Promise.all(promisesArray);
|
|
4315
|
+
}, 200);
|
|
4316
|
+
}
|
|
3995
4317
|
|
|
3996
4318
|
const exhibitionConfig = await _user.getConfigV2({ key: 'exhibition_manager', user_id: 'manager' });
|
|
3997
4319
|
exhibitionConfig.list = exhibitionConfig.list ?? [];
|
|
@@ -4679,6 +5001,7 @@ export class Shopping {
|
|
|
4679
5001
|
delete product['content'];
|
|
4680
5002
|
delete product['preview_image'];
|
|
4681
5003
|
const og_content = og_data['content'];
|
|
5004
|
+
|
|
4682
5005
|
if (og_content.language_data && og_content.language_data[store_info.language_setting.def]) {
|
|
4683
5006
|
og_content.language_data[store_info.language_setting.def].seo = product.seo;
|
|
4684
5007
|
og_content.language_data[store_info.language_setting.def].title = product.title;
|
|
@@ -4692,10 +5015,10 @@ export class Shopping {
|
|
|
4692
5015
|
product.preview_image = og_data['content'].preview_image || [];
|
|
4693
5016
|
productArray[index] = product;
|
|
4694
5017
|
} else {
|
|
4695
|
-
console.error('Product id not exist:', product);
|
|
5018
|
+
console.error('Product id not exist:', product.title);
|
|
4696
5019
|
}
|
|
4697
5020
|
} else {
|
|
4698
|
-
console.error('Product has not id:', product);
|
|
5021
|
+
console.error('Product has not id:', product.title);
|
|
4699
5022
|
}
|
|
4700
5023
|
resolve(true);
|
|
4701
5024
|
});
|
|
@@ -4729,8 +5052,8 @@ export class Shopping {
|
|
|
4729
5052
|
|
|
4730
5053
|
if (productArray.length) {
|
|
4731
5054
|
const data = await db.query(
|
|
4732
|
-
`
|
|
4733
|
-
|
|
5055
|
+
`REPLACE INTO \`${this.app}\`.\`t_manager_post\` (id,userID,content) values ?
|
|
5056
|
+
`,
|
|
4734
5057
|
[
|
|
4735
5058
|
productArray.map((product: any) => {
|
|
4736
5059
|
if (!product.id) {
|
|
@@ -4759,37 +5082,55 @@ export class Shopping {
|
|
|
4759
5082
|
product.id = product.id || insertIDStart++;
|
|
4760
5083
|
return new Shopping(this.app, this.token).postVariantsAndPriceValue(product);
|
|
4761
5084
|
});
|
|
4762
|
-
await Promise.all(promises);
|
|
4763
|
-
}
|
|
4764
5085
|
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
and id != ${content.id}`,
|
|
4774
|
-
[]
|
|
4775
|
-
);
|
|
4776
|
-
if (find_conflict[0]['count(1)'] > 0) {
|
|
4777
|
-
throw exception.BadRequestError('BAD_REQUEST', 'DOMAIN ALREADY EXISTS:', {
|
|
4778
|
-
message: '網域已被使用',
|
|
4779
|
-
code: '733',
|
|
4780
|
-
});
|
|
4781
|
-
}
|
|
4782
|
-
}
|
|
5086
|
+
const chunk = 10;
|
|
5087
|
+
const chunkLength = Math.ceil(promises.length / chunk);
|
|
5088
|
+
|
|
5089
|
+
for (let i = 0; i < chunkLength; i++) {
|
|
5090
|
+
const promisesArray = promises.slice(i * chunk, (i + 1) * chunk);
|
|
5091
|
+
setTimeout(async () => {
|
|
5092
|
+
await Promise.all(promisesArray);
|
|
5093
|
+
}, 200);
|
|
4783
5094
|
}
|
|
5095
|
+
}
|
|
4784
5096
|
|
|
5097
|
+
async putProduct(content: any) {
|
|
4785
5098
|
try {
|
|
4786
5099
|
content.type = 'product';
|
|
4787
5100
|
|
|
5101
|
+
// 檢查 seo domain 是否重複
|
|
5102
|
+
if (content.language_data) {
|
|
5103
|
+
const language = await App.getSupportLanguage(this.app);
|
|
5104
|
+
for (const b of language) {
|
|
5105
|
+
const find_conflict = await db.query(
|
|
5106
|
+
`SELECT count(1)
|
|
5107
|
+
FROM \`${this.app}\`.t_manager_post
|
|
5108
|
+
WHERE content ->>'$.language_data."${b}".seo.domain'='${decodeURIComponent(content.language_data[b].seo.domain)}'
|
|
5109
|
+
AND id != ${content.id}`,
|
|
5110
|
+
[]
|
|
5111
|
+
);
|
|
5112
|
+
if (find_conflict[0]['count(1)'] > 0) {
|
|
5113
|
+
throw exception.BadRequestError('BAD_REQUEST', 'DOMAIN ALREADY EXISTS:', {
|
|
5114
|
+
message: '網域已被使用',
|
|
5115
|
+
code: '733',
|
|
5116
|
+
});
|
|
5117
|
+
}
|
|
5118
|
+
}
|
|
5119
|
+
}
|
|
5120
|
+
|
|
5121
|
+
// 檢查 Variant 資料屬性
|
|
4788
5122
|
this.checkVariantDataType(content.variants);
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
5123
|
+
|
|
5124
|
+
// 重新設置管理員標籤
|
|
5125
|
+
await Promise.all([
|
|
5126
|
+
this.setProductCustomizeTagConifg(content.product_customize_tag ?? []),
|
|
5127
|
+
this.setProductGeneralTagConifg(content.product_tag?.language ?? []),
|
|
5128
|
+
]);
|
|
5129
|
+
|
|
5130
|
+
// 更新商品
|
|
5131
|
+
await db.query(
|
|
5132
|
+
`UPDATE \`${this.app}\`.\`t_manager_post\` SET ? WHERE id = ?
|
|
5133
|
+
`,
|
|
4793
5134
|
[
|
|
4794
5135
|
{
|
|
4795
5136
|
content: JSON.stringify(content),
|
|
@@ -4797,7 +5138,11 @@ export class Shopping {
|
|
|
4797
5138
|
content.id,
|
|
4798
5139
|
]
|
|
4799
5140
|
);
|
|
5141
|
+
|
|
5142
|
+
// 更新商品 Variant
|
|
4800
5143
|
await new Shopping(this.app, this.token).postVariantsAndPriceValue(content);
|
|
5144
|
+
|
|
5145
|
+
// 同步更新蝦皮
|
|
4801
5146
|
if (content.shopee_id) {
|
|
4802
5147
|
await new Shopee(this.app, this.token).asyncStockToShopee({
|
|
4803
5148
|
product: {
|
|
@@ -5000,9 +5345,11 @@ export class Shopping {
|
|
|
5000
5345
|
query.id && querySql.push(`(v.id = ${query.id})`);
|
|
5001
5346
|
if (query.id_list) {
|
|
5002
5347
|
if (query.id_list?.includes('-')) {
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5348
|
+
querySql.push(
|
|
5349
|
+
`(v.product_id in (${query.id_list.split(',').map(dd => {
|
|
5350
|
+
return dd.split('-')[0];
|
|
5351
|
+
})}))`
|
|
5352
|
+
);
|
|
5006
5353
|
} else {
|
|
5007
5354
|
querySql.push(`(v.id in (${query.id_list}))`);
|
|
5008
5355
|
}
|
|
@@ -5102,11 +5449,11 @@ export class Shopping {
|
|
|
5102
5449
|
if (query.id_list) {
|
|
5103
5450
|
//過濾出需要的商品規格
|
|
5104
5451
|
if (query.id_list?.includes('-')) {
|
|
5105
|
-
data.data=data.data.filter((dd:any)=>{
|
|
5106
|
-
return query.id_list?.split(',').find(
|
|
5107
|
-
return d1 === [dd.product_id
|
|
5108
|
-
})
|
|
5109
|
-
})
|
|
5452
|
+
data.data = data.data.filter((dd: any) => {
|
|
5453
|
+
return query.id_list?.split(',').find(d1 => {
|
|
5454
|
+
return d1 === [dd.product_id, ...dd.variant_content.spec].join('-');
|
|
5455
|
+
});
|
|
5456
|
+
});
|
|
5110
5457
|
}
|
|
5111
5458
|
}
|
|
5112
5459
|
const shopee_data_list: { id: string; data: any }[] = [];
|