2026-07-23 泰额版:平台 / 公司登录与拉菜单用法
本文说明泰额版 平台管理员 与 公司账号 应如何登录、如何拉菜单,以及完整传参 / 反参示例。
相关文档:
2026-07-23泰额版当前登录账号菜单接口.md2026-07-23泰额版平台端操作公司级账号逻辑.md
一、先分清两套身份
| 角色 | 登录接口 | 用户所在库 | 拉菜单接口 | 菜单数据来源 |
|---|---|---|---|---|
| 平台管理员 | POST /api/app/th-web-auth/login(选 Default + 平台邮箱)或 POST /api/app/account/login |
主库 antis-foodlabeling-host.user |
GET /api/app/account/Vue3Router/vben5(H5 实际调用) |
主库 menu(MenuSource=0,后端 vben5 空时回退 Ruoyi) |
| 公司账号 | POST /api/app/th-web-auth/login(选具体公司 tenantId) |
该公司业务库 user |
GET /api/app/auth-session/my-menus 或 H5 侧 Vue3Router/vben5 |
当前租户业务库 menu |
H5 同一登录框(2026-07-23 后端兼容):
- 前端始终打
POST /api/app/th-web-auth/login,不会打account/login。 - 下拉选 Default(
tenantId=11111111-1111-1111-1111-111111111111)+ 邮箱admin@example.com→ 后端在主库校验,签发无 TenantId 的平台 Token,tenantName返回Platform。 - 下拉选 具体公司(如「中国麦当劳公司」)→ 仍在该公司业务库校验,JWT 含
TenantId。 - Default 租户业务库可能指向
antis-foodlabeling-us;平台邮箱账号不会误入 US 库。
禁止混用:
- 公司 Token 不要用平台-only 的管理接口(无租户上下文)
- 平台 Token 调
auth-session/my-menus现已可读主库菜单(兼容);H5 仍优先Vue3Router/vben5
Base URL 示例:http://127.0.0.1:19002(以部署为准)。
flowchart TB
subgraph platform [平台管理员]
P1[POST account/login]
P2[GET account/Vue3Router/ruoyi]
PHost[(antis-foodlabeling-host)]
P1 --> PHost
P2 --> PHost
end
subgraph company [公司账号]
C1[POST th-web-auth/login]
C2[GET auth-session/my-menus]
CBiz[(租户业务库)]
C1 --> CBiz
C2 --> CBiz
end
二、平台管理员
2.1 登录
| 项 | 值 |
|---|---|
| 方法 / 路径 | POST /api/app/account/login |
| Content-Type | application/json |
| 说明 | 校验主库用户;登录框按 邮箱 匹配(Email 优先,其次 UserName);值须含 @ |
传参(LoginInputVo)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
userName |
string | 是 | 填邮箱,例如种子账号 admin@example.com(字段名虽为 userName) |
password |
string | 是 | 明文密码;种子默认 123456 |
uuid |
string | 视环境 | 验证码会话 Id;未开验证码可省略 |
code |
string | 视环境 | 图形验证码;未开验证码可省略 |
{
"userName": "admin@example.com",
"password": "123456"
}
反参(LoginOutputDto)
| 字段 | 类型 | 说明 |
|---|---|---|
token |
string | JWT(后续请求 Authorization: Bearer {token}) |
refreshToken |
string | 刷新令牌 |
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "..."
}
若全局包装了统一响应,实际可能是
{ "data": { "token": "...", "refreshToken": "..." } },以 Swagger / 实际返回为准。
curl -X POST "http://127.0.0.1:19002/api/app/account/login" \
-H "Content-Type: application/json" \
-d "{\"userName\":\"admin@example.com\",\"password\":\"123456\"}"
2.2 拉菜单(路由)
| 项 | 值 |
|---|---|
| 方法 / 路径 | GET /api/app/account/Vue3Router/ruoyi |
| Header | Authorization: Bearer {token} |
| 说明 | 将当前用户菜单转为 Ruoyi 路由树。主库种子菜单 MenuSource=0,须用 ruoyi,不要用 vben5(否则按 MenuSource=2 过滤会空) |
路径参数 routerType:
| 值 | 对应 MenuSource | 何时用 |
|---|---|---|
ruoyi |
0 | 当前平台种子推荐 |
pure |
1 | Pure 前端 |
vben5 |
2 | 仅当菜单已标成 Vben5 时 |
传参
无 Query Body;路径上带 ruoyi 即可。
反参
返回 前端路由结构数组/对象(由 Vue3RuoYiRouterBuild 生成),不是 auth-session/my-menus 那种 menus 树。字段随框架版本可能含:name、path、component、meta、children 等。以实际 JSON / Swagger 为准。
超级管理员(用户名 admin)会拿到对应 MenuSource 下全部未删菜单再构建路由。
curl -G "http://127.0.0.1:19002/api/app/account/Vue3Router/ruoyi" \
-H "Authorization: Bearer <platform-token>"
2.3 平台菜单数据位置
| 库表 | 说明 |
|---|---|
antis-foodlabeling-host.menu |
约 26 条:首页概览、平台管理/SAAS 公司、标签管理…、管理/账户管理… |
user / role / rolemenu |
平台 admin 已绑定上述菜单 |
种子脚本:th-tenant-menu-seed.sql(menu)、th-platform-user-role-seed.sql(user/role)。菜单 Id 均为合法 Guid(见下文「平台应有菜单清单」)。
七、平台应有菜单清单
主库 antis-foodlabeling-host.menu 共 26 条未删食品 SaaS 菜单,MenuSource=0(Ruoyi)。根菜单 ParentId='0';子菜单 ParentId 为父目录 Guid。
| 菜单名称 | Id | router | routerName | component | menuType | parentId | orderNum | menuIcon |
|---|---|---|---|---|---|---|---|---|
| 首页概览 | f0010001-0001-4000-8000-000000000001 |
/analytics |
FoodLabelingDashboard |
/food-labeling/dashboard/index |
1 | 0 |
-1 | lucide:layout-dashboard |
| 平台管理 | f0010002-0001-4000-8000-000000000002 |
/platform |
FoodLabelingPlatform |
空 | 0 | 0 |
5 | lucide:cloud-cog |
| SAAS 公司 | f0010003-0001-4000-8000-000000000003 |
/platform/tenants |
FoodLabelingPlatformTenants |
/food-labeling/platform/tenants/index |
1 | f0010002-0001-4000-8000-000000000002 |
6 | lucide:building |
| 标签管理 | f0010010-0001-4000-8000-000000000010 |
/labeling |
FoodLabelingLabeling |
空 | 0 | 0 |
10 | lucide:tags |
| 标签 | f0010011-0001-4000-8000-000000000011 |
/labels |
FoodLabelingLabels |
/food-labeling/labeling/labels/index |
1 | f0010010-0001-4000-8000-000000000010 |
11 | lucide:tag |
| 标签分类 | f0010012-0001-4000-8000-000000000012 |
/label-categories |
FoodLabelingLabelCategories |
/food-labeling/labeling/label-categories/index |
1 | f0010010-0001-4000-8000-000000000010 |
12 | lucide:folder-tree |
| 标签类型 | f0010013-0001-4000-8000-000000000013 |
/label-types |
FoodLabelingLabelTypes |
/food-labeling/labeling/label-types/index |
1 | f0010010-0001-4000-8000-000000000010 |
13 | lucide:layers |
| 标签模板 | f0010014-0001-4000-8000-000000000014 |
/label-templates |
FoodLabelingLabelTemplates |
/food-labeling/labeling/label-templates/index |
1 | f0010010-0001-4000-8000-000000000010 |
14 | lucide:layout-template |
| 多选选项集 | f0010015-0001-4000-8000-000000000015 |
/multiple-options |
FoodLabelingMultipleOptions |
/food-labeling/labeling/multiple-options/index |
1 | f0010010-0001-4000-8000-000000000010 |
15 | lucide:list-checks |
| 业务模块 | f0010020-0001-4000-8000-000000000020 |
/modules |
FoodLabelingModules |
空 | 0 | 0 |
15 | lucide:boxes |
| 培训 | f0010021-0001-4000-8000-000000000021 |
/training |
FoodLabelingTraining |
/food-labeling/modules/training/index |
1 | f0010020-0001-4000-8000-000000000020 |
16 | lucide:graduation-cap |
| 告警 | f0010022-0001-4000-8000-000000000022 |
/alerts |
FoodLabelingAlerts |
/food-labeling/modules/alerts/index |
1 | f0010020-0001-4000-8000-000000000020 |
17 | lucide:bell |
| 任务 | f0010023-0001-4000-8000-000000000023 |
/tasks |
FoodLabelingTasks |
/food-labeling/modules/tasks/index |
1 | f0010020-0001-4000-8000-000000000020 |
18 | lucide:list-todo |
| 传感器 | f0010024-0001-4000-8000-000000000024 |
/sensors |
FoodLabelingSensors |
/food-labeling/modules/sensors/index |
1 | f0010020-0001-4000-8000-000000000020 |
19 | lucide:activity |
| 食物浪费 | f0010025-0001-4000-8000-000000000025 |
/food-waste |
FoodLabelingFoodWaste |
/food-labeling/modules/food-waste/index |
1 | f0010020-0001-4000-8000-000000000020 |
20 | lucide:apple |
| 电子标签 | f0010026-0001-4000-8000-000000000026 |
/e-label-module |
FoodLabelingELabelModule |
/food-labeling/modules/e-label/index |
1 | f0010020-0001-4000-8000-000000000020 |
21 | lucide:file-digit |
| 管理 | f0010030-0001-4000-8000-000000000030 |
/management |
FoodLabelingManagement |
空 | 0 | 0 |
20 | lucide:building-2 |
| 账户管理 | f0010031-0001-4000-8000-000000000031 |
/account-management |
FoodLabelingAccountManagement |
/food-labeling/management/account-management/index |
1 | f0010030-0001-4000-8000-000000000030 |
21 | lucide:users |
| 系统菜单 | f0010032-0001-4000-8000-000000000032 |
/system-menu |
FoodLabelingSystemMenu |
/food-labeling/management/system-menu/index |
1 | f0010030-0001-4000-8000-000000000030 |
22 | lucide:menu-square |
| 菜单管理 | f0010033-0001-4000-8000-000000000033 |
/menu-management |
FoodLabelingMenuManagement |
/food-labeling/management/menu-management/index |
1 | f0010030-0001-4000-8000-000000000030 |
23 | lucide:utensils |
| 设备 | f0010034-0001-4000-8000-000000000034 |
/devices |
FoodLabelingDevices |
/food-labeling/modules/devices/index |
1 | f0010030-0001-4000-8000-000000000030 |
24 | lucide:smartphone |
| 报表 | f0010035-0001-4000-8000-000000000035 |
/reports |
FoodLabelingReports |
/food-labeling/management/reports/index |
1 | f0010030-0001-4000-8000-000000000030 |
25 | lucide:file-bar-chart |
| 发票 | f0010036-0001-4000-8000-000000000036 |
/invoices |
FoodLabelingInvoices |
/food-labeling/modules/invoices/index |
1 | f0010030-0001-4000-8000-000000000030 |
26 | lucide:receipt |
| 二维码 | f0010037-0001-4000-8000-000000000037 |
/qr-codes |
FoodLabelingQrCodes |
/food-labeling/modules/qr-codes/index |
1 | f0010030-0001-4000-8000-000000000030 |
27 | lucide:qr-code |
| 支持 | f0010038-0001-4000-8000-000000000038 |
/support |
FoodLabelingSupport |
/food-labeling/management/support/index |
1 | f0010030-0001-4000-8000-000000000030 |
28 | lucide:life-buoy |
| API | f0010039-0001-4000-8000-000000000039 |
/api-settings |
FoodLabelingApi |
/food-labeling/modules/api/index |
1 | f0010030-0001-4000-8000-000000000030 |
29 | lucide:code-2 |
平台 admin 账号:UserName=admin,Email=admin@example.com,Id=f0020001-0001-4000-8000-000000000001;角色 Id=f0020002-0001-4000-8000-000000000002;rolemenu 绑定上述 26 条菜单。
三、公司账号
3.1 登录
| 项 | 值 |
|---|---|
| 方法 / 路径 | POST /api/app/th-web-auth/login |
| Content-Type | application/json |
| 说明 | 须指定租户;在该公司业务库校验账号,JWT 含 TenantId |
传参(ThWebLoginInputVo)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
tenantId |
guid | 与 tenantName 二选一 |
租户 Id(推荐) |
tenantName |
string | 与 tenantId 二选一 |
租户名称,如 中国麦当劳公司 |
userName |
string | 是 | 登录账号(可为邮箱或用户名) |
password |
string | 是 | 明文密码 |
uuid / code |
string | 视环境 | 验证码 |
{
"tenantId": "3a229a02-77eb-1dcc-afb6-09e2a2b6386c",
"userName": "admin",
"password": "123456"
}
或:
{
"tenantName": "中国麦当劳公司",
"userName": "admin",
"password": "123456"
}
反参(ThWebLoginOutputDto)
| 字段 | 类型 | 说明 |
|---|---|---|
token |
string | JWT(含租户与 RBAC Claims) |
refreshToken |
string | 刷新令牌 |
tenantId |
guid | 当前租户 Id |
tenantName |
string | 当前租户名称 |
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "...",
"tenantId": "3a229a02-77eb-1dcc-afb6-09e2a2b6386c",
"tenantName": "中国麦当劳公司"
}
curl -X POST "http://127.0.0.1:19002/api/app/th-web-auth/login" \
-H "Content-Type: application/json" \
-d "{\"tenantId\":\"3a229a02-77eb-1dcc-afb6-09e2a2b6386c\",\"userName\":\"admin\",\"password\":\"123456\"}"
3.2 拉菜单
| 项 | 值 |
|---|---|
| 方法 / 路径 | GET /api/app/auth-session/my-menus |
| Header | Authorization: Bearer {公司 token} |
| 建议 Header | __tenant: {tenantId}(与 JWT 中 TenantId 一致更稳妥) |
| 说明 | 读当前租户业务库 menu + 角色;用户名为 admin 时返回该库全部未删菜单 |
传参
无 Body;依赖 Token(及可选 __tenant)。
反参(CurrentUserMenuPermissionsOutputDto,字段一般为 camelCase)
| 字段 | 类型 | 说明 |
|---|---|---|
user |
object | 当前用户简要信息 |
user.id |
guid/string | 用户 Id |
user.userName |
string | 登录名 |
user.nick |
string? | 昵称 |
user.email |
string? | 邮箱 |
user.icon |
string? | 头像 |
roleCodes |
string[] | 角色编码 |
permissionCodes |
string[] | 权限码(超管常见 *:*:*) |
accessPermissionCodes |
string[] | 角色访问权限编码 |
menus |
array | 菜单树(根列表,children 嵌套) |
role |
string | 角色展示名 |
fullName |
string | 全名 |
lastUpdated |
datetime? | 供前端刷新缓存 |
菜单节点(CurrentUserMenuNodeDto)常见字段:
| 字段 | 说明 |
|---|---|
id / parentId |
菜单 Id、父 Id(根多为 "0") |
menuName |
名称 |
router / routerName / component |
路由与组件 |
menuType / menuSource / orderNum |
类型、来源、排序 |
permissionCode |
权限码 |
menuIcon / isShow / state |
图标、显示、启用 |
children |
子节点数组 |
{
"user": {
"id": "...",
"userName": "admin",
"nick": "超级管理员",
"email": "admin@example.com"
},
"roleCodes": ["admin"],
"permissionCodes": ["*:*:*"],
"accessPermissionCodes": [],
"menus": [
{
"id": "...",
"parentId": "0",
"menuName": "系统管理",
"router": "/system",
"orderNum": 100,
"children": []
}
],
"role": "管理员",
"fullName": "超级管理员",
"lastUpdated": "2026-07-23T10:00:00"
}
curl -G "http://127.0.0.1:19002/api/app/auth-session/my-menus" \
-H "Authorization: Bearer <company-token>" \
-H "__tenant: 3a229a02-77eb-1dcc-afb6-09e2a2b6386c"
未识别租户时典型错误:
未识别租户上下文。请使用泰额登录接口(th-web-auth / th-app-auth)或请求头
__tenant携带租户 Id。
3.3 公司库菜单现状说明
| 库 | 当前菜单大致情况 |
|---|---|
| 主库 host | 已种食品 SaaS 中文菜单(平台用) |
Default → antis-foodlabeling-us |
美国版英文业务菜单 |
如 antis-foodlabeling-t46d56528(中国麦当劳) |
多为 Yi 框架种子(系统管理/用户管理…),尚未种 th-tenant-menu-seed.sql 那套食品 SaaS 菜单 |
若公司端侧边栏也要与平台同一套「首页概览 / 标签管理 / 业务模块…」:
- 对该公司业务库执行
项目相关文档/th-tenant-menu-seed.sql(禁止对antis-foodlabeling-us执行,以免污染美国版) - 为公司管理员角色绑定对应
rolemenu(或公司admin用户名可直接看全库未删菜单) - 再用
th-web-auth/login+auth-session/my-menus验证
四、对照速查
| 步骤 | 平台管理员(H5 选 Default) | 公司账号 |
|---|---|---|
| 1. 登录 | POST /api/app/th-web-auth/login(Default tenantId + 邮箱) |
POST /api/app/th-web-auth/login |
| 2. 关键 | Default tenantId + 邮箱 userName + password |
公司 tenantId + userName + password |
| 3. 登录反参 | token / refreshToken / tenantName=Platform |
token / refreshToken / tenantId / tenantName |
| 4. 拉菜单(H5) | GET /api/app/account/Vue3Router/vben5 |
GET /api/app/auth-session/my-menus 或 H5 同 vben5 |
| 5. 菜单 Header | Authorization: Bearer … |
Authorization + 建议 __tenant |
| 6. 菜单反参形态 | Vben5 路由树(Ruoyi 回退) | user + menus 树 + 权限码 |
五、前端对接注意(H5 / Vben5,只读不改源码)
- 登录:
POST /api/app/th-web-auth/login(见th-web-auth.ts),Header 带__tenant: tenantId。 - 登录 Body:
tenantId、userName(Email 字段)、password;可选uuid/code(验证码)。 - tenant-select:
GET /api/app/th-multi-tenancy/tenant-select现返回id+name;前端用id作为下拉 value。 - 平台管理员操作:选 Default,邮箱填
admin@example.com,密码123456。 - 公司操作:选 中国麦当劳公司 等公司项,填该公司业务库账号(如
admin)。 - 拉菜单:H5 dist 实际调
GET /api/app/account/Vue3Router/vben5(非my-menus);平台 Token 无租户即可;主库MenuSource=0时后端自动回退 Ruoyi 再 Vben5 构建。 - 公司端仍可用
auth-session/my-menus(须 Token +__tenant)。 - 统一响应包装时从
data取token/menus。
5.1 H5 登录请求示例(平台)
POST /api/app/th-web-auth/login
Header: __tenant: 11111111-1111-1111-1111-111111111111
Body:
{
"tenantId": "11111111-1111-1111-1111-111111111111",
"userName": "admin@example.com",
"password": "123456"
}
成功反参(平台):
{
"token": "eyJ...",
"refreshToken": "...",
"tenantId": "00000000-0000-0000-0000-000000000000",
"tenantName": "Platform"
}
5.2 H5 登录请求示例(公司)
{
"tenantId": "3a229a02-77eb-1dcc-afb6-09e2a2b6386c",
"userName": "admin",
"password": "123456"
}
六、自检清单
- [ ] H5 选 Default +
admin@example.com:th-web-auth/login成功,tenantName=Platform,Token 无 TenantId Claim - [ ] 平台:
Vue3Router/vben5返回非空路由(Ruoyi 菜单回退) - [ ] 公司:选公司 tenantId + 公司账号登录未破坏;
my-menus带__tenant成功 - [ ] 公司业务库菜单内容符合产品预期(必要时单独执行租户库 menu 种子,避开 US 库)