123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579 |
- <?php
- namespace app\install\controller;
- use app\model\site\Site;
- use app\model\sys\SysUser;
- use app\service\admin\install\InstallSystemService;
- use app\service\admin\shop\admin\ShopCategoryService;
- use app\service\admin\shop\admin\ShopService;
- use app\service\admin\shop\admin\ShopSiteGroupService;
- use app\service\core\addon\CoreAddonInstallService;
- use app\service\core\addon\CoreAddonService;
- use app\service\core\schedule\CoreScheduleInstallService;
- use Exception;
- use think\facade\Cache;
- use think\facade\Db;
- use think\facade\View;
- use think\Response;
- class Index extends BaseInstall
- {
- /**
- *安装
- */
- public function index()
- {
- $this->checkLock();
- $step = input("step", 1);
- if ($step == 1) {
- return View::fetch('index/step-1');
- } elseif ($step == 2) {
- //系统变量
- $system_variables = [];
- $phpv = PHP_VERSION;
- $os = PHP_OS;
- $server = $_SERVER[ 'SERVER_SOFTWARE' ];
- $host = ( empty($_SERVER[ 'REMOTE_ADDR' ]) ? $_SERVER[ 'REMOTE_HOST' ] : $_SERVER[ 'REMOTE_ADDR' ] );
- $name = $_SERVER[ 'SERVER_NAME' ];
- $verison = !(version_compare(PHP_VERSION, '8.0.0') == -1);
- //pdo
- $pdo = extension_loaded('pdo') && extension_loaded('pdo_mysql');
- $system_variables[] = [ "name" => "pdo", "need" => "开启", "status" => $pdo ];
- //curl
- $curl = extension_loaded('curl') && function_exists('curl_init');
- $system_variables[] = [ "name" => "curl", "need" => "开启", "status" => $curl ];
- //openssl
- $openssl = extension_loaded('openssl');
- $system_variables[] = [ "name" => "openssl", "need" => "开启", "status" => $openssl ];
- //gd
- $gd = extension_loaded('gd');
- $system_variables[] = [ "name" => "GD库", "need" => "开启", "status" => $gd ];
- //fileinfo
- $fileinfo = extension_loaded('fileinfo');
- $system_variables[] = [ "name" => "fileinfo", "need" => "开启", "status" => $fileinfo ];
- //sodium
- $sodium = extension_loaded('sodium');
- $system_variables[] = [ "name" => "sodium", "need" => "开启", "status" => $sodium ];
- $root_path = str_replace("\\", DIRECTORY_SEPARATOR, dirname(__FILE__, 4));
- $root_path = str_replace("../", DIRECTORY_SEPARATOR, $root_path);
- $dirs_list = [
- [ "path" => $root_path . DIRECTORY_SEPARATOR, "path_name" => "niucloud/", "name" => "网站目录" ],
- [ "path" => $root_path . DIRECTORY_SEPARATOR . ".env", "path_name" => "niucloud/.env", "name" => "env" ],
- [ "path" => $root_path . DIRECTORY_SEPARATOR . ".example.env", "path_name" => "niucloud/.example_env", "name" => "env" ],
- [ "path" => $root_path . DIRECTORY_SEPARATOR . 'runtime'.DIRECTORY_SEPARATOR, "path_name" => "niucloud/runtime", "name" => "runtime" ],
- [ "path" => $root_path . DIRECTORY_SEPARATOR . 'public'.DIRECTORY_SEPARATOR.'upload'.DIRECTORY_SEPARATOR, "path_name" => "niucloud/public/upload", "name" => "upload" ],
- [ "path" => $root_path . DIRECTORY_SEPARATOR . 'app'.DIRECTORY_SEPARATOR.'install'.DIRECTORY_SEPARATOR, "path_name" => "niucloud/app/install", "name" => "安装目录" ]
- ];
- //目录 可读 可写检测
- $is_dir = true;
- foreach ($dirs_list as $k => $v) {
- @mkdir($v[ "path" ], 0755, true);
- $is_readable = is_readable($v[ "path" ]);
- $is_write = is_write($v[ "path" ]);
- $dirs_list[ $k ][ "is_readable" ] = $is_readable;
- $dirs_list[ $k ][ "is_write" ] = $is_write;
- if (!$is_readable || !$is_write) {
- $is_dir = false;
- }
- }
- $this->assign("root_path", $root_path);
- $this->assign("system_variables", $system_variables);
- $this->assign("phpv", $phpv);
- $this->assign("server", $server);
- $this->assign("host", $host);
- $this->assign("os", $os);
- $this->assign("name", $name);
- $this->assign("verison", $verison);
- $this->assign("dirs_list", $dirs_list);
- if ($verison && $pdo && $curl && $openssl && $gd && $fileinfo && $sodium && $is_dir) {
- $continue = true;
- } else {
- $continue = false;
- }
- $this->assign("continue", $continue);
- return $this->fetch('index/step-2');
- } elseif ($step == 3) {
- return $this->fetch('index/step-3');
- }
- }
- public function installSuccess()
- {
- Cache::delete('install_data');
- Cache::delete('install_status');
- return $this->fetch('index/step-4');
- }
- /**
- * 测试数据库
- */
- public function testDb()
- {
- $this->checkLock();
- $dbport = input("dbport", "");
- $dbhost = input("dbhost", "");
- $dbuser = input("dbuser", "");
- $dbpwd = input("dbpwd", "");
- $dbname = input("dbname", "");
- try {
- if ($dbport != "" && $dbhost != "") {
- $dbhost = $dbport != '3306' ? $dbhost . ':' . $dbport : $dbhost;
- }
- if ($dbhost == '' || $dbuser == '') {
- return fail([
- "status" => -1,
- "message" => "数据库账号或密码不能为空"
- ]);
- }
- if (!function_exists("mysqli_connect")) {
- return fail([
- "status" => -1,
- "message" => "mysqli扩展类必须开启"
- ]);
- }
- $conn = @mysqli_connect($dbhost, $dbuser, $dbpwd);
- if ($conn) {
- if (empty($dbname)) {
- $result = [
- "status" => 1,
- "message" => "数据库连接成功"
- ];
- } else {
- try {
- if (@mysqli_select_db($conn, $dbname)) {
- $result = [
- "status" => 2,
- "message" => "数据库存在,系统将覆盖数据库"
- ];
- } else {
- $result = [
- "status" => 1,
- "message" => "数据库不存在,系统将自动创建"
- ];
- }
- } catch ( Exception $e) {
- $result = [
- "status" => 1,
- "message" => "数据库不存在,系统将自动创建"
- ];
- return fail($result);
- }
- }
- @mysqli_close($conn);
- } else {
- $result = [
- "status" => -1,
- "message" => "数据库连接失败!"
- ];
- return fail($result);
- }
- return success($result);
- } catch ( Exception $e) {
- $result = [
- "status" => -1,
- "message" => $e->getMessage()
- ];
- return fail($result);
- }
- }
- /**
- * @param $sql_data sql文件
- * @return array
- */
- public function getSqlQuery($sql_data)
- {
- $this->checkLock();
- $sql_data = preg_replace("/TYPE=(InnoDB|MyISAM|MEMORY)( DEFAULT CHARSET=[^; ]+)?/", "ENGINE=\\1 DEFAULT CHARSET=utf8", $sql_data);
- $sql_data = str_replace("\r", "\n", $sql_data);
- $sql_query = [];
- $num = 0;
- $sql_arr = explode(";\n", trim($sql_data));
- unset($sql);
- foreach ($sql_arr as $sql) {
- $sql_query[ $num ] = '';
- $sqls = explode("\n", trim($sql));
- $sqls = array_filter($sqls);
- foreach ($sqls as $query) {
- $str1 = $query[0] ?? '';
- if ($str1 != '#' && $str1 != '-')
- $sql_query[ $num ] .= $query;
- }
- $num++;
- }
- return $sql_query;
- }
- public function install()
- {
- set_time_limit(300);
- Cache::delete('install_data');
- Cache::set('install_status', 0);//进行中
- $check = $this->testDb()->getData();
- if ($check[ 'code' ] != 1) {
- $this->setSuccessLog([ $check[ 'data' ][ 'message' ], 'error' ]);
- return fail($check[ 'data' ][ 'message' ]);
- }
- $admin_name = input('admin_name', "");
- $username = input('username', "");
- $password = input('password', "");
- $password2 = input('password2', "");
- $site_name = input('site_name', "");
- $site_username = input('site_username', "");
- $site_password = input('site_password', "");
- $site_password2 = input('site_password2', "");
- if ($admin_name == '' || $username == '' || $password == '') {
- $this->setSuccessLog([ '平台信息不能为空', 'error' ]);
- return fail('平台信息不能为空!');
- }
- if ($site_username == $username) {
- $this->setSuccessLog([ '站点管理员和平台管理员不能相同,请重新输入', 'error' ]);
- return fail('站点管理员和平台管理员不能相同,请重新输入');
- }
- if ($password != $password2) {
- $this->setSuccessLog([ '平台两次密码输入不一样,请重新输入', 'error' ]);
- return fail('平台两次密码输入不一样,请重新输入');
- }
- // if ($site_name == '' || $site_username == '' || $site_password == '') {
- // $this->setSuccessLog([ '平台信息不能为空', 'error' ]);
- // return fail('平台信息不能为空!');
- // }
- if($site_username == $username) {
- $this->setSuccessLog([ '站点账号不能跟平台账号一致', 'error' ]);
- return fail('站点账号不能跟平台账号一致!');
- }
- if ($site_password != $site_password2) {
- $this->setSuccessLog([ '站点两次密码输入不一样,请重新输入', 'error' ]);
- return fail('站点两次密码输入不一样,请重新输入');
- }
- try {
- //配置写入
- $res = $this->installConfig(input())->getData();
- if ($res[ 'code' ] != 1) {
- $this->setSuccessLog([ $res[ 'msg' ], 'error' ]);
- return fail($res[ 'msg' ]);
- }
- //数据库
- $res = $this->installSql(input())->getData();
- if ($res[ 'code' ] != 1) {
- $this->setSuccessLog([ $res[ 'msg' ], 'error' ]);
- return fail($res[ 'msg' ]);
- }
- Cache::set('install_status', 1);//成功
- return success();
- } catch ( Exception $e) {
- $this->setSuccessLog([ '安装失败' . $e->getMessage(), 'error' ]);
- return fail('安装失败' . $e->getMessage());
- }
- }
- public function initData()
- {
- $this->checkLock();
- $admin_name = input('admin_name', "");
- $username = input('username', "");
- $password = input('password', "");
- $password2 = input('password2', "");
- $site_name = input('site_name', "");
- $site_username = input('site_username', "");
- $site_password = input('site_password', "");
- $site_password2 = input('site_password2', "");
- if ($admin_name == '' || $username == '' || $password == '') {
- return fail('平台信息不能为空!');
- }
- if ($password != $password2) {
- return fail('平台两次密码输入不一样,请重新输入');
- }
- if($site_username == $username) {
- return fail('站点账号不能跟平台账号一致');
- }
- if ($site_password != $site_password2) {
- return fail('站点两次密码输入不一样,请重新输入');
- }
- try {
- //初始化数据
- $res = ( new InstallSystemService() )->install();
- if (!$res) {
- $this->setSuccessLog([ '菜单初始化失败', 'error' ]);
- return fail('菜单初始化失败');
- }
- //初始化计划任务
- $res = ( new CoreScheduleInstallService())->installSystemSchedule();
- if (!$res) {
- $this->setSuccessLog([ '计划任务初始化失败', 'error' ]);
- return fail('计划任务初始化失败');
- }
- $user = ( new SysUser() )->where([ [ 'uid', '=', 1 ] ])->findOrEmpty();
- if (!$user->isEmpty()) {
- $user->save([
- 'username' => $username,
- 'password' => create_password($password),
- ]);
- }
- ( new Site() )->where([ [ 'site_id', '=', 1 ] ])->update(['site_id' => 0]);
- $site = ( new Site() )->where([ [ 'site_id', '=', 0 ] ])->findOrEmpty();
- if (!$site->isEmpty()) {
- $site->save([
- 'site_name' => $admin_name,
- 'expire_time' => date('Y-m-d H:i:s',strtotime('+1 year'))
- ]);
- }
- //修改自增主键默认值
- // Db::execute("alter table ".env('database.prefix', '')."site auto_increment = 100000");
- // 安装插件
- $this->installAddon();
- //todo 创建店铺套餐
- $default_group_id = (new ShopSiteGroupService())->add(
- [
- 'group_name' => '店铺默认套餐',
- 'group_desc' => '',
- 'addon' => []
- ]
- );
- //todo 创建店铺分类
- $default_category_id = (new ShopCategoryService())->add(
- [
- 'category_name' => '店铺默认分类',
- ]
- );
- $shop_insert_data = [
- 'site_id' => 1,
- 'site_name' => $site_name,
- 'uid' => 1,
- 'username' => '',
- 'group_id' => $default_group_id,
- 'is_self' => 1,
- 'category_id' => $default_category_id,
- 'expire_time' => 0
- ];
- (new ShopService())->add($shop_insert_data);
- $fp = fopen($this->lock_file, 'wb');
- if (!$fp) {
- $this->setSuccessLog([ "写入失败,请检查目录" . dirname(__FILE__, 2) . "是否可写入!'", 'error' ]);
- return fail("写入失败,请检查目录" . dirname(__FILE__, 2) . "是否可写入!'");
- }
- $this->setSuccessLog([ '初始化成功', 'success' ]);
- fwrite($fp, '已安装');
- fclose($fp);
- Cache::set('install_status', 2);//成功
- // Cache::tag(MenuService::$cache_tag_name)->clear();
- return success();
- } catch ( Exception $e) {
- $this->setSuccessLog([ '安装失败' . $e->getMessage(), 'error' ]);
- return fail('安装失败' . $e->getMessage());
- }
- }
- /**
- * 安装sql
- * @param array $data
- * @return Response
- */
- public function installSql(array $data)
- {
- $this->checkLock();
- $dbport = $data[ 'dbport' ] ?? '';
- $dbhost = $data[ 'dbhost' ] ?? '';
- $dbuser = $data[ 'dbuser' ] ?? '';
- $dbpwd = $data[ 'dbpwd' ] ?? '';
- $dbname = $data[ 'dbname' ] ?? '';
- $dbprefix = $data[ 'dbprefix' ] ?? '';
- if ($dbhost == '' || $dbuser == '') {
- return fail('数据库链接配置信息丢失!');
- }
- $file_name = $this->install_root . "/source/database.sql";//数据文件
- //数据库连接测试
- $conn = @mysqli_connect($dbhost, $dbuser, $dbpwd, "", $dbport);
- if (!$conn) {
- return fail('连接数据库失败!请检查连接参数!');
- }
- //数据库可写和是否存在测试
- $empty_db = mysqli_select_db($conn, $dbname);
- if ($empty_db) {
- $sql = "DROP DATABASE `$dbname`";
- $retval = mysqli_query($conn, $sql);
- if (!$retval) {
- return fail('删除数据库失败: ' . mysqli_error($conn));
- }
- }
- //如果数据库不存在,我们就进行创建。
- $dbsql = "CREATE DATABASE `$dbname`";
- $db_create = mysqli_query($conn, $dbsql);
- if (!$db_create) {
- return fail('创建数据库失败,请确认是否有足够的权限!');
- }
- //链接数据库
- @mysqli_select_db($conn, $dbname);
- //导入SQL并执行。
- $get_sql_data = file_get_contents($file_name);
- $sql_query = $this->getSqlQuery($get_sql_data);
- @mysqli_query($conn, "SET NAMES utf8mb4");
- $query_count = count($sql_query);
- for ($i = 0; $i < $query_count; $i++) {
- $sql = trim($sql_query[ $i ]);
- $is_write = false;
- if (str_contains($sql, 'CREATE TABLE')) {
- $match_item = preg_match('/CREATE TABLE [`]?(\\w+)[`]?/is', $sql, $match_data);
- $is_write = true;
- } elseif (str_contains($sql, 'ALTER TABLE')) {
- $match_item = preg_match('/ALTER TABLE [`]?(\\w+)[`]?/is', $sql, $match_data);
- } elseif (str_contains($sql, 'INSERT INTO')) {
- $match_item = preg_match('/INSERT INTO [`]?(\\w+)[`]?/is', $sql, $match_data);
- } else {
- $match_item = 0;
- }
- if ($match_item > 0) {
- try {
- $table_name = $match_data[ 1 ];
- $new_table_name = $dbprefix . $table_name;
- $sql_item = $this->str_replace_first($table_name, $new_table_name, $sql);
- @mysqli_query($conn, $sql_item);
- if ($is_write) $this->setSuccessLog([ '创建表' . $table_name, 'success' ]);
- } catch ( Exception $e) {
- $this->setSuccessLog([ $e->getMessage(), 'error' ]);
- return fail('数据库解析失败' . $e->getMessage());
- }
- }
- }
- @mysqli_close($conn);
- return success();
- }
- /**
- * 配置设置
- * @param array $data
- * @return Response
- */
- public function installConfig(array $data)
- {
- $this->checkLock();
- $root_path = str_replace("\\", DIRECTORY_SEPARATOR, dirname(__FILE__, 4));
- $root_path = str_replace("../", DIRECTORY_SEPARATOR, $root_path);
- $env_dir = $root_path . DIRECTORY_SEPARATOR . ".env";
- $example_env = $root_path . DIRECTORY_SEPARATOR . ".example.env";
- $dbport = $data[ 'dbport' ] ?? '';
- $dbhost = $data[ 'dbhost' ] ?? '';
- $dbuser = $data[ 'dbuser' ] ?? '';
- $dbpwd = $data[ 'dbpwd' ] ?? '';
- $dbname = $data[ 'dbname' ] ?? '';
- $dbprefix = $data[ 'dbprefix' ] ?? '';
- $replace_key = [
- '{dbhost}',
- '{dbport}',
- '{dbuser}',
- '{dbpwd}',
- '{dbprefix}',
- '{dbname}',
- '{auth_key}'
- ];
- $replace_val = [
- $dbhost,
- $dbport,
- $dbuser,
- $dbpwd,
- $dbprefix,
- $dbname,
- unique_random(32)
- ];
- $content = str_replace($replace_key, $replace_val, file_get_contents($example_env));
- file_put_contents($env_dir, $content);
- $this->setSuccessLog([ '写入配置', 'success' ]);
- return success();
- }
- public function getInstallInfo()
- {
- $install_data = Cache::get('install_data') ?? [];
- $install_status = Cache::get('install_status') ?? 0;
- return success('', [
- 'log' => $install_data,
- 'status' => $install_status
- ]);
- }
- public function setSuccessLog($data)
- {
- if ($data[ 1 ] == 'error') {
- Cache::set('install_status', -1);
- }
- $time = @(int)microtime(true);
- $data[] = date('Y-m-d H:i:s', $time);
- $install_data = Cache::get('install_data') ?? [];
- $install_data[] = $data;
- Cache::set('install_data', $install_data);
- }
- /**
- * 安装插件
- * @return true
- */
- public function installAddon() {
- $root_path = str_replace("\\", DIRECTORY_SEPARATOR, dirname(__FILE__, 4));
- $root_path = str_replace("../", DIRECTORY_SEPARATOR, $root_path);
- $addon_path = $root_path . DIRECTORY_SEPARATOR . 'addon';
- $files = get_files_by_dir($addon_path);
- if (!empty($files)) {
- foreach ($files as $path) {
- $data = (new CoreAddonService())->getAddonConfig($path);
- if (isset($data['key'])) {
- $install_service = (new CoreAddonInstallService($data['key']));
- $install_service->installCheck();
- $install_service->install();
- }
- }
- }
- return true;
- }
- }
|