ThinkAdmin v5 是一个基于 ThinkPHP 5.1 和 ThinkLibrary 开发的后台管理系统。 我们致力于二次开发底层框架,提供完整的组件及API,基于此框架可以快速开发应用,另外项目安装及二次开发可以参考 ThinkPHP 官方文档,数据库文件摆放在项目根目录下。 ThinkAdmin 非常适用于快速二次开发,默认集成 微信开发组件、支持微信服务号、微信支付、支付宝支付,文件存储集成阿里云OSS存储、七牛云存储、本地服务器存储。
注意事项 :
登录页面
后台首页
开发文档:http://doc.thinkadmin.top/thinkadmin-v5 开发前请认真阅读 ThinkPHP 官方文档会对您有帮助哦! 本地开发命令php think run,使用http://127.0.0.1:8000访问项目。 PHP 开发技术交流( QQ 群 513350915)
php think run
http://127.0.0.1:8000
ThinkAdmin 为 MIT 协议开源项目,安装使用或二次开发不受约束,欢迎 fork 项目。 部分代码及功能组件来自互联网,若有异议可以联系作者进行删除。
build.cmd
Composer
vendor
php think xsync:admin
admin
php think xsync:wechat
wechat
php think xsync:plugs
plugs
php think xsync:service
service
php think xsync:config
config
php think xfans:all
php think xfans:list
php think xfans:tags
php think xfans:black
php think xtask:reset
php think xtask:start
php think xtask:state
php think xtask:stop
php think xclean:session
php think xclean:store
ThinkAdmin 的权限管理基于标准RBAC简化而来,去除了繁杂的节点管理,使得权限管理起来更简单,具体包含节点管理、权限管理、菜单管理、用户管理。
RBAC
自 ThinkAdmin v5 版本开始,系统节点使用代码注释实现; 需要加入权限控制的访问方法,需要写上标准的块注释。如:
/** * 操作的名称 * @auth true # 表示需要验证权限 * @menu true # 在菜单编辑的节点可选项 */ public function index(){ // @todo }
@auth true
@menu true
创建好权限后,需要给权限配置好需要控制的节点的列表。 如:权限A只能访问哪些节点,就需要勾选对应功能的节点。
菜单创建与编辑里,要特别注意菜单对应的节点规范。 如:admin/menu/index 如果在节点注释中含menu true则该节点会出现在自动提示中。
admin/menu/index
menu true
添加用户后,需要给用户配置对应权限。 注意admin为超级用户,不需要配置权限,因为他拥有后台所有权限。
ThinkLibrary 与 ThinkPHP 组合起来就是现在的 ThinkAdmin v5,都是基于 Composer 来管理; 如果需要使用到 ThinkLibrary 里面的功能,控制器需要继承 \library\Controller 类。
\library\Controller
在控制器访问中只需加入$this->page(表名)可以显示默认数据表的分页列表; 如果需要对列表进行条件处理,可以使用查询器来实现。如:
$this->page(表名)
// 创建查询器 $query = $this->_query('表名')->where(['status'=>'1']); // 查询器分页输出 $query->page();
注意 :在 ThinkPHP 5.1 之后,控制器不需要直接返回内容了,函数_page里面使用HttpResponseException直接输出机制。 另外对于url输入的变量也可以快速输入到查询器条件中,如:
_page
HttpResponseException
url
// 创建查询器 $query = $this->_query('表名'); // 切入url参数,接收 username 和 sex 并使用 like 查询,接收 status 使用 eq 查询 $query->like('username,sex')->equal('status'); // 查询器分页输出 $query->page();
有时候,url输入的名称与数据字段不一定是匹配的,所以需要用到别名,这里就需要按规则写条件,如:
// 切入url参数,接收 username_alias 和 sex 并使用 like 查询,接收 user_status 使用 eq 查询 // 这里用到了别名,username_alias 对应数据库中的 username 字段,user_status 对应数据库的 status 字段 $query = $this->_query('表名')->like('username#username_alias,sex')->equal('status#user_status'); // 查询器分页输出 $query->page();
输出额外数据到模板,与 ThinkPHP 操作无异,如:
// 额外列表数据赋值到模板,模板里直接使用变量 $userList $this->userList = Db::name('User')->where(['status'=>'1'])->select(); // 切入url参数,接收 username 和 sex 并使用 like 查询,接收 status 使用 eq 查询 $query = $this->_query('表名')->like('username,sex')->equal('status'); // 查询器分页输出 $query->page();
对于通过page方法实现的即将显示到模板的列表,还可以进行引用二次处理,如:
page
protected function _page_filter(&$data){ // 这里可以对 $data 进行二次处理,注意是引用 } ### 当一个控制器存在多个page操作时,可以指定回调前缀 protected function _index_page_filter(&$data){ // 精准回调对 $data 进行二次处理,注意是引用 }
下面提供一个完整的DEMO
/** * 系统操作日志 * @auth true * @menu true * @throws \think\Exception * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\ModelNotFoundException * @throws \think\exception\DbException */ public function index() { $this->title = '系统操作日志'; $query = $this->_query($this->table)->like('action,node,content,username,geoip'); $query->dateBetween('create_at')->order('id desc')->page(); } /** * 列表数据处理 * @param array $data * @throws \Exception */ protected function _index_page_filter(&$data) { $ip = new \Ip2Region(); foreach ($data as &$vo) { $result = $ip->btreeSearch($vo['geoip']); $vo['isp'] = isset($result['region']) ? $result['region'] : ''; $vo['isp'] = str_replace(['内网IP', '0', '|'], '', $vo['isp']); } }
ThinkLibrary 表单处理可能简化数据保存与更新操作, 控制器只需要一行代码,就可以实现数据添加与更新,如:
$this->_form('表名','模板名称');
当然,这里使用了HttpResponseException直接输出,不需要返回内容的。 需要给模板额外赋值,可以直接在控制器$this->username='你的值'; 这样在模板中可以直接使用$username变量;
$this->username='你的值';
$username
如果提交的表单数据包含指定主键时则为更新操作,否则为添加记录; 另外对表单还有callback操作(参数使用引用),统一名称为protected function _form_filter(&$data)
callback
protected function _form_filter(&$data)
另外关于模板的使用,可以参考下demo哦。
对于表单操作,Controller内置了两个回调方法,如:
Controller
[_ACTION]_form_filter($vo) [_ACTION]_form_result($result, $vo)
当回调函数返回false时,Controller默认的行为将不会执行。
false
/** * 添加拼团 * @auth true */ public function add() { $this->title = '添加拼团'; $this->_form($this->table, 'form'); } /** * 编辑拼团 * @auth true */ public function edit() { $this->title = '编辑拼团'; $this->_form($this->table, 'form'); } /** * 添加拼团商品表单处理 * @param array $data * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\ModelNotFoundException * @throws \think\exception\DbException */ protected function _form_filter(&$data) { if (empty($data['code'])) $data['code'] = Data::uniqidNumberCode(10); if ($this->request->isGet()) { $map = ['package_code' => $data['code']]; $data['list'] = Db::name('StoreGoodsGroupList')->where($map)->select(); } else { if (empty($data['logo'])) $this->error('请上传商品图标图片'); if (empty($data['image'])) $this->error('请上传商品展示图片'); if (empty($data['item_number'])) $this->error('请添加套卡包含内容'); $all = []; foreach (array_keys($data['item_number']) as $key) $all[] = [ 'package_code' => $data['code'], 'goods_code' => $data['item_code'][$key], 'goods_type' => $data['item_type'][$key], 'goods_title' => $data['item_title'][$key], 'goods_number' => $data['item_number'][$key], ]; try { Db::transaction(function () use ($data, $all) { $map = ['package_code' => $data['code']]; Db::name('StoreGoodsGroupList')->where($map)->delete(); Db::name('StoreGoodsGroupList')->insertAll($all); }); } catch (Exception $e) { $this->error("商品详情处理失败,{$e->getMessage()}"); } } } /** * 表单结果处理 * @param boolean $result */ protected function _form_result($result) { if ($result && $this->request->isPost()) { $this->success('商品编辑成功!', 'javascript:history.back()'); } }
如果是在 ThinkAdmin 后台基于 admin.js 的情况下,可使用 form[data-auto] 来与 $this->_form 配合使用。
数据删除同样也只需要一行代码$this->_delete('表名'); 前端只需要传入数据表的主键就可以了,不需要做额外处理。
$this->_delete('表名');
如果数据表中不存在is_deleted字段,则为硬删除。
is_deleted
当前数据表中存在is_deleted字段时,$this->_delete则自动为软删除操作, 在列表操作时加上条件过滤下就可以正常操作。
$this->_delete
对于数据删除的结果,可以进行自定义处理,回调函数规则如:[_ACTION]_delete_result 下面提供一个完整的demo:
[_ACTION]_delete_result
/** * 删除系统权限 * @auth true */ public function remove() { $this->applyCsrfToken(); $this->_delete($this->table); } /** * 删除结果处理 * @param boolean $result * @throws \think\Exception * @throws \think\exception\PDOException */ protected function _remove_delete_result($result) { if ($result) { $where = ['auth' => $this->request->post('id')]; Db::name('SystemAuthNode')->where($where)->delete(); $this->success("权限删除成功!", ''); } else { $this->error("权限删除失败,请稍候再试!"); } }
如果是在 ThinkAdmin 后台基于 admin.js 的情况下,可台使用 data-action 来与 $this->_delete 配合使用。 前端提交上来的主键值支持多个,以英文逗号分隔。
数据更新主要用于 数据状态更新,比如:数据禁用,数据启用,状态更改
在服务端只需要一行代码$this->_save($this->table)就可以实现更新操作。
$this->_save($this->table)
前端需要提供需要修改的数据ID以及数据状态值,当然也可以后第二个参数指定(强烈建议配置第二个字段)
这个地方可能存在数据恶意修改的情况,所有指定第二个参数非常有必要。
下面提供一个完整的demo,数据禁用与启用操作:
/** * 启用系统菜单 * @auth true * @throws \think\Exception * @throws \think\exception\PDOException */ public function resume() { $this->applyCsrfToken(); $this->_save($this->table, ['status' => '1']); } /** * 禁用系统菜单 * @auth true * @throws \think\Exception * @throws \think\exception\PDOException */ public function forbid() { $this->applyCsrfToken(); $this->_save($this->table, ['status' => '0']); }
如果是在 ThinkAdmin 后台基于 admin.js 的情况下,可台使用 data-action 来与 $this->_save 配合使用。 前端提交上来的主键值支持多个,以英文逗号分隔。
体验账号及密码都是admin
ThinkAdmin v1 基于 ThinkPHP 5.0 开发