Skip to content

菜单管理接口文档

概述

菜单管理模块提供子应用向一单位一平台上报和查询菜单数据的能力,支持菜单的上报、查询、树形结构查询等功能。菜单采用树形结构组织,支持多级嵌套。所有接口遵循国密 SM2/SM4 数字信封加密方案,确保数据传输安全。

交互方向

本模块包含以下交互方向:

交互方向接口类型子应用实现要求说明
子应用→一单位一平台(上报)新增菜单、修改菜单、删除菜单❌ 无需实现子应用主动上报菜单数据,一单位一平台提供接收接口
子应用→一单位一平台(查询)查询菜单数据❌ 无需实现子应用主动查询菜单数据,一单位一平台提供查询接口

重要说明: 本模块所有接口均为"子应用→一单位一平台"上报/查询接口,子应用直接调用一单位一平台提供的接口,无需额外实现。

使用场景

  • 子应用→一单位一平台(上报): 子应用向一单位一平台上报菜单配置数据
  • 子应用→一单位一平台(查询): 子应用向一单位一平台查询菜单树、查询菜单信息
  • 前端渲染: 根据用户角色动态生成菜单树
  • 数据同步: 子应用定期向一单位一平台同步菜单数据

接口设计原则

所有接口均采用国密 SM2/SM4 数字信封加密方案:

  1. 统一 POST 方式:所有接口使用 POST 方法,业务参数在 encryptData 中加密传输
  2. 无路径参数:URL 路径中不包含任何业务参数,所有业务参数均在加密报文中
  3. 安全性:通过 SM2 混合加密和数字签名确保数据传输的机密性、完整性和不可抵赖性
  4. 应用隔离:每个菜单数据都包含应用标识 appId,实现多应用菜单隔离

适用范围

适用于子应用向一单位一平台上报和查询菜单数据的场景。

术语定义

核心概念

术语说明
一单位一平台核心管理平台,负责数据存储、权限管理、接口路由等核心功能
子应用接入一单位一平台的独立业务系统,通过一单位一平台网关与其他系统交互
网关一单位一平台的统一入口,负责路由转发、身份认证、权限控制、速率限制等

操作语义

术语说明数据流向接口实现方
查询主动请求获取数据子应用→一单位一平台一单位一平台实现
上报主动提交业务数据子应用→一单位一平台一单位一平台实现

重要提示:

  • "查询"表示子应用主动向一单位一平台请求数据,由一单位一平台提供查询接口
  • "上报"表示子应用主动向一单位一平台提交数据,由一单位一平台提供接收接口

系统架构

数据流向

查询流程(子应用→一单位一平台)

子应用 → [加密请求] → 一单位一平台 → [加密响应] → 子应用

上报流程(子应用→一单位一平台)

子应用 → [加密上报] → 一单位一平台 → [加密响应] → 子应用

接口列表

子应用→一单位一平台(上报接口)

接口名称请求地址交互方向说明
新增菜单POST /hztech-application/menu/create子→主(上报)新增单个菜单
修改菜单POST /hztech-application/menu/update子→主(上报)修改菜单信息
删除菜单POST /hztech-application/menu/delete子→主(上报)删除菜单

子应用→一单位一平台(查询接口)

接口名称请求地址交互方向说明
查询菜单数据POST /hztech-application/menu/query子→主(查询)查询菜单列表或树

: 所有业务参数均在 encryptData 中加密传输,URL 路径中不包含任何业务参数。

接口详情

1.1 新增菜单

接口说明

向一单位一平台新增菜单数据。新增的菜单必须包含应用标识,实现多应用菜单隔离。新增菜单时,菜单编码在同一应用下必须唯一。

请求方式

POST

请求地址

POST /ydyp/menu/create

交互方向

子应用 → 一单位一平台 (上报)

完整时序图

请求参数

参数名类型必填说明示例值
nameString菜单名称"概览"
codeString菜单编码(同一应用下唯一)"home"
aliasString菜单别名"home"
parentIdString父菜单ID(根菜单为"0")"0"
parentNameString父菜单名称""
pathString路由路径"/home"
componentString组件路径"views/home/Index"
sourceString图标来源"lucide:layout-dashboard"
categoryInteger分类1
categoryNameString分类名称""
sortInteger排序号0
actionInteger动作标识-1
actionNameString动作名称""
isOpenInteger是否展开-1
isOpenNameString展开状态名称""
hasChildrenBoolean是否有子菜单true
remarkString备注""
appIdString应用标识"SUB_APP_001"

HTTP 请求示例

http
POST /ydyp/menu/create HTTP/1.1
Host: main.example.com
Content-Type: application/json

