diff --git a/.env.example b/.env.example index 917da860..f25e8903 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,12 @@ [app] debug = false trace = false + +[database] +hostname = {hostname} +database = {database} +username = {username} +password = {password} +hostport = {hostport} +charset = utf8mb4 +prefix = lsky_ diff --git a/README.md b/README.md index e5605f34..e03ccddb 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@

-# Lsky Pro - Your photo album on the cloud. +

Lsky Pro - Your photo album on the cloud.

[官网](https://www.lsky.pro)   [手册](https://www.kancloud.cn/wispx/lsky-pro)   @@ -22,21 +22,20 @@ ![homepage.png](./public/static/app/images/demo/1.png) ![homepage.png](./public/static/app/images/demo/2.png) -主要特性 ---- -- 支持第三方云储存,支持本地、阿里云 OSS、腾讯云 COS、七牛云、又拍云、FTP。 -- 支持多图上传、拖拽上传、粘贴上传、上传预览、全屏预览、页面响应式布局。 -- 简洁的图片管理功能,支持鼠标右键、单选多选、重命名等操作。 -- 强大的图片预览功能,支持响应式。 -- 支持全局配置用户初始剩余储存空间、支持单个设置用户剩余储存空间。 -- 支持一键复制图片外链、二维码扫描链接。 -- 支持设置上传文件、文件夹路径命名规则。 -- 支持图片鉴黄功能。 -- 支持文件夹分类功能。 -- 对外开放的上传接口。 +### 📌 TODO +* [x] 支持第三方云储存,支持本地、阿里云 OSS、腾讯云 COS、七牛云、又拍云、FTP。 +* [x] 支持多图上传、拖拽上传、粘贴上传、上传预览、全屏预览、页面响应式布局。 +* [x] 简洁的图片管理功能,支持鼠标右键、单选多选、重命名等操作。 +* [x] 强大的图片预览功能,支持响应式。 +* [x] 支持全局配置用户初始剩余储存空间、支持单个设置用户剩余储存空间。 +* [x] 支持一键复制图片外链、二维码扫描链接。 +* [x] 支持设置上传文件、文件夹路径命名规则。 +* [x] 支持在线平滑升级系统 +* [x] 支持图片鉴黄功能。 +* [x] 支持文件夹分类功能。 +* [x] 对外开放的上传接口。 -安装需求 ---- +### 🛠 安装要求 * PHP 版本 ≥ 5.6(≤ 7.3) * mysql 版本 ≥ 5.5 * mysqli 支持 @@ -47,8 +46,7 @@ 注:如果使用 FTP 功能,需要开启 PHP 的 FTP 拓展 -安装教程 ---- +### 🔍 安装教程 1. 下载兰空,上传至 web 运行环境,解压。 2. 设置运行目录为 public。 3. 配置 Rewrite 规则: @@ -67,60 +65,23 @@ 4. 访问首页,未安装自动跳转至安装页面,根据页面提示安装即可。 5. 安装完成以后请设置 runtime 目录 0755 权限,如果你使用本地存储,public 目录也需要设置为0755权限 -如何更新到最新版? ---- -升级过程并不复杂,但也简单粗暴,总共分为四个步骤。 -1. [下载](https://github.com/wisp-x/lsky-pro/releases)最新版程序并解压到本地。 -2. 将旧版程序 ```config/db.php``` 文件复制到新版程序的 ```config``` 文件夹,如果你使用的是本地储存策略,文件是储存在本地的,请注意也要将你旧版本的图片资源移动到新程序对应的目录。 -3. 删除旧版本程序所有文件,上传最新版程序到站点根目录即可(这一步也可以直接覆盖,但会有残留文件,不选择覆盖的话建议先打包备份旧版本)。 -4. 使用管理员账号登录,访问任意页面会跳转到升级数据库结构页面,根据提示操作即可。 - -FAQ: -- 如果你开启了 ThinkPHP 系统的 debug,请先关闭,否则无法自动跳转至更新数据库结构页面。 -- 如果覆盖更新文件后无法重定向到更新页面,或首页出现错误,请直接访问 ```http://域名/install/update.html``` 进行更新。 - -如何修改网站运行目录? ---- -默认程序的入口文件在 ```public``` 目录下,所以需要把 public 目录设置为网站运行目录,这样做是为了: -> 入口文件位置的设计是为了让应用部署更安全,```public``` 目录为web可访问目录,其他的文件都可以放到非WEB访问目录下面。 - -而你如果安装时没有设置,使用 ```http://域名/public``` 的方式来访问站点,会导致 css 和 js 等静态资源无法获取。 -如果你 无法 或 不会 设置运行目录,可以将 public 目录下的所有文件和文件夹(包括 .htaccess 文件)移动到根目录 -(和 ```application``` 文件夹同级)即可,尽管我们不推荐你这么做,这样会导致应用程序核心文件暴露在外。 - -移动文件以后,打开根目录 ```index.php``` 文件,修改如下: -```php -bind('index')->run()->send(); - ``` - -注意:请不要使用记事本打开修改,修改完成后保存即可。 - -联系我 ---- -- QQ:1591788658 +### 📧 联系我 - Email: i@wispx.cn -- Blog:[https://www.wispx.cn](https://www.wispx.cn) -捐赠 ---- -Lsky Pro 的开发和更新等,都是作者在空余时间独立开发,并免费开源使用,如果您认可我的作品,并且觉得对你有所帮助我们愿意接受来自各方面的捐赠😃。 -![支付宝](./public/static/app/images/demo/alipay.png?t=201911251121) -![微信](./public/static/app/images/demo/wechat.jpeg?t=201911251121) -左图支付宝,右图微信 +### 💰 捐赠 +Lsky Pro 的开发和更新等,都是作者在空余时间独立开发,并免费开源使用,如果您认可我的作品,并且觉得对你有所帮助我愿意接受来自各方面的捐赠😃。 + + + + + + + + + +
支付宝微信
-鸣谢 ---- +### ♥ 鸣谢 - ThinkPHP - Jquery - BootStrap @@ -128,8 +89,7 @@ Lsky Pro 的开发和更新等,都是作者在空余时间独立开发,并 - viewer.js - context.js -开源许可 ---- +### 📃 开源许可 [GPL 3.0](https://opensource.org/licenses/GPL-3.0) Copyright (c) 2018-present Lsky Pro. diff --git a/application/http/middleware/WebAuth.php b/application/http/middleware/Auth.php similarity index 98% rename from application/http/middleware/WebAuth.php rename to application/http/middleware/Auth.php index 2a9b23c2..44fe13fc 100644 --- a/application/http/middleware/WebAuth.php +++ b/application/http/middleware/Auth.php @@ -4,7 +4,7 @@ namespace app\http\middleware; use think\facade\Session; -class WebAuth +class Auth { /** * 无需登录可访问的方法(除分层控制器) diff --git a/application/http/middleware/Init.php b/application/http/middleware/Init.php new file mode 100644 index 00000000..e4631414 --- /dev/null +++ b/application/http/middleware/Init.php @@ -0,0 +1,20 @@ +getAppPath() . 'install.lock')) { + if ($request->controller(true) !== 'install' || $request->action(true) !== 'index') { + return redirect(url('install/index')); + } + } + + return $next($request); + } +} diff --git a/application/index/controller/Base.php b/application/index/controller/Base.php index 0830a5f2..a0aec741 100644 --- a/application/index/controller/Base.php +++ b/application/index/controller/Base.php @@ -19,7 +19,7 @@ use think\facade\Env; class Base extends Controller { - protected $middleware = ['WebAuth']; + protected $middleware = ['Auth']; protected $user = null; @@ -40,11 +40,6 @@ class Base extends Controller { parent::initialize(); - // 检测程序是否已安装 - if (!file_exists(Env::get('config_path') . 'db.php')) { - if (!\config('app.app_debug')) $this->redirect(url('/install')); - } - $configs = \app\common\model\Config::all(); foreach ($configs as $key => &$value) { $this->config[$value->name] = $value->value; @@ -58,13 +53,6 @@ class Base extends Controller } } - // 检测数据库结构更新 - if ($user && $user->is_admin) { - if (file_exists(Env::get('root_path') . 'update.sql') && !\config('app.app_debug')) { - $this->redirect(url('/install/update')); - } - } - $this->init($user); $this->assign([ diff --git a/application/index/controller/Install.php b/application/index/controller/Install.php index 518da1c9..a1fd0f0b 100644 --- a/application/index/controller/Install.php +++ b/application/index/controller/Install.php @@ -8,24 +8,18 @@ namespace app\index\controller; -use app\common\model\Users; use think\Controller; use think\Db; use think\Exception; -use think\facade\Config; -use think\facade\Env; use think\facade\Session; class Install extends Controller { public function index($step = 1) { - $rootPath = Env::get('root_path'); - $configPath = Env::get('config_path'); - // 检测是否已安装 - if (file_exists($configPath . 'db.php') && !Session::has('install_success')) { - exit('你已安装成功,请勿重复安装!'); + if (file_exists(app()->getAppPath() . 'install.lock') && !Session::has('install_success')) { + exit('你已安装成功,需要重新安装请删除 install.lock 文件'); } $phpVerGt56 = PHP_VERSION >= 5.6; @@ -45,7 +39,7 @@ class Install extends Controller 'isMysqli' => $isMysqli, 'isZip' => $isZip, 'testing' => $testing, - 'dir' => is_writable(Env::get('runtime_path')) && is_writable($configPath), + 'dir' => is_writable(app()->getRuntimePath()) && is_writable(app()->getConfigPath()), ]); break; case 2: @@ -57,27 +51,42 @@ class Install extends Controller $password = $this->request->post('password'); $hostport = $this->request->post('hostport'); try { - if (!$sqlFile = @file_get_contents($rootPath . 'install.sql')) { - throw new Exception('安装文件不存在'); + $installSql = app()->getAppPath() . 'sql/install.sql'; + if (!is_file($installSql)) { + throw new Exception('数据库 SQL 文件不存在'); } - $mysqli = new \mysqli($hostname, $username, $password, $database, $hostport); - if ($mysqli->connect_error) { - $mysqli->close(); - throw new Exception($mysqli->connect_error); - } - $mysqli->query("SET NAMES utf8"); - if (!$mysqli->multi_query($sqlFile)) { - throw new Exception('数据写入失败'); + $db = Db::connect(array_merge(\config('database.'), [ + 'hostname' => $hostname, + 'database' => $database, + 'username' => $username, + 'password' => $password, + 'hostport' => $hostport, + ])); + + $lines = file($installSql); + $temp = ''; + foreach ($lines as &$line) { + $line = trim($line); + if (substr($line, 0, 2) == '--' || $line == '' || substr($line, 0, 2) == '/*') continue; + $temp .= $line; + if (substr($line, -1, 1) == ';') { + $db->execute($temp); + $temp = ''; + } } + Session::set('db', [ 'hostname' => $hostname, 'database' => $database, 'username' => $username, 'password' => $password, 'hostport' => $hostport, + 'prefix' => 'lsky_' ]); } catch (Exception $e) { $this->error($e->getMessage()); + } catch (\PDOException $e) { + $this->error($e->getMessage()); } $this->success('数据写入成功'); } @@ -98,64 +107,37 @@ class Install extends Controller $data['password'] = md5($data['password']); $data['reg_ip'] = request()->ip(); $data['token'] = make_token(); - $dbConfig = Session::get('db'); - $hostname = $dbConfig['hostname']; - $database = $dbConfig['database']; - $username = $dbConfig['username']; - $password = $dbConfig['password']; - $hostport = $dbConfig['hostport']; - $dbPath = $configPath . 'db.php'; - $str = << '$hostname', - // 数据库名 - 'database' => '$database', - // 用户名 - 'username' => '$username', - // 密码 - 'password' => '$password', - // 端口 - 'hostport' => '$hostport', -]; -EOT; - if (file_exists($dbPath)) { - @file_put_contents($dbPath, $str); - } else { - $fp = fopen($dbPath, "w+"); - fwrite($fp, $str); - fclose($fp); + $config = Session::get('db'); + + // 写入 env 文件 + $env = str_ireplace([ + '{hostname}', + '{database}', + '{username}', + '{password}', + '{hostport}', + ], $config, @file_get_contents(app()->getRootPath() . '.env.example')); + if (!@file_put_contents(app()->getRootPath() . '.env', $env)) { + throw new \Exception('配置文件写入失败'); } - $db = Db::connect(array_merge($dbConfig, [ - // 数据库类型 - 'type' => 'mysql', - // 数据库连接参数 - 'params' => [], - // 数据库编码默认采用utf8 - 'charset' => 'utf8mb4', - // 数据库表前缀 - 'prefix' => 'lsky_', - ])); + + $db = Db::connect(array_merge(\config('database.'), $config)); unset($data['password_confirm']); $db->name('users')->insert($data); + + // 创建安装锁文件 + if (!@fopen(app()->getAppPath() . 'install.lock', 'w')) { + throw new \Exception('安装锁文件创建失败'); + } } catch (Exception $e) { - @unlink($configPath . 'db.php'); + @unlink(app()->getAppPath() . 'install.lock'); + $this->error($e->getMessage()); + } catch (\PDOException $e) { + @unlink(app()->getAppPath() . 'install.lock'); $this->error($e->getMessage()); } Session::flash('install_success', true); - // 删除sql文件 - @unlink($rootPath . 'install.sql'); - if (file_exists($rootPath . 'update.sql')) { - @unlink($rootPath . 'update.sql'); - } // 删除session Session::delete('db'); $this->success('设置成功'); diff --git a/application/index/controller/admin/System.php b/application/index/controller/admin/System.php index 368566d8..1a4a689c 100644 --- a/application/index/controller/admin/System.php +++ b/application/index/controller/admin/System.php @@ -108,11 +108,35 @@ class System extends Base $dir = $upgrade->unzip($file, $upgrade->getWorkspace()); // 解压安装包到工作区目录 $path = rtrim($dir . $release->path, '/') . '/'; // 新版本程序根目录 - $sqlPath = $path . $release->sql; // sql 文件路径 - if (!$sql = @file_get_contents($sqlPath)) { + $updateSql = $path . $release->sql; // 更新数据库结构 sql 文件路径 + if (!$sql = @file_get_contents($updateSql)) { throw new \Exception('SQL 文件获取失败'); } + // 复制 env 文件 + $config = \config('database.'); + $env = str_ireplace([ + '{hostname}', + '{database}', + '{username}', + '{password}', + '{hostport}', + ], [ + $config['hostname'], + $config['database'], + $config['username'], + $config['password'], + $config['hostport'], + ], @file_get_contents($path . '.env.example')); + if (!@file_put_contents($path . '.env', $env)) { + throw new \Exception('配置文件写入失败'); + } + + // 创建安装锁文件 + if (!@fopen($path . 'application/install.lock', 'w')) { + throw new \Exception('安装锁文件创建失败'); + } + // 检测新增表字段 if (!$tableFields = @include($path . 'config/table.php')) { throw new \Exception('表字段配置文件获取失败'); @@ -153,10 +177,6 @@ class System extends Base } } - // 删除安装包 sql 文件 - @unlink($sqlPath); - @unlink($path . 'install.sql'); - // 复制文件夹 $upgrade->copyDirs($path, $upgrade->getRootPath()); diff --git a/application/index/view/install/index.html b/application/index/view/install/index.html index e12054c8..1709628d 100644 --- a/application/index/view/install/index.html +++ b/application/index/view/install/index.html @@ -86,18 +86,6 @@ {/if} - - - ZipArchive: - - - {if ($isMysqli) } - - {else/} - - {/if} - - ZipArchive: diff --git a/application/install.lock b/application/install.lock new file mode 100644 index 00000000..e69de29b diff --git a/application/middleware.php b/application/middleware.php new file mode 100644 index 00000000..be3b34ef --- /dev/null +++ b/application/middleware.php @@ -0,0 +1,17 @@ + +// +---------------------------------------------------------------------- + +// +---------------------------------------------------------------------- +// | 中间件配置 +// +---------------------------------------------------------------------- +return [ + app\http\middleware\Init::class, +]; diff --git a/install.sql b/application/sql/install.sql similarity index 100% rename from install.sql rename to application/sql/install.sql diff --git a/update.sql b/application/sql/update.sql similarity index 100% rename from update.sql rename to application/sql/update.sql diff --git a/config/database.php b/config/database.php index d83ee93e..a51a6e44 100644 --- a/config/database.php +++ b/config/database.php @@ -9,29 +9,29 @@ // | Author: liu21st // +---------------------------------------------------------------------- -$database = [ +return [ // 数据库类型 'type' => 'mysql', // 数据库连接DSN配置 'dsn' => '', // 服务器地址 - 'hostname' => '127.0.0.1', + 'hostname' => env('database.hostname', '127.0.0.1'), // 数据库名 - 'database' => '', + 'database' => env('database.database', 'lsky'), // 数据库用户名 - 'username' => 'root', + 'username' => env('database.username', 'root'), // 数据库密码 - 'password' => '', + 'password' => env('database.password', ''), // 数据库连接端口 - 'hostport' => '', + 'hostport' => env('database.hostport', '3306'), // 数据库连接参数 'params' => [], // 数据库编码默认采用utf8 - 'charset' => 'utf8mb4', + 'charset' => env('database.charset', 'utf8mb4'), // 数据库表前缀 - 'prefix' => 'lsky_', + 'prefix' => env('database.prefix'), // 数据库调试模式 - 'debug' => true, + 'debug' => false, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) 'deploy' => 0, // 数据库读写是否分离 主从式有效 @@ -61,10 +61,3 @@ $database = [ // 断线标识字符串 'break_match_str' => [], ]; - -$pathname = Env::get('config_path') . 'db.php'; -if (file_exists($pathname)) { - return array_merge($database, require $pathname); -} else { - return $database; -} diff --git a/config/middleware.php b/config/middleware.php index 0ac680c0..91dc6f52 100644 --- a/config/middleware.php +++ b/config/middleware.php @@ -13,5 +13,6 @@ // | 中间件配置 // +---------------------------------------------------------------------- return [ - 'WebAuth' => app\http\middleware\WebAuth::class + 'Init' => app\http\middleware\Init::class, + 'Auth' => app\http\middleware\Auth::class ];