info("__ __ ____ _ "); $this->info("\ \ / /| __ ) ___ __ _ _ __ __| | "); $this->info(" \ \/ / | __ \ / _ \ / _` | '__/ _` | "); $this->info(" / /\ \ | |_) | (_) | (_| | | | (_| | "); $this->info("/_/ \_\|____/ \___/ \__,_|_| \__,_| "); if ((\File::exists(base_path() . '/.env') && $this->getEnvValue('INSTALLED')) || (env('INSTALLED', false) && $isDocker) ) { $securePath = admin_setting('secure_path', admin_setting('frontend_admin_path', hash('crc32b', config('app.key')))); $this->info("访问 http(s)://你的站点/{$securePath} 进入管理面板,你可以在用户中心修改你的密码。"); $this->warn("如需重新安装请清空目录下 .env 文件的内容(Docker安装方式不可以删除此文件)"); $this->warn("快捷清空.env命令:"); note('rm .env && touch .env'); return ; } if (is_dir(base_path() . '/.env')){ $this->error('😔:安装失败,Docker环境下安装请保留空的 .env 文件'); return ; } // 选择是否使用Sqlite if(confirm(label: '是否启用Sqlite(无需额外安装)代替Mysql',default: false, yes: '启用', no: '不启用')) { $sqliteFile = '.docker/.data/database.sqlite'; if (!file_exists(base_path($sqliteFile))) { // 创建空文件 if (!touch(base_path($sqliteFile))) { echo "sqlite创建成功: $sqliteFile"; } else { echo "sqlite创建失败"; } } $envConfig = [ 'DB_CONNECTION' => 'sqlite', 'DB_DATABASE' => $sqliteFile, 'DB_HOST' => '', 'DB_USERNAME' => '', 'DB_PASSWORD' => '', ]; }else{ $isMysqlValid = false; while(!$isMysqlValid){ $envConfig = [ 'DB_CONNECTION' => 'mysql', 'DB_HOST' => text(label: "请输入数据库地址", default: '127.0.0.1', required: true), 'DB_PORT' => text(label: '请输入数据库端口', default: '3306', required: true), 'DB_DATABASE' => text(label:'请输入数据库名', default:'xboard', required: true), 'DB_USERNAME' => text(label:'请输入数据库用户名', required: true), 'DB_PASSWORD' => text(label:'请输入数据库密码', required: false), ]; try { \Config::set("database.connections.mysql.host", $envConfig['DB_HOST']); \Config::set("database.connections.mysql.port", $envConfig['DB_PORT']); \Config::set("database.connections.mysql.database", $envConfig['DB_DATABASE']); \Config::set("database.connections.mysql.username", $envConfig['DB_USERNAME']); \Config::set("database.connections.mysql.password", $envConfig['DB_PASSWORD']); \DB::purge('mysql'); \DB::connection('mysql')->getPdo(); $isMysqlValid = true; } catch (\Exception $e) { // 连接失败,输出错误消息 $this->error("数据库连接失败:" . $e->getMessage()); $this->info("请重新输入数据库配置"); } } } $envConfig['APP_KEY'] = 'base64:' . base64_encode(Encrypter::generateKey('AES-256-CBC')); $envConfig['INSTALLED'] = true; $isReidsValid = false; while(!$isReidsValid){ // 判断是否为Docker环境 if ($isDocker == 'true' && (confirm(label: '是否启用Docker内置的Redis', default: true, yes:'启用', no:'不启用'))){ $envConfig['REDIS_HOST'] = '/run/redis-socket/redis.sock'; $envConfig['REDIS_PORT'] = 0; $envConfig['REDIS_PASSWORD'] = null; }else{ $envConfig['REDIS_HOST'] = text(label: '请输入Redis地址', default: '127.0.0.1',required: true); $envConfig['REDIS_PORT'] = text(label: '请输入Redis端口', default: '6379', required: true); $envConfig['REDIS_PASSWORD'] = text(label: '请输入redis密码(默认: null)', default: ''); } $redisConfig = [ 'client' => 'phpredis', // 或 'phpredis' 'default' => [ 'host' => $envConfig['REDIS_HOST'], 'password' => $envConfig['REDIS_PASSWORD'], 'port' => $envConfig['REDIS_PORT'], 'database' => 0, ], ]; try{ $redis = new \Illuminate\Redis\RedisManager(app(), 'phpredis', $redisConfig); $redis->ping(); $isReidsValid = true; }catch(\Exception $e){ // 连接失败,输出错误消息 $this->error("redis连接失败:" . $e->getMessage()); $this->info("请重新输入REDIS配置"); } } if (!copy(base_path() . '/.env.example', base_path() . '/.env')) { abort(500, '复制环境文件失败,请检查目录权限'); }; $email = text(label: '请输入管理员账号',required: true, validate: fn (string $email): ?string => match (true) { ! filter_var($email, FILTER_VALIDATE_EMAIL) => '请输入有效的邮箱地址.', default => null, }); $password = Helper::guid(false); $this->saveToEnv($envConfig); \Artisan::call('config:clear'); \Artisan::call('config:cache'); \Artisan::call('cache:clear'); $this->info('正在清空数据库请稍等'); \Artisan::call('db:wipe'); $this->info('数据库清空完成'); $this->info('正在导入数据库请稍等...'); \Artisan::call("migrate"); $this->info(\Artisan::output()); $this->info('数据库导入完成'); $this->info('开始注册管理员账号'); if (!$this->registerAdmin($email, $password)) { abort(500, '管理员账号注册失败,请重试'); } $this->info('🎉:一切就绪'); $this->info("管理员邮箱:{$email}"); $this->info("管理员密码:{$password}"); $defaultSecurePath = hash('crc32b', config('app.key')); $this->info("访问 http(s)://你的站点/{$defaultSecurePath} 进入管理面板,你可以在用户中心修改你的密码。"); } catch (\Exception $e) { $this->error($e); } } public function registerAdmin($email, $password) { $user = new User(); $user->email = $email; if (strlen($password) < 8) { abort(500, '管理员密码长度最小为8位字符'); } $user->password = password_hash($password, PASSWORD_DEFAULT); $user->uuid = Helper::guid(true); $user->token = Helper::guid(); $user->is_admin = 1; return $user->save(); } private function saveToEnv($data = []) { function set_env_var($key, $value) { if (! is_bool(strpos($value, ' '))) { $value = '"' . $value . '"'; } $key = strtoupper($key); $envPath = app()->environmentFilePath(); $contents = file_get_contents($envPath); preg_match("/^{$key}=[^\r\n]*/m", $contents, $matches); $oldValue = count($matches) ? $matches[0] : ''; if ($oldValue) { $contents = str_replace("{$oldValue}", "{$key}={$value}", $contents); } else { $contents = $contents . "\n{$key}={$value}\n"; } $file = fopen($envPath, 'w'); fwrite($file, $contents); return fclose($file); } foreach($data as $key => $value) { set_env_var($key, $value); } return true; } function getEnvValue($key, $default = null) { $dotenv = \Dotenv\Dotenv::createImmutable(base_path()); $dotenv->load(); return Env::get($key, $default); } }