@pisell/pisellos 2.3.84 → 2.3.86
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/server/index.js +1 -1
- package/dist/server/modules/order/index.d.ts +8 -0
- package/dist/server/modules/order/index.js +251 -215
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/UnifiedBookingSales/index.js +19 -4
- package/lib/model/strategy/adapter/promotion/index.js +1 -46
- package/lib/server/index.js +1 -1
- package/lib/server/modules/order/index.d.ts +8 -0
- package/lib/server/modules/order/index.js +23 -0
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/UnifiedBookingSales/index.js +14 -0
- package/package.json +1 -1
|
@@ -326,7 +326,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
326
326
|
date: string;
|
|
327
327
|
status: string;
|
|
328
328
|
week: string;
|
|
329
|
-
weekNum: 0 | 1 |
|
|
329
|
+
weekNum: 0 | 1 | 5 | 2 | 3 | 4 | 6;
|
|
330
330
|
}[]>;
|
|
331
331
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
332
332
|
private getScheduleDataByIds;
|
|
@@ -1068,6 +1068,7 @@ var POS_OVERRIDABLE_AVAILABILITY_CONFLICT_CODES = new Set(['past', 'booking_cuto
|
|
|
1068
1068
|
// as missing_resource at group level. Structural validation below still
|
|
1069
1069
|
// rejects a genuinely missing selection.
|
|
1070
1070
|
'missing_resource']);
|
|
1071
|
+
var POS_NO_RESOURCE_ID = 0;
|
|
1071
1072
|
function matchesForcedSelectionGroup(selection, group) {
|
|
1072
1073
|
var hasGroupId = typeof selection.requirementGroupId === 'string' && selection.requirementGroupId.trim().length > 0;
|
|
1073
1074
|
var hasFormId = selection.formId !== undefined && selection.formId !== null;
|
|
@@ -1153,7 +1154,21 @@ function buildPosForcedAvailabilityAssignments(params) {
|
|
|
1153
1154
|
return;
|
|
1154
1155
|
}
|
|
1155
1156
|
selectedResourceIds.forEach(function (resourceId) {
|
|
1156
|
-
var _group$resourceIds2, _group$
|
|
1157
|
+
var _group$resourceIds2, _group$formId2, _candidate$primarySch7, _candidate$primarySch8;
|
|
1158
|
+
if (sameAvailabilityId(resourceId, POS_NO_RESOURCE_ID)) {
|
|
1159
|
+
var _group$formId, _candidate$primarySch5, _candidate$primarySch6;
|
|
1160
|
+
assignments.push({
|
|
1161
|
+
productId: product.id,
|
|
1162
|
+
resourceId: POS_NO_RESOURCE_ID,
|
|
1163
|
+
formId: (_group$formId = group.formId) !== null && _group$formId !== void 0 ? _group$formId : selection.formId,
|
|
1164
|
+
startAt: candidate.bookingStartAt || candidate.startAt,
|
|
1165
|
+
endAt: candidate.bookingEndAt || candidate.endAt,
|
|
1166
|
+
capacityRequired: Math.max(1, partySize),
|
|
1167
|
+
scheduleId: (_candidate$primarySch5 = candidate.primaryScheduleRef) === null || _candidate$primarySch5 === void 0 ? void 0 : _candidate$primarySch5.scheduleId,
|
|
1168
|
+
timeSlotId: (_candidate$primarySch6 = candidate.primaryScheduleRef) === null || _candidate$primarySch6 === void 0 ? void 0 : _candidate$primarySch6.timeSlotId
|
|
1169
|
+
});
|
|
1170
|
+
return;
|
|
1171
|
+
}
|
|
1157
1172
|
var resource = resources.find(function (item) {
|
|
1158
1173
|
return sameAvailabilityId(item.id, resourceId);
|
|
1159
1174
|
});
|
|
@@ -1171,12 +1186,12 @@ function buildPosForcedAvailabilityAssignments(params) {
|
|
|
1171
1186
|
assignments.push({
|
|
1172
1187
|
productId: product.id,
|
|
1173
1188
|
resourceId: resourceId,
|
|
1174
|
-
formId: (_group$
|
|
1189
|
+
formId: (_group$formId2 = group.formId) !== null && _group$formId2 !== void 0 ? _group$formId2 : resource.formId,
|
|
1175
1190
|
startAt: candidate.bookingStartAt || candidate.startAt,
|
|
1176
1191
|
endAt: candidate.bookingEndAt || candidate.endAt,
|
|
1177
1192
|
capacityRequired: Math.max(1, partySize),
|
|
1178
|
-
scheduleId: (_candidate$
|
|
1179
|
-
timeSlotId: (_candidate$
|
|
1193
|
+
scheduleId: (_candidate$primarySch7 = candidate.primaryScheduleRef) === null || _candidate$primarySch7 === void 0 ? void 0 : _candidate$primarySch7.scheduleId,
|
|
1194
|
+
timeSlotId: (_candidate$primarySch8 = candidate.primaryScheduleRef) === null || _candidate$primarySch8 === void 0 ? void 0 : _candidate$primarySch8.timeSlotId
|
|
1180
1195
|
});
|
|
1181
1196
|
});
|
|
1182
1197
|
});
|
|
@@ -1,46 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
Object.defineProperty(exports, "BUY_X_GET_Y_FREE_STRATEGY", {
|
|
7
|
-
enumerable: true,
|
|
8
|
-
get: function () {
|
|
9
|
-
return _examples.BUY_X_GET_Y_FREE_STRATEGY;
|
|
10
|
-
}
|
|
11
|
-
});
|
|
12
|
-
Object.defineProperty(exports, "ITEM_REWARD_STRATEGY", {
|
|
13
|
-
enumerable: true,
|
|
14
|
-
get: function () {
|
|
15
|
-
return _examples.ITEM_REWARD_STRATEGY;
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
Object.defineProperty(exports, "PromotionAdapter", {
|
|
19
|
-
enumerable: true,
|
|
20
|
-
get: function () {
|
|
21
|
-
return _adapter.PromotionAdapter;
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
Object.defineProperty(exports, "PromotionEvaluator", {
|
|
25
|
-
enumerable: true,
|
|
26
|
-
get: function () {
|
|
27
|
-
return _evaluator.PromotionEvaluator;
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
Object.defineProperty(exports, "X_ITEMS_FOR_Y_PRICE_STRATEGY", {
|
|
31
|
-
enumerable: true,
|
|
32
|
-
get: function () {
|
|
33
|
-
return _examples.X_ITEMS_FOR_Y_PRICE_STRATEGY;
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
Object.defineProperty(exports, "default", {
|
|
37
|
-
enumerable: true,
|
|
38
|
-
get: function () {
|
|
39
|
-
return _adapter.default;
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
var _evaluator = require("./evaluator");
|
|
43
|
-
var _adapter = _interopRequireWildcard(require("./adapter"));
|
|
44
|
-
var _examples = require("./examples");
|
|
45
|
-
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
46
|
-
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
1
|
+
"use strict";
|
package/lib/server/index.js
CHANGED
|
@@ -1481,7 +1481,7 @@ class Server {
|
|
|
1481
1481
|
// timerIds.push(timerId);
|
|
1482
1482
|
// }
|
|
1483
1483
|
setInterval(() => {
|
|
1484
|
-
const currentTime = (0, _dayjs.default)().format('
|
|
1484
|
+
const currentTime = (0, _dayjs.default)().format('HH:mm');
|
|
1485
1485
|
if (timePoints.includes(currentTime)) {
|
|
1486
1486
|
this.onScheduleTimePointTimerFire(subscriberId);
|
|
1487
1487
|
}
|
|
@@ -20,6 +20,8 @@ export declare class OrderModule extends BaseModule implements Module {
|
|
|
20
20
|
private storage;
|
|
21
21
|
private orderSQLiteSaveQueue; /** 按 storageKey 记录最近一次 SQLite 写入来源与时间,用于去重 */
|
|
22
22
|
private recentSqliteWriteByStorageKey;
|
|
23
|
+
/** 最近一次清理过期 SQLite 去重记录的时间,避免每次写入都遍历 Map */
|
|
24
|
+
private lastRecentSqliteWriteCleanupAtMs;
|
|
23
25
|
/** 最近一次 SSE 全量拉取完成时间 */
|
|
24
26
|
private lastServerFullFetchAtMs;
|
|
25
27
|
constructor(name?: string, version?: string);
|
|
@@ -58,6 +60,12 @@ export declare class OrderModule extends BaseModule implements Module {
|
|
|
58
60
|
*/
|
|
59
61
|
private mergeAuthoritativeOrderCollection;
|
|
60
62
|
private reconcileOverwriteOrderCollections;
|
|
63
|
+
/**
|
|
64
|
+
* 惰性清理已经超过去重窗口的 SQLite 写入记录。
|
|
65
|
+
*
|
|
66
|
+
* 清理频率与去重窗口一致,既限制 Map 长期增长,也不会移除仍参与去重的记录。
|
|
67
|
+
*/
|
|
68
|
+
private cleanupExpiredRecentSqliteWrites;
|
|
61
69
|
/**
|
|
62
70
|
* 记录订单最近一次 SQLite 写入,供 pubsub 回声去重使用。
|
|
63
71
|
*
|
|
@@ -57,6 +57,8 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
57
57
|
storage;
|
|
58
58
|
orderSQLiteSaveQueue = Promise.resolve(); /** 按 storageKey 记录最近一次 SQLite 写入来源与时间,用于去重 */
|
|
59
59
|
recentSqliteWriteByStorageKey = new Map();
|
|
60
|
+
/** 最近一次清理过期 SQLite 去重记录的时间,避免每次写入都遍历 Map */
|
|
61
|
+
lastRecentSqliteWriteCleanupAtMs = 0;
|
|
60
62
|
/** 最近一次 SSE 全量拉取完成时间 */
|
|
61
63
|
lastServerFullFetchAtMs = 0;
|
|
62
64
|
constructor(name, version) {
|
|
@@ -292,6 +294,24 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
292
294
|
return this.normalizeOrderCollectionsForIngress((0, _orderCollectionIdentity.applyOrderCollectionUidRemaps)(reconciled, uidRemaps), 'overwriteExistingOrder.reconciled');
|
|
293
295
|
}
|
|
294
296
|
|
|
297
|
+
/**
|
|
298
|
+
* 惰性清理已经超过去重窗口的 SQLite 写入记录。
|
|
299
|
+
*
|
|
300
|
+
* 清理频率与去重窗口一致,既限制 Map 长期增长,也不会移除仍参与去重的记录。
|
|
301
|
+
*/
|
|
302
|
+
cleanupExpiredRecentSqliteWrites(now) {
|
|
303
|
+
const elapsedSinceCleanup = now - this.lastRecentSqliteWriteCleanupAtMs;
|
|
304
|
+
if (this.lastRecentSqliteWriteCleanupAtMs > 0 && elapsedSinceCleanup >= 0 && elapsedSinceCleanup < ORDER_SQLITE_DEDUPE_MS) {
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
for (const [storageKey, recentWrite] of this.recentSqliteWriteByStorageKey) {
|
|
308
|
+
if (now - recentWrite.ts >= ORDER_SQLITE_DEDUPE_MS) {
|
|
309
|
+
this.recentSqliteWriteByStorageKey.delete(storageKey);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
this.lastRecentSqliteWriteCleanupAtMs = now;
|
|
313
|
+
}
|
|
314
|
+
|
|
295
315
|
/**
|
|
296
316
|
* 记录订单最近一次 SQLite 写入,供 pubsub 回声去重使用。
|
|
297
317
|
*
|
|
@@ -300,6 +320,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
300
320
|
*/
|
|
301
321
|
recordRecentSqliteWrite(source, orders) {
|
|
302
322
|
const now = Date.now();
|
|
323
|
+
this.cleanupExpiredRecentSqliteWrites(now);
|
|
303
324
|
for (const order of orders) {
|
|
304
325
|
const storageKey = this.getOrderStorageKey(order);
|
|
305
326
|
if (!storageKey) continue;
|
|
@@ -1264,6 +1285,8 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1264
1285
|
}
|
|
1265
1286
|
this.isProcessingSyncBatch = false;
|
|
1266
1287
|
this.pendingSyncMessages = [];
|
|
1288
|
+
this.recentSqliteWriteByStorageKey.clear();
|
|
1289
|
+
this.lastRecentSqliteWriteCleanupAtMs = 0;
|
|
1267
1290
|
if (this.orderDataSource?.destroy) this.orderDataSource.destroy();
|
|
1268
1291
|
super.destroy();
|
|
1269
1292
|
}
|
|
@@ -326,7 +326,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
326
326
|
date: string;
|
|
327
327
|
status: string;
|
|
328
328
|
week: string;
|
|
329
|
-
weekNum: 0 | 1 |
|
|
329
|
+
weekNum: 0 | 1 | 5 | 2 | 3 | 4 | 6;
|
|
330
330
|
}[]>;
|
|
331
331
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
332
332
|
private getScheduleDataByIds;
|
|
@@ -986,6 +986,7 @@ const POS_OVERRIDABLE_AVAILABILITY_CONFLICT_CODES = new Set(['past', 'booking_cu
|
|
|
986
986
|
// as missing_resource at group level. Structural validation below still
|
|
987
987
|
// rejects a genuinely missing selection.
|
|
988
988
|
'missing_resource']);
|
|
989
|
+
const POS_NO_RESOURCE_ID = 0;
|
|
989
990
|
function matchesForcedSelectionGroup(selection, group) {
|
|
990
991
|
const hasGroupId = typeof selection.requirementGroupId === 'string' && selection.requirementGroupId.trim().length > 0;
|
|
991
992
|
const hasFormId = selection.formId !== undefined && selection.formId !== null;
|
|
@@ -1066,6 +1067,19 @@ function buildPosForcedAvailabilityAssignments(params) {
|
|
|
1066
1067
|
return;
|
|
1067
1068
|
}
|
|
1068
1069
|
selectedResourceIds.forEach(resourceId => {
|
|
1070
|
+
if (sameAvailabilityId(resourceId, POS_NO_RESOURCE_ID)) {
|
|
1071
|
+
assignments.push({
|
|
1072
|
+
productId: product.id,
|
|
1073
|
+
resourceId: POS_NO_RESOURCE_ID,
|
|
1074
|
+
formId: group.formId ?? selection.formId,
|
|
1075
|
+
startAt: candidate.bookingStartAt || candidate.startAt,
|
|
1076
|
+
endAt: candidate.bookingEndAt || candidate.endAt,
|
|
1077
|
+
capacityRequired: Math.max(1, partySize),
|
|
1078
|
+
scheduleId: candidate.primaryScheduleRef?.scheduleId,
|
|
1079
|
+
timeSlotId: candidate.primaryScheduleRef?.timeSlotId
|
|
1080
|
+
});
|
|
1081
|
+
return;
|
|
1082
|
+
}
|
|
1069
1083
|
const resource = resources.find(item => sameAvailabilityId(item.id, resourceId));
|
|
1070
1084
|
const belongsToGroup = Boolean(resource && !(group.formId !== undefined && resource.formId !== undefined && !sameAvailabilityId(group.formId, resource.formId)) && !(group.resourceIds?.length && !group.resourceIds.some(id => sameAvailabilityId(id, resourceId))));
|
|
1071
1085
|
if (!resource || !belongsToGroup) {
|