@pisell/private-materials 6.12.361 → 6.12.362

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 (33) 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.css +1 -1
  6. package/build/lowcode/render/default/view.js +6 -6
  7. package/build/lowcode/view.css +1 -1
  8. package/build/lowcode/view.js +6 -6
  9. package/es/components/scanOrder/components/Check/index.js +95 -84
  10. package/es/components/scanOrder/locales.js +15 -0
  11. package/es/plus/skuOptionsSelection/utils/normalizeSelectorLayout.js +15 -0
  12. package/es/plus/skuOptionsSelection/utils/resolveCollectionLayout.js +2 -2
  13. package/es/plus/walletEditor/WalletEditor.js +19 -5
  14. package/es/plus/walletEditor/components/PassDisplayConfig/index.js +60 -0
  15. package/es/plus/walletEditor/components/PassDisplayConfig/index.less +27 -0
  16. package/es/plus/walletEditor/components/PassDisplayConfig/serve.js +18 -0
  17. package/es/plus/walletEditor/index.d.ts +1 -1
  18. package/es/plus/walletEditor/locales.js +40 -0
  19. package/es/plus/walletEditor/types.d.ts +8 -1
  20. package/es/plus/walletPassGallery/index.js +11 -6
  21. package/lib/components/scanOrder/components/Check/index.js +94 -83
  22. package/lib/components/scanOrder/locales.js +15 -0
  23. package/lib/plus/skuOptionsSelection/utils/normalizeSelectorLayout.js +15 -0
  24. package/lib/plus/skuOptionsSelection/utils/resolveCollectionLayout.js +2 -2
  25. package/lib/plus/walletEditor/WalletEditor.js +19 -5
  26. package/lib/plus/walletEditor/components/PassDisplayConfig/index.js +62 -0
  27. package/lib/plus/walletEditor/components/PassDisplayConfig/index.less +27 -0
  28. package/lib/plus/walletEditor/components/PassDisplayConfig/serve.js +18 -0
  29. package/lib/plus/walletEditor/index.d.ts +1 -1
  30. package/lib/plus/walletEditor/locales.js +40 -0
  31. package/lib/plus/walletEditor/types.d.ts +8 -1
  32. package/lib/plus/walletPassGallery/index.js +11 -6
  33. package/package.json +3 -3
@@ -4,7 +4,7 @@ import { useScanOrderContext } from "../../context.js";
4
4
  import Cart from "../Cart/index.js";
5
5
  import FulfillmentMode from "../FulfillmentMode/index.js";
6
6
  import ManualPickupRefModal from "../ManualPickupRefModal/index.js";
7
- import React, { useCallback, useEffect, useMemo, useState } from "react";
7
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
8
8
  import { Input, Modal, message } from "antd";
9
9
  import { locales } from "@pisell/utils";
10
10
  import { Button as Button$1, PisellLoading, PisellToast } from "@pisell/materials";