{
  "appId": "SUB_APP_001",
  "version": "1.0",
  "timestamp": 1735516800000,
  "nonce": "f6a7b8c9-d0e1-1234-5678-9abcdef01234",
  "encryptKey": "MIIBOgIBAAJBAKj34GkxFhD90vcNLYLInFEX6...",
  "encryptData": "U2FsdGVkX1+jmZn5KqWYEgjPkQKpH5KqWYEg...",
  "sign": "MEUCIQDZ5KqWYEgjPkQKpH5KqWYEgjPkQKpH5KqWY..."
}

encryptData 解密后的业务数据

json
{
  "name": "概览",
  "code": "home",
  "alias": "home",
  "parentId": "0",
  "parentName": "",
  "path": "/home",
  "component": "views/home/Index",
  "source": "lucide:layout-dashboard",
  "category": 1,
  "categoryName": "",
  "sort": 0,
  "action": -1,
  "actionName": "",
  "isOpen": -1,
  "isOpenName": "",
  "hasChildren": true,
  "remark": "",
  "appId": "SUB_APP_001"
}

HTTP 响应示例

json
{
  "code": 200,
  "message": "success",
  "data": {
    "id": "1981548240639504386"
  },
  "timestamp": 1735516801500
}

错误响应示例

json
{
  "code": 2102,
  "message": "菜单编码已存在",
  "timestamp": 1735516801000
}

1.2 修改菜单

接口说明

修改一单位一平台中已有的菜单数据。可以修改菜单的名称、路径、组件等信息,但菜单编码不可修改。

请求方式

POST

请求地址

POST /ydyp/menu/update

交互方向

子应用 → 一单位一平台 (上报)

完整时序图

请求参数

参数名类型必填说明示例值
idString菜单ID"1981548240639504386"
nameString菜单名称"概览"
aliasString菜单别名"home"
parentIdString父菜单ID"0"
parentNameString父菜单名称""
pathString路由路径"/home"
componentString组件路径"views/home/Index"
sourceString图标来源"lucide:layout-dashboard"
categoryInteger分类1
categoryNameString分类名称""
sortInteger排序号0
actionInteger动作标识-1
actionNameString动作名称""
isOpenInteger是否展开-1
isOpenNameString展开状态名称""
hasChildrenBoolean是否有子菜单true
remarkString备注""
appIdString应用标识"SUB_APP_001"

HTTP 请求示例

http
POST /ydyp/menu/update HTTP/1.1
Host: main.example.com
Content-Type: application/json

{
  "appId": "SUB_APP_001",
  "version": "1.0",
  "timestamp": 1735516800000,
  "nonce": "f6a7b8c9-d0e1-1234-5678-9abcdef01234",
  "encryptKey": "MIIBOgIBAAJBAKj34GkxFhD90vcNLYLInFEX6...",
  "encryptData": "U2FsdGVkX1+jmZn5KqWYEgjPkQKpH5KqWYEg...",
  "sign": "MEUCIQDZ5KqWYEgjPkQKpH5KqWYEgjPkQKpH5KqWY..."
}

encryptData 解密后的业务数据

json
{
  "id": "1981548240639504386",
  "name": "概览",
  "alias": "home",
  "parentId": "0",
  "path": "/home",
  "component": "views/home/Index",
  "source": "lucide:layout-dashboard",
  "category": 1,
  "sort": 0,
  "hasChildren": true,
  "remark": "",
  "appId": "SUB_APP_001"
}

HTTP 响应示例

json
{
  "code": 200,
  "message": "success",
  "data": {
    "id": "1981548240639504386"
  },
  "timestamp": 1735516801500
}

错误响应示例

json
{
  "code": 2106,
  "message": "菜单不存在",
  "timestamp": 1735516801000
}

1.3 删除菜单

接口说明

删除一单位一平台中已有的菜单数据。删除菜单时,如果菜单存在子菜单,需要先删除所有子菜单或使用级联删除。

请求方式

POST

请求地址

POST /ydyp/menu/delete

交互方向

子应用 → 一单位一平台 (上报)

完整时序图

请求参数

参数名类型必填说明示例值
idString菜单ID"1981548240639504386"
appIdString应用标识"SUB_APP_001"
cascadeBoolean是否级联删除子菜单(默认false)true

HTTP 请求示例

http
POST /ydyp/menu/delete HTTP/1.1
Host: main.example.com
Content-Type: application/json

{
  "appId": "SUB_APP_001",
  "version": "1.0",
  "timestamp": 1735516800000,
  "nonce": "f6a7b8c9-d0e1-1234-5678-9abcdef01234",
  "encryptKey": "MIIBOgIBAAJBAKj34GkxFhD90vcNLYLInFEX6...",
  "encryptData": "U2FsdGVkX1+jmZn5KqWYEgjPkQKpH5KqWYEg...",
  "sign": "MEUCIQDZ5KqWYEgjPkQKpH5KqWYEgjPkQKpH5KqWY..."
}

