setName('stat_month_data') ->setDescription('the stat_month_data command'); } protected function execute(Input $input, Output $output) { $output->writeln("SMD开始统计 === "); // 获取区服列表 $appid = env('app.appid', 'daodao'); $cids = CidConfig::where('Appid', $appid) ->where('Inner', 0) ->where('Status', 1) ->order('Cid', 'asc') ->column('Cid'); $month = date('Y-m', strtotime('-1 day')); $src = app()->getRootPath() . '/public/download/' . $month . '/'; if (!file_exists($src)) { mkdir($src, 0775, true); } // 关卡 $output->writeln("-- 关卡开始"); $tmpBarrieries = Db::connect('config') ->table('barrieres') ->field('barrierId,difficulty,chapter,largeLevel') ->order('barrierId', 'asc') ->select() ->toArray(); $barrierConfig = []; foreach ($tmpBarrieries as $b) { $barrierConfig[$b['barrierId']] = $b['difficulty'] . '-' . $b['chapter'] . '-' . $b['largeLevel']; } $barrieres = []; foreach ($cids as $k => $cid) { $output->writeln('--- ' . $cid . "区关卡开始"); $barrierData = UserRoles::where('zone', $cid) ->group('barrierId') ->order('barrierId', 'asc') ->column('COUNT(1)', 'barrierId'); $maxBarrierId = max(array_keys($barrierData)); foreach ($barrierConfig as $bid => $chapter) { if ($bid > $maxBarrierId) { break; } $barrieres[$k][$chapter] = isset($barrierData[$bid]) ? $barrierData[$bid] : 0; } $output->writeln('--- ' . $cid . "区关卡开始"); } $output->writeln('--- 生成关卡excel'); $this->_createExcel($src, $cids, $barrieres, '关卡'); $output->writeln("-- 关卡结束"); // 任务 $output->writeln("-- 任务开始"); $missions = []; foreach ($cids as $k => $cid) { $output->writeln('--- ' . $cid . "区任务开始"); $missionData = UserRoles::where('zone', $cid) ->group('missionId') ->order('missionId', 'asc') ->column('COUNT(1)', 'missionId'); $maxMissionId = max(array_keys($missionData)); $missions[$k] = $this->_padArrayKey($missionData, $maxMissionId); $output->writeln('--- ' . $cid . "区任务结束"); } $output->writeln('--- 生成任务excel'); $this->_createExcel($src, $cids, $missions, '任务'); $output->writeln("-- 任务结束"); // 爬塔 $output->writeln("-- 爬塔开始"); $storey = []; foreach ($cids as $k => $cid) { $output->writeln('--- ' . $cid . "区爬塔开始"); $storeyData = UserRoles::where('zone', $cid) ->group('storey') ->order('storey', 'asc') ->column('COUNT(1)', 'storey'); $maxStorey = max(array_keys($storeyData)); $storey[$k] = $this->_padArrayKey($storeyData, $maxStorey); $output->writeln('--- ' . $cid . "区爬塔结束"); } $output->writeln('--- 生成爬塔excel'); $this->_createExcel($src, $cids, $storey, '爬塔'); $output->writeln("-- 爬塔结束"); // 战队等级 $output->writeln($cid . "区等级开始"); $output->writeln("-- 等级开始"); $lv = []; foreach ($cids as $k => $cid) { $output->writeln('--- ' . $cid . "区等级开始"); $lvData = UserAccount::where('Cid', $cid) ->group('Lv') ->order('Lv', 'asc') ->column('COUNT(1)', 'Lv'); $lv[$k] = $this->_padArrayKey($lvData); $output->writeln('--- ' . $cid . "区等级结束"); } $output->writeln('--- 生成等级excel'); $this->_createExcel($src, $cids, $lv, '等级'); $output->writeln("-- 等级结束"); // 主关卡战力 $output->writeln("-- 战力开始"); $powers = []; foreach ($cids as $k => $cid) { $firstUid = $cid * 100000; $endUid = $firstUid + 99999; $output->writeln('--- ' . $cid . "区战力开始"); $troops = UserTroops::whereBetween('uid', [$firstUid, $endUid]) ->where('type', 1) ->where('sort', 1) ->column('uuids', 'uid'); $heroes = Heroes::whereBetween('uid', [$firstUid, $endUid]) ->field('uid,uuid,power') ->select() ->toArray(); if (!$troops || !$heroes) { continue; } $heroPowers = []; foreach ($heroes as $h) { $heroPowers[$h['uid']][$h['uuid']] = $h['power']; } $powerData = []; foreach ($troops as $uid => $t) { if (!isset($heroPowers[$uid])) { continue; } $heroPower = 0; $uuids = json_decode($t, true); if (!$uuids || !is_array($uuids)) { continue; } foreach ($uuids as $uuid) { if ($uuid <= 0) { continue; } $heroPower += $heroPowers[$uid][$uuid]; } $key = intval($heroPower / 1000); if ($key <= 0) { continue; } if ($key >= 200) { $key = 200; } if (array_key_exists($key, $powerData)) { $powerData[$key]++; } else { $powerData[$key] = 1; } } ksort($powerData); $powers[$k] = $this->_padArrayKey($powerData); $output->writeln('--- ' . $cid . "区战力结束"); } $output->writeln('--- 生成战力excel'); $this->_createExcel($src, $cids, $powers, '战力(k)'); $output->writeln("-- 等级结束"); $output->writeln("SMD结束统计 === "); } private function _getNextColumn($column = '') { if (!$column) { return 'A'; } // 最多支持2位 if (strlen($column) > 2) { return ''; } // A=65 $sen = ''; if (strlen($column) > 1) { $columns = str_split($column, 1); list($first, $sen) = $columns; } else { $first = $column; } $firstInt = ord($first); // 单字母 if (!$sen) { // 如果是Z if ($firstInt == 90) { return 'AA'; } return chr($firstInt + 1); } else { $senInt = ord($sen); if ($senInt == 90) { return chr($firstInt + 1) . 'A'; } return $first . chr($senInt + 1); } } private function _padArrayKey($data, $max = 200) { $result = []; for ($i = 1; $i <= $max; $i++) { if (isset($data[$i])) { $result[$i] = $data[$i]; } else { $result[$i] = 0; } } return $result; } private function _createExcel($src, $cids, $data, $name) { if (!$data) { return false; } $date = date('Y-m-d', strtotime('-1 day')); $month = date('Y-m', strtotime($date)); //创建excel文件 $fileName = $month . '月-' . $name . '.xlsx'; if (file_exists($src . $fileName)) { $spreadsheet = IOFactory::load($src . $fileName); } else { $spreadsheet = new Spreadsheet(); } foreach ($cids as $k => $cid) { $sheet = $spreadsheet->getSheetByName($cid . '区'); if (!$sheet) { $sheet = new Worksheet($spreadsheet, $cid . '区'); $spreadsheet->addSheet($sheet, $k); } $column = $sheet->getHighestColumn(); $nextColumn = $this->_getNextColumn($column); // 设置单元格内容 $sheet->setCellValue('A1', $name); $sheet->setCellValue($nextColumn . '1', $date); if (!isset($data[$k])) { continue; } $row = 2; $columnData = $data[$k]; foreach ($columnData as $k => $v) { $sheet->setCellValue('A' . $row, $k); $sheet->setCellValue($nextColumn . $row, $v); $row++; } } $writer = IOFactory::createWriter($spreadsheet, 'Xlsx'); $writer->save($src . $fileName); unset($spreadsheet); unset($sheet); $log = [ 'type' => 2, 'statkey' => $month, 'filename' => '/download/' . $month . '/' . $fileName, 'createtime' => date('Y-m-d H:i:s'), 'updatetime' => date('Y-m-d H:i:s'), ]; $exist = Db::connect('log')->table('log_download') ->where('type', 2) ->where('statkey', $log['statkey']) ->where('filename', $log['filename']) ->find(); if (!$exist) { Db::connect('log')->table('log_download')->insert($log); } else { Db::connect('log')->table('log_download') ->where('type', 2) ->where('statkey', $log['statkey']) ->where('filename', $log['filename']) ->update(['updatetime' => $log['updatetime']]); } return true; } }