# 菜单注册: {{Entity}}

> 模块: {{module}} | 实体: {{Entity}} | 组件路径: `{{domain}}/{{entity}}/index`

---

## 1. 菜单配置

| 配置项 | 值 | 说明 |
|--------|-----|------|
| 菜单名称 | {{moduleName}} | 显示在侧边栏的名称 |
| 父级菜单 | 根据实际选择 | c_sys_resource.pid |
| 排序 | 100 | 同级菜单排序 |
| 图标 | ios-folder | ViewUI 图标名称 |
| 路由路径 | /{{domain}}/{{entity}} | 前端路由 |
| 组件路径 | {{domain}}/{{entity}}/index | Vue 组件路径（相对 src/views/） |

---

## 2. c_sys_resource 表结构

| 字段 | 类型 | 说明 |
|------|------|------|
| id | bigint | 主键（雪花算法） |
| title | varchar | 菜单/按钮显示名称 |
| pid | bigint | 父级 ID（0 = 顶级） |
| sort | int | 排序号 |
| enable | int | 1=启用 |
| type | int | 1=路由菜单, 2=按钮权限, 3=API 资源 |
| path | varchar | URL 路径 |
| component | varchar | Vue 组件路径 |
| icon | varchar | 图标 |
| permission | varchar | 权限标识 |

---

## 3. SQL 插入语句

```sql
-- ============================================================
-- 菜单注册（c_sys_resource）
-- ============================================================

-- 1. 菜单项（type=1 路由菜单）
-- 请先确认父级菜单 ID（替换下面的 @parentId）
-- 可通过 SELECT id FROM c_sys_resource WHERE title = '父级菜单名' 获取

INSERT INTO c_sys_resource (id, title, pid, sort, enable, type, path, component, icon, permission, created_by, created_date, last_updated_by, last_updated_date)
VALUES (
  -- id: 使用雪花算法生成，或手动指定一个不冲突的大数字
  {{menu_id}},                    -- 菜单 ID（需唯一）
  '{{moduleName}}',               -- 菜单名称
  {{parent_id}},                  -- 父级菜单 ID（0=顶级）
  100,                            -- 排序号
  1,                              -- 启用
  1,                              -- type=1 路由菜单
  '/{{domain}}/{{entity}}',       -- 路由路径
  '{{domain}}/{{entity}}/index',  -- 组件路径
  'ios-folder',                   -- 图标
  '{{module}}:{{entity}}:view',   -- 权限标识
  'admin',
  SYSTIMESTAMP,
  'admin',
  SYSTIMESTAMP
);

-- 2. 按钮权限（type=2 按钮）
-- @menuId 替换为上面插入的菜单 ID

INSERT INTO c_sys_resource (id, title, pid, sort, enable, type, path, component, icon, permission, created_by, created_date, last_updated_by, last_updated_date)
VALUES
-- 查询按钮
({{menu_id}} + 1, '{{moduleName}}查询', {{menu_id}}, 1, 1, 2, '#', '', '', '{{module}}:{{entity}}:view', 'admin', SYSTIMESTAMP, 'admin', SYSTIMESTAMP),
-- 新增按钮
({{menu_id}} + 2, '{{moduleName}}新增', {{menu_id}}, 2, 1, 2, '#', '', '', '{{module}}:{{entity}}:add', 'admin', SYSTIMESTAMP, 'admin', SYSTIMESTAMP),
-- 修改按钮
({{menu_id}} + 3, '{{moduleName}}修改', {{menu_id}}, 3, 1, 2, '#', '', '', '{{module}}:{{entity}}:edit', 'admin', SYSTIMESTAMP, 'admin', SYSTIMESTAMP),
-- 删除按钮
({{menu_id}} + 4, '{{moduleName}}删除', {{menu_id}}, 4, 1, 2, '#', '', '', '{{module}}:{{entity}}:delete', 'admin', SYSTIMESTAMP, 'admin', SYSTIMESTAMP),
-- 导出按钮
({{menu_id}} + 5, '{{moduleName}}导出', {{menu_id}}, 5, 1, 2, '#', '', '', '{{module}}:{{entity}}:export', 'admin', SYSTIMESTAMP, 'admin', SYSTIMESTAMP);
```

---

## 4. 权限标识

| 权限标识 | 描述 | 前端使用方式 |
|---------|------|-------------|
| `{{module}}:{{entity}}:view` | 查看 | `v-hasPerm="'{{module}}:{{entity}}:view'"` |
| `{{module}}:{{entity}}:add` | 新增 | `v-hasPerm="'{{module}}:{{entity}}:add'"` |
| `{{module}}:{{entity}}:edit` | 修改 | `v-hasPerm="'{{module}}:{{entity}}:edit'"` |
| `{{module}}:{{entity}}:delete` | 删除 | `v-hasPerm="'{{module}}:{{entity}}:delete'"` |
| `{{module}}:{{entity}}:export` | 导出 | `v-hasPerm="'{{module}}:{{entity}}:export'"` |

---

## 5. 前端路由（参考）

> MES 项目使用动态路由：后端通过 `c_sys_resource` 返回路由配置，前端通过 `router.addRoutes()` 注册。
> 以下仅为参考，实际路由由后端 `GET /resource/listTreeByUser` 接口返回。

```javascript
// 后端返回的路由数据结构（resources）
{
  title: '{{moduleName}}',
  path: '/{{domain}}/{{entity}}',
  component: '{{domain}}/{{entity}}/index',  // 前端 import.meta.glob 解析
  icon: 'ios-folder',
  permission: '{{module}}:{{entity}}:view',
}
```

---

## 6. 刷新缓存

执行 SQL 后，需要刷新 Redis 中的资源缓存：

```bash
# 通过 API 刷新
curl -X GET http://localhost:8000/api/sys/resource/reloadCache \
  -H "Authorization: Bearer <token>"
```

> **注意**: 执行 SQL 前请先确认 `pid` 的值（根据实际父级菜单调整），菜单 ID 需确保全局唯一。
