首页
直播
壁纸
友链
搜索
1
微信小程序支付全链路实战:JSAPI 下单、调起支付、回调验签与退款
266 阅读
2
微信小程序云开发实战:云函数、云数据库与云存储的正确使用姿势
256 阅读
3
微信小程序自定义 tabBar 实战:custom-tab-bar 从适配到深色模式
255 阅读
4
微信小程序 Skyline 渲染引擎实战:worklet 动画从原理到落地
253 阅读
5
微信小程序分包进阶:独立分包、预下载与分包异步化实战
246 阅读
服务器运维
后端技术
前端技术
梯子
数据库
小程序
登录
搜索
标签搜索
fastadmin
Redis
微信小程序
前端开发
RabbitMQ
Go
服务器
codex
buildadmin
小程序
mysql
Nginx
Docker
Vue3
Node.js
MySQL优化
Linux
TypeScript
JWT
PHP
沿途的风景
累计撰写
74
篇文章
累计收到
0
条评论
首页
栏目
服务器运维
后端技术
前端技术
梯子
数据库
小程序
页面
直播
壁纸
友链
搜索到
8
篇与
» fastadmin
的结果
2026-03-29
FastAdmin API 接口开发:前后端分离实践
前言随着前后端分离架构的普及,FastAdmin 的 API 模块越来越重要。本文将系统讲解如何使用 FastAdmin 开发 RESTful API 接口,包括 Token 认证、参数验证、数据返回格式规范以及与前端框架的对接实践。一、API 模块概述FastAdmin 的 API 模块位于 application/api/,专门用于提供接口服务:application/api/ ├── controller/ │ ├── Common.php # 公共控制器 │ ├── Index.php # 首页接口 │ ├── User.php # 用户接口 │ ├── Api.php # 基类控制器 │ └── Demo.php # 示例接口 ├── model/ │ └── User.php # API 用户模型 └── config.php # API 模块配置二、API 基类控制器所有 API 控制器继承自 app\common\controller\Api:<?php // application/common/controller/Api.php namespace app\common\controller; use think\Controller; use app\common\library\Token; use app\common\library\Auth; class Api extends Controller { // 不需要登录的方法 protected $noNeedLogin = ['*']; // 不需要权限验证的方法 protected $noNeedRight = ['*']; // 当前请求的 Token protected $token = ''; // 当前登录用户 protected $auth = null; // 初始化 public function _initialize() { parent::_initialize(); // 跨域处理 $this->checkCors(); // Token 认证 $this->token = $this->request->server('HTTP_TOKEN', $this->request->request('token', '')); // 初始化认证 $this->auth = Auth::instance(); // 检查是否需要登录 $action = strtolower($this->request->action()); if (!in_array($action, array_map('strtolower', $this->noNeedLogin))) { if (!$this->auth->isLogin()) { $this->error(__('Please login first'), null, 401); } } } // 跨域设置 protected function checkCors() { header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS'); header('Access-Control-Allow-Headers: token, Content-Type, Authorization'); if ($this->request->method() == 'OPTIONS') { $this->success(); } } // 成功返回 protected function success($msg = '', $data = null, $code = 1) { $this->result($msg, $data, $code); } // 失败返回 protected function error($msg = '', $data = null, $code = 0) { $this->result($msg, $data, $code); } // 统一返回格式 protected function result($msg, $data = null, $code = 1) { $result = [ 'code' => $code, 'msg' => $msg, 'time' => time(), 'data' => $data, ]; throw new \think\exception\HttpResponseException( json($result) ); } }统一返回格式{ "code": 1, "msg": "获取成功", "time": 1721800000, "data": { "id": 1, "username": "admin" } }字段说明code1=成功,0=失败msg提示消息time服务器时间戳data业务数据三、用户认证3.1 注册接口<?php // application/api/controller/User.php namespace app\api\controller; use app\common\controller\Api; use app\common\model\User; use app\common\library\Token; use think\Validate; class User extends Api { protected $noNeedLogin = ['register', 'login']; protected $noNeedRight = ['*']; /** * 用户注册 * POST /api/user/register */ public function register() { $username = $this->request->post('username'); $password = $this->request->post('password'); $email = $this->request->post('email'); $mobile = $this->request->post('mobile'); // 参数验证 $validate = new Validate([ 'username' => 'require|length:3,30', 'password' => 'require|length:6,30', 'email' => 'require|email', 'mobile' => 'require|regex:/^1[3-9]\d{9}$/', ], [ 'username.require' => '用户名不能为空', 'username.length' => '用户名长度3-30个字符', 'password.require' => '密码不能为空', 'password.length' => '密码长度6-30个字符', 'email.email' => '邮箱格式不正确', 'mobile.regex' => '手机号格式不正确', ]); $data = [ 'username' => $username, 'password' => $password, 'email' => $email, 'mobile' => $mobile, ]; if (!$validate->check($data)) { $this->error($validate->getError()); } // 检查用户名是否已存在 if (User::where('username', $username)->find()) { $this->error('用户名已存在'); } // 创建用户 $user = new User(); $user->allowField(true)->save([ 'username' => $username, 'password' => \app\common\library\Hash::make($password), 'email' => $email, 'mobile' => $mobile, 'jointime' => time(), 'createtime' => time(), 'updatetime' => time(), ]); // 生成 Token $token = Token::create($user->id, 'user', 86400 * 7); $this->success('注册成功', [ 'token' => $token, 'user' => [ 'id' => $user->id, 'username' => $user->username, 'email' => $user->email, 'mobile' => $user->mobile, ], ]); } /** * 用户登录 * POST /api/user/login */ public function login() { $account = $this->request->post('account'); $password = $this->request->post('password'); if (!$account || !$password) { $this->error('账号和密码不能为空'); } // 支持用户名/邮箱/手机号登录 $user = User::where('username|email|mobile', $account)->find(); if (!$user) { $this->error('账号不存在'); } if (!\app\common\library\Hash::check($password, $user->password)) { $this->error('密码错误'); } if ($user->status != 'normal') { $this->error('账号已被禁用'); } // 更新登录信息 $user->save([ 'logintime' => time(), 'loginip' => $this->request->ip(), ]); // 生成 Token $token = Token::create($user->id, 'user', 86400 * 7); $this->success('登录成功', [ 'token' => $token, 'user' => [ 'id' => $user->id, 'username' => $user->username, 'avatar' => $user->avatar, 'email' => $user->email, ], ]); } /** * 获取当前用户信息 * GET /api/user/info */ public function info() { $user = $this->auth->getUser(); $this->success('获取成功', [ 'id' => $user->id, 'username' => $user->username, 'avatar' => $user->avatar, 'email' => $user->email, 'mobile' => $user->mobile, 'createtime'=> $user->createtime, ]); } /** * 退出登录 * POST /api/user/logout */ public function logout() { Token::clear($this->token); $this->success('退出成功'); } }3.2 Token 机制FastAdmin 的 Token 存储在 fa_token 表中:// 生成 Token(有效期 7 天) $token = Token::create($userId, 'user', 86400 * 7); // 验证 Token $userId = Token::get($token); // 刷新 Token $token = Token::refresh($token); // 清除 Token Token::clear($token);前端请求时在 Header 中携带 Token:// axios 请求拦截器 axios.interceptors.request.use(config => { const token = localStorage.getItem('token'); if (token) { config.headers['token'] = token; } return config; }); // 响应拦截器处理 401 axios.interceptors.response.use( response => response.data, error => { if (error.response && error.response.status === 401) { localStorage.removeItem('token'); router.push('/login'); } return Promise.reject(error); } );四、RESTful 接口开发4.1 文章接口完整实现<?php // application/api/controller/Article.php namespace app\api\controller; use app\common\controller\Api; use app\common\model\Article as ArticleModel; use think\Validate; class Article extends Api { protected $noNeedLogin = ['index', 'detail']; protected $noNeedRight = ['*']; /** * 文章列表 * GET /api/article/index?page=1&limit=10&keyword=xxx */ public function index() { $page = $this->request->get('page/d', 1); $limit = $this->request->get('limit/d', 10); $keyword = $this->request->get('keyword', ''); $categoryId = $this->request->get('category_id/d', 0); $query = ArticleModel::where('status', 'normal'); // 关键词搜索 if ($keyword) { $query->where('title', 'like', "%{$keyword}%"); } // 分类筛选 if ($categoryId) { $query->where('category_id', $categoryId); } // 分页查询 $total = $query->count(); $list = $query->order('id', 'desc') ->field('id,title,author,views,createtime') ->page($page, $limit) ->select(); $this->success('获取成功', [ 'total' => $total, 'page' => $page, 'limit' => $limit, 'list' => $list, ]); } /** * 文章详情 * GET /api/article/detail?id=1 */ public function detail() { $id = $this->request->get('id/d', 0); if (!$id) { $this->error('参数错误'); } $article = ArticleModel::where('id', $id) ->where('status', 'normal') ->find(); if (!$article) { $this->error('文章不存在'); } // 浏览量 +1 ArticleModel::where('id', $id)->inc('views')->update(); $this->success('获取成功', $article); } /** * 创建文章 * POST /api/article/add */ public function add() { $data = $this->request->post(); $data['admin_id'] = $this->auth->id; $validate = new Validate([ 'title' => 'require|length:2,100', 'content' => 'require|min:10', ], [ 'title.require' => '标题不能为空', 'content.require' => '内容不能为空', ]); if (!$validate->check($data)) { $this->error($validate->getError()); } $data['createtime'] = time(); $data['updatetime'] = time(); $article = new ArticleModel(); $article->allowField(true)->save($data); $this->success('创建成功', ['id' => $article->id]); } /** * 编辑文章 * PUT /api/article/edit?id=1 */ public function edit() { $id = $this->request->get('id/d', 0); $data = $this->request->post(); $article = ArticleModel::find($id); if (!$article) { $this->error('文章不存在'); } // 权限检查:只能编辑自己的文章 if ($article->admin_id != $this->auth->id) { $this->error('无权操作', null, 403); } $data['updatetime'] = time(); $article->allowField(true)->save($data); $this->success('修改成功'); } /** * 删除文章 * DELETE /api/article/del?id=1 */ public function del() { $id = $this->request->get('id/d', 0); $article = ArticleModel::find($id); if (!$article) { $this->error('文章不存在'); } if ($article->admin_id != $this->auth->id) { $this->error('无权操作', null, 403); } $article->delete(); $this->success('删除成功'); } }4.2 路由配置在 application/api/route.php 中定义路由规则:<?php use think\Route; // 文章相关 Route::get('articles', 'api/article/index'); Route::get('article/:id', 'api/article/detail'); Route::post('article', 'api/article/add'); Route::put('article/:id', 'api/article/edit'); Route::delete('article/:id', 'api/article/del'); // 用户相关 Route::post('register', 'api/user/register'); Route::post('login', 'api/user/login'); Route::get('user/info', 'api/user/info'); Route::post('logout', 'api/user/logout');五、接口文档自动生成FastAdmin 内置 API 文档生成功能:# 生成 API 文档 php think api --force=true文档输出到 public/api.html,包含所有接口的参数说明、返回示例和在线测试功能。注释规范/** * @ApiTitle (文章列表) * @ApiSummary (获取文章列表,支持分页和搜索) * @ApiMethod (GET) * @ApiRoute (/api/article/index) * @ApiParams (name="page", type="integer", required=false, description="页码,默认1") * @ApiParams (name="limit", type="integer", required=false, description="每页条数,默认10") * @ApiParams (name="keyword", type="string", required=false, description="搜索关键词") * @ApiReturn ({"code":1,"msg":"获取成功","data":{"total":100,"list":[...]}}) */ public function index() { // ... }六、与前端对接6.1 Vue3 对接示例// api/article.ts import axios from 'axios' const API_BASE = '/api' export interface Article { id: number title: string author: string views: number createtime: number } export interface ArticleListResponse { total: number page: number limit: number list: Article[] } export const getArticles = (params: { page?: number limit?: number keyword?: string }) => { return axios.get<{ code: number; data: ArticleListResponse }>( `${API_BASE}/article/index`, { params } ) } export const getArticleDetail = (id: number) => { return axios.get<{ code: number; data: Article }>( `${API_BASE}/article/detail`, { params: { id } } ) }6.2 小程序对接示例// utils/request.js const BASE_URL = 'https://api.example.com' export function request(options) { const token = wx.getStorageSync('token') return new Promise((resolve, reject) => { wx.request({ url: BASE_URL + options.url, method: options.method || 'GET', data: options.data, header: { 'token': token, 'Content-Type': 'application/json' }, success(res) { if (res.data.code === 1) { resolve(res.data.data) } else if (res.data.code === 0 && res.statusCode === 401) { wx.removeStorageSync('token') wx.redirectTo({ url: '/pages/login/login' }) } else { wx.showToast({ title: res.data.msg, icon: 'none' }) reject(res.data) } }, fail(err) { reject(err) } }) }) } // 调用 request({ url: '/api/article/index', data: { page: 1, limit: 10 } }) .then(data => { console.log(data.list) })七、安全防护7.1 接口限流// 使用缓存实现简单限流 public function _initialize() { parent::_initialize(); $ip = $this->request->ip(); $key = 'api_rate_' . $ip; $count = \think\Cache::inc($key); if ($count == 1) { \think\Cache::expire($key, 60); // 60秒内 } if ($count > 60) { $this->error('请求过于频繁', null, 429); } }7.2 签名验证// 客户端生成签名 // sign = md5(参数按key排序拼接 + secret_key) public function verifySign($params, $sign) { unset($params['sign']); ksort($params); $str = http_build_query($params) . '&key=' . config('api_secret'); return md5($str) === $sign; }总结FastAdmin API 模块提供了完整的前后端分离方案:统一返回格式和错误处理Token 认证机制,支持多端登录RESTful 路由设计,接口语义清晰内置 API 文档自动生成配合 Vue3/小程序等前端框架,快速搭建完整应用
2026年03月29日
17 阅读
0 评论
0 点赞
2026-03-28
FastAdmin 插件开发实战:从零开发自定义插件
前言FastAdmin 的插件系统是其生态的核心——通过在线安装插件,可以快速扩展论坛、CMS、商城等功能模块,无需修改框架核心代码。本文将从零开始,带你完整开发一个 FastAdmin 插件。一、插件目录结构一个标准的 FastAdmin 插件目录如下:addons/ └── mydemo/ # 插件目录(插件标识) ├── Mydemo.php # 插件主类 ├── config.php # 插件配置文件 ├── info.ini # 插件信息文件 ├── controller/ │ └── Index.php # 插件控制器 ├── model/ │ └── Demo.php # 插件模型 ├── view/ │ └── index/ │ └── index.html # 插件视图 ├── public/ │ ├── css/ │ │ └── mydemo.css # 插件样式 │ └── js/ │ └── mydemo.js # 插件脚本 └── hooks.php # 钩子定义(可选)二、创建插件2.1 使用命令行创建php think addon -a mydemo -c create这会在 addons/mydemo/ 目录下自动生成插件骨架文件。2.2 info.ini 插件信息name = mydemo title = 示例插件 description = 这是一个 FastAdmin 示例插件 author = Your Name version = 1.0.0 state = 1字段说明name插件标识(目录名,全小写)title插件名称description插件描述author作者version版本号state状态:1=正常,0=禁用2.3 插件主类 Mydemo.php<?php namespace addons\mydemo; use think\Addons; class Mydemo extends Addons { // 插件安装时执行 public function install() { // 创建数据表 $sql = "CREATE TABLE IF NOT EXISTS `fa_mydemo` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `title` varchar(100) NOT NULL DEFAULT '', `content` text, `createtime` int(10) unsigned NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; \think\Db::execute($sql); return true; } // 插件卸载时执行 public function uninstall() { // 删除数据表 \think\Db::execute("DROP TABLE IF EXISTS `fa_mydemo`"); return true; } // 插件启用时执行 public function enable() { return true; } // 插件禁用时执行 public function disable() { return true; } // 钩子:在后台首页显示 public function adminIndexTop($params) { echo '<div class="alert alert-info">欢迎使用 Mydemo 插件!</div>'; } }2.4 config.php 插件配置<?php return [ [ 'name' => 'title', 'title' => '插件标题', 'type' => 'text', 'content' => '', 'value' => 'Mydemo Plugin', 'rule' => 'required', 'msg' => '请填写插件标题', 'tip' => '显示在插件管理页面的标题', ], [ 'name' => 'display_count', 'title' => '显示数量', 'type' => 'number', 'content' => '', 'value' => '10', 'rule' => 'required', 'msg' => '请填写显示数量', 'tip' => '前台显示的数据条数', ], [ 'name' => 'is_open', 'title' => '是否开启', 'type' => 'radio', 'content' => ['0' => '关闭', '1' => '开启'], 'value' => '1', 'rule' => 'required', 'msg' => '', 'tip' => '', ], ];配置在后台 → 插件管理 → 配置 中可编辑,读取方式:$config = get_addon_config('mydemo'); $title = $config['title'];三、插件控制器3.1 后台控制器<?php // addons/mydemo/controller/Index.php namespace addons\mydemo\controller; use app\common\controller\Backend; use think\Db; class Index extends Backend { // 不需要登录的方法 protected $noNeedLogin = []; // 不需要权限验证的方法 protected $noNeedRight = []; /** * 插件后台首页 */ public function index() { $list = Db::name('mydemo')->order('id', 'desc')->paginate(15); $this->view->assign('list', $list); return $this->view->fetch(); } /** * 添加数据 */ public function add() { if ($this->request->isPost()) { $data = $this->request->post('row/a'); $data['createtime'] = time(); Db::name('mydemo')->insert($data); $this->success('添加成功'); } return $this->view->fetch(); } /** * 删除数据 */ public function del($ids = null) { Db::name('mydemo')->where('id', 'in', $ids)->delete(); $this->success('删除成功'); } }3.2 访问路由插件控制器的 URL 格式为:http://yourdomain.com/addons/mydemo/index/index对应:addons - 固定前缀mydemo - 插件标识index - 控制器名index - 方法名3.3 前台控制器<?php // addons/mydemo/controller/Api.php namespace addons\mydemo\controller; use app\common\controller\Api; class Api extends Api { // 不需要登录的方法 protected $noNeedLogin = ['getList']; /** * 获取数据列表(API 接口) */ public function getList() { $count = \think\Db::name('mydemo')->count(); $list = \think\Db::name('mydemo') ->order('id', 'desc') ->limit(10) ->select(); $this->success('获取成功', [ 'total' => $count, 'list' => $list, ]); } }四、钩子机制(Hook)4.1 注册钩子在插件主类中定义钩子方法,方法名即钩子名:// addons/mydemo/Mydemo.php class Mydemo extends Addons { // 钩子:文章详情页底部 public function articleDetailBottom($params) { // $params 是传递的参数 $article = $params['article']; // 输出自定义内容 echo '<div class="mydemo-box">'; echo '<h3>相关推荐</h3>'; echo '</div>'; } // 钩子:后台导航栏 public function adminSidebar($params) { echo '<li><a href="' . addon_url('mydemo/index/index') . '">'; echo '<i class="fa fa-puzzle-piece"></i> <span>Mydemo</span>'; echo '</a></li>'; } }4.2 触发钩子在任意位置触发钩子:// 传递参数给钩子 \think\Hook::listen('article_detail_bottom', ['article' => $article]);4.3 FastAdmin 内置常用钩子钩子名触发位置参数admin_index_top后台首页顶部无admin_sidebar后台左侧菜单无article_detail_bottom文章详情底部article 数据user_register_after用户注册后user 数据config_init配置初始化配置数组五、插件打包发布5.1 打包# 将插件目录打包为 zip cd addons zip -r mydemo.zip mydemo/注意:打包时不要包含 runtime、temp 等临时目录。5.2 发布到插件市场注册 FastAdmin 官网账号进入"开发者中心"点击"发布插件"上传 zip 包,填写插件信息等待审核通过5.3 版本更新更新 info.ini 中的版本号后重新打包上传,用户可在后台一键升级。六、调试技巧6.1 开启插件调试// application/config.php 'app_debug' => true; // 确保插件目录有读写权限 chmod -R 755 addons/mydemo/6.2 查看插件日志// 在插件代码中记录日志 \think\Log::info('Mydemo: ' . json_encode($data)); // 查看日志 // runtime/log/202607/24.log6.3 热更新开发阶段修改插件代码后,清除缓存即可生效:php think clear --type=cache php think clear --type=temp七、完整插件开发流程1. php think addon -a mydemo -c create → 创建骨架 2. 编辑 info.ini → 填写插件信息 3. 编辑 Mydemo.php → 实现安装/卸载/钩子 4. 编辑 config.php → 定义插件配置项 5. 编写 controller/ → 实现业务逻辑 6. 编写 view/ → 编写视图模板 7. 编写 public/ → 添加前端资源 8. 后台安装插件 → 测试 → 调试 9. 打包 zip → 发布总结FastAdmin 插件系统通过目录约定 + 钩子机制实现了松耦合的功能扩展。核心要点:插件主类继承 think\Addons,实现 install/uninstall 生命周期通过 config.php 定义可视化配置项通过 Hook::listen() 在框架任意位置触发钩子插件可以有自己的 MVC 结构,独立于主应用
2026年03月28日
36 阅读
0 评论
0 点赞
2026-03-26
FastAdmin 权限认证体系:RBAC 角色与菜单管理
前言FastAdmin 内置了完整的 RBAC(基于角色的访问控制)权限体系,支持细粒度的菜单管理、操作权限和数据权限控制。本文将深入讲解 FastAdmin 权限认证的工作原理和实际配置方法。一、RBAC 权限模型概述FastAdmin 的权限体系包含三个核心实体:管理员(Admin)──→ 角色组(Group)──→ 权限规则(Rule)实体数据表说明管理员fa_admin后台用户,每个用户属于一个或多个角色组角色组fa_group角色定义,每个角色关联一组权限规则权限规则fa_auth_rule权限节点,对应控制器的每个操作方法二、权限认证流程2.1 认证类 AuthFastAdmin 的权限认证由 application/common/library/Auth.php 实现:namespace app\common\library; use think\Session; use think\Cookie; use app\admin\model\Admin as AdminModel; class Auth { protected $logined = false; // 是否登录 protected $admin = null; // 当前管理员信息 protected $error = ''; // 错误信息 protected $requestUri = ''; // 当前请求 URL // 检查是否已登录 public function isLogin() { if ($this->logined) { return true; } $admin = Session::get('admin'); if (!$admin) { return false; } // 验证管理员状态 $this->admin = AdminModel::get($admin['id']); if (!$this->admin || $this->admin['status'] != 'normal') { return false; } $this->logined = true; return true; } // 检查权限 public function check($name = '') { if (!$this->isLogin()) { return false; } // 超级管理员直接通过 if ($this->admin['id'] == 1) { return true; } // 获取当前用户的所有权限规则 $rules = $this->getRuleList(); if (!$name) { $name = strtolower($this->request->module() . '/' . $this->request->controller() . '/' . $this->request->action()); } $name = strtolower($name); // 检查是否有匹配的权限 foreach ($rules as $rule) { if ($this->checkRule($rule, $name)) { return true; } } return false; } }2.2 权限检查链路请求进入 → Backend 控制器初始化 → Auth::check() 检查当前 URL 是否有权限 → 无权限 → 返回 403 / 跳转登录 → 有权限 → 继续执行2.3 控制器中的权限注解FastAdmin 通过注解方式声明权限节点:// application/admin/controller/content/Article.php namespace app\admin\controller\content; use app\common\controller\Backend; class Article extends Backend { // 默认不需要登录的方法 protected $noNeedLogin = []; // 默认不需要权限验证的方法 protected $noNeedRight = []; /** * 文章列表 */ public function index() { return parent::index(); } /** * 添加文章 */ public function add() { return parent::add(); } /** * 编辑文章 */ public function edit($ids = null) { return parent::edit($ids); } /** * 删除文章 */ public function del($ids = null) { return parent::del($ids); } }每个 public 方法自动注册为一个权限节点,格式为 content/article/index。三、菜单管理3.1 菜单结构菜单存储在 fa_auth_rule 表中,采用树形结构:-- 查看菜单结构 SELECT id, pid, name, title, type FROM fa_auth_rule ORDER BY weigh DESC;字段说明id节点 IDpid父节点 ID(0 为顶级)name权限规则名(URL 路径)title菜单显示名称type类型:menu=菜单,file=操作节点icon菜单图标(FontAwesome)ismenu是否在左侧菜单显示(1=显示)3.2 命令行生成菜单# 根据控制器自动生成菜单 php think menu -c content/article # 强制覆盖 php think menu -c content/article -f 13.3 后台手动管理菜单进入 后台 → 权限管理 → 菜单规则,可以:添加/编辑/删除菜单节点拖拽排序设置菜单图标控制菜单是否显示3.4 菜单与权限的关系菜单规则(fa_auth_rule) ├── 内容管理 (ismenu=1, type=menu) │ ├── 文章管理 (ismenu=1, type=menu) │ │ ├── 查看 (ismenu=0, type=file) → content/article/index │ │ ├── 添加 (ismenu=0, type=file) → content/article/add │ │ ├── 编辑 (ismenu=0, type=file) → content/article/edit │ │ └── 删除 (ismenu=0, type=file) → content/article/delismenu=1 的节点显示在左侧导航栏,ismenu=0 的是操作按钮权限。四、角色组管理4.1 创建角色组进入 后台 → 权限管理 → 角色组:点击"添加"填写角色名称(如"内容编辑")勾选该角色拥有的权限保存4.2 角色权限继承角色组支持树形结构,子角色自动继承父角色的所有权限:超级管理员(id=1,拥有所有权限) ├── 内容主管(拥有内容管理全部权限) │ ├── 内容编辑(拥有文章增改权限,无删除权限) │ └── 内容审核(拥有文章审核权限) └── 系统管理员(拥有系统设置权限)4.3 数据权限FastAdmin 支持基于角色组的数据隔离:// 在控制器中启用数据权限 public function index() { // 只能查看自己创建的数据 $this->dataLimit = 'personal'; // 只能查看本角色组的数据 $this->dataLimit = 'auth'; // 自定义数据限制字段 $this->dataLimitField = 'admin_id'; return parent::index(); }数据权限模式说明:模式说明null不限制,可查看所有数据personal只能查看自己创建的数据auth只能查看本角色组及子角色组的数据五、API Token 认证除了后台 Session 认证,FastAdmin 的 API 模块支持 Token 认证:5.1 Token 生成// application/api/controller/User.php namespace app\api\controller; use app\common\controller\Api; use app\common\library\Token; class User extends Api { // 登录获取 Token public function login() { $username = $this->request->post('username'); $password = $this->request->post('password'); $admin = \app\admin\model\Admin::get(['username' => $username]); if (!$admin || $admin->password != md5(md5($password) . $admin->salt)) { $this->error('用户名或密码错误'); } // 生成 Token $token = Token::create($admin['id'], 'admin', 86400 * 7); $this->success('登录成功', [ 'token' => $token, 'admin' => $admin, ]); } }5.2 Token 验证中间件// API 请求头携带 Token // Authorization: Bearer xxx-xxx-xxx // 在 API 控制器中验证 namespace app\api\controller; class Order extends Api { // 需要登录的方法 protected $noNeedLogin = []; public function list() { // $this->auth 已自动初始化 $adminId = $this->auth->id; $orders = model('Order')->where('admin_id', $adminId)->select(); $this->success('获取成功', $orders); } }六、安全加固建议6.1 密码安全// FastAdmin 使用双重 MD5 加盐 // password = md5(md5(明文密码) . salt) // 自定义更安全的加密方式 \app\admin\model\Admin::event('before_insert', function ($admin) { $admin->salt = \fast\Random::alnum(8); $admin->password = password_hash($admin->password, PASSWORD_BCRYPT); });6.2 登录失败限制FastAdmin 默认 5 次登录失败后锁定 15 分钟,可在配置中调整:// application/extra/site.php 'login_failure_retry' => 5, // 最大失败次数 'login_failure_lock' => 900, // 锁定时间(秒)6.3 操作日志所有后台操作自动记录到 fa_admin_log 表:// 手动记录日志 \app\admin\model\AdminLog::record([ 'title' => '手动操作文章', 'content' => '修改了文章ID:' . $id, ]);总结FastAdmin 的权限体系基于标准 RBAC 模型,通过菜单规则表实现细粒度权限控制。核心要点:权限规则对应控制器的每个方法,自动注册角色组支持树形继承,子角色继承父角色权限数据权限支持 personal 和 auth 两种模式API 模块通过 Token 实现无状态认证
2026年03月26日
7 阅读
0 评论
0 点赞
2026-03-22
FastAdmin CRUD 代码生成器使用指南:一键生成增删改查
前言FastAdmin 的 CRUD 代码生成器是框架最核心的功能之一——只需要一条命令,就能根据数据库表结构自动生成控制器、模型、视图、JS、验证器和菜单,实现完整的增删改查。本文将全面讲解 CRUD 生成器的使用方法和进阶技巧。一、基础用法1.1 准备数据表先创建一张示例表:CREATE TABLE `fa_article` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', `title` varchar(100) NOT NULL DEFAULT '' COMMENT '标题', `content` text COMMENT '内容', `category_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '分类ID', `author` varchar(50) NOT NULL DEFAULT '' COMMENT '作者', `status` enum('normal','hidden') NOT NULL DEFAULT 'normal' COMMENT '状态', `views` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '浏览量', `createtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间', `updatetime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文章表';1.2 一键生成 CRUDphp think crud -t fa_article -c content/article参数说明:参数说明-t数据表名(带前缀)-c控制器路径,格式为 模块/控制器执行后自动生成以下文件:application/admin/controller/content/Article.php application/admin/model/Article.php application/admin/validate/Article.php application/admin/view/content/article/index.html application/admin/view/content/article/add.html application/admin/view/content/article/edit.html application/admin/view/content/article/recyclebin.html public/assets/js/backend/content/article.js1.3 生成菜单php think menu -c content/article执行后在后台菜单管理中会自动出现"文章管理"菜单。二、字段注释驱动生成FastAdmin 的 CRUD 生成器会读取数据库字段注释来决定前端控件的渲染方式。这是最强大的特性之一:2.1 字段注释格式`status` enum('normal','hidden') NOT NULL DEFAULT 'normal' COMMENT '状态:normal=正常,hidden=隐藏'生成器会解析注释中的 normal=正常,hidden=隐藏,自动渲染为下拉选择框:<select class="form-control selectpicker" name="status"> <option value="normal">正常</option> <option value="hidden">隐藏</option> </select>2.2 常用字段类型映射数据库字段类型自动生成的控件varchar文本输入框text富文本编辑器int(含 time 关键字)日期时间选择器enum下拉选择框decimal数字输入框date日期选择器2.3 特殊字段名约定FastAdmin 对特定字段名有特殊处理:字段名自动行为createtime / updatetime自动维护创建/更新时间status列表页显示状态切换按钮weigh自动添加拖拽排序功能image / images自动生成图片上传组件file / files自动生成文件上传组件ids生成多选关联组件三、进阶用法3.1 关联模型生成如果表中有外键字段,可以通过命名约定自动生成关联:-- 主表 CREATE TABLE `fa_category` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 从表 CREATE TABLE `fa_article` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `title` varchar(100) NOT NULL DEFAULT '', `category_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '分类ID', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;在模型中定义关联:// application/admin/model/Article.php namespace app\admin\model; use think\Model; class Article extends Model { // 关联分类 public function category() { return $this->belongsTo('Category', 'category_id', 'id'); } }在控制器中启用关联查询:// application/admin/controller/content/Article.php public function index() { $this->relationSearch = true; $this->searchFields = 'id,title,category.name'; // 设置关联 $this->with = ['category']; return parent::index(); }3.2 强制覆盖生成php think crud -t fa_article -c content/article -f 1-f 1 参数会覆盖已存在的文件,适合修改表结构后重新生成。3.3 删除生成的文件php think crud -t fa_article -c content/article -d 1-d 1 参数会删除该表对应的所有 CRUD 文件。四、自定义模板4.1 修改生成模板CRUD 模板位于 extend/fast/crud/tpl/ 目录:extend/fast/crud/tpl/ ├── controller.tpl # 控制器模板 ├── model.tpl # 模型模板 ├── validate.tpl # 验证器模板 ├── index.tpl # 列表视图模板 ├── add.tpl # 添加视图模板 ├── edit.tpl # 编辑视图模板 └── javascript.tpl # JS 模板4.2 自定义列表字段显示在 JS 文件中控制列表列的显示:// public/assets/js/backend/content/article.js define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) { var Controller = { index: function () { Table.init({ extend: { index_url: 'content/article/index', add_url: 'content/article/add', edit_url: 'content/article/edit', del_url: 'content/article/del', table: 'article', } }); var table = $("#table"); // 初始化表格 table.bootstrapTable({ url: $.extend({}, Table.config.url), columns: [ [ {checkbox: true}, {field: 'id', title: __('Id')}, {field: 'title', title: __('Title')}, {field: 'category.name', title: __('Category')}, {field: 'author', title: __('Author')}, {field: 'status', title: __('Status'), searchList: {"normal": __('Normal'), "hidden": __('Hidden')}, formatter: Table.api.formatter.status}, {field: 'views', title: __('Views')}, {field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime}, {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate} ] ] }); Table.api.bindevent(table); }, add: function () { Controller.api.bindevent(); }, edit: function () { Controller.api.bindevent(); }, api: { bindevent: function () { Form.api.bindevent($("form[role=form]")); } } }; return Controller; });五、CRUD 常用参数汇总参数说明示例-t数据表名(带前缀)-t fa_user-c控制器路径-c user/index-f强制覆盖-f 1-d删除生成文件-d 1-o输出文件路径-o /tmp/crud-uURL 绑定的模型-u model_name--local不调用远程 API--local=1六、最佳实践先设计表结构再生成:字段注释直接决定生成质量,务必写清楚生成后不要改生成的文件名:保持命名一致性,便于重新生成自定义逻辑在生成文件基础上修改:先 php think crud 生成骨架,再手动添加业务逻辑修改表结构后重新生成:用 -f 1 覆盖,但注意备份自定义代码善用关联搜索:$this->relationSearch = true 可以快速实现跨表搜索总结FastAdmin CRUD 生成器的核心思想是"约定优于配置"——通过数据库字段注释驱动代码生成,大幅减少重复劳动。掌握字段注释规范和关联模型用法后,90% 的后台增删改查功能可以在几分钟内完成。
2026年03月22日
11 阅读
0 评论
0 点赞
2026-03-20
FastAdmin 框架入门:安装配置与目录结构详解
前言FastAdmin 是一款基于 ThinkPHP 5.x 和 Bootstrap 的极速后台开发框架,凭借其强大的代码生成器和零配置上手的特点,在国内开发者群体中广受欢迎。本文将从安装配置开始,系统讲解 FastAdmin 的目录结构与核心概念。一、环境要求PHP >= 7.1(推荐 7.4+)MySQL >= 5.6(推荐 5.7+)Nginx / Apache / IISComposer二、安装步骤2.1 通过 Git 安装# 克隆项目 git clone https://gitee.com/karson/fastadmin.git # 进入目录 cd fastadmin # 安装依赖 composer install2.2 通过完整包安装从 FastAdmin 官网下载完整包,解压到 Web 目录即可。2.3 配置数据库编辑 application/database.php:return [ 'type' => 'mysql', 'hostname' => '127.0.0.1', 'database' => 'fastadmin', 'username' => 'root', 'password' => 'your_password', 'hostport' => '3306', 'prefix' => 'fa_', 'charset' => 'utf8mb4', ];2.4 导入初始数据库mysql -u root -p fastadmin < fastadmin.sql2.5 配置伪静态(Nginx)location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php/$1 last; break; } }2.6 访问安装浏览器访问 http://yourdomain.com/install.php,按提示完成安装后删除该文件。三、目录结构详解fastadmin/ ├── application/ # 应用目录 │ ├── admin/ # 后台模块 │ │ ├── controller/ # 后台控制器 │ │ ├── model/ # 后台模型 │ │ ├── view/ # 后台视图 │ │ └── validate/ # 验证器 │ ├── api/ # API 模块 │ │ ├── controller/ │ │ └── model/ │ ├── common/ # 公共模块 │ │ ├── model/ # 公共模型 │ │ └── library/ # 扩展类库 │ ├── index/ # 前台模块 │ ├── extra/ # 扩展配置 │ ├── command.php # 命令行配置 │ ├── database.php # 数据库配置 │ └── config.php # 全局配置 ├── public/ # Web 根目录 │ ├── assets/ # 静态资源 │ │ ├── js/backend/ # 后台 JS │ │ ├── css/ # 样式文件 │ │ └── libs/ # 前端库 │ ├── index.php # 入口文件 │ └── install.php # 安装文件(用后删除) ├── addons/ # 插件目录 ├── extend/ # 扩展类库 ├── runtime/ # 运行时缓存 ├── vendor/ # Composer 依赖 └── think # 命令行入口核心目录说明目录作用application/admin后台管理模块,所有后台控制器、模型、视图都在这里application/apiAPI 接口模块,用于前后端分离开发application/common/library框架核心类库,包含 Auth 权限认证、Token 等public/assets/js/backend后台各模块对应的 JS 文件,采用 RequireJS 模块化加载addons在线安装的插件存放目录四、核心概念4.1 模块化设计FastAdmin 采用多模块设计,默认包含 admin、api、index 三个模块:// application/admin/controller/Example.php namespace app\admin\controller; use app\common\controller\Backend; class Example extends Backend { // 自动继承后台基础控制器 // 拥有权限认证、菜单管理、CRUD 等能力 }4.2 权限认证(Auth)FastAdmin 内置基于 RBAC 的权限认证体系:// 检查当前用户是否有某权限 if (!$this->auth->check('example/index')) { $this->error('您没有权限'); } // 获取当前登录用户 $admin = $this->auth->getUser();4.3 一键 CRUDFastAdmin 最强大的功能是代码生成器,通过命令行一键生成控制器、模型、视图、JS:# 生成一个完整的 CRUD php think crud -t fa_user -c my/user # 参数说明 # -t 指定数据表 # -c 指定控制器路径(模块/控制器)生成的文件包括:application/admin/controller/my/User.php # 控制器 application/admin/model/User.php # 模型 application/admin/validate/User.php # 验证器 application/admin/view/my/user/index.html # 列表视图 application/admin/view/my/user/add.html # 添加视图 application/admin/view/my/user/edit.html # 编辑视图 public/assets/js/backend/my/user.js # 前端 JS五、配置优化建议5.1 修改默认密码安装后立即修改默认管理员密码(默认 admin/123456):# 后台 → 个人信息 → 修改密码5.2 关闭调试模式生产环境关闭调试:// application/config.php 'app_debug' => false, 'app_trace' => false,5.3 设置域名根目录Nginx 配置 root 指向 public 目录:server { listen 80; server_name admin.example.com; root /var/www/fastadmin/public; index index.php; location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php/$1 last; } } location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }六、常见问题Q: 安装后访问首页 404?检查伪静态配置,确保 Nginx/Apache 的 rewrite 规则正确。Q: 后台菜单不显示?执行 php think menu -c controller_name 生成菜单。Q: 在线安装插件失败?检查 addons 目录权限,确保 Web 进程可写:chmod -R 755 addons/总结FastAdmin 通过模块化设计 + 代码生成器大幅提升了后台开发效率。掌握目录结构和核心概念后,配合 CRUD 命令,可以在几分钟内搭建出一个功能完整的后台管理系统。后续文章将深入讲解 CRUD 生成器、权限体系和插件开发。
2026年03月20日
10 阅读
0 评论
0 点赞
1
2
0:00