作者 Karson

修复分类管理和规则管理父级调整的BUG

修复管理员日志数据过长的BUG
... ... @@ -4,13 +4,10 @@ namespace app\admin\behavior;
class AdminLog
{
public function run(&$params)
{
if (request()->isPost())
{
if (request()->isPost()) {
\app\admin\model\AdminLog::record();
}
}
}
... ...
... ... @@ -35,16 +35,18 @@
{
name: 'Restore',
text: __('Restore'),
classname: 'btn btn-xs btn-info btn-restoreit',
classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
icon: 'fa fa-rotate-left',
url: '{%controllerUrl%}/restore'
url: '{%controllerUrl%}/restore',
refresh: true
},
{
name: 'Destroy',
text: __('Destroy'),
classname: 'btn btn-xs btn-danger btn-destroyit',
classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
icon: 'fa fa-times',
url: '{%controllerUrl%}/destroy'
url: '{%controllerUrl%}/destroy',
refresh: true
}
],
formatter: Table.api.formatter.operate
... ...
... ... @@ -130,14 +130,14 @@ if (!function_exists('build_toolbar')) {
$template = str_replace('/', '_', $controller);
$download = '';
if (file_exists("./template/{$template}.xlsx")) {
$download .= "\n <li><a href=\"/template/{$template}.xlsx\" target=\"_blank\">XLSX模版</a></li>";
$download .= "<li><a href=\"/template/{$template}.xlsx\" target=\"_blank\">XLSX模版</a></li>";
}
if (file_exists("./template/{$template}.xls")) {
$download .= "\n <li><a href=\"/template/{$template}.xls\" target=\"_blank\">XLS模版</a></li>";
$download .= "<li><a href=\"/template/{$template}.xls\" target=\"_blank\">XLS模版</a></li>";
}
if (file_exists("./template/{$template}.csv")) {
$download .= empty($download) ? '' : "\n <li class=\"divider\"></li>";
$download .= "\n <li><a href=\"/template/{$template}.csv\" target=\"_blank\">CSV模版</a></li>";
$download .= empty($download) ? '' : "<li class=\"divider\"></li>";
$download .= "<li><a href=\"/template/{$template}.csv\" target=\"_blank\">CSV模版</a></li>";
}
$download .= empty($download) ? '' : "\n ";
if (!empty($download)) {
... ...
... ... @@ -10,7 +10,7 @@ use fast\Tree;
* 分类管理
*
* @icon fa fa-list
* @remark 用于统一管理网站的所有分类,分类可进行无限级分类
* @remark 用于统一管理网站的所有分类,分类可进行无限级分类,分类类型请在常规管理->系统配置->字典配置中添加
*/
class Category extends Backend
{
... ... @@ -32,13 +32,14 @@ class Category extends Backend
$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)
{
foreach ($this->categorylist as $k => $v) {
$categorydata[$v['id']] = $v;
}
$typeList = CategoryModel::getTypeList();
$this->view->assign("flagList", $this->model->getFlagList());
$this->view->assign("typeList", CategoryModel::getTypeList());
$this->view->assign("typeList", $typeList);
$this->view->assign("parentList", $categorydata);
$this->assignconfig('typeList', $typeList);
}
/**
... ... @@ -46,34 +47,29 @@ class Category extends Backend
*/
public function index()
{
if ($this->request->isAjax())
{
if ($this->request->isAjax()) {
$search = $this->request->request("search");
$type = $this->request->request("type");
//构造父类select列表选项数据
$list = [];
foreach ($this->categorylist as $k => $v)
{
foreach ($this->categorylist as $k => $v) {
if ($search) {
if ($v['type'] == $type && stripos($v['name'], $search) !== false || stripos($v['nickname'], $search) !== false)
{
if($type == "all" || $type == null) {
if ($v['type'] == $type && stripos($v['name'], $search) !== false || stripos($v['nickname'], $search) !== false) {
if ($type == "all" || $type == null) {
$list = $this->categorylist;
} else {
$list[] = $v;
}
}
} else {
if($type == "all" || $type == null) {
if ($type == "all" || $type == null) {
$list = $this->categorylist;
} else if ($v['type'] == $type){
} elseif ($v['type'] == $type) {
$list[] = $v;
}
}
}
$total = count($list);
... ... @@ -85,6 +81,59 @@ class Category extends Backend
}
/**
* 编辑
*/
public function edit($ids = null)
{
$row = $this->model->get($ids);
if (!$row) {
$this->error(__('No Results were found'));
}
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
if (!in_array($row[$this->dataLimitField], $adminIds)) {
$this->error(__('You have no permission'));
}
}
if ($this->request->isPost()) {
$params = $this->request->post("row/a");
if ($params) {
$params = $this->preExcludeFields($params);
if ($params['pid'] != $row['pid']) {
$childrenIds = Tree::instance()->init(collection(\app\common\model\Category::select())->toArray())->getChildrenIds($row['id']);
if (in_array($params['pid'], $childrenIds)) {
$this->error(__('Can not change the parent to child'));
}
}
try {
//是否采用模型验证
if ($this->modelValidate) {
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
$row->validate($validate);
}
$result = $row->allowField(true)->save($params);
if ($result !== false) {
$this->success();
} else {
$this->error($row->getError());
}
} catch (\think\exception\PDOException $e) {
$this->error($e->getMessage());
} catch (\think\Exception $e) {
$this->error($e->getMessage());
}
}
$this->error(__('Parameter %s can not be empty', ''));
}
$this->view->assign("row", $row);
return $this->view->fetch();
}
/**
* Selectpage搜索
*
* @internal
... ... @@ -93,5 +142,4 @@ class Category extends Backend
{
return parent::selectpage();
}
}
... ...
... ... @@ -2,6 +2,7 @@
namespace app\admin\controller\auth;
use app\admin\model\AuthRule;
use app\common\controller\Backend;
use fast\Tree;
use think\Cache;
... ... @@ -28,8 +29,7 @@ class Rule extends Backend
$this->model = model('AuthRule');
// 必须将结果集转换为数组
$ruleList = collection($this->model->order('weigh', 'desc')->order('id', 'asc')->select())->toArray();
foreach ($ruleList as $k => &$v)
{
foreach ($ruleList as $k => &$v) {
$v['title'] = __($v['title']);
$v['remark'] = __($v['remark']);
}
... ... @@ -37,10 +37,10 @@ class Rule extends Backend
Tree::instance()->init($ruleList);
$this->rulelist = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0), 'title');
$ruledata = [0 => __('None')];
foreach ($this->rulelist as $k => &$v)
{
if (!$v['ismenu'])
foreach ($this->rulelist as $k => &$v) {
if (!$v['ismenu']) {
continue;
}
$ruledata[$v['id']] = $v['title'];
}
unset($v);
... ... @@ -52,8 +52,7 @@ class Rule extends Backend
*/
public function index()
{
if ($this->request->isAjax())
{
if ($this->request->isAjax()) {
$list = $this->rulelist;
$total = count($this->rulelist);
... ... @@ -69,18 +68,14 @@ class Rule extends Backend
*/
public function add()
{
if ($this->request->isPost())
{
if ($this->request->isPost()) {
$params = $this->request->post("row/a", [], 'strip_tags');
if ($params)
{
if (!$params['ismenu'] && !$params['pid'])
{
if ($params) {
if (!$params['ismenu'] && !$params['pid']) {
$this->error(__('The non-menu rule must have parent'));
}
$result = $this->model->validate()->save($params);
if ($result === FALSE)
{
if ($result === false) {
$this->error($this->model->getError());
}
Cache::rm('__menu__');
... ... @@ -94,28 +89,31 @@ class Rule extends Backend
/**
* 编辑
*/
public function edit($ids = NULL)
public function edit($ids = null)
{
$row = $this->model->get(['id' => $ids]);
if (!$row)
if (!$row) {
$this->error(__('No Results were found'));
if ($this->request->isPost())
{
}
if ($this->request->isPost()) {
$params = $this->request->post("row/a", [], 'strip_tags');
if ($params)
{
if (!$params['ismenu'] && !$params['pid'])
{
if ($params) {
if (!$params['ismenu'] && !$params['pid']) {
$this->error(__('The non-menu rule must have parent'));
}
if ($params['pid'] != $row['pid']) {
$childrenIds = Tree::instance()->init(collection(AuthRule::select())->toArray())->getChildrenIds($row['id']);
if (in_array($params['pid'], $childrenIds)) {
$this->error(__('Can not change the parent to child'));
}
}
//这里需要针对name做唯一验证
$ruleValidate = \think\Loader::validate('AuthRule');
$ruleValidate->rule([
'name' => 'require|format|unique:AuthRule,name,' . $row->id,
]);
$result = $row->validate()->save($params);
if ($result === FALSE)
{
if ($result === false) {
$this->error($row->getError());
}
Cache::rm('__menu__');
... ... @@ -132,22 +130,18 @@ class Rule extends Backend
*/
public function del($ids = "")
{
if ($ids)
{
if ($ids) {
$delIds = [];
foreach (explode(',', $ids) as $k => $v)
{
$delIds = array_merge($delIds, Tree::instance()->getChildrenIds($v, TRUE));
foreach (explode(',', $ids) as $k => $v) {
$delIds = array_merge($delIds, Tree::instance()->getChildrenIds($v, true));
}
$delIds = array_unique($delIds);
$count = $this->model->where('id', 'in', $delIds)->delete();
if ($count)
{
if ($count) {
Cache::rm('__menu__');
$this->success();
}
}
$this->error();
}
}
... ...
... ... @@ -172,7 +172,7 @@ return [
'Third group 2' => '三级管理组2',
'Dashboard tips' => '用于展示当前系统中的统计数据、统计报表及重要实时数据',
'Config tips' => '可以在此增改系统的变量和分组,也可以自定义分组和变量,如果需要删除请从数据库中删除',
'Category tips' => '用于统一管理网站的所有分类,分类可进行无限级分类',
'Category tips' => '用于统一管理网站的所有分类,分类可进行无限级分类,分类类型请在常规管理->系统配置->字典配置中添加',
'Attachment tips' => '主要用于管理上传到服务器或第三方存储的数据',
'Addon tips' => '可在线安装、卸载、禁用、启用插件,同时支持添加本地插件。FastAdmin已上线插件商店 ,你可以发布你的免费或付费插件:<a href="https://www.fastadmin.net/store.html" target="_blank">https://www.fastadmin.net/store.html</a>',
'Admin tips' => '一个管理员可以有多个角色组,左侧的菜单根据管理员所拥有的权限进行生成',
... ...
... ... @@ -15,5 +15,6 @@ return [
'Menu tips' => '父级菜单无需匹配控制器和方法,子级菜单请使用控制器名',
'Node tips' => '控制器/方法名,如果有目录请使用 目录名/控制器名/方法名',
'The non-menu rule must have parent' => '非菜单规则节点必须有父级',
'Can not change the parent to child' => '父组别不能是它的子组别',
'Name only supports letters, numbers, underscore and slash' => 'URL规则只能是小写字母、数字、下划线和/组成',
];
... ...
... ... @@ -12,5 +12,6 @@ return [
'Createtime' => '创建时间',
'Updatetime' => '更新时间',
'Weigh' => '权重',
'Can not change the parent to child' => '父组别不能是它的子组别',
'Status' => '状态'
];
... ...
... ... @@ -17,7 +17,7 @@ trait Backend
* @param $params
* @return array
*/
private function preExcludeFields($params)
protected function preExcludeFields($params)
{
if (is_array($this->excludeFields)) {
foreach ($this->excludeFields as $field) {
... ...
... ... @@ -34,24 +34,19 @@ class AdminLog extends Model
$admin_id = $auth->isLogin() ? $auth->id : 0;
$username = $auth->isLogin() ? $auth->username : __('Unknown');
$content = self::$content;
if (!$content)
{
if (!$content) {
$content = request()->param();
foreach ($content as $k => $v)
{
if (is_string($v) && strlen($v) > 200 || stripos($k, 'password') !== false)
{
foreach ($content as $k => $v) {
if (is_string($v) && strlen($v) > 200 || stripos($k, 'password') !== false) {
unset($content[$k]);
}
}
}
$title = self::$title;
if (!$title)
{
if (!$title) {
$title = [];
$breadcrumb = Auth::instance()->getBreadcrumb();
foreach ($breadcrumb as $k => $v)
{
foreach ($breadcrumb as $k => $v) {
$title[] = $v['title'];
}
$title = implode(' ', $title);
... ... @@ -59,10 +54,10 @@ class AdminLog extends Model
self::create([
'title' => $title,
'content' => !is_scalar($content) ? json_encode($content) : $content,
'url' => request()->url(),
'url' => substr(request()->url(), 0, 1500),
'admin_id' => $admin_id,
'username' => $username,
'useragent' => request()->server('HTTP_USER_AGENT'),
'useragent' => substr(request()->server('HTTP_USER_AGENT'), 0, 255),
'ip' => request()->ip()
]);
}
... ... @@ -71,5 +66,4 @@ class AdminLog extends Model
{
return $this->belongsTo('Admin', 'admin_id')->setEagerlyType(0);
}
}
... ...
... ... @@ -14,7 +14,6 @@ use think\Validate;
*/
class User extends Frontend
{
protected $layout = 'default';
protected $noNeedLogin = ['login', 'register', 'third'];
protected $noNeedRight = ['*'];
... ... @@ -82,8 +81,9 @@ class User extends Frontend
public function register()
{
$url = $this->request->request('url');
if ($this->auth->id)
if ($this->auth->id) {
$this->success(__('You\'ve logged in, do not login again'), $url);
}
if ($this->request->isPost()) {
$username = $this->request->post('username');
$password = $this->request->post('password');
... ... @@ -152,8 +152,9 @@ class User extends Frontend
public function login()
{
$url = $this->request->request('url');
if ($this->auth->id)
if ($this->auth->id) {
$this->success(__('You\'ve logged in, do not login again'), $url);
}
if ($this->request->isPost()) {
$account = $this->request->post('account');
$password = $this->request->post('password');
... ... @@ -180,7 +181,7 @@ class User extends Frontend
$result = $validate->check($data);
if (!$result) {
$this->error(__($validate->getError()), null, ['token' => $this->request->token()]);
return FALSE;
return false;
}
if ($this->auth->login($account, $password)) {
$synchtml = '';
... ... @@ -208,7 +209,7 @@ class User extends Frontend
/**
* 注销登录
*/
function logout()
public function logout()
{
//注销本站
$this->auth->logout();
... ... @@ -264,7 +265,7 @@ class User extends Frontend
$result = $validate->check($data);
if (!$result) {
$this->error(__($validate->getError()), null, ['token' => $this->request->token()]);
return FALSE;
return false;
}
$ret = $this->auth->changepwd($newpassword, $oldpassword);
... ... @@ -283,5 +284,4 @@ class User extends Frontend
$this->view->assign('title', __('Change password'));
return $this->view->fetch();
}
}
... ...
... ... @@ -45,17 +45,19 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'jstree'], function (
escape: false,
columns: [
[
{field: 'state', checkbox: true, },
{field: 'state', checkbox: true,},
{field: 'id', title: 'ID'},
{field: 'pid', title: __('Parent')},
{field: 'name', title: __('Name'), align: 'left'},
{field: 'status', title: __('Status'), formatter: Table.api.formatter.status},
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: function (value, row, index) {
{
field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: function (value, row, index) {
if (Config.admin.group_ids.indexOf(parseInt(row.id)) > -1) {
return '';
}
return Table.api.formatter.operate.call(this, value, row, index);
}}
}
}
]
],
pagination: false,
... ... @@ -105,7 +107,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'jstree'], function (
$("#treeview").jstree("destroy");
Controller.api.rendertree(data);
} else {
Backend.api.toastr.error(ret.data);
Backend.api.toastr.error(ret.msg);
}
}
}, error: function (e) {
... ...
... ... @@ -15,7 +15,6 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
}
});
var table = $("#table");
var tableOptions = {
url: $.fn.bootstrapTable.defaults.extend.index_url,
... ... @@ -24,11 +23,12 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
sortName: 'weigh',
pagination: false,
commonSearch: false,
search: false,
columns: [
[
{checkbox: true},
{field: 'id', title: __('Id')},
{field: 'type', title: __('Type')},
{field: 'type', title: __('Type'), searchList: Config.searchList, formatter: Table.api.formatter.normal},
{field: 'name', title: __('Name'), align: 'left'},
{field: 'nickname', title: __('Nickname')},
{field: 'flag', title: __('Flag'), operate: false, formatter: Table.api.formatter.flag},
... ... @@ -48,7 +48,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
//绑定TAB事件
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
// var options = table.bootstrapTable(tableOptions);
var typeStr = $(this).attr("href").replace('#','');
var typeStr = $(this).attr("href").replace('#', '');
var options = table.bootstrapTable('getOptions');
options.pageNumber = 1;
options.queryParams = function (params) {
... ...