@pisell/pisellos 2.3.67 → 2.3.68
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/dist/core/index.d.ts +0 -7
- package/dist/core/index.js +65 -109
- package/dist/model/strategy/adapter/walletPass/evaluator.js +0 -1
- package/dist/model/strategy/adapter/walletPass/utils.js +0 -2
- package/dist/modules/BaseModule.d.ts +1 -0
- package/dist/modules/BaseModule.js +24 -28
- package/dist/modules/Customer/index.d.ts +4 -0
- package/dist/modules/Customer/index.js +91 -59
- package/dist/modules/Customer/types.d.ts +2 -0
- package/dist/modules/Order/index.d.ts +22 -2
- package/dist/modules/Order/index.js +313 -142
- package/dist/modules/Order/types.d.ts +13 -1
- package/dist/modules/Order/utils/orderCollectionIdentity.d.ts +15 -0
- package/dist/modules/Order/utils/orderCollectionIdentity.js +75 -0
- package/dist/modules/Order/utils.js +0 -1
- package/dist/modules/Payment/index.d.ts +4 -0
- package/dist/modules/Payment/index.js +14 -4
- package/dist/modules/Payment/walletpass.js +52 -18
- package/dist/modules/Quotation/index.d.ts +0 -6
- package/dist/modules/Quotation/index.js +19 -75
- package/dist/modules/Rules/index.js +46 -31
- package/dist/plugins/request.d.ts +0 -1
- package/dist/server/index.d.ts +2 -8
- package/dist/server/index.js +143 -212
- package/dist/server/modules/floor-plan/index.d.ts +0 -4
- package/dist/server/modules/floor-plan/index.js +98 -240
- package/dist/server/modules/menu/index.js +23 -48
- package/dist/server/modules/order/index.d.ts +8 -17
- package/dist/server/modules/order/index.js +453 -506
- package/dist/server/modules/products/index.d.ts +2 -8
- package/dist/server/modules/products/index.js +75 -167
- package/dist/server/modules/resource/index.js +13 -21
- package/dist/server/utils/small-ticket.js +2 -1
- package/dist/solution/BaseSales/index.d.ts +3 -1
- package/dist/solution/BaseSales/index.js +99 -82
- package/dist/solution/BaseSales/utils.js +31 -20
- package/dist/solution/BookingTicket/index.d.ts +6 -2
- package/dist/solution/BookingTicket/index.js +123 -75
- package/dist/solution/ScanOrder/utils.js +31 -20
- package/dist/solution/UnifiedBookingSales/index.d.ts +25 -0
- package/dist/solution/UnifiedBookingSales/index.js +640 -321
- package/dist/solution/UnifiedBookingSales/types.d.ts +7 -0
- package/lib/core/index.d.ts +0 -7
- package/lib/core/index.js +2 -20
- package/lib/model/strategy/adapter/walletPass/evaluator.js +0 -1
- package/lib/model/strategy/adapter/walletPass/utils.js +0 -1
- package/lib/modules/BaseModule.d.ts +1 -0
- package/lib/modules/BaseModule.js +24 -37
- package/lib/modules/Customer/index.d.ts +4 -0
- package/lib/modules/Customer/index.js +11 -0
- package/lib/modules/Customer/types.d.ts +2 -0
- package/lib/modules/Order/index.d.ts +22 -2
- package/lib/modules/Order/index.js +212 -54
- package/lib/modules/Order/types.d.ts +13 -1
- package/lib/modules/Order/utils/orderCollectionIdentity.d.ts +15 -0
- package/lib/modules/Order/utils/orderCollectionIdentity.js +70 -0
- package/lib/modules/Order/utils.js +0 -1
- package/lib/modules/Payment/index.d.ts +4 -0
- package/lib/modules/Payment/index.js +7 -0
- package/lib/modules/Payment/walletpass.js +27 -2
- package/lib/modules/Quotation/index.d.ts +0 -6
- package/lib/modules/Quotation/index.js +5 -49
- package/lib/modules/Rules/index.js +17 -1
- package/lib/plugins/request.d.ts +0 -1
- package/lib/server/index.d.ts +2 -8
- package/lib/server/index.js +20 -58
- package/lib/server/modules/floor-plan/index.d.ts +0 -4
- package/lib/server/modules/floor-plan/index.js +6 -54
- package/lib/server/modules/menu/index.js +5 -31
- package/lib/server/modules/order/index.d.ts +8 -17
- package/lib/server/modules/order/index.js +106 -199
- package/lib/server/modules/products/index.d.ts +2 -8
- package/lib/server/modules/products/index.js +24 -97
- package/lib/server/modules/resource/index.js +2 -7
- package/lib/server/utils/small-ticket.js +1 -1
- package/lib/solution/BaseSales/index.d.ts +3 -1
- package/lib/solution/BaseSales/index.js +29 -16
- package/lib/solution/BaseSales/utils.js +29 -18
- package/lib/solution/BookingTicket/index.d.ts +6 -2
- package/lib/solution/BookingTicket/index.js +53 -14
- package/lib/solution/ScanOrder/utils.js +29 -18
- package/lib/solution/UnifiedBookingSales/index.d.ts +25 -0
- package/lib/solution/UnifiedBookingSales/index.js +188 -0
- package/lib/solution/UnifiedBookingSales/types.d.ts +7 -0
- package/package.json +1 -1
|
@@ -192,7 +192,7 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
192
192
|
* Server 层负责传入完整 schedule 模块,Products 只负责把报价单计算结果转成价格响应形状。
|
|
193
193
|
*/
|
|
194
194
|
async setupQuotationPriceBridge(params) {
|
|
195
|
-
var _a
|
|
195
|
+
var _a;
|
|
196
196
|
if (!this.core) {
|
|
197
197
|
this.logWarning("setupQuotationPriceBridge: core 尚未初始化");
|
|
198
198
|
return;
|
|
@@ -211,13 +211,13 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
211
211
|
this.quotationScheduleCacheSource = params.scheduleModule;
|
|
212
212
|
}
|
|
213
213
|
this.quotationPriceBridge.setScheduleResolver((id) => {
|
|
214
|
-
var _a2,
|
|
214
|
+
var _a2, _b, _c, _d, _e, _f;
|
|
215
215
|
const scheduleId = String(id);
|
|
216
216
|
if (this.quotationScheduleCache.has(scheduleId)) {
|
|
217
217
|
return this.quotationScheduleCache.get(scheduleId);
|
|
218
218
|
}
|
|
219
219
|
if (!this.quotationScheduleCacheLoaded) {
|
|
220
|
-
const scheduleList = ((
|
|
220
|
+
const scheduleList = ((_b = (_a2 = params.scheduleModule).getScheduleList) == null ? void 0 : _b.call(_a2)) || [];
|
|
221
221
|
for (const schedule of scheduleList) {
|
|
222
222
|
this.quotationScheduleCache.set(String(schedule.id), schedule);
|
|
223
223
|
}
|
|
@@ -226,21 +226,12 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
226
226
|
if (this.quotationScheduleCache.has(scheduleId)) {
|
|
227
227
|
return this.quotationScheduleCache.get(scheduleId);
|
|
228
228
|
}
|
|
229
|
-
const schedules = ((_d = (
|
|
229
|
+
const schedules = ((_d = (_c = params.scheduleModule).getScheduleListByIds) == null ? void 0 : _d.call(_c, [id])) || ((_f = (_e = params.scheduleModule).getScheduleByIds) == null ? void 0 : _f.call(_e, [id])) || [];
|
|
230
230
|
if (schedules[0])
|
|
231
231
|
this.quotationScheduleCache.set(scheduleId, schedules[0]);
|
|
232
232
|
return schedules[0];
|
|
233
233
|
});
|
|
234
234
|
}
|
|
235
|
-
if (params.onQuotationUpdated) {
|
|
236
|
-
this.quotationBridgeUpdatedCallback = params.onQuotationUpdated;
|
|
237
|
-
}
|
|
238
|
-
(_c = (_b = this.quotationPriceBridge).setQuotationListUpdatedListener) == null ? void 0 : _c.call(_b, () => {
|
|
239
|
-
var _a2;
|
|
240
|
-
this.quotationBridgeLoadedKey = this.getQuotationBridgeScopeKey();
|
|
241
|
-
this.clearPriceCache();
|
|
242
|
-
(_a2 = this.quotationBridgeUpdatedCallback) == null ? void 0 : _a2.call(this);
|
|
243
|
-
});
|
|
244
235
|
await this.refreshQuotationPriceBridge({ customer_id: params.customer_id });
|
|
245
236
|
}
|
|
246
237
|
/**
|
|
@@ -807,20 +798,17 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
807
798
|
*/
|
|
808
799
|
clearPriceCache() {
|
|
809
800
|
this.productsPriceCache.clear();
|
|
810
|
-
this.quotationScheduleCache.clear();
|
|
811
|
-
this.quotationScheduleCacheLoaded = false;
|
|
812
801
|
console.log("[ProductsModule] 🗑️ 商品价格缓存已清空");
|
|
813
802
|
}
|
|
814
803
|
/**
|
|
815
804
|
* 通过 ProductDataSource SSE 加载完整商品列表
|
|
816
805
|
*/
|
|
817
|
-
async loadProductsByServer(
|
|
806
|
+
async loadProductsByServer() {
|
|
818
807
|
if (!this.productDataSource) {
|
|
819
808
|
this.logWarning("loadProductsByServer: ProductDataSource 不可用");
|
|
820
809
|
return [];
|
|
821
810
|
}
|
|
822
|
-
|
|
823
|
-
this.logInfo("开始通过 DataSource SSE 加载商品列表", { trigger });
|
|
811
|
+
this.logInfo("开始通过 DataSource SSE 加载商品列表");
|
|
824
812
|
const t0 = performance.now();
|
|
825
813
|
try {
|
|
826
814
|
const tSSE = performance.now();
|
|
@@ -828,7 +816,6 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
828
816
|
const list = productList || [];
|
|
829
817
|
(0, import_product.perfMark)("loadProductsByServer.SSE", performance.now() - tSSE, { count: list.length });
|
|
830
818
|
this.logInfo("通过 DataSource SSE 加载商品列表成功", {
|
|
831
|
-
trigger,
|
|
832
819
|
productCount: list.length,
|
|
833
820
|
duration: `${Math.round(performance.now() - t0)}ms`
|
|
834
821
|
});
|
|
@@ -842,7 +829,6 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
842
829
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
843
830
|
console.error("[Products] 加载商品数据失败:", error);
|
|
844
831
|
this.logError("通过 DataSource SSE 加载商品列表失败", {
|
|
845
|
-
trigger,
|
|
846
832
|
duration: `${duration}ms`,
|
|
847
833
|
error: errorMessage
|
|
848
834
|
});
|
|
@@ -1033,9 +1019,7 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
1033
1019
|
async refreshProducts() {
|
|
1034
1020
|
const tTotal = performance.now();
|
|
1035
1021
|
this.logInfo("refreshProducts 开始");
|
|
1036
|
-
const products = await this.loadProductsByServer(
|
|
1037
|
-
trigger: "product_sync"
|
|
1038
|
-
});
|
|
1022
|
+
const products = await this.loadProductsByServer();
|
|
1039
1023
|
if (products && products.length > 0) {
|
|
1040
1024
|
this.store.list = products;
|
|
1041
1025
|
this.syncProductsMap();
|
|
@@ -1080,23 +1064,18 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
1080
1064
|
this.logWarning("loadProductsFromIndexDB: dbManager 不可用");
|
|
1081
1065
|
return [];
|
|
1082
1066
|
}
|
|
1083
|
-
const startedAt = performance.now();
|
|
1084
1067
|
try {
|
|
1068
|
+
const t0 = performance.now();
|
|
1085
1069
|
const products = await this.dbManager.getAll(INDEXDB_STORE_NAME);
|
|
1086
|
-
|
|
1087
|
-
(0, import_product.perfMark)("loadProductsFromIndexDB", durationMs, { count: (products == null ? void 0 : products.length) ?? 0 });
|
|
1070
|
+
(0, import_product.perfMark)("loadProductsFromIndexDB", performance.now() - t0, { count: (products == null ? void 0 : products.length) ?? 0 });
|
|
1088
1071
|
this.logInfo("从 IndexDB 加载商品数据", {
|
|
1089
|
-
productCount: (products == null ? void 0 : products.length) ?? 0
|
|
1090
|
-
durationMs
|
|
1072
|
+
productCount: (products == null ? void 0 : products.length) ?? 0
|
|
1091
1073
|
});
|
|
1092
1074
|
return products || [];
|
|
1093
1075
|
} catch (error) {
|
|
1094
1076
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1095
1077
|
console.error("[Products] 从 IndexDB 读取数据失败:", error);
|
|
1096
|
-
this.logError("从 IndexDB 读取数据失败", {
|
|
1097
|
-
durationMs: +(performance.now() - startedAt).toFixed(2),
|
|
1098
|
-
error: errorMessage
|
|
1099
|
-
});
|
|
1078
|
+
this.logError("从 IndexDB 读取数据失败", { error: errorMessage });
|
|
1100
1079
|
return [];
|
|
1101
1080
|
}
|
|
1102
1081
|
}
|
|
@@ -1124,54 +1103,22 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
1124
1103
|
this.logWarning("replaceProductsSnapshotInIndexDB: dbManager 不可用");
|
|
1125
1104
|
return;
|
|
1126
1105
|
}
|
|
1127
|
-
const enqueuedAt = performance.now();
|
|
1128
|
-
let queueWaitMs = 0;
|
|
1129
|
-
let clearDurationMs = 0;
|
|
1130
|
-
let writeDurationMs = 0;
|
|
1131
1106
|
try {
|
|
1132
1107
|
await this.runInProductIndexDBSaveQueue(async () => {
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
this.
|
|
1136
|
-
source,
|
|
1137
|
-
productCount: products.length,
|
|
1138
|
-
queueWaitMs
|
|
1139
|
-
});
|
|
1140
|
-
const clearStartedAt = performance.now();
|
|
1141
|
-
try {
|
|
1142
|
-
await this.dbManager.clear(INDEXDB_STORE_NAME);
|
|
1143
|
-
} finally {
|
|
1144
|
-
clearDurationMs = +(performance.now() - clearStartedAt).toFixed(2);
|
|
1145
|
-
}
|
|
1108
|
+
this.logInfo("replaceProductsSnapshotInIndexDB 开始", { source, productCount: products.length });
|
|
1109
|
+
const t0 = performance.now();
|
|
1110
|
+
await this.dbManager.clear(INDEXDB_STORE_NAME);
|
|
1146
1111
|
if (products.length > 0) {
|
|
1147
|
-
|
|
1148
|
-
try {
|
|
1149
|
-
await this.dbManager.bulkUpdate(INDEXDB_STORE_NAME, products);
|
|
1150
|
-
} finally {
|
|
1151
|
-
writeDurationMs = +(performance.now() - writeStartedAt).toFixed(2);
|
|
1152
|
-
}
|
|
1112
|
+
await this.dbManager.bulkUpdate(INDEXDB_STORE_NAME, products);
|
|
1153
1113
|
}
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
this.logInfo("replaceProductsSnapshotInIndexDB 完成", {
|
|
1157
|
-
source,
|
|
1158
|
-
productCount: products.length,
|
|
1159
|
-
queueWaitMs,
|
|
1160
|
-
clearDurationMs,
|
|
1161
|
-
writeDurationMs,
|
|
1162
|
-
executeDurationMs,
|
|
1163
|
-
totalDurationMs: +(performance.now() - enqueuedAt).toFixed(2)
|
|
1164
|
-
});
|
|
1114
|
+
(0, import_product.perfMark)("replaceProductsSnapshotInIndexDB", performance.now() - t0, { count: products.length });
|
|
1115
|
+
this.logInfo("replaceProductsSnapshotInIndexDB 完成", { source, productCount: products.length });
|
|
1165
1116
|
});
|
|
1166
1117
|
} catch (error) {
|
|
1167
1118
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1168
1119
|
this.logError("全量保存商品到 IndexDB 失败", {
|
|
1169
1120
|
source,
|
|
1170
1121
|
productCount: products.length,
|
|
1171
|
-
queueWaitMs,
|
|
1172
|
-
clearDurationMs,
|
|
1173
|
-
writeDurationMs,
|
|
1174
|
-
totalDurationMs: +(performance.now() - enqueuedAt).toFixed(2),
|
|
1175
1122
|
error: errorMessage
|
|
1176
1123
|
});
|
|
1177
1124
|
}
|
|
@@ -1253,7 +1200,6 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
1253
1200
|
source: "IndexDB"
|
|
1254
1201
|
});
|
|
1255
1202
|
this.logInfo("预加载完成(从 IndexDB)", {
|
|
1256
|
-
trigger: "preload",
|
|
1257
1203
|
productCount: cachedData.length,
|
|
1258
1204
|
duration: `${Math.round(performance.now() - tTotal)}ms`,
|
|
1259
1205
|
source: "IndexDB"
|
|
@@ -1269,9 +1215,7 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
1269
1215
|
this.logWarning("从 IndexDB 加载数据失败,准备从服务器加载", { error: errorMessage });
|
|
1270
1216
|
}
|
|
1271
1217
|
const tServer = performance.now();
|
|
1272
|
-
const products = await this.loadProductsByServer(
|
|
1273
|
-
trigger: "preload"
|
|
1274
|
-
});
|
|
1218
|
+
const products = await this.loadProductsByServer();
|
|
1275
1219
|
(0, import_product.perfMark)("preload.loadFromServer", performance.now() - tServer, { count: (products == null ? void 0 : products.length) ?? 0 });
|
|
1276
1220
|
if (products && products.length > 0) {
|
|
1277
1221
|
this.store.list = products;
|
|
@@ -1284,7 +1228,6 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
1284
1228
|
source: "Server"
|
|
1285
1229
|
});
|
|
1286
1230
|
this.logInfo("预加载完成(从服务器)", {
|
|
1287
|
-
trigger: "preload",
|
|
1288
1231
|
productCount: products.length,
|
|
1289
1232
|
duration: `${Math.round(performance.now() - tTotal)}ms`,
|
|
1290
1233
|
source: "Server"
|
|
@@ -1649,31 +1592,17 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
1649
1592
|
* 拿到完整数据后一次性替换 store,清除价格缓存,触发 onProductsSyncCompleted
|
|
1650
1593
|
* @returns 刷新后的商品列表
|
|
1651
1594
|
*/
|
|
1652
|
-
async silentRefresh(
|
|
1595
|
+
async silentRefresh() {
|
|
1653
1596
|
const t0 = performance.now();
|
|
1654
1597
|
const now = Date.now();
|
|
1655
|
-
const
|
|
1656
|
-
const
|
|
1657
|
-
|
|
1658
|
-
if (this.lastPreloadCompletedAtMs > 0 && elapsedSincePreloadMs < PRODUCT_SILENT_REFRESH_MIN_INTERVAL_MS || this.lastServerFullFetchAtMs > 0 && elapsedSinceFullFetchMs < PRODUCT_SILENT_REFRESH_MIN_INTERVAL_MS) {
|
|
1659
|
-
this.logInfo("silentRefresh 跳过全量 SSE", {
|
|
1660
|
-
trigger,
|
|
1661
|
-
reason: "within_min_interval",
|
|
1662
|
-
minIntervalMs: PRODUCT_SILENT_REFRESH_MIN_INTERVAL_MS,
|
|
1663
|
-
elapsedSincePreloadMs,
|
|
1664
|
-
elapsedSinceFullFetchMs,
|
|
1665
|
-
productCount: this.store.list.length
|
|
1666
|
-
});
|
|
1598
|
+
const elapsedSincePreload = now - this.lastPreloadCompletedAtMs;
|
|
1599
|
+
const elapsedSinceFullFetch = now - this.lastServerFullFetchAtMs;
|
|
1600
|
+
if (this.lastPreloadCompletedAtMs > 0 && elapsedSincePreload < PRODUCT_SILENT_REFRESH_MIN_INTERVAL_MS || this.lastServerFullFetchAtMs > 0 && elapsedSinceFullFetch < PRODUCT_SILENT_REFRESH_MIN_INTERVAL_MS) {
|
|
1667
1601
|
return this.store.list;
|
|
1668
1602
|
}
|
|
1669
|
-
this.logInfo("silentRefresh 开始"
|
|
1670
|
-
trigger,
|
|
1671
|
-
elapsedSincePreloadMs,
|
|
1672
|
-
elapsedSinceFullFetchMs,
|
|
1673
|
-
productCount: this.store.list.length
|
|
1674
|
-
});
|
|
1603
|
+
this.logInfo("silentRefresh 开始");
|
|
1675
1604
|
try {
|
|
1676
|
-
const products = await this.loadProductsByServer(
|
|
1605
|
+
const products = await this.loadProductsByServer();
|
|
1677
1606
|
if (products && products.length > 0) {
|
|
1678
1607
|
this.store.list = products;
|
|
1679
1608
|
this.syncProductsMap();
|
|
@@ -1681,7 +1610,6 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
1681
1610
|
this.core.effects.emit(import_types.ProductsHooks.onProductsChanged, this.store.list);
|
|
1682
1611
|
await this.core.effects.emit(import_types.ProductsHooks.onProductsSyncCompleted, null);
|
|
1683
1612
|
this.logInfo("silentRefresh 完成", {
|
|
1684
|
-
trigger,
|
|
1685
1613
|
productCount: products.length,
|
|
1686
1614
|
duration: `${Math.round(performance.now() - t0)}ms`
|
|
1687
1615
|
});
|
|
@@ -1693,7 +1621,6 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
|
|
|
1693
1621
|
} catch (error) {
|
|
1694
1622
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1695
1623
|
this.logError("silentRefresh 失败", {
|
|
1696
|
-
trigger,
|
|
1697
1624
|
duration: `${Math.round(performance.now() - t0)}ms`,
|
|
1698
1625
|
error: errorMessage
|
|
1699
1626
|
});
|
|
@@ -88,18 +88,13 @@ var ResourceModule = class extends import_BaseModule.BaseModule {
|
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
async preload() {
|
|
91
|
+
await this.setupResourceSync();
|
|
91
92
|
const cachedResources = await this.loadResourcesFromSQLite();
|
|
92
93
|
if (cachedResources.length > 0) {
|
|
93
94
|
this.store.list = (0, import_lodash_es.cloneDeep)(cachedResources).map((item) => this.normalizeResource(item));
|
|
94
95
|
this.syncResourcesMap();
|
|
95
96
|
await this.safeEmit(import_types.ResourceHooks.onResourcesChanged, this.store.list);
|
|
96
|
-
|
|
97
|
-
this.logError("后台初始化资源同步失败", error);
|
|
98
|
-
});
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
await this.setupResourceSync();
|
|
102
|
-
if (this.store.list.length === 0) {
|
|
97
|
+
} else {
|
|
103
98
|
const resources = await this.loadResourcesByServer();
|
|
104
99
|
if (resources.length > 0) {
|
|
105
100
|
this.store.list = (0, import_lodash_es.cloneDeep)(resources).map((item) => this.normalizeResource(item));
|
|
@@ -562,7 +562,7 @@ function buildOptionTitleSuffix(options) {
|
|
|
562
562
|
function formatBundlePrice(bundle, currencySymbol) {
|
|
563
563
|
const value = bundle.bundle_selling_price ?? bundle.bundle_sum_price ?? bundle.price ?? 0;
|
|
564
564
|
const amount = new import_decimal.default(toMoneyNumber(value));
|
|
565
|
-
const isNegative = bundle.price_type === "markdown"
|
|
565
|
+
const isNegative = bundle.price_type === "markdown";
|
|
566
566
|
if (isNegative)
|
|
567
567
|
return `-${currencySymbol}${amount.abs().toFixed(2)}`;
|
|
568
568
|
return formatMoney(amount, currencySymbol);
|
|
@@ -141,7 +141,9 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
141
141
|
* const params = this.buildSubModuleOtherParams();
|
|
142
142
|
* this.core.registerModule(orderModule, { otherParams: params });
|
|
143
143
|
*/
|
|
144
|
-
protected
|
|
144
|
+
protected isSessionStoragePersistEnabled(): boolean;
|
|
145
|
+
protected shouldUseSessionStorageForSubModule(_moduleName?: string): boolean;
|
|
146
|
+
protected buildSubModuleOtherParams(moduleName?: string): Record<string, any>;
|
|
145
147
|
/**
|
|
146
148
|
* 将父级 otherParams 的变更显式同步给已注册的子模块。
|
|
147
149
|
*
|
|
@@ -591,7 +591,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
591
591
|
});
|
|
592
592
|
});
|
|
593
593
|
}
|
|
594
|
-
async hydrateLatestLoadedSalesDetail(record, loadSequence) {
|
|
594
|
+
async hydrateLatestLoadedSalesDetail(record, loadSequence, hydrateSource) {
|
|
595
595
|
let hydratedSales = null;
|
|
596
596
|
let skippedBeforeHydrate = false;
|
|
597
597
|
const hydrateTask = async () => {
|
|
@@ -601,9 +601,10 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
601
601
|
}
|
|
602
602
|
if (!this.store.order)
|
|
603
603
|
throw new Error("order 模块未初始化");
|
|
604
|
-
const sales = await this.store.order.hydrateTempOrderFromRecord(
|
|
605
|
-
|
|
606
|
-
|
|
604
|
+
const sales = await this.store.order.hydrateTempOrderFromRecord(
|
|
605
|
+
record,
|
|
606
|
+
hydrateSource === "sessionStorage" ? { recalcOnHydrate: true, source: "sessionStorage" } : { recalcOnHydrate: false }
|
|
607
|
+
);
|
|
607
608
|
hydratedSales = sales;
|
|
608
609
|
if (loadSequence !== this.salesDetailLoadSequence)
|
|
609
610
|
return;
|
|
@@ -927,12 +928,18 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
927
928
|
* const params = this.buildSubModuleOtherParams();
|
|
928
929
|
* this.core.registerModule(orderModule, { otherParams: params });
|
|
929
930
|
*/
|
|
930
|
-
|
|
931
|
+
isSessionStoragePersistEnabled() {
|
|
932
|
+
return Boolean(this.cacheId);
|
|
933
|
+
}
|
|
934
|
+
shouldUseSessionStorageForSubModule(_moduleName) {
|
|
935
|
+
return this.isSessionStoragePersistEnabled();
|
|
936
|
+
}
|
|
937
|
+
buildSubModuleOtherParams(moduleName) {
|
|
931
938
|
return {
|
|
932
939
|
...this.otherParams,
|
|
933
940
|
salesSummaryModuleName: `${this.name}_salesSummary`,
|
|
934
941
|
fatherModule: this.name,
|
|
935
|
-
openCache: this.
|
|
942
|
+
openCache: this.shouldUseSessionStorageForSubModule(moduleName),
|
|
936
943
|
cacheId: this.cacheId
|
|
937
944
|
};
|
|
938
945
|
}
|
|
@@ -943,7 +950,6 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
943
950
|
* await this.syncOtherParamsToSubModules({ channel: 'pos' });
|
|
944
951
|
*/
|
|
945
952
|
async syncOtherParamsToSubModules(changedParams, { cover = false } = {}) {
|
|
946
|
-
const nextSubModuleOtherParams = this.buildSubModuleOtherParams();
|
|
947
953
|
await Promise.all(
|
|
948
954
|
Object.entries(this.store).map(async ([moduleName, subModule]) => {
|
|
949
955
|
if (this.reusedSharedSubModuleNames.has(moduleName)) {
|
|
@@ -953,6 +959,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
953
959
|
if (!targetModule || typeof targetModule.updateOtherParams !== "function") {
|
|
954
960
|
return;
|
|
955
961
|
}
|
|
962
|
+
const nextSubModuleOtherParams = this.buildSubModuleOtherParams(moduleName);
|
|
956
963
|
await targetModule.updateOtherParams(nextSubModuleOtherParams, {
|
|
957
964
|
changedParams,
|
|
958
965
|
cover
|
|
@@ -965,14 +972,16 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
965
972
|
* sessionStorage 损坏时静默忽略,按空状态注册。
|
|
966
973
|
*/
|
|
967
974
|
readSessionCacheData() {
|
|
968
|
-
|
|
975
|
+
const cacheId = this.cacheId;
|
|
976
|
+
if (!cacheId || !this.isSessionStoragePersistEnabled() || !this.window) {
|
|
969
977
|
return {};
|
|
978
|
+
}
|
|
970
979
|
try {
|
|
971
980
|
const sessionData = this.window.sessionStorage.getItem(this.name);
|
|
972
981
|
if (!sessionData)
|
|
973
982
|
return {};
|
|
974
983
|
const data = JSON.parse(sessionData);
|
|
975
|
-
return data && data[
|
|
984
|
+
return data && data[cacheId] || {};
|
|
976
985
|
} catch {
|
|
977
986
|
return {};
|
|
978
987
|
}
|
|
@@ -1074,9 +1083,9 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
1074
1083
|
const hooks = this.getSubModuleHooks(step);
|
|
1075
1084
|
this.store[step] = targetModule;
|
|
1076
1085
|
this.core.registerModule(targetModule, {
|
|
1077
|
-
initialState: (targetCacheData == null ? void 0 : targetCacheData[targetModule.name]) || {},
|
|
1086
|
+
initialState: this.shouldUseSessionStorageForSubModule(step) ? (targetCacheData == null ? void 0 : targetCacheData[targetModule.name]) || {} : {},
|
|
1078
1087
|
...hooks ? { hooks } : {},
|
|
1079
|
-
otherParams: this.buildSubModuleOtherParams()
|
|
1088
|
+
otherParams: this.buildSubModuleOtherParams(step)
|
|
1080
1089
|
});
|
|
1081
1090
|
});
|
|
1082
1091
|
if (this.store.schedule && !this.isScheduleListLoaded(this.store.schedule)) {
|
|
@@ -1143,17 +1152,21 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
1143
1152
|
const message = loadedRecord && (loadedRecord.message || loadedRecord.msg) || `加载销售详情失败: ${lookup}`;
|
|
1144
1153
|
throw new Error(message);
|
|
1145
1154
|
}
|
|
1146
|
-
const
|
|
1147
|
-
|
|
1148
|
-
);
|
|
1155
|
+
const loadedSalesDetail = preloadedSalesDetail ?? loadedRecord.data;
|
|
1156
|
+
const shouldFilterPendingPayments = params.hydrateSource !== "sessionStorage";
|
|
1157
|
+
const remoteRecord = shouldFilterPendingPayments ? filterPendingPaymentsFromLoadedSalesDetail(loadedSalesDetail) : loadedSalesDetail;
|
|
1149
1158
|
const currentTempOrder = params.merge ? this.store.order.getTempOrder() : null;
|
|
1150
1159
|
const mergedRecord = params.merge ? mergeSalesDetailRecordWithTempOrder(
|
|
1151
1160
|
currentTempOrder,
|
|
1152
1161
|
remoteRecord,
|
|
1153
1162
|
"preserve-local"
|
|
1154
1163
|
) : remoteRecord;
|
|
1155
|
-
const record = filterPendingPaymentsFromLoadedSalesDetail(mergedRecord);
|
|
1156
|
-
return await this.hydrateLatestLoadedSalesDetail(
|
|
1164
|
+
const record = shouldFilterPendingPayments ? filterPendingPaymentsFromLoadedSalesDetail(mergedRecord) : mergedRecord;
|
|
1165
|
+
return await this.hydrateLatestLoadedSalesDetail(
|
|
1166
|
+
record,
|
|
1167
|
+
loadSequence,
|
|
1168
|
+
params.hydrateSource
|
|
1169
|
+
);
|
|
1157
1170
|
} finally {
|
|
1158
1171
|
this.salesDetailLoadInFlightCount = Math.max(
|
|
1159
1172
|
0,
|
|
@@ -60,33 +60,44 @@ function createEmptySummary() {
|
|
|
60
60
|
};
|
|
61
61
|
}
|
|
62
62
|
function buildProductLineFingerprint(productOptionItem, productBundle) {
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
63
|
+
const normalizeOptions = (options) => {
|
|
64
|
+
const optionArr = Array.isArray(options) ? options : [];
|
|
65
|
+
return optionArr.map((item) => ({
|
|
66
|
+
option_group_item_id: Number(item == null ? void 0 : item.option_group_item_id) || 0,
|
|
67
|
+
option_group_id: Number(item == null ? void 0 : item.option_group_id) || 0,
|
|
68
|
+
num: typeof (item == null ? void 0 : item.num) === "number" && !Number.isNaN(item.num) ? Math.max(1, Math.floor(item.num)) : 1,
|
|
69
|
+
price: String((item == null ? void 0 : item.add_price) ?? (item == null ? void 0 : item.price) ?? "")
|
|
70
|
+
})).sort((p, q) => {
|
|
71
|
+
if (p.option_group_item_id !== q.option_group_item_id) {
|
|
72
|
+
return p.option_group_item_id - q.option_group_item_id;
|
|
73
|
+
}
|
|
74
|
+
if (p.option_group_id !== q.option_group_id) {
|
|
75
|
+
return p.option_group_id - q.option_group_id;
|
|
76
|
+
}
|
|
77
|
+
if (p.num !== q.num)
|
|
78
|
+
return p.num - q.num;
|
|
79
|
+
return p.price.localeCompare(q.price);
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
const normalizedOpts = normalizeOptions(productOptionItem);
|
|
79
83
|
const bundleArr = Array.isArray(productBundle) ? productBundle : [];
|
|
80
84
|
const normalizedBundles = bundleArr.map((item) => ({
|
|
81
85
|
bundle_id: Number((item == null ? void 0 : item.bundle_id) ?? (item == null ? void 0 : item.id) ?? 0) || 0,
|
|
82
86
|
product_id: Number(item == null ? void 0 : item.product_id) || 0,
|
|
83
|
-
|
|
87
|
+
product_variant_id: Number((item == null ? void 0 : item.bundle_variant_id) ?? (item == null ? void 0 : item.product_variant_id)) || 0,
|
|
88
|
+
num: typeof (item == null ? void 0 : item.num) === "number" && !Number.isNaN(item.num) ? Math.max(1, Math.floor(item.num)) : 1,
|
|
89
|
+
option: normalizeOptions(item == null ? void 0 : item.option)
|
|
84
90
|
})).sort((p, q) => {
|
|
85
91
|
if (p.bundle_id !== q.bundle_id)
|
|
86
92
|
return p.bundle_id - q.bundle_id;
|
|
87
93
|
if (p.product_id !== q.product_id)
|
|
88
94
|
return p.product_id - q.product_id;
|
|
89
|
-
|
|
95
|
+
if (p.product_variant_id !== q.product_variant_id) {
|
|
96
|
+
return p.product_variant_id - q.product_variant_id;
|
|
97
|
+
}
|
|
98
|
+
if (p.num !== q.num)
|
|
99
|
+
return p.num - q.num;
|
|
100
|
+
return JSON.stringify(p.option).localeCompare(JSON.stringify(q.option));
|
|
90
101
|
});
|
|
91
102
|
return JSON.stringify([normalizedOpts, normalizedBundles]);
|
|
92
103
|
}
|
|
@@ -29,6 +29,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
29
29
|
private addTimeProductsCatalog;
|
|
30
30
|
private orderCustomerDiscountRefreshInFlight;
|
|
31
31
|
private orderCustomerDiscountRefreshCustomerId;
|
|
32
|
+
private orderCustomerPromotionRefreshInFlight;
|
|
32
33
|
private loadOpenDataConfigInFlight;
|
|
33
34
|
/**
|
|
34
35
|
* 在 BaseSales 默认模块清单(products/order/salesSummary/schedule)基础上追加 customer + bookingContext。
|
|
@@ -63,6 +64,8 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
63
64
|
scanPromotionCode(code: string, customerId?: number): Promise<BaseSalesScanCodeResult>;
|
|
64
65
|
private hydrateOrderCustomerFromScanDiscounts;
|
|
65
66
|
private getDiscountCustomerId;
|
|
67
|
+
resolveCustomerById(customerId: string | number): Promise<ICustomer | null>;
|
|
68
|
+
/** 兼容既有优惠码扫码逻辑。 */
|
|
66
69
|
private resolveCustomerByDiscountCustomerId;
|
|
67
70
|
private findCustomerById;
|
|
68
71
|
private normalizeCustomer;
|
|
@@ -282,7 +285,8 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
282
285
|
restoreOrder(): Promise<import("../../modules/Order/types").OrderTempOrder>;
|
|
283
286
|
/** 内部:基于 OrderModule 当前状态构造一份 OrderCustomerChangePayload。 */
|
|
284
287
|
private buildOrderCustomerPayload;
|
|
285
|
-
|
|
288
|
+
protected refreshDiscountConfigAfterOrderCustomerChange(customerId: number | null): Promise<void>;
|
|
289
|
+
protected waitForOrderCustomerPromotionRefresh(): Promise<void>;
|
|
286
290
|
/**
|
|
287
291
|
* 获取客户分页信息
|
|
288
292
|
* @returns 分页信息
|
|
@@ -326,7 +330,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
326
330
|
* 获取当前的客户搜索条件
|
|
327
331
|
* @returns 当前搜索条件
|
|
328
332
|
*/
|
|
329
|
-
getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "
|
|
333
|
+
getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
|
|
330
334
|
/**
|
|
331
335
|
* 获取客户列表状态(包含滚动加载相关状态)
|
|
332
336
|
* @returns 客户状态
|