@@ -14,6 +14,8 @@ function Check() {
14
14
  const { viewModel, runModuleAction, refreshViewModel, tableName, entryMode, clearStepCache, entryContext } = useScanOrderContext();
15
15
  const isAdditionalOrder = entryMode === "additional_order";
16
16
  const [submitting, setSubmitting] = useState(false);
17
+ const submittingRef = useRef(false);
18
+ const menuUnavailableRef = useRef(false);
17
19
  const [note, setNote] = useState((viewModel === null || viewModel === void 0 ? void 0 : viewModel.note) || "");
18
20
  const [pickupRefOpen, setPickupRefOpen] = useState(false);
19
21
  const [addOnConfirmOpen, setAddOnConfirmOpen] = useState(false);
@@ -51,9 +53,52 @@ function Check() {
51
53
  const showSubmitFailedTip = useCallback((tip) => {
52
54
  PisellToast({ content: String(tip || locales.getText("pisell2.scan.order.submit.failed") || "Submit order failed") });
53
55
  }, []);
56
+ const handleMenuValidationFailure = (error) => {
57
+ if ((error === null || error === void 0 ? void 0 : error.code) === "SCAN_ORDER_MENU_UNAVAILABLE") {
58
+ if (menuUnavailableRef.current) return true;
59
+ menuUnavailableRef.current = true;
60
+ Modal.info({
61
+ title: String(locales.getText("pisell2.scan.order.menu.unavailable.title") || "Ordering time has ended"),
62
+ content: String(locales.getText("pisell2.scan.order.menu.unavailable.description") || "Some items in your cart are no longer available to order at this time. Select Confirm to refresh the page and choose your items again."),
63
+ okText: String(locales.getText("pisell2.event.confirm") || "OK"),
64
+ maskClosable: false,
65
+ keyboard: false,
66
+ closable: false,
67
+ onOk: () => {
68
+ const url = new URL(window.location.href);
69
+ url.searchParams.delete("cacheId");
70
+ window.location.replace(url.toString());
71
+ }
72
+ });
73
+ return true;
74
+ }
75
+ if ((error === null || error === void 0 ? void 0 : error.code) === "SCAN_ORDER_MENU_VALIDATION_FAILED") {
76
+ showSubmitFailedTip(String(locales.getText("pisell2.scan.order.menu.validation.failed") || "Unable to check the ordering time. Please try again. Your cart has been kept."));
77
+ return true;
78
+ }
79
+ return false;
80
+ };
81
+ const runSubmitAction = function() {
82
+ var _ref = _asyncToGenerator(function* (action) {
83
+ if (submittingRef.current || menuUnavailableRef.current) return;
84
+ submittingRef.current = true;
85
+ setSubmitting(true);
86
+ try {
87
+ yield action();
88
+ } catch (error) {
89
+ console.error("[scanOrder] submit action failed", error);
90
+ if (!handleMenuValidationFailure(error)) showSubmitFailedTip(error === null || error === void 0 ? void 0 : error.message);
91
+ } finally {
92
+ submittingRef.current = false;
93
+ setSubmitting(false);
94
+ }
95
+ });
96
+ return function runSubmitAction(_x) {
97
+ return _ref.apply(this, arguments);
98
+ };
99
+ }();
54
100
  const showInventoryInsufficientModal = useCallback((error) => {
55
101
  var _error$data;
56
- setSubmitting(false);
57
102
  const productNames = (Array.isArray(error === null || error === void 0 || (_error$data = error.data) === null || _error$data === void 0 ? void 0 : _error$data.unavailable_products) ? error.data.unavailable_products : []).map((product) => String((product === null || product === void 0 ? void 0 : product.title) || (product === null || product === void 0 ? void 0 : product.product_id) || "").trim()).filter(Boolean);
58
103
  const title = String(locales.getText("pisell2.scan.order.inventory.insufficient.title") || "Insufficient inventory");
59
104
  const description = String(locales.getText("pisell2.scan.order.inventory.insufficient.description") || "The following items are out of stock or do not have enough inventory. Please adjust your cart and try again.");
@@ -67,24 +112,22 @@ function Check() {
67
112
  });
68
113
  }, []);
69
114
  const doSubmit = function() {
70
- var _ref2 = _asyncToGenerator(function* () {
115
+ var _ref3 = _asyncToGenerator(function* () {
71
116
  if (((viewModel === null || viewModel === void 0 ? void 0 : viewModel.cartItems) || []).length === 0) {
72
117
  showCheckStepEmptyCartTip();
73
- setSubmitting(false);
74
118
  return;
75
119
  }
76
120
  try {
77
121
  var _res$data;
78
- setSubmitting(true);
79
122
  yield runModuleAction("updateTempOrderNote", note);
80
123
  const res = yield runModuleAction("submitScanOrder");
81
124
  console.log("submitScanOrder >>>>> ", res);
82
125
  if ((res === null || res === void 0 ? void 0 : res.status) === false) {
126
+ if (handleMenuValidationFailure(res)) return;
83
127
  if ((res === null || res === void 0 ? void 0 : res.code) === 6008) {
84
128
  showInventoryInsufficientModal(res);
85
129
  return;
86
130
  }
87
- setSubmitting(false);
88
131
  showSubmitFailedTip(res === null || res === void 0 ? void 0 : res.message);
89
132
  return;
90
133
  }
@@ -102,7 +145,6 @@ function Check() {
102
145
  }[channel] || channel;
103
146
  if (shouldPayOnSubmit) {
104
147
  var _res$data2, _viewModel$summary;
105
- setSubmitting(false);
106
148
  utils.action({
107
149
  type: "pisell1.payment",
108
150
  data: {
@@ -111,15 +153,15 @@ function Check() {
111
153
  sale_channel: saleChannel
112
154
  },
113
155
  callback: function() {
114
- var _ref = _asyncToGenerator(function* (_e) {
156
+ var _ref2 = _asyncToGenerator(function* (_e) {
115
157
  try {
116
158
  yield runModuleAction("restoreOrder");
117
159
  } catch (error) {
118
160
  console.warn("[scanOrder] restoreOrder after payment failed", error);
119
161
  }
120
162
  });
121
- return function callback(_x) {
122
- return _ref.apply(this, arguments);
163
+ return function callback(_x2) {
164
+ return _ref2.apply(this, arguments);
123
165
  };
124
166
  }()
125
167
  });
@@ -143,96 +185,65 @@ function Check() {
143
185
  yield refreshViewModel();
144
186
  } catch (error) {
145
187
  console.error("[scanOrder] submitScanOrder failed", error);
146
- if ((error === null || error === void 0 ? void 0 : error.code) === 670005) {
147
- setSubmitting(false);
148
- showSubmitFailedTip(String(locales.getText("pisell2.scan.order.settled.cannot.add.tip") || ""));
149
- } else if ((error === null || error === void 0 ? void 0 : error.code) === 670007 && (entryContext === null || entryContext === void 0 ? void 0 : entryContext.resource_id)) {
188
+ if (handleMenuValidationFailure(error)) return;
189
+ if ((error === null || error === void 0 ? void 0 : error.code) === 670005) showSubmitFailedTip(String(locales.getText("pisell2.scan.order.settled.cannot.add.tip") || ""));
190
+ else if ((error === null || error === void 0 ? void 0 : error.code) === 670007 && (entryContext === null || entryContext === void 0 ? void 0 : entryContext.resource_id)) {
150
191
  const reservationResourceSelectType = yield runModuleAction("getReservationResourceSelectType");
151
192
  const allowAddItems = yield runModuleAction("checkAllowAddItems");
152
193
  const res = yield runModuleAction("syncAdditionalOrderFromResource", entryContext === null || entryContext === void 0 ? void 0 : entryContext.resource_id);
153
- if (reservationResourceSelectType.resourceSelectType === "single" && (allowAddItems === null || allowAddItems === void 0 ? void 0 : allowAddItems.enabled) && (res === null || res === void 0 ? void 0 : res.matched)) {
154
- setSubmitting(false);
155
- setAddOnConfirmOpen(true);
156
- } else {
157
- setSubmitting(false);
158
- showSubmitFailedTip(error === null || error === void 0 ? void 0 : error.message);
159
- }
194
+ if (reservationResourceSelectType.resourceSelectType === "single" && (allowAddItems === null || allowAddItems === void 0 ? void 0 : allowAddItems.enabled) && (res === null || res === void 0 ? void 0 : res.matched)) setAddOnConfirmOpen(true);
195
+ else showSubmitFailedTip(error === null || error === void 0 ? void 0 : error.message);
160
196
  } else if ((error === null || error === void 0 ? void 0 : error.code) === 6008) showInventoryInsufficientModal(error);
161
- else {
162
- setSubmitting(false);
163
- showSubmitFailedTip(error === null || error === void 0 ? void 0 : error.message);
164
- }
197
+ else showSubmitFailedTip(error === null || error === void 0 ? void 0 : error.message);
165
198
  }
166
199
  });
167
200
  return function doSubmit() {
168
- return _ref2.apply(this, arguments);
169
- };
170
- }();
171
- const handleSubmit = function() {
172
- var _ref3 = _asyncToGenerator(function* () {
173
- if (submitting) return;
174
- if (((viewModel === null || viewModel === void 0 ? void 0 : viewModel.cartItems) || []).length === 0) {
175
- showCheckStepEmptyCartTip();
176
- return;
177
- }
178
- if (isAdditionalOrder) {
179
- yield doSubmit();
180
- return;
181
- }
182
- try {
183
- setSubmitting(true);
184
- const manualPickup = yield runModuleAction("checkManualPickupRef");
185
- if (manualPickup === null || manualPickup === void 0 ? void 0 : manualPickup.enabled) {
186
- setPickupRefOpen(true);
187
- setSubmitting(false);
188
- return;
189
- }
190
- } catch (error) {
191
- console.error("[scanOrder] checkManualPickupRef failed", error);
192
- message.error((error === null || error === void 0 ? void 0 : error.message) || "Submit order failed");
193
- setSubmitting(false);
194
- return;
195
- }
196
- yield doSubmit();
197
- });
198
- return function handleSubmit() {
199
201
  return _ref3.apply(this, arguments);
200
202
  };
201
203
  }();
202
- const handlePickupRefConfirm = function() {
203
- var _ref4 = _asyncToGenerator(function* (value) {
204
- try {
205
- setSubmitting(true);
206
- yield runModuleAction("setPickupRef", value);
207
- } catch (error) {
208
- console.error("[scanOrder] setPickupRef failed", error);
209
- message.error((error === null || error === void 0 ? void 0 : error.message) || "Submit order failed");
210
- setSubmitting(false);
204
+ const handleSubmit = () => runSubmitAction(_asyncToGenerator(function* () {
205
+ if (((viewModel === null || viewModel === void 0 ? void 0 : viewModel.cartItems) || []).length === 0) {
206
+ showCheckStepEmptyCartTip();
207
+ return;
208
+ }
209
+ if (isAdditionalOrder) {
210
+ yield doSubmit();
211
+ return;
212
+ }
213
+ try {
214
+ const manualPickup = yield runModuleAction("checkManualPickupRef");
215
+ if (manualPickup === null || manualPickup === void 0 ? void 0 : manualPickup.enabled) {
216
+ setPickupRefOpen(true);
211
217
  return;
212
218
  }
213
- setPickupRefOpen(false);
214
- yield doSubmit();
215
- });
216
- return function handlePickupRefConfirm(_x2) {
217
- return _ref4.apply(this, arguments);
218
- };
219
- }();
219
+ } catch (error) {
220
+ console.error("[scanOrder] checkManualPickupRef failed", error);
221
+ message.error((error === null || error === void 0 ? void 0 : error.message) || "Submit order failed");
222
+ return;
223
+ }
224
+ yield doSubmit();
225
+ }));
226
+ const handlePickupRefConfirm = (value) => runSubmitAction(_asyncToGenerator(function* () {
227
+ try {
228
+ yield runModuleAction("setPickupRef", value);
229
+ } catch (error) {
230
+ console.error("[scanOrder] setPickupRef failed", error);
231
+ message.error((error === null || error === void 0 ? void 0 : error.message) || "Submit order failed");
232
+ return;
233
+ }
234
+ setPickupRefOpen(false);
235
+ yield doSubmit();
236
+ }));
220
237
  const handlePickupRefCancel = () => {
221
- if (submitting) return;
238
+ if (submittingRef.current) return;
222
239
  setPickupRefOpen(false);
223
240
  };
224
- const handleAddOnConfirm = function() {
225
- var _ref5 = _asyncToGenerator(function* () {
226
- if (submitting) return;
227
- setAddOnConfirmOpen(false);
228
- yield doSubmit();
229
- });
230
- return function handleAddOnConfirm() {
231
- return _ref5.apply(this, arguments);
232
- };
233
- }();
241
+ const handleAddOnConfirm = () => runSubmitAction(_asyncToGenerator(function* () {
242
+ setAddOnConfirmOpen(false);
243
+ yield doSubmit();
244
+ }));
234
245
  const handleAddOnReturn = () => {
235
- if (submitting) return;
246
+ if (submittingRef.current) return;
236
247
  setAddOnConfirmOpen(false);
237
248
  };
238
249
  const noteContent = /* @__PURE__ */ React.createElement("div", { className: "pisell-scan-order-check-note" }, /* @__PURE__ */ React.createElement("div", { className: "pisell-scan-order-check-note-title" }, noteTitle), /* @__PURE__ */ React.createElement(Input.TextArea, {
@@ -32,6 +32,9 @@ var locales_default = {
32
32
  "pisell2.scan.order.check.cart.empty.tip": "Please go back to add products",
33
33
  "pisell2.scan.order.submit.disabled.default": "Order submission is currently disabled.",
34
34
  "pisell2.scan.order.submit.failed": "Failed to submit order",
35
+ "pisell2.scan.order.menu.unavailable.title": "Ordering time has ended",
36
+ "pisell2.scan.order.menu.unavailable.description": "Some items in your cart are no longer available to order at this time. Select Confirm to refresh the page and choose your items again.",
37
+ "pisell2.scan.order.menu.validation.failed": "Unable to check the ordering time. Please try again. Your cart has been kept.",
35
38
  "pisell2.scan.order.multiple.orders.tip": "There are multiple active orders for this table. Please contact staff for add-on orders.",
36
39
  "pisell2.scan.order.multiple.orders.confirm": "I Got It",
37
40
  "pisell2.scan.order.settled.cannot.add.tip": "This order has already been settled and you cannot add more items. Please scan again to create a new order or contact staff.",
@@ -97,6 +100,9 @@ var locales_default = {
97
100
  "pisell2.scan.order.check.cart.empty.tip": "请返回添加商品",
98
101
  "pisell2.scan.order.submit.disabled.default": "当前暂不可下单",
99
102
  "pisell2.scan.order.submit.failed": "订单提交失败",
103
+ "pisell2.scan.order.menu.unavailable.title": "已过可下单时间",
104
+ "pisell2.scan.order.menu.unavailable.description": "购物车中有商品已不在可下单时间内。点击确定后将刷新页面,请重新选择商品。",
105
+ "pisell2.scan.order.menu.validation.failed": "暂时无法校验商品的可下单时间,请重试。购物车已保留。",
100
106
  "pisell2.scan.order.multiple.orders.tip": "当前桌台存在多个进行中的订单,请联系店员处理加餐。",
101
107
  "pisell2.scan.order.multiple.orders.confirm": "我知道了",
102
108
  "pisell2.scan.order.settled.cannot.add.tip": "当前订单已结账,无法继续加餐。请重新扫码创建新订单或联系店员。",
@@ -162,6 +168,9 @@ var locales_default = {
162
168
  "pisell2.scan.order.check.cart.empty.tip": "請返回添加商品",
163
169
  "pisell2.scan.order.submit.disabled.default": "當前暫不可下單",
164
170
  "pisell2.scan.order.submit.failed": "訂單提交失敗",
171
+ "pisell2.scan.order.menu.unavailable.title": "已過可下單時間",
172
+ "pisell2.scan.order.menu.unavailable.description": "購物車中有商品已不在可下單時間內。點擊確定後將重新整理頁面,請重新選擇商品。",
173
+ "pisell2.scan.order.menu.validation.failed": "暫時無法核實商品的可下單時間,請重試。購物車已保留。",
165
174
  "pisell2.scan.order.multiple.orders.tip": "當前桌台存在多個進行中的訂單,請聯繫店員處理加餐。",
166
175
  "pisell2.scan.order.multiple.orders.confirm": "我知道了",
167
176
  "pisell2.scan.order.settled.cannot.add.tip": "當前訂單已結賬,無法繼續加餐。請重新掃碼創建新訂單或聯繫店員。",
@@ -227,6 +236,9 @@ var locales_default = {
227
236
  "pisell2.scan.order.check.cart.empty.tip": "商品を追加するには、前の画面に戻ってください",
228
237
  "pisell2.scan.order.submit.disabled.default": "現在、注文を送信できません。",
229
238
  "pisell2.scan.order.submit.failed": "注文の送信に失敗しました",
239
+ "pisell2.scan.order.menu.unavailable.title": "注文可能な時間を過ぎています",
240
+ "pisell2.scan.order.menu.unavailable.description": "カートに注文可能な時間を過ぎた商品があります。「確認」を押すとページが再読み込みされます。商品を選び直してください。",
241
+ "pisell2.scan.order.menu.validation.failed": "注文可能な時間を確認できませんでした。もう一度お試しください。カートの内容は保持されています。",
230
242
  "pisell2.scan.order.multiple.orders.tip": "現在のテーブルには進行中の注文が複数あります。追加注文についてはスタッフにお問い合わせください。",
231
243
  "pisell2.scan.order.multiple.orders.confirm": "了解しました",
232
244
  "pisell2.scan.order.settled.cannot.add.tip": "現在の注文はすでに会計済みのため、追加注文できません。再度QRコードをスキャンして新しい注文を作成するか、スタッフにお問い合わせください。",
@@ -292,6 +304,9 @@ var locales_default = {
292
304
  "pisell2.scan.order.check.cart.empty.tip": "Volte para adicionar produtos",
293
305
  "pisell2.scan.order.submit.disabled.default": "No momento, não é possível enviar pedidos.",
294
306
  "pisell2.scan.order.submit.failed": "Falha ao enviar o pedido",
307
+ "pisell2.scan.order.menu.unavailable.title": "O horário para pedidos terminou",
308
+ "pisell2.scan.order.menu.unavailable.description": "Alguns itens no carrinho não estão mais disponíveis para pedido neste horário. Selecione Confirmar para atualizar a página e escolher os itens novamente.",
309
+ "pisell2.scan.order.menu.validation.failed": "Não foi possível verificar o horário para pedidos. Tente novamente. Seu carrinho foi mantido.",
295
310
  "pisell2.scan.order.multiple.orders.tip": "Há vários pedidos ativos nesta mesa. Entre em contato com a equipe para adicionar itens.",
296
311
  "pisell2.scan.order.multiple.orders.confirm": "Entendi",
297
312
  "pisell2.scan.order.settled.cannot.add.tip": "Este pedido já foi finalizado e não é possível adicionar mais itens. Escaneie novamente para criar um novo pedido ou entre em contato com a equipe.",
@@ -0,0 +1,15 @@
1
+ import { _objectSpread2 } from "../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js";
2
+ //#region src/plus/skuOptionsSelection/utils/normalizeSelectorLayout.ts
3
+ /** 商品选项的固定栅格默认在手机端使用单列,保留显式响应式配置。 */
4
+ const normalizeSelectorLayout = (layout) => {
5
+ var _colConfig$span, _colConfig$xs, _colConfig$sm;
6
+ if (!layout || layout.type !== "antdGrid" || layout.responsive) return layout || null;
7
+ const colConfig = layout.colConfig || {};
8
+ const span = (_colConfig$span = colConfig.span) !== null && _colConfig$span !== void 0 ? _colConfig$span : 24 / (layout.columns || 1);
9
+ return _objectSpread2(_objectSpread2({}, layout), {}, { colConfig: _objectSpread2(_objectSpread2({}, colConfig), {}, {
10
+ xs: (_colConfig$xs = colConfig.xs) !== null && _colConfig$xs !== void 0 ? _colConfig$xs : 24,
11
+ sm: (_colConfig$sm = colConfig.sm) !== null && _colConfig$sm !== void 0 ? _colConfig$sm : span
12
+ }) });
13
+ };
14
+ //#endregion
15
+ export { normalizeSelectorLayout };
@@ -1,7 +1,7 @@
1
+ import { normalizeSelectorLayout } from "./normalizeSelectorLayout.js";
1
2
  //#region src/plus/skuOptionsSelection/utils/resolveCollectionLayout.ts
2
3
  function resolveCollectionLayout(collection, context, fallback) {
3
- if (!collection) return fallback;
4
- return typeof collection === "function" ? collection(context) : collection;
4
+ return normalizeSelectorLayout(!collection ? fallback : typeof collection === "function" ? collection(context) : collection) || fallback;
5
5
  }
6
6
  //#endregion
7
7
  export { resolveCollectionLayout };
@@ -10,6 +10,7 @@ import SortableWalletPassTypes, { DEFAULT_WALLET_PASS_TYPES_CONFIG } from "./com
10
10
  import ValidityPeriodSelector from "./components/ValidityPeriodSelector/index.js";
11
11
  import RelationProduct from "./components/relationProduct/index.js";
12
12
  import MobileWalletTemplate from "./components/MobileWalletTemplate/index.js";
13
+ import PassDisplayConfig from "./components/PassDisplayConfig/index.js";
13
14
  import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
14
15
  import { Form, InputNumber, Radio } from "antd";
15
16
  import { locales } from "@pisell/utils";
@@ -17,13 +18,14 @@ import { Icon, PisellModal, Translation, WalletCard } from "@pisell/materials";
17
18
  import "./WalletEditor.less";
18
19
  //#region src/plus/walletEditor/WalletEditor.tsx
19
20
  const WalletEditor = forwardRef((props, ref) => {
20
- var _context$appHelper, _context$appHelper$ut, _context$appHelper$ut2, _context$appHelper$ut3, _context$appHelper$ut4, _context$appHelper$ut5, _context$appHelper$ut6, _store$global;
21
+ var _context$appHelper, _context$appHelper$ut, _context$appHelper$ut2, _context$appHelper$ut3, _context$appHelper$ut4, _context$appHelper$ut5, _context$appHelper$ut6, _store$global, _context$appHelper2, _context$appHelper2$g;
21
22
  const { value, onChange, disabled = false, className, style } = props;
22
23
  const context = useEngineContext();
23
24
  if ((_context$appHelper = context.appHelper) === null || _context$appHelper === void 0 || (_context$appHelper = _context$appHelper.utils) === null || _context$appHelper === void 0 ? void 0 : _context$appHelper.request) request.setRequest(context.appHelper.utils.request);
24
25
  locales.init(locales_default, ((_context$appHelper$ut = context.appHelper.utils) === null || _context$appHelper$ut === void 0 || (_context$appHelper$ut = _context$appHelper$ut.storage) === null || _context$appHelper$ut === void 0 ? void 0 : _context$appHelper$ut.get("umi_locale")) || "en");
25
26
  const amountSymbol = ((_context$appHelper$ut2 = (_context$appHelper$ut3 = context.appHelper.utils).getData) === null || _context$appHelper$ut2 === void 0 ? void 0 : _context$appHelper$ut2.call(_context$appHelper$ut3, "shop_symbol")) || "";
26
27
  const shopName = ((_store$global = (((_context$appHelper$ut4 = (_context$appHelper$ut5 = context.appHelper.utils).getStore) === null || _context$appHelper$ut4 === void 0 || (_context$appHelper$ut4 = _context$appHelper$ut4.call(_context$appHelper$ut5)) === null || _context$appHelper$ut4 === void 0 || (_context$appHelper$ut6 = _context$appHelper$ut4.getState) === null || _context$appHelper$ut6 === void 0 ? void 0 : _context$appHelper$ut6.call(_context$appHelper$ut4)) || {}).global) === null || _store$global === void 0 || (_store$global = _store$global.shopDetail) === null || _store$global === void 0 ? void 0 : _store$global.name) || "";
28
+ const hasFranchisor = Boolean((_context$appHelper2 = context.appHelper) === null || _context$appHelper2 === void 0 || (_context$appHelper2 = _context$appHelper2.utils) === null || _context$appHelper2 === void 0 || (_context$appHelper2 = _context$appHelper2.businessUtils) === null || _context$appHelper2 === void 0 || (_context$appHelper2$g = _context$appHelper2.getAppByModal) === null || _context$appHelper2$g === void 0 ? void 0 : _context$appHelper2$g.call(_context$appHelper2, "franchisor"));
27
29
  const [sendConfigVisible, setSendConfigVisible] = useState(true);
28
30
  const [previewVisible, setPreviewVisible] = useState(false);
29
31
  const [form] = Form.useForm();
@@ -118,7 +120,19 @@ const WalletEditor = forwardRef((props, ref) => {
118
120
  }, /* @__PURE__ */ React.createElement(Translation, null)), /* @__PURE__ */ React.createElement(Form.Item, {
119
121
  label: locales.getText("validityPeriod"),
120
122
  name: "valid_for"
121
- }, /* @__PURE__ */ React.createElement(ValidityPeriodSelector, null)), /* @__PURE__ */ React.createElement(Form.Item, {
123
+ }, /* @__PURE__ */ React.createElement(ValidityPeriodSelector, null)), hasFranchisor && /* @__PURE__ */ React.createElement(Form.Item, {
124
+ label: locales.getText("passesShownInWallet"),
125
+ name: ["metadata", "pass_visibility"],
126
+ rules: [{ validator: function() {
127
+ var _ref2 = _asyncToGenerator(function* (_, value) {
128
+ var _value$shop_ids;
129
+ if ((value === null || value === void 0 ? void 0 : value.type) === "selected_franchisees" && !((_value$shop_ids = value.shop_ids) === null || _value$shop_ids === void 0 ? void 0 : _value$shop_ids.length)) throw new Error(locales.getText("passIssuerShopsRequired"));
130
+ });
131
+ return function validator(_x3, _x4) {
132
+ return _ref2.apply(this, arguments);
133
+ };
134
+ }() }]
135
+ }, /* @__PURE__ */ React.createElement(PassDisplayConfig, { disabled })), /* @__PURE__ */ React.createElement(Form.Item, {
122
136
  label: locales.getText("linkedPasses"),
123
137
  name: "relation_id",
124
138
  initialValue: []
@@ -127,7 +141,7 @@ const WalletEditor = forwardRef((props, ref) => {
127
141
  name: ["metadata", "holder"],
128
142
  initialValue: { type: "customer" },
129
143
  rules: [{ validator: function() {
130
- var _ref2 = _asyncToGenerator(function* (_, value) {
144
+ var _ref3 = _asyncToGenerator(function* (_, value) {
131
145
  if ((value === null || value === void 0 ? void 0 : value.type) === "custom") {
132
146
  var _value$custom, _holderSelectorRef$cu, _holderSelectorRef$cu2;
133
147
  if (!(value === null || value === void 0 || (_value$custom = value.custom) === null || _value$custom === void 0 ? void 0 : _value$custom.custom_id)) return Promise.reject(new Error(locales.getText("pisell2.wallet-editor.holder.required")));
@@ -139,8 +153,8 @@ const WalletEditor = forwardRef((props, ref) => {
139
153
  }
140
154
  return Promise.resolve();
141
155
  });
142
- return function validator(_x3, _x4) {
143
- return _ref2.apply(this, arguments);
156
+ return function validator(_x5, _x6) {
157
+ return _ref3.apply(this, arguments);
144
158
  };
145
159
  }() }]
146
160
  }, /* @__PURE__ */ React.createElement(HolderSelector, { ref: holderSelectorRef })), /* @__PURE__ */ React.createElement(Form.Item, {
@@ -0,0 +1,60 @@
1
+ import { _objectSpread2 } from "../../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js";
2
+ import { getFranchiseeShops } from "./serve.js";
3
+ import React from "react";
4
+ import { Button, Radio, Select } from "antd";
5
+ import { locales } from "@pisell/utils";
6
+ import { useRequest } from "ahooks";
7
+ import "./index.less";
8
+ //#region src/plus/walletEditor/components/PassDisplayConfig/index.tsx
9
+ const PassDisplayConfig = ({ id, value = {
10
+ type: "self",
11
+ shop_ids: []
12
+ }, onChange, disabled = false }) => {
13
+ const { data: shops = [], loading, error, refresh } = useRequest(getFranchiseeShops, { ready: value.type === "selected_franchisees" });
14
+ return /* @__PURE__ */ React.createElement("div", {
15
+ id,
16
+ className: "wallet-pass-display-config"
17
+ }, /* @__PURE__ */ React.createElement("div", { className: "wallet-pass-display-config__label" }, locales.getText("showPassesIssuedBy")), /* @__PURE__ */ React.createElement("div", {
18
+ role: "radiogroup",
19
+ "aria-label": locales.getText("showPassesIssuedBy")
20
+ }, /* @__PURE__ */ React.createElement(Radio.Group, {
21
+ className: "wallet-pass-display-config__scope",
22
+ value: value.type,
23
+ onChange: (event) => onChange === null || onChange === void 0 ? void 0 : onChange(_objectSpread2(_objectSpread2({}, value), {}, { type: event.target.value })),
24
+ disabled
25
+ }, /* @__PURE__ */ React.createElement(Radio, {
26
+ value: "self",
27
+ className: "wallet-pass-display-config__option"
28
+ }, locales.getText("passIssuerCurrentShop")), /* @__PURE__ */ React.createElement(Radio, {
29
+ value: "all_franchisees",
30
+ className: "wallet-pass-display-config__option"
31
+ }, locales.getText("passIssuerAllShops")), /* @__PURE__ */ React.createElement(Radio, {
32
+ value: "selected_franchisees",
33
+ className: "wallet-pass-display-config__option"
34
+ }, locales.getText("passIssuerSpecifiedShops")))), value.type === "selected_franchisees" && /* @__PURE__ */ React.createElement("div", { className: "wallet-pass-display-config__shops" }, /* @__PURE__ */ React.createElement(Select, {
35
+ className: "wallet-pass-display-config__shop-select",
36
+ mode: "multiple",
37
+ allowClear: true,
38
+ showSearch: true,
39
+ optionFilterProp: "name",
40
+ maxTagCount: "responsive",
41
+ placeholder: locales.getText("passIssuerSelectShops"),
42
+ "aria-label": locales.getText("passIssuerSelectShops"),
43
+ options: shops,
44
+ fieldNames: {
45
+ value: "source_shop_id",
46
+ label: "name"
47
+ },
48
+ loading,
49
+ notFoundContent: error && !loading ? /* @__PURE__ */ React.createElement(Button, {
50
+ type: "link",
51
+ size: "small",
52
+ onClick: refresh
53
+ }, locales.getText("passIssuerLoadFailedRetry")) : void 0,
54
+ value: value.shop_ids,
55
+ onChange: (shop_ids) => onChange === null || onChange === void 0 ? void 0 : onChange(_objectSpread2(_objectSpread2({}, value), {}, { shop_ids })),
56
+ disabled
57
+ })));
58
+ };
59
+ //#endregion
60
+ export { PassDisplayConfig as default };
@@ -0,0 +1,27 @@
1
+ .wallet-pass-display-config {
2
+ &__label {
3
+ margin-bottom: 8px;
4
+ color: var(--Gray-600, #475467);
5
+ font-size: 14px;
6
+ line-height: 22px;
7
+ }
8
+
9
+ [role='radiogroup'] .wallet-pass-display-config__scope {
10
+ display: flex;
11
+ flex-direction: column;
12
+ gap: 8px;
13
+
14
+ .wallet-pass-display-config__option {
15
+ margin: 0;
16
+ }
17
+ }
18
+
19
+ &__shops {
20
+ margin-top: 12px;
21
+ padding-left: 24px;
22
+
23
+ .wallet-pass-display-config__shop-select {
24
+ width: 100%;
25
+ }
26
+ }
27
+ }
@@ -0,0 +1,18 @@
1
+ import { _asyncToGenerator } from "../../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/asyncToGenerator.js";
2
+ import { request } from "../../../../utils/index.js";
3
+ //#region src/plus/walletEditor/components/PassDisplayConfig/serve.ts
4
+ const getFranchiseeShops = function() {
5
+ var _ref = _asyncToGenerator(function* () {
6
+ const { data } = yield request.getRequest().get("/shop/franchisor/shop", {
7
+ skip: 1,
8
+ num: 199,
9
+ status: "approved"
10
+ }, { isShopApi: true });
11
+ return data.list;
12
+ });
13
+ return function getFranchiseeShops() {
14
+ return _ref.apply(this, arguments);
15
+ };
16
+ }();
17
+ //#endregion
18
+ export { getFranchiseeShops };
@@ -1,2 +1,2 @@
1
- import { MultiLanguageTitle, SendConfig, ShowcaseWalletPassItem, ValidForConfig, WalletEditorProps, WalletEditorRef, WalletEditorValue, WalletMetadata, WalletPassType } from "./types.js";
1
+ import { MultiLanguageTitle, PassDisplayConfigValue, SendConfig, ShowcaseWalletPassItem, ValidForConfig, WalletEditorProps, WalletEditorRef, WalletEditorValue, WalletMetadata, WalletPassType } from "./types.js";
2
2
  import { WalletEditor } from "./WalletEditor.js";
@@ -3,6 +3,14 @@ var locales_default = {
3
3
  en: {
4
4
  walletName: "Wallet name",
5
5
  validityPeriod: "Validity Period",
6
+ passesShownInWallet: "Passes shown in this Wallet:",
7
+ showPassesIssuedBy: "Show passes issued by:",
8
+ passIssuerCurrentShop: "Current store",
9
+ passIssuerAllShops: "All stores in the chain",
10
+ passIssuerSpecifiedShops: "Specified stores",
11
+ passIssuerSelectShops: "Select stores",
12
+ passIssuerShopsRequired: "Please select at least one store",
13
+ passIssuerLoadFailedRetry: "Failed to load stores. Click to retry.",
6
14
  linkedPasses: "Linked passes",
7
15
  linkedPassesDesc: "Select the passes that will be available in this Wallet.",
8
16
  sort: "Sort",
@@ -54,6 +62,14 @@ var locales_default = {
54
62
  "zh-CN": {
55
63
  walletName: "钱包名称",
56
64
  validityPeriod: "有效期",
65
+ passesShownInWallet: "此钱包中显示的卡券:",
66
+ showPassesIssuedBy: "显示由以下门店发放的卡券:",
67
+ passIssuerCurrentShop: "当前门店",
68
+ passIssuerAllShops: "连锁内所有门店",
69
+ passIssuerSpecifiedShops: "指定门店",
70
+ passIssuerSelectShops: "选择门店",
71
+ passIssuerShopsRequired: "请至少选择一个门店",
72
+ passIssuerLoadFailedRetry: "门店加载失败,点击重试",
57
73
  linkedPasses: "包含的卡券",
58
74
  linkedPassesDesc: "选择此 Wallet 中可展示与使用的卡券。",
59
75
  sort: "排序",
@@ -105,6 +121,14 @@ var locales_default = {
105
121
  "zh-HK": {
106
122
  walletName: "錢包名稱",
107
123
  validityPeriod: "有效期",
124
+ passesShownInWallet: "此錢包中顯示的卡券:",
125
+ showPassesIssuedBy: "顯示由以下門店發放的卡券:",
126
+ passIssuerCurrentShop: "目前門店",
127
+ passIssuerAllShops: "連鎖內所有門店",
128
+ passIssuerSpecifiedShops: "指定門店",
129
+ passIssuerSelectShops: "選擇門店",
130
+ passIssuerShopsRequired: "請至少選擇一個門店",
131
+ passIssuerLoadFailedRetry: "門店載入失敗,點擊重試",
108
132
  linkedPasses: "包含的卡券",
109
133
  linkedPassesDesc: "選擇此 Wallet 中可展示與使用的卡券。",
110
134
  sort: "排序",
@@ -156,6 +180,14 @@ var locales_default = {
156
180
  ja: {
157
181
  walletName: "ウォレット名",
158
182
  validityPeriod: "有効期間",
183
+ passesShownInWallet: "このウォレットに表示するパス:",
184
+ showPassesIssuedBy: "次の店舗が発行したパスを表示:",
185
+ passIssuerCurrentShop: "現在の店舗",
186
+ passIssuerAllShops: "チェーン内のすべての店舗",
187
+ passIssuerSpecifiedShops: "指定した店舗",
188
+ passIssuerSelectShops: "店舗を選択",
189
+ passIssuerShopsRequired: "店舗を1つ以上選択してください",
190
+ passIssuerLoadFailedRetry: "店舗を読み込めませんでした。クリックして再試行。",
159
191
  linkedPasses: "リンクされたパス",
160
192
  linkedPassesDesc: "このウォレットで利用可能なパスを選択します。",
161
193
  sort: "並び替え",
@@ -207,6 +239,14 @@ var locales_default = {
207
239
  pt: {
208
240
  walletName: "Nome da carteira",
209
241
  validityPeriod: "Período de Validade",
242
+ passesShownInWallet: "Passes exibidos nesta carteira:",
243
+ showPassesIssuedBy: "Mostrar passes emitidos por:",
244
+ passIssuerCurrentShop: "Loja atual",
245
+ passIssuerAllShops: "Todas as lojas da rede",
246
+ passIssuerSpecifiedShops: "Lojas específicas",
247
+ passIssuerSelectShops: "Selecionar lojas",
248
+ passIssuerShopsRequired: "Selecione pelo menos uma loja",
249
+ passIssuerLoadFailedRetry: "Falha ao carregar lojas. Clique para tentar novamente.",
210
250
  linkedPasses: "Passes vinculados",
211
251
  linkedPassesDesc: "Selecione os passes que estarão disponíveis nesta Carteira.",
212
252
  sort: "Ordenar",
@@ -27,6 +27,12 @@ interface SendConfig {
27
27
  type: string;
28
28
  [key: string]: any;
29
29
  }
30
+ /** 在原展示范围上追加子店卡券的配置。 */
31
+ interface PassDisplayConfigValue {
32
+ type: 'self' | 'all_franchisees' | 'selected_franchisees';
33
+ /** 仅 selected_franchisees 使用,其他模式忽略。 */
34
+ shop_ids?: number[];
35
+ }
30
36
  interface WalletMetadata {
31
37
  mobile_wallet_id?: string | number;
32
38
  showcaseWalletPass?: string[];
@@ -35,6 +41,7 @@ interface WalletMetadata {
35
41
  customerName?: string;
36
42
  coverImage?: string;
37
43
  send_config?: SendConfig;
44
+ pass_visibility?: PassDisplayConfigValue;
38
45
  }
39
46
  interface WalletEditorValue {
40
47
  name?: MultiLanguageTitle;
@@ -56,4 +63,4 @@ interface WalletEditorProps {
56
63
  style?: React.CSSProperties;
57
64
  }
58
65
  //#endregion
59
- export { MultiLanguageTitle, SendConfig, ShowcaseWalletPassItem, ValidForConfig, WalletEditorProps, WalletEditorRef, WalletEditorValue, WalletMetadata, WalletPassType };
66
+ export { MultiLanguageTitle, PassDisplayConfigValue, SendConfig, ShowcaseWalletPassItem, ValidForConfig, WalletEditorProps, WalletEditorRef, WalletEditorValue, WalletMetadata, WalletPassType };