@pisell/pisellos
Version:
一个可扩展的前端模块化SDK框架,支持插件系统
536 lines (534 loc) • 21.2 kB
JavaScript
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
});