@pisell/pisellos 2.2.135 → 2.2.137
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/modules/Order/index.d.ts +3 -1
- package/dist/modules/Order/index.js +98 -15
- package/dist/modules/Order/types.d.ts +25 -0
- package/dist/modules/Order/types.js +8 -0
- package/dist/modules/Product/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +1 -1
- package/dist/solution/Sales/index.d.ts +10 -1
- package/dist/solution/Sales/index.js +273 -59
- package/dist/solution/Sales/types.d.ts +20 -0
- package/lib/model/strategy/adapter/promotion/index.js +0 -49
- package/lib/modules/Order/index.d.ts +3 -1
- package/lib/modules/Order/index.js +36 -0
- package/lib/modules/Order/types.d.ts +25 -0
- package/lib/modules/Product/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +1 -1
- package/lib/solution/Sales/index.d.ts +10 -1
- package/lib/solution/Sales/index.js +141 -8
- package/lib/solution/Sales/types.d.ts +20 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Module, PisellCore, ModuleOptions } from '../../types';
|
|
2
2
|
import { BaseModule } from '../BaseModule';
|
|
3
|
-
import { OrderModuleAPI, CommitOrderParams, CheckoutOrderParams } from './types';
|
|
3
|
+
import { OrderModuleAPI, CommitOrderParams, CheckoutOrderParams, CancelOrderParams, ChangeBookingStatusParams } from './types';
|
|
4
4
|
import { CartItem } from '../Cart/types';
|
|
5
5
|
export declare class OrderModule extends BaseModule implements Module, OrderModuleAPI {
|
|
6
6
|
protected defaultName: string;
|
|
@@ -39,6 +39,8 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
39
39
|
type: 'holder' | 'account';
|
|
40
40
|
}): boolean;
|
|
41
41
|
submitOrder(order: CommitOrderParams): Promise<void>;
|
|
42
|
+
cancelOrder(params: CancelOrderParams): Promise<any>;
|
|
43
|
+
changeBookingStatus(params: ChangeBookingStatusParams): Promise<any>;
|
|
42
44
|
/**
|
|
43
45
|
* Checkout 专用:创建订单到后端
|
|
44
46
|
*
|
|
@@ -238,6 +238,89 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
238
238
|
}
|
|
239
239
|
return submitOrder;
|
|
240
240
|
}()
|
|
241
|
+
}, {
|
|
242
|
+
key: "cancelOrder",
|
|
243
|
+
value: function () {
|
|
244
|
+
var _cancelOrder = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(params) {
|
|
245
|
+
var payload;
|
|
246
|
+
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
|
|
247
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
248
|
+
case 0:
|
|
249
|
+
if (!(!Array.isArray(params.order_ids) || params.order_ids.length === 0)) {
|
|
250
|
+
_context3.next = 2;
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
throw new Error('取消订单失败:order_ids 不能为空');
|
|
254
|
+
case 2:
|
|
255
|
+
payload = {
|
|
256
|
+
order_ids: params.order_ids,
|
|
257
|
+
status: 'cancelled',
|
|
258
|
+
change_schedule_event_appointment_status: 1,
|
|
259
|
+
is_void: 1
|
|
260
|
+
};
|
|
261
|
+
this.logInfo('cancelOrder called', {
|
|
262
|
+
url: '/order/update-status',
|
|
263
|
+
method: 'PUT',
|
|
264
|
+
orderIdsCount: params.order_ids.length
|
|
265
|
+
});
|
|
266
|
+
return _context3.abrupt("return", this.request.put('/order/update-status', payload, {
|
|
267
|
+
isShopApi: true
|
|
268
|
+
}));
|
|
269
|
+
case 5:
|
|
270
|
+
case "end":
|
|
271
|
+
return _context3.stop();
|
|
272
|
+
}
|
|
273
|
+
}, _callee3, this);
|
|
274
|
+
}));
|
|
275
|
+
function cancelOrder(_x4) {
|
|
276
|
+
return _cancelOrder.apply(this, arguments);
|
|
277
|
+
}
|
|
278
|
+
return cancelOrder;
|
|
279
|
+
}()
|
|
280
|
+
}, {
|
|
281
|
+
key: "changeBookingStatus",
|
|
282
|
+
value: function () {
|
|
283
|
+
var _changeBookingStatus = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(params) {
|
|
284
|
+
var url, payload;
|
|
285
|
+
return _regeneratorRuntime().wrap(function _callee4$(_context4) {
|
|
286
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
287
|
+
case 0:
|
|
288
|
+
if (params.booking_id) {
|
|
289
|
+
_context4.next = 2;
|
|
290
|
+
break;
|
|
291
|
+
}
|
|
292
|
+
throw new Error('变更预约状态失败:booking_id 不能为空');
|
|
293
|
+
case 2:
|
|
294
|
+
if (params.appointment_status) {
|
|
295
|
+
_context4.next = 4;
|
|
296
|
+
break;
|
|
297
|
+
}
|
|
298
|
+
throw new Error('变更预约状态失败:appointment_status 不能为空');
|
|
299
|
+
case 4:
|
|
300
|
+
url = "/schedule/booking/appointment-status/".concat(params.booking_id);
|
|
301
|
+
payload = {
|
|
302
|
+
appointment_status: params.appointment_status
|
|
303
|
+
};
|
|
304
|
+
this.logInfo('changeBookingStatus called', {
|
|
305
|
+
url: url,
|
|
306
|
+
method: 'PUT',
|
|
307
|
+
bookingId: params.booking_id,
|
|
308
|
+
appointmentStatus: params.appointment_status
|
|
309
|
+
});
|
|
310
|
+
return _context4.abrupt("return", this.request.put(url, payload, {
|
|
311
|
+
isShopApi: true
|
|
312
|
+
}));
|
|
313
|
+
case 8:
|
|
314
|
+
case "end":
|
|
315
|
+
return _context4.stop();
|
|
316
|
+
}
|
|
317
|
+
}, _callee4, this);
|
|
318
|
+
}));
|
|
319
|
+
function changeBookingStatus(_x5) {
|
|
320
|
+
return _changeBookingStatus.apply(this, arguments);
|
|
321
|
+
}
|
|
322
|
+
return changeBookingStatus;
|
|
323
|
+
}()
|
|
241
324
|
/**
|
|
242
325
|
* Checkout 专用:创建订单到后端
|
|
243
326
|
*
|
|
@@ -251,11 +334,11 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
251
334
|
}, {
|
|
252
335
|
key: "createOrderByCheckout",
|
|
253
336
|
value: (function () {
|
|
254
|
-
var _createOrderByCheckout = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function
|
|
337
|
+
var _createOrderByCheckout = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(params) {
|
|
255
338
|
var _params$payments, _params$bookings2, _params$relation_prod2, _params$payments2, _params$payments3, _params$bookings3, _params$relation_prod3, _params$payments4;
|
|
256
339
|
var onlineStorePaymentCodeList, _orderData$payments, _orderData$bookings, _orderData$relation_p, _orderData$payments2, _orderData$payments3, _orderData$bookings2, _orderData$relation_p2, _orderData$payments4, _orderData$payments5, _response$data, orderData, response;
|
|
257
|
-
return _regeneratorRuntime().wrap(function
|
|
258
|
-
while (1) switch (
|
|
340
|
+
return _regeneratorRuntime().wrap(function _callee5$(_context5) {
|
|
341
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
259
342
|
case 0:
|
|
260
343
|
// 过滤掉由在线店铺下单的 payment 支付数据
|
|
261
344
|
onlineStorePaymentCodeList = ['WXPAY', 'WECHAT', 'ALIPAY', 'APPLE_PAY', 'CREDIT_CARD_3DS', 'CREDIT_CARD_TOKEN', 'GOOGLE_PAY', 'GOOGLE_PAY_3DS', 'CREDIT_CARD'];
|
|
@@ -289,7 +372,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
289
372
|
relationProductsCount: ((_params$relation_prod3 = params.relation_products) === null || _params$relation_prod3 === void 0 ? void 0 : _params$relation_prod3.length) || 0,
|
|
290
373
|
paymentsCount: ((_params$payments4 = params.payments) === null || _params$payments4 === void 0 ? void 0 : _params$payments4.length) || 0
|
|
291
374
|
});
|
|
292
|
-
|
|
375
|
+
_context5.prev = 4;
|
|
293
376
|
// 构建订单数据,设置默认值并允许 params 覆盖
|
|
294
377
|
orderData = _objectSpread({
|
|
295
378
|
sales_channel: 'my_pisel',
|
|
@@ -353,10 +436,10 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
353
436
|
});
|
|
354
437
|
|
|
355
438
|
// 调用后端接口
|
|
356
|
-
|
|
439
|
+
_context5.next = 12;
|
|
357
440
|
return this.request.post('/order/checkout', orderData);
|
|
358
441
|
case 12:
|
|
359
|
-
response =
|
|
442
|
+
response = _context5.sent;
|
|
360
443
|
this.logInfo('Order API called successfully', {
|
|
361
444
|
response: response
|
|
362
445
|
});
|
|
@@ -364,22 +447,22 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
364
447
|
success: !!response,
|
|
365
448
|
hasOrderId: !!(response !== null && response !== void 0 && (_response$data = response.data) !== null && _response$data !== void 0 && _response$data.order_id || response !== null && response !== void 0 && response.order_id)
|
|
366
449
|
});
|
|
367
|
-
return
|
|
450
|
+
return _context5.abrupt("return", response);
|
|
368
451
|
case 18:
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
console.error('[Order] createOrderByCheckout 创建订单失败:',
|
|
452
|
+
_context5.prev = 18;
|
|
453
|
+
_context5.t0 = _context5["catch"](4);
|
|
454
|
+
console.error('[Order] createOrderByCheckout 创建订单失败:', _context5.t0);
|
|
372
455
|
this.logInfo('Order API called failed', {
|
|
373
|
-
error:
|
|
456
|
+
error: _context5.t0 instanceof Error ? _context5.t0.message : String(_context5.t0)
|
|
374
457
|
});
|
|
375
|
-
throw
|
|
458
|
+
throw _context5.t0;
|
|
376
459
|
case 23:
|
|
377
460
|
case "end":
|
|
378
|
-
return
|
|
461
|
+
return _context5.stop();
|
|
379
462
|
}
|
|
380
|
-
},
|
|
463
|
+
}, _callee5, this, [[4, 18]]);
|
|
381
464
|
}));
|
|
382
|
-
function createOrderByCheckout(
|
|
465
|
+
function createOrderByCheckout(_x6) {
|
|
383
466
|
return _createOrderByCheckout.apply(this, arguments);
|
|
384
467
|
}
|
|
385
468
|
return createOrderByCheckout;
|
|
@@ -58,6 +58,19 @@ export interface CheckoutOrderParams {
|
|
|
58
58
|
small_ticket_data_flag?: number;
|
|
59
59
|
[key: string]: any;
|
|
60
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* 取消订单参数
|
|
63
|
+
*/
|
|
64
|
+
export interface CancelOrderParams {
|
|
65
|
+
order_ids: Array<number | string>;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* 变更预约状态参数
|
|
69
|
+
*/
|
|
70
|
+
export interface ChangeBookingStatusParams {
|
|
71
|
+
booking_id: number | string;
|
|
72
|
+
appointment_status: string;
|
|
73
|
+
}
|
|
61
74
|
/**
|
|
62
75
|
* 订单模块 API
|
|
63
76
|
*/
|
|
@@ -86,4 +99,16 @@ export interface OrderModuleAPI {
|
|
|
86
99
|
* @returns 后端返回的订单数据
|
|
87
100
|
*/
|
|
88
101
|
createOrderByCheckout: (params: CheckoutOrderParams) => Promise<any>;
|
|
102
|
+
/**
|
|
103
|
+
* 取消订单
|
|
104
|
+
* @param params 取消订单参数
|
|
105
|
+
* @returns 后端返回结果
|
|
106
|
+
*/
|
|
107
|
+
cancelOrder: (params: CancelOrderParams) => Promise<any>;
|
|
108
|
+
/**
|
|
109
|
+
* 变更预约状态
|
|
110
|
+
* @param params 预约状态参数
|
|
111
|
+
* @returns 后端返回结果
|
|
112
|
+
*/
|
|
113
|
+
changeBookingStatus: (params: ChangeBookingStatusParams) => Promise<any>;
|
|
89
114
|
}
|
|
@@ -49,5 +49,5 @@ export declare class Product extends BaseModule implements Module {
|
|
|
49
49
|
getCategories(): ProductCategory[];
|
|
50
50
|
setOtherParams(key: string, value: any): void;
|
|
51
51
|
getOtherParams(): any;
|
|
52
|
-
getProductType(): "
|
|
52
|
+
getProductType(): "normal" | "duration" | "session";
|
|
53
53
|
}
|
|
@@ -136,7 +136,7 @@ export declare class BookingTicketImpl extends BaseModule implements Module {
|
|
|
136
136
|
* 获取当前的客户搜索条件
|
|
137
137
|
* @returns 当前搜索条件
|
|
138
138
|
*/
|
|
139
|
-
getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "
|
|
139
|
+
getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
|
|
140
140
|
/**
|
|
141
141
|
* 获取客户列表状态(包含滚动加载相关状态)
|
|
142
142
|
* @returns 客户状态
|
|
@@ -2,7 +2,7 @@ import dayjs from 'dayjs';
|
|
|
2
2
|
import { Module, ModuleOptions, PisellCore } from '../../types';
|
|
3
3
|
import { BaseModule } from '../../modules/BaseModule';
|
|
4
4
|
import type { RequestPlugin } from '../../plugins/request';
|
|
5
|
-
import { SalesState, SalesModuleAPI, Reservation, SalesResourceBookingItem, SalesTimelineHighlights } from './types';
|
|
5
|
+
import { SalesState, SalesModuleAPI, Reservation, SalesResourceBookingItem, SalesResourceBookingItemWithGroups, SalesTimelineHighlights, ChangeBookingStatusParams, GetResourceBookingItemParams } from './types';
|
|
6
6
|
import type { BookingData } from '../../server/modules/order/types';
|
|
7
7
|
export * from './types';
|
|
8
8
|
/**
|
|
@@ -39,6 +39,8 @@ export declare class SalesImpl extends BaseModule implements Module, SalesModule
|
|
|
39
39
|
setReservationList(reservationList: Reservation[]): Reservation[];
|
|
40
40
|
/** 重置预约列表为空 */
|
|
41
41
|
resetReservationList(): Reservation[];
|
|
42
|
+
cancelOrder(orderIds: Array<number | string>): Promise<any>;
|
|
43
|
+
changeBookingStatus(params: ChangeBookingStatusParams): Promise<any>;
|
|
42
44
|
destroy(): Promise<void>;
|
|
43
45
|
/**
|
|
44
46
|
* 时间轴粒度(分钟)
|
|
@@ -77,6 +79,10 @@ export declare class SalesImpl extends BaseModule implements Module, SalesModule
|
|
|
77
79
|
*/
|
|
78
80
|
private getBookingStatus;
|
|
79
81
|
private getResourceId;
|
|
82
|
+
private getBookingAppointmentStatus;
|
|
83
|
+
private getBookingOrderPaymentStatus;
|
|
84
|
+
private isBookingMatchedResource;
|
|
85
|
+
private sortMatchedBookings;
|
|
80
86
|
/**
|
|
81
87
|
* 资源下 bookings 的返回裁剪策略:
|
|
82
88
|
* 1) 优先返回当前时刻正在进行中的预约(允许并发返回多条)
|
|
@@ -98,6 +104,8 @@ export declare class SalesImpl extends BaseModule implements Module, SalesModule
|
|
|
98
104
|
* - 否则走快照分支(纯时间窗判定,忽略 appointment_status 的 arrived/started/completed 差异)
|
|
99
105
|
*/
|
|
100
106
|
private normalizeMatchedBooking;
|
|
107
|
+
private normalizeResourceBookings;
|
|
108
|
+
private buildCompletedBooking;
|
|
101
109
|
/**
|
|
102
110
|
* 实时模式(current === deviceCurrent):信任 appointment_status
|
|
103
111
|
* - 过滤 new / completed(实时视角下视为非活跃数据)
|
|
@@ -122,6 +130,7 @@ export declare class SalesImpl extends BaseModule implements Module, SalesModule
|
|
|
122
130
|
*/
|
|
123
131
|
private buildSnapshotBooking;
|
|
124
132
|
getResourceBookingList(currentTime: string, bookingList?: BookingData[], deviceTime?: string): Promise<SalesResourceBookingItem[]>;
|
|
133
|
+
getResourceBookingItem(params: GetResourceBookingItemParams): Promise<SalesResourceBookingItemWithGroups | null>;
|
|
125
134
|
}
|
|
126
135
|
export { SalesImpl as Sales };
|
|
127
136
|
export default SalesImpl;
|
|
@@ -161,26 +161,80 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
161
161
|
});
|
|
162
162
|
return [];
|
|
163
163
|
}
|
|
164
|
-
|
|
165
|
-
|
|
164
|
+
}, {
|
|
165
|
+
key: "cancelOrder",
|
|
166
|
+
value: function () {
|
|
167
|
+
var _cancelOrder = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(orderIds) {
|
|
168
|
+
var orderModule;
|
|
169
|
+
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
170
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
171
|
+
case 0:
|
|
172
|
+
orderModule = this.core.getModule('order');
|
|
173
|
+
if (orderModule) {
|
|
174
|
+
_context2.next = 3;
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
throw new Error('Sales 取消订单失败:Order 模块未注册');
|
|
178
|
+
case 3:
|
|
179
|
+
return _context2.abrupt("return", orderModule.cancelOrder({
|
|
180
|
+
order_ids: orderIds
|
|
181
|
+
}));
|
|
182
|
+
case 4:
|
|
183
|
+
case "end":
|
|
184
|
+
return _context2.stop();
|
|
185
|
+
}
|
|
186
|
+
}, _callee2, this);
|
|
187
|
+
}));
|
|
188
|
+
function cancelOrder(_x2) {
|
|
189
|
+
return _cancelOrder.apply(this, arguments);
|
|
190
|
+
}
|
|
191
|
+
return cancelOrder;
|
|
192
|
+
}()
|
|
193
|
+
}, {
|
|
194
|
+
key: "changeBookingStatus",
|
|
195
|
+
value: function () {
|
|
196
|
+
var _changeBookingStatus = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(params) {
|
|
197
|
+
var orderModule;
|
|
198
|
+
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
|
|
199
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
200
|
+
case 0:
|
|
201
|
+
orderModule = this.core.getModule('order');
|
|
202
|
+
if (orderModule) {
|
|
203
|
+
_context3.next = 3;
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
throw new Error('Sales 变更预约状态失败:Order 模块未注册');
|
|
207
|
+
case 3:
|
|
208
|
+
return _context3.abrupt("return", orderModule.changeBookingStatus(params));
|
|
209
|
+
case 4:
|
|
210
|
+
case "end":
|
|
211
|
+
return _context3.stop();
|
|
212
|
+
}
|
|
213
|
+
}, _callee3, this);
|
|
214
|
+
}));
|
|
215
|
+
function changeBookingStatus(_x3) {
|
|
216
|
+
return _changeBookingStatus.apply(this, arguments);
|
|
217
|
+
}
|
|
218
|
+
return changeBookingStatus;
|
|
219
|
+
}() // -------------------------------------------------------------------------
|
|
166
220
|
// 生命周期
|
|
167
221
|
// -------------------------------------------------------------------------
|
|
168
222
|
}, {
|
|
169
223
|
key: "destroy",
|
|
170
224
|
value: function () {
|
|
171
|
-
var _destroy = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function
|
|
172
|
-
return _regeneratorRuntime().wrap(function
|
|
173
|
-
while (1) switch (
|
|
225
|
+
var _destroy = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4() {
|
|
226
|
+
return _regeneratorRuntime().wrap(function _callee4$(_context4) {
|
|
227
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
174
228
|
case 0:
|
|
175
|
-
|
|
229
|
+
_context4.next = 2;
|
|
176
230
|
return this.core.effects.emit("".concat(this.name, ":onDestroy"), {});
|
|
177
231
|
case 2:
|
|
178
232
|
_get(_getPrototypeOf(SalesImpl.prototype), "destroy", this).call(this);
|
|
179
233
|
case 3:
|
|
180
234
|
case "end":
|
|
181
|
-
return
|
|
235
|
+
return _context4.stop();
|
|
182
236
|
}
|
|
183
|
-
},
|
|
237
|
+
}, _callee4, this);
|
|
184
238
|
}));
|
|
185
239
|
function destroy() {
|
|
186
240
|
return _destroy.apply(this, arguments);
|
|
@@ -342,6 +396,38 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
342
396
|
var _ref3, _resource$id;
|
|
343
397
|
return (_ref3 = (_resource$id = resource.id) !== null && _resource$id !== void 0 ? _resource$id : resource.form_record_id) !== null && _ref3 !== void 0 ? _ref3 : '';
|
|
344
398
|
}
|
|
399
|
+
}, {
|
|
400
|
+
key: "getBookingAppointmentStatus",
|
|
401
|
+
value: function getBookingAppointmentStatus(booking) {
|
|
402
|
+
var _ref4, _booking$appointment_2;
|
|
403
|
+
return String((_ref4 = (_booking$appointment_2 = booking.appointment_status) !== null && _booking$appointment_2 !== void 0 ? _booking$appointment_2 : booking.status) !== null && _ref4 !== void 0 ? _ref4 : '');
|
|
404
|
+
}
|
|
405
|
+
}, {
|
|
406
|
+
key: "getBookingOrderPaymentStatus",
|
|
407
|
+
value: function getBookingOrderPaymentStatus(booking) {
|
|
408
|
+
var _booking$order$paymen, _booking$order;
|
|
409
|
+
return String((_booking$order$paymen = (_booking$order = booking.order) === null || _booking$order === void 0 ? void 0 : _booking$order.payment_status) !== null && _booking$order$paymen !== void 0 ? _booking$order$paymen : '');
|
|
410
|
+
}
|
|
411
|
+
}, {
|
|
412
|
+
key: "isBookingMatchedResource",
|
|
413
|
+
value: function isBookingMatchedResource(booking, resourceId) {
|
|
414
|
+
if (!Array.isArray(booking.resources)) return false;
|
|
415
|
+
return booking.resources.some(function (resource) {
|
|
416
|
+
var relationId = resource === null || resource === void 0 ? void 0 : resource.relation_id;
|
|
417
|
+
if (relationId === undefined || relationId === null) return false;
|
|
418
|
+
return String(relationId) === String(resourceId);
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
}, {
|
|
422
|
+
key: "sortMatchedBookings",
|
|
423
|
+
value: function sortMatchedBookings(bookings) {
|
|
424
|
+
var _this2 = this;
|
|
425
|
+
return _toConsumableArray(bookings).sort(function (left, right) {
|
|
426
|
+
var leftStartAt = _this2.toBookingDateTime(left.start_date, left.start_time).valueOf();
|
|
427
|
+
var rightStartAt = _this2.toBookingDateTime(right.start_date, right.start_time).valueOf();
|
|
428
|
+
return leftStartAt - rightStartAt;
|
|
429
|
+
});
|
|
430
|
+
}
|
|
345
431
|
|
|
346
432
|
/**
|
|
347
433
|
* 资源下 bookings 的返回裁剪策略:
|
|
@@ -353,17 +439,17 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
353
439
|
}, {
|
|
354
440
|
key: "pickBookingsForCurrentPoint",
|
|
355
441
|
value: function pickBookingsForCurrentPoint(current, bookings) {
|
|
356
|
-
var
|
|
442
|
+
var _this3 = this;
|
|
357
443
|
if (bookings.length === 0) return [];
|
|
358
444
|
var currentDayStart = current.startOf('day');
|
|
359
445
|
var currentDayEnd = current.endOf('day');
|
|
360
446
|
|
|
361
447
|
// 仅保留与 current 当天有时间交集的预约,避免跨天误命中
|
|
362
448
|
var dayScopedBookings = bookings.filter(function (booking) {
|
|
363
|
-
var startAt =
|
|
364
|
-
var endAt =
|
|
449
|
+
var startAt = _this3.toBookingDateTime(booking.start_date, booking.start_time);
|
|
450
|
+
var endAt = _this3.toBookingDateTime(booking.end_date, booking.end_time);
|
|
365
451
|
if (!startAt.isValid() || !endAt.isValid()) return false;
|
|
366
|
-
return
|
|
452
|
+
return _this3.isSameOrBefore(startAt, currentDayEnd) && _this3.isSameOrAfter(endAt, currentDayStart);
|
|
367
453
|
});
|
|
368
454
|
if (dayScopedBookings.length === 0) return [];
|
|
369
455
|
var appendNextStartGroupIfNeeded = function appendNextStartGroupIfNeeded(selectedBookings) {
|
|
@@ -373,21 +459,21 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
373
459
|
});
|
|
374
460
|
if (!shouldAppendNextGroup) return selectedBookings;
|
|
375
461
|
var selectedStartValues = new Set(selectedBookings.map(function (booking) {
|
|
376
|
-
return
|
|
462
|
+
return _this3.toBookingDateTime(booking.start_date, booking.start_time);
|
|
377
463
|
}).filter(function (startAt) {
|
|
378
464
|
return startAt.isValid();
|
|
379
465
|
}).map(function (startAt) {
|
|
380
466
|
return startAt.valueOf();
|
|
381
467
|
}));
|
|
382
468
|
var futureCandidates = dayScopedBookings.filter(function (booking) {
|
|
383
|
-
var startAt =
|
|
469
|
+
var startAt = _this3.toBookingDateTime(booking.start_date, booking.start_time);
|
|
384
470
|
if (!startAt.isValid()) return false;
|
|
385
471
|
return startAt.isAfter(current) && !selectedStartValues.has(startAt.valueOf());
|
|
386
472
|
});
|
|
387
473
|
if (futureCandidates.length === 0) return selectedBookings;
|
|
388
|
-
var nextStartAt =
|
|
474
|
+
var nextStartAt = _this3.toBookingDateTime(futureCandidates[0].start_date, futureCandidates[0].start_time).valueOf();
|
|
389
475
|
var nextStartGroup = futureCandidates.filter(function (booking) {
|
|
390
|
-
var startAt =
|
|
476
|
+
var startAt = _this3.toBookingDateTime(booking.start_date, booking.start_time);
|
|
391
477
|
return startAt.isValid() && startAt.valueOf() === nextStartAt;
|
|
392
478
|
});
|
|
393
479
|
if (nextStartGroup.length === 0) return selectedBookings;
|
|
@@ -399,10 +485,10 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
399
485
|
|
|
400
486
|
// active: current 处于 [startAt, endAt] 区间
|
|
401
487
|
var activeBookings = dayScopedBookings.filter(function (booking) {
|
|
402
|
-
var startAt =
|
|
403
|
-
var endAt =
|
|
488
|
+
var startAt = _this3.toBookingDateTime(booking.start_date, booking.start_time);
|
|
489
|
+
var endAt = _this3.toBookingDateTime(booking.end_date, booking.end_time);
|
|
404
490
|
if (!startAt.isValid() || !endAt.isValid()) return false;
|
|
405
|
-
return
|
|
491
|
+
return _this3.isSameOrAfter(current, startAt) && _this3.isSameOrBefore(current, endAt);
|
|
406
492
|
});
|
|
407
493
|
if (activeBookings.length > 0) return appendNextStartGroupIfNeeded(activeBookings);
|
|
408
494
|
|
|
@@ -414,13 +500,13 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
414
500
|
|
|
415
501
|
// upcoming: 从未来预约里只取最早那一组(同 start_time)
|
|
416
502
|
var upcoming = dayScopedBookings.filter(function (booking) {
|
|
417
|
-
var startAt =
|
|
503
|
+
var startAt = _this3.toBookingDateTime(booking.start_date, booking.start_time);
|
|
418
504
|
return startAt.isValid() && startAt.isAfter(current) && startAt.isSame(current, 'day');
|
|
419
505
|
});
|
|
420
506
|
if (upcoming.length > 0) {
|
|
421
507
|
var firstStartAt = this.toBookingDateTime(upcoming[0].start_date, upcoming[0].start_time).valueOf();
|
|
422
508
|
var upcomingStartGroup = upcoming.filter(function (booking) {
|
|
423
|
-
var startAt =
|
|
509
|
+
var startAt = _this3.toBookingDateTime(booking.start_date, booking.start_time);
|
|
424
510
|
return startAt.valueOf() === firstStartAt;
|
|
425
511
|
});
|
|
426
512
|
return appendNextStartGroupIfNeeded(upcomingStartGroup);
|
|
@@ -457,16 +543,58 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
457
543
|
}, {
|
|
458
544
|
key: "normalizeMatchedBooking",
|
|
459
545
|
value: function normalizeMatchedBooking(current, deviceCurrent, booking) {
|
|
460
|
-
var
|
|
461
|
-
var appointmentStatus =
|
|
546
|
+
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
547
|
+
var appointmentStatus = this.getBookingAppointmentStatus(booking);
|
|
462
548
|
if (appointmentStatus === 'rejected' || appointmentStatus === 'cancelled') return null;
|
|
463
549
|
var startAt = this.toBookingDateTime(booking.start_date, booking.start_time);
|
|
464
550
|
var endAt = this.toBookingDateTime(booking.end_date, booking.end_time);
|
|
551
|
+
if (appointmentStatus === 'completed' && options.includeCompleted) {
|
|
552
|
+
return this.buildCompletedBooking(current, booking, startAt, endAt);
|
|
553
|
+
}
|
|
465
554
|
if (current.isSame(deviceCurrent)) {
|
|
466
555
|
return this.buildRealtimeBooking(current, booking, appointmentStatus, startAt, endAt);
|
|
467
556
|
}
|
|
468
557
|
return this.buildSnapshotBooking(current, booking, appointmentStatus, startAt, endAt);
|
|
469
558
|
}
|
|
559
|
+
}, {
|
|
560
|
+
key: "normalizeResourceBookings",
|
|
561
|
+
value: function normalizeResourceBookings(current, deviceCurrent, bookingList) {
|
|
562
|
+
var _this4 = this;
|
|
563
|
+
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
564
|
+
var normalizedBookings = bookingList.map(function (booking) {
|
|
565
|
+
return _this4.normalizeMatchedBooking(current, deviceCurrent, booking, options);
|
|
566
|
+
}).filter(function (booking) {
|
|
567
|
+
return Boolean(booking);
|
|
568
|
+
}).filter(function (booking) {
|
|
569
|
+
return booking.status;
|
|
570
|
+
});
|
|
571
|
+
return this.sortMatchedBookings(normalizedBookings);
|
|
572
|
+
}
|
|
573
|
+
}, {
|
|
574
|
+
key: "buildCompletedBooking",
|
|
575
|
+
value: function buildCompletedBooking(current, booking, startAt, endAt) {
|
|
576
|
+
if (!startAt.isValid() || !endAt.isValid()) return null;
|
|
577
|
+
if (current.isBefore(startAt)) {
|
|
578
|
+
return _objectSpread(_objectSpread({}, booking), {}, {
|
|
579
|
+
status: 'reserved',
|
|
580
|
+
isTimeout: false,
|
|
581
|
+
timeoutTime: undefined,
|
|
582
|
+
progressPercent: 0,
|
|
583
|
+
lateTime: undefined,
|
|
584
|
+
reserved_status: 'not_arrived',
|
|
585
|
+
remainingReserveTime: Math.max(startAt.diff(current, 'minute'), 0)
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
return _objectSpread(_objectSpread({}, booking), {}, {
|
|
589
|
+
status: 'occupied',
|
|
590
|
+
isTimeout: false,
|
|
591
|
+
timeoutTime: undefined,
|
|
592
|
+
progressPercent: this.isSameOrAfter(current, endAt) ? 100 : this.calcProgressPercent(current, startAt, endAt),
|
|
593
|
+
lateTime: undefined,
|
|
594
|
+
reserved_status: undefined,
|
|
595
|
+
remainingReserveTime: undefined
|
|
596
|
+
});
|
|
597
|
+
}
|
|
470
598
|
|
|
471
599
|
/**
|
|
472
600
|
* 实时模式(current === deviceCurrent):信任 appointment_status
|
|
@@ -561,10 +689,10 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
561
689
|
}, {
|
|
562
690
|
key: "getResourceBookingList",
|
|
563
691
|
value: function () {
|
|
564
|
-
var _getResourceBookingList = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function
|
|
692
|
+
var _getResourceBookingList = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(currentTime) {
|
|
565
693
|
var _resourceResponse$dat,
|
|
566
694
|
_resourceResponse$dat2,
|
|
567
|
-
|
|
695
|
+
_this5 = this;
|
|
568
696
|
var bookingList,
|
|
569
697
|
deviceTime,
|
|
570
698
|
current,
|
|
@@ -574,28 +702,28 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
574
702
|
normalizedBookings,
|
|
575
703
|
bookingMap,
|
|
576
704
|
list,
|
|
577
|
-
|
|
578
|
-
return _regeneratorRuntime().wrap(function
|
|
579
|
-
while (1) switch (
|
|
705
|
+
_args5 = arguments;
|
|
706
|
+
return _regeneratorRuntime().wrap(function _callee5$(_context5) {
|
|
707
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
580
708
|
case 0:
|
|
581
|
-
bookingList =
|
|
582
|
-
deviceTime =
|
|
709
|
+
bookingList = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : [];
|
|
710
|
+
deviceTime = _args5.length > 2 && _args5[2] !== undefined ? _args5[2] : currentTime;
|
|
583
711
|
// currentTime 约定为完整 datetime;非法值直接返回空,避免误判
|
|
584
712
|
current = dayjs(currentTime);
|
|
585
713
|
if (current.isValid()) {
|
|
586
|
-
|
|
714
|
+
_context5.next = 5;
|
|
587
715
|
break;
|
|
588
716
|
}
|
|
589
|
-
return
|
|
717
|
+
return _context5.abrupt("return", []);
|
|
590
718
|
case 5:
|
|
591
719
|
deviceCurrent = dayjs(deviceTime);
|
|
592
720
|
if (deviceCurrent.isValid()) {
|
|
593
|
-
|
|
721
|
+
_context5.next = 8;
|
|
594
722
|
break;
|
|
595
723
|
}
|
|
596
|
-
return
|
|
724
|
+
return _context5.abrupt("return", []);
|
|
597
725
|
case 8:
|
|
598
|
-
|
|
726
|
+
_context5.next = 10;
|
|
599
727
|
return this.request.get('/shop/form/resource/page', {
|
|
600
728
|
skip: 1,
|
|
601
729
|
num: 999
|
|
@@ -606,29 +734,16 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
606
734
|
isShopApi: true
|
|
607
735
|
});
|
|
608
736
|
case 10:
|
|
609
|
-
resourceResponse =
|
|
737
|
+
resourceResponse = _context5.sent;
|
|
610
738
|
resourceList = (_resourceResponse$dat = resourceResponse === null || resourceResponse === void 0 || (_resourceResponse$dat2 = resourceResponse.data) === null || _resourceResponse$dat2 === void 0 ? void 0 : _resourceResponse$dat2.list) !== null && _resourceResponse$dat !== void 0 ? _resourceResponse$dat : [];
|
|
611
739
|
if (!(!Array.isArray(resourceList) || resourceList.length === 0)) {
|
|
612
|
-
|
|
740
|
+
_context5.next = 14;
|
|
613
741
|
break;
|
|
614
742
|
}
|
|
615
|
-
return
|
|
743
|
+
return _context5.abrupt("return", []);
|
|
616
744
|
case 14:
|
|
617
745
|
// 全局先做 booking 标准化 + start_time 升序,后续映射直接复用
|
|
618
|
-
normalizedBookings =
|
|
619
|
-
return _this3.normalizeMatchedBooking(current, deviceCurrent, booking);
|
|
620
|
-
}).filter(function (booking) {
|
|
621
|
-
return Boolean(booking);
|
|
622
|
-
}).sort(function (left, right) {
|
|
623
|
-
var leftStartAt = _this3.toBookingDateTime(left.start_date, left.start_time).valueOf();
|
|
624
|
-
var rightStartAt = _this3.toBookingDateTime(right.start_date, right.start_time).valueOf();
|
|
625
|
-
return leftStartAt - rightStartAt;
|
|
626
|
-
}); // 过滤掉没有 status 的 booking
|
|
627
|
-
normalizedBookings = normalizedBookings.filter(function (booking) {
|
|
628
|
-
return booking.status;
|
|
629
|
-
});
|
|
630
|
-
|
|
631
|
-
// 建立 resourceId -> bookings[] 倒排索引,加速资源匹配
|
|
746
|
+
normalizedBookings = this.normalizeResourceBookings(current, deviceCurrent, bookingList); // 建立 resourceId -> bookings[] 倒排索引,加速资源匹配
|
|
632
747
|
bookingMap = new Map();
|
|
633
748
|
normalizedBookings.forEach(function (booking) {
|
|
634
749
|
if (!Array.isArray(booking.resources)) return;
|
|
@@ -644,9 +759,9 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
644
759
|
|
|
645
760
|
// 输出:每个资源都返回;bookings 可能是 0 / 1 / 多条(并发场景)
|
|
646
761
|
list = resourceList.map(function (resource) {
|
|
647
|
-
var resourceId =
|
|
762
|
+
var resourceId = _this5.getResourceId(resource);
|
|
648
763
|
var matchedBookings = bookingMap.get(String(resourceId)) || [];
|
|
649
|
-
var bookings =
|
|
764
|
+
var bookings = _this5.pickBookingsForCurrentPoint(current, matchedBookings);
|
|
650
765
|
return _objectSpread(_objectSpread({}, resource), {}, {
|
|
651
766
|
resource_id: resourceId,
|
|
652
767
|
bookings: bookings
|
|
@@ -662,18 +777,117 @@ export var SalesImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
662
777
|
list: list === null || list === void 0 ? void 0 : list.length
|
|
663
778
|
}
|
|
664
779
|
});
|
|
665
|
-
return
|
|
666
|
-
case
|
|
780
|
+
return _context5.abrupt("return", list);
|
|
781
|
+
case 20:
|
|
667
782
|
case "end":
|
|
668
|
-
return
|
|
783
|
+
return _context5.stop();
|
|
669
784
|
}
|
|
670
|
-
},
|
|
785
|
+
}, _callee5, this);
|
|
671
786
|
}));
|
|
672
|
-
function getResourceBookingList(
|
|
787
|
+
function getResourceBookingList(_x4) {
|
|
673
788
|
return _getResourceBookingList.apply(this, arguments);
|
|
674
789
|
}
|
|
675
790
|
return getResourceBookingList;
|
|
676
791
|
}()
|
|
792
|
+
}, {
|
|
793
|
+
key: "getResourceBookingItem",
|
|
794
|
+
value: function () {
|
|
795
|
+
var _getResourceBookingItem = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(params) {
|
|
796
|
+
var _resourceResponse$dat3,
|
|
797
|
+
_resourceResponse$dat4,
|
|
798
|
+
_this6 = this,
|
|
799
|
+
_params$bookingList;
|
|
800
|
+
var current, deviceCurrent, resourceResponse, resourceList, targetResource, resourceId, matchedBookingList, completedBookingList, unpaidBookingList, bookings, completedBookings, unpaidBookings;
|
|
801
|
+
return _regeneratorRuntime().wrap(function _callee6$(_context6) {
|
|
802
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
803
|
+
case 0:
|
|
804
|
+
current = dayjs(params.currentTime);
|
|
805
|
+
if (current.isValid()) {
|
|
806
|
+
_context6.next = 3;
|
|
807
|
+
break;
|
|
808
|
+
}
|
|
809
|
+
return _context6.abrupt("return", null);
|
|
810
|
+
case 3:
|
|
811
|
+
deviceCurrent = dayjs(params.deviceTime || params.currentTime);
|
|
812
|
+
if (deviceCurrent.isValid()) {
|
|
813
|
+
_context6.next = 6;
|
|
814
|
+
break;
|
|
815
|
+
}
|
|
816
|
+
return _context6.abrupt("return", null);
|
|
817
|
+
case 6:
|
|
818
|
+
_context6.next = 8;
|
|
819
|
+
return this.request.get('/shop/form/resource/page', {
|
|
820
|
+
skip: 1,
|
|
821
|
+
num: 999
|
|
822
|
+
},
|
|
823
|
+
// @ts-ignore
|
|
824
|
+
{
|
|
825
|
+
osServer: true,
|
|
826
|
+
isShopApi: true
|
|
827
|
+
});
|
|
828
|
+
case 8:
|
|
829
|
+
resourceResponse = _context6.sent;
|
|
830
|
+
resourceList = (_resourceResponse$dat3 = resourceResponse === null || resourceResponse === void 0 || (_resourceResponse$dat4 = resourceResponse.data) === null || _resourceResponse$dat4 === void 0 ? void 0 : _resourceResponse$dat4.list) !== null && _resourceResponse$dat3 !== void 0 ? _resourceResponse$dat3 : [];
|
|
831
|
+
if (!(!Array.isArray(resourceList) || resourceList.length === 0)) {
|
|
832
|
+
_context6.next = 12;
|
|
833
|
+
break;
|
|
834
|
+
}
|
|
835
|
+
return _context6.abrupt("return", null);
|
|
836
|
+
case 12:
|
|
837
|
+
targetResource = resourceList.find(function (resource) {
|
|
838
|
+
return String(_this6.getResourceId(resource)) === String(params.resourceId);
|
|
839
|
+
});
|
|
840
|
+
if (targetResource) {
|
|
841
|
+
_context6.next = 15;
|
|
842
|
+
break;
|
|
843
|
+
}
|
|
844
|
+
return _context6.abrupt("return", null);
|
|
845
|
+
case 15:
|
|
846
|
+
resourceId = this.getResourceId(targetResource);
|
|
847
|
+
matchedBookingList = params.bookingList.filter(function (booking) {
|
|
848
|
+
return _this6.isBookingMatchedResource(booking, resourceId);
|
|
849
|
+
});
|
|
850
|
+
completedBookingList = matchedBookingList.filter(function (booking) {
|
|
851
|
+
return _this6.getBookingAppointmentStatus(booking) === 'completed';
|
|
852
|
+
});
|
|
853
|
+
unpaidBookingList = matchedBookingList.filter(function (booking) {
|
|
854
|
+
return _this6.getBookingOrderPaymentStatus(booking) === 'unpaid';
|
|
855
|
+
});
|
|
856
|
+
bookings = this.pickBookingsForCurrentPoint(current, this.normalizeResourceBookings(current, deviceCurrent, matchedBookingList));
|
|
857
|
+
completedBookings = this.pickBookingsForCurrentPoint(current, this.normalizeResourceBookings(current, deviceCurrent, completedBookingList, {
|
|
858
|
+
includeCompleted: true
|
|
859
|
+
}));
|
|
860
|
+
unpaidBookings = this.pickBookingsForCurrentPoint(current, this.normalizeResourceBookings(current, deviceCurrent, unpaidBookingList));
|
|
861
|
+
this.logger.addLog({
|
|
862
|
+
type: 'info',
|
|
863
|
+
title: 'getResourceBookingItem',
|
|
864
|
+
metadata: {
|
|
865
|
+
currentTime: params.currentTime,
|
|
866
|
+
deviceTime: params.deviceTime || params.currentTime,
|
|
867
|
+
resourceId: resourceId,
|
|
868
|
+
bookingList: (_params$bookingList = params.bookingList) === null || _params$bookingList === void 0 ? void 0 : _params$bookingList.length,
|
|
869
|
+
bookings: bookings.length,
|
|
870
|
+
completedBookings: completedBookings.length,
|
|
871
|
+
unpaidBookings: unpaidBookings.length
|
|
872
|
+
}
|
|
873
|
+
});
|
|
874
|
+
return _context6.abrupt("return", _objectSpread(_objectSpread({}, targetResource), {}, {
|
|
875
|
+
resource_id: resourceId,
|
|
876
|
+
bookings: bookings,
|
|
877
|
+
completedBookings: completedBookings,
|
|
878
|
+
unpaidBookings: unpaidBookings
|
|
879
|
+
}));
|
|
880
|
+
case 24:
|
|
881
|
+
case "end":
|
|
882
|
+
return _context6.stop();
|
|
883
|
+
}
|
|
884
|
+
}, _callee6, this);
|
|
885
|
+
}));
|
|
886
|
+
function getResourceBookingItem(_x5) {
|
|
887
|
+
return _getResourceBookingItem.apply(this, arguments);
|
|
888
|
+
}
|
|
889
|
+
return getResourceBookingItem;
|
|
890
|
+
}()
|
|
677
891
|
}]);
|
|
678
892
|
return SalesImpl;
|
|
679
893
|
}(BaseModule);
|
|
@@ -32,7 +32,21 @@ export interface SalesResourceBookingItem extends Omit<ResourceData, 'bookings'>
|
|
|
32
32
|
resource_id: ResourceId;
|
|
33
33
|
bookings: SalesResourceMatchedBooking[];
|
|
34
34
|
}
|
|
35
|
+
export interface SalesResourceBookingItemWithGroups extends SalesResourceBookingItem {
|
|
36
|
+
completedBookings: SalesResourceMatchedBooking[];
|
|
37
|
+
unpaidBookings: SalesResourceMatchedBooking[];
|
|
38
|
+
}
|
|
35
39
|
export type SalesTimelineHighlights = number[];
|
|
40
|
+
export interface ChangeBookingStatusParams {
|
|
41
|
+
booking_id: number | string;
|
|
42
|
+
appointment_status: string;
|
|
43
|
+
}
|
|
44
|
+
export interface GetResourceBookingItemParams {
|
|
45
|
+
resourceId: ResourceId;
|
|
46
|
+
currentTime: string;
|
|
47
|
+
bookingList: BookingData[];
|
|
48
|
+
deviceTime?: string;
|
|
49
|
+
}
|
|
36
50
|
/**
|
|
37
51
|
* Sales 解决方案状态
|
|
38
52
|
*
|
|
@@ -61,8 +75,14 @@ export interface SalesModuleAPI {
|
|
|
61
75
|
setReservationList: (reservationList: Reservation[]) => Reservation[];
|
|
62
76
|
/** 重置预约列表为空 */
|
|
63
77
|
resetReservationList: () => Reservation[];
|
|
78
|
+
/** 取消订单 */
|
|
79
|
+
cancelOrder: (orderIds: Array<number | string>) => Promise<any>;
|
|
80
|
+
/** 变更预约状态 */
|
|
81
|
+
changeBookingStatus: (params: ChangeBookingStatusParams) => Promise<any>;
|
|
64
82
|
/** 获取资源维度的预约占用列表 */
|
|
65
83
|
getResourceBookingList: (currentTime: string, bookingList: BookingData[], deviceTime?: string) => Promise<SalesResourceBookingItem[]>;
|
|
84
|
+
/** 获取单个资源维度的预约占用、已完成、未支付列表 */
|
|
85
|
+
getResourceBookingItem: (params: GetResourceBookingItemParams) => Promise<SalesResourceBookingItemWithGroups | null>;
|
|
66
86
|
/** 获取时间轴每个时间片的预约数量 */
|
|
67
87
|
getTimelineHighlights: (bookingList: BookingData[], startDateTime?: string, endDateTime?: string) => SalesTimelineHighlights;
|
|
68
88
|
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
-
};
|
|
11
|
-
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
-
for (let key of __getOwnPropNames(from))
|
|
14
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
-
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
-
mod
|
|
26
|
-
));
|
|
27
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
-
|
|
29
|
-
// src/model/strategy/adapter/promotion/index.ts
|
|
30
|
-
var promotion_exports = {};
|
|
31
|
-
__export(promotion_exports, {
|
|
32
|
-
BUY_X_GET_Y_FREE_STRATEGY: () => import_examples.BUY_X_GET_Y_FREE_STRATEGY,
|
|
33
|
-
PromotionAdapter: () => import_adapter.PromotionAdapter,
|
|
34
|
-
PromotionEvaluator: () => import_evaluator.PromotionEvaluator,
|
|
35
|
-
X_ITEMS_FOR_Y_PRICE_STRATEGY: () => import_examples.X_ITEMS_FOR_Y_PRICE_STRATEGY,
|
|
36
|
-
default: () => import_adapter2.default
|
|
37
|
-
});
|
|
38
|
-
module.exports = __toCommonJS(promotion_exports);
|
|
39
|
-
var import_evaluator = require("./evaluator");
|
|
40
|
-
var import_adapter = require("./adapter");
|
|
41
|
-
var import_adapter2 = __toESM(require("./adapter"));
|
|
42
|
-
var import_examples = require("./examples");
|
|
43
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
44
|
-
0 && (module.exports = {
|
|
45
|
-
BUY_X_GET_Y_FREE_STRATEGY,
|
|
46
|
-
PromotionAdapter,
|
|
47
|
-
PromotionEvaluator,
|
|
48
|
-
X_ITEMS_FOR_Y_PRICE_STRATEGY
|
|
49
|
-
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Module, PisellCore, ModuleOptions } from '../../types';
|
|
2
2
|
import { BaseModule } from '../BaseModule';
|
|
3
|
-
import { OrderModuleAPI, CommitOrderParams, CheckoutOrderParams } from './types';
|
|
3
|
+
import { OrderModuleAPI, CommitOrderParams, CheckoutOrderParams, CancelOrderParams, ChangeBookingStatusParams } from './types';
|
|
4
4
|
import { CartItem } from '../Cart/types';
|
|
5
5
|
export declare class OrderModule extends BaseModule implements Module, OrderModuleAPI {
|
|
6
6
|
protected defaultName: string;
|
|
@@ -39,6 +39,8 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
39
39
|
type: 'holder' | 'account';
|
|
40
40
|
}): boolean;
|
|
41
41
|
submitOrder(order: CommitOrderParams): Promise<void>;
|
|
42
|
+
cancelOrder(params: CancelOrderParams): Promise<any>;
|
|
43
|
+
changeBookingStatus(params: ChangeBookingStatusParams): Promise<any>;
|
|
42
44
|
/**
|
|
43
45
|
* Checkout 专用:创建订单到后端
|
|
44
46
|
*
|
|
@@ -182,6 +182,42 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
182
182
|
});
|
|
183
183
|
return this.request.post(fetchUrl, params);
|
|
184
184
|
}
|
|
185
|
+
async cancelOrder(params) {
|
|
186
|
+
if (!Array.isArray(params.order_ids) || params.order_ids.length === 0) {
|
|
187
|
+
throw new Error("取消订单失败:order_ids 不能为空");
|
|
188
|
+
}
|
|
189
|
+
const payload = {
|
|
190
|
+
order_ids: params.order_ids,
|
|
191
|
+
status: "cancelled",
|
|
192
|
+
change_schedule_event_appointment_status: 1,
|
|
193
|
+
is_void: 1
|
|
194
|
+
};
|
|
195
|
+
this.logInfo("cancelOrder called", {
|
|
196
|
+
url: "/order/update-status",
|
|
197
|
+
method: "PUT",
|
|
198
|
+
orderIdsCount: params.order_ids.length
|
|
199
|
+
});
|
|
200
|
+
return this.request.put("/order/update-status", payload, { isShopApi: true });
|
|
201
|
+
}
|
|
202
|
+
async changeBookingStatus(params) {
|
|
203
|
+
if (!params.booking_id) {
|
|
204
|
+
throw new Error("变更预约状态失败:booking_id 不能为空");
|
|
205
|
+
}
|
|
206
|
+
if (!params.appointment_status) {
|
|
207
|
+
throw new Error("变更预约状态失败:appointment_status 不能为空");
|
|
208
|
+
}
|
|
209
|
+
const url = `/schedule/booking/appointment-status/${params.booking_id}`;
|
|
210
|
+
const payload = {
|
|
211
|
+
appointment_status: params.appointment_status
|
|
212
|
+
};
|
|
213
|
+
this.logInfo("changeBookingStatus called", {
|
|
214
|
+
url,
|
|
215
|
+
method: "PUT",
|
|
216
|
+
bookingId: params.booking_id,
|
|
217
|
+
appointmentStatus: params.appointment_status
|
|
218
|
+
});
|
|
219
|
+
return this.request.put(url, payload, { isShopApi: true });
|
|
220
|
+
}
|
|
185
221
|
/**
|
|
186
222
|
* Checkout 专用:创建订单到后端
|
|
187
223
|
*
|
|
@@ -58,6 +58,19 @@ export interface CheckoutOrderParams {
|
|
|
58
58
|
small_ticket_data_flag?: number;
|
|
59
59
|
[key: string]: any;
|
|
60
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* 取消订单参数
|
|
63
|
+
*/
|
|
64
|
+
export interface CancelOrderParams {
|
|
65
|
+
order_ids: Array<number | string>;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* 变更预约状态参数
|
|
69
|
+
*/
|
|
70
|
+
export interface ChangeBookingStatusParams {
|
|
71
|
+
booking_id: number | string;
|
|
72
|
+
appointment_status: string;
|
|
73
|
+
}
|
|
61
74
|
/**
|
|
62
75
|
* 订单模块 API
|
|
63
76
|
*/
|
|
@@ -86,4 +99,16 @@ export interface OrderModuleAPI {
|
|
|
86
99
|
* @returns 后端返回的订单数据
|
|
87
100
|
*/
|
|
88
101
|
createOrderByCheckout: (params: CheckoutOrderParams) => Promise<any>;
|
|
102
|
+
/**
|
|
103
|
+
* 取消订单
|
|
104
|
+
* @param params 取消订单参数
|
|
105
|
+
* @returns 后端返回结果
|
|
106
|
+
*/
|
|
107
|
+
cancelOrder: (params: CancelOrderParams) => Promise<any>;
|
|
108
|
+
/**
|
|
109
|
+
* 变更预约状态
|
|
110
|
+
* @param params 预约状态参数
|
|
111
|
+
* @returns 后端返回结果
|
|
112
|
+
*/
|
|
113
|
+
changeBookingStatus: (params: ChangeBookingStatusParams) => Promise<any>;
|
|
89
114
|
}
|
|
@@ -49,5 +49,5 @@ export declare class Product extends BaseModule implements Module {
|
|
|
49
49
|
getCategories(): ProductCategory[];
|
|
50
50
|
setOtherParams(key: string, value: any): void;
|
|
51
51
|
getOtherParams(): any;
|
|
52
|
-
getProductType(): "
|
|
52
|
+
getProductType(): "normal" | "duration" | "session";
|
|
53
53
|
}
|
|
@@ -136,7 +136,7 @@ export declare class BookingTicketImpl extends BaseModule implements Module {
|
|
|
136
136
|
* 获取当前的客户搜索条件
|
|
137
137
|
* @returns 当前搜索条件
|
|
138
138
|
*/
|
|
139
|
-
getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "
|
|
139
|
+
getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
|
|
140
140
|
/**
|
|
141
141
|
* 获取客户列表状态(包含滚动加载相关状态)
|
|
142
142
|
* @returns 客户状态
|
|
@@ -2,7 +2,7 @@ import dayjs from 'dayjs';
|
|
|
2
2
|
import { Module, ModuleOptions, PisellCore } from '../../types';
|
|
3
3
|
import { BaseModule } from '../../modules/BaseModule';
|
|
4
4
|
import type { RequestPlugin } from '../../plugins/request';
|
|
5
|
-
import { SalesState, SalesModuleAPI, Reservation, SalesResourceBookingItem, SalesTimelineHighlights } from './types';
|
|
5
|
+
import { SalesState, SalesModuleAPI, Reservation, SalesResourceBookingItem, SalesResourceBookingItemWithGroups, SalesTimelineHighlights, ChangeBookingStatusParams, GetResourceBookingItemParams } from './types';
|
|
6
6
|
import type { BookingData } from '../../server/modules/order/types';
|
|
7
7
|
export * from './types';
|
|
8
8
|
/**
|
|
@@ -39,6 +39,8 @@ export declare class SalesImpl extends BaseModule implements Module, SalesModule
|
|
|
39
39
|
setReservationList(reservationList: Reservation[]): Reservation[];
|
|
40
40
|
/** 重置预约列表为空 */
|
|
41
41
|
resetReservationList(): Reservation[];
|
|
42
|
+
cancelOrder(orderIds: Array<number | string>): Promise<any>;
|
|
43
|
+
changeBookingStatus(params: ChangeBookingStatusParams): Promise<any>;
|
|
42
44
|
destroy(): Promise<void>;
|
|
43
45
|
/**
|
|
44
46
|
* 时间轴粒度(分钟)
|
|
@@ -77,6 +79,10 @@ export declare class SalesImpl extends BaseModule implements Module, SalesModule
|
|
|
77
79
|
*/
|
|
78
80
|
private getBookingStatus;
|
|
79
81
|
private getResourceId;
|
|
82
|
+
private getBookingAppointmentStatus;
|
|
83
|
+
private getBookingOrderPaymentStatus;
|
|
84
|
+
private isBookingMatchedResource;
|
|
85
|
+
private sortMatchedBookings;
|
|
80
86
|
/**
|
|
81
87
|
* 资源下 bookings 的返回裁剪策略:
|
|
82
88
|
* 1) 优先返回当前时刻正在进行中的预约(允许并发返回多条)
|
|
@@ -98,6 +104,8 @@ export declare class SalesImpl extends BaseModule implements Module, SalesModule
|
|
|
98
104
|
* - 否则走快照分支(纯时间窗判定,忽略 appointment_status 的 arrived/started/completed 差异)
|
|
99
105
|
*/
|
|
100
106
|
private normalizeMatchedBooking;
|
|
107
|
+
private normalizeResourceBookings;
|
|
108
|
+
private buildCompletedBooking;
|
|
101
109
|
/**
|
|
102
110
|
* 实时模式(current === deviceCurrent):信任 appointment_status
|
|
103
111
|
* - 过滤 new / completed(实时视角下视为非活跃数据)
|
|
@@ -122,6 +130,7 @@ export declare class SalesImpl extends BaseModule implements Module, SalesModule
|
|
|
122
130
|
*/
|
|
123
131
|
private buildSnapshotBooking;
|
|
124
132
|
getResourceBookingList(currentTime: string, bookingList?: BookingData[], deviceTime?: string): Promise<SalesResourceBookingItem[]>;
|
|
133
|
+
getResourceBookingItem(params: GetResourceBookingItemParams): Promise<SalesResourceBookingItemWithGroups | null>;
|
|
125
134
|
}
|
|
126
135
|
export { SalesImpl as Sales };
|
|
127
136
|
export default SalesImpl;
|
|
@@ -100,6 +100,20 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
100
100
|
this.core.effects.emit(import_types.SalesHooks.onReservationListChanged, { reservationList: [] });
|
|
101
101
|
return [];
|
|
102
102
|
}
|
|
103
|
+
async cancelOrder(orderIds) {
|
|
104
|
+
const orderModule = this.core.getModule("order");
|
|
105
|
+
if (!orderModule) {
|
|
106
|
+
throw new Error("Sales 取消订单失败:Order 模块未注册");
|
|
107
|
+
}
|
|
108
|
+
return orderModule.cancelOrder({ order_ids: orderIds });
|
|
109
|
+
}
|
|
110
|
+
async changeBookingStatus(params) {
|
|
111
|
+
const orderModule = this.core.getModule("order");
|
|
112
|
+
if (!orderModule) {
|
|
113
|
+
throw new Error("Sales 变更预约状态失败:Order 模块未注册");
|
|
114
|
+
}
|
|
115
|
+
return orderModule.changeBookingStatus(params);
|
|
116
|
+
}
|
|
103
117
|
// -------------------------------------------------------------------------
|
|
104
118
|
// 生命周期
|
|
105
119
|
// -------------------------------------------------------------------------
|
|
@@ -233,6 +247,30 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
233
247
|
getResourceId(resource) {
|
|
234
248
|
return resource.id ?? resource.form_record_id ?? "";
|
|
235
249
|
}
|
|
250
|
+
getBookingAppointmentStatus(booking) {
|
|
251
|
+
return String(booking.appointment_status ?? booking.status ?? "");
|
|
252
|
+
}
|
|
253
|
+
getBookingOrderPaymentStatus(booking) {
|
|
254
|
+
var _a;
|
|
255
|
+
return String(((_a = booking.order) == null ? void 0 : _a.payment_status) ?? "");
|
|
256
|
+
}
|
|
257
|
+
isBookingMatchedResource(booking, resourceId) {
|
|
258
|
+
if (!Array.isArray(booking.resources))
|
|
259
|
+
return false;
|
|
260
|
+
return booking.resources.some((resource) => {
|
|
261
|
+
const relationId = resource == null ? void 0 : resource.relation_id;
|
|
262
|
+
if (relationId === void 0 || relationId === null)
|
|
263
|
+
return false;
|
|
264
|
+
return String(relationId) === String(resourceId);
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
sortMatchedBookings(bookings) {
|
|
268
|
+
return [...bookings].sort((left, right) => {
|
|
269
|
+
const leftStartAt = this.toBookingDateTime(left.start_date, left.start_time).valueOf();
|
|
270
|
+
const rightStartAt = this.toBookingDateTime(right.start_date, right.start_time).valueOf();
|
|
271
|
+
return leftStartAt - rightStartAt;
|
|
272
|
+
});
|
|
273
|
+
}
|
|
236
274
|
/**
|
|
237
275
|
* 资源下 bookings 的返回裁剪策略:
|
|
238
276
|
* 1) 优先返回当前时刻正在进行中的预约(允许并发返回多条)
|
|
@@ -341,17 +379,50 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
341
379
|
* - current === deviceCurrent 走实时分支(信任 appointment_status)
|
|
342
380
|
* - 否则走快照分支(纯时间窗判定,忽略 appointment_status 的 arrived/started/completed 差异)
|
|
343
381
|
*/
|
|
344
|
-
normalizeMatchedBooking(current, deviceCurrent, booking) {
|
|
345
|
-
const appointmentStatus =
|
|
382
|
+
normalizeMatchedBooking(current, deviceCurrent, booking, options = {}) {
|
|
383
|
+
const appointmentStatus = this.getBookingAppointmentStatus(booking);
|
|
346
384
|
if (appointmentStatus === "rejected" || appointmentStatus === "cancelled")
|
|
347
385
|
return null;
|
|
348
386
|
const startAt = this.toBookingDateTime(booking.start_date, booking.start_time);
|
|
349
387
|
const endAt = this.toBookingDateTime(booking.end_date, booking.end_time);
|
|
388
|
+
if (appointmentStatus === "completed" && options.includeCompleted) {
|
|
389
|
+
return this.buildCompletedBooking(current, booking, startAt, endAt);
|
|
390
|
+
}
|
|
350
391
|
if (current.isSame(deviceCurrent)) {
|
|
351
392
|
return this.buildRealtimeBooking(current, booking, appointmentStatus, startAt, endAt);
|
|
352
393
|
}
|
|
353
394
|
return this.buildSnapshotBooking(current, booking, appointmentStatus, startAt, endAt);
|
|
354
395
|
}
|
|
396
|
+
normalizeResourceBookings(current, deviceCurrent, bookingList, options = {}) {
|
|
397
|
+
const normalizedBookings = bookingList.map((booking) => this.normalizeMatchedBooking(current, deviceCurrent, booking, options)).filter((booking) => Boolean(booking)).filter((booking) => booking.status);
|
|
398
|
+
return this.sortMatchedBookings(normalizedBookings);
|
|
399
|
+
}
|
|
400
|
+
buildCompletedBooking(current, booking, startAt, endAt) {
|
|
401
|
+
if (!startAt.isValid() || !endAt.isValid())
|
|
402
|
+
return null;
|
|
403
|
+
if (current.isBefore(startAt)) {
|
|
404
|
+
return {
|
|
405
|
+
...booking,
|
|
406
|
+
status: "reserved",
|
|
407
|
+
isTimeout: false,
|
|
408
|
+
timeoutTime: void 0,
|
|
409
|
+
progressPercent: 0,
|
|
410
|
+
lateTime: void 0,
|
|
411
|
+
reserved_status: "not_arrived",
|
|
412
|
+
remainingReserveTime: Math.max(startAt.diff(current, "minute"), 0)
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
return {
|
|
416
|
+
...booking,
|
|
417
|
+
status: "occupied",
|
|
418
|
+
isTimeout: false,
|
|
419
|
+
timeoutTime: void 0,
|
|
420
|
+
progressPercent: this.isSameOrAfter(current, endAt) ? 100 : this.calcProgressPercent(current, startAt, endAt),
|
|
421
|
+
lateTime: void 0,
|
|
422
|
+
reserved_status: void 0,
|
|
423
|
+
remainingReserveTime: void 0
|
|
424
|
+
};
|
|
425
|
+
}
|
|
355
426
|
/**
|
|
356
427
|
* 实时模式(current === deviceCurrent):信任 appointment_status
|
|
357
428
|
* - 过滤 new / completed(实时视角下视为非活跃数据)
|
|
@@ -462,12 +533,7 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
462
533
|
const resourceList = ((_a = resourceResponse == null ? void 0 : resourceResponse.data) == null ? void 0 : _a.list) ?? [];
|
|
463
534
|
if (!Array.isArray(resourceList) || resourceList.length === 0)
|
|
464
535
|
return [];
|
|
465
|
-
|
|
466
|
-
const leftStartAt = this.toBookingDateTime(left.start_date, left.start_time).valueOf();
|
|
467
|
-
const rightStartAt = this.toBookingDateTime(right.start_date, right.start_time).valueOf();
|
|
468
|
-
return leftStartAt - rightStartAt;
|
|
469
|
-
});
|
|
470
|
-
normalizedBookings = normalizedBookings.filter((booking) => booking.status);
|
|
536
|
+
const normalizedBookings = this.normalizeResourceBookings(current, deviceCurrent, bookingList);
|
|
471
537
|
const bookingMap = /* @__PURE__ */ new Map();
|
|
472
538
|
normalizedBookings.forEach((booking) => {
|
|
473
539
|
if (!Array.isArray(booking.resources))
|
|
@@ -504,6 +570,73 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
504
570
|
});
|
|
505
571
|
return list;
|
|
506
572
|
}
|
|
573
|
+
async getResourceBookingItem(params) {
|
|
574
|
+
var _a, _b;
|
|
575
|
+
const current = (0, import_dayjs.default)(params.currentTime);
|
|
576
|
+
if (!current.isValid())
|
|
577
|
+
return null;
|
|
578
|
+
const deviceCurrent = (0, import_dayjs.default)(params.deviceTime || params.currentTime);
|
|
579
|
+
if (!deviceCurrent.isValid())
|
|
580
|
+
return null;
|
|
581
|
+
const resourceResponse = await this.request.get(
|
|
582
|
+
"/shop/form/resource/page",
|
|
583
|
+
{ skip: 1, num: 999 },
|
|
584
|
+
// @ts-ignore
|
|
585
|
+
{ osServer: true, isShopApi: true }
|
|
586
|
+
);
|
|
587
|
+
const resourceList = ((_a = resourceResponse == null ? void 0 : resourceResponse.data) == null ? void 0 : _a.list) ?? [];
|
|
588
|
+
if (!Array.isArray(resourceList) || resourceList.length === 0)
|
|
589
|
+
return null;
|
|
590
|
+
const targetResource = resourceList.find(
|
|
591
|
+
(resource) => String(this.getResourceId(resource)) === String(params.resourceId)
|
|
592
|
+
);
|
|
593
|
+
if (!targetResource)
|
|
594
|
+
return null;
|
|
595
|
+
const resourceId = this.getResourceId(targetResource);
|
|
596
|
+
const matchedBookingList = params.bookingList.filter(
|
|
597
|
+
(booking) => this.isBookingMatchedResource(booking, resourceId)
|
|
598
|
+
);
|
|
599
|
+
const completedBookingList = matchedBookingList.filter(
|
|
600
|
+
(booking) => this.getBookingAppointmentStatus(booking) === "completed"
|
|
601
|
+
);
|
|
602
|
+
const unpaidBookingList = matchedBookingList.filter(
|
|
603
|
+
(booking) => this.getBookingOrderPaymentStatus(booking) === "unpaid"
|
|
604
|
+
);
|
|
605
|
+
const bookings = this.pickBookingsForCurrentPoint(
|
|
606
|
+
current,
|
|
607
|
+
this.normalizeResourceBookings(current, deviceCurrent, matchedBookingList)
|
|
608
|
+
);
|
|
609
|
+
const completedBookings = this.pickBookingsForCurrentPoint(
|
|
610
|
+
current,
|
|
611
|
+
this.normalizeResourceBookings(current, deviceCurrent, completedBookingList, {
|
|
612
|
+
includeCompleted: true
|
|
613
|
+
})
|
|
614
|
+
);
|
|
615
|
+
const unpaidBookings = this.pickBookingsForCurrentPoint(
|
|
616
|
+
current,
|
|
617
|
+
this.normalizeResourceBookings(current, deviceCurrent, unpaidBookingList)
|
|
618
|
+
);
|
|
619
|
+
this.logger.addLog({
|
|
620
|
+
type: "info",
|
|
621
|
+
title: "getResourceBookingItem",
|
|
622
|
+
metadata: {
|
|
623
|
+
currentTime: params.currentTime,
|
|
624
|
+
deviceTime: params.deviceTime || params.currentTime,
|
|
625
|
+
resourceId,
|
|
626
|
+
bookingList: (_b = params.bookingList) == null ? void 0 : _b.length,
|
|
627
|
+
bookings: bookings.length,
|
|
628
|
+
completedBookings: completedBookings.length,
|
|
629
|
+
unpaidBookings: unpaidBookings.length
|
|
630
|
+
}
|
|
631
|
+
});
|
|
632
|
+
return {
|
|
633
|
+
...targetResource,
|
|
634
|
+
resource_id: resourceId,
|
|
635
|
+
bookings,
|
|
636
|
+
completedBookings,
|
|
637
|
+
unpaidBookings
|
|
638
|
+
};
|
|
639
|
+
}
|
|
507
640
|
};
|
|
508
641
|
var Sales_default = SalesImpl;
|
|
509
642
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -32,7 +32,21 @@ export interface SalesResourceBookingItem extends Omit<ResourceData, 'bookings'>
|
|
|
32
32
|
resource_id: ResourceId;
|
|
33
33
|
bookings: SalesResourceMatchedBooking[];
|
|
34
34
|
}
|
|
35
|
+
export interface SalesResourceBookingItemWithGroups extends SalesResourceBookingItem {
|
|
36
|
+
completedBookings: SalesResourceMatchedBooking[];
|
|
37
|
+
unpaidBookings: SalesResourceMatchedBooking[];
|
|
38
|
+
}
|
|
35
39
|
export type SalesTimelineHighlights = number[];
|
|
40
|
+
export interface ChangeBookingStatusParams {
|
|
41
|
+
booking_id: number | string;
|
|
42
|
+
appointment_status: string;
|
|
43
|
+
}
|
|
44
|
+
export interface GetResourceBookingItemParams {
|
|
45
|
+
resourceId: ResourceId;
|
|
46
|
+
currentTime: string;
|
|
47
|
+
bookingList: BookingData[];
|
|
48
|
+
deviceTime?: string;
|
|
49
|
+
}
|
|
36
50
|
/**
|
|
37
51
|
* Sales 解决方案状态
|
|
38
52
|
*
|
|
@@ -61,8 +75,14 @@ export interface SalesModuleAPI {
|
|
|
61
75
|
setReservationList: (reservationList: Reservation[]) => Reservation[];
|
|
62
76
|
/** 重置预约列表为空 */
|
|
63
77
|
resetReservationList: () => Reservation[];
|
|
78
|
+
/** 取消订单 */
|
|
79
|
+
cancelOrder: (orderIds: Array<number | string>) => Promise<any>;
|
|
80
|
+
/** 变更预约状态 */
|
|
81
|
+
changeBookingStatus: (params: ChangeBookingStatusParams) => Promise<any>;
|
|
64
82
|
/** 获取资源维度的预约占用列表 */
|
|
65
83
|
getResourceBookingList: (currentTime: string, bookingList: BookingData[], deviceTime?: string) => Promise<SalesResourceBookingItem[]>;
|
|
84
|
+
/** 获取单个资源维度的预约占用、已完成、未支付列表 */
|
|
85
|
+
getResourceBookingItem: (params: GetResourceBookingItemParams) => Promise<SalesResourceBookingItemWithGroups | null>;
|
|
66
86
|
/** 获取时间轴每个时间片的预约数量 */
|
|
67
87
|
getTimelineHighlights: (bookingList: BookingData[], startDateTime?: string, endDateTime?: string) => SalesTimelineHighlights;
|
|
68
88
|
}
|