setName('ChannelClean')->setDescription('渠道定期清理脚本'); } protected function execute(Input $input, Output $output) { ini_set('memory_limit', '1024M'); $this->now_time = time(); $this->_output = $output; $this->sdkGameListModel = new SdkGameList; $output->writeln(date('Y-m-d H:i:s')." ChannelClean start\r\n"); $this->cleanNewChannel(); $this->cleanOldChannel(); $this->cleanGame(); $output->writeln(date('Y-m-d H:i:s')." ChannelClean end\r\n"); exit; } /** * 清理新创建渠道 * */ private function cleanNewChannel() { $settingModel = new Setting; $subChannel = new SubChannel; $adminModel = new AdminModel(); $channelModel = new Channel; $this->_output->writeln(" cleanNewChannel\r\n"); $day_limit = $settingModel::getSetting('NEW_CHANNEL_DAY'); $channel_ids= []; //要清理的新增渠道 //创建了几天以上的新渠道 $adminList = $adminModel->field('channel_id')->where(['channel_id'=>['>',$this->old_max_channel_id]])->where(['status'=>1,'type'=>2,'create_time'=>['<',($this->now_time-$day_limit*24*3600)]])->select(); $this->_output->writeln("cleanNewChannel----adminModel: ".$adminModel->getLastSql()." \r\n"); if(!empty($adminList)){ $channel_ids = arrayColumnByObject($adminList,'channel_id'); } else{ return false; } //有注册用户的渠道ID $activeRegitsterChannelIds = $this->getRegitsterChannelIds($day_limit); //有流水渠道 $activePayChannelIds = $this->getPayChannelIds($day_limit); //活跃渠道 $activeChannelIds = array_unique(array_merge($activeRegitsterChannelIds,$activePayChannelIds)); //过滤掉有活跃用户的渠道ID $channel_ids = array_diff($channel_ids, $activeChannelIds); //过滤掉下级渠道有注册用户的渠道 $channel_ids = $this->filterCleanNewChannel($channel_ids,$activeChannelIds); $sdkGameList = $this->sdkGameListModel->field('id,channel_id,gameid,package_type,filename')->where('channel_id',['in',$channel_ids],['>',$this->old_max_channel_id])->select(); $this->_output->writeln("cleanNewChannel----sdkGameListModel: ".$this->sdkGameListModel->getLastSql()." \r\n"); //要冻结的渠道 $adminArr = $adminModel->field('id,channel_id,username')->where('channel_id',['in',$channel_ids],['>',$this->old_max_channel_id])->where(['status'=>1,'type'=>2])->select(); $this->_output->writeln("cleanNewChannel----adminArr: ".$adminModel->getLastSql()." \r\n"); // 启动事务 Db::startTrans(); try{ //包体删除及分包记录删除 if(!empty($sdkGameList)){ foreach ($sdkGameList as $key => $value) { //删除包体文件 $removeResult = $subChannel->removePackageFile($value['gameid'], $value['filename']); $this->sdkGameListModel->where(['id' => $value['id']])->delete(); } } //冻结渠道 if(!empty($adminArr)){ foreach ($adminArr as $akey => $avalue) { $adminModel->where(['id' => $avalue['id'],'type'=>2])->update(['status'=>0]); $channelModel->where(['id' => $avalue['channel_id'],'flag'=>3])->update(['status'=>0]); Log::insertOperateLog('crontab/ChannelClean/cleanNewChannel', "编辑子渠道: {$avalue['username']},状态:冻结", 42, 1, 'admin'); } } Db::commit(); } catch (\Exception $e) { $this->_output->writeln(date('H:i:s')." 清理新创建渠道结果:fail".$e->getMessage()."\r\n"); // 回滚事务 Db::rollback(); } } /** * 过滤掉下级渠道有活跃用户的渠道 * * @param $channel_ids array 要冻结的渠道id * @param $activeChannelIds array 有活跃用户的渠道ID * */ private function filterCleanNewChannel($channel_ids,$activeChannelIds) { $channelModel = new Channel; $result = []; if(!empty($channel_ids)){ foreach($channel_ids as $id){ //子渠道id $sub_channelIds = $channelModel->getChildIds($id); //有子渠道并且子渠道有活跃用户 if(!empty($sub_channelIds) && !empty(array_intersect($sub_channelIds, $activeChannelIds))){ } else{ $result[] = $id; } } } return $result; } /** * 清理历史渠道 * */ private function cleanOldChannel() { $settingModel = new Setting; $subChannel = new SubChannel; $adminModel = new AdminModel(); $this->_output->writeln(date('Y-m-d H:i:s')." cleanOldChannel \r\n"); $day_limit = $settingModel::getSetting('OLD_CHANNEL_DAY'); $activeRegitsterChannelIds = $this->getRegitsterChannelIds($day_limit); //有注册用户渠道 $activePayChannelIds = $this->getPayChannelIds($day_limit); //有流水渠道 $activeChannelIds = array_unique(array_merge($activeRegitsterChannelIds,$activePayChannelIds)); //活跃渠道 $sdkGameList = $this->sdkGameListModel->field('id,channel_id,gameid,package_type,filename') ->where('channel_id',['not in',$activeChannelIds],['<=',$this->old_max_channel_id]) ->where(['update_time'=>['<',($this->now_time-$day_limit*24*3600)]])->select(); $this->_output->writeln(date('Y-m-d H:i:s')." cleanOldChannel----sdkGameListModel: ".$this->sdkGameListModel->getLastSql()." \r\n"); //包体删除及分包记录删除 if(!empty($sdkGameList)){ foreach ($sdkGameList as $key => $value) { //删除包体文件 $removeResult = $subChannel->removePackageFile($value['gameid'], $value['filename']); $this->sdkGameListModel->where(['id' => $value['id']])->delete(); } } } /** * 清理下架的游戏 * */ private function cleanGame() { $settingModel = new Setting; $subChannel = new SubChannel; $shortLinkModel = new PromotionShortLink; $this->_output->writeln(date('Y-m-d H:i:s')." cleanGame\r\n"); $day_limit = $settingModel::getSetting('GAME_DAY'); //下架的游戏并且创建时间超过30天 $game_list = Db::table('cy_game')->field('id,pinyin')->where(['cooperation_status'=>3,'create_time'=>['<',($this->now_time-$day_limit*24*3600)]])->select(); //下架的游戏拼音数组 $pinyin_list= []; //下架的游戏ID $game_ids = []; if (!empty($game_list)) { foreach ($game_list as $gvalue) { $game_ids[] = $gvalue['id']; $pinyin_list[$gvalue['id']] = $gvalue['pinyin']; } } else{ return false; } //------------------- 指定时间内有流水的下架游戏 start ------------------------// $pay_gameids = Db::table('cy_pay force index(idx_status_createtime)')->field('DISTINCT gameid')->where(['status'=>1,'create_time'=>['>=',($this->now_time-$day_limit*24*3600)],'gameid'=>['in',$game_ids]])->select(); if(!empty($pay_gameids)){ $pay_gameids = arrayColumnByObject($pay_gameids,'gameid'); //过滤掉有流水的下架游戏 $game_ids = array_diff($game_ids, $pay_gameids); } //------------------- 指定时间内有流水的下架游戏 end ------------------------// //------------------- 指定时间内有登录用户的下架游戏 start ------------------------// //指定天数的前半部分 $day_before_limit= (int)($day_limit/2); //指定时间内有登录用户的下架游戏ID $login_before_gameids = Db::table('cy_logininfo')->field('DISTINCT gameid') ->where("login_time>=".($this->now_time-$day_limit*24*3600)." and login_time<".($this->now_time-$day_before_limit*24*3600)) ->where(['gameid'=>['in',$game_ids]])->select(); if(!empty($login_before_gameids)){ $login_before_gameids = arrayColumnByObject($login_before_gameids,'gameid'); //过滤掉有登录用户的下架游戏 $game_ids = array_diff($game_ids, $login_before_gameids); } //指定时间内有登录用户的下架游戏ID $login_after_gameids = Db::table('cy_logininfo')->field('DISTINCT gameid') ->where("login_time>=".($this->now_time-$day_before_limit*24*3600)) ->where(['gameid'=>['in',$game_ids]])->select(); if(!empty($login_after_gameids)){ $login_after_gameids = arrayColumnByObject($login_after_gameids,'gameid'); //过滤掉有登录用户的下架游戏 $game_ids = array_diff($game_ids, $login_after_gameids); } //------------------- 指定时间内有登录用户的下架游戏 end ------------------------// $sdkGameList = $this->sdkGameListModel->field('id,channel_id,gameid,package_type,filename')->where(['gameid'=>['in',$game_ids]])->select(); //删除推广落地页的短链接记录 $shortLinkModel->where(['game_id'=>['in',$game_ids]])->delete(); $this->_output->writeln("cleanGame----sdkGameListModel: ".$this->sdkGameListModel->getLastSql()." \r\n"); //包体删除及分包记录删除 if(!empty($sdkGameList)){ foreach ($sdkGameList as $key => $value) { //删除包体文件 $subChannel->removePackageFile($value['gameid'], $value['filename']); $this->sdkGameListModel->where(['id' => $value['id']])->delete(); } } //删除游戏母包 if (!empty($game_ids)) { foreach ($game_ids as $gid) { $path = '/data/www/aoyou/download/sygame/'.$pinyin_list[$gid]; //文件夹是否存在,并且是个目录 if (is_dir($path)) { $this->_output->writeln("cleanGame----删除游戏母包: ".$path." \r\n"); $matches = glob($path . '/*'); if (is_array($matches)) { array_map('unlink', $matches); } rmdir($path); } } } } /** * 获得指定时间内有注册玩家的渠道ID * * @param $day_limit int 指定的天数 * * @return $channel_ids array 渠道ID集 */ private function getRegitsterChannelIds($day_limit) { $settingModel = new Setting; $channel_ids = []; for($i=1;$i<=$day_limit;$i++){ $temp_ids = Db::table('cy_member_channel_game_rel')->field('DISTINCT channel_id')->where("mcgr_createtime>=".($this->now_time-$i*24*3600)." and mcgr_createtime<".($this->now_time-($i-1)*24*3600))->select(); //$this->_output->writeln(" getRegitsterChannelIds:".Db::table('cy_member_channel_game_rel')->getLastSql()."\r\n"); $temp_ids = !empty($temp_ids) ? arrayColumnByObject($temp_ids,'channel_id') : []; $channel_ids = array_unique(array_merge($channel_ids,$temp_ids)); } //白名单 $channel_white_list = $settingModel::getSetting('CHANNEL_WHITE_LIST'); if(!empty($channel_white_list)){ $channel_white_list = explode(",", $channel_white_list); $channel_ids = array_unique(array_merge($channel_ids,$channel_white_list)); } return $channel_ids; } /** * 获得指定时间内有流水的渠道ID * * @param $day_limit int 指定的天数 * * @return $channel_ids array 渠道ID集 * */ private function getPayChannelIds($day_limit) { $channel_ids = []; for($i=1;$i<=$day_limit;$i++){ $temp_ids = Db::table('cy_pay')->field('DISTINCT channel_id')->where("create_time>=".($this->now_time-$i*24*3600)." and create_time<".($this->now_time-($i-1)*24*3600))->where(['status'=>1])->select(); //$this->_output->writeln(" getPayChannelIds:".Db::table('cy_pay')->getLastSql()."\r\n"); $temp_ids = !empty($temp_ids) ? arrayColumnByObject($temp_ids,'channel_id') : []; $channel_ids = array_unique(array_merge($channel_ids,$temp_ids)); } return $channel_ids; } }