UNPKG

@pisell/pisellos

Version:

一个可扩展的前端模块化SDK框架,支持插件系统

536 lines (534 loc) 21.2 kB
var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/solution/ShopDiscount/index.ts var ShopDiscount_exports = {}; __export(ShopDiscount_exports, { ShopDiscountImpl: () => ShopDiscountImpl, default: () => ShopDiscount_default }); module.exports = __toCommonJS(ShopDiscount_exports); var import_BaseModule = require("../../modules/BaseModule"); var import_Discount = require("../../modules/Discount"); var import_Rules = require("../../modules/Rules"); var import_utils = require("./utils"); var import_decimal = __toESM(require("decimal.js")); var import_lodash_es = require("lodash-es"); var ShopDiscountImpl = class extends import_BaseModule.BaseModule { constructor(name, version) { super(name, version); this.defaultName = "shopDiscount"; this.defaultVersion = "1.0.0"; this.isSolution = true; this.options = {}; this.store = { customer: null, productList: [], discount: null, rules: null, holders: [], originalDiscountList: [], currentBookingTime: "", filteredDiscountList: [], bookingSubject: void 0, orderTotalAmount: 0 }; } // =========== 生命周期方法 =========== async initialize(core, options) { var _a, _b; this.core = core; this.options = options; this.store = { ...this.store, ...options.store || {} }; this.hooks = (_b = (_a = options.otherParams) == null ? void 0 : _a.rules) == null ? void 0 : _b.hooks; console.log("[ShopDiscount] 初始化完成"); this.initializePlugins(); this.registerDependentModules(); this.registerEventListeners(); } async destroy() { var _a, _b; this.store.productList = []; this.store.customer = null; (_a = this.store.discount) == null ? void 0 : _a.destroy(); (_b = this.store.rules) == null ? void 0 : _b.destroy(); this.core.effects.offByModuleDestroy(this.name); await this.core.effects.emit(`${this.name}:onDestroy`, {}); console.log("[ShopDiscount] 已销毁"); } async clear() { var _a, _b; this.store.productList = []; this.store.customer = null; (_a = this.store.discount) == null ? void 0 : _a.clear(); (_b = this.store.rules) == null ? void 0 : _b.clear(); console.log("[ShopDiscount] clear"); } // =========== 初始化辅助方法 =========== initializePlugins() { this.request = this.core.getPlugin("request"); this.window = this.core.getPlugin("window"); if (!this.request) { throw new Error("ShopDiscount需要 request 插件支持"); } if (!this.window) { throw new Error("ShopDiscount需要 window 插件支持"); } } registerDependentModules() { var _a, _b, _c, _d, _e, _f, _g; let targetCacheData = {}; if ((_a = this.options.otherParams) == null ? void 0 : _a.cacheId) { const sessionData = this.window.sessionStorage.getItem(this.name); if (sessionData) { const data = JSON.parse(sessionData); targetCacheData = data[this.options.otherParams.cacheId]; } } const discount = new import_Discount.DiscountModule(`${this.name}_discount`); this.core.registerModule(discount, { initialState: targetCacheData == null ? void 0 : targetCacheData[discount.name], hooks: (_c = (_b = this.options.otherParams) == null ? void 0 : _b.discount) == null ? void 0 : _c.hooks, otherParams: { fatherModule: this.name, openCache: ((_d = this.options.otherParams) == null ? void 0 : _d.cacheId) ? true : false, cacheId: (_e = this.options.otherParams) == null ? void 0 : _e.cacheId } }); this.store.discount = discount; const rules = new import_Rules.RulesModule(`${this.name}_rules`); this.core.registerModule(rules, { hooks: (_g = (_f = this.options.otherParams) == null ? void 0 : _f.rules) == null ? void 0 : _g.hooks }); this.store.rules = rules; } registerEventListeners() { this.core.effects.only( `${this.name}:onCustomerChange`, (customer) => { var _a; if (((_a = this.options.otherParams) == null ? void 0 : _a.cacheId) && this.getDiscountList().length) { return; } this.loadPrepareConfig({ customerId: customer.id, action: "create", with_good_pass: 1, with_discount_card: 1 }); } ); } // =========== 公共 API =========== // 设置预约时间 // public async setBookingTime(bookingTime: string | null): Promise<void> { // if (this.store.currentBookingTime !== bookingTime) { // this.store.currentBookingTime = bookingTime; // // // 更新过滤后的优惠券列表 // await this.updateFilteredDiscountList(); // } // } // 获取当前预约时间 getCurrentBookingTime() { return this.store.currentBookingTime; } // 根据预约时间过滤优惠券列表 filterDiscountListByBookingTime(discountList, bookingTime) { if ((0, import_utils.isAllNormalProduct)(this.store.productList || [])) { return discountList; } return (0, import_utils.filterDiscountListByBookingTime)(discountList, bookingTime); } // 更新过滤后的优惠券列表 // private async updateFilteredDiscountList(): Promise<void> { // const originalList = this.store.originalDiscountList; // const filteredList = this.filterDiscountListByBookingTime(originalList, this.store.currentBookingTime); // // this.store.filteredDiscountList = filteredList; // // // 更新 DiscountModule 中的优惠券列表 // this.setDiscountList(filteredList); // // if (this.store.productList?.length) { // const result = this.calcDiscount(this.store.productList); // await this.core.effects.emit( // ShopDiscountHooks.onLoadPrepareCalcResult, // result, // ); // } // } // 设置客户 async setCustomer(customer) { var _a; if (((_a = this.store.customer) == null ? void 0 : _a.id) !== customer.id) { this.store.customer = customer; await this.core.effects.emit( `${this.name}:onCustomerChange`, customer ); } } setOriginTotalAmount(amount) { this.store.orderTotalAmount = amount; } // 设置holders setHolders(holders) { this.store.holders = holders; } setBookingSubject(bookingSubject) { this.store.bookingSubject = bookingSubject; } // 计算优惠券 calcDiscount(productList, options) { var _a; this.store.productList = productList; const rulesModule = this.core.getModule(`${this.name}_rules`); if (!rulesModule) { return { productList, discountList: this.getDiscountList() }; } let { productList: newProductList, discountList: newDiscountList } = rulesModule.calcDiscount( { productList, discountList: this.getDiscountList(), orderTotalAmount: this.store.orderTotalAmount || 0, holders: this.store.holders || [], isFormSubject: ((_a = this.store.bookingSubject) == null ? void 0 : _a.type) === "form" }, options ) || { productList, discountList: this.getDiscountList() }; if (newDiscountList) { newDiscountList = this.setDiscountList(newDiscountList); } return { productList: newProductList || productList, discountList: newDiscountList || this.getDiscountList() }; } // 设置优惠券使用状态 setDiscountSelected(params) { const discountList = this.getDiscountList(); const selectionOperations = []; selectionOperations.push({ discountId: params.discountId, isSelected: params.isSelected }); if (params.selectedList && params.selectedList.length > 0) { selectionOperations.push(...params.selectedList); } const selectionMap = /* @__PURE__ */ new Map(); selectionOperations.forEach((operation) => { selectionMap.set(operation.discountId, operation.isSelected); }); const newDiscountList = discountList.map((discount) => { if (discount.isEditMode) return discount; if (selectionMap.has(discount.id)) { const targetIsSelected = selectionMap.get(discount.id); return { ...discount, isSelected: targetIsSelected, // 手动设置不使用 isManualSelect: !targetIsSelected }; } return { ...discount, isManualSelect: !(discount == null ? void 0 : discount.isSelected) }; }); this.setDiscountList(newDiscountList); return this.calcDiscount(this.store.productList || [], params); } setProductList(productList) { this.store.productList = productList; } // 扫码输入code async scanCode(code, customerId) { var _a, _b, _c; try { const resultDiscountList = await ((_a = this.store.discount) == null ? void 0 : _a.batchSearch(code, customerId)) || []; const rulesModule = this.store.rules; if (!rulesModule) { return { type: "clientCalc", isAvailable: false, productList: this.store.productList || [], discountList: this.getDiscountList() }; } if (!resultDiscountList.length) { return { type: "server", isAvailable: false, productList: this.store.productList || [], discountList: this.getDiscountList() }; } const withScanList = resultDiscountList.map((item) => { return { ...item, isScan: true }; }); const currentSelectedDiscountList = this.getDiscountList().filter((n) => n.isSelected); if (currentSelectedDiscountList.length && currentSelectedDiscountList.some((n) => withScanList.some((m) => m.id === n.id))) { return { type: "clientCalc", isAvailable: true, productList: this.store.productList || [], discountList: this.getDiscountList() }; } const { productList: newProductList, discountList: newDiscountList, isAvailable } = rulesModule.isDiscountListAvailable({ productList: this.store.productList || [], oldDiscountList: this.getDiscountList(), newDiscountList: withScanList, holders: this.store.holders || [], isFormSubject: ((_b = this.store.bookingSubject) == null ? void 0 : _b.type) === "form", orderTotalAmount: this.store.orderTotalAmount || 0 }) || { isAvailable: false, productList: this.store.productList || [], discountList: this.getDiscountList() }; if (isAvailable) { this.setDiscountList(newDiscountList || []); this.store.originalDiscountList = newDiscountList || []; this.setProductList(newProductList || []); if (this.isWalkIn() && resultDiscountList.length && ((_c = this.options.otherParams) == null ? void 0 : _c.platform) === "shop") { await this.getCustomerWallet( resultDiscountList[0].customer_id ); } } return { type: "clientCalc", isAvailable: isAvailable || false, productList: newProductList || this.store.productList || [], discountList: newDiscountList || this.getDiscountList() }; } catch (error) { console.error("[ShopDiscount] 扫码出错:", error); return { type: "clientCalc", isAvailable: false, productList: this.store.productList || [], discountList: this.getDiscountList() }; } } calcDiscountApplicableProductTotalPrice(discount) { var _a; return (_a = this.store.discount) == null ? void 0 : _a.calcDiscountApplicableProductTotalPrice( discount ); } // =========== 私有辅助方法 =========== // 获取客户 getCustomer() { return this.store.customer; } // 是否是walkIn isWalkIn() { var _a; return (((_a = this.getCustomer()) == null ? void 0 : _a.id) || 1) === 1; } // 触发优惠列表变更事件 async emitDiscountListChange(discountList) { await this.core.effects.emit( `${this.name}:onDiscountListChange`, discountList ); } // 设置优惠券列表 setDiscountList(discountList) { var _a; const productList = this.store.productList || []; const editModeDiscountList = []; productList.forEach((item) => { var _a2; if (item.booking_id) { const product = (_a2 = this.hooks) == null ? void 0 : _a2.getProduct(item); (item.discount_list || []).forEach((discount) => { var _a3, _b, _c, _d, _e; if (discount.id && ["good_pass", "discount_card"].includes(discount.type)) { const index = editModeDiscountList.findIndex((n) => { var _a4; return n.id === (((_a4 = discount.discount) == null ? void 0 : _a4.resource_id) || discount.id); }); if (index !== -1) { editModeDiscountList[index] = { ...editModeDiscountList[index], amount: new import_decimal.default(discount.amount || 0).plus(new import_decimal.default(editModeDiscountList[index].amount || 0)).toNumber(), savedAmount: new import_decimal.default(discount.amount || 0).times((product == null ? void 0 : product.quantity) || (product == null ? void 0 : product.num) || 1).plus(((_a3 = discount == null ? void 0 : discount.metadata) == null ? void 0 : _a3.product_discount_difference) || 0).plus(new import_decimal.default(editModeDiscountList[index].savedAmount || 0)).toNumber() }; } else { if (discount.type && !discount.tag) { discount.tag = discount.type; } editModeDiscountList.push({ ...discount, name: discount.name || discount.discount.title.auto, isEditMode: true, limited_relation_product_data: {}, savedAmount: new import_decimal.default(discount.amount || 0).times((product == null ? void 0 : product.quantity) || (product == null ? void 0 : product.num) || 1).plus(((_b = discount == null ? void 0 : discount.metadata) == null ? void 0 : _b.product_discount_difference) || 0).toNumber(), isAvailable: true, id: ((_c = discount.discount) == null ? void 0 : _c.resource_id) || discount.id, format_title: ((_d = discount.discount) == null ? void 0 : _d.title) || discount.format_title, isDisabled: true, isSelected: true, product_id: ((_e = discount.discount) == null ? void 0 : _e.product_id) || discount.product_id }); } } }); } }); const newDiscountList = [ ...editModeDiscountList, ...discountList.filter((item) => !item.isDisabled) ]; const isProductFree = (id) => { var _a2; const targetProduct = productList.find((n) => n.id === id); if (!targetProduct) return false; const product = (_a2 = this.hooks) == null ? void 0 : _a2.getProduct(targetProduct); return Number(product == null ? void 0 : product.total) <= 0 && (Number(product == null ? void 0 : product.origin_total) <= 0 || !(product == null ? void 0 : product.origin_total)) || (0, import_lodash_es.isBoolean)(product == null ? void 0 : product.vouchersApplicable) && !(product == null ? void 0 : product.vouchersApplicable); }; const allUsedProductIds = newDiscountList.filter((item) => !(item == null ? void 0 : item.isEditMode)).map((n) => { var _a2; return n.isSelected ? ((_a2 = n.appliedProductDetails) == null ? void 0 : _a2.map((n2) => { var _a3; return (_a3 = n2.discount) == null ? void 0 : _a3.product_id; })) || n.product_id : []; }).flat(); newDiscountList.forEach((item) => { var _a2; const isAllProductUsedOrFree = (_a2 = item.applicableProductIds) == null ? void 0 : _a2.every((id) => { var _a3; const sameIdTimes = ((_a3 = item.applicableProductIds) == null ? void 0 : _a3.filter((n) => n === id).length) || 1; const targetIdTimes = (allUsedProductIds == null ? void 0 : allUsedProductIds.filter((n) => n === id).length) || 0; return targetIdTimes >= sameIdTimes || isProductFree(id); }); if (!item.isSelected && isAllProductUsedOrFree) { item.isDisabledForProductUsed = true; } else { item.isDisabledForProductUsed = false; } }); (_a = this.store.discount) == null ? void 0 : _a.setDiscountList(newDiscountList); this.emitDiscountListChange(newDiscountList); return newDiscountList; } // 获取优惠券列表 getDiscountList() { var _a; return ((_a = this.store.discount) == null ? void 0 : _a.getDiscountList()) || []; } // 获取客户钱包信息 async getCustomerWallet(id) { try { const result = await this.request.get(`/customer/info/${id}`, { with_trashed: 1 }); if (result == null ? void 0 : result.data) { const { ...customer } = result.data; this.setCustomer(customer); await this.core.effects.emit( `${this.name}:onScanCustomerChange`, customer ); } } catch (error) { console.error("[ShopDiscount] 获取客户钱包信息出错:", error); } } async bestDiscount(cb) { var _a; const newDiscountList = this.store.originalDiscountList; this.setDiscountList(newDiscountList); if ((_a = this.store.productList) == null ? void 0 : _a.length) { const result = this.calcDiscount(this.store.productList); cb == null ? void 0 : cb(result); await this.core.effects.emit( `${this.name}:onLoadPrepareCalcResult`, result ); } await this.core.effects.emit( `${this.name}:onLoadDiscountList`, newDiscountList ); } // 加载准备配置 async loadPrepareConfig(params) { var _a, _b, _c, _d, _e; try { const customerId = params.customerId || ((_a = this.getCustomer()) == null ? void 0 : _a.id); const goodPassList = await ((_b = this.store.discount) == null ? void 0 : _b.loadPrepareConfig({ customer_id: customerId, action: "create", with_good_pass: 1, with_discount_card: 1, with_wallet_pass_holder: 1, request_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone })); const scanDiscount = (_c = this.getDiscountList()) == null ? void 0 : _c.filter( (item) => item.isScan ); const scanDiscountIds = scanDiscount.map((n) => n.id); const newGoodPassList = goodPassList == null ? void 0 : goodPassList.filter((n) => !scanDiscountIds.includes(n.id)); const newDiscountList = [...scanDiscount, ...newGoodPassList || []]; this.store.originalDiscountList = newDiscountList; await ((_d = this.store.discount) == null ? void 0 : _d.setOriginalDiscountList(newDiscountList)); const filteredDiscountList = this.filterDiscountListByBookingTime(newDiscountList, this.store.currentBookingTime); this.store.filteredDiscountList = filteredDiscountList; this.setDiscountList(filteredDiscountList || []); if ((_e = this.store.productList) == null ? void 0 : _e.length) { const result = this.calcDiscount(this.store.productList); await this.core.effects.emit( `${this.name}:onLoadPrepareCalcResult`, result ); } await this.core.effects.emit( `${this.name}:onLoadDiscountList`, filteredDiscountList ); } catch (error) { console.error("[ShopDiscount] 加载准备配置出错:", error); } } }; var ShopDiscount_default = ShopDiscountImpl; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { ShopDiscountImpl });