From 8bc581c07cbbb8153898cd4250c425532b4f88ba Mon Sep 17 00:00:00 2001 From: Karson Date: Thu, 26 Oct 2017 13:43:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=AF=BC=E5=85=A5Excel?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=20=E6=96=B0=E5=A2=9E=E5=9B=9E=E6=94=B6?= =?UTF-8?q?=E7=AB=99=E5=8A=9F=E8=83=BD=20=E6=96=B0=E5=A2=9E=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E4=BC=AA=E9=9D=99=E6=80=81=E9=85=8D=E7=BD=AE=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=89=8D=E7=AB=AF=E4=B8=8A=E4=BC=A0=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E5=9B=9E=E8=B0=83=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=A1=A8=E6=A0=BCcolumn=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E4=B8=AD=E7=9A=84width=E5=8F=82=E6=95=B0=E5=8A=9F=E8=83=BD=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=B8=8A=E4=BC=A0=E5=92=8C=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E9=99=90=E6=97=B6=E6=9C=80=E5=A4=9A=E5=8F=AF=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E3=80=81=E9=80=89=E6=8B=A9=E6=95=B0=20=E6=B7=BB=E5=8A=A0CRUD?= =?UTF-8?q?=E4=B8=ADadmin=5Fid=E4=BF=9D=E7=95=99=E5=AD=97=E6=AE=B5=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=9D=9Esummernote=E5=AF=8C=E6=96=87?= =?UTF-8?q?=E6=9C=AC=E6=8F=92=E4=BB=B6=E4=B8=8D=E6=B8=B2=E6=9F=93=E7=9A=84?= =?UTF-8?q?BUG=20=E7=A7=BB=E9=99=A4Backend.php=E4=B8=AD=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=92=8C=E4=BF=AE=E6=94=B9=E6=97=B6=E5=AF=B9=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E7=9A=84=E6=95=B0=E6=8D=AE=E8=87=AA=E5=8A=A8=E5=A4=84=E7=90=86?= =?UTF-8?q?=20=E4=BC=98=E5=8C=96=E5=88=86=E7=B1=BB=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E7=9A=84=E6=95=88=E7=8E=87=20=E4=BF=AE=E5=A4=8D=E5=90=8E?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E6=9D=83=E9=99=90=E7=AE=A1=E7=90=86=E7=BB=84?= =?UTF-8?q?=E4=B8=8D=E6=98=BE=E7=A4=BA=E7=9A=84BUG=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=9D=83=E9=99=90=E7=BA=A7=E5=92=8C=E7=AE=A1=E7=90=86=E5=91=98?= =?UTF-8?q?=E5=88=97=E8=A1=A8=EF=BC=8C=E4=BD=BF=E7=94=A8=E6=A0=91=E7=8A=B6?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=20=E4=BF=AE=E5=A4=8Dcdnurl=E4=BD=BF=E7=94=A8?= =?UTF-8?q?site.cdnurl=E7=9A=84=E9=94=99=E8=AF=AF=20=E4=BF=AE=E5=A4=8DDate?= =?UTF-8?q?::unixtime=E4=B8=AD=E8=8E=B7=E5=8F=96=E6=9C=88=E5=A4=A9?= =?UTF-8?q?=E6=95=B0=E9=94=99=E8=AF=AF=E7=9A=84BUG=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=90=8E=E5=8F=B0=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/admin/command/Crud.php | 20 +- .../command/Crud/stubs/mixins/modelinit.stub | 3 +- .../admin/command/Install/fastadmin.sql | 8 +- application/admin/common.php | 16 +- application/admin/controller/Ajax.php | 3 +- application/admin/controller/Category.php | 2 +- application/admin/controller/Index.php | 10 +- application/admin/controller/auth/Admin.php | 27 +- .../admin/controller/auth/Adminlog.php | 2 +- application/admin/controller/auth/Group.php | 38 +- .../admin/controller/general/Config.php | 48 +- application/admin/lang/zh-cn.php | 13 +- .../admin/lang/zh-cn/general/config.php | 1 + application/admin/library/traits/Backend.php | 221 ++++++- application/admin/model/AuthGroup.php | 5 + application/admin/model/AuthRule.php | 4 + .../admin/view/general/attachment/add.html | 2 +- .../admin/view/general/profile/index.html | 2 +- application/admin/view/index/login.html | 2 +- application/common.php | 102 ++- application/common/controller/Backend.php | 3 + application/common/controller/Frontend.php | 13 +- application/common/model/Config.php | 88 ++- application/config.php | 5 +- application/extra/addons.php | 3 + application/index/view/index/index.html | 3 +- application/route.php | 14 +- composer.json | 3 +- extend/fast/Date.php | 4 +- public/assets/css/backend.css | 28 +- public/assets/css/backend.min.css | 2 +- public/assets/css/fastadmin.min.css | 107 ++-- public/assets/css/frontend.min.css | 2 +- public/assets/js/backend.js | 8 +- public/assets/js/backend/general/config.js | 22 - public/assets/js/backend/index.js | 2 +- .../assets/js/bootstrap-table-commonsearch.js | 10 + public/assets/js/require-backend.min.js | 521 +++++++++++----- public/assets/js/require-form.js | 74 ++- public/assets/js/require-frontend.js | 49 +- public/assets/js/require-frontend.min.js | 49 +- public/assets/js/require-table.js | 52 +- public/assets/js/require-upload.js | 78 ++- public/assets/less/backend.less | 35 +- public/assets/less/fastadmin.less | 4 +- public/assets/less/fastadmin/dropdown.less | 583 ++++++++++-------- public/assets/less/frontend.less | 11 - 47 files changed, 1524 insertions(+), 778 deletions(-) diff --git a/application/admin/command/Crud.php b/application/admin/command/Crud.php index d53af006..dd9a25c7 100644 --- a/application/admin/command/Crud.php +++ b/application/admin/command/Crud.php @@ -85,7 +85,7 @@ class Crud extends Command /** * 保留字段 */ - protected $reservedField = ['createtime', 'updatetime']; + protected $reservedField = ['admin_id', 'createtime', 'updatetime']; /** * 排序字段 @@ -95,7 +95,7 @@ class Crud extends Command /** * 编辑器的Class */ - protected $editorClass = 'summernote'; + protected $editorClass = 'editor'; protected function configure() { @@ -478,6 +478,10 @@ class Crud extends Command $itemArr = $this->getLangArray($itemArr, FALSE); //添加一个获取器 $this->getAttr($getAttrArr, $field, $v['DATA_TYPE'] == 'set' ? 'multiple' : 'select'); + if ($v['DATA_TYPE'] == 'set') + { + $this->setAttr($setAttrArr, $field, $inputType); + } $this->appendAttr($appendAttrList, $field); $formAddElement = $this->getReplacedStub('html/select', ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => $defaultValue]); $formEditElement = $this->getReplacedStub('html/select', ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => "\$row.{$field}"]); @@ -533,6 +537,10 @@ class Crud extends Command $itemArr = $this->getLangArray($itemArr, FALSE); //添加一个获取器 $this->getAttr($getAttrArr, $field, $inputType); + if ($inputType == 'checkbox') + { + $this->setAttr($setAttrArr, $field, $inputType); + } $this->appendAttr($appendAttrList, $field); $defaultValue = $inputType == 'radio' && !$defaultValue ? key($itemArr) : $defaultValue; @@ -838,13 +846,19 @@ EOD; protected function setAttr(&$setAttr, $field, $inputType = '') { - if ($inputType != 'datetime') + if (!in_array($inputType, ['datetime', 'checkbox', 'select'])) return; $attrField = ucfirst($this->getCamelizeName($field)); if ($inputType == 'datetime') { $return = <<save(['{%order%}' => $row['id']]); + $pk = $row->getPk(); + $row->getQuery()->where($pk, $row[$pk])->update(['{%order%}' => $row[$pk]]); }); } diff --git a/application/admin/command/Install/fastadmin.sql b/application/admin/command/Install/fastadmin.sql index 954c24cb..8d169021 100755 --- a/application/admin/command/Install/fastadmin.sql +++ b/application/admin/command/Install/fastadmin.sql @@ -68,11 +68,11 @@ CREATE TABLE `fa_attachment` ( `id` int(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', `url` varchar(255) NOT NULL DEFAULT '' COMMENT '物理路径', `imagewidth` varchar(30) NOT NULL DEFAULT '' COMMENT '宽度', - `imageheight` varchar(30) NOT NULL DEFAULT '' COMMENT '宽度', + `imageheight` varchar(30) NOT NULL DEFAULT '' COMMENT '高度', `imagetype` varchar(30) NOT NULL DEFAULT '' COMMENT '图片类型', `imageframes` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '图片帧数', `filesize` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '文件大小', - `mimetype` varchar(30) NOT NULL DEFAULT '' COMMENT 'mime类型', + `mimetype` varchar(50) NOT NULL DEFAULT '' COMMENT 'mime类型', `extparam` varchar(255) NOT NULL DEFAULT '' COMMENT '透传数据', `createtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建日期', `updatetime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间', @@ -301,13 +301,13 @@ CREATE TABLE `fa_config` ( BEGIN; INSERT INTO `fa_config` VALUES (1, 'name', 'basic', 'Site name', '请填写站点名称', 'string', 'FastAdmin', '', 'required', ''); INSERT INTO `fa_config` VALUES (2, 'beian', 'basic', 'Beian', '粤ICP备15054802号-4', 'string', '', '', '', ''); -INSERT INTO `fa_config` VALUES (3, 'cdnurl', 'basic', 'Cdn url', '如果使用CDN云储存请配置该值', 'string', '', '', '', ''); +INSERT INTO `fa_config` VALUES (3, 'cdnurl', 'basic', 'Cdn url', '如果静态资源使用第三方云储存请配置该值', 'string', '', '', '', ''); INSERT INTO `fa_config` VALUES (4, 'version', 'basic', 'Version', '如果静态资源有变动请重新配置该值', 'string', '1.0.1', '', 'required', ''); INSERT INTO `fa_config` VALUES (5, 'timezone', 'basic', 'Timezone', '', 'string', 'Asia/Shanghai', '', 'required', ''); INSERT INTO `fa_config` VALUES (6, 'forbiddenip', 'basic', 'Forbidden ip', '一行一条记录', 'text', '', '', '', ''); INSERT INTO `fa_config` VALUES (7, 'languages', 'basic', 'Languages', '', 'array', '{\"backend\":\"zh-cn\",\"frontend\":\"zh-cn\"}', '', 'required', ''); INSERT INTO `fa_config` VALUES (8, 'fixedpage', 'basic', 'Fixed page', '请尽量输入左侧菜单栏存在的链接', 'string', 'dashboard', '', 'required', ''); -INSERT INTO `fa_config` VALUES (9, 'categorytype', 'dictionary', 'Cateogry type', '', 'array', '{\"default\":\"Default\",\"page\":\"Page\",\"article\":\"Article\",\"test\":\"Test\"}', '', '', ''); +INSERT INTO `fa_config` VALUES (9, 'categorytype', 'dictionary', 'Category type', '', 'array', '{\"default\":\"Default\",\"page\":\"Page\",\"article\":\"Article\",\"test\":\"Test\"}', '', '', ''); INSERT INTO `fa_config` VALUES (10, 'configgroup', 'dictionary', 'Config group', '', 'array', '{\"basic\":\"Basic\",\"email\":\"Email\",\"dictionary\":\"Dictionary\",\"user\":\"User\",\"example\":\"Example\"}', '', '', ''); INSERT INTO `fa_config` VALUES (11, 'mail_type', 'email', 'Mail type', '选择邮件发送方式', 'select', '1', '[\"Please select\",\"SMTP\",\"Mail\"]', '', ''); INSERT INTO `fa_config` VALUES (12, 'mail_smtp_host', 'email', 'Mail smtp host', '错误的配置发送邮件会导致服务器超时', 'string', 'smtp.qq.com', '', '', ''); diff --git a/application/admin/common.php b/application/admin/common.php index 250034ee..c23f2ca4 100644 --- a/application/admin/common.php +++ b/application/admin/common.php @@ -90,7 +90,7 @@ function build_toolbar($btns = NULL, $attr = []) { $auth = \app\admin\library\Auth::instance(); $controller = str_replace('.', '/', strtolower(think\Request::instance()->controller())); - $btns = $btns ? $btns : ['refresh', 'add', 'edit', 'del']; + $btns = $btns ? $btns : ['refresh', 'add', 'edit', 'del', 'import']; $btns = is_array($btns) ? $btns : explode(',', $btns); $index = array_search('delete', $btns); if ($index !== FALSE) @@ -98,10 +98,11 @@ function build_toolbar($btns = NULL, $attr = []) $btns[$index] = 'del'; } $btnAttr = [ - 'refresh' => ['javascript:;', 'btn btn-primary btn-refresh', 'fa fa-refresh', ''], - 'add' => ['javascript:;', 'btn btn-success btn-add', 'fa fa-plus', __('Add')], - 'edit' => ['javascript:;', 'btn btn-success btn-edit btn-disabled disabled', 'fa fa-pencil', __('Edit')], - 'del' => ['javascript:;', 'btn btn-danger btn-del btn-disabled disabled', 'fa fa-trash', __('Delete')], + 'refresh' => ['javascript:;', 'btn btn-primary btn-refresh', 'fa fa-refresh', '', __('Refresh')], + 'add' => ['javascript:;', 'btn btn-success btn-add', 'fa fa-plus', __('Add'), __('Add')], + 'edit' => ['javascript:;', 'btn btn-success btn-edit btn-disabled disabled', 'fa fa-pencil', __('Edit'), __('Edit')], + 'del' => ['javascript:;', 'btn btn-danger btn-del btn-disabled disabled', 'fa fa-trash', __('Delete'), __('Delete')], + 'import' => ['javascript:;', 'btn btn-danger btn-import', 'fa fa-upload', __('Import'), __('Import')], ]; $btnAttr = array_merge($btnAttr, $attr); $html = []; @@ -112,8 +113,9 @@ function build_toolbar($btns = NULL, $attr = []) { continue; } - list($href, $class, $icon, $text) = $btnAttr[$v]; - $html[] = ' ' . $text . ''; + list($href, $class, $icon, $text, $title) = $btnAttr[$v]; + $extend = $v == 'import' ? 'id="btn-import-' . \fast\Random::alpha() . '" data-url="ajax/upload" data-mimetype="csv,xsl,xslx" data-multiple="false"' : ''; + $html[] = ' ' . $text . ''; } return implode(' ', $html); } diff --git a/application/admin/controller/Ajax.php b/application/admin/controller/Ajax.php index 65dd8c45..f625b87a 100644 --- a/application/admin/controller/Ajax.php +++ b/application/admin/controller/Ajax.php @@ -107,7 +107,8 @@ class Ajax extends Backend 'sha1' => $sha1, ); $attachment = model("attachment"); - $attachment->create(array_filter($params)); + $attachment->data(array_filter($params)); + $attachment->save(); \think\Hook::listen("upload_after", $attachment); $this->success('上传成功', null, [ 'url' => $uploadDir . $splInfo->getSaveName() diff --git a/application/admin/controller/Category.php b/application/admin/controller/Category.php index 0cc95d97..e86118c4 100644 --- a/application/admin/controller/Category.php +++ b/application/admin/controller/Category.php @@ -26,7 +26,7 @@ class Category extends Backend $this->model = model('Category'); $tree = Tree::instance(); - $tree->init($this->model->order('weigh desc,id desc')->select(), 'pid'); + $tree->init(collection($this->model->order('weigh desc,id desc')->select())->toArray(), 'pid'); $this->categorylist = $tree->getTreeList($tree->getTreeArray(0), 'name'); $categorydata = [0 => ['type' => 'all', 'name' => __('None')]]; foreach ($this->categorylist as $k => $v) diff --git a/application/admin/controller/Index.php b/application/admin/controller/Index.php index b624f4ef..b00870e9 100644 --- a/application/admin/controller/Index.php +++ b/application/admin/controller/Index.php @@ -28,10 +28,10 @@ class Index extends Backend { // $menulist = $this->auth->getSidebar([ - 'dashboard' => 'hot', - 'addon' => ['new', 'red', 'badge'], - 'auth/rule' => 'side', - 'general' => ['18', 'purple'], + 'dashboard' => 'hot', + 'addon' => ['new', 'red', 'badge'], + 'auth/rule' => 'side', + 'general' => ['18', 'purple'], ], $this->view->site['fixedpage']); $this->view->assign('menulist', $menulist); $this->view->assign('title', __('Home')); @@ -87,8 +87,6 @@ class Index extends Backend { $this->redirect($url); } - $background = cdnurl("/assets/img/loginbg.jpg"); - $this->view->assign('background', $background); \think\Hook::listen("login_init", $this->request); return $this->view->fetch(); } diff --git a/application/admin/controller/auth/Admin.php b/application/admin/controller/auth/Admin.php index c89fbae8..b81c0599 100644 --- a/application/admin/controller/auth/Admin.php +++ b/application/admin/controller/auth/Admin.php @@ -27,15 +27,28 @@ class Admin extends Backend $this->model = model('Admin'); $this->childrenAdminIds = $this->auth->getChildrenAdminIds(true); - $this->childrenGroupIds = $this->auth->getChildrenGroupIds(); - - $groupName = AuthGroup::where('id', 'in', $this->childrenGroupIds) - ->column('id,name'); - foreach ($groupName as $k => &$v) + $this->childrenGroupIds = $this->auth->getChildrenGroupIds($this->auth->isSuperAdmin() ? true : false); + + $groupList = collection(AuthGroup::where('id', 'in', $this->childrenGroupIds)->select())->toArray(); + $groupIds = $this->auth->getGroupIds(); + Tree::instance()->init($groupList); + $result = []; + if ($this->auth->isSuperAdmin()) { - $v = __($v); + $result = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0)); + } + else + { + foreach ($groupIds as $m => $n) + { + $result = array_merge($result, Tree::instance()->getTreeList(Tree::instance()->getTreeArray($n))); + } + } + $groupName = []; + foreach ($result as $k => $v) + { + $groupName[$v['id']] = $v['name']; } - unset($v); $this->view->assign('groupdata', $groupName); $this->assignconfig("admin", ['id' => $this->auth->id]); diff --git a/application/admin/controller/auth/Adminlog.php b/application/admin/controller/auth/Adminlog.php index cb743b65..f54c9c7d 100644 --- a/application/admin/controller/auth/Adminlog.php +++ b/application/admin/controller/auth/Adminlog.php @@ -24,7 +24,7 @@ class Adminlog extends Backend $this->model = model('AdminLog'); $this->childrenAdminIds = $this->auth->getChildrenAdminIds(true); - $this->childrenGroupIds = $this->auth->getChildrenGroupIds(); + $this->childrenGroupIds = $this->auth->getChildrenGroupIds($this->auth->isSuperAdmin() ? true : false); $groupName = AuthGroup::where('id', 'in', $this->childrenGroupIds) ->column('id,name'); diff --git a/application/admin/controller/auth/Group.php b/application/admin/controller/auth/Group.php index 5a19be43..2b63a02c 100644 --- a/application/admin/controller/auth/Group.php +++ b/application/admin/controller/auth/Group.php @@ -30,13 +30,26 @@ class Group extends Backend $this->childrenGroupIds = $this->auth->getChildrenGroupIds(true); - $groupName = AuthGroup::where('id', 'in', $this->childrenGroupIds) - ->column('id,name'); - foreach ($groupName as $k => &$v) + $groupList = collection(AuthGroup::where('id', 'in', $this->childrenGroupIds)->select())->toArray(); + $groupIds = $this->auth->getGroupIds(); + Tree::instance()->init($groupList); + $result = []; + if ($this->auth->isSuperAdmin()) { - $v = __($v); + $result = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0)); + } + else + { + foreach ($groupIds as $m => $n) + { + $result = array_merge($result, Tree::instance()->getTreeList(Tree::instance()->getTreeArray($n))); + } + } + $groupName = []; + foreach ($result as $k => $v) + { + $groupName[$v['id']] = $v['name']; } - unset($v); $this->groupdata = $groupName; $this->assignconfig("admin", ['id' => $this->auth->id, 'group_ids' => $this->auth->getGroupIds()]); @@ -51,12 +64,21 @@ class Group extends Backend { if ($this->request->isAjax()) { + $list = AuthGroup::all(array_keys($this->groupdata)); + $list = collection($list)->toArray(); + $groupList = []; + foreach ($list as $k => $v) + { + $groupList[$v['id']] = $v; + } $list = []; foreach ($this->groupdata as $k => $v) { - $data = $this->model->get($k); - $data->name = $v; - $list[] = $data; + if (isset($groupList[$k])) + { + $groupList[$k]['name'] = $v; + $list[] = $groupList[$k]; + } } $total = count($list); $result = array("total" => $total, "rows" => $list); diff --git a/application/admin/controller/general/Config.php b/application/admin/controller/general/Config.php index e19ad988..6761d3e4 100644 --- a/application/admin/controller/general/Config.php +++ b/application/admin/controller/general/Config.php @@ -82,19 +82,9 @@ class Config extends Backend } try { - if ($params['content'] && in_array($params['type'], ['select', 'selects', 'checkbox', 'radio'])) + if (in_array($params['type'], ['select', 'selects', 'checkbox', 'radio', 'array'])) { - $content = explode("\r\n", $params['content']); - $arr = []; - foreach ($content as $k => &$v) - { - if (stripos($v, "|") !== false) - { - $item = explode('|', $v); - $arr[$item[0]] = $item[1]; - } - } - $params['content'] = $arr ? json_encode($arr, JSON_UNESCAPED_UNICODE) : ''; + $params['content'] = ConfigModel::decode($params['content']); } else { @@ -132,40 +122,28 @@ class Config extends Backend { if ($this->request->isPost()) { - $params = $this->request->post("row/a"); - if ($params) + $row = $this->request->post("row/a"); + if ($row) { $configList = []; - foreach ($this->model->all() as $k => $v) + foreach ($this->model->all() as $v) { - if (isset($params[$v['name']])) + if (isset($row[$v['name']])) { - if ($v['type'] == 'array') + $value = $row[$v['name']]; + if (is_array($value) && isset($value['field'])) { - $fieldarr = $valuearr = []; - $field = $params[$v['name']]['field']; - $value = $params[$v['name']]['value']; - - foreach ($field as $m => $n) - { - if ($n != '') - { - $fieldarr[] = $field[$m]; - $valuearr[] = $value[$m]; - } - } - $params[$v['name']] = array_combine($fieldarr, $valuearr); - $value = json_encode($params[$v['name']], JSON_UNESCAPED_UNICODE); + $value = json_encode(\app\common\model\Config::getArrayData($value), JSON_UNESCAPED_UNICODE); } else { - $value = is_array($params[$v['name']]) ? implode(',', $params[$v['name']]) : $params[$v['name']]; + $value = is_array($value) ? implode(',', $value) : $value; } - - $configList[] = ['id' => $v['id'], 'value' => $value]; + $v['value'] = $value; + $configList[] = $v; } } - $this->model->saveAll($configList); + $this->model->allowField(true)->saveAll($configList); try { $this->refreshFile(); diff --git a/application/admin/lang/zh-cn.php b/application/admin/lang/zh-cn.php index 111ffedc..a959c1d7 100644 --- a/application/admin/lang/zh-cn.php +++ b/application/admin/lang/zh-cn.php @@ -16,6 +16,7 @@ return [ 'Edit' => '编辑', 'Del' => '删除', 'Delete' => '删除', + 'Import' => '导入', 'Detail' => '详情', 'Multi' => '批量更新', 'Setting' => '配置', @@ -116,6 +117,8 @@ return [ 'Network error' => '网络错误!', 'Invalid parameters' => '未知参数', 'No results were found' => '记录未找到', + 'No rows were deleted' => '未删除任何行', + 'No rows were updated' => '未更新任何行', 'Parameter %s can not be empty' => '参数%s不能为空', 'Are you sure you want to delete the %s selected item?' => '确定删除选中的 %s 项?', 'Are you sure you want to delete this item?' => '确定删除此项?', @@ -124,6 +127,8 @@ return [ 'Please enter your username' => '请输入你的用户名', 'Please enter your password' => '请输入你的密码', 'Please login first' => '请登录后操作', + 'You can upload up to %d file%s' => '你最多还可以上传%d个文件', + 'You can choose up to %d file%s' => '你最多还可以选择%d个文件', 'An unexpected error occurred' => '发生了一个意外错误,程序猿正在紧急处理中', 'This page will be re-directed in %s seconds' => '页面将在 %s 秒后自动跳转', //菜单 @@ -152,9 +157,9 @@ return [ 'Config tips' => '可以在此增改系统的变量和分组,也可以自定义分组和变量,如果需要删除请从数据库中删除', 'Category tips' => '用于统一管理网站的所有分类,分类可进行无限级分类', 'Attachment tips' => '主要用于管理上传到服务器或第三方存储的数据', - 'Addon tips' => '可在线安装、卸载、禁用、启用插件,同时支持Add本地插件。FastAdmin已上线插件商店 ,你可以发布你的免费或付费插件:http://www.fastadmin.net/store.html', + 'Addon tips' => '可在线安装、卸载、禁用、启用插件,同时支持添加本地插件。FastAdmin已上线插件商店 ,你可以发布你的免费或付费插件:http://www.fastadmin.net/store.html', 'Admin tips' => '一个管理员可以有多个角色组,左侧的菜单根据管理员所拥有的权限进行生成', - 'Admin log tips' => '管理员可以View自己所拥有的权限的管理员日志', - 'Group tips' => '角色组可以有多个,角色有上下级层级关系,如果子角色有角色组和管理员的权限则可以派生属于自己组别下级的角色组或管理员', - 'Rule tips' => '规则通常对应一个控制器的方法,同时左侧的菜单栏数据也从规则中体现,通常建议通过控制台进行生成规则节点', + 'Admin log tips' => '管理员可以查看自己所拥有的权限的管理员日志', + 'Group tips' => '角色组可以有多个,角色有上下级层级关系,如果子角色有角色组和管理员的权限则可以派生属于自己组别的下级角色组或管理员', + 'Rule tips' => '规则通常对应一个控制器的方法,同时左侧的菜单栏数据也从规则中体现,通常建议通过命令行进行生成规则节点', ]; diff --git a/application/admin/lang/zh-cn/general/config.php b/application/admin/lang/zh-cn/general/config.php index 89877983..8754c1e4 100644 --- a/application/admin/lang/zh-cn/general/config.php +++ b/application/admin/lang/zh-cn/general/config.php @@ -16,6 +16,7 @@ return [ 'Extend' => '扩展属性', 'String' => '字符', 'Text' => '文本', + 'Editor' => '编辑器', 'Number' => '数字', 'Date' => '日期', 'Time' => '时间', diff --git a/application/admin/library/traits/Backend.php b/application/admin/library/traits/Backend.php index dce1c9fb..4ecc9e34 100644 --- a/application/admin/library/traits/Backend.php +++ b/application/admin/library/traits/Backend.php @@ -38,6 +38,36 @@ trait Backend return $this->view->fetch(); } + /** + * 回收站 + */ + public function recyclebin() + { + //设置过滤方法 + $this->request->filter(['strip_tags']); + if ($this->request->isAjax()) + { + list($where, $sort, $order, $offset, $limit) = $this->buildparams(); + $total = $this->model + ->onlyTrashed() + ->where($where) + ->order($sort, $order) + ->count(); + + $list = $this->model + ->onlyTrashed() + ->where($where) + ->order($sort, $order) + ->limit($offset, $limit) + ->select(); + + $result = array("total" => $total, "rows" => $list); + + return json($result); + } + return $this->view->fetch(); + } + /** * 添加 */ @@ -48,10 +78,13 @@ trait Backend $params = $this->request->post("row/a"); if ($params) { - foreach ($params as $k => &$v) - { - $v = is_array($v) ? implode(',', $v) : $v; - } + /* + * 已经弃用,如果为了兼容老版可取消注释 + foreach ($params as $k => &$v) + { + $v = is_array($v) ? implode(',', $v) : $v; + } + */ if ($this->dataLimit) { $params[$this->dataLimitField] = $this->auth->id; @@ -65,7 +98,7 @@ trait Backend $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : true) : $this->modelValidate; $this->model->validate($validate); } - $result = $this->model->save($params); + $result = $this->model->allowField(true)->save($params); if ($result !== false) { $this->success(); @@ -106,10 +139,13 @@ trait Backend $params = $this->request->post("row/a"); if ($params) { - foreach ($params as $k => &$v) - { - $v = is_array($v) ? implode(',', $v) : $v; - } + /* + * 已经弃用,如果为了兼容老版可取消注释 + foreach ($params as $k => &$v) + { + $v = is_array($v) ? implode(',', $v) : $v; + } + */ try { //是否采用模型验证 @@ -119,7 +155,7 @@ trait Backend $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : true) : $this->modelValidate; $row->validate($validate); } - $result = $row->save($params); + $result = $row->allowField(true)->save($params); if ($result !== false) { $this->success(); @@ -129,7 +165,7 @@ trait Backend $this->error($row->getError()); } } - catch (think\exception\PDOException $e) + catch (\think\exception\PDOException $e) { $this->error($e->getMessage()); } @@ -147,23 +183,85 @@ trait Backend { if ($ids) { + $pk = $this->model->getPk(); $adminIds = $this->getDataLimitAdminIds(); if (is_array($adminIds)) { - $count = $this->model->where($this->dataLimitField, 'in', $adminIds)->delete($ids); + $count = $this->model->where($this->dataLimitField, 'in', $adminIds); } - else + $list = $this->model->where($pk, 'in', $ids)->select(); + $count = 0; + foreach ($list as $k => $v) { - $count = $this->model->destroy($ids); + $count += $v->delete(); } if ($count) { $this->success(); } + else + { + $this->error(__('No rows were deleted')); + } } $this->error(__('Parameter %s can not be empty', 'ids')); } + /** + * 真实删除 + */ + public function destroy($ids = "") + { + $pk = $this->model->getPk(); + $adminIds = $this->getDataLimitAdminIds(); + if (is_array($adminIds)) + { + $count = $this->model->where($this->dataLimitField, 'in', $adminIds); + } + if ($ids) + { + $this->model->where($pk, 'in', $ids); + } + $count = 0; + $list = $this->model->onlyTrashed()->select(); + foreach ($list as $k => $v) + { + $count += $v->delete(true); + } + if ($count) + { + $this->success(); + } + else + { + $this->error(__('No rows were deleted')); + } + $this->error(__('Parameter %s can not be empty', 'ids')); + } + + /** + * 还原 + */ + public function restore($ids = "") + { + $pk = $this->model->getPk(); + $adminIds = $this->getDataLimitAdminIds(); + if (is_array($adminIds)) + { + $this->model->where($this->dataLimitField, 'in', $adminIds); + } + if ($ids) + { + $this->model->where($pk, 'in', $ids); + } + $count = $this->model->restore('1=1'); + if ($count) + { + $this->success(); + } + $this->error(__('No rows were updated')); + } + /** * 批量更新 */ @@ -188,6 +286,10 @@ trait Backend { $this->success(); } + else + { + $this->error(__('No rows were updated')); + } } else { @@ -198,4 +300,95 @@ trait Backend $this->error(__('Parameter %s can not be empty', 'ids')); } + /** + * 导入 + */ + protected function import() + { + $file = $this->request->request('file'); + if (!$file) + { + $this->error(__('Parameter %s can not be empty', 'file')); + } + $filePath = ROOT_PATH . DS . 'public' . DS . $file; + if (!is_file($filePath)) + { + $this->error(__('No results were found')); + } + $PHPReader = new \PHPExcel_Reader_Excel2007(); + if (!$PHPReader->canRead($filePath)) + { + $PHPReader = new \PHPExcel_Reader_Excel5(); + if (!$PHPReader->canRead($filePath)) + { + $PHPReader = new \PHPExcel_Reader_CSV(); + if (!$PHPReader->canRead($filePath)) + { + $this->error(__('Unknown data format')); + } + } + } + + $table = $this->model->getQuery()->getTable(); + $database = \think\Config::get('database.database'); + $fieldArr = []; + $list = db()->query("SELECT COLUMN_NAME,COLUMN_COMMENT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ? AND TABLE_SCHEMA = ?", [$table, $database]); + foreach ($list as $k => $v) + { + $fieldArr[$v['COLUMN_COMMENT']] = $v['COLUMN_NAME']; + } + + $PHPExcel = $PHPReader->load($filePath); //加载文件 + $currentSheet = $PHPExcel->getSheet(0); //读取文件中的第一个工作表 + $allColumn = $currentSheet->getHighestColumn(); //取得最大的列号 + $allRow = $currentSheet->getHighestRow(); //取得一共有多少行 + + for ($currentRow = 1; $currentRow <= 1; $currentRow++) + { + for ($currentColumn = 'A'; $currentColumn <= $allColumn; $currentColumn++) + { + $val = $currentSheet->getCellByColumnAndRow(ord($currentColumn) - 65, $currentRow)->getValue(); + $fields[] = $val; + } + } + $insert = []; + for ($currentRow = 2; $currentRow <= $allRow; $currentRow++) + { + $values = []; + for ($currentColumn = 'A'; $currentColumn <= $allColumn; $currentColumn++) + { + $val = $currentSheet->getCellByColumnAndRow(ord($currentColumn) - 65, $currentRow)->getValue(); /* * ord()将字符转为十进制数 */ + $values[] = is_null($val) ? '' : $val; + //echo iconv('utf-8','gb2312', $val)."\t"; + } + $row = []; + $temp = array_combine($fields, $values); + foreach ($temp as $k => $v) + { + if (isset($fieldArr[$k]) && $k !== '') + { + $row[$fieldArr[$k]] = $v; + } + } + if ($row) + { + $insert[] = $row; + } + } + if (!$insert) + { + $this->error(__('No rows were updated')); + } + try + { + $this->model->saveAll($insert); + } + catch (\think\exception\PDOException $exception) + { + $this->error($exception->getMessage()); + } + + $this->success(); + } + } diff --git a/application/admin/model/AuthGroup.php b/application/admin/model/AuthGroup.php index 214a6985..72ed7a1a 100644 --- a/application/admin/model/AuthGroup.php +++ b/application/admin/model/AuthGroup.php @@ -13,4 +13,9 @@ class AuthGroup extends Model protected $createTime = 'createtime'; protected $updateTime = 'updatetime'; + public function getNameAttr($value, $data) + { + return __($value); + } + } diff --git a/application/admin/model/AuthRule.php b/application/admin/model/AuthRule.php index ad2da0ab..1ca6fcfb 100644 --- a/application/admin/model/AuthRule.php +++ b/application/admin/model/AuthRule.php @@ -13,4 +13,8 @@ class AuthRule extends Model protected $createTime = 'createtime'; protected $updateTime = 'updatetime'; + public function getTitleAttr($value, $data) + { + return __($value); + } } diff --git a/application/admin/view/general/attachment/add.html b/application/admin/view/general/attachment/add.html index 4d2b7b1b..a927d382 100644 --- a/application/admin/view/general/attachment/add.html +++ b/application/admin/view/general/attachment/add.html @@ -10,7 +10,7 @@
- +
{/if} diff --git a/application/admin/view/general/profile/index.html b/application/admin/view/general/profile/index.html index d08071ab..0991a80c 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/admin/view/index/login.html b/application/admin/view/index/login.html index d0f2cc69..08650440 100644 --- a/application/admin/view/index/login.html +++ b/application/admin/view/index/login.html @@ -6,7 +6,7 @@