@pisell/private-materials 6.12.355 → 6.12.357

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.
Files changed (41) hide show
  1. package/build/lowcode/assets-daily.json +11 -11
  2. package/build/lowcode/assets-dev.json +2 -2
  3. package/build/lowcode/assets-prod.json +11 -11
  4. package/build/lowcode/meta.js +1 -1
  5. package/build/lowcode/render/default/view.js +12 -12
  6. package/build/lowcode/view.js +12 -12
  7. package/es/components/appointmentBooking/components/Cart/Item/index.js +64 -12
  8. package/es/components/appointmentBooking/components/ConfirmInformation/index.js +7 -2
  9. package/es/components/appointmentBooking/components/Content/index.js +6 -4
  10. package/es/components/appointmentBooking/components/Voucher/index.js +11 -1
  11. package/es/components/appointmentBooking/hooks.js +33 -18
  12. package/es/components/appointmentBooking/utils.js +16 -5
  13. package/es/components/venueBooking/components/Cart/index.js +112 -18
  14. package/es/components/venueBooking/context.js +14 -3
  15. package/es/components/venueBooking/locales.js +10 -5
  16. package/es/plus/invoice/README.md +8 -2
  17. package/es/plus/invoice/ReceiptRenderer.js +1 -1
  18. package/es/plus/invoice/receipt.d.ts +2 -0
  19. package/es/plus/invoice/receipt.js +38 -8
  20. package/es/plus/invoice/receiptTranslations.js +8 -2
  21. package/es/plus/saleDetail/tmpl/B/components/Invoice/useInvoiceReceiptPreview.js +19 -13
  22. package/es/utils/buildCartHolderParams.js +166 -0
  23. package/es/utils/holderConfig.js +6 -0
  24. package/lib/components/appointmentBooking/components/Cart/Item/index.js +63 -11
  25. package/lib/components/appointmentBooking/components/ConfirmInformation/index.js +7 -2
  26. package/lib/components/appointmentBooking/components/Content/index.js +6 -4
  27. package/lib/components/appointmentBooking/components/Voucher/index.js +11 -1
  28. package/lib/components/appointmentBooking/hooks.js +33 -18
  29. package/lib/components/appointmentBooking/utils.js +16 -5
  30. package/lib/components/venueBooking/components/Cart/index.js +111 -17
  31. package/lib/components/venueBooking/context.js +14 -3
  32. package/lib/components/venueBooking/locales.js +10 -5
  33. package/lib/plus/invoice/README.md +8 -2
  34. package/lib/plus/invoice/ReceiptRenderer.js +1 -1
  35. package/lib/plus/invoice/receipt.d.ts +2 -0
  36. package/lib/plus/invoice/receipt.js +38 -8
  37. package/lib/plus/invoice/receiptTranslations.js +8 -2
  38. package/lib/plus/saleDetail/tmpl/B/components/Invoice/useInvoiceReceiptPreview.js +18 -12
  39. package/lib/utils/buildCartHolderParams.js +172 -0
  40. package/lib/utils/holderConfig.js +7 -0
  41. package/package.json +3 -3
@@ -1,6 +1,7 @@
1
1
  import { _objectSpread2 } from "../../../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js";
2
2
  import { _asyncToGenerator } from "../../../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/asyncToGenerator.js";
3
3
  import shoppingCart from "../../../../shoppingCart/index.js";
4
+ import { isHolderConfigEnabled } from "../../../../../utils/holderConfig.js";
4
5
  import { formatCurrentUser, formatHolder, getMultiResources, openForm, updateCartResources } from "../../../utils.js";
5
6
  import SubTotal from "../../../../subTotal/index.js";
6
7
  import { contextUtils, useAppointmentBooking, useAppointmentBookingAccount, useAppointmentBookingLogin, useAppointmentBookingResource, useAppointmentBookingSetting } from "../../../hooks.js";
@@ -9,7 +10,8 @@ import Deposit from "../../Deposit/index.js";
9
10
  import { handleAddHolder } from "../utils.js";
10
11
  import ContinueButton from "../ContinueButton/index.js";
11
12
  import VoucherCard from "../../Voucher/index.js";
12
- import React, { useMemo } from "react";
13
+ import { buildCartHolderOption, buildCartHolderParams, getAppointmentCartHolderConfig, getSkuRelationFormId, handleCartHolderFormSuccess } from "../../../../../utils/buildCartHolderParams.js";
14
+ import React, { useEffect, useMemo, useState } from "react";
13
15
  import { isMobile, locales } from "@pisell/utils";
14
16
  import "./index.less";
15
17
  //#region src/components/appointmentBooking/components/Cart/Item/index.tsx