encryptData 解密后的业务数据

删除单个菜单:

json
{
  "id": "1981548240639504386",
  "appId": "SUB_APP_001",
  "cascade": false
}

级联删除菜单及其子菜单:

json
{
  "id": "1981548240639504386",
  "appId": "SUB_APP_001",
  "cascade": true
}

HTTP 响应示例

成功删除:

json
{
  "code": 200,
  "message": "success",
  "data": {
    "id": "1981548240639504386",
    "deletedCount": 1
  },
  "timestamp": 1735516801500
}

级联删除响应:

json
{
  "code": 200,
  "message": "success",
  "data": {
    "id": "1981548240639504386",
    "deletedCount": 5
  },
  "timestamp": 1735516801500
}

错误响应示例

菜单不存在:

json
{
  "code": 2106,
  "message": "菜单不存在",
  "timestamp": 1735516801000
}

存在子菜单且未启用级联删除:

json
{
  "code": 2108,
  "message": "菜单存在子菜单,无法删除",
  "timestamp": 1735516801000
}

1.4 查询菜单数据

接口说明

查询菜单数据。支持按应用标识查询、查询菜单树结构、按条件筛选等功能。

请求方式

POST

请求地址

POST /hztech-application/menu/query

交互方向

子应用 → 一单位一平台 (查询)

完整时序图

请求参数

参数名类型必填说明示例值
appIdString应用标识"SUB_APP_001"
queryTypeString查询类型(list/tree,默认list)"tree"
parentIdString父菜单ID(查询指定父菜单下的子菜单)"0"
categoryInteger分类筛选1
keywordString关键词(模糊搜索菜单名称/编码)"概览"
isDeletedInteger是否删除(0:未删除,1:已删除,默认0)0
pageNumInteger页码(仅list模式有效,默认1)1
pageSizeInteger每页数量(仅list模式有效,默认20)20

HTTP 请求示例

http
POST /hztech-application/menu/query HTTP/1.1
Host: main.example.com
Content-Type: application/json

{
  "appId": "SUB_APP_001",
  "version": "1.0",
  "timestamp": 1735516800000,
  "nonce": "f6a7b8c9-d0e1-1234-5678-9abcdef01234",
  "encryptKey": "MIIBOgIBAAJBAKj34GkxFhD90vcNLYLInFEX6...",
  "encryptData": "U2FsdGVkX1+jmZn5KqWYEgjPkQKpH5KqWYEg...",
  "sign": "MEUCIQDZ5KqWYEgjPkQKpH5KqWYEgjPkQKpH5KqWY..."
}

encryptData 解密后的业务数据

查询菜单树:

json
{
  "appId": "SUB_APP_001",
  "queryType": "tree",
  "parentId": "",
  "isDeleted": 0
}

分页查询菜单列表:

json
{
  "appId": "SUB_APP_001",
  "queryType": "list",
  "parentId": "0",
  "category": 1,
  "keyword": "",
  "isDeleted": 0,
  "pageNum": 1,
  "pageSize": 20
}

HTTP 响应示例

树形结构响应:

json
{
  "code": 200,
  "message": "success",
  "data": [
    {
      "id": "1981548240639504386",
      "name": "概览",
      "code": "home",
      "alias": "home",
      "parentId": "0",
      "parentName": "",
      "path": "/home",
      "component": "views/home/Index",
      "source": "lucide:layout-dashboard",
      "category": 1,
      "categoryName": "",
      "sort": 0,
      "action": -1,
      "actionName": "",
      "isOpen": -1,
      "isOpenName": "",
      "hasChildren": true,
      "remark": "",
      "isDeleted": 0,
      "appId": "SUB_APP_001",
      "children": [
        {
          "id": "1981548240639504388",
          "name": "数据概览",
          "code": "home:data",
          "alias": "data",
          "parentId": "1981548240639504386",
          "parentName": "概览",
          "path": "/home/data",
          "component": "views/home/Data",
          "source": "lucide:bar-chart",
          "category": 1,
          "sort": 0,
          "hasChildren": false,
          "appId": "SUB_APP_001",
          "children": []
        }
      ]
    }
  ],
  "timestamp": 1735516801500
}

列表分页响应:

