index.ts 2.97 KB
import request from '@/utils/request'
import { ADMIN_API_PREFIX } from '@/config'

/**
 * 系统管理 - 菜单
 *
 * 契约说明(新契约,与后端 parking-module-system 对齐):
 *  - 前缀 /admin-api,回归 CommonResult{code=0}
 *  - 标准 CRUD URL 命名:/create /update /delete /delete-list /get /list /export-excel
 *  - 权限标识:system:menu:create / update / delete / query / export
 *
 * 菜单是**树形结构**,因此没有分页接口:/list 一次返回整棵树,由前端用
 * el-table 的 row-key + children 字段递归渲染。
 *
 * ⚠️ `type`(1 目录 / 2 菜单 / 3 按钮)是**必填**的:
 *    它决定了这个节点有没有 path/component(目录、菜单)以及有没有 permission(按钮)。
 *    老前端的菜单表单漏了 type,导致新建出来的节点无法区分是页面还是按钮。
 *
 * ⚠️ 后端存的是 `visible` 为 `TINYINT`(1 显示 / 0 隐藏),但 RespVO 已经转成
 *    **Boolean** 下发;SaveReqVO 接收的也是 Boolean,前端不需要做 1/0 转换。
 */
const BASE = `${ADMIN_API_PREFIX}/system/menu`

export interface MenuVO {
  id: number
  /** 父菜单编号,顶层为 0 */
  parentId?: number | null
  name: string
  /** 权限标识,仅按钮需要,如 system:user:create */
  permission?: string
  /** 菜单类型:1 目录,2 菜单,3 按钮(字典 system_menu_type) */
  type?: number
  sort?: number
  /** 路由地址,如 /system/user */
  path?: string
  icon?: string
  /** 组件路径(相对 src/views),目录节点为空 */
  component?: string | null
  componentName?: string
  /** 状态:0 启用,1 停用 */
  status?: number
  visible?: boolean
  /** 创建时间(毫秒时间戳) */
  createTime?: number
  /** 子菜单,树形接口一次性下发 */
  children?: MenuVO[]
}

export interface MenuListReqVO {
  name?: string
}

export interface MenuSaveReqVO {
  id?: number
  parentId?: number | null
  name: string
  /** 必填:1 目录,2 菜单,3 按钮 */
  type: number
  /** 必填(后端 @NotNull) */
  sort: number
  /** 必填(后端 @NotNull):0 启用,1 停用 */
  status: number
  permission?: string
  path?: string
  icon?: string
  component?: string | null
  componentName?: string
  visible?: boolean
}

export const MenuApi = {
  getMenuList: (params?: Partial<MenuListReqVO>) => request.get<MenuVO[]>(`${BASE}/list`, { params }),
  getMenu: (id: number) => request.get<MenuVO>(`${BASE}/get`, { params: { id } }),
  createMenu: (data: MenuSaveReqVO) => request.post<number>(`${BASE}/create`, data),
  updateMenu: (data: MenuSaveReqVO) => request.put<boolean>(`${BASE}/update`, data),
  deleteMenu: (id: number) => request.delete<boolean>(`${BASE}/delete`, { params: { id } }),
  deleteMenuList: (ids: number[]) =>
    request.delete<boolean>(`${BASE}/delete-list`, { params: { ids: ids.join(',') } }),
  exportMenu: (params?: Partial<MenuListReqVO>) =>
    request.download(`${BASE}/export-excel`, params, '菜单列表.xlsx')
}