文章目录
-
- 在当今电子商务蓬勃发展的时代,促销活动已成为电商平台吸引用户、提升销量的核心手段。无论是限时折扣、满减优惠、买赠活动还是会员专享,这些促销规则都需要通过精心设计的接口来实现。对于使用WordPress开源系统的开发者而言,如何设计高效、灵活且易于维护的促销活动规则接口,是提升电商网站竞争力的关键。 本指南将基于WordPress开发环境,详细解析促销活动规则接口的5个核心逻辑设计,帮助行业新人和程序员快速掌握这一关键技术。我们将从基础架构设计开始,逐步深入到复杂的规则组合与扩展机制,每个部分都配有实际代码示例和最佳实践建议。
-
- 在WordPress中设计促销规则接口,首先需要建立合理的数据模型。我们建议使用自定义文章类型(Custom Post Type)来存储促销活动,同时利用自定义字段(Custom Fields)或元数据(Metadata)来存储规则参数。 // 注册促销活动自定义文章类型 function register_promotion_post_type() { $args = array( 'public' => true, 'label' => '促销活动', 'supports' => array('title', 'editor', 'custom-fields'), 'menu_icon' => 'dashicons-tag', 'has_archive' => true, ); register_post_type('promotion', $args); } add_action('init', 'register_promotion_post_type'); // 添加促销规则元数据 function add_promotion_meta_fields() { add_meta_box( 'promotion_rules', '促销规则设置', 'render_promotion_rules_meta_box', 'promotion', 'normal', 'high' ); } add_action('add_meta_boxes', 'add_promotion_meta_fields');
- 创建一个抽象基类,定义所有促销规则必须实现的方法,确保接口的一致性: abstract class Promotion_Rule_Base { protected $rule_id; protected $rule_data; public function __construct($rule_id, $rule_data) { $this->rule_id = $rule_id; $this->rule_data = $rule_data; } // 验证规则是否适用于当前购物车 abstract public function is_applicable($cart_data); // 应用规则计算折扣 abstract public function apply($cart_data); // 获取规则描述 abstract public function get_description(); // 验证规则配置是否有效 abstract public function validate_configuration(); }
- 使用工厂模式创建规则实例,提高代码的可维护性和扩展性: class Promotion_Rule_Factory { private static $rule_types = array(); public static function register_rule_type($type, $class_name) { self::$rule_types[$type] = $class_name; } public static function create_rule($rule_id, $rule_type, $rule_data) { if (!isset(self::$rule_types[$rule_type])) { throw new Exception("未知的规则类型: {$rule_type}"); } $class_name = self::$rule_types[$rule_type]; return new $class_name($rule_id, $rule_data); } public static function get_available_rule_types() { return array_keys(self::$rule_types); } }
-
- 折扣规则是最基础的促销类型,支持百分比折扣和固定金额折扣: class Discount_Rule extends Promotion_Rule_Base { const TYPE_PERCENTAGE = 'percentage'; const TYPE_FIXED_AMOUNT = 'fixed_amount'; public function is_applicable($cart_data) { // 检查活动时间 $current_time = current_time('timestamp'); $start_time = strtotime($this->rule_data['start_date']); $end_time = strtotime($this->rule_data['end_date']); if ($current_time < $start_time || $current_time > $end_time) { return false; } // 检查最低消费金额 if (isset($this->rule_data['min_amount']) && $cart_data['subtotal'] < $this->rule_data['min_amount']) { return false; } // 检查适用商品 if (!$this->check_applicable_products($cart_data['items'])) { return false; } return true; } public function apply($cart_data) { if (!$this->is_applicable($cart_data)) { return $cart_data; } $discount_amount = 0; if ($this->rule_data['discount_type'] === self::TYPE_PERCENTAGE) { $discount_amount = $cart_data['subtotal'] * ($this->rule_data['discount_value'] / 100); } else { $discount_amount = min($this->rule_data['discount_value'], $cart_data['subtotal']); } // 应用折扣 $cart_data['discount'] += $discount_amount; $cart_data['total'] = $cart_data['subtotal'] - $cart_data['discount']; // 记录应用详情 $cart_data['applied_rules'][] = array( 'rule_id' => $this->rule_id, 'rule_name' => $this->rule_data['name'], 'discount_amount' => $discount_amount, 'type' => 'discount' ); return $cart_data; } private function check_applicable_products($cart_items) { // 实现商品检查逻辑 // 可以基于商品ID、分类、标签等进行过滤 return true; } public function get_description() { $type = $this->rule_data['discount_type']; $value = $this->rule_data['discount_value']; if ($type === self::TYPE_PERCENTAGE) { return "享受{$value}%折扣"; } else { return "立减{$value}元"; } } public function validate_configuration() { // 验证折扣配置 $errors = array(); if (!isset($this->rule_data['discount_type']) || !in_array($this->rule_data['discount_type'], [self::TYPE_PERCENTAGE, self::TYPE_FIXED_AMOUNT])) { $errors[] = "折扣类型无效"; } if (!isset($this->rule_data['discount_value']) || !is_numeric($this->rule_data['discount_value']) || $this->rule_data['discount_value'] <= 0) { $errors[] = "折扣值必须为正数"; } if ($this->rule_data['discount_type'] === self::TYPE_PERCENTAGE && $this->rule_data['discount_value'] > 100) { $errors[] = "百分比折扣不能超过100%"; } return empty($errors) ? true : $errors; } }
- 满减规则鼓励用户达到特定消费金额,是提升客单价的有效手段: class Spend_X_Get_Y_Discount_Rule extends Promotion_Rule_Base { public function is_applicable($cart_data) { // 检查是否达到满减门槛 return $cart_data['subtotal'] >= $this->rule_data['threshold']; } public function apply($cart_data) { if (!$this->is_applicable($cart_data)) { return $cart_data; } $discount_amount = $this->calculate_discount($cart_data['subtotal']); // 应用折扣 $cart_data['discount'] += $discount_amount; $cart_data['total'] = $cart_data['subtotal'] - $cart_data['discount']; // 记录应用详情 $cart_data['applied_rules'][] = array( 'rule_id' => $this->rule_id, 'rule_name' => $this->rule_data['name'], 'discount_amount' => $discount_amount, 'type' => 'spend_x_get_y' ); return $cart_data; } private function calculate_discount($subtotal) { $threshold = $this->rule_data['threshold']; $discount = $this->rule_data['discount']; // 支持多级满减 if (isset($this->rule_data['multi_level']) && $this->rule_data['multi_level']) { $levels = $this->rule_data['levels']; usort($levels, function($a, $b) { return $b['threshold'] - $a['threshold']; }); foreach ($levels as $level) { if ($subtotal >= $level['threshold']) { return $level['discount']; } } } return $discount; } public function get_description() { $threshold = $this->rule_data['threshold']; $discount = $this->rule_data['discount']; if (isset($this->rule_data['multi_level']) && $this->rule_data['multi_level']) { $descriptions = array(); foreach ($this->rule_data['levels'] as $level) { $descriptions[] = "满{$level['threshold']}减{$level['discount']}"; } return implode(',', $descriptions); } return "满{$threshold}减{$discount}"; } public function validate_configuration() { $errors = array(); if (!isset($this->rule_data['threshold']) || $this->rule_data['threshold'] <= 0) { $errors[] = "满减门槛必须大于0"; } if (!isset($this->rule_data['discount']) || $this->rule_data['discount'] <= 0) { $errors[] = "折扣金额必须大于0"; } if (isset($this->rule_data['multi_level']) && $this->rule_data['multi_level']) { if (!isset($this->rule_data['levels']) || !is_array($this->rule_data['levels'])) { $errors[] = "多级满减必须设置级别"; } else { foreach ($this->rule_data['levels'] as $index => $level) { if (!isset($level['threshold']) || !isset($level['discount'])) { $errors[] = "第" . ($index + 1) . "级满减配置不完整"; } } } } return empty($errors) ? true : $errors; } }
- 买赠规则通过赠送商品或礼品来刺激消费: class Buy_X_Get_Y_Free_Rule extends Promotion_Rule_Base { public function is_applicable($cart_data) { // 检查购物车中指定商品的数量 $target_product_count = $this->count_target_products($cart_data['items']); return $target_product_count >= $this->rule_data['buy_quantity']; } public function apply($cart_data) { if (!$this->is_applicable($cart_data)) { return $cart_data; } $target_product_count = $this->count_target_products($cart_data['items']); $free_quantity = floor($target_product_count / $this->rule_data['buy_quantity']) * $this->rule_data['get_quantity']; // 添加赠品到购物车 $free_product = array( 'product_id' => $this->rule_data['free_product_id'], 'quantity' => $free_quantity, 'price' => 0, 'is_free_gift' => true, 'rule_id' => $this->rule_id ); $cart_data['items'][] = $free_product; // 更新购物车总计 $cart_data = $this->recalculate_cart_totals($cart_data); // 记录应用详情 $cart_data['applied_rules'][] = array( 'rule_id' => $this->rule_id, 'rule_name' => $this->rule_data['name'], 'free_product_id' => $this->rule_data['free_product_id'], 'free_quantity' => $free_quantity, 'type' => 'buy_x_get_y_free' ); return $cart_data; } private function count_target_products($cart_items) { $count = 0; $target_products = $this->rule_data['target_products']; foreach ($cart_items as $item) { if (in_array($item['product_id'], $target_products) && !isset($item['is_free_gift'])) { $count += $item['quantity']; } } return $count; } private function recalculate_cart_totals($cart_data) { $subtotal = 0; foreach ($cart_data['items'] as $item) { if (!isset($item['is_free_gift'])) { $subtotal += $item['price'] * $item['quantity']; } } $cart_data['subtotal'] = $subtotal; $cart_data['total'] = $subtotal - $cart_data['discount']; return $cart_data; } public function get_description() { $buy_qty = $this->rule_data['buy_quantity']; $get_qty = $this->rule_data['get_quantity']; $free_product_name = get_the_title($this->rule_data['free_product_id']); return "买{$buy_qty}赠{$get_qty} - {$free_product_name}"; } public function validate_configuration() { $errors = array(); if (!isset($this->rule_data['buy_quantity']) || $this->rule_data['buy_quantity'] <= 0) { $errors[] = "购买数量必须大于0"; } if (!isset($this->rule_data['get_quantity']) || $this->rule_data['get_quantity'] <= 0) { $errors[] = "赠送数量必须大于0"; } if (!isset($this->rule_data['free_product_id']) || !get_post($this->rule_data['free_product_id'])) { $errors[] = "赠品商品不存在"; } if (!isset($this->rule_data['target_products']) || !is_array($this->rule_data['target_products']) || empty($this->rule_data['target_products'])) { $errors[] = "必须指定适用商品"; } return empty($errors) ? true : $errors; } }
- 会员专享规则为不同等级的会员提供差异化优惠: class Member_Exclusive_Rule extends Promotion_Rule_Base { public function is_applicable($cart_data) { // 检查用户会员等级 $user_id = get_current_user_id(); if ($user_id === 0) { return false; // 未登录用户 } $user_member_level = $this->get_user_member_level($user_id); $required_level = $this->rule_data['required_member_level']; return $this->compare_member_levels($user_member_level, $required_level); } public function apply($cart_data) { if (!$this->is_applicable($cart_data)) { return $cart_data; } // 根据会员等级计算折扣 $user_id = get_current_user_id(); $user_member_level = $this->get_user_member_level($user_id); $discount_rate = $this->get_discount_for_member_level($user_member_level); $discount_amount = $cart_data['subtotal'] * ($discount_rate / 100); // 应用折扣 $cart_data['discount'] += $discount_amount; $cart_data['total'] = $cart_data['subtotal'] - $cart_data['discount']; // 记录应用详情 $cart_data['applied_rules'][] = array( 'rule_id' => $this->rule_id, 'rule_name' => $this->rule_data['name'], 'discount_amount' => $discount_amount, 'member_level' => $user_member_level, 'type' => 'member_exclusive' ); return $cart_data; } private function get_user_member_level($user_id) { // 这里需要根据实际的会员系统实现 // 假设使用用户元数据存储会员等级 $level = get_user_meta($user_id, 'member_level', true); return $level ? $level : 'regular'; } private function compare_member_levels($user_level, $required_level) { // 定义会员等级顺序 $level_order = array('regular', 'silver', 'gold', 'platinum', 'diamond'); $user_index = array_search($user_level, $level_order); $required_index = array_search($required_level, $level_order); return $user_index !== false && $required_index !== false && $user_index >= $required_index; } private function get_discount_for_member_level($member_level) { // 根据会员等级获取对应的折扣率 $discount_map = $this->rule_data['discount_by_level']; return isset($discount_map[$member_level]) ? $discount_map[$member_level] : 0; } public function get_description() { $levels = array(); foreach ($this->rule_data['discount_by_level'] as $level => $discount) { $levels[] = "{$level}会员{$discount}%折扣"; }
- 组合规则允许将多个促销规则组合使用,实现更复杂的营销策略: class Combined_Promotion_Rule extends Promotion_Rule_Base { private $sub_rules = array(); public function __construct($rule_id, $rule_data) { parent::__construct($rule_id, $rule_data); $this->initialize_sub_rules(); } private function initialize_sub_rules() { if (!isset($this->rule_data['sub_rules']) || !is_array($this->rule_data['sub_rules'])) { return; } foreach ($this->rule_data['sub_rules'] as $sub_rule_data) { try { $sub_rule = Promotion_Rule_Factory::create_rule( $sub_rule_data['id'], $sub_rule_data['type'], $sub_rule_data['data'] ); $this->sub_rules[] = $sub_rule; } catch (Exception $e) { error_log("初始化子规则失败: " . $e->getMessage()); } } } public function is_applicable($cart_data) { // 检查组合规则的整体条件 if (!$this->check_combined_conditions($cart_data)) { return false; } // 检查子规则的适用性 $applicable_sub_rules = array(); foreach ($this->sub_rules as $sub_rule) { if ($sub_rule->is_applicable($cart_data)) { $applicable_sub_rules[] = $sub_rule; } } // 根据组合类型判断是否适用 $combination_type = $this->rule_data['combination_type'] ?? 'all'; switch ($combination_type) { case 'all': return count($applicable_sub_rules) === count($this->sub_rules); case 'any': return !empty($applicable_sub_rules); case 'at_least': $min_count = $this->rule_data['min_rule_count'] ?? 1; return count($applicable_sub_rules) >= $min_count; default: return false; } } public function apply($cart_data) { if (!$this->is_applicable($cart_data)) { return $cart_data; } // 确定要应用的子规则 $applicable_sub_rules = array(); foreach ($this->sub_rules as $sub_rule) { if ($sub_rule->is_applicable($cart_data)) { $applicable_sub_rules[] = $sub_rule; } } // 根据优先级排序 usort($applicable_sub_rules, function($a, $b) { $priority_a = $a->get_priority() ?? 0; $priority_b = $b->get_priority() ?? 0; return $priority_b - $priority_a; // 优先级高的先应用 }); // 应用子规则 $original_cart_data = $cart_data; $applied_rules_info = array(); foreach ($applicable_sub_rules as $sub_rule) { $cart_data = $sub_rule->apply($cart_data); // 记录每个子规则的应用结果 if (isset($cart_data['applied_rules'])) { $last_rule = end($cart_data['applied_rules']); if ($last_rule) { $applied_rules_info[] = $last_rule; } } } // 添加组合规则的应用记录 $cart_data['applied_rules'][] = array( 'rule_id' => $this->rule_id, 'rule_name' => $this->rule_data['name'], 'type' => 'combined', 'sub_rules_applied' => $applied_rules_info, 'total_discount' => $original_cart_data['subtotal'] - $cart_data['total'] ); return $cart_data; } private function check_combined_conditions($cart_data) { // 检查组合规则特有的条件 $conditions = $this->rule_data['conditions'] ?? array(); foreach ($conditions as $condition) { if (!$this->evaluate_condition($condition, $cart_data)) { return false; } } return true; } private function evaluate_condition($condition, $cart_data) { $type = $condition['type'] ?? ''; $value = $condition['value'] ?? ''; $operator = $condition['operator'] ?? 'equals'; switch ($type) { case 'total_amount': $cart_value = $cart_data['subtotal']; return $this->compare_values($cart_value, $value, $operator); case 'product_count': $product_count = count($cart_data['items']); return $this->compare_values($product_count, $value, $operator); case 'contains_category': $category_ids = $this->get_cart_category_ids($cart_data); $target_category = intval($value); return in_array($target_category, $category_ids); case 'user_segment': $user_id = get_current_user_id(); $user_segment = $this->get_user_segment($user_id); return $user_segment === $value; default: return true; } } private function compare_values($actual, $expected, $operator) { switch ($operator) { case 'equals': return $actual == $expected; case 'greater_than': return $actual > $expected; case 'less_than': return $actual < $expected; case 'greater_than_or_equal': return $actual >= $expected; case 'less_than_or_equal': return $actual <= $expected; default: return false; } } public function get_description() { $descriptions = array(); foreach ($this->sub_rules as $sub_rule) { $descriptions[] = $sub_rule->get_description(); } $combination_type = $this->rule_data['combination_type'] ?? 'all'; $connector = $combination_type === 'all' ? '且' : '或'; return "组合优惠:" . implode(" {$connector} ", $descriptions); } public function validate_configuration() { $errors = array(); if (!isset($this->rule_data['sub_rules']) || !is_array($this->rule_data['sub_rules']) || empty($this->rule_data['sub_rules'])) { $errors[] = "组合规则必须包含至少一个子规则"; } if (isset($this->rule_data['combination_type']) && !in_array($this->rule_data['combination_type'], ['all', 'any', 'at_least'])) { $errors[] = "无效的组合类型"; } if (isset($this->rule_data['combination_type']) && $this->rule_data['combination_type'] === 'at_least' && (!isset($this->rule_data['min_rule_count']) || $this->rule_data['min_rule_count'] < 1)) { $errors[] = "至少应用规则数量必须大于0"; } // 验证子规则 if (isset($this->rule_data['sub_rules'])) { foreach ($this->rule_data['sub_rules'] as $index => $sub_rule_data) { try { $sub_rule = Promotion_Rule_Factory::create_rule( $sub_rule_data['id'] ?? 'temp_' . $index, $sub_rule_data['type'], $sub_rule_data['data'] ); $validation_result = $sub_rule->validate_configuration(); if ($validation_result !== true) { $errors[] = "子规则" . ($index + 1) . "配置错误: " . implode(', ', $validation_result); } } catch (Exception $e) { $errors[] = "子规则" . ($index + 1) . "创建失败: " . $e->getMessage(); } } } return empty($errors) ? true : $errors; } }
-
- 当多个促销规则同时适用时,需要检测和处理规则冲突: class Promotion_Rule_Conflict_Resolver { private $applied_rules = array(); private $conflict_strategy; const STRATEGY_FIRST_WINS = 'first_wins'; const STRATEGY_HIGHEST_DISCOUNT = 'highest_discount'; const STRATEGY_MOST_RESTRICTIVE = 'most_restrictive'; const STRATEGY_COMBINE_ALL = 'combine_all'; public function __construct($strategy = self::STRATEGY_FIRST_WINS) { $this->conflict_strategy = $strategy; } public function add_rule($rule) { $this->applied_rules[] = $rule; } public function resolve_conflicts($cart_data) { if (count($this->applied_rules) <= 1) { return $this->applied_rules; } // 检测冲突 $conflicts = $this->detect_conflicts(); if (empty($conflicts)) { return $this->applied_rules; } // 根据策略解决冲突 switch ($this->conflict_strategy) { case self::STRATEGY_FIRST_WINS: return $this->resolve_first_wins($conflicts); case self::STRATEGY_HIGHEST_DISCOUNT: return $this->resolve_highest_discount($conflicts, $cart_data); case self::STRATEGY_MOST_RESTRICTIVE: return $this->resolve_most_restrictive($conflicts); case self::STRATEGY_COMBINE_ALL: return $this->resolve_combine_all($conflicts, $cart_data); default: return $this->applied_rules; } } private function detect_conflicts() { $conflicts = array(); for ($i = 0; $i < count($this->applied_rules); $i++) { for ($j = $i + 1; $j < count($this->applied_rules); $j++) { $rule_a = $this->applied_rules[$i]; $rule_b = $this->applied_rules[$j]; if ($this->are_rules_conflicting($rule_a, $rule_b)) { $conflicts[] = array( 'rule_a' => $rule_a, 'rule_b' => $rule_b, 'conflict_type' => $this->get_conflict_type($rule_a, $rule_b) ); } } } return $conflicts; } private function are_rules_conflicting($rule_a, $rule_b) { // 检查规则类型是否冲突 $type_a = $rule_a->get_type(); $type_b = $rule_b->get_type(); // 定义冲突矩阵 $conflict_matrix = array( 'discount' => array('discount', 'member_exclusive'), 'spend_x_get_y' => array('spend_x_get_y'), 'member_exclusive' => array('discount', 'member_exclusive') ); if (isset($conflict_matrix[$type_a]) && in_array($type_b, $conflict_matrix[$type_a])) { return true; } // 检查规则作用范围是否重叠 $scope_a = $rule_a->get_scope(); $scope_b = $rule_b->get_scope(); return $this->scopes_overlap($scope_a, $scope_b); } private function get_conflict_type($rule_a, $rule_b) { $type_a = $rule_a->get_type(); $type_b = $rule_b->get_type(); if ($type_a === $type_b) { return 'same_type'; } if (($type_a === 'discount' && $type_b === 'member_exclusive') || ($type_a === 'member_exclusive' && $type_b === 'discount')) { return 'discount_overlap'; } return 'scope_overlap'; } private function resolve_first_wins($conflicts) { // 保留第一个规则,移除冲突的后续规则 $resolved_rules = array(); $excluded_rules = array(); foreach ($conflicts as $conflict) { $excluded_rules[] = $conflict['rule_b']->get_id(); } foreach ($this->applied_rules as $rule) { if (!in_array($rule->get_id(), $excluded_rules)) { $resolved_rules[] = $rule; } } return $resolved_rules; } private function resolve_highest_discount($conflicts, $cart_data) { // 计算每个规则的折扣金额 $rule_discounts = array(); foreach ($this->applied_rules as $rule) { $temp_cart = $rule->apply($cart_data); $discount = $cart_data['subtotal'] - $temp_cart['total']; $rule_discounts[$rule->get_id()] = $discount; } // 解决冲突,保留折扣最高的规则 $resolved_rules = array(); foreach ($conflicts as $conflict) { $discount_a = $rule_discounts[$conflict['rule_a']->get_id()]; $discount_b = $rule_discounts[$conflict['rule_b']->get_id()]; if ($discount_a >= $discount_b) { $resolved_rules[$conflict['rule_a']->get_id()] = $conflict['rule_a']; } else { $resolved_rules[$conflict['rule_b']->get_id()] = $conflict['rule_b']; } } return array_values($resolved_rules); } }
- 为促销规则添加优先级管理,确保重要规则优先应用: class Promotion_Rule_Priority_Manager { private $rules_with_priority = array(); public function add_rule_with_priority($rule, $priority = 0) { $this->rules_with_priority[] = array( 'rule' => $rule, 'priority' => $priority, 'id' => $rule->get_id() ); } public function sort_rules_by_priority() { usort($this->rules_with_priority, function($a, $b) { // 优先级高的排在前面 if ($a['priority'] != $b['priority']) { return $b['priority'] - $a['priority']; } // 如果优先级相同,按ID排序确保稳定性 return strcmp($a['id'], $b['id']); }); return array_column($this->rules_with_priority, 'rule'); } public function get_rules_by_priority_group() { $groups = array(); foreach ($this->rules_with_priority as $item) { $priority = $item['priority']; if (!isset($groups[$priority])) { $groups[$priority] = array(); } $groups[$priority][] = $item['rule']; } // 按优先级从高到低排序 krsort($groups); return $groups; } public function apply_rules_in_priority_order($cart_data) { $sorted_rules = $this->sort_rules_by_priority(); $result_cart = $cart_data; foreach ($sorted_rules as $rule) { if ($rule->is_applicable($result_cart)) { $result_cart = $rule->apply($result_cart); } } return $result_cart; } }
在当今电子商务蓬勃发展的时代,促销活动已成为电商平台吸引用户、提升销量的核心手段。无论是限时折扣、满减优惠、买赠活动还是会员专享,这些促销规则都需要通过精心设计的接口来实现。对于使用WordPress开源系统的开发者而言,如何设计高效、灵活且易于维护的促销活动规则接口,是提升电商网站竞争力的关键。
本指南将基于WordPress开发环境,详细解析促销活动规则接口的5个核心逻辑设计,帮助行业新人和程序员快速掌握这一关键技术。我们将从基础架构设计开始,逐步深入到复杂的规则组合与扩展机制,每个部分都配有实际代码示例和最佳实践建议。
在WordPress中设计促销规则接口,首先需要建立合理的数据模型。我们建议使用自定义文章类型(Custom Post Type)来存储促销活动,同时利用自定义字段(Custom Fields)或元数据(Metadata)来存储规则参数。
// 注册促销活动自定义文章类型
function register_promotion_post_type() {
$args = array(
'public' => true,
'label' => '促销活动',
'supports' => array('title', 'editor', 'custom-fields'),
'menu_icon' => 'dashicons-tag',
'has_archive' => true,
);
register_post_type('promotion', $args);
}
add_action('init', 'register_promotion_post_type');
// 添加促销规则元数据
function add_promotion_meta_fields() {
add_meta_box(
'promotion_rules',
'促销规则设置',
'render_promotion_rules_meta_box',
'promotion',
'normal',
'high'
);
}
add_action('add_meta_boxes', 'add_promotion_meta_fields');
创建一个抽象基类,定义所有促销规则必须实现的方法,确保接口的一致性:
abstract class Promotion_Rule_Base {
protected $rule_id;
protected $rule_data;
public function __construct($rule_id, $rule_data) {
$this->rule_id = $rule_id;
$this->rule_data = $rule_data;
}
// 验证规则是否适用于当前购物车
abstract public function is_applicable($cart_data);
// 应用规则计算折扣
abstract public function apply($cart_data);
// 获取规则描述
abstract public function get_description();
// 验证规则配置是否有效
abstract public function validate_configuration();
}
使用工厂模式创建规则实例,提高代码的可维护性和扩展性:
class Promotion_Rule_Factory {
private static $rule_types = array();
public static function register_rule_type($type, $class_name) {
self::$rule_types[$type] = $class_name;
}
public static function create_rule($rule_id, $rule_type, $rule_data) {
if (!isset(self::$rule_types[$rule_type])) {
throw new Exception("未知的规则类型: {$rule_type}");
}
$class_name = self::$rule_types[$rule_type];
return new $class_name($rule_id, $rule_data);
}
public static function get_available_rule_types() {
return array_keys(self::$rule_types);
}
}
折扣规则是最基础的促销类型,支持百分比折扣和固定金额折扣:
class Discount_Rule extends Promotion_Rule_Base {
const TYPE_PERCENTAGE = 'percentage';
const TYPE_FIXED_AMOUNT = 'fixed_amount';
public function is_applicable($cart_data) {
// 检查活动时间
$current_time = current_time('timestamp');
$start_time = strtotime($this->rule_data['start_date']);
$end_time = strtotime($this->rule_data['end_date']);
if ($current_time < $start_time || $current_time > $end_time) {
return false;
}
// 检查最低消费金额
if (isset($this->rule_data['min_amount']) &&
$cart_data['subtotal'] < $this->rule_data['min_amount']) {
return false;
}
// 检查适用商品
if (!$this->check_applicable_products($cart_data['items'])) {
return false;
}
return true;
}
public function apply($cart_data) {
if (!$this->is_applicable($cart_data)) {
return $cart_data;
}
$discount_amount = 0;
if ($this->rule_data['discount_type'] === self::TYPE_PERCENTAGE) {
$discount_amount = $cart_data['subtotal'] * ($this->rule_data['discount_value'] / 100);
} else {
$discount_amount = min($this->rule_data['discount_value'], $cart_data['subtotal']);
}
// 应用折扣
$cart_data['discount'] += $discount_amount;
$cart_data['total'] = $cart_data['subtotal'] - $cart_data['discount'];
// 记录应用详情
$cart_data['applied_rules'][] = array(
'rule_id' => $this->rule_id,
'rule_name' => $this->rule_data['name'],
'discount_amount' => $discount_amount,
'type' => 'discount'
);
return $cart_data;
}
private function check_applicable_products($cart_items) {
// 实现商品检查逻辑
// 可以基于商品ID、分类、标签等进行过滤
return true;
}
public function get_description() {
$type = $this->rule_data['discount_type'];
$value = $this->rule_data['discount_value'];
if ($type === self::TYPE_PERCENTAGE) {
return "享受{$value}%折扣";
} else {
return "立减{$value}元";
}
}
public function validate_configuration() {
// 验证折扣配置
$errors = array();
if (!isset($this->rule_data['discount_type']) ||
!in_array($this->rule_data['discount_type'], [self::TYPE_PERCENTAGE, self::TYPE_FIXED_AMOUNT])) {
$errors[] = "折扣类型无效";
}
if (!isset($this->rule_data['discount_value']) ||
!is_numeric($this->rule_data['discount_value']) ||
$this->rule_data['discount_value'] <= 0) {
$errors[] = "折扣值必须为正数";
}
if ($this->rule_data['discount_type'] === self::TYPE_PERCENTAGE &&
$this->rule_data['discount_value'] > 100) {
$errors[] = "百分比折扣不能超过100%";
}
return empty($errors) ? true : $errors;
}
}
满减规则鼓励用户达到特定消费金额,是提升客单价的有效手段:
class Spend_X_Get_Y_Discount_Rule extends Promotion_Rule_Base {
public function is_applicable($cart_data) {
// 检查是否达到满减门槛
return $cart_data['subtotal'] >= $this->rule_data['threshold'];
}
public function apply($cart_data) {
if (!$this->is_applicable($cart_data)) {
return $cart_data;
}
$discount_amount = $this->calculate_discount($cart_data['subtotal']);
// 应用折扣
$cart_data['discount'] += $discount_amount;
$cart_data['total'] = $cart_data['subtotal'] - $cart_data['discount'];
// 记录应用详情
$cart_data['applied_rules'][] = array(
'rule_id' => $this->rule_id,
'rule_name' => $this->rule_data['name'],
'discount_amount' => $discount_amount,
'type' => 'spend_x_get_y'
);
return $cart_data;
}
private function calculate_discount($subtotal) {
$threshold = $this->rule_data['threshold'];
$discount = $this->rule_data['discount'];
// 支持多级满减
if (isset($this->rule_data['multi_level']) && $this->rule_data['multi_level']) {
$levels = $this->rule_data['levels'];
usort($levels, function($a, $b) {
return $b['threshold'] - $a['threshold'];
});
foreach ($levels as $level) {
if ($subtotal >= $level['threshold']) {
return $level['discount'];
}
}
}
return $discount;
}
public function get_description() {
$threshold = $this->rule_data['threshold'];
$discount = $this->rule_data['discount'];
if (isset($this->rule_data['multi_level']) && $this->rule_data['multi_level']) {
$descriptions = array();
foreach ($this->rule_data['levels'] as $level) {
$descriptions[] = "满{$level['threshold']}减{$level['discount']}";
}
return implode(',', $descriptions);
}
return "满{$threshold}减{$discount}";
}
public function validate_configuration() {
$errors = array();
if (!isset($this->rule_data['threshold']) || $this->rule_data['threshold'] <= 0) {
$errors[] = "满减门槛必须大于0";
}
if (!isset($this->rule_data['discount']) || $this->rule_data['discount'] <= 0) {
$errors[] = "折扣金额必须大于0";
}
if (isset($this->rule_data['multi_level']) && $this->rule_data['multi_level']) {
if (!isset($this->rule_data['levels']) || !is_array($this->rule_data['levels'])) {
$errors[] = "多级满减必须设置级别";
} else {
foreach ($this->rule_data['levels'] as $index => $level) {
if (!isset($level['threshold']) || !isset($level['discount'])) {
$errors[] = "第" . ($index + 1) . "级满减配置不完整";
}
}
}
}
return empty($errors) ? true : $errors;
}
}
买赠规则通过赠送商品或礼品来刺激消费:
class Buy_X_Get_Y_Free_Rule extends Promotion_Rule_Base {
public function is_applicable($cart_data) {
// 检查购物车中指定商品的数量
$target_product_count = $this->count_target_products($cart_data['items']);
return $target_product_count >= $this->rule_data['buy_quantity'];
}
public function apply($cart_data) {
if (!$this->is_applicable($cart_data)) {
return $cart_data;
}
$target_product_count = $this->count_target_products($cart_data['items']);
$free_quantity = floor($target_product_count / $this->rule_data['buy_quantity']) *
$this->rule_data['get_quantity'];
// 添加赠品到购物车
$free_product = array(
'product_id' => $this->rule_data['free_product_id'],
'quantity' => $free_quantity,
'price' => 0,
'is_free_gift' => true,
'rule_id' => $this->rule_id
);
$cart_data['items'][] = $free_product;
// 更新购物车总计
$cart_data = $this->recalculate_cart_totals($cart_data);
// 记录应用详情
$cart_data['applied_rules'][] = array(
'rule_id' => $this->rule_id,
'rule_name' => $this->rule_data['name'],
'free_product_id' => $this->rule_data['free_product_id'],
'free_quantity' => $free_quantity,
'type' => 'buy_x_get_y_free'
);
return $cart_data;
}
private function count_target_products($cart_items) {
$count = 0;
$target_products = $this->rule_data['target_products'];
foreach ($cart_items as $item) {
if (in_array($item['product_id'], $target_products) &&
!isset($item['is_free_gift'])) {
$count += $item['quantity'];
}
}
return $count;
}
private function recalculate_cart_totals($cart_data) {
$subtotal = 0;
foreach ($cart_data['items'] as $item) {
if (!isset($item['is_free_gift'])) {
$subtotal += $item['price'] * $item['quantity'];
}
}
$cart_data['subtotal'] = $subtotal;
$cart_data['total'] = $subtotal - $cart_data['discount'];
return $cart_data;
}
public function get_description() {
$buy_qty = $this->rule_data['buy_quantity'];
$get_qty = $this->rule_data['get_quantity'];
$free_product_name = get_the_title($this->rule_data['free_product_id']);
return "买{$buy_qty}赠{$get_qty} - {$free_product_name}";
}
public function validate_configuration() {
$errors = array();
if (!isset($this->rule_data['buy_quantity']) || $this->rule_data['buy_quantity'] <= 0) {
$errors[] = "购买数量必须大于0";
}
if (!isset($this->rule_data['get_quantity']) || $this->rule_data['get_quantity'] <= 0) {
$errors[] = "赠送数量必须大于0";
}
if (!isset($this->rule_data['free_product_id']) ||
!get_post($this->rule_data['free_product_id'])) {
$errors[] = "赠品商品不存在";
}
if (!isset($this->rule_data['target_products']) ||
!is_array($this->rule_data['target_products']) ||
empty($this->rule_data['target_products'])) {
$errors[] = "必须指定适用商品";
}
return empty($errors) ? true : $errors;
}
}
会员专享规则为不同等级的会员提供差异化优惠:
class Member_Exclusive_Rule extends Promotion_Rule_Base {
public function is_applicable($cart_data) {
// 检查用户会员等级
$user_id = get_current_user_id();
if ($user_id === 0) {
return false; // 未登录用户
}
$user_member_level = $this->get_user_member_level($user_id);
$required_level = $this->rule_data['required_member_level'];
return $this->compare_member_levels($user_member_level, $required_level);
}
public function apply($cart_data) {
if (!$this->is_applicable($cart_data)) {
return $cart_data;
}
// 根据会员等级计算折扣
$user_id = get_current_user_id();
$user_member_level = $this->get_user_member_level($user_id);
$discount_rate = $this->get_discount_for_member_level($user_member_level);
$discount_amount = $cart_data['subtotal'] * ($discount_rate / 100);
// 应用折扣
$cart_data['discount'] += $discount_amount;
$cart_data['total'] = $cart_data['subtotal'] - $cart_data['discount'];
// 记录应用详情
$cart_data['applied_rules'][] = array(
'rule_id' => $this->rule_id,
'rule_name' => $this->rule_data['name'],
'discount_amount' => $discount_amount,
'member_level' => $user_member_level,
'type' => 'member_exclusive'
);
return $cart_data;
}
private function get_user_member_level($user_id) {
// 这里需要根据实际的会员系统实现
// 假设使用用户元数据存储会员等级
$level = get_user_meta($user_id, 'member_level', true);
return $level ? $level : 'regular';
}
private function compare_member_levels($user_level, $required_level) {
// 定义会员等级顺序
$level_order = array('regular', 'silver', 'gold', 'platinum', 'diamond');
$user_index = array_search($user_level, $level_order);
$required_index = array_search($required_level, $level_order);
return $user_index !== false && $required_index !== false &&
$user_index >= $required_index;
}
private function get_discount_for_member_level($member_level) {
// 根据会员等级获取对应的折扣率
$discount_map = $this->rule_data['discount_by_level'];
return isset($discount_map[$member_level]) ?
$discount_map[$member_level] : 0;
}
public function get_description() {
$levels = array();
foreach ($this->rule_data['discount_by_level'] as $level => $discount) {
$levels[] = "{$level}会员{$discount}%折扣";
}
组合规则允许将多个促销规则组合使用,实现更复杂的营销策略:
class Combined_Promotion_Rule extends Promotion_Rule_Base {
private $sub_rules = array();
public function __construct($rule_id, $rule_data) {
parent::__construct($rule_id, $rule_data);
$this->initialize_sub_rules();
}
private function initialize_sub_rules() {
if (!isset($this->rule_data['sub_rules']) ||
!is_array($this->rule_data['sub_rules'])) {
return;
}
foreach ($this->rule_data['sub_rules'] as $sub_rule_data) {
try {
$sub_rule = Promotion_Rule_Factory::create_rule(
$sub_rule_data['id'],
$sub_rule_data['type'],
$sub_rule_data['data']
);
$this->sub_rules[] = $sub_rule;
} catch (Exception $e) {
error_log("初始化子规则失败: " . $e->getMessage());
}
}
}
public function is_applicable($cart_data) {
// 检查组合规则的整体条件
if (!$this->check_combined_conditions($cart_data)) {
return false;
}
// 检查子规则的适用性
$applicable_sub_rules = array();
foreach ($this->sub_rules as $sub_rule) {
if ($sub_rule->is_applicable($cart_data)) {
$applicable_sub_rules[] = $sub_rule;
}
}
// 根据组合类型判断是否适用
$combination_type = $this->rule_data['combination_type'] ?? 'all';
switch ($combination_type) {
case 'all':
return count($applicable_sub_rules) === count($this->sub_rules);
case 'any':
return !empty($applicable_sub_rules);
case 'at_least':
$min_count = $this->rule_data['min_rule_count'] ?? 1;
return count($applicable_sub_rules) >= $min_count;
default:
return false;
}
}
public function apply($cart_data) {
if (!$this->is_applicable($cart_data)) {
return $cart_data;
}
// 确定要应用的子规则
$applicable_sub_rules = array();
foreach ($this->sub_rules as $sub_rule) {
if ($sub_rule->is_applicable($cart_data)) {
$applicable_sub_rules[] = $sub_rule;
}
}
// 根据优先级排序
usort($applicable_sub_rules, function($a, $b) {
$priority_a = $a->get_priority() ?? 0;
$priority_b = $b->get_priority() ?? 0;
return $priority_b - $priority_a; // 优先级高的先应用
});
// 应用子规则
$original_cart_data = $cart_data;
$applied_rules_info = array();
foreach ($applicable_sub_rules as $sub_rule) {
$cart_data = $sub_rule->apply($cart_data);
// 记录每个子规则的应用结果
if (isset($cart_data['applied_rules'])) {
$last_rule = end($cart_data['applied_rules']);
if ($last_rule) {
$applied_rules_info[] = $last_rule;
}
}
}
// 添加组合规则的应用记录
$cart_data['applied_rules'][] = array(
'rule_id' => $this->rule_id,
'rule_name' => $this->rule_data['name'],
'type' => 'combined',
'sub_rules_applied' => $applied_rules_info,
'total_discount' => $original_cart_data['subtotal'] - $cart_data['total']
);
return $cart_data;
}
private function check_combined_conditions($cart_data) {
// 检查组合规则特有的条件
$conditions = $this->rule_data['conditions'] ?? array();
foreach ($conditions as $condition) {
if (!$this->evaluate_condition($condition, $cart_data)) {
return false;
}
}
return true;
}
private function evaluate_condition($condition, $cart_data) {
$type = $condition['type'] ?? '';
$value = $condition['value'] ?? '';
$operator = $condition['operator'] ?? 'equals';
switch ($type) {
case 'total_amount':
$cart_value = $cart_data['subtotal'];
return $this->compare_values($cart_value, $value, $operator);
case 'product_count':
$product_count = count($cart_data['items']);
return $this->compare_values($product_count, $value, $operator);
case 'contains_category':
$category_ids = $this->get_cart_category_ids($cart_data);
$target_category = intval($value);
return in_array($target_category, $category_ids);
case 'user_segment':
$user_id = get_current_user_id();
$user_segment = $this->get_user_segment($user_id);
return $user_segment === $value;
default:
return true;
}
}
private function compare_values($actual, $expected, $operator) {
switch ($operator) {
case 'equals': return $actual == $expected;
case 'greater_than': return $actual > $expected;
case 'less_than': return $actual < $expected;
case 'greater_than_or_equal': return $actual >= $expected;
case 'less_than_or_equal': return $actual <= $expected;
default: return false;
}
}
public function get_description() {
$descriptions = array();
foreach ($this->sub_rules as $sub_rule) {
$descriptions[] = $sub_rule->get_description();
}
$combination_type = $this->rule_data['combination_type'] ?? 'all';
$connector = $combination_type === 'all' ? '且' : '或';
return "组合优惠:" . implode(" {$connector} ", $descriptions);
}
public function validate_configuration() {
$errors = array();
if (!isset($this->rule_data['sub_rules']) ||
!is_array($this->rule_data['sub_rules']) ||
empty($this->rule_data['sub_rules'])) {
$errors[] = "组合规则必须包含至少一个子规则";
}
if (isset($this->rule_data['combination_type']) &&
!in_array($this->rule_data['combination_type'], ['all', 'any', 'at_least'])) {
$errors[] = "无效的组合类型";
}
if (isset($this->rule_data['combination_type']) &&
$this->rule_data['combination_type'] === 'at_least' &&
(!isset($this->rule_data['min_rule_count']) ||
$this->rule_data['min_rule_count'] < 1)) {
$errors[] = "至少应用规则数量必须大于0";
}
// 验证子规则
if (isset($this->rule_data['sub_rules'])) {
foreach ($this->rule_data['sub_rules'] as $index => $sub_rule_data) {
try {
$sub_rule = Promotion_Rule_Factory::create_rule(
$sub_rule_data['id'] ?? 'temp_' . $index,
$sub_rule_data['type'],
$sub_rule_data['data']
);
$validation_result = $sub_rule->validate_configuration();
if ($validation_result !== true) {
$errors[] = "子规则" . ($index + 1) . "配置错误: " .
implode(', ', $validation_result);
}
} catch (Exception $e) {
$errors[] = "子规则" . ($index + 1) . "创建失败: " . $e->getMessage();
}
}
}
return empty($errors) ? true : $errors;
}
}
当多个促销规则同时适用时,需要检测和处理规则冲突:
class Promotion_Rule_Conflict_Resolver {
private $applied_rules = array();
private $conflict_strategy;
const STRATEGY_FIRST_WINS = 'first_wins';
const STRATEGY_HIGHEST_DISCOUNT = 'highest_discount';
const STRATEGY_MOST_RESTRICTIVE = 'most_restrictive';
const STRATEGY_COMBINE_ALL = 'combine_all';
public function __construct($strategy = self::STRATEGY_FIRST_WINS) {
$this->conflict_strategy = $strategy;
}
public function add_rule($rule) {
$this->applied_rules[] = $rule;
}
public function resolve_conflicts($cart_data) {
if (count($this->applied_rules) <= 1) {
return $this->applied_rules;
}
// 检测冲突
$conflicts = $this->detect_conflicts();
if (empty($conflicts)) {
return $this->applied_rules;
}
// 根据策略解决冲突
switch ($this->conflict_strategy) {
case self::STRATEGY_FIRST_WINS:
return $this->resolve_first_wins($conflicts);
case self::STRATEGY_HIGHEST_DISCOUNT:
return $this->resolve_highest_discount($conflicts, $cart_data);
case self::STRATEGY_MOST_RESTRICTIVE:
return $this->resolve_most_restrictive($conflicts);
case self::STRATEGY_COMBINE_ALL:
return $this->resolve_combine_all($conflicts, $cart_data);
default:
return $this->applied_rules;
}
}
private function detect_conflicts() {
$conflicts = array();
for ($i = 0; $i < count($this->applied_rules); $i++) {
for ($j = $i + 1; $j < count($this->applied_rules); $j++) {
$rule_a = $this->applied_rules[$i];
$rule_b = $this->applied_rules[$j];
if ($this->are_rules_conflicting($rule_a, $rule_b)) {
$conflicts[] = array(
'rule_a' => $rule_a,
'rule_b' => $rule_b,
'conflict_type' => $this->get_conflict_type($rule_a, $rule_b)
);
}
}
}
return $conflicts;
}
private function are_rules_conflicting($rule_a, $rule_b) {
// 检查规则类型是否冲突
$type_a = $rule_a->get_type();
$type_b = $rule_b->get_type();
// 定义冲突矩阵
$conflict_matrix = array(
'discount' => array('discount', 'member_exclusive'),
'spend_x_get_y' => array('spend_x_get_y'),
'member_exclusive' => array('discount', 'member_exclusive')
);
if (isset($conflict_matrix[$type_a]) &&
in_array($type_b, $conflict_matrix[$type_a])) {
return true;
}
// 检查规则作用范围是否重叠
$scope_a = $rule_a->get_scope();
$scope_b = $rule_b->get_scope();
return $this->scopes_overlap($scope_a, $scope_b);
}
private function get_conflict_type($rule_a, $rule_b) {
$type_a = $rule_a->get_type();
$type_b = $rule_b->get_type();
if ($type_a === $type_b) {
return 'same_type';
}
if (($type_a === 'discount' && $type_b === 'member_exclusive') ||
($type_a === 'member_exclusive' && $type_b === 'discount')) {
return 'discount_overlap';
}
return 'scope_overlap';
}
private function resolve_first_wins($conflicts) {
// 保留第一个规则,移除冲突的后续规则
$resolved_rules = array();
$excluded_rules = array();
foreach ($conflicts as $conflict) {
$excluded_rules[] = $conflict['rule_b']->get_id();
}
foreach ($this->applied_rules as $rule) {
if (!in_array($rule->get_id(), $excluded_rules)) {
$resolved_rules[] = $rule;
}
}
return $resolved_rules;
}
private function resolve_highest_discount($conflicts, $cart_data) {
// 计算每个规则的折扣金额
$rule_discounts = array();
foreach ($this->applied_rules as $rule) {
$temp_cart = $rule->apply($cart_data);
$discount = $cart_data['subtotal'] - $temp_cart['total'];
$rule_discounts[$rule->get_id()] = $discount;
}
// 解决冲突,保留折扣最高的规则
$resolved_rules = array();
foreach ($conflicts as $conflict) {
$discount_a = $rule_discounts[$conflict['rule_a']->get_id()];
$discount_b = $rule_discounts[$conflict['rule_b']->get_id()];
if ($discount_a >= $discount_b) {
$resolved_rules[$conflict['rule_a']->get_id()] = $conflict['rule_a'];
} else {
$resolved_rules[$conflict['rule_b']->get_id()] = $conflict['rule_b'];
}
}
return array_values($resolved_rules);
}
}
为促销规则添加优先级管理,确保重要规则优先应用:
class Promotion_Rule_Priority_Manager {
private $rules_with_priority = array();
public function add_rule_with_priority($rule, $priority = 0) {
$this->rules_with_priority[] = array(
'rule' => $rule,
'priority' => $priority,
'id' => $rule->get_id()
);
}
public function sort_rules_by_priority() {
usort($this->rules_with_priority, function($a, $b) {
// 优先级高的排在前面
if ($a['priority'] != $b['priority']) {
return $b['priority'] - $a['priority'];
}
// 如果优先级相同,按ID排序确保稳定性
return strcmp($a['id'], $b['id']);
});
return array_column($this->rules_with_priority, 'rule');
}
public function get_rules_by_priority_group() {
$groups = array();
foreach ($this->rules_with_priority as $item) {
$priority = $item['priority'];
if (!isset($groups[$priority])) {
$groups[$priority] = array();
}
$groups[$priority][] = $item['rule'];
}
// 按优先级从高到低排序
krsort($groups);
return $groups;
}
public function apply_rules_in_priority_order($cart_data) {
$sorted_rules = $this->sort_rules_by_priority();
$result_cart = $cart_data;
foreach ($sorted_rules as $rule) {
if ($rule->is_applicable($result_cart)) {
$result_cart = $rule->apply($result_cart);
}
}
return $result_cart;
}
}
确保促销规则配置的正确性和完整性:
class Promotion_Rule_Validator {
public static function validate_rule_configuration($rule_type, $rule_data) {
$errors = array();
// 通用验证
$errors = array_merge($errors, self::validate_common_fields($rule_data));
// 特定规则类型验证
switch ($rule_type) {
case 'discount':
$errors = array_merge($errors, self::validate_discount_rule($rule_data));
break;
case 'spend_x_get_y':
$errors = array_merge($errors, self::validate_spend_x_get_y_rule($rule_data));
break;
case 'buy_x_get_y_free':
$errors = array_merge($errors, self::validate_buy_x_get_y_free_rule($rule_data));
break;
case 'member_exclusive':
$errors = array_merge($errors, self::validate_member_exclusive_rule($rule_data));
break;
case 'combined':
$errors = array_merge($errors, self::validate_combined_rule($rule_data));
break;
default:
$errors[] = "未知的规则类型: {$rule_type}";
}
return empty($errors) ? true : $errors;
}
private static function validate_common_fields($rule_data) {
$errors = array();
if (!isset($rule_data['name']) || empty(trim($rule_data['name']))) {
$errors[] = "规则名称不能为空";
}
if (!isset($rule_data['start_date']) ||
!self::is_valid_date($rule_data['start_date'])) {
$errors[] = "开始日期无效";
}
if (!isset($rule_data['end_date']) ||


