@pisell/pisellos 0.0.232 → 0.0.234

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.
@@ -11,7 +11,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
11
11
  initialize(core: PisellCore, options: ModuleOptions): Promise<void>;
12
12
  createOrder(params: CommitOrderParams['query']): {
13
13
  type: "virtual" | "appointment_booking";
14
- platform: "pc" | "h5";
14
+ platform: string;
15
15
  sales_channel: string;
16
16
  order_sales_channel: string;
17
17
  bookings: any[];
@@ -66,7 +66,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
66
66
  var order = {
67
67
  type: (params === null || params === void 0 ? void 0 : params.type) || 'appointment_booking',
68
68
  // 要从外面拿,virtual
69
- platform: (params === null || params === void 0 ? void 0 : params.platform) || 'pc',
69
+ platform: (params === null || params === void 0 ? void 0 : params.platform) === 'pc' ? 'PC' : 'H5',
70
70
  sales_channel: 'my_pisel',
71
71
  order_sales_channel: 'online_store',
72
72
  bookings: [],
@@ -517,7 +517,7 @@ export interface WalletDeductionRecommendParams {
517
517
  /** 订单待支付金额 */
518
518
  order_wait_pay_amount: number;
519
519
  /** 统计计数用户id */
520
- order_behavior_count_customer_id: number;
520
+ order_behavior_count_customer_id?: number;
521
521
  /** 已选商品 */
522
522
  products: {
523
523
  /** 商品id */
@@ -555,6 +555,7 @@ export interface WalletInitBusinessData {
555
555
  quantity: number;
556
556
  selling_price: number;
557
557
  }[];
558
+ order_wait_pay_amount?: number;
558
559
  }
559
560
  /**
560
561
  * 查询用户识别码列表请求参数
@@ -55,17 +55,22 @@ export var WalletPassPaymentImpl = /*#__PURE__*/function () {
55
55
  value: function generateWalletParams(businessData) {
56
56
  var customer_id = businessData.customer_id,
57
57
  amountInfo = businessData.amountInfo,
58
- products = businessData.products;
58
+ products = businessData.products,
59
+ order_wait_pay_amount = businessData.order_wait_pay_amount;
59
60
 
60
61
  // 转换金额为数字类型
61
- var totalAmount = Number(amountInfo.subTotal) || Number(amountInfo.totalAmount);
62
+ var totalAmount = Number(amountInfo.totalAmount);
63
+ var subTotal = Number(amountInfo.subTotal);
62
64
  var walletParams = {
63
- sale_channel: 'kiosk',
64
- customer_id: customer_id,
65
+ sale_channel: 'pos',
66
+ customer_id: customer_id || 0,
67
+ // 提供默认值,确保类型为 number
65
68
  order_expect_amount: totalAmount,
66
- order_product_amount: totalAmount,
67
- order_wait_pay_amount: totalAmount,
68
- order_behavior_count_customer_id: 1,
69
+ // 订单小计金额
70
+ order_product_amount: subTotal,
71
+ // 订单待支付金额
72
+ order_wait_pay_amount: order_wait_pay_amount || totalAmount,
73
+ // order_behavior_count_customer_id: 1,
69
74
  products: products,
70
75
  prepare_payments: []
71
76
  };
@@ -207,7 +212,8 @@ export var WalletPassPaymentImpl = /*#__PURE__*/function () {
207
212
  _context3.prev = 10;
208
213
  _context3.t0 = _context3["catch"](0);
209
214
  console.error('获取钱包推荐列表失败:', _context3.t0);
210
- throw _context3.t0;
215
+ // throw error;
216
+ return _context3.abrupt("return", []);
211
217
  case 14:
212
218
  case "end":
213
219
  return _context3.stop();
@@ -252,7 +258,7 @@ export var WalletPassPaymentImpl = /*#__PURE__*/function () {
252
258
  _context4.prev = 12;
253
259
  _context4.t0 = _context4["catch"](0);
254
260
  console.error('获取用户识别码列表失败:', _context4.t0);
255
- throw _context4.t0;
261
+ return _context4.abrupt("return", []);
256
262
  case 16:
257
263
  case "end":
258
264
  return _context4.stop();
@@ -30,7 +30,7 @@ export declare class ScheduleModule extends BaseModule implements Module, Schedu
30
30
  * @param param0 { date: string, schedule: any } date: 日期, schedule: schedule
31
31
  * @returns
32
32
  */
33
- static isInScheduleByDate({ date, schedule }: {
33
+ static isInScheduleByDate({ date, schedule, }: {
34
34
  date: string;
35
35
  schedule: any;
36
36
  }): true | undefined;
@@ -246,7 +246,7 @@ export var ScheduleModule = /*#__PURE__*/function (_BaseModule) {
246
246
  /**
247
247
  * 传入一个时间, 判断改时间是否在schedule 内
248
248
  * @param param0 { date: string, schedule: any } date: 日期, schedule: schedule
249
- * @returns
249
+ * @returns
250
250
  */
251
251
  }], [{
252
252
  key: "isInScheduleByDate",
@@ -257,23 +257,31 @@ export var ScheduleModule = /*#__PURE__*/function (_BaseModule) {
257
257
  // 节约性能, 强制将schedule的时间范围改为前后一天,避免大量计算.
258
258
  var _schedule = _objectSpread(_objectSpread({}, schedule), {}, {
259
259
  // 开始时间向前推一天
260
- start_time: dayjs(date).subtract(1, "day").format("YYYY-MM-DD HH:mm:ss"),
261
- end_time: dayjs(date).add(1, "day").format("YYYY-MM-DD HH:mm:ss")
260
+ start_time: dayjs(date).subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'),
261
+ end_time: dayjs(date).add(1, 'day').format('YYYY-MM-DD HH:mm:ss')
262
262
  });
263
263
 
264
264
  // 不限制的 改为后一天
265
- if (((_schedule$repeat_rule = _schedule.repeat_rule) === null || _schedule$repeat_rule === void 0 || (_schedule$repeat_rule = _schedule$repeat_rule.end) === null || _schedule$repeat_rule === void 0 ? void 0 : _schedule$repeat_rule.type) === "never") {
266
- _schedule.repeat_rule.end = {
267
- type: "date",
268
- end_date: _schedule.end_time,
269
- occurrence: null
270
- };
265
+ if (((_schedule$repeat_rule = _schedule.repeat_rule) === null || _schedule$repeat_rule === void 0 || (_schedule$repeat_rule = _schedule$repeat_rule.end) === null || _schedule$repeat_rule === void 0 ? void 0 : _schedule$repeat_rule.type) === 'never') {
266
+ _schedule = _objectSpread(_objectSpread({}, _schedule), {}, {
267
+ repeat_rule: _objectSpread(_objectSpread({}, _schedule.repeat_rule), {}, {
268
+ end: {
269
+ type: 'date',
270
+ end_date: _schedule.end_time,
271
+ occurrence: null
272
+ }
273
+ })
274
+ });
271
275
  }
272
276
 
273
277
  // 限制结束日期的也改为后一天
274
- if (((_schedule$repeat_rule2 = _schedule.repeat_rule) === null || _schedule$repeat_rule2 === void 0 || (_schedule$repeat_rule2 = _schedule$repeat_rule2.end) === null || _schedule$repeat_rule2 === void 0 ? void 0 : _schedule$repeat_rule2.type) === "date") {
275
- _schedule.repeat_rule.end = _objectSpread(_objectSpread({}, _schedule.repeat_rule.end), {}, {
276
- end_date: _schedule.end_time
278
+ if (((_schedule$repeat_rule2 = _schedule.repeat_rule) === null || _schedule$repeat_rule2 === void 0 || (_schedule$repeat_rule2 = _schedule$repeat_rule2.end) === null || _schedule$repeat_rule2 === void 0 ? void 0 : _schedule$repeat_rule2.type) === 'date') {
279
+ _schedule = _objectSpread(_objectSpread({}, _schedule), {}, {
280
+ repeat_rule: _objectSpread(_objectSpread({}, _schedule.repeat_rule), {}, {
281
+ end: _objectSpread(_objectSpread({}, _schedule.repeat_rule.end), {}, {
282
+ end_date: _schedule.end_time
283
+ })
284
+ })
277
285
  });
278
286
  }
279
287
  var dateRanges = calcScheduleDateRange(_objectSpread({}, _schedule));
@@ -95,6 +95,12 @@ export function findFastestAvailableResource(_ref2) {
95
95
  var currentTime = dayjs();
96
96
  var fastestTime = null;
97
97
  var fastestResources = [];
98
+ console.log('[TimeslotUtils] 查找最快可用资源:', {
99
+ currentTime: currentTime.format('YYYY-MM-DD HH:mm:ss'),
100
+ resourceCount: resources.length,
101
+ currentCapacity: currentCapacity,
102
+ countMap: countMap
103
+ });
98
104
 
99
105
  // 遍历所有资源,找到最快可用的时间点
100
106
  var _iterator2 = _createForOfIteratorHelper(resources),
@@ -102,75 +108,120 @@ export function findFastestAvailableResource(_ref2) {
102
108
  try {
103
109
  for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
104
110
  var _resource = _step2.value;
105
- // 获取资源当天的时间段
111
+ // 获取资源当天且还在工作时间内的时间段
106
112
  var todayTimes = _resource.times.filter(function (time) {
107
- return dayjs(time.start_at).isSame(currentTime, 'day');
108
- });
109
- if (todayTimes.length === 0) continue;
110
-
111
- // 按开始时间排序
112
- todayTimes.sort(function (a, b) {
113
- return dayjs(a.start_at).diff(dayjs(b.start_at));
113
+ var isToday = dayjs(time.start_at).isSame(currentTime, 'day');
114
+ var isStillWorking = dayjs(time.end_at).isAfter(currentTime);
115
+ return isToday && isStillWorking;
114
116
  });
115
-
116
- // 找到第一个可用的时间段
117
- var _iterator3 = _createForOfIteratorHelper(todayTimes),
118
- _step3;
117
+ if (todayTimes.length === 0) {
118
+ console.log("[TimeslotUtils] \u8D44\u6E90 ".concat(_resource.id, "(").concat(_resource.main_field, ") \u4ECA\u65E5\u65E0\u53EF\u7528\u65F6\u95F4\u6BB5"));
119
+ continue;
120
+ }
121
+ var _iterator4 = _createForOfIteratorHelper(todayTimes),
122
+ _step4;
119
123
  try {
120
124
  var _loop = function _loop() {
121
- var time = _step3.value;
122
- var startTime = dayjs(time.start_at);
123
-
124
- // 如果开始时间在当前时间之前,跳过
125
- if (startTime.isBefore(currentTime)) return 0; // continue
126
-
127
- // 检查这个时间段是否可用
128
- if (_resource.resourceType === 'single') {
129
- var _time$event_list;
130
- // 单个预约类型:检查是否有预约
131
- var hasBooking = (_time$event_list = time.event_list) === null || _time$event_list === void 0 ? void 0 : _time$event_list.some(function (event) {
132
- return dayjs(event.start_at).isSame(startTime);
133
- });
134
- if (!hasBooking) {
135
- if (!fastestTime || startTime.isSame(fastestTime)) {
136
- fastestTime = startTime;
137
- fastestResources.push(_resource);
138
- } else if (startTime.isBefore(fastestTime)) {
139
- fastestTime = startTime;
140
- fastestResources = [_resource];
141
- }
142
- return 1; // break
143
- }
144
- } else {
145
- var _time$event_list2;
146
- // 多个预约类型:检查容量
147
- var totalCapacity = _resource.capacity || 0;
148
- var usedCapacity = ((_time$event_list2 = time.event_list) === null || _time$event_list2 === void 0 ? void 0 : _time$event_list2.reduce(function (sum, event) {
149
- return dayjs(event.start_at).isSame(startTime) ? sum + (event.pax || 0) : sum;
150
- }, 0)) || 0;
151
- var remainingCapacity = totalCapacity - usedCapacity;
152
- if (remainingCapacity >= (countMap[_resource.id] || 0) + currentCapacity) {
153
- if (!fastestTime || startTime.isSame(fastestTime)) {
154
- fastestTime = startTime;
155
- fastestResources.push(_resource);
156
- } else if (startTime.isBefore(fastestTime)) {
157
- fastestTime = startTime;
158
- fastestResources = [_resource];
125
+ var _time$event_list, _time$event_list2;
126
+ var time = _step4.value;
127
+ var workStartTime = dayjs(time.start_at);
128
+ var workEndTime = dayjs(time.end_at);
129
+
130
+ // 确定检查的起始时间(当前时间 vs 工作开始时间)
131
+ var nextAvailableTime = currentTime.isBefore(workStartTime) ? workStartTime : currentTime;
132
+ console.log("[TimeslotUtils] \u68C0\u67E5\u8D44\u6E90 ".concat(_resource.id, "(").concat(_resource.main_field, "):"), {
133
+ workTime: "".concat(workStartTime.format('HH:mm'), "-").concat(workEndTime.format('HH:mm')),
134
+ checkStartTime: nextAvailableTime.format('HH:mm:ss'),
135
+ eventCount: ((_time$event_list = time.event_list) === null || _time$event_list === void 0 ? void 0 : _time$event_list.length) || 0
136
+ });
137
+
138
+ // 获取所有影响的预约事件(当前时间之后的)
139
+ var relevantEvents = ((_time$event_list2 = time.event_list) === null || _time$event_list2 === void 0 ? void 0 : _time$event_list2.filter(function (event) {
140
+ var eventEnd = dayjs(event.end_at);
141
+ return eventEnd.isAfter(nextAvailableTime);
142
+ })) || [];
143
+
144
+ // 按开始时间排序
145
+ relevantEvents.sort(function (a, b) {
146
+ return dayjs(a.start_at).diff(dayjs(b.start_at));
147
+ });
148
+
149
+ // 检查从 nextAvailableTime 开始的可用性
150
+ var finalAvailableTime = nextAvailableTime;
151
+ var _iterator5 = _createForOfIteratorHelper(relevantEvents),
152
+ _step5;
153
+ try {
154
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
155
+ var _event = _step5.value;
156
+ var _eventStart = dayjs(_event.start_at);
157
+ var _eventEnd = dayjs(_event.end_at);
158
+ console.log("[TimeslotUtils] \u68C0\u67E5\u4E8B\u4EF6\u51B2\u7A81:", {
159
+ resourceId: _resource.id,
160
+ eventTime: "".concat(_eventStart.format('HH:mm'), "-").concat(_eventEnd.format('HH:mm')),
161
+ checkTime: finalAvailableTime.format('HH:mm:ss'),
162
+ pax: _event.pax || 1
163
+ });
164
+
165
+ // 检查资源类型和容量
166
+ if (_resource.resourceType === 'single' || (_resource.capacity || 1) === 1) {
167
+ // 单人预约资源:检查时间冲突
168
+ if (finalAvailableTime.isBefore(_eventEnd) && _eventStart.isBefore(finalAvailableTime.add(30, 'minute'))) {
169
+ // 有冲突,使用事件结束时间
170
+ finalAvailableTime = _eventEnd;
171
+ console.log("[TimeslotUtils] \u53D1\u73B0\u65F6\u95F4\u51B2\u7A81\uFF0C\u8C03\u6574\u5230: ".concat(finalAvailableTime.format('HH:mm:ss')));
172
+ }
173
+ } else {
174
+ // 多人预约资源:检查容量
175
+ var totalCapacity = _resource.capacity || 0;
176
+ var currentUsedCapacity = countMap[_resource.id] || 0;
177
+ var eventUsedCapacity = _event.pax || 1;
178
+
179
+ // 如果在事件时间范围内,检查容量是否足够
180
+ if (finalAvailableTime.isBefore(_eventEnd) && _eventStart.isBefore(finalAvailableTime.add(30, 'minute'))) {
181
+ var totalRequiredCapacity = currentUsedCapacity + currentCapacity + eventUsedCapacity;
182
+ if (totalRequiredCapacity > totalCapacity) {
183
+ // 容量不足,使用事件结束时间
184
+ finalAvailableTime = _eventEnd;
185
+ console.log("[TimeslotUtils] \u5BB9\u91CF\u4E0D\u8DB3\uFF0C\u8C03\u6574\u5230: ".concat(finalAvailableTime.format('HH:mm:ss')));
186
+ }
187
+ }
159
188
  }
160
- return 1; // break
161
189
  }
190
+
191
+ // 确保可用时间在工作时间内
192
+ } catch (err) {
193
+ _iterator5.e(err);
194
+ } finally {
195
+ _iterator5.f();
196
+ }
197
+ if (finalAvailableTime.isAfter(workEndTime)) {
198
+ console.log("[TimeslotUtils] \u8D44\u6E90 ".concat(_resource.id, " \u53EF\u7528\u65F6\u95F4\u8D85\u51FA\u5DE5\u4F5C\u65F6\u95F4\uFF0C\u8DF3\u8FC7"));
199
+ return 0; // continue
162
200
  }
201
+ console.log("[TimeslotUtils] \u8D44\u6E90 ".concat(_resource.id, "(").concat(_resource.main_field, ") \u6700\u5FEB\u53EF\u7528\u65F6\u95F4: ").concat(finalAvailableTime.format('HH:mm:ss')));
202
+
203
+ // 更新最快可用时间和资源
204
+ if (!fastestTime || finalAvailableTime.isBefore(fastestTime)) {
205
+ fastestTime = finalAvailableTime;
206
+ fastestResources = [_resource];
207
+ console.log("[TimeslotUtils] \u66F4\u65B0\u6700\u5FEB\u65F6\u95F4: ".concat(fastestTime.format('HH:mm:ss'), ", \u8D44\u6E90: ").concat(_resource.main_field));
208
+ } else if (finalAvailableTime.isSame(fastestTime)) {
209
+ fastestResources.push(_resource);
210
+ console.log("[TimeslotUtils] \u6DFB\u52A0\u76F8\u540C\u65F6\u95F4\u8D44\u6E90: ".concat(_resource.main_field));
211
+ }
212
+ return 1; // break
213
+ // 每个资源只需要计算一次
163
214
  },
164
215
  _ret;
165
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
216
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
166
217
  _ret = _loop();
167
218
  if (_ret === 0) continue;
168
219
  if (_ret === 1) break;
169
220
  }
170
221
  } catch (err) {
171
- _iterator3.e(err);
222
+ _iterator4.e(err);
172
223
  } finally {
173
- _iterator3.f();
224
+ _iterator4.f();
174
225
  }
175
226
  }
176
227
 
@@ -180,31 +231,72 @@ export function findFastestAvailableResource(_ref2) {
180
231
  } finally {
181
232
  _iterator2.f();
182
233
  }
183
- if (!fastestTime || fastestResources.length === 0) return null;
234
+ if (!fastestTime || fastestResources.length === 0) {
235
+ console.log('[TimeslotUtils] 未找到可用资源');
236
+ return null;
237
+ }
238
+ console.log("[TimeslotUtils] \u627E\u5230 ".concat(fastestResources.length, " \u4E2A\u6700\u5FEB\u53EF\u7528\u8D44\u6E90\uFF0C\u65F6\u95F4: ").concat(fastestTime.format('HH:mm:ss')));
184
239
 
185
240
  // 如果只有一个最快可用的资源,直接返回
186
- if (fastestResources.length === 1) return fastestResources[0];
241
+ if (fastestResources.length === 1) {
242
+ console.log("[TimeslotUtils] \u8FD4\u56DE\u552F\u4E00\u6700\u5FEB\u8D44\u6E90: ".concat(fastestResources[0].main_field));
243
+ return fastestResources[0];
244
+ }
187
245
 
188
- // 如果有多个最快可用的资源,比较它们的空闲时间
246
+ // 如果有多个最快可用的资源,选择空闲时间最长的资源
247
+ var selectedResource = fastestResources[0];
189
248
  var maxIdleTime = 0;
190
- var selectedResource = null;
249
+ console.log("[TimeslotUtils] \u6BD4\u8F83 ".concat(fastestResources.length, " \u4E2A\u8D44\u6E90\u7684\u7A7A\u95F2\u65F6\u95F4:"));
191
250
  for (var _i2 = 0, _fastestResources = fastestResources; _i2 < _fastestResources.length; _i2++) {
251
+ var _workingTime$event_li;
192
252
  var resource = _fastestResources[_i2];
193
- var idleTime = calculateResourceAvailableTime({
194
- resource: resource,
195
- timeSlots: {
196
- start_time: fastestTime.format('HH:mm'),
197
- end_time: fastestTime.format('HH:mm'),
198
- start_at: fastestTime,
199
- end_at: fastestTime
200
- },
201
- currentCapacity: (countMap[resource.id] || 0) + currentCapacity
253
+ // 找到该资源当天且还在工作的时间段
254
+ var workingTime = resource.times.find(function (time) {
255
+ var isToday = dayjs(time.start_at).isSame(fastestTime, 'day');
256
+ var isStillWorking = dayjs(time.end_at).isAfter(fastestTime);
257
+ return isToday && isStillWorking;
258
+ });
259
+ if (!workingTime) continue;
260
+ var workEndTime = dayjs(workingTime.end_at);
261
+
262
+ // 计算从最快可用时间到工作结束时间的空闲时长(分钟)
263
+ var totalIdleTime = workEndTime.diff(fastestTime, 'minute');
264
+
265
+ // 减去已有预约占用的时间
266
+ var relevantEvents = ((_workingTime$event_li = workingTime.event_list) === null || _workingTime$event_li === void 0 ? void 0 : _workingTime$event_li.filter(function (event) {
267
+ var eventStart = dayjs(event.start_at);
268
+ var eventEnd = dayjs(event.end_at);
269
+ // 只计算在最快可用时间之后的预约
270
+ return eventEnd.isAfter(fastestTime) && eventStart.isAfter(fastestTime);
271
+ })) || [];
272
+ var _iterator3 = _createForOfIteratorHelper(relevantEvents),
273
+ _step3;
274
+ try {
275
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
276
+ var event = _step3.value;
277
+ var eventStart = dayjs(event.start_at);
278
+ var eventEnd = dayjs(event.end_at);
279
+ var eventDuration = eventEnd.diff(eventStart, 'minute');
280
+ totalIdleTime -= eventDuration;
281
+ }
282
+ } catch (err) {
283
+ _iterator3.e(err);
284
+ } finally {
285
+ _iterator3.f();
286
+ }
287
+ console.log("[TimeslotUtils] \u8D44\u6E90 ".concat(resource.id, "(").concat(resource.main_field, "):"), {
288
+ 工作结束时间: workEndTime.format('HH:mm'),
289
+ 总工作时长: workEndTime.diff(fastestTime, 'minute') + '分钟',
290
+ 预约占用时长: workEndTime.diff(fastestTime, 'minute') - totalIdleTime + '分钟',
291
+ 实际空闲时长: totalIdleTime + '分钟'
202
292
  });
203
- if (idleTime > maxIdleTime) {
204
- maxIdleTime = idleTime;
293
+ if (totalIdleTime > maxIdleTime) {
294
+ maxIdleTime = totalIdleTime;
205
295
  selectedResource = resource;
296
+ console.log("[TimeslotUtils] \u66F4\u65B0\u6700\u4F73\u9009\u62E9: ".concat(resource.main_field, " (\u7A7A\u95F2").concat(totalIdleTime, "\u5206\u949F)"));
206
297
  }
207
298
  }
299
+ console.log("[TimeslotUtils] \u6700\u7EC8\u9009\u62E9\u8D44\u6E90: ".concat(selectedResource.main_field, " (\u6700\u957F\u7A7A\u95F2").concat(maxIdleTime, "\u5206\u949F)"));
208
300
  return selectedResource;
209
301
  }
210
302
 
@@ -40,6 +40,9 @@ export declare class CheckoutImpl extends BaseModule implements Module, Checkout
40
40
  quantity: number;
41
41
  selling_price: number;
42
42
  }[];
43
+ initWalletData(params?: {
44
+ order_wait_pay_amount: number;
45
+ }): Promise<void>;
43
46
  /**
44
47
  * 创建本地订单 (前端模拟下单流程)
45
48
  *