scanaddon(); $pluginCount = count(array_filter($plugins, fn($p) => ($p['state'] ?? 0) == 1)); // 应用模块数(app 目录下) $appDir = root_path() . 'app'; $apps = array_filter(scandir($appDir), function ($d) use ($appDir) { return $d !== '.' && $d !== '..' && is_dir($appDir . DIRECTORY_SEPARATOR . $d); }); $features = [ [ 'icon' => 'plugin', 'title' => '插件机制', 'desc' => '基于事件订阅器的热插拔插件,钩子自动注册,与业务完全解耦。', 'url' => url('feature/detail', ['name' => 'plugin']), ], [ 'icon' => 'app', 'title' => '多应用架构', 'desc' => 'api / backend / member / frontend 多应用隔离,路由分组清晰。', 'url' => url('feature/detail', ['name' => 'multi-app']), ], [ 'icon' => 'vip', 'title' => '会员 / 支付', 'desc' => 'mqpay 免签支付 + 会员开通事件链,扫码即到帐自动开通。', 'url' => url('feature/detail', ['name' => 'member-pay']), ], [ 'icon' => 'doc', 'title' => '文档 / 示例', 'desc' => '完善的开发文档、API 示例与快速开始指南,开箱即用。', 'url' => url('feature/detail', ['name' => 'doc']), ], ]; return view('site/index', [ 'controller' => $this->request->controller(), 'features' => $features, 'pluginCount' => $pluginCount, 'appCount' => count($apps), ]); } /** * 扫描 addon 目录,读取各插件 info.php */ private function scanaddon(): array { $dir = root_path() . 'addon'; $list = []; if (!is_dir($dir)) { return $list; } foreach (scandir($dir) as $name) { if ($name === '.' || $name === '..' || !is_dir($dir . DIRECTORY_SEPARATOR . $name)) { continue; } $infoFile = $dir . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR . 'info.php'; if (!is_file($infoFile)) { continue; } $info = include $infoFile; if (is_array($info)) { $list[] = $info; } } return $list; } }