@@ -21,9 +23,29 @@ const CartItem = ({ onNext, renderContactInfo }) => {
21
23
  const { getResourceList } = useAppointmentBookingResource();
22
24
  const { isFormSubject, bookingSubject, isRetailTemplate } = useAppointmentBookingSetting();
23
25
  const { isLogin } = useAppointmentBookingLogin();
26
+ const isLoggedIn = isLogin();
24
27
  const utils = contextUtils();
25
- const { businessUtils, translation } = utils;
28
+ const { businessUtils, translation, pisellos } = utils;
26
29
  const { taxTitle, totalTaxFee, isPriceIncludeTax, total, deposit } = summary;
30
+ const [holderMap, setHolderMap] = useState({});
31
+ useEffect(() => {
32
+ var _pisellos$effects;
33
+ const onHolderChanged = (res) => {
34
+ if ((res === null || res === void 0 ? void 0 : res.path) === "holderMap") {
35
+ var _appointmentBooking$g;
36
+ setHolderMap((appointmentBooking === null || appointmentBooking === void 0 || (_appointmentBooking$g = appointmentBooking.getHolderFormMap) === null || _appointmentBooking$g === void 0 ? void 0 : _appointmentBooking$g.call(appointmentBooking)) || {});
37
+ }
38
+ };
39
+ pisellos === null || pisellos === void 0 || (_pisellos$effects = pisellos.effects) === null || _pisellos$effects === void 0 || _pisellos$effects.on("appointmentBooking_holder:changed", onHolderChanged);
40
+ return () => {
41
+ var _pisellos$effects2;
42
+ pisellos === null || pisellos === void 0 || (_pisellos$effects2 = pisellos.effects) === null || _pisellos$effects2 === void 0 || _pisellos$effects2.off("appointmentBooking_holder:changed", onHolderChanged);
43
+ };
44
+ }, [appointmentBooking, pisellos]);
45
+ useEffect(() => {
46
+ var _appointmentBooking$g2;
47
+ setHolderMap((appointmentBooking === null || appointmentBooking === void 0 || (_appointmentBooking$g2 = appointmentBooking.getHolderFormMap) === null || _appointmentBooking$g2 === void 0 ? void 0 : _appointmentBooking$g2.call(appointmentBooking)) || {});
48
+ }, [appointmentBooking, isLoggedIn]);
27
49
  /**
28
50
  * @title: 当前客户
29
51
  * @description:
@@ -78,14 +100,32 @@ const CartItem = ({ onNext, renderContactInfo }) => {
78
100
  }
79
101
  if (type === "add_holder") {
80
102
  const relationShipFormId = bookingSubject === null || bookingSubject === void 0 ? void 0 : bookingSubject.relationship_form_id;
103
+ const holderConfig = getAppointmentCartHolderConfig(e);
104
+ const formId = isHolderConfigEnabled(holderConfig) ? holderConfig === null || holderConfig === void 0 ? void 0 : holderConfig.resource_id : void 0;
105
+ const skuRelationFormId = getSkuRelationFormId(holderMap, formId);
81
106
  return openForm({
82
- form_id: relationShipFormId || (bookingSubject === null || bookingSubject === void 0 ? void 0 : bookingSubject.form_id),
107
+ form_id: skuRelationFormId || formId || relationShipFormId || (bookingSubject === null || bookingSubject === void 0 ? void 0 : bookingSubject.form_id),
83
108
  title: locales.getText("pisell2.event.create.form"),
84
109
  utils,
85
110
  callback: function() {
86
111
  var _ref = _asyncToGenerator(function* (res) {
87
112
  if ((res === null || res === void 0 ? void 0 : res.status) === "success") {
88
113
  let result = void 0;
114
+ if (formId) {
115
+ const { formRecordId, mainField } = handleCartHolderFormSuccess({
116
+ res,
117
+ formId,
118
+ skuRelationFormId,
119
+ utils,
120
+ module: appointmentBooking
121
+ });
122
+ result = buildCartHolderOption(_objectSpread2(_objectSpread2({}, res === null || res === void 0 ? void 0 : res.values), {}, { formRecordId }), utils);
123
+ appointmentBooking.updateCart({
124
+ _id: e === null || e === void 0 ? void 0 : e._id,
125
+ account: result
126
+ });
127
+ return;
128
+ }
89
129
  if (!relationShipFormId) result = yield addAccount(res === null || res === void 0 ? void 0 : res.values, "holder");
90
130
  else result = yield handleAddHolder({
91
131
  res,
@@ -110,24 +150,36 @@ const CartItem = ({ onNext, renderContactInfo }) => {
110
150
  };
111
151
  const products = useMemo(() => {
112
152
  if (!(carts === null || carts === void 0 ? void 0 : carts.length)) return [];
113
- carts.forEach((item) => {
114
- item.isShowChangeHolder = !appointmentBooking.isTargetCartIdNormalProduct(item === null || item === void 0 ? void 0 : item._id);
153
+ const enrichedCarts = carts.map((item) => {
154
+ const isNormalProduct = appointmentBooking.isTargetCartIdNormalProduct(item === null || item === void 0 ? void 0 : item._id);
155
+ const holderConfig = getAppointmentCartHolderConfig(item);
156
+ const holderParams = buildCartHolderParams({
157
+ item,
158
+ holderConfig,
159
+ formData: isHolderConfigEnabled(holderConfig) ? holderMap === null || holderMap === void 0 ? void 0 : holderMap[holderConfig === null || holderConfig === void 0 ? void 0 : holderConfig.resource_id] : {},
160
+ translation,
161
+ enabled: isLoggedIn && isFormSubject && !isNormalProduct,
162
+ utils
163
+ });
164
+ return _objectSpread2(_objectSpread2({}, item), holderParams);
115
165
  });
116
- if ((currentSelectedResources === null || currentSelectedResources === void 0 ? void 0 : currentSelectedResources.length) > 0) return carts.map((item) => {
166
+ if ((currentSelectedResources === null || currentSelectedResources === void 0 ? void 0 : currentSelectedResources.length) > 0) return enrichedCarts.map((item) => {
117
167
  const currentResourceData = currentSelectedResources.find((resource) => (resource === null || resource === void 0 ? void 0 : resource._id) === (item === null || item === void 0 ? void 0 : item._id));
118
168
  const multiResources = getMultiResources(item, currentResourceData === null || currentResourceData === void 0 ? void 0 : currentResourceData.currentSelectedResource, currentStepParams === null || currentStepParams === void 0 ? void 0 : currentStepParams.key);
119
169
  return _objectSpread2(_objectSpread2({}, item), {}, {
120
170
  isMultipleResource: true,
121
- multiResources,
122
- isErrorHolder: isErrorHolder || false
171
+ multiResources
123
172
  });
124
173
  });
125
- else return carts;
174
+ else return enrichedCarts;
126
175
  }, [
127
176
  carts,
128
177
  currentSelectedResources,
129
178
  currentStepParams === null || currentStepParams === void 0 ? void 0 : currentStepParams.key,
130
- isErrorHolder
179
+ isErrorHolder,
180
+ holderMap,
181
+ isFormSubject,
182
+ isLoggedIn
131
183
  ]);
132
184
  /**
133
185
  * @description: 结算列表数据
@@ -187,8 +239,8 @@ const CartItem = ({ onNext, renderContactInfo }) => {
187
239
  isShowDelete: (currentStep === null || currentStep === void 0 || (_currentStep$step2 = currentStep.step) === null || _currentStep$step2 === void 0 ? void 0 : _currentStep$step2.key) === "select-service",
188
240
  isShowAmountFooter: true,
189
241
  isShowPackageNote: false,
190
- isShowChangeHolder: isLastStep ? false : isFormSubject && isLogin,
191
- isShowHolder: isFormSubject,
242
+ isShowChangeHolder: isLastStep ? false : isFormSubject && isLoggedIn,
243
+ isShowHolder: isFormSubject && isLoggedIn,
192
244
  isShowAddHolderButton: true
193
245
  },
194
246
  collapseParams: {
@@ -2,6 +2,7 @@ import useEngineContext from "../../../../hooks/useEngineContext.js";
2
2
  import { _objectSpread2 } from "../../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js";
3
3
  import { _asyncToGenerator } from "../../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/asyncToGenerator.js";
4
4
  import ContactInfoContent from "../../../../plus/contactInfoModal/ContactInfoContent.js";
5
+ import { isHolderConfigEnabled } from "../../../../utils/holderConfig.js";
5
6
  import { Toast, formatAppointmentCartSummary, formatAppointmentCustomerInfo, sendAppointmentBookingLog } from "../../utils.js";
6
7
  import useLoginUser from "../../../../hooks/useLoginUser.js";
7
8
  import productStockCheckModal_default from "../../../productStockCheckModal/index.js";
@@ -23,7 +24,7 @@ const ConfirmInformation = forwardRef((props, ref) => {
23
24
  const utils = contextUtils();
24
25
  const { pubsub } = context.appHelper.utils;
25
26
  const { appointmentBooking, summary, isAgreeDepositPolicy, setLoading, carts, setTimes } = useAppointmentBookingContext();
26
- const { isRetailTemplate, bookingSetting } = useAppointmentBookingSetting();
27
+ const { isRetailTemplate, bookingSetting, isFormSubject } = useAppointmentBookingSetting();
27
28
  console.log(bookingSetting, "bookingSetting");
28
29
  const [form] = Form.useForm();
29
30
  const userInfo = useLoginUser();
@@ -179,10 +180,14 @@ const ConfirmInformation = forwardRef((props, ref) => {
179
180
  const onCheckout = function() {
180
181
  var _ref5 = _asyncToGenerator(function* (extraData) {
181
182
  try {
183
+ const _extraData = (carts === null || carts === void 0 ? void 0 : carts.some((item) => {
184
+ var _item$_productInit;
185
+ return isHolderConfigEnabled(item === null || item === void 0 || (_item$_productInit = item._productInit) === null || _item$_productInit === void 0 ? void 0 : _item$_productInit.holder_config);
186
+ })) ? _objectSpread2(_objectSpread2({}, extraData), {}, { is_add_holder_info: isFormSubject }) : extraData;
182
187
  const { deposit } = summary;
183
188
  const customer = formatAppointmentCustomerInfo(_objectSpread2(_objectSpread2({}, userInfo), extraData === null || extraData === void 0 ? void 0 : extraData.contacts_info));
184
189
  logCheckout("调用 submitOrder", _objectSpread2({ products: formatAppointmentCartSummary(carts) }, customer));
185
- const { data } = yield appointmentBooking.submitOrder(extraData);
190
+ const { data } = yield appointmentBooking.submitOrder(_extraData);
186
191
  const { is_deposit, deposit_amount, total_amount, order_id } = data || {};
187
192
  logCheckout("submitOrder 返回", _objectSpread2(_objectSpread2({ products: formatAppointmentCartSummary(carts) }, customer), {}, {
188
193
  order_id: order_id || null,
@@ -27,6 +27,7 @@ const Layout = () => {
27
27
  const { currentStep, setResourceOtherParams, resourceOtherParams, setIsAgreeDepositPolicy, appointmentBooking, setLoading, policyParams, closePolicy, currentStepParams, setIsErrorHolder } = useAppointmentBookingContext();
28
28
  const { isDateSelectedFirst, isFormSubject, isRetailTemplate } = useAppointmentBookingSetting();
29
29
  const { isLogin } = useAppointmentBookingLogin();
30
+ const isLoggedIn = isLogin();
30
31
  const { getHolders } = useAppointmentBookingAccount();
31
32
  const { removeStep } = useAppointmentBookingStep();
32
33
  const { shopDiscount } = useShopDiscount();
@@ -47,7 +48,7 @@ const Layout = () => {
47
48
  const accountLists = yield appointmentBooking.getAccounts();
48
49
  const meAccount = accountLists === null || accountLists === void 0 ? void 0 : accountLists.find((d) => !(d === null || d === void 0 ? void 0 : d.isGuest));
49
50
  appointmentBooking.setLoginAccount(meAccount === null || meAccount === void 0 ? void 0 : meAccount.id, currentUser);
50
- } else if (!isRetailTemplate) getHolders();
51
+ } else if (!isRetailTemplate) yield getHolders();
51
52
  });
52
53
  return function handleLoginSuccess(_x) {
53
54
  return _ref.apply(this, arguments);
@@ -86,11 +87,12 @@ const Layout = () => {
86
87
  } catch (error) {}
87
88
  }, [isFormSubject, isRetailTemplate]);
88
89
  useEffect(() => {
89
- if (isFormSubject && isLogin && !isRetailTemplate) getHolders();
90
+ if (isFormSubject && isLoggedIn && !isRetailTemplate) getHolders();
90
91
  }, [
91
92
  isFormSubject,
92
- isLogin,
93
- isRetailTemplate
93
+ isLoggedIn,
94
+ isRetailTemplate,
95
+ appointmentBooking
94
96
  ]);
95
97
  useEffect(() => {
96
98
  var _currentStep$step;
@@ -2,6 +2,7 @@ import useEngineContext from "../../../../hooks/useEngineContext.js";
2
2
  import { _objectSpread2 } from "../../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js";
3
3
  import { _asyncToGenerator } from "../../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/asyncToGenerator.js";
4
4
  import { showDiscountScanFailMessage } from "../../../booking/utils.js";
5
+ import { getCustomer } from "../../utils.js";
5
6
  import { useAppointmentBooking, useAppointmentBookingAccount, useAppointmentBookingLogin, useShopDiscount } from "../../hooks.js";
6
7
  import { useAppointmentBookingContext } from "../../context.js";
7
8
  import React, { useEffect, useMemo, useRef, useState } from "react";
@@ -195,7 +196,16 @@ const VoucherCard = (props) => {
195
196
  className: "login-btn",
196
197
  onClick: () => {
197
198
  if (!action) return;
198
- openLoginModal({ callback: (status) => {} });
199
+ openLoginModal({
200
+ data: { type: "plugin" },
201
+ callback: (status) => {
202
+ if (status === "success") {
203
+ var _appointmentBooking$r;
204
+ const customer = getCustomer(utils);
205
+ appointmentBooking === null || appointmentBooking === void 0 || (_appointmentBooking$r = appointmentBooking.refreshAllHolderFormRecords) === null || _appointmentBooking$r === void 0 || _appointmentBooking$r.call(appointmentBooking, { customer_id: customer === null || customer === void 0 ? void 0 : customer.id });
206
+ }
207
+ }
208
+ });
199
209
  }
200
210
  }, locales.getText("pisell2.text.goodpass.login")), /* @__PURE__ */ React.createElement("span", null, locales.getText("pisell2.text.goodpass.login-tip"))));
