| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364 |
- <?php
- // +----------------------------------------------------------------------
- // | saiadmin [ saiadmin快速开发框架 ]
- // +----------------------------------------------------------------------
- // | Author: sai <1430792918@qq.com>
- // +----------------------------------------------------------------------
- namespace plugin\saiadmin\app\controller;
- use Throwable;
- use support\Request;
- use support\Response;
- use plugin\saiadmin\exception\ApiException;
- use plugin\saiadmin\basic\OpenController;
- /**
- * 安装控制器
- */
- class InstallController extends OpenController
- {
- /**
- * 不需要登录的方法
- */
- protected array $noNeedLogin = ['index', 'install'];
- /**
- * 应用名称
- * @var string
- */
- protected string $app = 'saiadmin';
- protected string $version = '6.0.0';
- /**
- * 安装首页
- */
- public function index()
- {
- $data['app'] = $this->app;
- $data['version'] = config('plugin.saiadmin.app.version', $this->version);
- $env = base_path() . DIRECTORY_SEPARATOR . '.env';
- clearstatcache();
- if (is_file($env)) {
- $data['error'] = '程序已经安装';
- return view('install/error', $data);
- }
- if (!is_writable(base_path() . DIRECTORY_SEPARATOR . 'config')) {
- $data['error'] = '权限认证失败';
- return view('install/error', $data);
- }
- return view('install/index', $data);
- }
- /**
- * 执行安装
- */
- public function install(Request $request)
- {
- $env = base_path() . DIRECTORY_SEPARATOR . '.env';
- clearstatcache();
- if (is_file($env)) {
- return $this->fail('管理后台已经安装!如需重新安装,请删除根目录env配置文件并重启');
- }
- $user = $request->post('username');
- $password = $request->post('password');
- $database = $request->post('database');
- $host = $request->post('host');
- $port = (int) $request->post('port') ?: 3306;
- $dataType = $request->post('dataType', 'demo');
- try {
- $db = $this->getPdo($host, $user, $password, $port);
- $smt = $db->query("show databases like '$database'");
- if (empty($smt->fetchAll())) {
- $db->exec("create database `$database` CHARSET utf8mb4 COLLATE utf8mb4_general_ci");
- }
- } catch (\Throwable $e) {
- $message = $e->getMessage();
- if (stripos($message, 'Access denied for user')) {
- return $this->fail('数据库用户名或密码错误');
- }
- if (stripos($message, 'Connection refused')) {
- return $this->fail('Connection refused. 请确认数据库IP端口是否正确,数据库已经启动');
- }
- if (stripos($message, 'timed out')) {
- return $this->fail('数据库连接超时,请确认数据库IP端口是否正确,安全组及防火墙已经放行端口');
- }
- throw $e;
- }
- $db->exec("use `$database`");
- $smt = $db->query("show tables like 'sa_system_menu';");
- $tables = $smt->fetchAll();
- if (count($tables) > 0) {
- return $this->fail('数据库已经安装,请勿重复安装');
- }
- if ($dataType == 'demo') {
- $sql_file = base_path() . '/plugin/saiadmin/db/saiadmin-6.0.sql';
- } else {
- $sql_file = base_path() . '/plugin/saiadmin/db/saiadmin-pure.sql';
- }
- if (!is_file($sql_file)) {
- return $this->fail('数据库SQL文件不存在');
- }
- $sql_query = file_get_contents($sql_file);
- $db->exec($sql_query);
- $this->generateConfig();
- $env_config = <<<EOF
- # 数据库配置
- DB_TYPE = mysql
- DB_HOST = $host
- DB_PORT = $port
- DB_NAME = $database
- DB_USER = $user
- DB_PASSWORD = $password
- DB_PREFIX =
- # 缓存方式
- CACHE_MODE = file
- # Redis配置
- REDIS_HOST = 127.0.0.1
- REDIS_PORT = 6379
- REDIS_PASSWORD = ''
- REDIS_DB = 0
- DB_CHARSET = utf8mb4
- # 验证码配置
- CAPTCHA_MODE = cache
- #前端目录
- FRONTEND_DIR = saiadmin-artd
- EOF;
- file_put_contents(base_path() . DIRECTORY_SEPARATOR . '.env', $env_config);
- // 尝试reload
- if (function_exists('posix_kill')) {
- set_error_handler(function () {});
- posix_kill(posix_getppid(), SIGUSR1);
- restore_error_handler();
- }
- return $this->success('安装成功');
- }
- /**
- * 生成配置文件
- */
- protected function generateConfig()
- {
- // 1、think-orm配置文件
- $think_orm_config = <<<EOF
- <?php
- return [
- 'default' => 'mysql',
- 'connections' => [
- 'mysql' => [
- // 数据库类型
- 'type' => env('DB_TYPE', 'mysql'),
- // 服务器地址
- 'hostname' => env('DB_HOST', '127.0.0.1'),
- // 数据库名
- 'database' => env('DB_NAME', 'saiadmin'),
- // 数据库用户名
- 'username' => env('DB_USER', 'root'),
- // 数据库密码
- 'password' => env('DB_PASSWORD', '123456'),
- // 数据库连接端口
- 'hostport' => env('DB_PORT', 3306),
- // 数据库连接参数
- 'params' => [
- // 连接超时3秒
- \PDO::ATTR_TIMEOUT => 3,
- ],
- // 数据库编码默认采用utf8
- 'charset' => env('DB_CHARSET', 'utf8mb4'),
- // 数据库表前缀
- 'prefix' => env('DB_PREFIX', ''),
- // 断线重连
- 'break_reconnect' => true,
- // 自定义分页类
- 'bootstrap' => '',
- // 连接池配置
- 'pool' => [
- 'max_connections' => 5, // 最大连接数
- 'min_connections' => 1, // 最小连接数
- 'wait_timeout' => 3, // 从连接池获取连接等待超时时间
- 'idle_timeout' => 60, // 连接最大空闲时间,超过该时间会被回收
- 'heartbeat_interval' => 50, // 心跳检测间隔,需要小于60秒
- ],
- ],
- ],
- ];
- EOF;
- file_put_contents(base_path() . '/config/think-orm.php', $think_orm_config);
- // 2、chache配置文件
- $cache_config = <<<EOF
- <?php
- return [
- 'default' => env('CACHE_MODE', 'file'),
- 'stores' => [
- 'file' => [
- 'driver' => 'file',
- 'path' => runtime_path('cache')
- ],
- 'redis' => [
- 'driver' => 'redis',
- 'connection' => 'default'
- ],
- 'array' => [
- 'driver' => 'array'
- ]
- ]
- ];
- EOF;
- file_put_contents(base_path() . '/config/cache.php', $cache_config);
- // 3、redis配置文件
- $redis_config = <<<EOF
- <?php
- return [
- 'default' => [
- 'password' => env('REDIS_PASSWORD', ''),
- 'host' => env('REDIS_HOST', '127.0.0.1'),
- 'port' => env('REDIS_PORT', 6379),
- 'database' => env('REDIS_DB', 0),
- 'pool' => [
- 'max_connections' => 5,
- 'min_connections' => 1,
- 'wait_timeout' => 3,
- 'idle_timeout' => 60,
- 'heartbeat_interval' => 50,
- ],
- ]
- ];
- EOF;
- file_put_contents(base_path() . '/config/redis.php', $redis_config);
- // 4、think-cache配置文件
- $think_cache_config = <<<EOF
- <?php
- return [
- // 默认缓存驱动
- 'default' => env('CACHE_MODE', 'file'),
- // 缓存连接方式配置
- 'stores' => [
- // redis缓存
- 'redis' => [
- // 驱动方式
- 'type' => 'redis',
- // 服务器地址
- 'host' => env('REDIS_HOST', '127.0.0.1'),
- // 服务器端口
- 'port' => env('REDIS_PORT', 6379),
- // 服务器密码
- 'password' => env('REDIS_PASSWORD', ''),
- // 数据库
- 'select' => env('REDIS_DB', 0),
- // 缓存前缀
- 'prefix' => 'cache:',
- // 默认缓存有效期 0表示永久缓存
- 'expire' => 0,
- // Thinkphp官方没有这个参数,由于生成的tag键默认不过期,如果tag键数量很大,避免长时间占用内存,可以设置一个超过其他缓存的过期时间,0为不设置
- 'tag_expire' => 86400 * 30,
- // 缓存标签前缀
- 'tag_prefix' => 'tag:',
- // 连接池配置
- 'pool' => [
- 'max_connections' => 5, // 最大连接数
- 'min_connections' => 1, // 最小连接数
- 'wait_timeout' => 3, // 从连接池获取连接等待超时时间
- 'idle_timeout' => 60, // 连接最大空闲时间,超过该时间会被回收
- 'heartbeat_interval' => 50, // 心跳检测间隔,需要小于60秒
- ],
- ],
- // 文件缓存
- 'file' => [
- // 驱动方式
- 'type' => 'file',
- // 设置不同的缓存保存目录
- 'path' => runtime_path() . '/file/',
- ],
- ],
- ];
- EOF;
- file_put_contents(base_path() . '/config/think-cache.php', $think_cache_config);
- // 5、database配置文件
- $database = <<<EOF
- <?php
- return [
- 'default' => 'mysql',
- 'connections' => [
- 'mysql' => [
- 'driver' => env('DB_TYPE', 'mysql'),
- 'host' => env('DB_HOST', '127.0.0.1'),
- 'port' => env('DB_PORT', 3306),
- 'database' => env('DB_NAME', 'saiadmin'),
- 'username' => env('DB_USER', 'root'),
- 'password' => env('DB_PASSWORD', '123456'),
- 'charset' => env('DB_CHARSET', 'utf8mb4'),
- 'collation' => env('DB_COLLATION', 'utf8mb4_general_ci'),
- 'prefix' => env('DB_PREFIX', ''),
- 'strict' => true,
- 'engine' => null,
- 'options' => [
- PDO::ATTR_EMULATE_PREPARES => false, // Must be false for Swoole and Swow drivers.
- ],
- 'pool' => [
- 'max_connections' => 5,
- 'min_connections' => 1,
- 'wait_timeout' => 3,
- 'idle_timeout' => 60,
- 'heartbeat_interval' => 50,
- ],
- ],
- ],
- ];
- EOF;
- file_put_contents(base_path() . '/config/database.php', $database);
- }
- /**
- * 获取pdo连接
- * @param $host
- * @param $username
- * @param $password
- * @param $port
- * @param $database
- * @return \PDO
- */
- protected function getPdo($host, $username, $password, $port, $database = null): \PDO
- {
- $dsn = "mysql:host=$host;port=$port;";
- if ($database) {
- $dsn .= "dbname=$database";
- }
- $params = [
- \PDO::MYSQL_ATTR_INIT_COMMAND => "set names utf8mb4",
- \PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
- \PDO::ATTR_EMULATE_PREPARES => false,
- \PDO::ATTR_TIMEOUT => 5,
- \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
- ];
- return new \PDO($dsn, $username, $password, $params);
- }
- }
|