UNPKG

@pisell/pisellos

Version:

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

271 lines (252 loc) 11 kB
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); } function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } import { PROMOTION_ACTION_TYPES } from "./type"; // ============================================ // Promotion 适配器实现 // ============================================ /** * Promotion 适配器 * * 用于将促销活动业务数据转换为策略引擎可识别的格式 * 策略引擎只负责匹配,具体的优惠计算由业务层完成 */ export var PromotionAdapter = /*#__PURE__*/function () { function PromotionAdapter() { _classCallCheck(this, PromotionAdapter); _defineProperty(this, "name", 'PromotionAdapter'); _defineProperty(this, "version", '1.0.0'); } _createClass(PromotionAdapter, [{ key: "prepareContext", value: /** * 准备运行时上下文 * * 将业务数据转换为策略引擎可识别的 RuntimeContext */ function prepareContext(businessData) { var products = businessData.products, currentProduct = businessData.currentProduct, channel = businessData.channel, custom = businessData.custom; // 当前时间(用于时间条件判断) var now = new Date(); var currentDateTime = this.formatDateTime(now); // 如果有 currentProduct,用于单商品场景(商品卡片展示) var evaluatingProduct = currentProduct || (products.length > 0 ? products[0] : null); return { entities: { products: products, currentProduct: evaluatingProduct }, attributes: _objectSpread({ // 当前时间(格式化字符串,用于时间条件判断) currentDateTime: currentDateTime, // 当前评估的商品信息(用于 product_match 运算符) productIdAndVariantId: evaluatingProduct ? { product_id: evaluatingProduct.product_id, product_variant_id: evaluatingProduct.product_variant_id } : null, // 渠道 channel: channel || '', // 商品总数量 totalQuantity: products.reduce(function (sum, p) { return sum + p.quantity; }, 0), // 商品总金额 totalAmount: products.reduce(function (sum, p) { return sum + p.price * p.quantity; }, 0) }, custom), metadata: { timestamp: Date.now() } }; } /** * 转换执行结果 * * 将策略引擎的通用结果转换为业务层需要的格式 * 主要是整理 matchedActions,让业务层更容易使用 */ }, { key: "transformResult", value: function transformResult(result, businessData) { // 获取适用的商品列表 var applicableProducts = businessData ? this.getApplicableProducts(result, businessData) : []; if (!result.applicable) { return { isApplicable: false, applicableProducts: [], reason: result.message, reasonCode: result.code, strategyResult: result }; } // 获取第一个匹配的 action(按 priority 排序后的) var matchedAction = result.matchedActions[0]; if (!matchedAction) { return { isApplicable: false, applicableProducts: [], reason: 'No matched action', reasonCode: 'NO_ACTION', strategyResult: result }; } // 解析 action 详情 var actionDetail = this.parseActionDetail(matchedAction); return { isApplicable: true, actionType: matchedAction.type, actionDetail: actionDetail, applicableProducts: applicableProducts, strategyResult: result }; } /** * 格式化配置 */ }, { key: "formatConfig", value: function formatConfig(result, businessData) { return { result: result, businessData: businessData }; } // ============================================ // 私有辅助方法 // ============================================ /** * 格式化日期时间 */ }, { key: "formatDateTime", value: function formatDateTime(date) { var year = date.getFullYear(); var month = String(date.getMonth() + 1).padStart(2, '0'); var day = String(date.getDate()).padStart(2, '0'); var hours = String(date.getHours()).padStart(2, '0'); var minutes = String(date.getMinutes()).padStart(2, '0'); var seconds = String(date.getSeconds()).padStart(2, '0'); return "".concat(year, "-").concat(month, "-").concat(day, " ").concat(hours, ":").concat(minutes, ":").concat(seconds); } /** * 解析 Action 详情 * * 将 matchedAction 转换为更易用的结构 */ }, { key: "parseActionDetail", value: function parseActionDetail(action) { switch (action.type) { case PROMOTION_ACTION_TYPES.X_ITEMS_FOR_Y_PRICE: return this.parseXItemsForYPriceAction(action); case PROMOTION_ACTION_TYPES.BUY_X_GET_Y_FREE: return this.parseBuyXGetYFreeAction(action); default: return undefined; } } /** * 解析 X件Y元 Action */ }, { key: "parseXItemsForYPriceAction", value: function parseXItemsForYPriceAction(action) { var _config$allowCrossPro, _config$cumulative; var value = action.value || {}; var config = action.config || {}; return { type: PROMOTION_ACTION_TYPES.X_ITEMS_FOR_Y_PRICE, x: value.x || 2, price: value.price || 0, allowCrossProduct: (_config$allowCrossPro = config.allowCrossProduct) !== null && _config$allowCrossPro !== void 0 ? _config$allowCrossPro : true, cumulative: (_config$cumulative = config.cumulative) !== null && _config$cumulative !== void 0 ? _config$cumulative : true }; } /** * 解析 买X送Y Action */ }, { key: "parseBuyXGetYFreeAction", value: function parseBuyXGetYFreeAction(action) { var _config$cumulative2; var value = action.value || {}; var config = action.config || {}; return { type: PROMOTION_ACTION_TYPES.BUY_X_GET_Y_FREE, buyQuantity: value.buyQuantity || 1, freeQuantity: value.freeQuantity || 1, giftSelectionMode: config.giftSelectionMode || 'user_select', cumulative: (_config$cumulative2 = config.cumulative) !== null && _config$cumulative2 !== void 0 ? _config$cumulative2 : true, giftProducts: config.giftProducts || [] }; } /** * 获取适用的商品列表 * * 从购物车商品中筛选出符合策略条件的商品 */ }, { key: "getApplicableProducts", value: function getApplicableProducts(result, businessData) { var _this = this; var products = businessData.products; // 从策略配置中获取商品范围条件 var productMatchRule = this.findProductMatchRule(result.config); if (!productMatchRule) { // 如果没有商品范围条件,所有商品都适用 return products; } var configProducts = productMatchRule.value; // 筛选适用的商品 return products.filter(function (product) { return _this.isProductMatch(product, configProducts); }); } /** * 查找商品匹配规则 */ }, { key: "findProductMatchRule", value: function findProductMatchRule(config) { var _config$conditions; if (!(config !== null && config !== void 0 && (_config$conditions = config.conditions) !== null && _config$conditions !== void 0 && _config$conditions.rules)) { return null; } return config.conditions.rules.find(function (rule) { return rule.field === 'productIdAndVariantId' && (rule.operator === 'product_match' || rule.operator === 'object_in'); }); } /** * 检查商品是否匹配 */ }, { key: "isProductMatch", value: function isProductMatch(product, configProducts) { return configProducts.some(function (config) { // 首先检查 product_id if (config.product_id !== product.product_id) { return false; } // 如果配置的 product_variant_id = 0,只需要 product_id 匹配 if (config.product_variant_id === 0) { return true; } // 否则需要 product_variant_id 精确匹配 return config.product_variant_id === product.product_variant_id; }); } }]); return PromotionAdapter; }(); export default PromotionAdapter;