ts-glitter 20.6.8 → 20.7.0
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/stock-history.js +75 -63
- package/lowcode/cms-plugin/stock-history.ts +390 -376
- 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/stock.ts +1 -0
- 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 +371 -95
- package/src/api-public/services/shopping.js.map +1 -1
- package/src/api-public/services/shopping.ts +499 -141
- package/src/api-public/services/stock.js +0 -3
- package/src/api-public/services/stock.js.map +1 -1
- package/src/api-public/services/stock.ts +3 -3
- package/src/api-public/services/user.d.ts +1 -0
- package/src/api-public/services/user.js +32 -12
- package/src/api-public/services/user.js.map +1 -1
- package/src/api-public/services/user.ts +38 -19
- 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/ios/proshake/AppDelegate.swift +51 -7
- package/src/app-project/ios/proshake/Info.plist +11 -9
- package/src/app-project/ios/proshake/SceneDelegate.swift +18 -0
- package/src/app-project/ios/proshake/glitter-interface/BasicUtil.swift +43 -2
- package/src/app-project/ios/proshake/glitter-interface/Ecommerce.swift +56 -0
- package/src/app-project/ios/proshake.xcodeproj/project.xcworkspace/xcuserdata/jianzhi.wang.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- 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/ios-project.js +12 -6
- package/src/services/ios-project.js.map +1 -1
- package/src/services/ios-project.ts +12 -6
- 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,6 +34,7 @@ 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
40
|
type BindItem = {
|
|
@@ -206,16 +207,17 @@ class OrderDetail {
|
|
|
206
207
|
custom_form_delivery?: any;
|
|
207
208
|
shipment:
|
|
208
209
|
| 'normal'
|
|
209
|
-
| 'FAMIC2C'
|
|
210
210
|
| 'black_cat_freezing'
|
|
211
|
-
| 'UNIMARTC2C'
|
|
212
|
-
| 'HILIFEC2C'
|
|
213
|
-
| 'OKMARTC2C'
|
|
214
211
|
| 'now'
|
|
215
212
|
| 'shop'
|
|
216
213
|
| 'global_express'
|
|
217
214
|
| 'black_cat'
|
|
218
|
-
| '
|
|
215
|
+
| 'UNIMARTC2C'
|
|
216
|
+
| 'FAMIC2C'
|
|
217
|
+
| 'HILIFEC2C'
|
|
218
|
+
| 'OKMARTC2C'
|
|
219
|
+
| 'UNIMARTFREEZE'
|
|
220
|
+
| 'FAMIC2CFREEZE';
|
|
219
221
|
CVSStoreName: string;
|
|
220
222
|
CVSStoreID: string;
|
|
221
223
|
CVSTelephone: string;
|
|
@@ -307,8 +309,6 @@ type Collection = {
|
|
|
307
309
|
hidden?: boolean;
|
|
308
310
|
};
|
|
309
311
|
|
|
310
|
-
|
|
311
|
-
|
|
312
312
|
type MultiSaleType = 'store' | 'level' | 'tags';
|
|
313
313
|
|
|
314
314
|
export type Cart = {
|
|
@@ -396,6 +396,8 @@ export class Shopping {
|
|
|
396
396
|
max_price?: string;
|
|
397
397
|
status?: string;
|
|
398
398
|
channel?: string;
|
|
399
|
+
general_tag?: string;
|
|
400
|
+
manager_tag?: string;
|
|
399
401
|
whereStore?: string;
|
|
400
402
|
order_by?: string;
|
|
401
403
|
id_list?: string;
|
|
@@ -424,6 +426,9 @@ export class Shopping {
|
|
|
424
426
|
query.language = query.language ?? store_info.language_setting.def;
|
|
425
427
|
query.show_hidden = query.show_hidden ?? 'true';
|
|
426
428
|
|
|
429
|
+
// 初始化商品與管理員標籤 Config
|
|
430
|
+
// await Promise.all([this.initProductCustomizeTagConifg(), this.initProductGeneralTagConifg()]);
|
|
431
|
+
|
|
427
432
|
const orderMapping: Record<string, string> = {
|
|
428
433
|
title: `ORDER BY JSON_EXTRACT(content, '$.title')`,
|
|
429
434
|
max_price: `ORDER BY CAST(JSON_UNQUOTE(JSON_EXTRACT(content, '$.max_price')) AS SIGNED) DESC , id DESC`,
|
|
@@ -521,12 +526,12 @@ export class Shopping {
|
|
|
521
526
|
// 當非管理員時,檢查是否顯示隱形商品
|
|
522
527
|
if (query.filter_visible) {
|
|
523
528
|
if (query.filter_visible === 'true') {
|
|
524
|
-
querySql.push(`(content->>'$.visible'
|
|
529
|
+
querySql.push(`(content->>'$.visible' IS NULL || content->>'$.visible' = 'true')`);
|
|
525
530
|
} else {
|
|
526
531
|
querySql.push(`(content->>'$.visible' = 'false')`);
|
|
527
532
|
}
|
|
528
533
|
} else if (!query.is_manger && `${query.show_hidden}` !== 'true') {
|
|
529
|
-
querySql.push(`(content->>'$.visible'
|
|
534
|
+
querySql.push(`(content->>'$.visible' IS NULL || content->>'$.visible' = 'true')`);
|
|
530
535
|
}
|
|
531
536
|
|
|
532
537
|
// 判斷有帶入商品類型時,顯示商品類型,反之預設折是一班商品
|
|
@@ -685,6 +690,29 @@ export class Shopping {
|
|
|
685
690
|
}
|
|
686
691
|
}
|
|
687
692
|
|
|
693
|
+
if (query.manager_tag) {
|
|
694
|
+
const tagSplit = query.manager_tag.split(',').map(tag => tag.trim());
|
|
695
|
+
if (tagSplit.length > 0) {
|
|
696
|
+
const tagJoin = tagSplit.map(tag => {
|
|
697
|
+
return `JSON_CONTAINS(content->>'$.product_customize_tag', '"${tag}"')`;
|
|
698
|
+
});
|
|
699
|
+
querySql.push(`(${tagJoin.join(' OR ')})`);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
if (query.general_tag) {
|
|
704
|
+
const tagSplit = query.general_tag.split(',').map(tag => tag.trim());
|
|
705
|
+
if (tagSplit.length > 0) {
|
|
706
|
+
const tagJoin = tagSplit.map(tag => {
|
|
707
|
+
return `(JSON_CONTAINS(
|
|
708
|
+
JSON_EXTRACT(content, '$.product_tag.language."${query.language ?? 'zh-TW'}"'),
|
|
709
|
+
JSON_QUOTE('${tag}')
|
|
710
|
+
))`;
|
|
711
|
+
});
|
|
712
|
+
querySql.push(`(${tagJoin.join(' OR ')})`);
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
|
|
688
716
|
if (query.id_list && idStr) {
|
|
689
717
|
querySql.push(`(id in (${idStr}))`);
|
|
690
718
|
}
|
|
@@ -967,6 +995,7 @@ export class Shopping {
|
|
|
967
995
|
|
|
968
996
|
products.data = foundProduct || products.data[0];
|
|
969
997
|
}
|
|
998
|
+
|
|
970
999
|
if (query.id && products.data.length > 0) {
|
|
971
1000
|
products.data = products.data[0];
|
|
972
1001
|
}
|
|
@@ -1168,6 +1197,175 @@ export class Shopping {
|
|
|
1168
1197
|
}
|
|
1169
1198
|
}
|
|
1170
1199
|
|
|
1200
|
+
async initProductCustomizeTagConifg() {
|
|
1201
|
+
try {
|
|
1202
|
+
const managerTags = await new User(this.app).getConfigV2({ key: 'product_manager_tags', user_id: 'manager' });
|
|
1203
|
+
console.log(`initProductCustomizeTagConifg=>getData=>`, managerTags);
|
|
1204
|
+
if (managerTags && Array.isArray(managerTags.list)) {
|
|
1205
|
+
return managerTags;
|
|
1206
|
+
}
|
|
1207
|
+
console.log(
|
|
1208
|
+
`query_sql=>`,
|
|
1209
|
+
`SELECT 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
|
+
);
|
|
1213
|
+
const getData = await db.query(
|
|
1214
|
+
`
|
|
1215
|
+
SELECT 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 GROUP_CONCAT(DISTINCT JSON_UNQUOTE(JSON_EXTRACT(content, '$.product_tag.language')) SEPARATOR ',') AS unique_tags
|
|
1265
|
+
FROM \`${this.app}\`.t_manager_post
|
|
1266
|
+
WHERE JSON_UNQUOTE(JSON_EXTRACT(content, '$.type')) = 'product'
|
|
1267
|
+
`,
|
|
1268
|
+
[]
|
|
1269
|
+
);
|
|
1270
|
+
const unique_tags_string = getData[0]?.unique_tags ?? '';
|
|
1271
|
+
console.log(`JSON_STRING=>`, `[${unique_tags_string}]`);
|
|
1272
|
+
const unique_tags_array = JSON.parse(`[${unique_tags_string}]`);
|
|
1273
|
+
console.log(`JSON_DATA=>`, unique_tags_array);
|
|
1274
|
+
const unique_tags_flot = Array.isArray(unique_tags_array) ? unique_tags_array.flat() : [];
|
|
1275
|
+
const list: { [k in LanguageLocation]?: string[] } = {};
|
|
1276
|
+
|
|
1277
|
+
unique_tags_flot.map(item => {
|
|
1278
|
+
Language.locationList.map(lang => {
|
|
1279
|
+
list[lang] = [...(list[lang] ?? []), ...item[lang]];
|
|
1280
|
+
});
|
|
1281
|
+
});
|
|
1282
|
+
|
|
1283
|
+
Language.locationList.map(lang => {
|
|
1284
|
+
list[lang] = [...new Set(list[lang])];
|
|
1285
|
+
});
|
|
1286
|
+
|
|
1287
|
+
const data = { list };
|
|
1288
|
+
await new User(this.app).setConfig({
|
|
1289
|
+
key: 'product_general_tags',
|
|
1290
|
+
user_id: 'manager',
|
|
1291
|
+
value: data,
|
|
1292
|
+
});
|
|
1293
|
+
|
|
1294
|
+
return data;
|
|
1295
|
+
} catch (error) {
|
|
1296
|
+
throw exception.BadRequestError('BAD_REQUEST', 'Set product general tag conifg Error:' + error, null);
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
async setProductGeneralTagConifg(add_tags: { [k in LanguageLocation]: string[] }) {
|
|
1301
|
+
const tagConfig =
|
|
1302
|
+
(await new User(this.app).getConfigV2({ key: 'product_general_tags', user_id: 'manager' })) ??
|
|
1303
|
+
(await this.initProductGeneralTagConifg());
|
|
1304
|
+
|
|
1305
|
+
tagConfig.list ??= {};
|
|
1306
|
+
|
|
1307
|
+
Language.locationList.map(lang => {
|
|
1308
|
+
const originList = tagConfig.list[lang] ?? [];
|
|
1309
|
+
const updateList = add_tags[lang];
|
|
1310
|
+
tagConfig.list[lang] = [...new Set([...originList, ...updateList])];
|
|
1311
|
+
});
|
|
1312
|
+
|
|
1313
|
+
await new User(this.app).setConfig({
|
|
1314
|
+
key: 'product_general_tags',
|
|
1315
|
+
user_id: 'manager',
|
|
1316
|
+
value: tagConfig,
|
|
1317
|
+
});
|
|
1318
|
+
|
|
1319
|
+
return tagConfig;
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
async initOrderCustomizeTagConifg() {
|
|
1323
|
+
try {
|
|
1324
|
+
const managerTags = await new User(this.app).getConfigV2({ key: 'order_manager_tags', user_id: 'manager' });
|
|
1325
|
+
|
|
1326
|
+
if (managerTags && Array.isArray(managerTags.list)) {
|
|
1327
|
+
return managerTags;
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
const getData = await db.query(
|
|
1331
|
+
`
|
|
1332
|
+
SELECT GROUP_CONCAT(DISTINCT JSON_UNQUOTE(JSON_EXTRACT(orderData, '$.tags')) SEPARATOR ',') AS unique_tags
|
|
1333
|
+
FROM \`${this.app}\`.t_checkout
|
|
1334
|
+
WHERE JSON_UNQUOTE(JSON_EXTRACT(orderData, '$.tags')) IS NOT NULL
|
|
1335
|
+
`,
|
|
1336
|
+
[]
|
|
1337
|
+
);
|
|
1338
|
+
const unique_tags_string = getData[0]?.unique_tags ?? '';
|
|
1339
|
+
const unique_tags_array = JSON.parse(`[${unique_tags_string}]`);
|
|
1340
|
+
const unique_tags_flot = Array.isArray(unique_tags_array) ? unique_tags_array.flat() : [];
|
|
1341
|
+
const data = { list: [...new Set(unique_tags_flot)] };
|
|
1342
|
+
|
|
1343
|
+
await new User(this.app).setConfig({
|
|
1344
|
+
key: 'order_manager_tags',
|
|
1345
|
+
user_id: 'manager',
|
|
1346
|
+
value: data,
|
|
1347
|
+
});
|
|
1348
|
+
|
|
1349
|
+
return data;
|
|
1350
|
+
} catch (error) {
|
|
1351
|
+
throw exception.BadRequestError('BAD_REQUEST', 'Set order customize tag conifg Error:' + e, null);
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
async setOrderCustomizeTagConifg(add_tags: string[]) {
|
|
1356
|
+
const tagConfig = await new User(this.app).getConfigV2({ key: 'order_manager_tags', user_id: 'manager' });
|
|
1357
|
+
const tagList = tagConfig?.list ?? [];
|
|
1358
|
+
const data = { list: [...new Set([...tagList, ...add_tags])] };
|
|
1359
|
+
|
|
1360
|
+
await new User(this.app).setConfig({
|
|
1361
|
+
key: 'order_manager_tags',
|
|
1362
|
+
user_id: 'manager',
|
|
1363
|
+
value: data,
|
|
1364
|
+
});
|
|
1365
|
+
|
|
1366
|
+
return data;
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1171
1369
|
async getAllUseVoucher(userID: any): Promise<VoucherData[]> {
|
|
1172
1370
|
const now = Date.now();
|
|
1173
1371
|
|
|
@@ -1739,8 +1937,6 @@ export class Shopping {
|
|
|
1739
1937
|
);
|
|
1740
1938
|
}
|
|
1741
1939
|
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
1940
|
async repayOrder(orderID: string, return_url: string) {
|
|
1745
1941
|
const app = this.app;
|
|
1746
1942
|
|
|
@@ -1748,9 +1944,9 @@ export class Shopping {
|
|
|
1748
1944
|
try {
|
|
1749
1945
|
const result = await db.query(
|
|
1750
1946
|
`
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1947
|
+
SELECT *
|
|
1948
|
+
FROM \`${app}\`.t_checkout
|
|
1949
|
+
WHERE cart_token = ?`,
|
|
1754
1950
|
[orderID]
|
|
1755
1951
|
);
|
|
1756
1952
|
return result[0];
|
|
@@ -1792,7 +1988,7 @@ export class Shopping {
|
|
|
1792
1988
|
count: number;
|
|
1793
1989
|
voucher_id: string;
|
|
1794
1990
|
}[];
|
|
1795
|
-
language?:
|
|
1991
|
+
language?: LanguageLocation;
|
|
1796
1992
|
pos_info?: any; //POS結帳資訊;
|
|
1797
1993
|
invoice_select?: string;
|
|
1798
1994
|
pre_order?: boolean;
|
|
@@ -1843,8 +2039,11 @@ export class Shopping {
|
|
|
1843
2039
|
ReturnURL: '',
|
|
1844
2040
|
NotifyURL: '',
|
|
1845
2041
|
};
|
|
2042
|
+
//現在是new一個新的版本
|
|
2043
|
+
//todo 新增一個fake單號 直接做付款的動作 同時做訂單上的更新把這個付款單號記錄下來
|
|
1846
2044
|
const newOrderID = Date.now();
|
|
1847
2045
|
const carData: Cart = {
|
|
2046
|
+
orderID: `${newOrderID}`,
|
|
1848
2047
|
discount: orderData.discount ?? 0,
|
|
1849
2048
|
customer_info: orderData.customer_info || {},
|
|
1850
2049
|
lineItems: orderData.lineItems ?? [],
|
|
@@ -1855,7 +2054,6 @@ export class Shopping {
|
|
|
1855
2054
|
rebate: orderData.rebate ?? 0,
|
|
1856
2055
|
goodsWeight: 0,
|
|
1857
2056
|
use_rebate: orderData.use_rebate || 0,
|
|
1858
|
-
orderID: `${newOrderID}`,
|
|
1859
2057
|
shipment_support: shipment_setting.support as any,
|
|
1860
2058
|
shipment_info: shipment_setting.info as any,
|
|
1861
2059
|
shipment_selector: [
|
|
@@ -1890,10 +2088,17 @@ export class Shopping {
|
|
|
1890
2088
|
fbp: sqlData.fbp as string,
|
|
1891
2089
|
editRecord: [],
|
|
1892
2090
|
};
|
|
1893
|
-
|
|
1894
|
-
|
|
2091
|
+
await OrderEvent.insertOrder({
|
|
2092
|
+
cartData: orderData,
|
|
2093
|
+
status: 0,
|
|
2094
|
+
app: this.app,
|
|
2095
|
+
});
|
|
2096
|
+
const result = await new PaymentTransaction(this.app, orderData.customer_info.payment_select).processPayment(
|
|
2097
|
+
carData,
|
|
2098
|
+
return_url
|
|
2099
|
+
);
|
|
1895
2100
|
|
|
1896
|
-
return result
|
|
2101
|
+
return result;
|
|
1897
2102
|
}
|
|
1898
2103
|
|
|
1899
2104
|
// return result
|
|
@@ -1967,7 +2172,7 @@ export class Shopping {
|
|
|
1967
2172
|
if (query.archived === 'true') {
|
|
1968
2173
|
querySql.push(`(archived="${query.archived}")`);
|
|
1969
2174
|
} else if (query.archived === 'false') {
|
|
1970
|
-
querySql.push(`((archived
|
|
2175
|
+
querySql.push(`((archived IS NULL) or (archived!='true'))`);
|
|
1971
2176
|
}
|
|
1972
2177
|
//退貨貨款狀態
|
|
1973
2178
|
query.status && querySql.push(`status IN (${query.status})`);
|
|
@@ -2188,6 +2393,57 @@ export class Shopping {
|
|
|
2188
2393
|
|
|
2189
2394
|
async splitOrder(obj: { orderData: Cart; splitOrderArray: OrderDetail[] }) {
|
|
2190
2395
|
try {
|
|
2396
|
+
async function processCheckoutsStaggered(
|
|
2397
|
+
splitOrderArray: any[],
|
|
2398
|
+
orderData: any,
|
|
2399
|
+
context: any
|
|
2400
|
+
): Promise<boolean | { result: string; reason: any }> {
|
|
2401
|
+
const promises = splitOrderArray.map((order, index) => {
|
|
2402
|
+
// 為每個操作返回一個新的 Promise
|
|
2403
|
+
return new Promise<void>((resolve, reject) => {
|
|
2404
|
+
// 可以定義更精確的 resolve 型別,這裡用 void 示意
|
|
2405
|
+
const delay = 1000 * index; // 計算延遲時間
|
|
2406
|
+
|
|
2407
|
+
setTimeout(() => {
|
|
2408
|
+
// 在 setTimeout 回呼中執行非同步操作
|
|
2409
|
+
const payload = {
|
|
2410
|
+
code_array: [],
|
|
2411
|
+
order_id: orderData?.splitOrders?.[index] ?? '',
|
|
2412
|
+
line_items: order.lineItems as any,
|
|
2413
|
+
customer_info: order.customer_info,
|
|
2414
|
+
return_url: '',
|
|
2415
|
+
user_info: order.user_info,
|
|
2416
|
+
discount: order.discount,
|
|
2417
|
+
voucher: order.voucher,
|
|
2418
|
+
total: order.total,
|
|
2419
|
+
pay_status: Number(order.pay_status),
|
|
2420
|
+
};
|
|
2421
|
+
|
|
2422
|
+
// 假設 context.toCheckout 本身返回一個 Promise
|
|
2423
|
+
context
|
|
2424
|
+
.toCheckout(payload, 'split')
|
|
2425
|
+
.then(() => {
|
|
2426
|
+
resolve(); // 當 toCheckout 成功時,resolve 外層的 Promise
|
|
2427
|
+
})
|
|
2428
|
+
.catch((error: any) => {
|
|
2429
|
+
reject(error); // 當 toCheckout 失敗時,reject 外層的 Promise
|
|
2430
|
+
});
|
|
2431
|
+
}, delay); // 使用計算出的延遲
|
|
2432
|
+
});
|
|
2433
|
+
}); // map 結束
|
|
2434
|
+
|
|
2435
|
+
try {
|
|
2436
|
+
await Promise.all(promises);
|
|
2437
|
+
return true; // 全部成功
|
|
2438
|
+
} catch (e) {
|
|
2439
|
+
console.error('處理拆分訂單結帳時至少發生一個錯誤 (從 Promise.all 捕獲):', e);
|
|
2440
|
+
return {
|
|
2441
|
+
result: 'failure',
|
|
2442
|
+
reason: e, // 返回捕獲到的錯誤
|
|
2443
|
+
};
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
|
|
2191
2447
|
const currentTime = new Date().toISOString();
|
|
2192
2448
|
|
|
2193
2449
|
//給定訂單編號 產生 編號A 編號B... 依此類推
|
|
@@ -2204,7 +2460,7 @@ export class Shopping {
|
|
|
2204
2460
|
return orderIdArray;
|
|
2205
2461
|
}
|
|
2206
2462
|
|
|
2207
|
-
//整理原本訂單的總價
|
|
2463
|
+
//整理原本訂單的總價 優惠卷的資訊 方便原本的訂單更新
|
|
2208
2464
|
function refreshOrder(orderData: Cart, splitOrderArray: OrderDetail[]) {
|
|
2209
2465
|
const { newTotal, newDiscount } = splitOrderArray.reduce(
|
|
2210
2466
|
(acc, order) => {
|
|
@@ -2231,37 +2487,7 @@ export class Shopping {
|
|
|
2231
2487
|
cart_token: orderData.orderID,
|
|
2232
2488
|
orderData,
|
|
2233
2489
|
});
|
|
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;
|
|
2490
|
+
return await processCheckoutsStaggered(splitOrderArray, orderData, this);
|
|
2265
2491
|
} catch (e) {
|
|
2266
2492
|
throw exception.BadRequestError('BAD_REQUEST', 'splitOrder Error:' + e, null);
|
|
2267
2493
|
}
|
|
@@ -2737,7 +2963,6 @@ export class Shopping {
|
|
|
2737
2963
|
// 恢復取消訂單的庫存
|
|
2738
2964
|
orderData.lineItems = resetLineItems(orderData.lineItems);
|
|
2739
2965
|
origin.orderData.lineItems = resetLineItems(origin.orderData.lineItems);
|
|
2740
|
-
|
|
2741
2966
|
// 釋放優惠券
|
|
2742
2967
|
await this.releaseVoucherHistory(orderData.orderID, orderData.orderStatus === '-1' ? 0 : 1);
|
|
2743
2968
|
|
|
@@ -2783,7 +3008,14 @@ export class Shopping {
|
|
|
2783
3008
|
|
|
2784
3009
|
// 當訂單出貨狀態變更,觸發通知事件
|
|
2785
3010
|
const updateProgress = update.orderData.progress;
|
|
2786
|
-
|
|
3011
|
+
|
|
3012
|
+
if (
|
|
3013
|
+
updateProgress === 'wait' &&
|
|
3014
|
+
update.orderData.user_info.shipment_number &&
|
|
3015
|
+
update.orderData.user_info.shipment_number !== origin.orderData.user_info.shipment_number
|
|
3016
|
+
) {
|
|
3017
|
+
await this.sendNotifications(orderData, 'in_stock');
|
|
3018
|
+
} else if (prevProgress !== updateProgress) {
|
|
2787
3019
|
if (updateProgress === 'shipping') {
|
|
2788
3020
|
await this.sendNotifications(orderData, 'shipment');
|
|
2789
3021
|
} else if (updateProgress === 'arrived') {
|
|
@@ -2819,6 +3051,11 @@ export class Shopping {
|
|
|
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,8 +3807,8 @@ 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(
|
|
@@ -3498,6 +3818,7 @@ export class Shopping {
|
|
|
3498
3818
|
[]
|
|
3499
3819
|
)
|
|
3500
3820
|
)[0];
|
|
3821
|
+
timer.checkPoint('get response_data (has query.id)');
|
|
3501
3822
|
resolve({
|
|
3502
3823
|
data: data,
|
|
3503
3824
|
result: !!data,
|
|
@@ -3509,21 +3830,20 @@ export class Shopping {
|
|
|
3509
3830
|
`,
|
|
3510
3831
|
[]
|
|
3511
3832
|
);
|
|
3512
|
-
timer.checkPoint('
|
|
3513
|
-
console.log(sql);
|
|
3833
|
+
timer.checkPoint('get response_data (not query.id)');
|
|
3514
3834
|
resolve({
|
|
3515
3835
|
data: data,
|
|
3516
3836
|
total: (
|
|
3517
3837
|
await db.query(
|
|
3518
3838
|
`SELECT count(1)
|
|
3519
|
-
|
|
3520
|
-
`,
|
|
3839
|
+
FROM (${sql}) as subqyery`,
|
|
3521
3840
|
[]
|
|
3522
3841
|
)
|
|
3523
3842
|
)[0]['count(1)'],
|
|
3524
3843
|
});
|
|
3525
3844
|
}
|
|
3526
3845
|
});
|
|
3846
|
+
|
|
3527
3847
|
const obMap = Array.isArray(response_data.data) ? response_data.data : [response_data.data];
|
|
3528
3848
|
const keyData = (
|
|
3529
3849
|
await Private_config.getConfig({
|
|
@@ -3531,6 +3851,7 @@ export class Shopping {
|
|
|
3531
3851
|
key: 'glitter_finance',
|
|
3532
3852
|
})
|
|
3533
3853
|
)[0].value;
|
|
3854
|
+
|
|
3534
3855
|
await Promise.all(
|
|
3535
3856
|
obMap
|
|
3536
3857
|
.map(async (order: any) => {
|
|
@@ -3543,9 +3864,7 @@ export class Shopping {
|
|
|
3543
3864
|
order.orderData.cash_flow = (
|
|
3544
3865
|
await new PayNow(this.app, keyData['paynow']).confirmAndCaptureOrder(order.orderData.paynow_id)
|
|
3545
3866
|
).result;
|
|
3546
|
-
}catch (e) {
|
|
3547
|
-
|
|
3548
|
-
}
|
|
3867
|
+
} catch (e) {}
|
|
3549
3868
|
}
|
|
3550
3869
|
if (order.orderData.user_info.shipment_refer === 'paynow') {
|
|
3551
3870
|
const pay_now = new PayNowLogistics(this.app);
|
|
@@ -3601,7 +3920,7 @@ export class Shopping {
|
|
|
3601
3920
|
page: 0,
|
|
3602
3921
|
limit: 1,
|
|
3603
3922
|
search: order.cart_token,
|
|
3604
|
-
searchType: order.orderData
|
|
3923
|
+
searchType: order.orderData?.order_number,
|
|
3605
3924
|
})
|
|
3606
3925
|
).data[0];
|
|
3607
3926
|
order.invoice_number = invoice && invoice.invoice_no;
|
|
@@ -3614,7 +3933,9 @@ export class Shopping {
|
|
|
3614
3933
|
})
|
|
3615
3934
|
)
|
|
3616
3935
|
);
|
|
3936
|
+
|
|
3617
3937
|
timer.checkPoint('finish-query-all');
|
|
3938
|
+
|
|
3618
3939
|
return response_data;
|
|
3619
3940
|
} catch (e) {
|
|
3620
3941
|
throw exception.BadRequestError('BAD_REQUEST', 'getCheckOut Error:' + e, null);
|
|
@@ -3967,31 +4288,40 @@ export class Shopping {
|
|
|
3967
4288
|
} else if (Object.keys(variant.stockList).length === 0) {
|
|
3968
4289
|
variant.stockList[storeConfig.list[0].id] = { count: variant.stock };
|
|
3969
4290
|
}
|
|
4291
|
+
const insertObj:any = {
|
|
4292
|
+
content: JSON.stringify(variant),
|
|
4293
|
+
product_id: content.id,
|
|
4294
|
+
};
|
|
4295
|
+
const originalVariant = originVariants.find(
|
|
4296
|
+
(item: any) => JSON.parse(item.spec).join(',') === variant.spec.join(',')
|
|
4297
|
+
);
|
|
4298
|
+
|
|
4299
|
+
//如果有找到原先的variant不要替換掉ID
|
|
4300
|
+
if (originalVariant) {
|
|
4301
|
+
insertObj.id = originalVariant.id;
|
|
4302
|
+
sourceMap[originalVariant.id] = originalVariant.id;
|
|
4303
|
+
}
|
|
3970
4304
|
|
|
3971
4305
|
const insertData = await db.query(
|
|
3972
4306
|
`INSERT INTO \`${this.app}\`.t_variants
|
|
3973
4307
|
SET ?
|
|
3974
4308
|
`,
|
|
3975
|
-
[
|
|
3976
|
-
{
|
|
3977
|
-
content: JSON.stringify(variant),
|
|
3978
|
-
product_id: content.id,
|
|
3979
|
-
},
|
|
3980
|
-
]
|
|
4309
|
+
[insertObj]
|
|
3981
4310
|
);
|
|
3982
4311
|
|
|
3983
|
-
const originalVariant = originVariants.find(
|
|
3984
|
-
(item: any) => JSON.parse(item.spec).join(',') === variant.spec.join(',')
|
|
3985
|
-
);
|
|
3986
|
-
|
|
3987
|
-
if (originalVariant) {
|
|
3988
|
-
sourceMap[originalVariant.id] = insertData.insertId;
|
|
3989
|
-
}
|
|
3990
4312
|
|
|
3991
4313
|
return insertData;
|
|
3992
4314
|
});
|
|
3993
4315
|
|
|
3994
|
-
|
|
4316
|
+
const chunk = 10;
|
|
4317
|
+
const chunkLength = Math.ceil(insertPromises.length / chunk);
|
|
4318
|
+
|
|
4319
|
+
for (let i = 0; i < chunkLength; i++) {
|
|
4320
|
+
const promisesArray = insertPromises.slice(i * chunk, (i + 1) * chunk);
|
|
4321
|
+
setTimeout(async () => {
|
|
4322
|
+
await Promise.all(promisesArray);
|
|
4323
|
+
}, 200);
|
|
4324
|
+
}
|
|
3995
4325
|
|
|
3996
4326
|
const exhibitionConfig = await _user.getConfigV2({ key: 'exhibition_manager', user_id: 'manager' });
|
|
3997
4327
|
exhibitionConfig.list = exhibitionConfig.list ?? [];
|
|
@@ -4679,6 +5009,7 @@ export class Shopping {
|
|
|
4679
5009
|
delete product['content'];
|
|
4680
5010
|
delete product['preview_image'];
|
|
4681
5011
|
const og_content = og_data['content'];
|
|
5012
|
+
|
|
4682
5013
|
if (og_content.language_data && og_content.language_data[store_info.language_setting.def]) {
|
|
4683
5014
|
og_content.language_data[store_info.language_setting.def].seo = product.seo;
|
|
4684
5015
|
og_content.language_data[store_info.language_setting.def].title = product.title;
|
|
@@ -4692,10 +5023,10 @@ export class Shopping {
|
|
|
4692
5023
|
product.preview_image = og_data['content'].preview_image || [];
|
|
4693
5024
|
productArray[index] = product;
|
|
4694
5025
|
} else {
|
|
4695
|
-
console.error('Product id not exist:', product);
|
|
5026
|
+
console.error('Product id not exist:', product.title);
|
|
4696
5027
|
}
|
|
4697
5028
|
} else {
|
|
4698
|
-
console.error('Product has not id:', product);
|
|
5029
|
+
console.error('Product has not id:', product.title);
|
|
4699
5030
|
}
|
|
4700
5031
|
resolve(true);
|
|
4701
5032
|
});
|
|
@@ -4729,8 +5060,9 @@ export class Shopping {
|
|
|
4729
5060
|
|
|
4730
5061
|
if (productArray.length) {
|
|
4731
5062
|
const data = await db.query(
|
|
4732
|
-
`
|
|
4733
|
-
INTO \`${this.app}\`.\`t_manager_post\` (id,userID,content) values
|
|
5063
|
+
`REPLACE
|
|
5064
|
+
INTO \`${this.app}\`.\`t_manager_post\` (id,userID,content) values ?
|
|
5065
|
+
`,
|
|
4734
5066
|
[
|
|
4735
5067
|
productArray.map((product: any) => {
|
|
4736
5068
|
if (!product.id) {
|
|
@@ -4759,37 +5091,57 @@ export class Shopping {
|
|
|
4759
5091
|
product.id = product.id || insertIDStart++;
|
|
4760
5092
|
return new Shopping(this.app, this.token).postVariantsAndPriceValue(product);
|
|
4761
5093
|
});
|
|
4762
|
-
await Promise.all(promises);
|
|
4763
|
-
}
|
|
4764
5094
|
|
|
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
|
-
}
|
|
5095
|
+
const chunk = 10;
|
|
5096
|
+
const chunkLength = Math.ceil(promises.length / chunk);
|
|
5097
|
+
|
|
5098
|
+
for (let i = 0; i < chunkLength; i++) {
|
|
5099
|
+
const promisesArray = promises.slice(i * chunk, (i + 1) * chunk);
|
|
5100
|
+
setTimeout(async () => {
|
|
5101
|
+
await Promise.all(promisesArray);
|
|
5102
|
+
}, 200);
|
|
4783
5103
|
}
|
|
5104
|
+
}
|
|
4784
5105
|
|
|
5106
|
+
async putProduct(content: any) {
|
|
4785
5107
|
try {
|
|
4786
5108
|
content.type = 'product';
|
|
4787
5109
|
|
|
5110
|
+
// 檢查 seo domain 是否重複
|
|
5111
|
+
if (content.language_data) {
|
|
5112
|
+
const language = await App.getSupportLanguage(this.app);
|
|
5113
|
+
for (const b of language) {
|
|
5114
|
+
const find_conflict = await db.query(
|
|
5115
|
+
`SELECT count(1)
|
|
5116
|
+
FROM \`${this.app}\`.t_manager_post
|
|
5117
|
+
WHERE content ->>'$.language_data."${b}".seo.domain'='${decodeURIComponent(content.language_data[b].seo.domain)}'
|
|
5118
|
+
AND id != ${content.id}`,
|
|
5119
|
+
[]
|
|
5120
|
+
);
|
|
5121
|
+
if (find_conflict[0]['count(1)'] > 0) {
|
|
5122
|
+
throw exception.BadRequestError('BAD_REQUEST', 'DOMAIN ALREADY EXISTS:', {
|
|
5123
|
+
message: '網域已被使用',
|
|
5124
|
+
code: '733',
|
|
5125
|
+
});
|
|
5126
|
+
}
|
|
5127
|
+
}
|
|
5128
|
+
}
|
|
5129
|
+
|
|
5130
|
+
// 檢查 Variant 資料屬性
|
|
4788
5131
|
this.checkVariantDataType(content.variants);
|
|
4789
|
-
|
|
4790
|
-
|
|
5132
|
+
|
|
5133
|
+
// 重新設置管理員標籤
|
|
5134
|
+
await Promise.all([
|
|
5135
|
+
this.setProductCustomizeTagConifg(content.product_customize_tag ?? []),
|
|
5136
|
+
this.setProductGeneralTagConifg(content.product_tag?.language ?? []),
|
|
5137
|
+
]);
|
|
5138
|
+
|
|
5139
|
+
// 更新商品
|
|
5140
|
+
await db.query(
|
|
5141
|
+
`UPDATE \`${this.app}\`.\`t_manager_post\`
|
|
4791
5142
|
SET ?
|
|
4792
|
-
|
|
5143
|
+
WHERE id = ?
|
|
5144
|
+
`,
|
|
4793
5145
|
[
|
|
4794
5146
|
{
|
|
4795
5147
|
content: JSON.stringify(content),
|
|
@@ -4797,7 +5149,11 @@ export class Shopping {
|
|
|
4797
5149
|
content.id,
|
|
4798
5150
|
]
|
|
4799
5151
|
);
|
|
5152
|
+
|
|
5153
|
+
// 更新商品 Variant
|
|
4800
5154
|
await new Shopping(this.app, this.token).postVariantsAndPriceValue(content);
|
|
5155
|
+
|
|
5156
|
+
// 同步更新蝦皮
|
|
4801
5157
|
if (content.shopee_id) {
|
|
4802
5158
|
await new Shopee(this.app, this.token).asyncStockToShopee({
|
|
4803
5159
|
product: {
|
|
@@ -5000,9 +5356,11 @@ export class Shopping {
|
|
|
5000
5356
|
query.id && querySql.push(`(v.id = ${query.id})`);
|
|
5001
5357
|
if (query.id_list) {
|
|
5002
5358
|
if (query.id_list?.includes('-')) {
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5359
|
+
querySql.push(
|
|
5360
|
+
`(v.product_id in (${query.id_list.split(',').map(dd => {
|
|
5361
|
+
return dd.split('-')[0];
|
|
5362
|
+
})}))`
|
|
5363
|
+
);
|
|
5006
5364
|
} else {
|
|
5007
5365
|
querySql.push(`(v.id in (${query.id_list}))`);
|
|
5008
5366
|
}
|
|
@@ -5102,11 +5460,11 @@ export class Shopping {
|
|
|
5102
5460
|
if (query.id_list) {
|
|
5103
5461
|
//過濾出需要的商品規格
|
|
5104
5462
|
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
|
-
})
|
|
5463
|
+
data.data = data.data.filter((dd: any) => {
|
|
5464
|
+
return query.id_list?.split(',').find(d1 => {
|
|
5465
|
+
return d1 === [dd.product_id, ...dd.variant_content.spec].join('-');
|
|
5466
|
+
});
|
|
5467
|
+
});
|
|
5110
5468
|
}
|
|
5111
5469
|
}
|
|
5112
5470
|
const shopee_data_list: { id: string; data: any }[] = [];
|
|
@@ -5208,8 +5566,8 @@ export class Shopping {
|
|
|
5208
5566
|
let variants = (
|
|
5209
5567
|
await db.query(
|
|
5210
5568
|
`SELECT *
|
|
5211
|
-
|
|
5212
|
-
|
|
5569
|
+
FROM \`${this.app}\`.t_variants
|
|
5570
|
+
WHERE product_id = ?`,
|
|
5213
5571
|
[data.product_id]
|
|
5214
5572
|
)
|
|
5215
5573
|
).map((dd: any) => {
|