--- description: FastAdmin 管理后台规范:CRUD 控制器、视图、语言包、前端表格 JS globs: backend/application/admin/**,backend/public/assets/js/backend/** alwaysApply: false --- # FastAdmin 管理后台规范 ## 新增模块 1. 先建表(`fa_` 前缀,`createtime`/`updatetime` 为 int,枚举字段 COMMENT 写成 `状态:0=关闭,1=招标中`) 2. 用命令生成骨架,再在生成结果上修改:`php think crud -t demands -u 1`,菜单 `php think menu -c demands` 3. 一个模块对应四处文件,命名保持一致: - 控制器 `admin/controller/[子目录/]Demands.php` - 视图 `admin/view/[子目录/]demands/{index,add,edit}.html` - 语言包 `admin/lang/zh-cn/[子目录/]demands.php`(字段名、`Status 1` 等枚举文案) - 表格 JS `public/assets/js/backend/[子目录/]demands.js` ## 控制器 - 继承 `app\common\controller\Backend`;在 `_initialize()` 中实例化 `$this->model`(使用 `app\common\model` 下的模型)并 `assign` 各 `xxxList` - 默认 `index/add/edit/del/multi` 由 trait 提供,只有需要定制时才覆盖;覆盖时以 `admin/library/traits/Backend.php` 中原方法为蓝本 - 关联查询覆盖 `index()`:`$this->relationSearch = true`,`->with([...])`,并用 `visible()` 限定关联字段 - 保存时用 `$this->model->allowField(true)->save($params)`,入参先经 `preExcludeFields()` - 自定义操作(审核、重新投标、取消等): ```php public function audit($ids) { $row = $this->model->get($ids); if (!$row) { $this->error(__('No Results were found')); } if ($this->request->isAjax()) { try { DemandService::auditPass($ids); } catch (\Exception $e) { $this->error($e->getMessage()); } $this->success('审核成功'); } $this->view->assign('row', $row->toArray()); return $this->view->fetch(); } ``` - 业务流程(资金、状态流转、通知)必须调用 `common/service`,与 API 共用同一套逻辑,不在后台控制器里重写 - `$this->success()` 放在 try 外,或在 catch 中对 `HttpResponseException` 原样抛出 - 新增自定义方法后需在权限菜单中添加对应节点,否则非超管无权限 ## 表格 JS - 使用 `define([... 'table', 'form'], ...)` + `Table.api.init({ extend: {...} })`,列文案一律 `__('Field')` - 枚举列 `searchList` 与模型 `getXxxList()` 保持一致,配合 `Table.api.formatter.status/normal` - 自定义按钮放在 `operate` 列的 `buttons` 中,弹窗用 `btn-dialog`,Ajax 用 `btn-ajax` 并带 `confirm` - 表单页调用 `Controller.api.bindevent()` → `Form.api.bindevent($("form[role=form]"))` ## 视图 - 表单字段名使用 `row[field]`;图片/文件使用 FastAdmin 的 `faupload` 组件 - 不在模板内写业务判断,下拉选项使用控制器 assign 的 `xxxList`