json
{
  "code": 200,
  "message": "success",
  "data": {
    "total": 50,
    "pageNum": 1,
    "pageSize": 20,
    "pages": 3,
    "list": [
      {
        "id": "1981548240639504386",
        "name": "概览",
        "code": "home",
        "alias": "home",
        "parentId": "0",
        "path": "/home",
        "component": "views/home/Index",
        "source": "lucide:layout-dashboard",
        "category": 1,
        "sort": 0,
        "hasChildren": true,
        "appId": "SUB_APP_001"
      }
    ]
  },
  "timestamp": 1735516801500
}

错误响应示例

json
{
  "code": 2101,
  "message": "应用不存在",
  "timestamp": 1735516801000
}

数据模型

菜单对象 (Menu)

完整的菜单数据结构:

json
{
  "id": "string",              // 菜单ID(系统生成或上报时指定)
  "name": "string",            // 菜单名称
  "code": "string",            // 菜单编码(同一应用下唯一)
  "alias": "string",           // 菜单别名
  "parentId": "string",        // 父菜单ID(根菜单为"0")
  "parentName": "string",      // 父菜单名称(冗余字段)
  "path": "string",            // 路由路径
  "component": "string",       // 组件路径
  "source": "string",          // 图标来源(如 lucide:layout-dashboard)
  "category": 1,               // 分类
  "categoryName": "string",    // 分类名称(冗余字段)
  "sort": 0,                   // 排序号
  "action": -1,                // 动作标识
  "actionName": "string",      // 动作名称(冗余字段)
  "isOpen": -1,                // 是否展开
  "isOpenName": "string",      // 展开状态名称(冗余字段)
  "hasChildren": true,         // 是否有子菜单
  "remark": "string",          // 备注
  "isDeleted": 0,              // 是否删除(0:未删除,1:已删除)
  "appId": "string",           // 应用标识(用于多应用隔离)
  "createTime": "string",      // 创建时间
  "updateTime": "string",      // 更新时间
  "children": []               // 子菜单列表(树形结构时包含)
}

字段说明

字段类型必填说明约束
idString菜单唯一标识同一应用下唯一
nameString菜单名称2-50个字符
codeString菜单编码同一应用下唯一
aliasString菜单别名用于路由跳转
parentIdString父菜单ID根菜单为"0"
parentNameString父菜单名称冗余字段
pathString路由路径以/开头
componentString组件路径前端组件路径
sourceString图标来源图标标识符
categoryInteger分类数字标识
categoryNameString分类名称冗余字段
sortInteger排序号数值越小越靠前
actionInteger动作标识数字标识
actionNameString动作名称冗余字段
isOpenInteger是否展开-1:未设置,0:折叠,1:展开
isOpenNameString展开状态名称冗余字段
hasChildrenBoolean是否有子菜单true或false
remarkString备注菜单说明
isDeletedInteger是否删除0或1
appIdString应用标识用于多应用菜单隔离
createTimeString创建时间YYYY-MM-DD HH:mm:ss
updateTimeString更新时间YYYY-MM-DD HH:mm:ss
childrenArray子菜单列表树形结构时包含

枚举值说明

是否删除 (isDeleted):

  • 0: 未删除
  • 1: 已删除

是否展开 (isOpen):

  • -1: 未设置
  • 0: 折叠
  • 1: 展开

查询类型 (queryType):

  • list: 列表查询(平铺结构,支持分页)
  • tree: 树形查询(树形结构,包含层级关系)

树形结构说明

菜单采用递归树形结构:

  • 根菜单的 parentId"0"
  • 每个菜单可包含多个子菜单,存储在 children 数组中
  • 查询菜单树时,会递归返回所有层级的子菜单
  • hasChildren 标识菜单是否有子菜单

应用隔离说明

通过 appId 实现多应用菜单隔离:

  • 每个菜单数据必须包含 appId 字段
  • 查询菜单时必须指定 appId,只返回该应用的菜单数据
  • 不同应用的菜单数据完全隔离,code 等字段在同一应用内唯一即可

错误码

业务错误码

错误码说明处理建议
2101应用不存在检查appId是否正确注册
2102菜单编码已存在使用其他编码
2103菜单名称已存在使用其他名称
2104父菜单不存在检查parentId是否正确
2105菜单循环引用检查parentId不能是菜单自身或后代菜单
2106菜单不存在检查菜单ID是否正确
2107参数错误检查请求参数是否完整
2108菜单存在子菜单,无法删除先删除子菜单或使用级联删除

系统错误码

错误码说明处理建议
1001时间戳过期同步系统时间
1002重复请求检查nonce生成逻辑
1003签名验证失败检查密钥配置
1004解密失败检查密钥配置
1005appId不存在检查appId注册
1006业务逻辑错误根据具体错误处理

相关文档


文档版本: v2.0.0 最后更新: 2026-01-05

最近更新