db->beginTransaction(); try { $res = $this->calculate($mallId, $isManual); if($res === false) throw new Exception($this->getError()); $trans->commit(); } catch (Exception $e) { $trans->rollBack(); } // 获取基础配置 $config = Yii::$app->services->setting->addons->get($mallId, 'ServeBonus', 'basic'); if ($config['is_enable'] == StatusEnum::ENABLED) { $continue = false; // 获取结算周期,0=天,1=周,2=月 $compute_period = $config['compute_period']; if ($isManual == false) { switch ($compute_period) { case 1: $start_day = date("Ymd", strtotime("-1 day")); $end_day = $start_day; break; case 2: if (date('w') != 1) $continue = true;// 非周一直接退出 $start_day = date("Ymd", strtotime("last Monday")); $end_day = date('Ymd', strtotime('-1 sunday', time()));; break; case 3: if (date('d') != 1) $continue = true;// 非当月1号直接退出 $start_day = date("Ym01", strtotime("-1 month")); $end_day = date('Ymd', strtotime(date('Y-m', time()) . '-01 00:00:00') - 86400); break; } } else { $start_day = $end_day = date("Ymd", time());// 手动执行当日的订单分红 } if ($continue) continue; $date_limit = $start_day . '-' . $end_day; $job = ServeBonusCommissionJob::findOne(['mall_id' => $mallId, 'compute_period' => $compute_period, 'date_limit' => $date_limit, 'status' => StatusEnum::ENABLED]); if ($job && $isManual == false) continue; // 生成执行记录 if (empty($job)) { $job = new ServeBonusCommissionJob(); $job->mall_id = $mallId; $job->date_limit = $date_limit; $job->compute_period = $compute_period; if (!$job->save()) throw new Exception($job->getErrorMessage()); } $trans = Yii::$app->db->beginTransaction(); try { $res = $this->addCommissionLog($mallId, $config, $start_day, $end_day); if($res === false) throw new Exception($this->getError()); $trans->commit(); } catch (Exception $e) { $trans->rollBack(); } } } return true; } } //修复用 public function fix($mallId = 0,$date=''){ $where = []; $where['where'] = ['=', 'id' ,$mallId];// 手动执行单个商城分红操作 $mall_list = Mall::getEnableMallList(true, $where); if(!empty($mall_list)){ foreach ($mall_list as $mall){ $mallId = $mall['id']; // 判断是否有安装该插件 if (MallAddons::isInstall($mallId, AddonsEnum::ADDONS_NAME_SERVEBONUS) == false) continue; // 获取基础配置 $config = Yii::$app->services->setting->addons->get($mallId, 'ServeBonus', 'basic'); if ($config['is_enable'] == StatusEnum::ENABLED) { $compute_period = $config['compute_period']; if(empty($date))$date = date("Ymd", time()); $start_day = $end_day = $date;// 手动执行当日的订单分红 $date_limit = $start_day . '-' . $end_day; // 生成执行记录 $job = new ServeBonusCommissionJob(); $job->mall_id = $mallId; $job->date_limit = $date_limit; $job->compute_period = $compute_period; if (!$job->save()) throw new Exception($job->getErrorMessage()); $trans = Yii::$app->db->beginTransaction(); try { $res = $this->addCommissionLog($mallId, $config, $start_day, $end_day); if($res === false) throw new Exception($this->getError()); $trans->commit(); } catch (Exception $e) { $trans->rollBack(); } } } return true; } } /** * 计算出单奖励 * @Author: lun * @DateTime: 2022/1/25 0025 18:55 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $mallId * @param $isManual */ private function calculate($mallId, $isManual) { try { $time = time(); $yesterday = date("Ymd", $time); $yesterday = $isManual ? $yesterday : date("Ymd", strtotime("-1 day")); // 获取出单奖励列表 $list = ServeBonusAchievement::getServeBonusAchievement([['mall_id' => $mallId, 'date' => $yesterday, 'is_settlement' => StatusEnum::DISABLED, 'status' => StatusEnum::ENABLED]]); if (empty($list)) return true; // 将同级别的用户组合为数组 foreach ($list as $item) { $bonus_uids[$item['level']][] = $item['user_id']; } // 循环操作 foreach ($list as $item) { $num = count(array_unique($bonus_uids[$item['level']]));// 该等级的人数 $commission = sprintf("%.2f",substr(sprintf("%.3f", $item['prize'] / $num), 0, -1));// 佣金 $new_uids = array_unique($bonus_uids[$item['level']]);// 移除重复的元素 foreach ($new_uids as $uid) { $rows[] = [ 'mall_id' => $mallId, 'order_id' => $item['order_id'], 'order_no' => $item['order_no'], 'user_id' => $uid, 'type' => 1, 'level' => $item['level'],// 服务商等级 'amounts' => $item['prize'], 'commission' => $commission, 'settlement_data' => Json::encode([ 'amounts' => $item['prize'], 'commonisson' => $commission, 'average_count' => $num, ]), 'date' => $yesterday, 'created_at' => $time, 'updated_at' => $time, ]; } // 修改统计人数,将此条数据改为已结算 ServeBonusAchievement::updateAll(['average_count' => $num, 'is_settlement' => StatusEnum::ENABLED], ['id' => $item['id']]); } // 生成数据 if (!empty($rows)) { $field = ['mall_id','order_id','order_no','user_id','type','level','amounts','commission','settlement_data','date','created_at','updated_at']; $res = Yii::$app->db->createCommand()->batchInsert(ServeBonusRewardLog::tableName(), $field, $rows)->execute(); if ($res == false) throw new \yii\db\Exception(ServeBonusRewardLog::getStaticError()); } return true; } catch (Exception $e) { return false; } } /** * 增加ServeBonus分红佣金 * @Author: ltm * @DateTime: 2021/11/5 0005 14:27 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $mallId * @param $config * @param $start_day * @param $end_time * @return bool */ private function addCommissionLog($mallId, $config, $start_day, $end_day) { if ($config['is_enable'] == StatusEnum::DISABLED) { Yii::error('系统没有开启服务商提成'); return true; } try { // 初始化数据 $time = time(); $table_name = ServeBonusCommissionLog::tableName(); // 获取所有服务商列表 $servebonus_list = ServeBonus::find()->where(['mall_id' => $mallId, 'status' => StatusEnum::ENABLED])->asArray()->all(); if (empty($servebonus_list)) return true; $servebonus_arr = array_column($servebonus_list,'user_id'); // 获取分红奖励列表 $reward_list = ServeBonusRewardLog::find() ->select('user_id,sum(amounts) amounts,sum(commission) commission,type') ->where(['mall_id' => $mallId, 'is_settlement' => StatusEnum::DISABLED]) ->andFilterWhere(['between', 'date', $start_day, $end_day]) ->groupBy('user_id,type') ->orderBy("user_id desc,type asc") ->asArray() ->all(); //获取业绩分红奖励列表 $achievement_reward_list = ServeBonusCloudStockPeriod::find() ->select('max(id) as id,user_id,amounts,amounts_num,total_amounts_num,commission,start_time,end_time') ->where(['mall_id' => $mallId, 'is_settlement' => StatusEnum::DISABLED]) ->andWhere(['=', 'start_time', $start_day]) ->andWhere(['=', 'end_time', $end_day]) ->groupBy('user_id') ->orderBy("id desc") ->asArray() ->all(); $level_arr = array_unique(array_column($servebonus_list,'level')); $servebonus_list = array_column($servebonus_list,null,'user_id'); $total = []; foreach($level_arr as $level){ $total[$level]['amounts_num'] = ServeBonusCloudStockPeriod::getAmountsNum($mallId,$level,$start_day,$end_day); $total[$level]['total_amounts_num'] = ServeBonusOrderLog::getTotalAmountsNum($mallId,$level,$start_day,$end_day); } if(!empty($achievement_reward_list)){ foreach($achievement_reward_list as &$achievement_reward){ $achievement_reward['type'] = ServeBonusEnum::BOUNS_TYPE_ACHIEVEMENT; if(empty($total[$servebonus_list[$achievement_reward['user_id']]['level']])) continue; $achievement_reward['amounts_num'] = $total[$servebonus_list[$achievement_reward['user_id']]['level']]['amounts_num']; $achievement_reward['total_amounts_num'] = $total[$servebonus_list[$achievement_reward['user_id']]['level']]['total_amounts_num']; $achievement_reward['commission'] = $achievement_reward['amounts'] / $achievement_reward['amounts_num'] * $achievement_reward['total_amounts_num']; } } $reward_list = array_merge($reward_list,$achievement_reward_list); if (empty($reward_list)) return true; // 获取本期期数id $period_id = ServeBonusPeriod::setData($mallId); $servebonus_commission = $forever_uids = [];// 用户佣金、记录加权分红、出单奖励用户初始化 $total_commission = $total_extra_commission = $total_achievement_commission = 0;// 统计加权分红跟出单奖励总额 $total_settlement_uids = []; // 生成计算好的结算数据 foreach ($reward_list as $item) { if (in_array($item['user_id'], $servebonus_arr)) { // 加权分红跟出单奖励数据处理 if(!$servebonus_commission[$item['user_id']]['commission']){ $servebonus_commission[$item['user_id']]['commission'] = 0; } if(!$servebonus_commission[$item['user_id']]['extra_commission']){ $servebonus_commission[$item['user_id']]['extra_commission'] = 0; } if(!$servebonus_commission[$item['user_id']]['achievement_commission']){ $servebonus_commission[$item['user_id']]['achievement_commission'] = 0; } if ($item['type'] == ServeBonusEnum::BOUNS_TYPE_FOREVER) { $forever_uids[] = $item['user_id'];// 出单奖励用户id $servebonus_commission[$item['user_id']]['commission'] = $item['commission']; $total_commission += $item['commission']; } elseif($item['type'] == ServeBonusEnum::BOUNS_TYPE_ACHIEVEMENT){ $servebonus_commission[$item['user_id']]['achievement_commission'] = $item['commission']; $total_achievement_commission += $item['commission']; $log = ServeBonusCloudStockPeriod::findOne($item['id']); $log->is_settlement = StatusEnum::ENABLED; $log->period_id = $period_id; $log->updated_at = $time; $log->amounts_num = $item['amounts_num']; $log->total_amounts_num = $item['total_amounts_num']; $log->commission = $item['commission']; if(!$log->save()) throw new \Exception(ServeBonusCloudStockPeriod::getStaticError()); }else { $servebonus_commission[$item['user_id']]['commission'] = $servebonus_commission[$item['user_id']]['commission'] ?? 0; $servebonus_commission[$item['user_id']]['extra_commission'] = $item['commission']; $total_extra_commission += $item['commission']; } $rows[$item['user_id']] = [ 'mall_id' => $mallId, 'user_id' => $item['user_id'], 'period_id' => $period_id, 'commission' => empty($rows[$item['user_id']]['commission']) ? $servebonus_commission[$item['user_id']]['commission'] : $rows[$item['user_id']]['commission'], 'extra_commission' => empty($rows[$item['user_id']]['extra_commission']) ? $servebonus_commission[$item['user_id']]['extra_commission'] : $rows[$item['user_id']]['extra_commission'], 'compute_period' => $config['compute_period'], 'start_time' => $start_day, 'end_time' => $end_day, 'created_at' => $time, 'updated_at' => $time, 'achievement_commission' => empty($rows[$item['user_id']]['achievement_commission']) ? $servebonus_commission[$item['user_id']]['achievement_commission'] : $rows[$item['user_id']]['achievement_commission'], ]; $total_settlement_uids[] = $item['user_id']; } } if (empty($rows)) return true; // 生成数据 $field = ['mall_id','user_id','period_id','commission','extra_commission','compute_period','start_time','end_time','created_at','updated_at','achievement_commission']; Yii::$app->db->createCommand()->batchInsert($table_name, $field, $rows)->execute(); // 数据生成完成记录表修改结算状态 ServeBonusRewardLog::updateAll( [ 'is_settlement' => StatusEnum::ENABLED, 'period_id' => $period_id, 'updated_at' => $time ], ['and', ['mall_id' => $mallId, 'is_settlement' => StatusEnum::DISABLED],['between', 'date', $start_day, $end_day]] ); // 增加对应服务商分佣金额 $log_list = ServeBonusCommissionLog::getServeBonusCommissionLog([['mall_id' => $mallId,'period_id' => $period_id,'start_time' => $start_day,'end_time' => $end_day]]); foreach ($log_list as $item) { $wallet_money = $item['commission'] + $item['extra_commission'] + $item['achievement_commission']; if (empty($wallet_money)) continue; $insert_wallet[] = [ 'mall_id' => $mallId, 'user_id' => $item['user_id'], 'is_frozen' => false, 'wallet_type' => 'commission', 'money' => $wallet_money, 'desc' => '服务商分红佣金', 'source_table' => $table_name, 'source_table_id' => $item['id'], 'from_type' => ServeBonusEnum::ADDONS_NAME, 'capital_type' => UserWalletEnum::BOUNS, ]; } if (!empty($insert_wallet)) { $res = UserWalletService::batchHandleByQueue($insert_wallet); if (empty($res)) throw new \Exception(UserWalletService::getStaticError()); } // 增加用户服务商金额 $commission_logs = ServeBonusCommissionLog::find()->where(['period_id' => $period_id, 'status' => StatusEnum::ENABLED])->asArray()->all(); foreach ($commission_logs as $commission_log) { $ServeBonus = ServeBonus::findOne(['mall_id' => $mallId, 'user_id' => $commission_log['user_id'], 'status' => StatusEnum::ENABLED]); if (empty($ServeBonus)) continue; if (!empty($commission_log['commission'])) {// 出单奖励 $ServeBonus->commission += $commission_log['commission'];// 增加出单奖励 $ServeBonus->total_commission += $commission_log['commission'];// 增加总累计 } if (!empty($commission_log['extra_commission'])) {// 加权分红 $ServeBonus->extra_commission += $commission_log['extra_commission'];// 增加加权分红奖励 $ServeBonus->total_commission += $commission_log['extra_commission'];// 增加总累计 } if (!empty($commission_log['achievement_commission'])) {// 加权分红 $ServeBonus->achievement_commission += $commission_log['achievement_commission'];// 增加加权分红奖励 $ServeBonus->total_commission += $commission_log['achievement_commission'];// 增加总累计 } $ServeBonus->temp_extra_commission = $ServeBonus->extra_commission;// 重置加权平分计算金额 $ServeBonus->period_num = $ServeBonus->period_num + 1;// 增加结算期数 if (!$ServeBonus->save()) throw new \Exception($ServeBonus->getErrorMessage()); } // 修改商城本期分红数据 ServeBonusPeriod::setData($mallId,[ 'id' => $period_id, 'amounts' => $total_commission, 'amounts_num' => count(array_unique($forever_uids)), 'extra_amounts' => $total_extra_commission, 'total_amounts_num' => count(array_unique($total_settlement_uids)), 'compute_period' => $config['compute_period'], 'start_time' => $start_day, 'end_time' => $end_day, 'achievement_commission' => $total_achievement_commission, ]); return true; } catch (Exception $e) { $exception = FormatHelper::exception($e, "mall_id={$mallId} 服务商定时分红任务失败"); echo $exception; Yii::error($exception); $this->setError($exception); return false; } } }