[ ['mall_id' => $order['mall_id']], ['status' => StatusEnum::ENABLED], // ['is_enable' => StatusEnum::ENABLED], // 必须是启用状态 ['item_id' => $goods_ids] ], 'select'=> ['item_id', 'config', 'is_enable'], 'index' => 'item_id' ]); $wallet_insert = []; $commission_insert = []; $is_frozen = $config['settlement_type'] == OrderStatusEnum::ACCOMPLISH ? StatusEnum::ENABLED : StatusEnum::DISABLED; $score_name = \Yii::$app->services->setting->mall->get($order['mall_id'], "score.score_name"); $score_name = !empty($score_name) ? $score_name : '积分'; $wechat_video_shop_order = WechatVideoShopOrder::getOne([ ['order_id' => $order['id']] ]); if (empty($wechat_video_shop_order->parent_id)) { // 没有上级可以进行分佣 return true; } $sharer = $wechat_video_shop_order->sharer; if (empty($sharer)) { // 没有上级可以进行分佣 return true; } // 当前用户等级 $level = $sharer->level; $reward_user_id = $wechat_video_shop_order->parent_id; if (!empty($level)) { // 等级配置奖励 $level_setting = WechatVideoShopLevel::getOne([ ['level' => $level], ['mall_id' => $order['mall_id']], ['status' => StatusEnum::ENABLED] ]); } foreach ($order['detail'] as $item) { // 判断有没有启用 $tmp_config = [ "compute_type" => $config['compute_type'], "reward_commission_type" => $config['reward_commission_type'], "reward_commission" => $config['reward_commission'], "reward_score_type" => $config['reward_score_type'], "reward_score" => $config['reward_score'], ]; if (!empty($level_setting)) { // 等级配置 $tmp_config['reward_commission_type'] = $level_setting['reward_commission_type']; $tmp_config['reward_commission'] = $level_setting['reward_commission']; $tmp_config['reward_score_type'] = $level_setting['reward_score_type']; $tmp_config['reward_score'] = $level_setting['reward_score']; } if (!empty($setting[$item['goods_id']])) { // 独立设置 - 必须有等级,不然无法获取奖励金额 - 默认等级为0 if (empty($setting[$item['goods_id']]['is_enable'])) continue; // 分佣没有启用 // 遍历所有奖励,判断是否为独立设置 $tmp_setting = Json::decode($setting[$item['goods_id']]['config']); if (!empty($tmp_setting['commission']['is_independent_setting'])) { // 独立设置 $tmp_config['reward_commission_type'] = $tmp_setting['commission']['reward_type'] ?? $config['reward_commission_type']; $tmp_config['reward_commission'] = $tmp_setting['commission']['level'][$level] ?? $config['reward_commission']; } if (!empty($tmp_setting['score']['is_independent_setting'])) { // 独立设置 $tmp_config['reward_score_type'] = $tmp_setting['score']['reward_type'] ?? $config['reward_score_type']; $tmp_config['reward_score'] = $tmp_setting['score']['level'][$level] ?? $config['reward_score']; } } if ($tmp_config['reward_commission'] > 0) { [$commission, $remark] = self::getCommission($tmp_config, $config, $item, UserWalletService::WALLET_TYPE_COMMISSION, "佣金"); $wallet_insert[] = self::packWalletInsert($reward_user_id, $order, $item, $is_frozen, UserWalletService::WALLET_TYPE_COMMISSION, $commission, "分销员 [$reward_user_id] 推荐用户 [{$order['user_id']}] 从微信视频号小店下单 [{$order['order_no']}] 获得 $commission 佣金奖励", WechatVideoShopEnums::ADDONS_NAME, WechatVideoShopEnums::ADDONS_NAME); $commission_insert[] = self::packCommissionInsert($reward_user_id, $order, $item, WechatVideoShopEnums::REWARD_TYPE_COMMISSION, $commission, $is_frozen, $remark, $wechat_video_shop_order->shop_id); if (empty($is_frozen)) $sharer->total_commission += $commission; } if ($tmp_config['reward_score'] > 0) { [$commission, $remark] = self::getCommission($tmp_config, $config, $item, UserWalletService::WALLET_TYPE_SCORE, $score_name); $wallet_insert[] = self::packWalletInsert($reward_user_id, $order, $item, $is_frozen, UserWalletService::WALLET_TYPE_SCORE, $commission, "分销员 [$reward_user_id] 推荐用户 [{$order['user_id']}] 从微信视频号小店下单 [{$order['order_no']}] 获得 $commission $score_name 奖励", WechatVideoShopEnums::ADDONS_NAME, WechatVideoShopEnums::ADDONS_NAME); if (empty($is_frozen)) $sharer->total_score += $commission; $commission_insert[] = self::packCommissionInsert($reward_user_id, $order, $item, WechatVideoShopEnums::REWARD_TYPE_SCORE, $commission, $is_frozen, $remark, $wechat_video_shop_order->shop_id); } } $t = \Yii::$app->db->beginTransaction(); if (!empty($commission_insert)) { // 写入插件记录 WechatVideoShopCommission::find()->createCommand() ->batchInsert(WechatVideoShopCommission::tableName(), array_keys($commission_insert[0]), $commission_insert)->execute(); // 给当前用户累加数据 $sharer->total_order += 1; // 累加订单数量 // 非冻结的才需要累加 $sharer->total_sales += $order['pay_money']; // 累加销售金额 $sharer->total_customers = WechatVideoShopOrder::find() ->where(['parent_id' => $sharer->user_id]) ->andWhere(['is_pay' => StatusEnum::ENABLED]) ->groupBy('user_id')->count(); if (!$sharer->save()) throw new \Exception($sharer->getErrorMessage()); } if (!empty($wallet_insert)) { UserWalletService::batchHandleByQueue($wallet_insert); if (!empty(UserWalletService::getStaticError())) throw new \Exception(UserWalletService::getStaticError()); } $t->commit(); } catch (\Exception $e) { if (!empty($t)) $t->rollBack(); \Yii::error(FormatHelper::exception($e, __METHOD__)); var_dump($e->getMessage(), $e->getLine(), $e->getFile()); return false; } return true; } /** * @param int $user_id * @param array $order * @param array $goods * @param bool $is_frozen * @param string $wallet_type * @param $commission * @param string $desc * @param string $from_type * @param string $capital_type * @return array */ protected static function packWalletInsert(int $user_id, array $order, array $goods, bool $is_frozen, string $wallet_type, $commission, string $desc, string $from_type, string $capital_type) { return [ 'mall_id' => $order['mall_id'], 'user_id' => $user_id, 'is_frozen' => $is_frozen, 'wallet_type' => $wallet_type, 'money' => $commission, 'desc' => $desc, 'source_table' => 'order_detail', 'source_table_id' => $goods['id'], 'from_type' => $from_type, 'capital_type' => $capital_type, 'order_no' =>$order['order_no'], 'contributor_name' =>$goods['goods_name'], 'contributor_id' => $order['user_id'], 'contributor_money' =>$goods['goods_price'], ]; } /** * @param int $user_id * @param array $order * @param array $goods * @param string $commission_type * @param $commission * @param int $settle_status * @param string $remark * @param int $shop_id * @return array */ protected static function packCommissionInsert(int $user_id, array $order, array $goods, string $commission_type, $commission, int $settle_status,string $remark, int $shop_id) { return [ 'mall_id' => $order['mall_id'], 'user_id' => $user_id, 'buy_user_id' => $order['user_id'], 'order_id' => $order['id'], 'order_no' => $order['order_no'], 'order_amount' => $order['pay_money'], 'remark' => $remark, 'settle_status' => $settle_status == StatusEnum::DISABLED ? WechatVideoShopEnums::SETTLE_STATUS_COMPLETE : WechatVideoShopEnums::SETTLE_STATUS_FREEZE, 'commission' => bcmul($commission, 100), 'commission_type' => $commission_type, 'goods_id' => $goods['id'], 'created_at' => time(), 'updated_at' => time(), 'shop_id' => $shop_id ]; } /** * @param array $setting * @param array $config * @param array $goods * @param string $commission_type * @param string $commission_name * @return array */ protected static function getCommission(array $setting, array $config, array $goods, string $commission_type, string $commission_name) { $commission = bcmul($setting["reward_{$commission_type}"], $goods['num'], 2); $remark = "固定"; if ($setting["reward_{$commission_type}_type"] == StatusEnum::ENABLED) { $remark = "比例"; } // 百分比 $suffix = ""; switch ($config['compute_type']) { case 0: // 实际支付金额 if ($setting["reward_{$commission_type}_type"] == StatusEnum::ENABLED) { $commission = bcmul(bcmul($setting["reward_$commission_type"], $goods['goods_price'], 2), 0.01, 2); } $suffix = "(按实际支付金额计算)"; break; case 1: // 商品售价 if ($setting["reward_{$commission_type}_type"] == StatusEnum::ENABLED) { $commission = bcmul(bcmul($setting["reward_$commission_type"], bcmul($goods['price'], $goods['num'], 2), 2), 0.01, 2); } $suffix = "(按商品售价计算)"; break; case 2: // 商品利润 if ($setting["reward_{$commission_type}_type"] == StatusEnum::ENABLED) { $commission = bcmul(bcmul($setting["reward_$commission_type"], bcmul(bcsub($goods['price'], $goods['cost_price'], 2), $goods['num'], 2), 2), 0.01, 2); } $suffix = "(按商品利润计算)"; break; } $remark .= "{$commission_name}[{$setting["reward_$commission_type"]}] $suffix"; return [$commission, $remark]; } /** * 完成事件执行 * @param array $order * @param array $config * @return bool */ public static function unfreeze(array $order, array $config) { $t = \Yii::$app->db->beginTransaction(); try { $order_detail_list = $order['detail'] ?? []; if (empty($order_detail_list)) return true; $source_table_id_arr = array_column($order_detail_list, 'id'); $capital_types = [ WechatVideoShopEnums::ADDONS_NAME ]; $where = [ ['source_table' => 'order_detail'], ['source_table_id' => $source_table_id_arr], ['from_type' => WechatVideoShopEnums::ADDONS_NAME], ['capital_type' => $capital_types], ['status' => CapitalLog::STATUS_WAIT_SEND] ]; $params['where'] = $where; //佣金 $wallet_type = 'commission'; CapitalLog::$capitalType = "{$wallet_type}_frozen"; $commission_list = CapitalLog::lists($params); // 取出分享员 if ($commission_list) { $sharer_user_id = $commission_list[0]['user_id'] ?? 0; $sharer = self::getSharer($sharer_user_id); foreach ($commission_list as $item) { $res = UserWalletService::unfrozen($item['id'], $wallet_type); if (!empty($sharer) && $res) { if ($item['change_type'] == 'add') $sharer->total_commission += $item['change_num']; } else { \Yii::error(__METHOD__ . " 分享员不存在 -> {$order['id']} -> {$sharer_user_id} -> {$res}"); } } } //积分 $wallet_type = 'score'; CapitalLog::$capitalType = "{$wallet_type}_frozen"; $score_list = CapitalLog::lists($params); if ($score_list) { if (empty($sharer)) { $sharer_user_id = $score_list[0]['user_id'] ?? 0; $sharer = self::getSharer($sharer_user_id); } foreach ($score_list as $item) { $res = UserWalletService::unfrozen($item['id'], $wallet_type); // change_num if (!empty($sharer) && $res) { if ($item['change_type'] == 'add') $sharer->total_commission += $item['change_num']; } else { \Yii::error(__METHOD__ . " 分享员不存在 -> {$order['id']} -> {$sharer_user_id} -> {$res}"); } } } WechatVideoShopCommission::updateAll(['settle_status' => WechatVideoShopEnums::SETTLE_STATUS_COMPLETE], ['order_id' => $order['id']]); $t->commit(); } catch (\Exception $e) { $t->rollBack(); \Yii::error(FormatHelper::exception($e, __METHOD__)); var_dump($e->getMessage()); return false; } return true; } /** * 退款完成事件执行 * @param array $refund * @param array $config * @return bool */ public static function refund(array $refund, array $config) { $t = \Yii::$app->db->beginTransaction(); try { $order_detail_id = $refund['order_detail_id']; $capital_types = [ WechatVideoShopEnums::ADDONS_NAME ]; $where = [ ['source_table' => 'order_detail'], ['source_table_id' => $order_detail_id], ['from_type' => WechatVideoShopEnums::ADDONS_NAME], ['capital_type' => $capital_types], ['status' => CapitalLog::STATUS_WAIT_SEND] ]; $params['where'] = $where; //佣金 $wallet_type = 'commission'; CapitalLog::$capitalType = "{$wallet_type}_frozen"; $commission_list = CapitalLog::lists($params); if (!empty($commission_list)) { // 默认会删除? // 执行删除 } $wallet_type = 'score'; CapitalLog::$capitalType = "{$wallet_type}_frozen"; $score_list = CapitalLog::lists($params); if (!empty($score_list)) { } $t->commit(); } catch (\Exception $e) { $t->rollBack(); \Yii::error(FormatHelper::exception($e, __METHOD__)); return false; } return true; } /** * @param int $user_id * @return WechatVideoShopSharer|null */ protected static function getSharer(int $user_id) { return WechatVideoShopSharer::getOne([ ['user_id' => $user_id], ['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]], ]); } }