MES 2026 年第 32 周工作小结

本周(8/3–8/6,约 50 次提交、合并 PR #360、#374)主线在 AI 图表内联渲染相对月份推理修复,同时推进运行日志可观测性和 ExternalApi 集成。主力模块 mes-ai(167 文件触达),次为 mes-chart(15 文件)。

一、AI 图表内联与看板增强(#360)

在 AI 聊天中落地面向 SQL 工具的内联图表渲染,并增强看板筛选能力:

  • SqlToolChartPolicy:新增图表配置编辑入口,支持为 SQL 工具指定折线/柱状/表格等图表类型,查询结果直接在对话中渲染
  • 看板增强:Tab 筛选与可见性管理、月份过滤支持、renderFilterBar 异步时序修复
  • 健壮性修复ClassCastException(图表配置为标量值时)、NumberUtil 统一替代自定义数值解析方法

二、相对月份查询修复(#985、#992)

针对性修复”上个月”等相对月份提示词输出错误日历月份的问题:

  • RelativeMonthOverviewNormalizer:正则从 RELATIVE_MONTH_PHRASES 集中化短语列表动态构建,消除分散常量
  • AgentReactExecutor:注入已解析年月提示,防止 Agent 在强制结单前过早输出 JSON 导致月份错误
  • 新增单测覆盖多种相对月份表述场景

三、AI 运行日志可观测性(#374)

  • 运行日志列表新增会话详情弹窗,支持按 sessionId 匹配 assistant 消息并展示
  • AiChatRunLogEntity 关联 SysUserEntity,日志列表展示用户信息(用户名/姓名)
  • AgentChatController 会话管理功能增强:分页、搜索、会话切换
  • AgentAnswerParser 新增 intentional_choices JSON 解析

四、ExternalApi 工具增强

  • URI 构造与编码重构,urlEncode 冗余方法移除
  • 测试用例覆盖 URI 特殊字符编码场景
  • 文档补充:高德天气工具、通用 External API 接入示例

五、文档与基础设施

  • MES vs Dify / AgentScope 对比文档大幅更新,详列成本/标注反馈闭环等维度差距
  • mes-ai 工具配置复杂度分析文档
  • 新增 mes-count-loc Skill
  • .mcp.json 加入 .gitignore,清理过期 LLM 文档和已吸收的单次 SQL 补丁

六、物料查询

  • 新增物料 ZZTJ 日进出 SQL 工具种子及文档索引
  • 物料单位 IO 明细查询增加含量、类别筛选参数

一句话:本周以 AI 图表内联和相对月份修复落地为主,运行日志可观测性明显提升,ExternalApi 和物料查询逐步补全。

MES 2026 年 5 月工作小结

5 月(约 220+ 次提交、合并 PR #239–#281)主线落在业务现场能力:交接班 Docx 模型导入、液体码头/船舶作业增强、仪表位号与报表关联,以及 RTDB/ISYS 采集链路。改动最集中的是 mes-operationmes-measuremes-vessel-operation,辅以 mes-web / mes-rtdb

一、交接班 ShiftLog(中下旬主线)

  • Docx 模型导入与解析预览(#263):锚点注入、单元格模式、输入类型与公式处理。
  • 跳过孤儿锚点(#270)、批量删除与归属校验、调度日志预览。
  • Docx 解析器持续增强(#278):条目类型、标签推断、TABLE_STR_BC 批量生成等。
  • 月末补齐 docx_code 唯一性校验(#281)。

二、船舶 / 液体码头作业

  • 内外贸字段、管线名称、货种筛选与泊位告警(#239/#241/#246/#248)。
  • 收发油罐按物料多选(#244);船名模糊检索等终端体验。
  • 船舶动态导入:到港时间格式与提示信息修复(#258/#276)。
  • 排船页接入真实 LLM 辅助(#275)。

三、仪表位号与报表

  • 手动采集按钮(#254);位号配置、导入导出、唯一性与时间处理(#267)。
  • 关联报表模板展示与批量查询、模板维度(#252/#265)。
  • 报表/位号侧过滤与 jqGrid 行范围选择。

四、实时库与工程体验

  • RTDB ISYS SDK RMI 回调(#271);ISYS 配置与 HTTP 客户端增强。
  • SpringDoc OpenAPI / Swagger UI 接入。
  • 多 Tab 溢出箭头滚动(#273)、滚动条样式、模态间菜单切换;菜单关键词逗号 OR 搜索(#269)。
  • 反馈排程关闭/驳回态隐藏按钮等细节(#250)。

五、月度节奏

阶段 重点
上旬 液体码头罐/管线/货种、位号手动采集、报表模板维度
中旬 交接班 Docx 导入起步、位号关联报表、菜单搜索与 UI 修复
下旬 ShiftLog 解析深化、RTDB RMI、排船 AI、到港时间导入、docx 唯一性

一句话:5 月把交接班 Docx 导入做成可用链路,并加强液体码头作业与仪表采集/报表关联;实时库回调与若干前端体验同步落地,为 6 月平台化(AI/能耗/图表)腾出业务底座。

MES 2026 年 6 月工作小结

6 月(约 340+ 次提交、合并 PR #277–#310)是平台能力铺开的一个月:落地 mes-ai Agent 平台mes-energy 模块,图表看板与 AI 向导增强,并同步推进 Eos 权限、OTP、在线消息与个人工作台。改动较均衡地落在 mes-core / mes-web / mes-ai / mes-energy / mes-chart

一、MES-AI Agent 平台(下旬主线,#305)

  • 新增 mes-ai 模块骨架:Agent 管理、聊天流式输出、thinking 步骤跟踪。
  • SQL 工具执行与表格流式渲染、能耗 Agent SQL/输出格式迭代。
  • Schema Tool、菜单权限与助手推荐问题/欢迎语等体验补齐。

二、能耗模块 mes-energy(中下旬)

  • 独立 mes-energy 并接入 web 依赖;峰谷(TOU)时段配置、日统计、分页/汇总/导出。
  • 电表数据源管理、手动录入、相邻时段合并、能耗看板菜单与电压等级过滤等。

三、图表看板与 AI 向导(#304)

  • 看板设计:布局预设、槽位、组件面板、主题与最大化查看。
  • SQL 编辑(CodeMirror)、安全校验与试跑;AI 配置/SQL 审查、图层面板主题说明。

四、权限、认证与消息

  • Eos 角色管理(#299):对象级权限配置、菜单同步、权限详情与 UI 重构。
  • OTP 二期(#289/#294);runas 用户切换修复(#277);权限 token 切换(#309)。
  • 在线消息通知(#307)与列表慢查询优化(#308);系统菜单导航慢查询(#306)。

五、其它业务与工程

  • 个人工作台(#310);首页用户下拉菜单(#295)。
  • 储罐体积/导入导出(#298);班组装置同步(#302);交接班 shiftlog(#286/#287)。
  • Flowable/请假流程与 Docker 配置;jqGrid 多表头紧凑样式;mes-core 单测补强。
  • SysLog 注解与敏感字段、QRTZ/监控相关增强。

六、月度节奏

阶段 重点
上旬 runas/OTP、交接班、jqGrid、mes-core 测试、反馈看板
中旬 Eos 角色权限、储罐体积、图表看板设计、mes-energy / mes-ai 起步
下旬 AI Agent 平台合入、图表 AI 向导、能耗 TOU、消息与慢查询、个人工作台

一句话:6 月搭好了 AI Agent、能耗与图表看板三块新底座,并在 Eos 权限与登录安全上完成一轮可用交付,为 7 月能耗智能体与生产运行闭环打基础。

MES 2026 年 7 月工作小结

7 月(约 400+ 次提交、合并 PR #312–#367)主线是把 mes-ai 从可用原型推进到能耗/生产运行可落地,并顺带补齐权限、调度、图表与安全。改动最集中的模块是 mes-ai,其次 mes-web / mes-security / mes-chart

一、MES-AI 平台能力(全月主线)

  • 多 Agent / 路由:协作 MVP、首页浮动助手接入 mes_router、窗口最大化、会话与统计增强。
  • 工具调用(FC/ReAct):空工具调用恢复与 nudge、互斥意图、few-shot / handler_config 常见错误提示、同参重复调用治理、运行日志可观测与重试。
  • SQL 工具链:参数槽位抽取、日期区间(含半月)、列标签/排序、存储过程工具、结果图表与表格渲染(列组、着色、汇总行、excludeFromUiTable)。
  • 模型与配置:thinking 模式、采样参数、工具业务分类、硬编码治理(默认模型可配置等)。
  • 管理端:工具/Agent 列表与编辑、级联删除、聊天停止、用户改消息、反馈/复测标记、页面规范(按钮/msg)。

二、业务智能体落地

  • 能耗分析:同比环比、日表多装置查询、Z_View_NHFX_*、列显隐与意图策略、图表双轴等多轮打磨。
  • 生产运行 / 工程师日志:填报状态意图与工具互斥、工程师/部门长问题频次与运行日志查询工具;月末落地 Eos 工程师日志 定时提交模块(#366)。
  • 生产运行 FC 智能体(#324)及相关 SQL/提示持续迭代。

三、权限与安全

  • Eos 角色对象权限、单权限替换模式、eosrole 一次完成 EOS+MES 用户授权。
  • JSON 请求加密、XSS 过滤与 AI/Chart 定点抽检。
  • mes-chart 安全与可维护性改造。

四、基础设施与其它业务

  • Quartz:P0/P1/P2 工程化、超时控制、失败告警、任务日志状态。
  • 工作台 P0–P2(#327)。
  • 船舶vesselOperationDynamicId 终端强制/校验。
  • Excel/JXLS、用户导出、在线消息详情、jqGrid 全局错误处理、本地 LLM profile 等。

五、月度节奏

阶段 重点
上旬 Eos 权限、本地 LLM、AI 管理端基础、聊天停止、生产运行 FC
中旬 运行可观测、意图互斥、槽位抽取、加密/XSS、协作与图表
下旬 多 Agent 路由入口、Quartz、能耗 SQL/表格体系、工程师日志模块、硬编码治理

一句话:7 月把 MES-AI 做成「能路由、能调工具、能出表/图、能追日志」的平台,并在能耗分析与生产运行上形成可演示的业务闭环;权限、调度、图表安全同步加固。

MES 本周工作小结(2026-07-28 ~ 08-01)

本周(7/28–8/1)工作以 MES-AI 能耗分析与对话表格展示 为主线,并落地了 Eos 工程师日志、船舶作业校验与一批文档。约 74 次提交,合并 10 个 PR(#357–#367)。

一、MES-AI 能耗智能体(主线)

  • SQL 工具与参数:完善能耗工具参数解析(#357)、同比环比工具、装置/时段槽位提取;多轮按运行日志纠偏(装置识别、明细 vs 汇总、单位标注等)。
  • 日表查询:新增 energy_nhfx_day / Z_View_NHFX_TABLE 日表多装置查询(#363),持续修 JSON、错误处理与设计物耗字段表述。
  • 表格与图表:复合表头/列组(#358)、单元格着色(#359)、汇总行与派生率(#361)、双图(多日/多装置)、excludeFromUiTable 隐藏辅助结果(#365)。
  • 稳定性StoredProcToolHandler 围绕 Fastjson 未闭合字符串等问题迭代,后简化控制字符预处理逻辑。
  • 硬编码治理:默认模型可配置、Embedding base-url 清理等 P0 项合入(#367)。

二、AI 管理端与规范

  • AI 列表/编辑页统一按钮样式、导航、成功提示改用 msg(#364)。
  • Cursor 规则与页面约定对齐(成功/失败提示、按钮风格)。

三、Eos / 安全任务

  • 新增 Eos 工程师日志 模块(OpenService 客户端、定时任务、装置配置、测试)(#366)。
  • 日常用 skill/脚本按 token 批量生成各装置工程师日志。
  • 补充/更新 EOS 角色-菜单、角色树 nodeId/objectId 文档。

四、船舶作业

  • 终端侧强制/校验 vesselOperationDynamicId(#362)。
  • 完善到离港接口与 mes-measure-vesselmes-vessel-operation 调用说明文档。

五、其他

  • mesdata 存储过程/函数梳理、能耗模型数据核对、日志错误报告更新。
  • README 与若干 AI/业务 PDF 文档整理。

六、周末进行中

本地仍有未合入改动:ai-chat-render.js、若干 AI HTML,以及 index.html / main.css(偏首页/样式微调)。


一句话:本周把能耗 AI 从「能查」推进到「表格好看、图表可用、结果可控、配置可治理」,并完成工程师日志自动化与船舶动态 ID 校验。

EOS 菜单树 NodeID 与 ObjectID 说明

本文档说明 eosrole 页面「配置 EOS 菜单权限」树节点中 NodeID(前端 zTree 的 id)与 ObjectID(前端 objectId)的含义、数据库来源、后端组装与前端使用方式。

关联文档:EOS 菜单与角色关联关系说明

2026-07-31 更新:权限树接口额外返回 menuType / sysMenuId;保存 body 含 MES 按钮与 ERP 操作扩展字段。

结论摘要

前端字段 含义 数据库来源 主要用途
zTree id 菜单节点 ID messys.Tree.NodeID 树结构、父子关系(pId);前端勾选态缓存键
zTree objectId EOS 权限对象 ID messys.Tree.ObjectID = messys.ObjectRegister.ObjectID 角色菜单授权(STPermission.ObjectID,「执行」)
zTree menuType 菜单类型 EosMenuTypeHelper.resolveMenuType mes / erp / folder,决定右侧详情面板
zTree sysMenuId MES 菜单 ID 优先 sys_menu_eos_node,否则 NodeDesc=MES_MENU: MES 菜单/按钮写入 sys_role_menu

NodeID 与 ObjectID 是两套独立编号体系,不可混用。角色菜单「执行」授权必须使用 ObjectID;NodeID 用于树层级与 detail 查询参数。


1. NodeID 是什么

NodeID 是 EOS 菜单树 messys.dbo.Tree 的主键,标识一个菜单/目录节点在树中的位置。

在 MES 前端 zTree 中,NodeID 映射为节点的 **id**(idKey: "id"),ParentID 映射为 **pId**,用于渲染树形结构与展开/折叠。前端勾选态 permissionCheckedNodeIds 也按 NodeID 缓存。

NodeID 不写入 STPermission。权限表引用的是 ObjectID。detail 接口用 nodeId 定位节点后再解析业务 ObjectID。


2. NodeID 从哪来

2.1 数据库表

字段 说明
Tree messys NodeID 菜单节点主键
Tree messys ParentID 父节点 NodeID(根为 0)
UniqueNO messys No 下一个可用 NodeID(NName='tree'

2.2 MES 新建节点时的分配逻辑

MES 通过 TreeServiceImpl.getNextNodeIdForTree()UniqueNO 表取号:

  1. 悲观锁查询 UniqueNONName='tree' 的记录(PESSIMISTIC_WRITE
  2. 取当前 No 作为新 NodeID
  3. No + 1 写回,占用该编号
1
2
3
4
5
6
// TreeServiceImpl.getNextNodeIdForTree()
UniqueNOEntity row = uniqueNODao.findByNnameForUpdate(UNIQUE_NO_NAME_TREE);
int currentNo = row.getNo();
row.setNo(currentNo + 1);
uniqueNODao.save(row);
return Long.valueOf(currentNo);

2.3 触发 NodeID 分配的操作

操作 方法 说明
新增菜单节点 TreeServiceImpl.addNode getNextNodeIdForTree(),再写 Tree
sys_menu 同步 TreeServiceImpl.syncFromSysMenu 每个同步节点分配新 NodeID
复制菜单 TreeServiceImpl.copyMenu 源节点及子树每个节点各分配新 NodeID
交接班菜单批量创建 createShiftLogDispatchMenusaddNode 同上

2.4 EOS 原生 / 历史数据

在 MES 介入之前,NodeID 可能由 EOS 客户端或其他工具写入 Tree,同样依赖 UniqueNO 序列或历史遗留编号。MES 只保证新增/同步/复制时走 getNextNodeIdForTree() 逻辑。

2.5 NodeID 在 Functions 中的用途

Tree.Functions 字段保存菜单跳转 URL,其中 menuId 参数值为 NodeID(不是 ObjectID)。例如同步 sys_menu 时:

1
{baseUrl}/{url}?token=%Token%&menuId={NodeID}

复制菜单时,TreeServiceImpl 会将 Functions 里的 menuId=旧NodeID 替换为 menuId=新NodeID

2.6 NodeID 生命周期

  • 查询treeDao.findAll(...)queryObject(nodeid)
  • 删除delete / deleteBatch 按 NodeID 删除 Tree,并先 ObjectRegisterDao.deleteByOwnerId(NodeID) 清理关联对象
1
2
3
4
flowchart LR
A[UniqueNO<br/>NName=tree] -->|取 No 作为 NodeID| B[Tree.NodeID]
B --> C[listTreeForPermission<br/>返回 id=NodeID]
C --> D[zTree id / pId<br/>树结构展示]

3. ObjectID 是什么

ObjectID 是 EOS 对象注册表 messys.dbo.ObjectRegister 的主键。每个可授权对象在 ObjectRegister 中注册一条记录;菜单/目录节点对应 TypeID = 7,并通过 OwnerID = Tree.NodeID 与菜单树关联。

MES 维护菜单时会将 ObjectID 冗余写入 Tree.ObjectID,便于权限树接口一次查询带出。

在角色菜单授权场景下,前端勾选菜单后提交的是 objectId 列表,写入 mesdata.dbo.STPermission.ObjectID(配合 UserID=角色 OID、Oprate=「执行」、Permission=1)。


4. ObjectID 从哪来

4.1 数据库表

层级 库/表 字段 含义
权威主键 messys ObjectRegister ObjectID 全局对象 ID(自增:MAX+1)
关联 messys ObjectRegister OwnerID = Tree.NodeID
类型 messys ObjectRegister TypeID MES 新建菜单固定为 7(菜单/目录)
冗余 messys Tree ObjectID ObjectRegister.ObjectID 一致
授权 mesdata STPermission ObjectID 引用 ObjectRegister.ObjectID

关系:Tree.NodeIDObjectRegister.OwnerIDTree.ObjectID = ObjectRegister.ObjectID

4.2 MES 新建节点时的分配逻辑

TreeServiceImpl.saveObjectRegisterForTree()

  1. ObjectRegisterDao.findMaxObjectId() 取 MAX(ObjectID) + 1
  2. 插入 ObjectRegisterTypeID=7OwnerID=NodeIDObject=菜单名)
  3. 将返回的 ObjectID 写入 Tree.ObjectID

与 NodeID 分配在同一事务内完成(如 addNode 先取 NodeID,再创建 ObjectRegister)。

4.3 触发 ObjectID 分配的操作

与 NodeID 分配的操作相同(新增、同步、复制)。复制菜单时 NodeID 与 ObjectID 均重新分配,不会沿用源节点的 ObjectID。

场景 ObjectID 来源
MES 新增 EOS 菜单节点 saveObjectRegisterForTree 新分配
从 sys_menu 同步 每个同步节点一条新 ObjectRegister
复制菜单 新 NodeID + 新 ObjectRegister + 新 ObjectID
EOS 原生/历史数据 可能由 EOS 客户端写入;Tree.ObjectID 可能已存在
失败兜底 object == nullTree.ObjectID = 0(无有效授权对象)
1
2
3
4
5
6
flowchart LR
A[分配 NodeID] --> B[插入 ObjectRegister<br/>ObjectID=MAX+1]
B --> C[Tree.ObjectID = ObjectID]
C --> D[listTreeForPermission<br/>返回 objectId]
D --> E[前端勾选提交 objectIds]
E --> F[STPermission 写入]

5. NodeID 与 ObjectID 对照

1
2
3
4
5
6
Tree.NodeID       ──►  zTree.id         (树结构、ParentID 父子关系)
Tree.ObjectID ──► zTree.objectId (STPermission「执行」授权键)

ObjectRegister.OwnerID = Tree.NodeID
ObjectRegister.ObjectID = Tree.ObjectID
ObjectRegister.TypeID = 7(菜单/目录)
对比项 NodeID ObjectID
所属表 messys.Tree 主键 messys.ObjectRegister 主键,冗余在 Tree.ObjectID
分配方式 UniqueNO(NName=’tree’)递增 MAX(ObjectID)+1
前端 zTree 字段 id objectId
是否用于 STPermission「执行」
复制菜单 重新分配 重新分配

5.1 业务 ObjectID 与 NodeID 的非 OwnerID 关联

菜单授权与 ERP 按钮授权使用不同的 ObjectID,且业务对象的 OwnerID 不一定等于 Tree.NodeID

场景 ObjectID 示例 TypeID OwnerID STPermission 用途
菜单对象 468 7 430 Oprate=执行, Permission=1
业务对象 965 1 null Oprate=EX61:..., Permission=0

解析路径EosMenuObjectResolver.resolveBusinessObjects):

  1. ObjectRegister.OwnerID = NodeIDTypeID != 7
  2. Tree.Functions 括号内单据名 + 菜单对象名 → DjDy.DjCNameObjectRegister.Object = DjCNameTypeID != 7
  3. 回退:Tree.ObjectID 对应 ObjectRegister(可能含 TypeID=7

禁止仅用 OwnerID=NodeIDTree.ObjectID 推断按钮授权 ObjectID。复合页可能返回多个业务 ObjectID;同一 ObjectID 上可有多个 EXxx: 按钮 Oprate。

listAvailableOperations:标准操作 + ExFunction EXxx: + 库中已有非「执行」Oprate。

示例(NodeID=430):菜单树 objectId=468 用于勾选「执行」;按钮 EX61:组织架构分发 写在 ObjectID=965。


6. 后端组装与 API

6.1 权限菜单树

  • 接口GET /eosrole/menu/tree(或 @RequestMapping
  • 实现EosRoleController.menuTree()TreeService.listTreeForPermission()
  • 返回字段
字段 来源 说明
id Tree.NodeID zTree 节点 ID
pId Tree.ParentID(0 → -1) 父节点
name Tree.NodeCaption 显示名
objectId Tree.ObjectID STPermission「执行」键
menuType EosMenuTypeHelper.resolveMenuType mes / erp / folder
sysMenuId sys_menu_eos_node,缺失时 NodeDesc fallback 仅 MES 节点有值
1
2
3
4
5
6
7
// TreeServiceImpl.listTreeForPermission()
m.put("id", e.getNodeid());
m.put("pId", e.getParentid() == null || e.getParentid() == 0 ? -1 : e.getParentid());
m.put("name", e.getNodecaption() != null ? e.getNodecaption().trim() : "");
m.put("objectId", e.getObjectid());
m.put("menuType", EosMenuTypeHelper.resolveMenuType(e));
m.put("sysMenuId", sysMenuIdLookup.get(e.getNodeid()));

listTreeForSelect()(eostree 选目录)的区别:后者不含 objectId / menuType / sysMenuId,仅 id / pId / name

6.2 权限查询与保存

接口 作用
GET /eosrole/permission/{roleId} 返回已授权 objectId 列表(「执行」+ Permission=1)
GET /eosrole/permission/detail/{roleId}?nodeId= 按 NodeID 加载对象/按钮详情(MES 或 ERP)
GET /eosrole/permission/mes-menu-ids/{roleId} 返回 MES sys_role_menu 全部 menuId
POST /eosrole/permission/save 菜单执行 + ERP 操作 + MES 按钮

EosRolePermissionServiceImpl.queryMenuObjectIds 过滤条件:Oprate=执行Permission=1当前未按 TypeID=7 过滤)。

save body(EosRolePermissionSaveRequest):

字段 说明
roleIds EOS 角色 OID
objectIds 勾选菜单的 Tree.ObjectID → STPermission「执行」
mode append / replace
mesMenuIds MES 目录/菜单 menu_id → sys_role_menu
mesButtonMenuIds MES 按钮 menu_id → sys_role_menu
operationPermissions ERP {objectId, oprate, granted}
operationReplaceObjectIds replace 时清理非「执行」行的业务 ObjectID

保存委托:先 EosRolePermissionServiceImpl 写「执行」,再 EosRoleObjectPermissionServiceImpl.saveMesAndObjectPermissions 写 ERP/MES。


7. 前端使用(eosrole.js)

7.1 zTree 配置

1
2
3
4
5
6
7
8
9
10
11
var permissionTreeSetting = {
data: {
simpleData: {
enable: true,
idKey: "id", // = NodeID
pIdKey: "pId", // = ParentID
rootPId: -1
}
},
check: { enable: true, nocheckInherit: true }
};

7.2 加载与回显

  1. loadPermissionMenuTree → 请求 /eosrole/menu/tree,用 treeList 初始化 zTree(含 menuType / sysMenuId
  2. 单角色 + replace 模式:
    • /eosrole/permission/{roleId} → 按 objectId 勾选菜单树(不是 id
    • /eosrole/permission/mes-menu-ids/{roleId} → 拆分 MES 菜单 ID / 按钮 ID 到 permissionMesMenuIds
  3. 点击节点 → /eosrole/permission/detail/{roleId}?nodeId=
    • menuType=mes:展示 MES 按钮勾选
    • menuType=erp:展示 ERP 操作「禁止」勾选
    • menuType=folder:目录摘要

勾选 MES 节点时把 sysMenuId 加入 permissionMesMenuIds;取消勾选时清理对应按钮态。

7.3 保存

savePermission 收集并提交:

收集方法 字段
collectPermissionObjectIds() objectIds(勾选节点的 objectId,不是 id
collectMesMenuIdsForSave() mesMenuIds
collectMesButtonMenuIdsForSave() mesButtonMenuIds
collectOperationPermissionsForSave() operationPermissions
collectOperationReplaceObjectIdsForSave() operationReplaceObjectIds

连同 roleIdsmode 一并 POST 到 /eosrole/permission/save


8. 验证 SQL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- NodeID 与 ObjectID 对照
SELECT
t.NodeID,
RTRIM(t.NodeCaption) AS MenuCaption,
t.ParentID,
t.ObjectID AS TreeObjectID,
o.ObjectID AS RegObjectID,
o.TypeID,
o.OwnerID
FROM messys.dbo.Tree t
LEFT JOIN messys.dbo.ObjectRegister o ON o.OwnerID = t.NodeID
ORDER BY t.NodeID;

-- UniqueNO 当前序列
SELECT NName, No FROM messys.dbo.UniqueNO WHERE NName = 'tree';

9. 相关代码路径

环节 路径
NodeID 分配 TreeServiceImpl.getNextNodeIdForTree()
ObjectID 分配 TreeServiceImpl.saveObjectRegisterForTree()
新增/同步/复制 TreeServiceImpl.addNode / syncFromSysMenu / copyMenu
权限树 API TreeServiceImpl.listTreeForPermission()EosRoleController
菜单类型 / sysMenuId EosMenuTypeHelperSysMenuEosNodeService
菜单「执行」读写 EosRolePermissionServiceImpl
ERP/MES 扩展保存 EosRoleObjectPermissionServiceImpl
业务 ObjectID 解析 EosMenuObjectResolver
实体 TreeEntityObjectRegisterEntityStPermissionEntity
前端 static/js/modules/security/eosrole.js

10. 修订记录

日期 说明
2026-06-16 初版:梳理 Tree NodeID 与 ObjectID 从数据库到前端权限树的完整链路
2026-06-16 补充 NodeID 在 Tree.Functions URL 中作为 menuId 参数的说明
2026-07-01 补充业务 ObjectID 与 NodeID 非 OwnerID 关联及 eosrole 解析路径
2026-07-31 按最新实现修订:权限树补 menuType/sysMenuId;save/前端补 MES 与 ERP 扩展字段;代码路径补 ObjectPermission / Resolver

EOS 菜单与角色关联关系说明

本文档说明 MES 项目中 EOS 原生权限体系与 MES Web RBAC 的关系,以及角色、菜单数据分别存储在哪里、如何保存关联。

2026-07-31 更新:按当前代码实现修订。eosrole 已映射并读写 **STPermission**(菜单「执行」+ ERP 对象操作)与 **STUserGroup**(用户-角色);MES Web 按钮权限写入 **sys_role_menu**。核心授权表仍为 **mesdata.dbo.STPermission**。

关联文档:EOS 菜单树 NodeID 与 ObjectID 说明

结论摘要

**在本项目(mes-parent)中,EOS 角色 ↔ 菜单授权可由 MES eosrole「配置菜单权限」写入 STPermission**;也可在 EOS 原生安全管理器中配置。用户 ↔ 角色由 eosrole「配置用户权限」双写 STUserGroup + sys_user_role

能力 MES 是否实现
EOS 用户/角色 mesdata STUsersuGroup=0/1 角色 CRUD(eosrole)
用户 ↔ 角色 mesdata STUserGroup 已映射,由 EosRoleUserServiceImpl 管理(双写 sys_user_role
角色 ↔ 菜单 mesdata STPermission 已映射,由 EosRolePermissionServiceImpl / EosRoleObjectPermissionServiceImpl 读写
EOS 菜单树 messys Tree + ObjectRegister eostree 维护/同步
EOS 角色 → MES 角色 mesdata sys_roleeos_role_id 同步元数据;权限保存时也可自动 syncRole
MES 角色 → MES 菜单/按钮 mesdata sys_role_menu 角色管理页面;eosrole 保存 MES 按钮时亦写入
EOS NodeID → MES menu_id mesdata sys_menu_eos_node sync/backfill/copy 写入

EOS 原生权限生效链路:

1
2
3
4
5
6
STUsers(用户,uGroup=0)
→ STUserGroup(UserID → GroupID)
→ STUsers(角色,uGroup=1)
→ STPermission(UserID=角色OID, ObjectID)
→ messys.ObjectRegister(TypeID=7)
→ messys.Tree(OwnerID=NodeID)

1. EOS 侧数据模型

1.1 用户与角色:STUsers(mesdata)

角色与用户共用 mesdata.dbo.STUsers,通过 uGroup 区分:

uGroup 含义
0 用户
1 角色

相关代码:StusersEntityStusersServiceImpl.saveRole / updateRoleEosRoleController(路径 /eosrole)。

eosrole 页面「保存角色」只写角色基本信息(编码、名称、描述、分组 Categories、启用状态),不涉及菜单勾选。菜单与对象操作权限在「配置菜单权限」弹窗中单独保存(见 §2.3);用户分配在「配置用户权限」中保存(见 §2.5)。

EmpowermentRightRelateUserH 等字段在 MES 新增角色时仅填默认值,不用于菜单授权;菜单授权走 STPermission

1.2 用户-角色:STUserGroup(mesdata)

字段 含义
UserID 用户 OID(STUsers.OIDuGroup=0
GroupID 角色 OID(STUsers.OIDuGroup=1
Back 备注

MES 已映射:StUserGroupEntity + EosRoleUserServiceImpl。eosrole「配置用户权限」保存时:

  1. 清空该角色在 STUserGroup 中的旧关联,再批量插入新用户
  2. STUsers.UserIDsys_user.username 匹配 MES 用户;有 MES 用户时先 ensureMesRole,再全量改写 sys_user_role

也可在 EOS 原生安全管理中分配角色(同样写入 STUserGroup)。

1.3 菜单:Tree + ObjectRegister(messys)

作用
Tree messys EOS Web 菜单树(NodeID、ParentID、NodeCaption、Functions 等)
ObjectRegister messys 对象注册;OwnerID = Tree.NodeIDTypeID = 7 表示菜单/目录
UniqueNO messys 分配 Tree 的 NodeID(NName='tree'

新增菜单节点时(TreeServiceImpl.addNode)会:

  1. UniqueNO 分配新 NodeID
  2. 写入 Tree
  3. 写入 ObjectRegister,并将返回的 ObjectID 回填到 Tree.ObjectID

从 MES 同步菜单时(TreeServiceImpl.syncFromSysMenu),同样会为每个节点创建 ObjectRegister 记录。

数据库 schema 配置见 mes-web/src/main/resources/schema.properties

1
eossys.schema=messys.dbo

1.4 角色-菜单关联:STPermission(mesdata)

核心授权表。EOS 原生安全管理器与 MES eosrole「配置菜单权限」保存时均写入此表。

字段 类型 含义
UserID int STUsers.OID;绝大多数为角色(uGroup=1),少量为用户直授(uGroup=0
ObjectID int messys.dbo.ObjectRegister.ObjectID
Oprate nvarchar 操作类型(见下表)
Permission int 权限值;含义随 Oprate 类型不同(见下表)

ERP 模式下 Permission 双语义(本环境 WebPermission 未启用,按钮授权均走 STPermission):

Oprate 类型 示例 Permission 含义
菜单 执行 1 允许可见(白名单;无记录=不可见)
按钮/操作 增加EX61:组织架构分发 0 禁用(黑名单;无记录=允许)

常见 Oprate 取值:执行(菜单);标准操作(增加、修改、删除、审核…);自定义 EX{ExFunction.ID}:{SDesc}(如 EX61:组织架构分发)。

菜单授权路径:

1
2
3
STPermission(ObjectID, Oprate='执行', Permission=1)
→ ObjectRegister (TypeID=7, OwnerID=Tree.NodeID)
→ Tree.NodeCaption

MES 读写实现:

服务 职责
EosRolePermissionServiceImpl 查询/保存菜单「执行」(objectIds + mode
EosRoleObjectPermissionServiceImpl ERP 对象操作(operationPermissions)+ MES 按钮(sys_role_menu

queryMenuObjectIds 过滤条件:Oprate=执行Permission=1当前未按 ObjectRegister.TypeID=7 过滤)。

1.5 ERP 按钮权限(ExFunction + DjDy)

层级 粒度 存储
按钮定义 每个 ExFunction 一条 messys.ExFunctionNote1 like 'button%'
授权 ObjectID 每个单据(DjDy)一个 ObjectRegister.Object = DjDy.DjCNameTypeID != 7(OwnerID 可为 null)
授权 Oprate 每个按钮一个 EX{ID}:{SDesc};同一 ObjectID 多行 = 同单据多按钮

链路:

1
2
3
4
5
Tree.Functions(如 单据(组织架构))
→ DjDy(DjCName=组织架构, DjDm=303)
→ ExFunction(SType=DJ, SID=DjDm)→ Oprate=EX61:组织架构分发
→ ObjectRegister(Object=组织架构, ObjectID=965, TypeID=1)
→ STPermission(UserID, ObjectID=965, Oprate, Permission=0 表示禁用)

复合单据示例(Tree NodeID=430)

用途 ObjectID TypeID 说明
菜单「执行」 468 7 OwnerID=430,名「组织机构关系表」
按钮 EX61 965 1 OwnerID=null,名「组织架构」,与菜单 ObjectID 不同

同一 DjDm 下多个 ExFunction(如 DjDm=212 的 EX13/EX14/EX16/EX17)共用同一业务 ObjectID,以不同 Oprate 区分。

业务 ObjectID 解析见 EOS 菜单树 NodeID 与 ObjectID 说明 §5.1(EosMenuObjectResolver)。

说明WebPermission 本环境未启用;SType=CX 且安全管理器不可见的 STPermission 记录(如 EX10:查看JSON)视为历史垃圾数据。

当前环境数据量(仅供参考)

记录数 说明
STPermission ~1625 主路径(角色 ~1595,用户直授 ~30)
WebPermission 0 Web 对象权限(RoleID + ObjID),本环境未使用
STDomainPermission 0 域-菜单节点(DomainID + MenuNodeID),本环境未使用

1.6 跨库关系图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
┌──────────────────────── mesdata ────────────────────────┐
│ STUsers (uGroup=0 用户 / uGroup=1 角色) │
│ ↑ UserID ↑ GroupID │
│ STUserGroup ──────────────┘ │
│ ↑ UserID (角色 OID) │
│ STPermission (ObjectID, Oprate, Permission) │
│ sys_role / sys_role_menu / sys_menu_eos_node │
└──────────────────────────│ ObjectID ──────────────────────┘

┌──────────────────────── messys ─────────────────────────┐
│ ObjectRegister (ObjectID, TypeID=7, OwnerID=NodeID) │
│ ↑ OwnerID │
│ Tree (NodeID, NodeCaption, ParentID, ObjectID) │
└─────────────────────────────────────────────────────────┘

2. MES 侧数据模型

2.1 角色-菜单:sys_role_menu

MES Web「角色管理」(role.html + role.js)通过 zTree 勾选菜单,提交 menuIdList/sys/role/save/sys/role/update

保存逻辑(SysRoleMenuServiceImpl.saveOrUpdate):

  1. role_id 删除原有关联
  2. 批量插入新的 (role_id, menu_id) 记录

权限生效链路:

1
sys_user → sys_user_role → sys_role → sys_role_menu → sys_menu

eosrole 保存 MES 菜单/按钮时也会写入同一张表(见 §2.3)。

2.2 EOS 角色同步到 MES

EosRoleSyncServiceImpl / 定时任务 EosTask.sycnEosRole() 调用:

  • sysRoleService.saveWithoutMenu() — 新建 MES 角色
  • sysRoleService.updateWithoutMenu() — 更新 MES 角色

同步字段:角色名、描述、分组、eos_role_id定时/手动同步本身不会同步 EOS STPermission 或 MES sys_role_menu

若在 eosrole「配置菜单权限」中提交了 mesMenuIds / mesButtonMenuIds,且尚无对应 MES 角色,会自动 syncRole 后再写 sys_role_menu

2.3 eosrole「配置菜单权限」

eosrole 弹窗支持统一配置:

菜单类型 识别 保存位置
ERP 原生 Functions 不含「函数打开网页」(menuType=erp 菜单 → STPermissionOprate=执行, Permission=1);按钮 → STPermissionEXxx:... 等, Permission=0=禁用)
MES Web Functions 含「函数打开网页」(menuType=mes),sys_menu_eos_nodemenu_ideos_node_id 菜单执行 → STPermission;按钮 → sys_role_menu
目录 menuType=folder 通常仅作树结构;勾选子节点时汇总子菜单 objectId

相关 API(EosRoleController,权限 eosrole:permission):

方法 路径 作用
* /eosrole/menu/tree 权限菜单树(含 objectId / menuType / sysMenuId
GET /eosrole/permission/{roleId} 已授权菜单 objectId(执行+Permission=1)
GET /eosrole/permission/detail/{roleId}?nodeId= 节点对象/按钮权限详情
GET /eosrole/permission/mes-menu-ids/{roleId} 回显 MES 角色全部 sys_role_menu menuId
POST /eosrole/permission/save 保存菜单执行 + ERP 操作 + MES 按钮
* /eosrole/menu/backfill-mes-menu-id 历史 MES 节点回填 sys_menu_eos_node

POST /eosrole/permission/save body(EosRolePermissionSaveRequest):

字段 说明
roleIds EOS 角色 OID 列表
objectIds 勾选菜单的 Tree.ObjectIDSTPermission「执行」
mode append / replace
mesMenuIds MES 目录/菜单 menu_idsys_role_menu
mesButtonMenuIds MES 按钮 menu_idsys_role_menu
operationPermissions {objectId, oprate, granted};ERP 禁止列表(granted=false 写 Permission=0)
operationReplaceObjectIds replace 时需清理非「执行」权限的业务 ObjectID

保存流程:

  1. EosRolePermissionServiceImpl.savePermissions(roleIds, objectIds, mode) — 写菜单「执行」
  2. EosRoleObjectPermissionServiceImpl.saveMesAndObjectPermissions(request) — ERP 操作 + MES 按钮

mode=replace 时:先按该角色已有「执行」的 ObjectID 删除这些 ObjectID 下全部 Oprate 行,再插入勾选的「执行」;mesMenuIdsmesButtonMenuIds 都为空时不改动 sys_role_menu

说明Tree.Functions 里 URL 的 menuId=EOS NodeID(页面跳转用);sys_menu.menu_id 的权威映射在 **mesdata.sys_menu_eos_node**(eos_node_idmenu_id),由 syncFromSysMenu 写入或 backfillSysMenuEosNode 按 URL/NodeDesc 回填。过渡期仍双写 NodeDesc=MES_MENU:{sysMenuId} 作兼容 fallback。

建表与历史迁移脚本:sys_menu_eos_node.sqlsys_menu_eos_node.mysql.sql(位于 mes-security-eos 模块 doc/)。

2.4 MES 菜单管理「设置到 EOS」

MES 菜单管理页(sys/menu)勾选目录/菜单后点击「设置到 EOS」,调用 POST /tree/syncFromSysMenumenu.js#setToEos)。

步骤 行为
1 用户选择 EOS 目标目录 parentNodeId
2 TreeServiceImpl.syncFromSysMenu 为每个 type=0/1 的 sys_menu 新建 EOS Tree 节点
3 applySysMenuMapping 写入 sys_menu_eos_node,并双写 NodeDesc=MES_MENU:{sysMenuId}(目录与菜单均写)
4 type=1 且有 url 时,Functions 生成 MES Web 跳转 URL,其中 menuId= 为新分配的 EOS NodeID

历史已同步但未写映射的节点,可任选以下方式处理(当前 sync 始终新建节点,不更新旧节点):

方式 说明
定时任务 EosTask.backfillSysMenuEosNode,默认每日 3:00(t_qrtz_schedule_job;升级见 V2__Update_backfill_sys_menu_eos_node_job.sql
手动接口 /eosrole/menu/backfill-mes-menu-id
重新同步 菜单管理页「设置到 EOS」(会新建节点)
SQL 迁移 执行 sys_menu_eos_node.sql 从 NodeDesc 导入历史映射

定时任务与手动接口共用 TreeService.backfillSysMenuEosNode()局限:仅对尚无映射记录的节点回填;URL 匹配仅适用于 Functions 含「函数打开网页」的 MES Web 菜单;type=0 目录(Functions 为空)若 NodeDesc 也无映射,需重新「设置到 EOS」。

2.5 eosrole「配置用户权限」

方法 路径 权限 作用
GET /eosrole/users/assigned/{roleId} eosrole:user 已授权用户(合并 EOS + MES)
GET /eosrole/users/unassigned/{roleId} eosrole:user 待授权用户
POST /eosrole/users/save eosrole:user 双写 STUserGroup + sys_user_role

3. 两套体系对照

维度 EOS 原生 MES Web
用户/角色表 mesdata.STUsers sys_user / sys_role
用户-角色 mesdata.STUserGroup sys_user_role
菜单表 messys.Tree + ObjectRegister sys_menu
角色-菜单关联 mesdata.STPermission sys_role_menu
MES 页面维护 eosrole(菜单+ERP 对象操作+MES 按钮+用户)/ eostree 角色管理(含菜单授权)
跨系统同步 EOS → MES 同步角色元数据;eosrole 保存时可统一写两侧 可与 eosrole 统一配置

4. 查询 SQL 示例

以下 SQL 在 SQL Server 上验证可用;跨库查询需当前连接对 mesdatamessys 均有读权限。

4.1 查看某角色的菜单权限(含菜单名)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
-- @RoleOID: STUsers.OID,且 uGroup = 1
DECLARE @RoleOID INT = 3;

SELECT
r.OID AS RoleOID,
r.UserName AS RoleName,
p.ObjectID,
o.[Object] AS ObjectName,
o.TypeID,
t.NodeID,
RTRIM(t.NodeCaption) AS MenuCaption,
p.Oprate,
p.Permission
FROM mesdata.dbo.STUsers r
JOIN mesdata.dbo.STPermission p ON p.UserID = r.OID
JOIN messys.dbo.ObjectRegister o ON p.ObjectID = o.ObjectID
LEFT JOIN messys.dbo.Tree t ON o.OwnerID = t.NodeID
WHERE r.OID = @RoleOID
AND r.uGroup = 1
AND o.TypeID = 7 -- 菜单/目录
ORDER BY t.NodeID, p.Oprate;

4.2 查看某用户通过角色继承的菜单(完整链路)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-- @UserOID: STUsers.OID,且 uGroup = 0
DECLARE @UserOID INT = 11;

SELECT
u.UserName AS UserName,
r.UserName AS RoleName,
RTRIM(t.NodeCaption) AS MenuCaption,
p.Oprate,
p.Permission
FROM mesdata.dbo.STUsers u
JOIN mesdata.dbo.STUserGroup ug ON ug.UserID = u.OID
JOIN mesdata.dbo.STUsers r ON ug.GroupID = r.OID AND r.uGroup = 1
JOIN mesdata.dbo.STPermission p ON p.UserID = r.OID
JOIN messys.dbo.ObjectRegister o ON p.ObjectID = o.ObjectID AND o.TypeID = 7
JOIN messys.dbo.Tree t ON o.OwnerID = t.NodeID
WHERE u.OID = @UserOID
AND u.uGroup = 0
AND p.Oprate = N'执行' -- 菜单可见通常对应「执行」
ORDER BY r.UserName, t.NodeID;

4.3 统计各角色的菜单授权数量

1
2
3
4
5
6
7
8
9
10
11
SELECT
r.OID,
r.UserName AS RoleName,
COUNT(DISTINCT p.ObjectID) AS MenuObjectCount,
COUNT(*) AS PermissionRowCount
FROM mesdata.dbo.STUsers r
JOIN mesdata.dbo.STPermission p ON p.UserID = r.OID
JOIN messys.dbo.ObjectRegister o ON p.ObjectID = o.ObjectID AND o.TypeID = 7
WHERE r.uGroup = 1
GROUP BY r.OID, r.UserName
ORDER BY MenuObjectCount DESC;

4.4 查找拥有某菜单权限的所有角色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- @MenuNodeID: messys.dbo.Tree.NodeID
DECLARE @MenuNodeID INT = 17;

SELECT DISTINCT
r.OID,
r.UserName AS RoleName,
RTRIM(t.NodeCaption) AS MenuCaption,
p.Oprate
FROM messys.dbo.Tree t
JOIN messys.dbo.ObjectRegister o ON o.OwnerID = t.NodeID AND o.TypeID = 7
JOIN mesdata.dbo.STPermission p ON p.ObjectID = o.ObjectID
JOIN mesdata.dbo.STUsers r ON p.UserID = r.OID AND r.uGroup = 1
WHERE t.NodeID = @MenuNodeID
ORDER BY r.UserName, p.Oprate;

4.5 对比 EOS 角色与 MES 角色(不含菜单)

1
2
3
4
5
6
7
8
9
10
11
SELECT
sr.role_id,
sr.role_name AS MesRoleName,
sr.eos_role_id,
er.UserName AS EosRoleName,
er.OID AS EosRoleOID
FROM mesdata.dbo.sys_role sr
LEFT JOIN mesdata.dbo.STUsers er
ON sr.eos_role_id = er.OID AND er.uGroup = 1
WHERE sr.eos_role_id IS NOT NULL
ORDER BY sr.role_id;

4.6 检查菜单节点是否已在 ObjectRegister 注册

1
2
3
4
5
6
7
8
9
SELECT
t.NodeID,
RTRIM(t.NodeCaption) AS MenuCaption,
t.ObjectID,
o.ObjectID AS RegObjectID,
o.TypeID
FROM messys.dbo.Tree t
LEFT JOIN messys.dbo.ObjectRegister o ON o.OwnerID = t.NodeID
ORDER BY t.NodeID;

5. 相关代码路径

模块 路径
EOS 角色实体 mes-security-eos/.../entity/StusersEntity.java
EOS 角色服务 mes-security-eos/.../service/impl/StusersServiceImpl.java
EOS 角色同步 mes-security-eos/.../service/impl/EosRoleSyncServiceImpl.java
EOS 菜单树 mes-security-eos/.../service/impl/TreeServiceImpl.java
菜单「执行」权限 mes-security-eos/.../service/impl/EosRolePermissionServiceImpl.java
ERP/MES 对象与按钮 mes-security-eos/.../service/impl/EosRoleObjectPermissionServiceImpl.java
用户-角色 mes-security-eos/.../service/impl/EosRoleUserServiceImpl.java
业务 ObjectID 解析 mes-security-eos/.../support/EosMenuObjectResolver.java
实体 StPermissionEntityStUserGroupEntityTreeEntityObjectRegisterEntity
前端 static/js/modules/security/eosrole.js
MES 角色-菜单 mes-core/.../service/impl/SysRoleMenuServiceImpl.java
NodeID ↔ menu_id sys_menu_eos_node + SysMenuEosNodeService
sys_menu → Tree SQL doc/sql/sys_menu_to_eos_tree.sql

本环境未使用的 EOS 权限表(可扩展)

说明
WebPermission Web 对象细粒度权限(RoleID + ObjID + Operate)
STDomainPermission 域 ↔ Tree.NodeID

6. 运维与开发建议

  1. EOS 客户端菜单权限:可在 EOS 原生安全管理中配置,也可在 MES eosrole「配置菜单权限」中配置;数据均写入 mesdata.dbo.STPermission。运维排查可用上文 SQL。
  2. MES 页面权限:可在「系统管理 → 角色管理」勾选 sys_menu;也可在 eosrole 中为 MES Web 菜单勾选按钮(写入同一 sys_role_menu)。菜单「执行」可见性仍依赖 STPermission
  3. 两套菜单数据源
    • Tree / ObjectRegister:EOS 客户端 / Web 壳菜单
    • sys_menu:MES 页面与 Shiro 权限
    • eosrole 可在同一弹窗统一配置两侧,但没有STPermission 自动全量同步到 sys_role_menu(或反向)的后台任务;MES 按钮仅在 eosrole 保存时写入。
  4. 从 EOS 同步角色后:若需在 MES Web 中使用该角色的菜单/按钮,可在角色管理中分配,或在 eosrole 配置菜单权限时一并提交 mesMenuIds / mesButtonMenuIds
  5. 跨库注意STUsersSTPermissionSTUserGroupsys_*mesdataTreeObjectRegistermessys,关联字段为 STPermission.ObjectIDObjectRegister.ObjectID

7. 修订记录

日期 说明
2026-06-15 初版:基于 mes-parent 代码梳理 EOS / MES 角色菜单关系
2026-06-16 eosrole 扩展:ERP 对象操作权限 + MES 按钮权限统一配置
2026-07-01 补充 ERP 按钮权限:STPermission 双语义、ExFunction/DjDy 链路、965/468 复合单据示例;WebPermission 未启用
2026-07-31 按最新实现修订:STPermission/STUserGroup 已映射;统一结论/§5/§6 口径;补 save body(含 operationReplaceObjectIds)、用户权限 API、相关代码路径

瘦身密码(五):甜蜜陷阱——肥胖引爆的八大健康地雷

肥胖是健康的「隐形杀手」——影响的不只是外形,而是心血管、代谢、内分泌、呼吸、骨骼、生殖乃至心理的全系统连锁反应。以下梳理书中重点阐述的八大健康地雷及应对思路。


1. 糖尿病:胰岛素遇上甜甜圈

中国 20~79 岁人群糖尿病患病率约 10.6%,患病人数约 1.41 亿。肥胖与糖尿病如影随形:

  • 体重每增加 1 kg,糖尿病风险至少升 5%
  • 约 50% 肥胖者将来可能患 2 型糖尿病
  • 糖尿病患者中约 2/3 超重或肥胖

机制:内脏脂肪像「棉袄」包裹细胞,胰岛素(钥匙)难以与受体(锁)结合,葡萄糖进不了细胞 → 胰岛素抵抗 → 代偿性高胰岛素 → 食欲增加 → 更胖 → 最终血糖失控。

逆转密码

  • 少吃深加工食品、奶茶炸鸡;多吃蔬菜、粗粮
  • 中低强度有氧运动,餐后 30~60 分钟,每次 ≥30 分钟,约 200~300 千卡
  • 超重人群 35~70 岁应每 3 年筛查血糖
  • 九体医学统计:气虚质、阴虚质、痰湿质最易患糖尿病

2. 冠心病:糖脂风暴下的冠状动脉

冠心病患者超重/肥胖率超 50%。BMI 越高,冠心病发病率越高;肥胖者患病概率约为常人 2~3 倍,超平均体重 40% 者死亡风险翻倍。

机制:肥胖 → 血脂紊乱 → 动脉粥样硬化斑块 → 冠脉狭窄 → 心肌缺血。心脏如同小发动机驱动重型卡车,长期超负荷终将「罢工」。

逆转密码:减重 + 控脂 + 戒烟限酒 + 规律运动;编写细胞层面的「燃脂程序」,减轻心脏负担。


3. 睡眠呼吸暂停:内脏脂肪的午夜叛乱

腹型肥胖者脂肪堆积在呼吸道周围,气道变窄,睡眠时呼吸暂停 → 缺氧 → 睡眠质量差 → 日间嗜睡 → 活动减少 → 更胖,形成死亡循环

逆转密码:减重是核心;侧睡、避免睡前饮酒;严重者需呼吸机等医学干预。


4. 脂肪肝:内脏的「垃圾处理厂」瘫痪

超重/肥胖者并发症中,脂肪肝最常见之一。肝脏本应将脂肪打包运出,糖尿病与肥胖使这一过程效率降低,脂肪在肝内堆积。

常见认知陷阱(书中强调):

  • 「不胖就不会脂肪肝」——瘦人脂肪肝也不少见
  • 「无症状就不用管」——可进展为肝纤维化
  • 「只吃素就能好」——关键在于总能量与代谢
  • 「护肝片够用了」——病因不除,难以逆转

逆转密码:减重 5%~10% 常可显著改善肝脂肪变;控糖控脂 + 运动。


5. 骨关节炎:关节的载荷安全阈值

体重每增加 1 kg,膝关节承受压力约增加 3~4 kg。肥胖 → 慢性炎症 → 软骨磨损加速。

逆转密码:减重减轻关节负荷;水中运动、肌力训练增强关节稳定性。


6. 多囊卵巢综合征:激素风暴

肥胖与多囊卵巢相互加剧:脂肪组织干扰激素平衡,胰岛素抵抗推高雄激素,影响排卵与生育。

逆转密码:减重 5%~10% 可显著改善月经与排卵;生活方式干预是一线治疗。


7. 乳腺癌:癌变风险的土壤

肥胖改变雌激素等激素水平,脂肪组织释放炎症因子,为癌细胞生长提供「土壤」。腹型肥胖与多种妇科、消化道肿瘤风险相关。

逆转密码:保持健康体重、规律筛查、减少久坐。


8. 心理沼泽:身材焦虑与情绪雪崩

肥胖与心理相互纠缠:

  • 自尊心、自我形象受损
  • 焦虑 → 暴食 → 更胖 → 更焦虑
  • 脂肪组织炎症因子可能影响大脑情绪通路
  • 社会偏见与「体型歧视」加重心理负担
  • 极端节食或暴食交替,饮食成为情绪的「翻译器」

逆转密码:接纳与改变并行;寻求心理咨询;用运动、社交替代情绪性进食;体重管理应是关爱自己,而非自我惩罚。


九体视角下的并发症预防

不同体质易患不同慢病,调理应有的放矢:

体质 相关风险
痰湿质 肥胖、高血压、糖尿病、高血脂
气虚质 感冒、内脏下垂、乏力
阳虚质 畏寒、腹泻、痹证
阴虚质 失眠、咽痛、「三高」
血瘀质 肿瘤、痛证、卒中
气郁质 甲状腺、乳腺疾病、情绪障碍

体质可调——在并发症尚未形成前调体,是最好的「逆转密码」。


系列结语

《瘦身密码》传递的核心信息可以概括为三句话:

  1. 中国肥胖形势严峻,腰围与 BMI 同样值得每日关注
  2. 科学减肥是马拉松,忌节食、代餐、极端断食
  3. 九体医学提供个体化路径——先识体质,再管体重,方能健康瘦身不反弹

2024 年国家「体重管理年」已经启程。愿我们都不再以「换大码裤子」为常态,而是在读懂自己身体密码的基础上,走出属于自己的健康之路。

瘦身密码(四):九大体质科学甩肉指南——管体加管重

核心理念:管体 + 管重

  • 管体:辨识体质、纠正偏颇——体质调好了,赘肉才不容易反弹
  • 管重:吃对食物比盲目少吃更重要;体重是体质的一面镜子,但不是唯一指标

同样体重的人,体脂率、肌肉量不同,健康状况可以天差地别。短期节食难持久,结合体质的长期调理才是正道。


平和质:别把好体质作没了

特征:体形匀称,精力充沛,患病少,适应力强。

要点

  • 膳食平衡,粗粮细粮搭配,寒温适中,七八分饱
  • 每天有氧运动约 30 分钟,或步行不少于 6000 步
  • 22:30 前入睡,春夏养阳、秋冬避风寒
  • 穴位保健:足三里、三阴交、涌泉

药膳举例:南瓜豆腐羹、芝麻山药粥


阳虚质:扶阳驱寒是关键

特征:怕冷、手足凉、夜尿多、精神不振,脂肪像给身体「穿羽绒服」。

要点

  • 避寒就温,多晒太阳,睡前 40~45℃ 泡脚 15 分钟
  • 宜羊肉、鸡肉、韭菜、核桃;少生冷、少苦寒苦瓜(可煮透减寒)
  • 运动选慢跑、太极拳、八段锦,微汗为度,忌大汗伤阳
  • 穴位:关元、命门、阳池

药膳举例:暖胃茶(红茶+桂圆+生姜+白术+红枣)、当归生姜羊肉汤


阴虚质:补水降火是核心

特征:口干咽燥、手足心热、盗汗、便干,体型偏瘦但血脂易偏高。

要点

  • 忌熬夜、桑拿、高温环境;室温 14~26℃ 为宜
  • 宜芝麻、蜂蜜、豆腐、鱼类;少辛辣燥烈、火锅
  • 运动选游泳、瑜伽、散步,避免大汗淋漓
  • 穴位:太溪、三阴交、大敦

药膳举例:三汁饮(黄精、生地、天门冬、茯苓)、冰糖五果羹


气郁质:疏肝解郁才能瘦

特征:多愁善感、胸闷叹息、睡眠差;一焦虑就暴食,压力肥堆腰腹

要点

  • 环境宜安静,春季多户外活动舒展阳气
  • 宜萝卜、洋葱、柑橘;玫瑰花、茉莉花代茶饮
  • 少芋艿、甘薯等易胀气食物
  • 推荐:玫瑰花茶 + 敲胆经,疏解肝郁

药膳举例:萝卜丝饼、玫瑰佛手茶


血瘀质:活血化瘀加速瘦身

特征:面色晦暗、唇舌黯、黑眼圈,肉硬腿粗,减肥进展慢如「挤牙膏」。

要点

  • 少食肥腻、寒凉,宜活血食物:山楂、黑豆、玫瑰花
  • 运动促进血液循环,避免久坐
  • 药浴泡脚 + 山楂茶是经典组合
  • 穴位:血海、膈俞、三阴交

痰湿质:祛湿排浊才是真抽脂

特征:体胖腹大、身重困倦、痰多、鼾声大,减肥易卡平台期。

要点

  • 饮食清淡:冬瓜、白萝卜、薏米、赤小豆;少甜腻、少暴饮暴食
  • 忌潮湿环境,宜阳光下午后运动
  • 按揉丰隆、足三里、中脘;红豆薏米汤、山药冬瓜汤
  • 古籍云:「肥人多痰湿」——祛湿比单纯节食更关键

湿热质:清火除湿瘦成清爽

特征:面油痤疮、口臭、便黏,脸油肚凸的「油胖子」。

要点

  • 宜冬瓜、绿豆、苦瓜、芹菜;忌辛辣、油炸、甜腻
  • 运动选中长跑、游泳等耗湿清热项目
  • 冬瓜汤、刮肝经,拒绝油腻感
  • 穴位:阴陵泉、曲池、委中

气虚质:补气提效懒人瘦身

特征:疲乏气短、声低懒言、易感冒,肉松垮像棉花。

要点

  • 宜山药、大枣、鸡肉、黄芪;忌过劳、过饱
  • 运动从散步、八段锦入手,循序渐进,忌大汗
  • 黄芪水 + 八段锦,提升运化效率再减重
  • 穴位:气海、脾俞、足三里

特禀质:温和调理避开雷区

特征:易过敏,减肥过激易诱发风团、喷嚏。

要点

  • 低敏饮食,避开已知过敏原
  • 运动环境清洁,避免花粉、尘螨密集处
  • 穴位按摩宜轻柔;中药调理需严格遵医嘱
  • 减肥方案宜缓不宜猛

通用运动时间表(可参考)

时段 建议 热量参考
6~9 点 慢跑、快走,微汗 200~300 千卡
12~14 点 午休 30~45 分钟,不宜剧烈运动
16~17 点 有氧操、骑行 300~400 千卡
20~22 点 瑜伽拉伸、仙人揉腹 50~100 千卡

写在最后

九体医学告诉我们:没有放之四海而皆准的减肥法。痰湿要祛湿,阳虚要温阳,气郁要疏肝,气虚要补气——先调体,再管重,才能瘦得健康、瘦得长久。

下一篇将聚焦肥胖引爆的八大健康地雷:糖尿病、冠心病、脂肪肝……早知早防。

瘦身密码(三):九体医学入门——解锁你的体质密码

世界上没有两片相同的树叶

九体医学以九种体质分类为指导,研究体质特征与疾病的相关性,从而指导预防、治疗与养生康复。王琦院士将人群科学分为九种类型:

体质 形象比喻 典型特征(口诀)
平和质 小太阳 气血匀,面红润,目光炯,元气振
气虚质 小懒猫 常气短,虚汗浸,懒言语,易疲晕
阳虚质 小冰块 手足冰,腰膝冷,舌淡胖,夜尿频
阴虚质 小火苗 颧潮红,五心热,口咽干,便秘困
痰湿质 小水库 体臃肿,大肚腩,鼾声大,腹胀闷
湿热质 小蒸笼 面油腻,痤疮丛,常口臭,便黏滞
血瘀质 小堵车 唇舌黯,黑眼圈,痛如刺,易长斑
气郁质 小气球 眉紧蹙,多善感,常郁闷,结节生
特禀质 小敏感 易过敏,风团起,喷嚏疾,泪涟涕

平和质是健康基准;其余八种为偏颇体质,如同八条通往特定疾病的道路——早发现、早调体,就能掉头往回走。

九体医学与精准医学

2015 年,王琦院士团队提出「九体医学健康计划」,被视为中国版「精准医学」:与奥巴马「精准医学」计划同年亮相,却更强调中医「治未病」「同病异治」思想。

  • 体质辨识已纳入《国家基本公共卫生服务标准》
  • 《中医体质分类与判定》量表已翻译成英、日、韩等多国语言
  • 覆盖全国 31 个省区,应用于健康管理、亚健康调理、慢病防控

古籍早有端倪:「肥人多痰湿」(朱丹溪)、「阴阳匀平……命曰平人」(《素问》)。王琦院士用 40 余年研究,将零散珍珠串成体系。

四大原理

  1. 体质过程论:体质随年龄阶段演变,养生应因时而异
  2. 形神构成论:躯体与心理一体,痰湿质者情绪稳定型居多
  3. 环境制约论:饮食、气候、地理塑造体质——嗜肥甘生痰湿,过逸成痰瘀
  4. 禀赋遗传论:先天禀赋决定体质底色,后天仍可调节

三大核心

  • 体质可分论:个体差异与群体趋同性并存
  • 体病相关论:痰湿质易患肥胖、三高;气虚质易感冒、内脏下垂;血瘀质易患肿瘤、痛证
  • 体质可调论:偏颇体质可通过饮食、起居、运动、情志干预改善

与肥胖的关系

肥胖与体质密切相关:

  • 痰湿质:中心性肥胖、高血脂、高血糖、高血压高发——「祛湿排浊才是真抽脂」
  • 气虚质:肉松垮、动则气短,减肥效率低
  • 阳虚质:怕冷,脂肪像「穿羽绒服」保温
  • 气郁质:压力肥,焦虑时暴食,肉易堆腰腹
  • 湿热质:脸油肚凸,「油胖子」需清火除湿
  • 血瘀质:肉硬、循环差,减肥像挤牙膏

国家 2024 年「体重管理年」方案明确发挥中医药技术优势;王琦院士「九体医学健康中国计划」正是体重个体化管理的理论基础。

如何判定自己的体质?

依据《中医体质分类与判定》标准:

1
2
原始分 = 各条目分值相加
转化分 = [(原始分 − 条目数) / (条目数 × 4)] × 100

平和质:转化分 ≥60,且其余 8 种均 <30(或均 <40 为「基本是」)

偏颇质:转化分 ≥40 为「是」;30~39 为「倾向是」

建议通过正规医疗机构或社区卫生中心的体质辨识服务获取准确结果,勿仅凭网络测试下定论。

体质不是终身标签

体质会随环境、饮食、情绪变化而调整。一方水土养一方人,养生需因人制宜、因时制宜——读懂身体密码,才能把健康主动权握在自己手里。

下一篇将进入实战:九大体质的科学甩肉指南,痰湿、湿热、阳虚……各有什么吃法、练法和穴位?