From f572e345d507910f251a0806e4794e48bea46fd0 Mon Sep 17 00:00:00 2001 From: Karson Date: Thu, 22 Feb 2018 20:30:36 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=8F=92=E4=BB=B6=E7=9A=84?= =?UTF-8?q?=E5=A4=9A=E8=AF=AD=E8=A8=80=E5=8C=85=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E9=99=84=E4=BB=B6=E5=88=A0=E9=99=A4=E7=9A=84=E8=A1=8C=E4=B8=BA?= =?UTF-8?q?=20=E6=96=B0=E5=A2=9E=E5=91=BD=E4=BB=A4=E8=A1=8C=E5=AE=89?= =?UTF-8?q?=E8=A3=85=E6=97=B6=E7=9A=84=E5=8F=82=E6=95=B0=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=20=E6=96=B0=E5=A2=9E=E4=B8=80=E9=94=AE=E7=94=9F=E6=88=90?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E6=97=B6=E5=BF=BD=E7=95=A5=E6=9C=AA=E5=90=AF?= =?UTF-8?q?=E7=94=A8=E8=BD=AF=E5=88=A0=E9=99=A4=E7=9A=84=E6=96=B9=E6=B3=95?= =?UTF-8?q?=20=E4=BF=AE=E5=A4=8D=E5=9C=A8iOS=E4=B8=8B=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E4=B8=AD=E5=88=97=E5=AD=97=E6=AE=B5=E8=BF=87=E5=A4=9A=E6=9C=AA?= =?UTF-8?q?=E5=90=AF=E7=94=A8=E5=8D=A1=E7=89=87=E8=A7=86=E5=9B=BE=E7=9A=84?= =?UTF-8?q?BUG=20=E4=BF=AE=E5=A4=8D=E4=BC=9A=E5=91=98=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E4=B8=AD=E8=A7=84=E5=88=99=E7=AE=A1=E7=90=86=E5=88=86=E9=A1=B5?= =?UTF-8?q?=E7=9A=84BUG=20=E4=BF=AE=E5=A4=8D=E5=AF=BC=E8=88=AA=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E9=9A=90=E8=97=8F=E5=90=8E=E4=BB=8D=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E7=9A=84BUG=20=E4=BC=98=E5=8C=96=E6=95=B0=E6=8D=AE=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E5=9C=A8=E7=A7=BB=E5=8A=A8=E7=AB=AF=E7=9A=84=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=20=E4=BC=98=E5=8C=96=E5=BC=82=E5=B8=B8=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E7=9A=84=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .travis.yml | 42 -------------- .../admin/command/Addon/stubs/addon.stub | 18 ++++++ .../admin/command/Crud/stubs/controller.stub | 7 +-- application/admin/command/Install.php | 39 +++++++++++-- application/admin/command/Menu.php | 20 ++++++- application/admin/controller/Index.php | 1 + .../admin/controller/general/Attachment.php | 20 +++++-- application/admin/lang/zh-cn.php | 1 + application/admin/lang/zh-cn/category.php | 1 + application/admin/library/Auth.php | 2 +- .../admin/view/general/profile/index.html | 2 +- application/common/behavior/Common.php | 12 +++- application/common/lang/zh-cn/addon.php | 9 +++ application/common/library/Menu.php | 56 +++++++++++++++++-- .../common/view/tpl/think_exception.tpl | 11 +++- application/config.php | 2 +- application/tags.php | 4 +- public/assets/js/backend/addon.js | 2 + public/assets/js/backend/user/rule.js | 5 +- .../assets/js/bootstrap-table-commonsearch.js | 8 ++- public/assets/js/require-backend.min.js | 18 ++++-- public/assets/js/require-table.js | 10 +++- 22 files changed, 207 insertions(+), 83 deletions(-) delete mode 100755 .travis.yml create mode 100644 application/common/lang/zh-cn/addon.php diff --git a/.travis.yml b/.travis.yml deleted file mode 100755 index 36f7b6f9..00000000 --- a/.travis.yml +++ /dev/null @@ -1,42 +0,0 @@ -sudo: false - -language: php - -branches: - only: - - stable - -cache: - directories: - - $HOME/.composer/cache - -before_install: - - composer self-update - -install: - - composer install --no-dev --no-interaction --ignore-platform-reqs - - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip . - - composer require --update-no-dev --no-interaction "topthink/think-image:^1.0" - - composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0" - - composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0" - - composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0" - - composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0" - - composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0" - - composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0" - - composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0" - - composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0" - - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip . - -script: - - php think unit - -deploy: - provider: releases - api_key: - secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw= - file: - - ThinkPHP_Core.zip - - ThinkPHP_Full.zip - skip_cleanup: true - on: - tags: true diff --git a/application/admin/command/Addon/stubs/addon.stub b/application/admin/command/Addon/stubs/addon.stub index 22567a43..eb5e4b0c 100644 --- a/application/admin/command/Addon/stubs/addon.stub +++ b/application/admin/command/Addon/stubs/addon.stub @@ -28,6 +28,24 @@ class {%addonClassName%} extends Addons return true; } + /** + * 插件启用方法 + * @return bool + */ + public function enable() + { + return true; + } + + /** + * 插件禁用方法 + * @return bool + */ + public function disable() + { + return true; + } + /** * 实现钩子方法 * @return mixed diff --git a/application/admin/command/Crud/stubs/controller.stub b/application/admin/command/Crud/stubs/controller.stub index 8953c2be..4c1b888a 100644 --- a/application/admin/command/Crud/stubs/controller.stub +++ b/application/admin/command/Crud/stubs/controller.stub @@ -4,9 +4,6 @@ namespace {%controllerNamespace%}; use app\common\controller\Backend; -use think\Controller; -use think\Request; - /** * {%tableComment%} * @@ -28,8 +25,8 @@ class {%controllerName%} extends Backend } /** - * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个方法 - * 因此在当前控制器中可不用编写增删改查的代码,如果需要自己控制这部分逻辑 + * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法 + * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑 * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改 */ diff --git a/application/admin/command/Install.php b/application/admin/command/Install.php index de1f6fc0..4fd17c0e 100644 --- a/application/admin/command/Install.php +++ b/application/admin/command/Install.php @@ -18,17 +18,29 @@ class Install extends Command protected function configure() { + $config = Config::get('database'); $this ->setName('install') + ->addOption('hostname', 'a', Option::VALUE_OPTIONAL, 'mysql hostname', $config['hostname']) + ->addOption('hostport', 'o', Option::VALUE_OPTIONAL, 'mysql hostport', $config['hostport']) + ->addOption('database', 'd', Option::VALUE_OPTIONAL, 'mysql database', $config['database']) + ->addOption('prefix', 'r', Option::VALUE_OPTIONAL, 'table prefix', $config['prefix']) + ->addOption('username', 'u', Option::VALUE_OPTIONAL, 'mysql username', $config['username']) + ->addOption('password', 'p', Option::VALUE_OPTIONAL, 'mysql password', $config['password']) ->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override', FALSE) ->setDescription('New installation of FastAdmin'); } protected function execute(Input $input, Output $output) { - - //覆盖安装 + // 覆盖安装 $force = $input->getOption('force'); + $hostname = $input->getOption('hostname'); + $hostport = $input->getOption('hostport'); + $database = $input->getOption('database'); + $prefix = $input->getOption('prefix'); + $username = $input->getOption('username'); + $password = $input->getOption('password'); $installLockFile = __DIR__ . "/Install/install.lock"; if (is_file($installLockFile) && !$force) @@ -38,11 +50,13 @@ class Install extends Command $sql = file_get_contents(__DIR__ . '/Install/fastadmin.sql'); + $sql = str_replace("`fa_", "`{$prefix}", $sql); + // 先尝试能否自动创建数据库 $config = Config::get('database'); - $pdo = new PDO("{$config['type']}:host={$config['hostname']}" . ($config['hostport'] ? ";port={$config['hostport']}" : ''), $config['username'], $config['password']); + $pdo = new PDO("{$config['type']}:host={$hostname}" . ($hostport ? ";port={$hostport}" : ''), $username, $password); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - $pdo->query("CREATE DATABASE IF NOT EXISTS `{$config['database']}` CHARACTER SET utf8 COLLATE utf8_general_ci;"); + $pdo->query("CREATE DATABASE IF NOT EXISTS `{$database}` CHARACTER SET utf8 COLLATE utf8_general_ci;"); // 查询一次SQL,判断连接是否正常 Db::execute("SELECT 1"); @@ -51,7 +65,22 @@ class Install extends Command Db::getPdo()->exec($sql); file_put_contents($installLockFile, 1); - + + $dbConfigFile = APP_PATH . 'database.php'; + $config = @file_get_contents($dbConfigFile); + $callback = function($matches) use($hostname, $hostport, $username, $password, $database, $prefix) { + $field = $matches[1]; + $replace = $$field; + if ($matches[1] == 'hostport' && $hostport == 3306) + { + $replace = ''; + } + return "'{$matches[1]}'{$matches[2]}=>{$matches[3]}Env::get('database.{$matches[1]}', '{$replace}'),"; + }; + $config = preg_replace_callback("/'(hostname|database|username|password|hostport|prefix)'(\s+)=>(\s+)Env::get\((.*)\)\,/", $callback, $config); + // 写入数据库配置 + file_put_contents($dbConfigFile, $config); + $output->info("Install Successed!"); } diff --git a/application/admin/command/Menu.php b/application/admin/command/Menu.php index 10264b48..834f31ba 100755 --- a/application/admin/command/Menu.php +++ b/application/admin/command/Menu.php @@ -187,6 +187,19 @@ class Menu extends Command //只匹配公共的方法 $methods = $reflector->getMethods(ReflectionMethod::IS_PUBLIC); $classComment = $reflector->getDocComment(); + //判断是否有启用软删除 + $softDeleteMethods = ['destroy', 'restore', 'recyclebin']; + $withSofeDelete = false; + preg_match_all("/\\\$this\->model\s*=\s*model\('(\w+)'\);/", $classContent, $matches); + if (isset($matches[1]) && isset($matches[1][0]) && $matches[1][0]) + { + \think\Request::instance()->module('admin'); + $model = model($matches[1][0]); + if (in_array('trashed', get_class_methods($model))) + { + $withSofeDelete = true; + } + } //忽略的类 if (stripos($classComment, "@internal") !== FALSE) { @@ -216,7 +229,7 @@ class Menu extends Command //导入中文语言包 \think\Lang::load(dirname(__DIR__) . DS . 'lang/zh-cn.php'); - //先定入菜单的数据 + //先导入菜单的数据 $pid = 0; foreach ($controllerArr as $k => $v) { @@ -248,6 +261,11 @@ class Menu extends Command { continue; } + //未启用软删除时过滤相关方法 + if (!$withSofeDelete && in_array($n->name, $softDeleteMethods)) + { + continue; + } //只匹配符合的方法 if (!preg_match('/^(\w+)' . Config::get('action_suffix') . '/', $n->name, $matchtwo)) { diff --git a/application/admin/controller/Index.php b/application/admin/controller/Index.php index ed262a7d..d5630408 100644 --- a/application/admin/controller/Index.php +++ b/application/admin/controller/Index.php @@ -97,6 +97,7 @@ class Index extends Backend } $background = cdnurl(Config::get('fastadmin.login_background')); $this->view->assign('background', $background); + $this->view->assign('title', __('Login')); Hook::listen("login_init", $this->request); return $this->view->fetch(); } diff --git a/application/admin/controller/general/Attachment.php b/application/admin/controller/general/Attachment.php index 02b0ce46..4ef2c48c 100644 --- a/application/admin/controller/general/Attachment.php +++ b/application/admin/controller/general/Attachment.php @@ -78,16 +78,28 @@ class Attachment extends Backend return $this->view->fetch(); } + /** + * 删除附件 + * @param array $ids + */ public function del($ids = "") { if ($ids) { - $count = $this->model->destroy($ids); - if ($count) + \think\Hook::add('upload_delete', function($params) { + $attachmentFile = ROOT_PATH . '/public' . $params['url']; + if (is_file($attachmentFile)) + { + @unlink($attachmentFile); + } + }); + $attachmentlist = $this->model->where('id', 'in', $ids)->select(); + foreach ($attachmentlist as $attachment) { - \think\Hook::listen("upload_after", $this); - $this->success(); + \think\Hook::listen("upload_delete", $attachment); + $attachment->delete(); } + $this->success(); } $this->error(__('Parameter %s can not be empty', 'ids')); } diff --git a/application/admin/lang/zh-cn.php b/application/admin/lang/zh-cn.php index d01376e4..20a154e2 100644 --- a/application/admin/lang/zh-cn.php +++ b/application/admin/lang/zh-cn.php @@ -97,6 +97,7 @@ return [ 'Create time' => '创建时间', 'Update time' => '更新时间', 'Flag' => '标志', + 'Drag to sort' => '拖动进行排序', 'Redirect now' => '立即跳转', 'Common search' => '普通搜索', 'Search %s' => '搜索 %s', diff --git a/application/admin/lang/zh-cn/category.php b/application/admin/lang/zh-cn/category.php index e7607480..8ded1a77 100644 --- a/application/admin/lang/zh-cn/category.php +++ b/application/admin/lang/zh-cn/category.php @@ -4,6 +4,7 @@ return [ 'Id' => 'ID', 'Pid' => '父ID', 'Type' => '栏目类型', + 'All' => '全部', 'Image' => '图片', 'Keywords' => '关键字', 'Description' => '描述', diff --git a/application/admin/library/Auth.php b/application/admin/library/Auth.php index 7ff03d94..ba230413 100644 --- a/application/admin/library/Auth.php +++ b/application/admin/library/Auth.php @@ -403,7 +403,7 @@ class Auth extends \fast\Auth $select_id = 0; $pinyin = new \Overtrue\Pinyin\Pinyin('Overtrue\Pinyin\MemoryFileDictLoader'); // 必须将结果集转换为数组 - $ruleList = collection(model('AuthRule')->where('ismenu', 1)->order('weigh', 'desc')->cache("__menu__")->select())->toArray(); + $ruleList = collection(model('AuthRule')->where('status', 'normal')->where('ismenu', 1)->order('weigh', 'desc')->cache("__menu__")->select())->toArray(); foreach ($ruleList as $k => &$v) { if (!in_array($v['name'], $userRule)) diff --git a/application/admin/view/general/profile/index.html b/application/admin/view/general/profile/index.html index f211abc8..c433f052 100644 --- a/application/admin/view/general/profile/index.html +++ b/application/admin/view/general/profile/index.html @@ -41,7 +41,7 @@
- +
{:__('Click to edit')}
diff --git a/application/common/behavior/Common.php b/application/common/behavior/Common.php index d63f4c20..a90cf969 100644 --- a/application/common/behavior/Common.php +++ b/application/common/behavior/Common.php @@ -3,11 +3,12 @@ namespace app\common\behavior; use think\Config; +use think\Lang; class Common { - public function run(&$request) + public function moduleInit(&$request) { // 设置mbstring字符编码 mb_internal_encoding("UTF-8"); @@ -53,4 +54,13 @@ class Common } } + public function addonBegin(&$request) + { + // 加载插件语言包 + Lang::load([ + APP_PATH . 'common' . DS . 'lang' . DS . $request->langset() . DS . 'addon' . EXT, + ]); + $this->moduleInit($request); + } + } diff --git a/application/common/lang/zh-cn/addon.php b/application/common/lang/zh-cn/addon.php new file mode 100644 index 00000000..c7cebef8 --- /dev/null +++ b/application/common/lang/zh-cn/addon.php @@ -0,0 +1,9 @@ + '插件未找到', + 'addon %s is disabled' => '插件已禁用', + 'addon controller %s not found' => '插件控制器未找到', + 'addon action %s not found' => '插件控制器方法未找到', + 'addon can not be empty' => '插件不能为空', +]; diff --git a/application/common/library/Menu.php b/application/common/library/Menu.php index f36d45b9..9d0ad843 100644 --- a/application/common/library/Menu.php +++ b/application/common/library/Menu.php @@ -59,6 +59,55 @@ class Menu */ public static function delete($name) { + $ids = self::getAuthRuleIdsByName($name); + if (!$ids) + { + return false; + } + AuthRule::destroy($ids); + return true; + } + + /** + * 启用菜单 + * @param string $name + * @return boolean + */ + public static function enable($name) + { + $ids = self::getAuthRuleIdsByName($name); + if (!$ids) + { + return false; + } + AuthRule::where('id', 'in', $ids)->update(['status' => 'normal']); + return true; + } + + /** + * 禁用菜单 + * @param string $name + * @return boolean + */ + public static function disable($name) + { + $ids = self::getAuthRuleIdsByName($name); + if (!$ids) + { + return false; + } + AuthRule::where('id', 'in', $ids)->update(['status' => 'hidden']); + return true; + } + + /** + * 根据名称获取规则IDS + * @param string $name + * @return array + */ + public static function getAuthRuleIdsByName($name) + { + $ids = []; $menu = AuthRule::getByName($name); if ($menu) { @@ -66,13 +115,8 @@ class Menu $ruleList = collection(model('AuthRule')->order('weigh', 'desc')->field('id,pid,name')->select())->toArray(); // 构造菜单数据 $ids = Tree::instance()->init($ruleList)->getChildrenIds($menu['id'], true); - if ($ids) - { - AuthRule::destroy($ids); - } - return true; } - return false; + return $ids; } } diff --git a/application/common/view/tpl/think_exception.tpl b/application/common/view/tpl/think_exception.tpl index 31102517..2ca62577 100644 --- a/application/common/view/tpl/think_exception.tpl +++ b/application/common/view/tpl/think_exception.tpl @@ -1,3 +1,7 @@ + @@ -5,6 +9,7 @@ 发生错误 +