'raw_retention_days', 'group' => 'nginx_log', 'value' => '7', 'remark' => '原始日志保留天数(0=永久)', 'sort' => 0, ], [ 'name' => 'stat_retention_days', 'group' => 'nginx_log', 'value' => '365', 'remark' => '统计聚合保留天数(0=永久)', 'sort' => 0, ], [ 'name' => 'topn_default', 'group' => 'nginx_log', 'value' => '10', 'remark' => 'Top N 默认值(热门 URL/Referer/UA)', 'sort' => 0, ], [ 'name' => 'exclude_static', 'group' => 'nginx_log', 'value' => '1', 'remark' => '是否排除静态资源访问(0=不排除,1=排除 /css/.js/.png 等扩展名)', 'sort' => 0, ], ]; /** * 待新增菜单. * 字段顺序与 adminInitData/SystemMenu.php 一致:id/pid/title/icon/href/params/target/sort/status. * id 显式分配 300-303,与 adminInitData 保持一致(顶级 300 + 3 个子菜单)。 */ public $newMenus = [ [ 'id' => 300, 'pid' => 0, 'title' => 'Nginx 日志分析', 'icon' => 'fa fa-chart-bar', 'href' => '', 'params' => '', 'target' => '_self', 'sort' => 0, 'status' => 1, ], [ 'id' => 301, 'pid' => 300, 'title' => '访问统计仪表盘', 'icon' => 'fa fa-line-chart', 'href' => 'system.nginx_log_stat/index', 'params' => '', 'target' => '_self', 'sort' => 0, 'status' => 1, ], [ 'id' => 302, 'pid' => 300, 'title' => '原始访问日志', 'icon' => 'fa fa-file-text', 'href' => 'nginx.access_log/index', 'params' => '', 'target' => '_self', 'sort' => 0, 'status' => 1, ], [ 'id' => 303, 'pid' => 300, 'title' => '读取位置管理', 'icon' => 'fa fa-map-marker', 'href' => 'nginx.log_position/index', 'params' => '', 'target' => '_self', 'sort' => 0, 'status' => 1, ], ]; public function update() { $this->output->writeln('更新代码'); $this->output->info('v2.4.0:nginx_log 分析模块存量升级(补齐 4 条 sysconfig + 4 条菜单)'); $configTable = config('database.connections.mysql.prefix', 'ul_') . 'system_config'; $menuTable = config('database.connections.mysql.prefix', 'ul_') . 'system_menu'; // 确认表存在(防御性检查,参照 v2.3.0.php 范式) $tablesExist = Db::query( "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME IN (?, ?)", [$configTable, $menuTable] ); if (count($tablesExist) < 2) { $this->output->warning("表 {$configTable} 或 {$menuTable} 不存在,跳过数据补齐。请先执行 scheme:sync 或 migrate:run 初始化表结构。"); return; } $configAdded = 0; $configSkipped = 0; foreach ($this->newConfigs as $cfg) { // 幂等:用 (group, name) 检查存在性 $exists = Db::name('system_config') ->where('group', $cfg['group']) ->where('name', $cfg['name']) ->find(); if ($exists) { $this->output->writeln(" - 配置 {$cfg['group']}.{$cfg['name']} 已存在,跳过"); ++$configSkipped; continue; } Db::name('system_config')->insert($cfg); $this->output->writeln(" - 新增配置 {$cfg['group']}.{$cfg['name']} 完成"); ++$configAdded; } $menuAdded = 0; $menuSkipped = 0; foreach ($this->newMenus as $menu) { // 幂等:用 id 检查存在性(顶级菜单 href 为空,不能用 href 去重) $exists = Db::name('system_menu') ->where('id', $menu['id']) ->find(); if ($exists) { $this->output->writeln(" - 菜单 id={$menu['id']} ({$menu['title']}) 已存在,跳过"); ++$menuSkipped; continue; } Db::name('system_menu')->insert($menu); $this->output->writeln(" - 新增菜单 id={$menu['id']} ({$menu['title']}) 完成"); ++$menuAdded; } $totalSkipped = $configSkipped + $menuSkipped; $this->output->info("本次新增 {$configAdded} 条配置、{$menuAdded} 条菜单,跳过 {$totalSkipped} 条已存在"); $this->output->writeln('更新代码完成'); } }