db->beginTransaction(); // 开启事务 try { $order = Order::find() ->where(['id' => $data['id'], 'status' => StatusEnum::ENABLED]) ->asArray()->one(); // 因为需要 拼团(新) 插件订单不参与平台积分、余额等赠送 if ($order['marketing_type'] == 'GroupBuyCopy') return false; // 获取订单详情 $orderDetailList = $this->getOrderDetails($data['id']); if (empty($orderDetailList)) return false; // 获取商品成本价 $order['cost_price'] = 0; $order['num'] = 0; foreach ($orderDetailList as $detail) { $order['cost_price'] += $detail['cost_price'] * $detail['num']; $order['num'] += $detail['num']; } // 获取用户信息 $this->userInfo = User::find() ->where(['id' => $order['user_id'], 'status' => StatusEnum::ENABLED]) ->asArray()->one(); if (empty($this->userInfo)) return false; // 获取商品营销配置 $goodsIds = array_column($orderDetailList, 'goods_id') ?? []; $goodsExtraList = $this->getGoodsExtraList($goodsIds); $isIndependentConfig = $this->checkIndependentConfig($goodsExtraList); // 根据配置处理赠送 if ($isIndependentConfig) { Yii::$app->custom->logs('营销赠送商品独立配置', json_encode($goodsExtraList)); $this->setIndependentGift($orderDetailList, $goodsExtraList); } else { // 获取全局营销配置:(并且判断条件是否满足) $marketingConfig = Yii::$app->services->setting->mall->get($order['mall_id'], 'marketing'); // 判断是否开启营销配送。并且订单金额是否满足赠送条件 if (empty($marketingConfig['enable_marketing']) || $order['goods_price'] < $marketingConfig['total_price']) return false; Yii::$app->custom->logs('营销赠送全局配置', json_encode($marketingConfig)); $this->setGlobalGift($order, $marketingConfig); } // 出来金额赠送 if (!empty($this->insertWallets)) { $res = UserWalletService::batchHandleByQueue($this->insertWallets); if (empty($res)) throw new \Exception(UserWalletService::getStaticError()); } $transaction->commit(); return true; } catch (\Exception $e) { Yii::$app->custom->logs('营销配置发送失败', $e->getMessage()); $transaction->rollBack(); return false; } } /** * @param $orderId * @return array|\yii\db\ActiveRecord[] */ protected function getOrderDetails($orderId): array { return OrderDetail::find() ->where(['order_id' => $orderId, 'status' => StatusEnum::ENABLED]) ->asArray()->all(); } /** * 获取商品营销配置 * @param $goodsIds * @return array|\yii\db\ActiveRecord[] */ protected function getGoodsExtraList($goodsIds): array { return GoodsExtra::find() ->select(['score_give_setting', 'balance_give_setting', 'goods_id']) ->where(['goods_id' => $goodsIds, 'status' => StatusEnum::ENABLED]) ->asArray()->indexBy('goods_id')->all(); } /** 检测商品独立设置支付结算方式和全局不同需要修改 * @param $goodsExtraList * @return bool */ protected function checkIndependentConfig(&$goodsExtraList): bool { $is_check = false; foreach ($goodsExtraList as &$extra) { $extra['score_give_setting'] = json_decode($extra['score_give_setting'], true) ?: []; $extra['balance_give_setting'] = json_decode($extra['balance_give_setting'], true) ?: []; $extra['balance_give_setting']['settlement'] = !empty($extra['balance_give_setting']['settlement']) ? $extra['balance_give_setting']['settlement'] : 2; $extra['score_give_setting']['settlement'] = !empty($extra['score_give_setting']['settlement']) ? $extra['score_give_setting']['settlement'] : 2; if (!empty($extra['score_give_setting']['enable_give_score']) || !empty($extra['balance_give_setting']['enable_give_balance'])) { $is_check = true; } } unset($extra); return $is_check; } /** * 全局设置赠送 * @param array $order * @param array $giftSystem * @return bool */ protected function setGlobalGift(array $order, array $giftSystem) { $scoreGiftSystem = $balanceGiftSystem = []; // 获取全局积分赠送设置 if (!empty($giftSystem['score_give_setting'])) { $scoreGiftSystem = json_decode($giftSystem['score_give_setting'], true); $scoreGiftSystem['enable_give_score'] = $giftSystem['enable_give_score']; $scoreGiftSystem['settlement'] = $giftSystem['settlement']; } // 获取全局余额赠送设置 if (!empty($giftSystem['balance_give_setting'])) { $balanceGiftSystem = json_decode($giftSystem['balance_give_setting'], true); $balanceGiftSystem['enable_give_balance'] = $giftSystem['enable_give_balance']; $balanceGiftSystem['settlement'] = $giftSystem['settlement']; } // 判断条件是否满足商品类型限制 if (!empty($order['store_id'])) return false; // 门店商品过滤 if (!empty($order['mch_id']) && !in_array(1, $scoreGiftSystem['score_giving_goods_type'])) return false; // 如果商品为多商户商品。营销配置商品类型没有选择多商户商品过滤 if (empty($order['mch_id']) && !in_array(0, $scoreGiftSystem['score_giving_goods_type'])) return false; // 如果商品为拼团商品。营销配置商品类型没有选择平台商品过滤 $order['order_id'] = $order['id']; if (!empty($scoreGiftSystem['enable_give_score'])) { // 积分赠送 $this->setGlobalGiftSystem($order, $scoreGiftSystem); } if (!empty($balanceGiftSystem['enable_give_balance'])) { // 余额赠送 $this->setGlobalGiftSystem($order, $balanceGiftSystem, 'balance'); } return true; } /** * 商品独立设置赠送 * @return bool */ protected function setIndependentGift(array $orderDetailList, array $goodsExtraList) { foreach ($orderDetailList as $detail) { $detail['cost_price'] = $detail['cost_price'] * $detail['num'] ?? 0; // 判断条件是否满足商品类型限制 if (empty($goodsExtraList[$detail['goods_id']])) continue; if (!empty($goodsExtraList[$detail['goods_id']]['score_give_setting']['enable_give_score'])) { // 积分赠送 // 判断是否开启等级限制 $give_level_setting = true; if (!empty($goodsExtraList[$detail['goods_id']]['score_give_setting']['enable_limit_level'])) { if (!in_array($this->userInfo['level'], $goodsExtraList[$detail['goods_id']]['score_give_setting']['limit_level'])) { $give_level_setting = false; } } if ($give_level_setting) { // 因为独立积分赠送的计算方式和全局积分赠送的计算方式不一样,所以这些从新赋值 $goodsExtraList[$detail['goods_id']]['score_give_setting']['score_giving_calculation'] = $goodsExtraList[$detail['goods_id']]['score_give_setting']['calculation_value']; $this->setGlobalGiftSystem($detail, $goodsExtraList[$detail['goods_id']]['score_give_setting'], 'score', 'order'); } } if (!empty($goodsExtraList[$detail['goods_id']]['balance_give_setting']['enable_give_balance'])) { // 余额赠送 $this->setGlobalGiftSystem($detail, $goodsExtraList[$detail['goods_id']]['balance_give_setting'], 'balance', 'order'); } } return true; } /** * 积分赠送 * @param $detail * @param $giftSystem * @param string $type * @param string $full * @return false|void */ protected function setGlobalGiftSystem($detail, $giftSystem, string $type = 'score', string $full = 'full') { $goodsPrice = 0; if ($type == 'score') { switch ($giftSystem['score_giving_calculation']) { case 1: // 商品利润 $goodsPrice = $detail['goods_price'] - $detail['cost_price']; break; case 2: // 商品售价 $goodsPrice = $detail['original_goods_price']; break; default: // 订单支付金额 $goodsPrice = $detail['goods_price']; break; } } else { $goodsPrice = $detail['goods_price']; } $money = $giftSystem['give_num'] * $detail['num'] ?? 0; // 计算赠送金额 if ($giftSystem['give_type'] == 2) { $money = bcmul($goodsPrice, $giftSystem['give_num'] / 100, 2); } if ($money <= 0) return false; if ($full == 'full') { $desc = '满额赠送'; $source_table = Order::tableName(); $from_type = UserWalletEnum::REWARD; } else { $desc = '支付赠送'; $source_table = OrderDetail::tableName(); $from_type = UserWalletEnum::CONSUME; } if (!empty($detail['mch_id']) && $type == 'score') { // 如果是多商户订单。订单赠送积分。需要扣除多商户订单 // 判断是否安装多商户插件 if (!MallAddons::isInstall($detail['mall_id'], 'Mch')) return false; // 获取当前多商户绑定的会员信息 $mch = Mch::findOne(['id' => $detail['mch_id'], 'status' => StatusEnum::ENABLED]); if (!$mch) return false; $userWallet = UserWallet::findOne(['user_id' => $mch->user_id, 'status' => StatusEnum::ENABLED]); if (!$userWallet) return false; if ($userWallet->score < $money) return false; $this->insertWallets[] = [ 'mall_id' => $detail['mall_id'], 'user_id' => $mch->user_id, 'is_frozen' => $giftSystem['settlement'] == 2, 'wallet_type' => 'score', 'money' => -$money, 'desc' => '订单支付赠送用户积分,扣除商家用户账户积分', 'source_table' => OrderDetail::tableName(), 'source_table_id' => $detail['id'], 'from_type' => UserWalletEnum::CONSUME, 'capital_type' => UserWalletEnum::CONSUME_ORDER_GIVE, ]; } $this->insertWallets[] = [ 'mall_id' => $detail['mall_id'], 'user_id' => $detail['user_id'], 'is_frozen' => $giftSystem['settlement'] == 2, 'wallet_type' => $type, 'money' => $money, 'desc' => '订单(' . $detail['order_id'] . ')' . $desc, 'source_table' => $source_table, 'source_table_id' => $detail['id'], 'from_type' => $from_type, 'capital_type' => UserWalletEnum::CONSUME_ORDER_GIVE, ]; } }