## 思路
一:將每一個控制器方法上放一個注釋說明
二:循環遍歷所有模塊兒及下邊每一個控制器的方法
二:用 `Annotations` 將每一個方法讀出并寫入到`auth_rule`
## 代碼
```
<?php
namespace app\agent\controller;
use think\Controller;
use think\Db;
use mindplay\annotations\Annotations;
class MenuController extends Controller
{
/**
* agent測試
* @adminMenu(
* 'name' => '鉤子管理',
* 'parent' => 'admin/Plugin/default',
* 'display'=> true,
* 'hasView'=> true,
* 'order' => 10000,
* 'icon' => '',
* 'remark' => 'agent測試描述',
* 'param' => ''
* )
*/
public function getActions()
{
Annotations::$config['cache'] = false;
$annotationManager = Annotations::getManager();
$annotationManager->registry['adminMenu'] = 'app\agent\annotation\AdminMenuAnnotation';
$annotationManager->registry['adminMenuRoot'] = 'app\agent\annotation\AdminMenuRootAnnotation';
$newMenus = [];
$apps = cmf_scan_dir(APP_PATH . '*', GLOB_ONLYDIR);
$app = $this->request->param('app', '');
if (empty($app)) {
$app = $apps[0];
}
if (!in_array($app, $apps)) {
$this->error('應用' . $app . '不存在!');
}
if ($app == 'agent') {
$filePatten = APP_PATH . $app . '/controller/*Controller.php';
} else {
$filePatten = APP_PATH . $app . '/controller/Admin*Controller.php';
}
$controllers = cmf_scan_dir($filePatten);
if (!empty($controllers)) {
foreach ($controllers as $controller) {
$controller = preg_replace('/\.php$/', '', $controller);
$controllerName = preg_replace('/\Controller$/', '', $controller);
$controllerClass = "app\\$app\\controller\\$controller";
$menuAnnotations = Annotations::ofClass($controllerClass, '@adminMenuRoot');
if (!empty($menuAnnotations)) {
foreach ($menuAnnotations as $menuAnnotation) {
$name = $menuAnnotation->name;
$icon = $menuAnnotation->icon;
$type = 0;//1:有界面可訪問菜單,2:無界面可訪問菜單,0:只作為菜單
$action = $menuAnnotation->action;
$status = empty($menuAnnotation->display) ? 0 : 1;
$listOrder = floatval($menuAnnotation->order);
$param = $menuAnnotation->param;
$remark = $menuAnnotation->remark;
if (empty($menuAnnotation->parent)) {
$parentId = 0;
} else {
$parent = explode('/', $menuAnnotation->parent);
$countParent = count($parent);
if ($countParent > 3) {
throw new \Exception($controllerClass . ':' . $action . ' @adminMenuRoot parent格式不正確!');
}
$parentApp = $app;
$parentController = $controllerName;
$parentAction = '';
switch ($countParent) {
case 1:
$parentAction = $parent[0];
break;
case 2:
$parentController = $parent[0];
$parentAction = $parent[1];
break;
case 3:
$parentApp = $parent[0];
$parentController = $parent[1];
$parentAction = $parent[2];
break;
}
$findParentAdminMenu = Db::name('admin_menu')->where([
'app' => $parentApp,
'controller' => $parentController,
'action' => $parentAction
])->find();
if (empty($findParentAdminMenu)) {
$parentId = Db::name('admin_menu')->insertGetId([
'app' => $parentApp,
'controller' => $parentController,
'action' => $parentAction,
'name' => '--new--'
]);
} else {
$parentId = $findParentAdminMenu['id'];
}
}
$findAdminMenu = Db::name('admin_menu')->where([
'app' => $app,
'controller' => $controllerName,
'action' => $action
])->find();
if (empty($findAdminMenu)) {
Db::name('admin_menu')->insert([
'parent_id' => $parentId,
'type' => $type,
'status' => $status,
'list_order' => $listOrder,
'app' => $app,
'controller' => $controllerName,
'action' => $action,
'param' => $param,
'name' => $name,
'icon' => $icon,
'remark' => $remark
]);
$menuName = $name;
array_push($newMenus, "$app/$controllerName/$action 已導入");
} else {
if ($findAdminMenu['name'] == '--new--') {
Db::name('admin_menu')->where([
'app' => $app,
'controller' => $controllerName,
'action' => $action
])->update([
'parent_id' => $parentId,
'type' => $type,
'status' => $status,
'list_order' => $listOrder,
'param' => $param,
'name' => $name,
'icon' => $icon,
'remark' => $remark
]);
$menuName = $name;
} else {
// 只關注菜單層級關系,是否有視圖
Db::name('admin_menu')->where([
'app' => $app,
'controller' => $controllerName,
'action' => $action
])->update([
'parent_id' => $parentId,
'type' => $type,
]);
$menuName = $findAdminMenu['name'];
}
array_push($newMenus, "$app/$controllerName/$action 層級關系已更新");
}
$authRuleName = "{$app}/{$controllerName}/{$action}";
$findAuthRuleCount = Db::name('auth_rule')->where([
'app' => $app,
'name' => $authRuleName,
'type' => 'admin_url'
])->count();
if ($findAuthRuleCount == 0) {
Db::name('auth_rule')->insert([
'app' => $app,
'name' => $authRuleName,
'type' => 'admin_url',
'param' => $param,
'title' => $menuName
]);
} else {
Db::name('auth_rule')->where([
'app' => $app,
'name' => $authRuleName,
'type' => 'admin_url',
])->update([
'param' => $param,
'title' => $menuName
]);
}
}
}
$reflect = new \ReflectionClass($controllerClass);
$methods = $reflect->getMethods(\ReflectionMethod::IS_PUBLIC);
if (!empty($methods)) {
foreach ($methods as $method) {
if ($method->class == $controllerClass && strpos($method->name, '_') !== 0) {
$menuAnnotations = Annotations::ofMethod($controllerClass, $method->name, '@adminMenu');
if (!empty($menuAnnotations)) {
$menuAnnotation = $menuAnnotations[0];
$name = $menuAnnotation->name;
$icon = $menuAnnotation->icon;
$type = $menuAnnotation->hasView ? 1 : 2;//1:有界面可訪問菜單,2:無界面可訪問菜單,0:只作為菜單
$action = $method->name;
$status = empty($menuAnnotation->display) ? 0 : 1;
$listOrder = floatval($menuAnnotation->order);
$param = $menuAnnotation->param;
$remark = $menuAnnotation->remark;
if (empty($menuAnnotation->parent)) {
$parentId = 0;
} else {
$parent = explode('/', $menuAnnotation->parent);
$countParent = count($parent);
if ($countParent > 3) {
throw new \Exception($controllerClass . ':' . $action . ' @menuRoot parent格式不正確!');
}
$parentApp = $app;
$parentController = $controllerName;
$parentAction = '';
switch ($countParent) {
case 1:
$parentAction = $parent[0];
break;
case 2:
$parentController = $parent[0];
$parentAction = $parent[1];
break;
case 3:
$parentApp = $parent[0];
$parentController = $parent[1];
$parentAction = $parent[2];
break;
}
$findParentAdminMenu = Db::name('admin_menu')->where([
'app' => $parentApp,
'controller' => $parentController,
'action' => $parentAction
])->find();
if (empty($findParentAdminMenu)) {
$parentId = Db::name('admin_menu')->insertGetId([
'app' => $parentApp,
'controller' => $parentController,
'action' => $parentAction,
'name' => '--new--'
]);
} else {
$parentId = $findParentAdminMenu['id'];
}
}
$findAdminMenu = Db::name('admin_menu')->where([
'app' => $app,
'controller' => $controllerName,
'action' => $action
])->find();
if (empty($findAdminMenu)) {
Db::name('admin_menu')->insert([
'parent_id' => $parentId,
'type' => $type,
'status' => $status,
'list_order' => $listOrder,
'app' => $app,
'controller' => $controllerName,
'action' => $action,
'param' => $param,
'name' => $name,
'icon' => $icon,
'remark' => $remark
]);
$menuName = $name;
array_push($newMenus, "$app/$controllerName/$action 已導入");
} else {
if ($findAdminMenu['name'] == '--new--') {
Db::name('admin_menu')->where([
'app' => $app,
'controller' => $controllerName,
'action' => $action
])->update([
'parent_id' => $parentId,
'type' => $type,
'status' => $status,
'list_order' => $listOrder,
'param' => $param,
'name' => $name,
'icon' => $icon,
'remark' => $remark
]);
$menuName = $name;
} else {
// 只關注菜單層級關系,是否有視圖
Db::name('admin_menu')->where([
'app' => $app,
'controller' => $controllerName,
'action' => $action
])->update([
'parent_id' => $parentId,
'type' => $type,
]);
$menuName = $findAdminMenu['name'];
}
array_push($newMenus, "$app/$controllerName/$action 已更新");
}
$authRuleName = "{$app}/{$controllerName}/{$action}";
$findAuthRuleCount = Db::name('auth_rule')->where([
'app' => $app,
'name' => $authRuleName,
'type' => 'admin_url'
])->count();
if ($findAuthRuleCount == 0) {
Db::name('auth_rule')->insert([
'app' => $app,
'name' => $authRuleName,
'type' => 'admin_url',
'param' => $param,
'title' => $menuName
]);
} else {
Db::name('auth_rule')->where([
'app' => $app,
'name' => $authRuleName,
'type' => 'admin_url',
])->update([
'param' => $param,
'title' => $menuName
]);
}
}
}
}
}
}
}
$index = array_search($app, $apps);
$nextIndex = $index + 1;
$nextIndex = $nextIndex >= count($apps) ? 0 : $nextIndex;
if ($nextIndex) {
$this->assign("next_app", $apps[$nextIndex]);
}
$this->assign("app", $app);
$this->assign("new_menus", $newMenus);
return $this->fetch();
}
}
```
- 附錄
- 邏輯與數據模型
- HTML約定-bootstrap
- HTML約定-LayUI
- 角色管理 role
- 數據表
- 列表
- 控制器
- 視圖
- 視圖-layui
- 角色添加
- 控制器
- 視圖
- 角色添加提交
- 控制器
- 驗證
- 角色修改
- 控制器
- 視圖
- 角色修改提交
- 控制器
- 角色刪除
- 控制器
- 權限設置
- 控制器
- 視圖
- 模型
- 權限設置提交
- 用戶 user
- 數據表
- 列表
- 控制器
- 視圖
- 模型
- 添加
- 控制器
- 視圖
- 添加提交
- 控制器
- 驗證器
- 編輯
- 控制器
- 視圖
- 編輯提交
- 控制器
- 驗證器
- 刪除
- 停用啟用
- 角色用戶中間表role_user
- 菜單管理
- 數據表
- 表格折疊列表
- 控制器
- 視圖
- 全部列表
- 控制器
- 視圖
- 填加
- 控制器
- 視圖
- 填加提交
- 控制器
- 驗證器
- 編輯
- 控制器
- 視圖
- 編輯提交
- 控制器
- 驗證器
- 刪除
- 控制器
- 視圖
- 導入菜單
- 視圖
- 控制器
- 特別注意
- annotation
- 導出菜單
- 視圖
- 控制器
- 排序
- 控制器
- 視圖
- 模型