diff --git a/README.md b/README.md index e20ce74600d2b0b4ec95bac6db5fd75c0a6841b2..90e0ea86dd5d0fc81c2991245a466b4112b1a008 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -FastAdmin是一款基于ThinkPHP5+Bootstrap的极速后台开发框架。 +FastAdmin是一款基于ThinkPHP+Bootstrap的极速后台开发框架。 ## 主要特性 diff --git a/application/admin/command/Api/library/Extractor.php b/application/admin/command/Api/library/Extractor.php index 401153657efd42fbb605ee7210595db778455568..fdd52de18734d88309db2f8e9f1c864cd8dbe2f3 100644 --- a/application/admin/command/Api/library/Extractor.php +++ b/application/admin/command/Api/library/Extractor.php @@ -297,7 +297,7 @@ class Extractor } } $methodAnnotations['ApiPermissionLogin'] = [!in_array('*', $noNeedLogin) && !in_array($methodName, $noNeedLogin)]; - $methodAnnotations['ApiPermissionRight'] = !$methodAnnotations['ApiPermissionLogin'][0] ? false : [!in_array('*', $noNeedRight) && !in_array($methodName, $noNeedRight)]; + $methodAnnotations['ApiPermissionRight'] = !$methodAnnotations['ApiPermissionLogin'][0] ? [false] : [!in_array('*', $noNeedRight) && !in_array($methodName, $noNeedRight)]; return $methodAnnotations; } diff --git a/application/admin/command/Crud.php b/application/admin/command/Crud.php index 927625b7768c15f457ad8c07cea4e62365390143..ec84b5ecc2826a69d94136ad89694dcf0c88243f 100755 --- a/application/admin/command/Crud.php +++ b/application/admin/command/Crud.php @@ -21,6 +21,16 @@ class Crud extends Command protected $internalKeywords = [ 'abstract', 'and', 'array', 'as', 'break', 'callable', 'case', 'catch', 'class', 'clone', 'const', 'continue', 'declare', 'default', 'die', 'do', 'echo', 'else', 'elseif', 'empty', 'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile', 'eval', 'exit', 'extends', 'final', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'namespace', 'new', 'or', 'print', 'private', 'protected', 'public', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor' ]; + + /** + * 受保护的系统表, crud不会生效 + */ + protected $systemTables = [ + 'admin', 'admin_log', 'auth_group', 'auth_group_access', 'auth_rule', + 'attachment', 'config', 'category', 'ems', 'sms', + 'user', 'user_group', 'user_rule', 'user_score_log', 'user_token', + ]; + /** * Selectpage搜索字段关联 */ @@ -204,9 +214,12 @@ class Crud extends Command $force = $input->getOption('force'); //是否为本地model,为0时表示为全局model将会把model放在app/common/model中 $local = $input->getOption('local'); + if (!$table) { throw new Exception('table name can\'t empty'); } + + //是否生成菜单 $menu = $input->getOption("menu"); //关联表 @@ -298,6 +311,11 @@ class Crud extends Command $dbname = Config::get($db . '.database'); $prefix = Config::get($db . '.prefix'); + //系统表无法生成,防止后台错乱 + if(in_array(str_replace($prefix,"",$table),$this->systemTables)){ + throw new Exception('system table can\'t be crud'); + } + //模块 $moduleName = 'admin'; $modelModuleName = $local ? $moduleName : 'common'; diff --git a/application/admin/command/Install/fastadmin.sql b/application/admin/command/Install/fastadmin.sql index 8df72f5f35bcf1baed936af02bf223a56917d87e..9fa3529ed7b3a8171cc6e28231ec772c72781b9e 100755 --- a/application/admin/command/Install/fastadmin.sql +++ b/application/admin/command/Install/fastadmin.sql @@ -80,6 +80,7 @@ CREATE TABLE `fa_area` ( DROP TABLE IF EXISTS `fa_attachment`; CREATE TABLE `fa_attachment` ( `id` int(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', + `category` varchar(50) DEFAULT '' COMMENT '类别', `admin_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '管理员ID', `user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '会员ID', `url` varchar(255) DEFAULT '' COMMENT '物理路径', @@ -103,7 +104,7 @@ CREATE TABLE `fa_attachment` ( -- Records of fa_attachment -- ---------------------------- BEGIN; -INSERT INTO `fa_attachment` VALUES (1, 1, 0, '/assets/img/qrcode.png', '150', '150', 'png', 0, 'qrcode.png', 21859, 'image/png', '', 1491635035, 1491635035, 1491635035, 'local', '17163603d0263e4838b9387ff2cd4877e8b018f6'); +INSERT INTO `fa_attachment` VALUES (1, '', 1, 0, '/assets/img/qrcode.png', '150', '150', 'png', 0, 'qrcode.png', 21859, 'image/png', '', 1491635035, 1491635035, 1491635035, 'local', '17163603d0263e4838b9387ff2cd4877e8b018f6'); COMMIT; -- ---------------------------- @@ -350,6 +351,7 @@ INSERT INTO `fa_config` VALUES (14, 'mail_smtp_user', 'email', 'Mail smtp user', INSERT INTO `fa_config` VALUES (15, 'mail_smtp_pass', 'email', 'Mail smtp password', '(填写您的密码或授权码)', 'string', 'password', '', '', '', ''); INSERT INTO `fa_config` VALUES (16, 'mail_verify_type', 'email', 'Mail vertify type', '(SMTP验证方式[推荐SSL])', 'select', '2', '[\"无\",\"TLS\",\"SSL\"]', '', '', ''); INSERT INTO `fa_config` VALUES (17, 'mail_from', 'email', 'Mail from', '', 'string', '10000@qq.com', '', '', '', ''); +INSERT INTO `fa_config` VALUES (18, 'attachmentcategory', 'dictionary', 'Attachment category', '', 'array', '{\"category1\":\"Category1\",\"category2\":\"Category2\",\"custom\":\"Custom\"}', '', '', '', ''); COMMIT; -- ---------------------------- diff --git a/application/admin/controller/Ajax.php b/application/admin/controller/Ajax.php index a1cc8a7169b0bb124b175562a2a3b453e9fcd633..bd0b5d005f6ebd13deb0e9bf8fa9e7bcaefd0b7f 100644 --- a/application/admin/controller/Ajax.php +++ b/application/admin/controller/Ajax.php @@ -158,7 +158,7 @@ class Ajax extends Backend $weighdata[$v[$prikey]] = $v[$field]; } $position = array_search($changeid, $ids); - $desc_id = $sour[$position]; //移动到目标的ID值,取出所处改变前位置的值 + $desc_id = isset($sour[$position]) ? $sour[$position] : end($sour); //移动到目标的ID值,取出所处改变前位置的值 $sour_id = $changeid; $weighids = array(); $temp = array_values(array_diff_assoc($ids, $sour)); diff --git a/application/admin/controller/general/Attachment.php b/application/admin/controller/general/Attachment.php index d73c25ceff590d390c6b725d1ce69f5db44a727d..2963a0993ddfd3af59d724ace2e69f83dcdd7740 100644 --- a/application/admin/controller/general/Attachment.php +++ b/application/admin/controller/general/Attachment.php @@ -8,7 +8,7 @@ use app\common\controller\Backend; * 附件管理 * * @icon fa fa-circle-o - * @remark 主要用于管理上传到又拍云的数据或上传至本服务的上传数据 + * @remark 主要用于管理上传到服务器或第三方存储的数据 */ class Attachment extends Backend { @@ -18,11 +18,16 @@ class Attachment extends Backend */ protected $model = null; + protected $searchFields = 'id,filename,url'; + protected $noNeedRight = ['classify']; + public function _initialize() { parent::_initialize(); $this->model = model('Attachment'); $this->view->assign("mimetypeList", \app\common\model\Attachment::getMimetypeList()); + $this->view->assign("categoryList", \app\common\model\Attachment::getCategoryList()); + $this->assignconfig("categoryList", \app\common\model\Attachment::getCategoryList()); } /** @@ -36,10 +41,15 @@ class Attachment extends Backend $mimetypeQuery = []; $filter = $this->request->request('filter'); $filterArr = (array)json_decode($filter, true); + if (isset($filterArr['category']) && $filterArr['category'] == 'unclassed') { + $filterArr['category'] = ''; + $this->request->get(['filter' => json_encode(array_diff_key($filterArr, ['category' => '']))]); + } if (isset($filterArr['mimetype']) && preg_match("/[]\,|\*]/", $filterArr['mimetype'])) { - $this->request->get(['filter' => json_encode(array_diff_key($filterArr, ['mimetype' => '']))]); - $mimetypeQuery = function ($query) use ($filterArr) { - $mimetypeArr = explode(',', $filterArr['mimetype']); + $mimetype = $filterArr['mimetype']; + $filterArr = array_diff_key($filterArr, ['mimetype' => '']); + $mimetypeQuery = function ($query) use ($mimetype) { + $mimetypeArr = explode(',', $mimetype); foreach ($mimetypeArr as $index => $item) { if (stripos($item, "/*") !== false) { $query->whereOr('mimetype', 'like', str_replace("/*", "/", $item) . '%'); @@ -49,6 +59,7 @@ class Attachment extends Backend } }; } + $this->request->get(['filter' => json_encode($filterArr)]); list($where, $sort, $order, $offset, $limit) = $this->buildparams(); @@ -121,4 +132,29 @@ class Attachment extends Backend $this->error(__('Parameter %s can not be empty', 'ids')); } + /** + * 归类 + */ + public function classify() + { + if (!$this->auth->check('general/attachment/edit')) { + \think\Hook::listen('admin_nopermission', $this); + $this->error(__('You have no permission'), ''); + } + if (!$this->request->isPost()) { + $this->error(__("Invalid parameters")); + } + $category = $this->request->post('category', ''); + $ids = $this->request->post('ids'); + if (!$ids) { + $this->error(__('Parameter %s can not be empty', 'ids')); + } + $categoryList = \app\common\model\Attachment::getCategoryList(); + if ($category && !isset($categoryList[$category])) { + $this->error(__('Category not found')); + } + \app\common\model\Attachment::where('id', 'in', $ids)->update(['category' => $category]); + $this->success(); + } + } diff --git a/application/admin/controller/general/Config.php b/application/admin/controller/general/Config.php index f4b93e2a1719d0cbfdf749049ba211f3cd33fda8..bab69e8412de09b871955e2e52ea4b42e46196de 100644 --- a/application/admin/controller/general/Config.php +++ b/application/admin/controller/general/Config.php @@ -60,6 +60,14 @@ class Config extends Backend $value['value'] = explode(',', $value['value']); } $value['content'] = json_decode($value['content'], true); + if (in_array($value['name'], ['categorytype', 'configgroup', 'attachmentcategory'])) { + $dictValue = (array)json_decode($value['value'], true); + foreach ($dictValue as $index => &$item) { + $item = __($item); + } + unset($item); + $value['value'] = json_encode($dictValue, JSON_UNESCAPED_UNICODE); + } $value['tip'] = htmlspecialchars($value['tip']); $siteList[$v['group']]['list'][] = $value; } diff --git a/application/admin/lang/zh-cn/general/attachment.php b/application/admin/lang/zh-cn/general/attachment.php index 90fe66d72bdfe3e7f3438f3d69d3ca177b2d79da..afcf06f3871920baf37e1054e773e7477fbedb63 100644 --- a/application/admin/lang/zh-cn/general/attachment.php +++ b/application/admin/lang/zh-cn/general/attachment.php @@ -23,9 +23,18 @@ return [ 'Createtime' => '创建日期', 'Uploadtime' => '上传时间', 'Storage' => '存储引擎', + 'Category1' => '分类一', + 'Category2' => '分类二', + 'Custom' => '自定义', + 'Unclassed' => '未归类', + 'Category' => '类别', + 'Classify' => '归类', 'Upload to third' => '上传到第三方', 'Upload to local' => '上传到本地', 'Upload to third by chunk' => '上传到第三方(分片模式)', 'Upload to local by chunk' => '上传到本地(分片模式)', + 'Please enter a new name' => '请输入新的类别名称', + 'Please select category' => '请选择一个类别', + 'Category not found' => '指定的类别未找到', 'Upload from editor' => '从编辑器上传' ]; diff --git a/application/admin/lang/zh-cn/general/config.php b/application/admin/lang/zh-cn/general/config.php index 021384f3b6603d890bda3f0242c4eecf4d7da1f1..6a2b95d6a6e53e2ad27bfdb536ec091a3b0176aa 100644 --- a/application/admin/lang/zh-cn/general/config.php +++ b/application/admin/lang/zh-cn/general/config.php @@ -57,6 +57,9 @@ return [ 'Fixed page' => '后台固定页', 'Category type' => '分类类型', 'Config group' => '配置分组', + 'Attachment category' => '附件类别', + 'Category1' => '分类一', + 'Category2' => '分类二', 'Rule tips' => '校验规则使用请参考Nice-validator文档', 'Extend tips' => '扩展属性支持{id}、{name}、{group}、{title}、{value}、{content}、{rule}替换', 'Mail type' => '邮件发送方式', diff --git a/application/admin/library/Auth.php b/application/admin/library/Auth.php index 5e265f5cc14ba296a80c75055045006e3f355b52..64bf1eece057ad01900caec9c27075848c9c8037 100644 --- a/application/admin/library/Auth.php +++ b/application/admin/library/Auth.php @@ -473,7 +473,7 @@ class Auth extends \fast\Auth foreach ($topList as $index => $item) { $childList = Tree::instance()->getTreeMenu( $item['id'], - '
  • @title @caret @badge @childlist
  • ', + '
  • @title @caret @badge @childlist
  • ', $select_id, '', 'ul', @@ -495,7 +495,7 @@ class Auth extends \fast\Auth Tree::instance()->init($ruleList); $menu = Tree::instance()->getTreeMenu( 0, - '
  • @title @caret @badge @childlist
  • ', + '
  • @title @caret @badge @childlist
  • ', $select_id, '', 'ul', diff --git a/application/admin/model/AuthRule.php b/application/admin/model/AuthRule.php index 236cb638302d808e98f5ae613a53ad76ab89c337..526b6b59178aecfd6f48abd74c5f166487872100 100644 --- a/application/admin/model/AuthRule.php +++ b/application/admin/model/AuthRule.php @@ -16,6 +16,12 @@ class AuthRule extends Model protected static function init() { + self::beforeWrite(function ($row) { + if (isset($_POST['row']) && is_array($_POST['row']) && isset($_POST['row']['condition'])) { + $originRow = $_POST['row']; + $row['condition'] = $originRow['condition'] ?? ''; + } + }); self::afterWrite(function ($row) { Cache::rm('__menu__'); }); diff --git a/application/admin/validate/User.php b/application/admin/validate/User.php index ab0622055382f8be139babe25489ee3604b32919..252f4cf5c3053554907b8def64b06bb8a9a6aae9 100644 --- a/application/admin/validate/User.php +++ b/application/admin/validate/User.php @@ -32,7 +32,7 @@ class User extends Validate */ protected $scene = [ 'add' => [], - 'edit' => ['username', 'email', 'nickname', 'password', 'email', 'mobile'], + 'edit' => ['username', 'nickname', 'password', 'email', 'mobile'], ]; public function __construct(array $rules = [], $message = [], $field = []) diff --git a/application/admin/view/general/attachment/edit.html b/application/admin/view/general/attachment/edit.html index 8caa393eca063809295c8f46b944e22475f19c9b..85898b57303b3e06c655cf922caeaf2259734fbb 100644 --- a/application/admin/view/general/attachment/edit.html +++ b/application/admin/view/general/attachment/edit.html @@ -1,5 +1,18 @@ + +
    +
    + +
    + +
    +
    diff --git a/application/admin/view/general/attachment/index.html b/application/admin/view/general/attachment/index.html index 53cb2b8f599e2e35365a0d29e675760d4cc450ad..7272d758123546547c4a1235fa754a8802d70cbd 100644 --- a/application/admin/view/general/attachment/index.html +++ b/application/admin/view/general/attachment/index.html @@ -2,9 +2,9 @@
    {:build_heading(null,FALSE)} -