| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419 |
- <?php
- namespace addons\Boss\common\logic;
- use addons\Boss\common\enums\BossEnum;
- use addons\Boss\common\enums\LevelEnum;
- use addons\Boss\common\models\AddonsBoss;
- use addons\Boss\common\models\AddonsBossCommissionJob;
- use addons\Boss\common\models\AddonsBossCommissionLog;
- use addons\Boss\common\models\AddonsBossLevelSetting;
- use addons\Boss\common\models\AddonsBossRewardLog;
- use addons\Boss\common\models\BossPoolPrizeJob;
- use common\enums\StatusEnum;
- use common\enums\UserWalletEnum;
- use common\helpers\FileHelper;
- use common\helpers\FormatHelper;
- use common\models\mall\Mall;
- use common\models\user\UserDigital;
- use common\traits\ErrorTrait;
- use Exception;
- use services\common\UserWalletService;
- use Yii;
- class CommissionLogLogic{
- use ErrorTrait;
- /**
- * 执行分红操作
- * @Author: lun
- * @DateTime: 2021/11/5 0005 14:27
- * @Copyright: copyright (c) 2021 广东七件事集团
- * @return bool
- */
- public function execute()
- {
- $mall_list = Mall::getEnableMallList(true);
- if(!empty($mall_list)){
- foreach ($mall_list as $mall){
- $mallId = $mall['id'];
- // 获取基础配置
- $config = Yii::$app->services->setting->addons->get($mallId, 'Boss', 'basic');
- if ($config['is_enable'] == StatusEnum::ENABLED) {
- $continue = false;
- // 获取结算周期,0=天,1=周,2=月
- $compute_period = $config['compute_period'];
- switch ($config['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;
- case LevelEnum::PERIOD_CUSTOM_DAYS:
- // 没配置直接退出
- if (empty($config['custom_compute_days'])) {
- $continue = true;
- break;
- }
- // 自定义天数
- $custom_compute_days = (int)$config['custom_compute_days'];
- $latestJobDateLimit = AddonsBossCommissionJob::find()
- ->where(['mall_id' => $mallId, 'compute_period' => $compute_period, 'status' => StatusEnum::ENABLED])
- ->orderBy('id desc')
- ->select('date_limit')
- ->scalar();
- // 得到本次开始时间
- $start_day = date("Ymd", strtotime("-$custom_compute_days day"));
- // 包含在这个时间则直接退出
- if ($latestJobDateLimit) {
- [, $latestEndDay] = explode('-', $latestJobDateLimit);
- if ($latestEndDay >= $start_day) {
- $continue = true;
- break;
- }
- }
- $end_day = date("Ymd", strtotime("-1 day"));
- break;
- }
- if ($continue) continue;
- $date_limit = $start_day . '-' . $end_day;
- $job = AddonsBossCommissionJob::findOne(['mall_id' => $mallId, 'compute_period' => $compute_period, 'date_limit' => $date_limit, 'status' => StatusEnum::ENABLED]);
- if ($job) continue;
- // 生成执行记录
- $job = new AddonsBossCommissionJob();
- $job->mall_id = $mallId;
- $job->date_limit = $date_limit;
- $job->compute_period = $compute_period;
- if (!$job->save()) throw new Exception($job->getErrorMessage());
- $res = $this->addCommissionLog($mallId, $config, $start_day, $end_day, $job->id);
- // 发放股东团队业绩奖励
- $bossPerformanceLogic = new BossPerformanceLogic();
- $bossPerformanceLogic->sendPerformancePrize($mallId, $config, $start_day, $end_day, $job->id);
- //if($res === false) throw new Exception($this->getError());
- }
- }
-
- foreach ($mall_list as $mall){
- $mallId = $mall['id'];
- // 获取基础配置
- $config = Yii::$app->services->setting->addons->get($mallId, 'Boss', 'basic');
- // 奖金池
- if($config['is_enable'] == StatusEnum::ENABLED && ($config['is_prize_pool'] ?? StatusEnum::DISABLED) == StatusEnum::ENABLED){
- list(
- 'continue' => $continue,
- 'start_day' => $start_day,
- 'end_day' => $end_day,
- 'compute_period' => $compute_period
- ) = $this->getExecutePeriod($config, 'prize_pool_period');
- if ($continue) continue;
- $date_limit = $start_day . '-' . $end_day;
-
- $date_limit = $start_day . '-' . $end_day;
- $job = BossPoolPrizeJob::findOne(['mall_id' => $mallId, 'compute_period' => $compute_period, 'date_limit' => $date_limit, 'status' => StatusEnum::ENABLED]);
- if ($job) continue;
- // 生成执行记录
- $job = new BossPoolPrizeJob();
- $job->mall_id = $mallId;
- $job->date_limit = $date_limit;
- $job->compute_period = $compute_period;
- $last_period = BossPoolPrizeJob::find()->where(['mall_id' => $mallId, 'status' => StatusEnum::ENABLED])
- ->select('period')->orderBy('id DESC')->scalar();
- $period = $last_period ? $last_period + 1 : 1;
- $job->period = $period;
- if (!$job->save()) throw new Exception($job->getErrorMessage());
- $poolPrizeLogic = new PoolPrizeLogic();
- $poolPrizeLogic->send($mallId, $config, $start_day, $end_day, $job->id);
- }
- }
- return true;
- }
- }
- protected function getExecutePeriod($config, $key)
- {
- $continue = false;
- $start_day = 0;
- $end_day = 0;
- // 获取结算周期,0=天,1=周,2=月
- $compute_period = $config[$key];
- switch ($config[$key]) {
- case 1:
- $start_day = date("Ymd", strtotime("-1 day"));
- // $start_day = date("Ymd");
- $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;
- }
- return compact('continue', 'start_day', 'end_day', 'compute_period');
- }
- /**
- * 增加boss分红佣金
- * @Author: lun
- * @DateTime: 2021/11/5 0005 14:27
- * @Copyright: copyright (c) 2021 广东七件事集团
- * @param $mallId
- * @param $config
- * @param $start_day
- * @param $end_time
- * @return bool
- */
- public function addCommissionLog($mallId, $config, $start_day, $end_day, $job_id = 0)
- {
- if ($config['is_enable'] == StatusEnum::DISABLED) {
- Yii::error('系统没有开启股东提成');
- return true;
- }
- $trans = Yii::$app->db->beginTransaction();
- try {
- // 初始化数据
- $time = time();
- $table_name = 'addons_boss_commission_log';
- $reward = [];
- // 获取等级设置
- $setting = AddonsBossLevelSetting::find()->where(['mall_id' => $mallId, 'status' => StatusEnum::ENABLED])->indexBy('level')->asArray()->all();
- foreach ($setting as $level => &$item) {
- $item['extra_restrict_keys'] = json_decode($item['extra_restrict_keys'], true) ?? [];
- $item['extra_restrict_values'] = json_decode($item['extra_restrict_values'], true) ?? [];
- }
- // 检查是否开启沉淀池,并且比例不为零
- $sediment_percent = !empty($config['is_sediment']) ? $config['sediment_percent'] ?? 0 : 0;
- $besides_price_type = [LevelEnum::DIGITAL_PRIZE, LevelEnum::EXTRA_DIGITAL_PRIZE];
- // 获取分红奖励列表
- $i = 1;
- $page_size = 1000;
- while ($reward_list = AddonsBossRewardLog::find()->select('user_id,sum(amounts) amounts,sum(commission) commission,type,from_type')
- ->where(['mall_id' => $mallId, 'is_settlement' => StatusEnum::DISABLED])
- ->andFilterWhere(['between', 'date', $start_day, $end_day])
- ->groupBy('user_id,type')
- ->offset(($i - 1) * $page_size)->limit($page_size)->asArray()->all()) {
- // 获取股东信息
- $boss_uids = array_unique(array_column($reward_list, 'user_id'));
- $boss_arr = AddonsBoss::find()->select('user_id,level,created_at')->where(['user_id' => $boss_uids, 'status' => StatusEnum::ENABLED])->indexBy('user_id')->asArray()->all();
- // 生成计算好的结算数据
- foreach ($reward_list as $item) {
- if (empty($boss_arr[$item['user_id']])) continue;
- $user_level = $boss_arr[$item['user_id']]['level'];// 股东当前等级
- if(!in_array($item['type'], $besides_price_type)){
- if ($item['type'] == 2 && !empty($setting[$user_level]['extra_restrict']) && !empty($setting[$user_level]['extra_restrict_keys'])) {
- // 符合条件三的用户
- if (in_array(2, $setting[$user_level]['extra_restrict_keys'])) {
- $item['commission'] = $this->restrictCond3($boss_arr[$item['user_id']], $setting[$user_level]['extra_restrict_values'][2]['value'], $time, $item['commission']);
- }
- }
-
- // 增加沉淀池数据
- if ($sediment_percent) {
- // sediment_type[1=永久分红,2=额外分红,3=永久+额外分红]
- if ($config['sediment_type'] == 1 && $item['type'] == 1 || $config['sediment_type'] == 2 && $item['type'] == 2 || $config['sediment_type'] == 3) {
- $item['level'] = $user_level;
- $sediment = AddonsBossRewardLog::createSediment($mallId, $item, $sediment_percent, $job_id);
- $item['commission'] = $sediment['commission'];
- $item['sedimen_money'] = $sediment['sedimen_money'];
- !empty($sediment['reward']) && $reward[] = $sediment['reward'];
- }
- }
- }
- if ($item['commission'] < 0.01) continue;// 小于一分钱不允许插入数据
- $rows[] = [
- 'mall_id' => $mallId,
- 'user_id' => $item['user_id'],
- 'amounts' => $item['amounts'],
- 'commission' => $item['commission'],
- 'sedimen_money' => $item['sedimen_money'] ?? 0,
- 'type' => $item['type'],
- 'compute_period' => $config['compute_period'],
- 'start_time' => $start_day,
- 'end_time' => $end_day,
- 'created_at' => $time,
- 'updated_at' => $time,
- 'from_type' => $item['from_type'],
- ];
- }
- $i++;
- }
- if (empty($rows)) throw new Exception('佣金记录为空');
- // 生成数据
- $field = ['mall_id','user_id','amounts','commission','sedimen_money','type','compute_period','start_time','end_time','created_at','updated_at', 'from_type'];
- $res = Yii::$app->db->createCommand()->batchInsert(AddonsBossCommissionLog::tableName(), $field, $rows)->execute();
- if (!$res) throw new Exception('批量生成分红数据失败');
- // 数据生成完成记录表修改结算状态
- AddonsBossRewardLog::updateAll(
- ['is_settlement' => StatusEnum::ENABLED, 'updated_at' => $time],
- ['and', ['mall_id' => $mallId, 'is_settlement' => StatusEnum::DISABLED],['between', 'date', $start_day, $end_day]]
- );
- // 生成沉淀池数据
- if ($reward) {
- $field = ['mall_id','user_id','type','level','amounts','commission','settlement_config','settlement_data','is_settlement','date','created_at','updated_at'];
- Yii::$app->db->createCommand()->batchInsert(AddonsBossRewardLog::tableName(), $field, $reward)->execute();
- }
- $digital_arr = [];
- $k = 1;
- $page_log = 1000;
- // 增加对应股东分佣金额
- while ($log_list = AddonsBossCommissionLog::find()->where(['mall_id' => $mallId,'start_time' => $start_day,'end_time' => $end_day])->andWhere(['!=', 'type', LevelEnum::PERFORMANCE_PRIZE])
- ->offset(($k - 1) * $page_log)->limit($page_log)->asArray()->all()) {
- foreach ($log_list as $item) {
- if(in_array($item['type'], $besides_price_type)){
- $desc = $item['type'] == LevelEnum::DIGITAL_PRIZE ? '股东管理数字币永久分红' : '股东管理额外分红数字币';
- $digital_arr[] = [
- 'mall_id' => $mallId,
- 'user_id' => $item['user_id'],
- 'change_num' => $item['commission'],
- 'is_frozen' => false,
- 'params' => [
- 'desc' => $desc,
- 'source_table' => $table_name,
- 'source_table_id' => $item['id'],
- 'from_type' => BossEnum::ADDONS_NAME,
- 'capital_type' => BossEnum::ADDONS_NAME,
- 'order_no' => ''
- ]
- ];
- if ($item['type'] == LevelEnum::DIGITAL_PRIZE) {
- $boss_commission[$item['user_id']]['digital'] = $item['commission'];
- } else {
- $boss_commission[$item['user_id']]['extra_digital'] = $item['commission'];
- }
- }else{
- $insert_wallet[] = [
- 'mall_id' => $mallId,
- 'user_id' => $item['user_id'],
- 'is_frozen' => false,
- 'wallet_type' => 'commission',
- 'money' => $item['commission'],
- 'desc' => '股东分红佣金',
- 'source_table' => $table_name,
- 'source_table_id' => $item['id'],
- 'from_type' => BossEnum::ADDONS_NAME,
- 'capital_type' => $item['type'] == 1 ? UserWalletEnum::FOREVER : UserWalletEnum::BO_EXTRA,
- ];
- if ($item['type'] == 1) {
- $boss_commission[$item['user_id']]['commission'] = $item['commission'];
- } else {
- $boss_commission[$item['user_id']]['extra_commission'] = $item['commission'];
- }
- }
-
- }
- $k++;
- }
- // 增加用户股东金额
- foreach ($boss_commission as $user_id => $commission) {
- $boss = AddonsBoss::findOne(['mall_id' => $mallId, 'user_id' => $user_id, 'status' => StatusEnum::ENABLED]);
- $boss->commission = empty($commission['commission']) ? $boss->commission : $boss->commission + $commission['commission'];
- $boss->extra_commission = empty($commission['extra_commission']) ? $boss->extra_commission : $boss->extra_commission + $commission['extra_commission'];
- $boss->total_commission = $boss->commission + $boss->extra_commission + $boss->performance_commission;
- $boss->digital = empty($commission['digital']) ? $boss->digital : $boss->digital + $commission['digital'];
- $boss->extra_digital = empty($commission['extra_digital']) ? $boss->extra_digital : $boss->extra_digital + $commission['extra_digital'];
- $boss->total_digital = $boss->digital + $boss->extra_digital;
- if (!$boss->save()) throw new \Exception($boss->getErrorMessage());
- }
- $trans->commit();
- if ($insert_wallet) {
- UserWalletService::batchHandleByQueue($insert_wallet);
- }
- if($digital_arr){
- foreach($digital_arr as $val){
- $res = UserDigital::handleUserDigital($val['mall_id'], $val['user_id'], $val['change_num'], $val['is_frozen'], $val['params']);
- if ($res === false) {
- \Yii::error(__METHOD__. '//股东定时分红赠送数字币,err:' . UserDigital::getStaticError());
- }
- }
- }
- return true;
- } catch (Exception $e) {
- $trans->rollBack();
- $exception = FormatHelper::exception($e, "mall_id={$mallId} 股东定时分红任务失败");
- Yii::error($exception);
- $this->setError($exception);
- return false;
- }
- }
- /**
- * desc@股东额外分红限制条件3
- * __天内最多可获得__元额外分红
- * @Author: lun
- * @DateTime: 2022/9/13 0013 14:39
- * @Copyright: copyright (c) 2021 广东七件事集团
- * @param $boss
- * @param $setting
- * @param $time
- * @param int $available_commission
- * @return int
- */
- public function restrictCond3($boss, $setting, $time, $available_commission = 0)
- {
- $user_id = $boss['user_id'];
- // 获取N天的时间戳 - 增加300秒作为误差值
- $end_time = $time - (86400 * $setting['day'] + 300);
- if ($boss['created_at'] < $end_time) return 0;// 超过N天直接没有额外收入
- $original_commission = $available_commission;
- // 计算N天内已获得的额外分红金额 - 增加300秒作为误差值
- $extra_commission = AddonsBossCommissionLog::find()->where(['user_id' => $user_id, 'type' => 2, 'status' => StatusEnum::ENABLED])
- ->andWhere(['>=', 'created_at', $end_time])->sum('commission') ?? 0;
- // 如果N天内已获得的金额大于或等于设置金额则不再获得金额
- if ($extra_commission >= $setting['money']) {
- $available_commission = 0;
- } else {
- $surplus_extra = $setting['money'] - $extra_commission;// 剩余可得额外分红
- // 如果本次结算额外分红大于剩余可得额外分红,则最多只能获取到剩余的分红
- if ($available_commission >= $surplus_extra) $available_commission = $surplus_extra;
- }
- // 将不发送额外分红的用户数据存入日志,便于查询
- if ($original_commission > $available_commission) {
- FileHelper::writeLog($this->getLogPath('restrictCond3'), "user_id={$user_id} 本次原额外分红={$original_commission},extra_commission={$extra_commission},set_money={$setting['money']},只得到{$available_commission}元额外分红");
- }
- return $available_commission;
- }
- protected function getLogPath($type)
- {
- return Yii::getAlias('@runtime') . "/logs/boss/" . $type . '/' . date('Y_m_d') . '.txt';
- }
- }
|