201
211
  };
@@ -184,15 +184,19 @@ const useAppointmentBookingStep = () => {
184
184
  const selectedResource = (currentSelectedResources === null || currentSelectedResources === void 0 || (_currentSelectedResou2 = currentSelectedResources[0]) === null || _currentSelectedResou2 === void 0 ? void 0 : _currentSelectedResou2.currentSelectedResource) || {};
185
185
  const renderItem = (selectedResource === null || selectedResource === void 0 ? void 0 : selectedResource.renderItem) || {};
186
186
  const checkHolder = function() {
187
- var _ref2 = _asyncToGenerator(function* () {
187
+ var _ref2 = _asyncToGenerator(function* (isLoginTrigger = false) {
188
188
  setLoading(false);
189
189
  if (isRetailTemplate || (appointmentBooking === null || appointmentBooking === void 0 ? void 0 : appointmentBooking.isCartAllNormalProducts())) return appointmentBooking.next();
190
190
  let cartLists = carts || [];
191
191
  if (!(carts === null || carts === void 0 ? void 0 : carts.length)) cartLists = (yield appointmentBooking.getCart()) || [];
192
192
  else cartLists = carts || [];
193
- const { hasError } = checkAndGoNext(isFormSubject, checkAccount, cartLists.filter((n) => !(appointmentBooking === null || appointmentBooking === void 0 ? void 0 : appointmentBooking.isTargetCartIdNormalProduct(n._id))));
193
+ const { hasError, isEnableSkuHolderRule } = checkAndGoNext(isFormSubject, checkAccount, cartLists.filter((n) => !(appointmentBooking === null || appointmentBooking === void 0 ? void 0 : appointmentBooking.isTargetCartIdNormalProduct(n._id))));
194
194
  setIsErrorHolder(hasError);
195
- if (hasError) return;
195
+ if (hasError) {
196
+ scrollToFirstErrorCard(".pisell-lowcode-product-card-select-holder-error");
197
+ return;
198
+ }
199
+ if (isLoginTrigger && isEnableSkuHolderRule) return;
196
200
  if (!!(renderItem === null || renderItem === void 0 ? void 0 : renderItem.policy_id)) openPolicy({ id: renderItem === null || renderItem === void 0 ? void 0 : renderItem.policy_id }, () => {
197
201
  return appointmentBooking.next();
198
202
  });
@@ -204,10 +208,17 @@ const useAppointmentBookingStep = () => {
204
208
  }();
205
209
  const checkLogin = function() {
206
210
  var _ref3 = _asyncToGenerator(function* () {
207
- if (!isLogin) {
211
+ if (!isLogin()) {
208
212
  const { pubsub } = utils;
209
213
  pubsub.once("pisell1.login.success", (res) => {
210
- if (res === "success") checkHolder();
214
+ if (res === "success") {
215
+ if (isFormSubject && !isRetailTemplate && !(appointmentBooking === null || appointmentBooking === void 0 ? void 0 : appointmentBooking.isCartAllNormalProducts())) {
216
+ var _appointmentBooking$r;
217
+ const customer = getCustomer(utils);
218
+ appointmentBooking === null || appointmentBooking === void 0 || (_appointmentBooking$r = appointmentBooking.refreshAllHolderFormRecords) === null || _appointmentBooking$r === void 0 || _appointmentBooking$r.call(appointmentBooking, { customer_id: customer === null || customer === void 0 ? void 0 : customer.id });
219
+ }
220
+ checkHolder(true);
221
+ }
211
222
  if (res === "close") setLoading(false);
212
223
  });
213
224
  return openLoginModal({ callback: (status) => {} });
@@ -341,10 +352,10 @@ const useAppointmentBookingLogin = () => {
341
352
  return Boolean(utils === null || utils === void 0 || (_utils$token = utils.token) === null || _utils$token === void 0 || (_utils$token$get = _utils$token.get) === null || _utils$token$get === void 0 ? void 0 : _utils$token$get.call(_utils$token));
342
353
  }, [utils]);
343
354
  const openLoginModal = (params) => {
344
- const { callback } = params || {};
355
+ const { callback, data = {} } = params || {};
345
356
  utils.action({
346
357
  type: "pisell1.login",
347
- data: { type: "plugin" },
358
+ data: _objectSpread2({ type: "plugin" }, data),
348
359
  callback
349
360
  });
350
361
  };
@@ -389,19 +400,23 @@ const useAppointmentBookingAccount = () => {
389
400
  }, []);
390
401
  const getHolders = function() {
391
402
  var _ref9 = _asyncToGenerator(function* () {
392
- var _utils$getStore$getSt;
403
+ var _utils$getStore$getSt, _appointmentBooking$r2;
393
404
  const shop_id = (_utils$getStore$getSt = utils.getStore().getState()) === null || _utils$getStore$getSt === void 0 || (_utils$getStore$getSt = _utils$getStore$getSt.global) === null || _utils$getStore$getSt === void 0 || (_utils$getStore$getSt = _utils$getStore$getSt.shop) === null || _utils$getStore$getSt === void 0 ? void 0 : _utils$getStore$getSt.id;
394
405
  const customer = getCustomer(utils);
395
- if (!shop_id || !form_id || !(customer === null || customer === void 0 ? void 0 : customer.id)) return [];
396
- const params = {
397
- url: "/form/data/v1",
398
- query: {
399
- customer_id: customer === null || customer === void 0 ? void 0 : customer.id,
400
- form_id,
401
- shop_id
402
- }
403
- };
404
- const data = yield appointmentBooking.fetchHolderAccountsAsync(params);
406
+ if (!(customer === null || customer === void 0 ? void 0 : customer.id)) return [];
407
+ let data;
408
+ if (shop_id && form_id) {
409
+ const params = {
410
+ url: "/form/data/v1",
411
+ query: {
412
+ customer_id: customer.id,
413
+ form_id,
414
+ shop_id
415
+ }
416
+ };
417
+ data = yield appointmentBooking.fetchHolderAccountsAsync(params);
418
+ }
419
+ yield appointmentBooking === null || appointmentBooking === void 0 || (_appointmentBooking$r2 = appointmentBooking.refreshAllHolderFormRecords) === null || _appointmentBooking$r2 === void 0 ? void 0 : _appointmentBooking$r2.call(appointmentBooking, { customer_id: customer.id });
405
420
  return (data === null || data === void 0 ? void 0 : data.map((item) => {
406
421
  return {
407
422
  id: item === null || item === void 0 ? void 0 : item.form_record_id,
@@ -1,5 +1,6 @@
1
1
  import { _objectSpread2 } from "../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js";
2
2
  import { _asyncToGenerator } from "../../_virtual/_@oxc-project_runtime@0.122.0/helpers/asyncToGenerator.js";
3
+ import { isHolderConfigEnabled, isHolderConfigRequired } from "../../utils/holderConfig.js";
3
4
  import { getUniqueId, locales } from "@pisell/utils";
4
5
  import { PisellToast } from "@pisell/materials";
5
6
  //#region src/components/appointmentBooking/utils.ts
@@ -338,10 +339,19 @@ const getFormInsertBeforeKey = (currentKey, stepList) => {
338
339
  * @Date: 2025-05-24 22:46
339
340
  */
340
341
  const checkAndGoNext = (isFormSubject, checkAccount, carts) => {
342
+ if (!isFormSubject) return {
343
+ hasError: false,
344
+ isEnableSkuHolderRule: false,
345
+ updatedCartList: carts
346
+ };
341
347
  let hasError = false;
348
+ let isEnableSkuHolderRule = false;
342
349
  let updatedCartList = [...carts];
343
- if (isFormSubject && !checkAccount("holder")) updatedCartList = carts === null || carts === void 0 ? void 0 : carts.map((item) => {
344
- if (!(item === null || item === void 0 ? void 0 : item.holder_id)) {
350
+ updatedCartList = carts === null || carts === void 0 ? void 0 : carts.map((item) => {
351
+ var _item$_productInit;
352
+ const holderConfig = (item === null || item === void 0 || (_item$_productInit = item._productInit) === null || _item$_productInit === void 0 ? void 0 : _item$_productInit.holder_config) || {};
353
+ if (!(item === null || item === void 0 ? void 0 : item.holder_id) && isHolderConfigEnabled(holderConfig) && !isHolderConfigRequired(holderConfig)) isEnableSkuHolderRule = true;
354
+ if (!(item === null || item === void 0 ? void 0 : item.holder_id) && isHolderConfigRequired(holderConfig)) {
345
355
  hasError = true;
346
356
  return _objectSpread2(_objectSpread2({}, item), {}, { isErrorHolder: true });
347
357
  }
@@ -349,7 +359,8 @@ const checkAndGoNext = (isFormSubject, checkAccount, carts) => {
349
359
  });
350
360
  return {
351
361
  hasError,
352
- updatedCartList
362
+ updatedCartList,
363
+ isEnableSkuHolderRule
353
364
  };
354
365
  };
355
366
  const currentAppointmentBoard = (currentKey, resources, appointmentBooking) => {
@@ -411,8 +422,8 @@ const isSessionProduct = function() {
411
422
  var _ref2 = _asyncToGenerator(function* (appointmentBooking) {
412
423
  const carts = yield appointmentBooking.getCart();
413
424
  return carts === null || carts === void 0 ? void 0 : carts.some((item) => {
414
- var _item$_productInit;
415
- return (item === null || item === void 0 || (_item$_productInit = item._productInit) === null || _item$_productInit === void 0 || (_item$_productInit = _item$_productInit["schedule.ids"]) === null || _item$_productInit === void 0 ? void 0 : _item$_productInit.length) > 0;
425
+ var _item$_productInit2;
426
+ return (item === null || item === void 0 || (_item$_productInit2 = item._productInit) === null || _item$_productInit2 === void 0 || (_item$_productInit2 = _item$_productInit2["schedule.ids"]) === null || _item$_productInit2 === void 0 ? void 0 : _item$_productInit2.length) > 0;
416
427
  });
417
428
  });
418
429
  return function isSessionProduct(_x) {
@@ -2,12 +2,15 @@ import useEngineContext from "../../../../hooks/useEngineContext.js";
2
2
  import { _objectSpread2 } from "../../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js";
3
3
  import { _asyncToGenerator } from "../../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/asyncToGenerator.js";
4
4
  import shoppingCart from "../../../shoppingCart/index.js";
5
+ import { isHolderConfigEnabled } from "../../../../utils/holderConfig.js";
6
+ import { getCustomer, openForm } from "../../../appointmentBooking/utils.js";
5
7
  import SubTotal from "../../../subTotal/index.js";
8
+ import { buildCartHolderParams, getSkuRelationFormId, getVenueCartHolderConfig, handleCartHolderFormSuccess } from "../../../../utils/buildCartHolderParams.js";
6
9
  import { getVenueBookingProductIdentity } from "../../utils/orderProductIdentity.js";
7
10
  import { useVenueBookingContext } from "../../context.js";
8
11
  import VoucherCard from "../Voucher/index.js";
9
12
  import VenueDeposit from "../Deposit/index.js";
10
- import React, { useEffect, useMemo } from "react";
13
+ import React, { useEffect, useMemo, useState } from "react";
11
14
  import { message } from "antd";
12
15
  import { locales } from "@pisell/utils";
13
16
  import { Button as Button$1 } from "@pisell/materials";
@@ -19,24 +22,65 @@ import "./index.less";
19
22
  * 支持两种模式:embedded(桌面端内嵌)和 drawer(移动端抽屉弹出)
20
23
  */
21
24
  function Cart(props) {
22
- var _engineContext$appHel, _engineContext$appHel2, _engineContext$appHel3, _engineContext$engine, _businessUtils$getApp, _businessUtils$getApp2, _ref, _ref2, _ref3, _summary$total_amount, _summary$deposit3;
25
+ var _engineContext$appHel, _engineContext$appHel2, _engineContext$appHel3, _engineContext$engine, _engineContext$appHel4, _businessUtils$getApp, _businessUtils$getApp2, _ref, _ref2, _ref3, _summary$total_amount, _summary$deposit3;
23
26
  const { open, onCancel, onNext, items, summary, embedded = false, confirmLoading = false, extraContent } = props;
24
- const { currentStep, runModuleAction, refreshViewModel, refreshTimeSlotGrid, venueBookingModule, isAgreeDepositPolicy, setIsAgreeDepositPolicy } = useVenueBookingContext();
27
+ const { currentStep, runModuleAction, refreshViewModel, refreshTimeSlotGrid, venueBookingModule, isAgreeDepositPolicy, setIsAgreeDepositPolicy, isLoading, isLogin } = useVenueBookingContext();
25
28
  const engineContext = useEngineContext();
26
29
  const businessUtils = engineContext === null || engineContext === void 0 || (_engineContext$appHel = engineContext.appHelper) === null || _engineContext$appHel === void 0 || (_engineContext$appHel = _engineContext$appHel.utils) === null || _engineContext$appHel === void 0 ? void 0 : _engineContext$appHel.businessUtils;
27
30
  const symbol = String((engineContext === null || engineContext === void 0 || (_engineContext$appHel2 = engineContext.appHelper) === null || _engineContext$appHel2 === void 0 || (_engineContext$appHel2 = _engineContext$appHel2.utils) === null || _engineContext$appHel2 === void 0 || (_engineContext$appHel3 = _engineContext$appHel2.getSymbolic) === null || _engineContext$appHel3 === void 0 ? void 0 : _engineContext$appHel3.call(_engineContext$appHel2)) || "$");
28
31
  const locale = (engineContext === null || engineContext === void 0 || (_engineContext$engine = engineContext.engine) === null || _engineContext$engine === void 0 || (_engineContext$engine = _engineContext$engine.props) === null || _engineContext$engine === void 0 ? void 0 : _engineContext$engine.locale) || "en";
32
+ const [holderMap, setHolderMap] = useState({});
33
+ const { pisellos, translation } = (engineContext === null || engineContext === void 0 || (_engineContext$appHel4 = engineContext.appHelper) === null || _engineContext$appHel4 === void 0 ? void 0 : _engineContext$appHel4.utils) || {};
29
34
  const hasGoodPassApp = !!(businessUtils === null || businessUtils === void 0 || (_businessUtils$getApp = businessUtils.getAppByModal) === null || _businessUtils$getApp === void 0 ? void 0 : _businessUtils$getApp.call(businessUtils, "goodpass"));
30
35
  const hasDiscountCardApp = !!(businessUtils === null || businessUtils === void 0 || (_businessUtils$getApp2 = businessUtils.getAppByModal) === null || _businessUtils$getApp2 === void 0 ? void 0 : _businessUtils$getApp2.call(businessUtils, "discountcard"));
31
36
  const showVoucher = hasGoodPassApp || hasDiscountCardApp;
37
+ useEffect(() => {
38
+ var _pisellos$effects;
39
+ const onHolderChanged = (res) => {
40
+ if ((res === null || res === void 0 ? void 0 : res.path) === "holderMap") setHolderMap(res === null || res === void 0 ? void 0 : res.value);
41
+ };
42
+ pisellos === null || pisellos === void 0 || (_pisellos$effects = pisellos.effects) === null || _pisellos$effects === void 0 || _pisellos$effects.on("venueBooking_holder:changed", onHolderChanged);
43
+ return () => {
44
+ var _pisellos$effects2;
45
+ pisellos === null || pisellos === void 0 || (_pisellos$effects2 = pisellos.effects) === null || _pisellos$effects2 === void 0 || _pisellos$effects2.off("venueBooking_holder:changed", onHolderChanged);
46
+ };
47
+ }, [pisellos]);
48
+ useEffect(() => {
49
+ if (isLoading || !venueBookingModule) return;
50
+ try {
51
+ var _venueBookingModule$g;
52
+ setHolderMap(((_venueBookingModule$g = venueBookingModule.getHolderFormMap) === null || _venueBookingModule$g === void 0 ? void 0 : _venueBookingModule$g.call(venueBookingModule)) || {});
53
+ } catch (error) {
54
+ console.warn("[venueBooking] Holder data is not ready", error);
55
+ setHolderMap({});
56
+ }
57
+ }, [venueBookingModule, isLoading]);
32
58
  const isVisible = embedded || open;
33
59
  const totalAmount = (_ref = (_ref2 = (_ref3 = (_summary$total_amount = summary === null || summary === void 0 ? void 0 : summary.total_amount) !== null && _summary$total_amount !== void 0 ? _summary$total_amount : summary === null || summary === void 0 ? void 0 : summary.expect_amount) !== null && _ref3 !== void 0 ? _ref3 : summary === null || summary === void 0 ? void 0 : summary.amount) !== null && _ref2 !== void 0 ? _ref2 : summary === null || summary === void 0 ? void 0 : summary.total) !== null && _ref !== void 0 ? _ref : "0.00";
34
60
  const cartProducts = useMemo(() => {
35
- return (items || []).map((item) => _objectSpread2(_objectSpread2({}, item), {}, {
36
- symbol: (item === null || item === void 0 ? void 0 : item.symbol) || symbol,
37
- is_hide_like: true
38
- }));
39
- }, [items, symbol]);
61
+ return (items || []).map((item) => {
62
+ var _item$_origin, _engineContext$appHel5;
63
+ const holderConfig = getVenueCartHolderConfig(item);
64
+ const holderParams = buildCartHolderParams({
65
+ item,
66
+ holderConfig,
67
+ formData: isHolderConfigEnabled(holderConfig) ? holderMap === null || holderMap === void 0 ? void 0 : holderMap[holderConfig === null || holderConfig === void 0 ? void 0 : holderConfig.resource_id] : {},
68
+ translation,
69
+ enabled: !!(item === null || item === void 0 || (_item$_origin = item._origin) === null || _item$_origin === void 0 || (_item$_origin = _item$_origin.product) === null || _item$_origin === void 0 ? void 0 : _item$_origin.bookingUuid),
70
+ utils: engineContext === null || engineContext === void 0 || (_engineContext$appHel5 = engineContext.appHelper) === null || _engineContext$appHel5 === void 0 ? void 0 : _engineContext$appHel5.utils
71
+ });
72
+ return _objectSpread2(_objectSpread2({}, item), {}, {
73
+ symbol: (item === null || item === void 0 ? void 0 : item.symbol) || symbol,
74
+ is_hide_like: true,
75
+ allowClearHolder: true
76
+ }, holderParams);
77
+ });
78
+ }, [
79
+ items,
80
+ symbol,
81
+ holderMap,
82
+ translation
83
+ ]);
40
84
  const confirmOrderText = currentStep === "checkout" ? String(locales.getText("pisell2.venue.action.pay.now") || "立即支付") : String(locales.getText("pisell2.venue.action.next") || "下一步");
41
85
  /**
42
86
  * SubTotal 金额明细列表
@@ -44,12 +88,12 @@ function Cart(props) {
44
88
  * surcharges 为服务费列表,label 支持多语言对象,按当前 locale 取值
45
89
  */
46
90
  const subTotalList = useMemo(() => {
47
- var _summary$product_amou, _summary$tax_fee, _ref4, _summary$total_amount2, _summary$deposit, _venueBookingModule$g, _tempSummary$is_price, _summary$deposit$tota, _summary$deposit2;
91
+ var _summary$product_amou, _summary$tax_fee, _ref4, _summary$total_amount2, _summary$deposit, _venueBookingModule$g2, _tempSummary$is_price, _summary$deposit$tota, _summary$deposit2;
48
92
  const subTotal = Number((_summary$product_amou = summary === null || summary === void 0 ? void 0 : summary.product_amount) !== null && _summary$product_amou !== void 0 ? _summary$product_amou : 0);
49
93
  const totalTaxFee = Number((_summary$tax_fee = summary === null || summary === void 0 ? void 0 : summary.tax_fee) !== null && _summary$tax_fee !== void 0 ? _summary$tax_fee : 0);
50
94
  const total = Number((_ref4 = (_summary$total_amount2 = summary === null || summary === void 0 ? void 0 : summary.total_amount) !== null && _summary$total_amount2 !== void 0 ? _summary$total_amount2 : summary === null || summary === void 0 ? void 0 : summary.expect_amount) !== null && _ref4 !== void 0 ? _ref4 : 0);
51
95
  const hasDeposit = !!(summary === null || summary === void 0 || (_summary$deposit = summary.deposit) === null || _summary$deposit === void 0 ? void 0 : _summary$deposit.hasDeposit);
52
- const tempOrder = venueBookingModule === null || venueBookingModule === void 0 || (_venueBookingModule$g = venueBookingModule.getTempOrder) === null || _venueBookingModule$g === void 0 ? void 0 : _venueBookingModule$g.call(venueBookingModule);
96
+ const tempOrder = venueBookingModule === null || venueBookingModule === void 0 || (_venueBookingModule$g2 = venueBookingModule.getTempOrder) === null || _venueBookingModule$g2 === void 0 ? void 0 : _venueBookingModule$g2.call(venueBookingModule);
53
97
  const tempSummary = (tempOrder === null || tempOrder === void 0 ? void 0 : tempOrder.summary) || {};
54
98
  const taxTitle = String((tempSummary === null || tempSummary === void 0 ? void 0 : tempSummary.tax_title) || (summary === null || summary === void 0 ? void 0 : summary.tax_title) || "GST/Tax");
55
99
  const rawTaxRate = Number(tempSummary === null || tempSummary === void 0 ? void 0 : tempSummary.tax_rate);
@@ -111,7 +155,57 @@ function Cart(props) {
111
155
  return false;
112
156
  };
113
157
  const handleCartChange = function() {
114
- var _ref5 = _asyncToGenerator(function* (item, type, sourceItem) {
158
+ var _ref6 = _asyncToGenerator(function* (item, type, sourceItem) {
159
+ if (type === "add_holder") {
160
+ var _engineContext$appHel6;
161
+ const holderConfig = getVenueCartHolderConfig(item);
162
+ if (!isHolderConfigEnabled(holderConfig)) return;
163
+ const formId = holderConfig === null || holderConfig === void 0 ? void 0 : holderConfig.resource_id;
164
+ if (!formId) return;
165
+ const skuRelationFormId = getSkuRelationFormId(holderMap, formId);
166
+ return openForm({
167
+ form_id: skuRelationFormId || formId,
168
+ title: locales.getText("pisell2.venue.create.form"),
169
+ utils: engineContext === null || engineContext === void 0 || (_engineContext$appHel6 = engineContext.appHelper) === null || _engineContext$appHel6 === void 0 ? void 0 : _engineContext$appHel6.utils,
170
+ callback: function() {
171
+ var _ref5 = _asyncToGenerator(function* (res) {
172
+ if ((res === null || res === void 0 ? void 0 : res.status) === "success") {
173
+ var _engineContext$appHel7, _engineContext$appHel8, _item$_origin2;
174
+ const { formRecordId, formId: holderFormId } = handleCartHolderFormSuccess({
175
+ res,
176
+ formId,
177
+ skuRelationFormId,
178
+ utils: engineContext === null || engineContext === void 0 || (_engineContext$appHel7 = engineContext.appHelper) === null || _engineContext$appHel7 === void 0 ? void 0 : _engineContext$appHel7.utils,
179
+ module: venueBookingModule
180
+ });
181
+ const customer = getCustomer(engineContext === null || engineContext === void 0 || (_engineContext$appHel8 = engineContext.appHelper) === null || _engineContext$appHel8 === void 0 ? void 0 : _engineContext$appHel8.utils);
182
+ venueBookingModule.setBookingHolder(item === null || item === void 0 || (_item$_origin2 = item._origin) === null || _item$_origin2 === void 0 || (_item$_origin2 = _item$_origin2.product) === null || _item$_origin2 === void 0 ? void 0 : _item$_origin2.bookingUuid, {
183
+ customer_id: customer === null || customer === void 0 ? void 0 : customer.id,
184
+ form_id: holderFormId,
185
+ form_record: [formRecordId]
186
+ });
187
+ yield refreshViewModel();
188
+ }
189
+ });
190
+ return function callback(_x) {
191
+ return _ref5.apply(this, arguments);
192
+ };
193
+ }()
194
+ });
195
+ }
196
+ if (type === "change_holder") {
197
+ var _engineContext$appHel9, _item$_origin3;
198
+ const customer = getCustomer(engineContext === null || engineContext === void 0 || (_engineContext$appHel9 = engineContext.appHelper) === null || _engineContext$appHel9 === void 0 ? void 0 : _engineContext$appHel9.utils);
199
+ const holder = (sourceItem === null || sourceItem === void 0 ? void 0 : sourceItem._origin) || sourceItem;
200
+ const params = !sourceItem ? null : {
201
+ customer_id: customer === null || customer === void 0 ? void 0 : customer.id,
202
+ form_id: holder === null || holder === void 0 ? void 0 : holder.form_id,
203
+ form_record: [holder === null || holder === void 0 ? void 0 : holder.form_record_id]
204
+ };
205
+ venueBookingModule.setBookingHolder(item === null || item === void 0 || (_item$_origin3 = item._origin) === null || _item$_origin3 === void 0 || (_item$_origin3 = _item$_origin3.product) === null || _item$_origin3 === void 0 ? void 0 : _item$_origin3.bookingUuid, params);
206
+ yield refreshViewModel();
207
+ return;
208
+ }
115
209
  if (type !== "delete") return;
116
210
  const targetItem = sourceItem && typeof sourceItem === "object" ? sourceItem : item;
117
211
  if (currentStep !== "select-venue" && isVenueBookingCartItem(targetItem)) {
@@ -137,8 +231,8 @@ function Cart(props) {
137
231
  });
138
232
  }
139
233
  });
140
- return function handleCartChange(_x, _x2, _x3) {
141
- return _ref5.apply(this, arguments);
234
+ return function handleCartChange(_x2, _x3, _x4) {
235
+ return _ref6.apply(this, arguments);
142
236
  };
143
237
  }();
144
238
  useEffect(() => {
@@ -154,9 +248,9 @@ function Cart(props) {
154
248
  isShowNote: false,
155
249
  isShowDelete: true,
156
250
  isShowPackageNote: false,
157
- isShowChangeHolder: false,
158
- isShowHolder: false,
159
- isShowAddHolderButton: false
251
+ isShowChangeHolder: currentStep === "checkout" ? false : !!isLogin,
252
+ isShowHolder: true,
253
+ isShowAddHolderButton: true
160
254
  },
161
255
  platform: "h5",
162
256
  emptyText: locales.getText("pisell2.venue.cart.empty"),
@@ -172,8 +266,8 @@ function Cart(props) {
172
266
  isAgreePolicy: isAgreeDepositPolicy,
173
267
  onChange: setIsAgreeDepositPolicy,
174
268
  getProtocol: (id) => {
175
- var _venueBookingModule$g2;
176
- return venueBookingModule === null || venueBookingModule === void 0 || (_venueBookingModule$g2 = venueBookingModule.getProtocol) === null || _venueBookingModule$g2 === void 0 ? void 0 : _venueBookingModule$g2.call(venueBookingModule, id);
269
+ var _venueBookingModule$g3;
270
+ return venueBookingModule === null || venueBookingModule === void 0 || (_venueBookingModule$g3 = venueBookingModule.getProtocol) === null || _venueBookingModule$g3 === void 0 ? void 0 : _venueBookingModule$g3.call(venueBookingModule, id);
177
271
  }
178
272
  }) : null), extraContent ? /* @__PURE__ */ React.createElement("div", { className: "pisell-venue-booking-cart-extra-content" }, extraContent) : null);
179
273
  if (embedded) return /* @__PURE__ */ React.createElement(React.Fragment, null, cartListContent, /* @__PURE__ */ React.createElement("div", { className: "pisell-venue-booking-cart-embedded-footer" }, cartSummaryContent, /* @__PURE__ */ React.createElement(Button$1, {
@@ -1,6 +1,7 @@
1
1
  import useEngineContext, { usePisellOS } from "../../hooks/useEngineContext.js";
2
2
  import { _objectSpread2 } from "../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js";
3
3
  import { _asyncToGenerator } from "../../_virtual/_@oxc-project_runtime@0.122.0/helpers/asyncToGenerator.js";
4
+ import { getVenueCartHolderConfig, validateRequiredCartHolders } from "../../utils/buildCartHolderParams.js";
4
5
  import { VENUE_PRODUCT_IDS, createVenueBookingViewModel, fetchResourceAvailability, getAllSelectedSlots, getDateRangeSummary, getOtherParams, getTimeSlotGrid, loadVenueProducts, safeRunModuleAction, toggleSlotAction, useVenueBookingLogin, useVenueBookingModule } from "./hooks.js";
5
6
  import { formatDateKey, getWeekDays } from "./utils.js";
6
7
  import dayjs from "dayjs";
@@ -501,13 +502,23 @@ function VenueBookingProvider({ entryContext, children }) {
501
502
  } });
502
503
  return;
503
504
  }
505
+ if (currentStep === "addons") {
506
+ const { hasError } = validateRequiredCartHolders({
507
+ items: viewModel.cartItems,
508
+ getHolderConfig: getVenueCartHolderConfig
509
+ });
510
+ if (hasError) return;
511
+ }
504
512
  goToStep("checkout");
505
513
  }, [
506
514
  isLogin,
507
515
  openLoginModal,
508
516
  handleLoginSuccess,
509
517
  goToStep,
510
- venueBookingModule
518
+ venueBookingModule,
519
+ currentStep,
520
+ viewModel.cartItems,
521
+ getVenueCartHolderConfig
511
522
  ]);
512
523
  /** 主操作按钮行为(含登录门禁,自适应 2/3 步流程) */
513
524
  const handlePrimaryAction = useCallback(() => {
@@ -543,9 +554,9 @@ function VenueBookingProvider({ entryContext, children }) {
543
554
  isAgreeDepositPolicy,
544
555
  viewModel.summary,
545
556
  stepList,
546
- proceedToCheckout,
547
557
  goToStep,
548
- handleSubmitOrder
558
+ handleSubmitOrder,
559
+ proceedToCheckout
549
560
  ]);
550
561
  useEffect(() => {
551
562
  var _pubsub$subscribe;