You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

338 lines
11 KiB
PHP

<?php
declare(strict_types=1);
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use app\common\model\game\Heroes;
use app\common\model\game\UserRoles;
use app\common\model\game\UserTroops;
use app\common\model\game\UserAccount;
use app\common\model\log\UserPayOrder;
use app\common\model\config\CidConfig;
use think\facade\Db;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PHPMailer\PHPMailer\Exception;
use PhpOffice\PhpSpreadsheet\Calculation\Engine\BranchPruner;
class StatMonthData extends Command
{
protected function configure()
{
// 指令配置
$this->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;
}
}