董哲
Published on 2025-09-09 / 56 Visits
1
0

iMOM 种子数据开发手册

一、 概述

1. 种子数据定义

“种子数据(Seed Data)”是指在系统初始化或模块上线时,预先导入的一组基础、标准化数据。这类数据通常不是用户动态录入的业务数据,而是系统运行所依赖的静态或半静态配置数据,具有如下特征:

● 具有系统级或平台级的通用性;

● 在不同环境(开发、测试、生产)中通常保持一致;

● 在部署初期或升级过程中需要初始化;

● 对功能运行起到支撑作用,缺失将导致功能异常或系统报错。

 

2. 使用场景

iMOM系统中的种子数据广泛用于以下典型场景:

场景

描述

系统首次部署

初始环境部署后加载基础数据,确保系统正常运行。

模块发布/功能上线

新模块上线时,附带其依赖的种子数据。

版本升级迁移

升级版本时,自动对比变更并注入新增种子数据。

新租户初始化

多租户场景中,为每个租户创建初始基础数据。

3. 数据注入生命周期

种子数据注入的生命周期分为以下几个关键阶段:

 

二、 字典参数

1、 定义类介绍

DictSeedData 实现了 SeedDataInitial<DictDefinition> 接口,并且需要加@Component注解,负责提供系统字典数据的初始种子定义。该类通过覆盖 getSeedData() 方法,返回一个包含若干 DictDefinition 对象的列表。

这些 DictDefinition 对象即为字典数据的具体条目,用于初始化系统中的字典项。

 

2、 定义示例

@Component
public class DictSeedData implements SeedDataInitial<DictDefinition> {
    @Override
    public List<DictDefinition> getSeedData() {
        return Arrays.asList(
            new DictDefinition() {{
                setAppInfo(AppEnum.IMES_CENTER);
                setCode("projectmanage");
                setSeq(1);
                setParentPath("imes.center.processmanage");
                setAppModule("imes.center.processmanage");
                setName("项目管理");
                setValue("projectmanage");
            }},
            new DictDefinition() {{
                setAppInfo(AppEnum.IMES_CENTER);
                setCode("projecttypet");
                setSeq(1);
                setParentPath("imes.center.processmanage.projectmanage");
                setAppModule("imes.center.processmanage");
                setName("项目类型");
                setValue("projecttypet");
            }}
        );
    }
}

3、 字段说明

字段名

类型/枚举

说明

AppInfo

AppEnum

所属应用系统标识,如 IMES_CENTER,方便区分不同应用模块的字典。

Code

String

字典项唯一标识码,建议使用有业务含义的英文字符串,作为字典的关键字。

Seq

Integer

排序号,决定该字典项在同级字典中的显示顺序。

ParentPath

String

上级字典的路径标识,支持多层级字典树结构,便于组织字典项层级关系。

AppModule

String

所属应用模块的路径,辅助字典数据归类管理。

Name

String

字典项名称,前端和业务中显示使用。

Value

String

字典值,实际存储和业务处理所使用的值。

 

4、 使用指南

● 新增字典项

在 getSeedData() 方法中添加新的 DictDefinition 对象,设置对应的字段值。建议保持 Code 唯一,避免重复。

● 多级字典结构

通过 ParentPath 字段定义父子关系,实现字典树形层级。如示例中 "projecttypet" 的 ParentPath 指向 "projectmanage",表示 它是“项目管理”字典项的子项。

● 排序展示

利用 Seq 字段控制同级字典项的排序顺序,数字越小,排序越靠前。

● 系统区分

AppInfo 与 AppModule 用于系统内部区分不同业务模块的字典数据,防止混淆和冲突。

 

三、 栏目菜单、按钮

1、 定义类介绍

MenuSeedData 实现了 SeedDataInitial<CatalogDefinition> 接口,用于初始化系统菜单(栏目、按钮)结构数据。它通过实现 getSeedData() 方法,返回一组 CatalogDefinition 实例,每条代表一个菜单资源节点。

 

2、 定义示例

public class CatalogSeedData implements SeedDataInitial<CatalogDefinition> {
    @Override
    public List<CatalogDefinition> getSeedData() {
        return Arrays.asList(
                new CatalogDefinition() {{
                    setId("SIECATELOG20250610001");
                    setCatalogName("工艺管理");
                    setCatalogKey("imes.center.processmanage");
                    setCatalogCode("processmanage");
                    setCatalogUrl("");
                    setCatalogType(CatalogTypeEnum.MODULE);
                    setAppInfo(AppEnum.IMES_CENTER);
                    setSeq(1);
                    setParentPath("imes.center");
                    setAppModule("imes.center.processmanage");
                }},
 
                new CatalogDefinition() {{
                    setId("SIECATELOG20250603002");
                    setCatalogName("EBOM管理");
                    setCatalogKey("imes.center.mpm.ebomManagement");
                    setCatalogCode("ebomManagement");
                    setCatalogUrl("ebom-management");
                    setCatalogPathname("imom-mpm/mpm/#/ebom-management");
                    setCatalogType(CatalogTypeEnum.MENU);
                    setAppInfo(AppEnum.IMES_CENTER);
                    setSeq(1);
                    setParentPath("imes.center.processmanage");
                    setAppModule("imes.center.processmanage");
                }},
                new CatalogDefinition() {{
                    setId("SIECATELOG20250603003");
                    setCatalogName("操作按钮");
                    setCatalogKey("imes.center.mpm.ebomManagementDetail");
                    setCatalogCode("ebomManagementDetail");
                    setCatalogUrl("ebom-management-detail");
                    setCatalogType(CatalogTypeEnum.BUTTON);
                    setAppInfo(AppEnum.IMES_CENTER);
                    setSeq(2);
                    setParentPath("imes.center.mpm.ebomManagement.ebomManagement");
                    setAppModule("imes.center.processmanage");
                }}
        );
    }
}

3、 字段说明

字段名

类型/枚举

说明

id

String

菜单唯一标识符(建议全局唯一,方便跟踪与比对)

catalogName

String

菜单显示名称,如“工艺管理”

catalogKey

String

菜单路径唯一键(全路径,建议采用“模块.功能.子项”的结构)

catalogCode

String

菜单编码,简写形式,一般对应前端路由或权限点

catalogUrl

String

菜单访问路径(前端路由地址,按钮为空)

catalogType

CatalogTypeEnum

菜单类型,分为 MODULE(模块)、MENU(菜单)、BUTTON(按钮)等

appInfo

AppEnum

所属系统枚举(如:IMES_CENTER)

seq

Integer

同级菜单显示排序(值越小,越靠前)

parentPath

String

父级菜单路径键(用于构建菜单树结构)

appModule

String

所属业务模块标识(用于系统内部归类)

 

4、 使用规范

类别

建议与规范

唯一性

id、catalogKey 全局唯一

层级结构

通过 parentPath 定义菜单树结构

编码规范

建议使用模块.功能格式命名,便于层级组织和搜索

类型说明

MODULE用于一级模块分类,MENU为具体页面菜单,BUTTON为操作控制权限

可维护性

所有菜单应定义清晰的 catalogName,可匹配前端显示逻辑

 

四、 模块定义

 

1、 定义类介绍

AppInfoSeedData 实现了 SeedDataInitial<AppInfoDefinition> 接口,作为平台中“模块定义”初始化定义的种子数据提供类。

该类通过重写 getSeedData() 方法,返回一个或多个模块(应用信息)对象,注册到MBM模块信息表中,用于构建平台模块树、权限归属、系统分区等基础信息。

 

2、 定义示例

/**
 * 模块定义
 */
public class AppInfoSeedData implements SeedDataInitial<AppInfoDefinition> {
 
    @Override
    public List<AppInfoDefinition> getSeedData() {
        return Arrays.asList(
                new AppInfoDefinition() {{
                    setAppCname("工艺管理");
                    setAppCode("processmanage");
                    setAppEname("processmanage");
                    setAppNickname("工艺管理");
                    setNodeType(AppInfoNodeTypeEnum.MODULE);
                    setParentPath(AppInfoAppEnum.IMES_CENTER);
                    setAppKey("imes.center.processmanage");
                }});
    }
}
 

3、 字段说明

字段名

类型

说明

appCname

String

模块中文名称(用于界面显示,如“工艺管理”)

appCode

String

模块编码,建议唯一,简洁明了

appEname

String

英文名称,一般与编码一致或为英文标识

appNickname

String

中文简称/别名,用于界面友好展示

nodeType

AppInfoNodeTypeEnum

节点类型(MODULE 表示为模块节点)

parentPath

AppInfoAppEnum

上级应用或系统(如 IMES_CENTER),表示模块归属

appKey

String

模块唯一路径键,全路径形式,如 imes.center.processmanage

五、 ID生成器分类

1、 定义类介绍

GenClassSeedData 实现了 SeedDataInitial<GenClassDefinition>接口,作为平台中“模块定义”初始化定义的种子数据提供类。该类通过重写 getSeedData() 方法,返回一个或多个模块(应用信息)对象,用于项目初始化基础数据

 

2、 定义示例

/**
 * ID生成器分类
 */
public class GenClassSeedData implements SeedDataInitial<GenClassDefinition> {
 
    @Override
    public List<GenClassDefinition> getSeedData() {
        return Arrays.asList(
                new GenClassDefinition() {{
                    setGenClassCode("testSeedDataGen");
                    setGenClassName("testSeedDataGen");
                    setGenClassDesc("testSeedDataGen");
                }}
        );
    }
}

3、 字段说明

字段名

类型

说明

genClassCode

String

分类编码(必须唯一,简洁明了)

genClassName

String

分类名称

genClassDesc

String

分类描述

六、 ID生成器定义

1、 定义类介绍

GenInfoSeedData 实现了 SeedDataInitial<GenInfoDefinition>接口,作为平台中“模块定义”初始化定义的种子数据提供类。该类通过重写 getSeedData() 方法,返回一个或多个模块(应用信息)对象,用于项目初始化ID生成器基础数据

 

2、 定义示例

注意:ChartInfo里面每一个组件对象的id都要与iconId对应

public class GenInfoSeedData implements SeedDataInitial<GenInfoDefinition> {
 
    @Override
    public List<GenInfoDefinition> getSeedData() {
        return Arrays.asList(
                //  demo
                new GenInfoDefinition() {{
                    setChartInfo("{\"cells\":[{\"position\":{\"x\":90,\"y\":125},\"size\":{\"width\":72,\"height\":66},\"attrs\":{\"text\":{\"text\":\"ABC202507020001\",\"textWrap\":{\"ellipsis\":true,\"height\":\"60%\"}},\"title\":{\"text\":\"ddTest\",\"textWrap\":{\"ellipsis\":true,\"height\":\"60%\"}}},\"visible\":true,\"shape\":\"idGenerator\",\"translate\":{\"tx\":0,\"ty\":0},\"id\":\"1c4fe6ca-d99c-4c40-a899-28e1cbc7a999\",\"zIndex\":1},{\"position\":{\"x\":190,\"y\":145},\"size\":{\"width\":60,\"height\":30},\"visible\":true,\"shape\":\"equals\",\"id\":\"a739965d-983d-43ed-af58-65945fb13386\",\"zIndex\":2},{\"position\":{\"x\":270,\"y\":127},\"size\":{\"width\":72,\"height\":66},\"attrs\":{\"text\":{\"text\":\"ABC\",\"isComponentFlag\":\"Y\",\"textWrap\":{\"ellipsis\":true,\"height\":\"60%\"}}},\"visible\":true,\"shape\":\"constString\",\"id\":\"00b79add-5ede-4168-8a03-94b159bec110\",\"zIndex\":3,\"data\":{\"no\":0}},{\"position\":{\"x\":356,\"y\":130},\"size\":{\"width\":50,\"height\":60},\"visible\":true,\"shape\":\"plus\",\"id\":\"281r4975-fc9e-4717-b3e2-64c76abd0de9\",\"zIndex\":4},{\"position\":{\"x\":416,\"y\":127},\"size\":{\"width\":72,\"height\":66},\"attrs\":{\"text\":{\"text\":\"20250702\",\"isComponentFlag\":\"Y\",\"textWrap\":{\"ellipsis\":true,\"height\":\"60%\"}}},\"visible\":true,\"shape\":\"dateCode\",\"id\":\"a89fa741-26d5-4ef8-8669-8f22445f5e98\",\"zIndex\":5,\"data\":{\"no\":1}},{\"position\":{\"x\":502,\"y\":130},\"size\":{\"width\":50,\"height\":60},\"visible\":true,\"shape\":\"plus\",\"id\":\"243368a5-aadf-4c0c-8dc3-881db57710ew\",\"zIndex\":6},{\"position\":{\"x\":562,\"y\":127},\"size\":{\"width\":72,\"height\":66},\"attrs\":{\"text\":{\"text\":\"0001\",\"isComponentFlag\":\"Y\",\"textWrap\":{\"ellipsis\":true,\"height\":\"60%\"}},\"title\":{\"text\":\"流水序号\"}},\"visible\":true,\"shape\":\"seqNo\",\"id\":\"52626a19-bddf-4479-92b7-6fff9f9dd811\",\"zIndex\":7,\"data\":{\"no\":2}}]}");
                    setGenCode("testSeedDataGen");
                    setGenName("testSeedDataGen");
                    setClassId("testSeedDataGen");
                    List<GenArticleInfo> genArticleInfoList = new ArrayList<>();
                    //  固定字符串
                    GenArticleInfo constStringInfo = new GenArticleInfo();
                    constStringInfo.setAimLength(3);
                    constStringInfo.setArticleName(GenArticleTypeEnum.CONST_STRING.getName());
                    constStringInfo.setArticleType(GenArticleTypeEnum.CONST_STRING.getCode());
                    constStringInfo.setGenId("1c4fe6ca-d99c-4c40-a899-28e1cbc7a999");
                    constStringInfo.setIconId("00b79add-5ede-4168-8a03-94b159bec110");
                    constStringInfo.setDefaultValue("ABC");
                    constStringInfo.setSortNo(0);
                    genArticleInfoList.add(constStringInfo);
 
                    //  日期代码
                    GenArticleInfo dateCodeInfo = new GenArticleInfo();
                    dateCodeInfo.setAimLength(3);
                    dateCodeInfo.setArticleName(GenArticleTypeEnum.DATE_CODE.getName());
                    dateCodeInfo.setArticleType(GenArticleTypeEnum.DATE_CODE.getCode());
                    dateCodeInfo.setGenId("1c4fe6ca-d99c-4c40-a899-28e1cbc7a999");
                    dateCodeInfo.setIconId("a89fa741-26d5-4ef8-8669-8f22445f5e98");
                    dateCodeInfo.setFormat(GenInfoDateTypeEnum.yyyyMMdd.getCode());
                    dateCodeInfo.setDateFormatType(GenInfoDateTypeEnum.yyyyMMdd.getType());
                    dateCodeInfo.setDefaultValue("20250702");
                    dateCodeInfo.setSortNo(1);
                    genArticleInfoList.add(dateCodeInfo);
 
                    //  流水序列
                    GenArticleInfo seqNuInfo = new GenArticleInfo();
                    seqNuInfo.setAimLength(4);
                    seqNuInfo.setArticleName(GenArticleTypeEnum.SEQ_NO.getName());
                    seqNuInfo.setArticleType(GenArticleTypeEnum.SEQ_NO.getCode());
                    seqNuInfo.setGenId("1c4fe6ca-d99c-4c40-a899-28e1cbc7a999");
                    seqNuInfo.setIconId("52626a19-bddf-4479-92b7-6fff9f9dd811");
                    seqNuInfo.setDefaultValue("0001");
                    seqNuInfo.setHexadecimalCharset(GenArticleHexadecimalCharsetType.DECIMAL.getNumber());
                    seqNuInfo.setHexadecimalSys(GenArticleHexadecimalSysType.INCREASING.getNumber());
                    seqNuInfo.setMaxValue(9999);
                    seqNuInfo.setMinValue(1);
                    seqNuInfo.setNumIncrease(1);
                    seqNuInfo.setResetIdenType(GenArticleResetIdenType.NEVER.getNumber());
                    seqNuInfo.setSerialDataType("10");
                    seqNuInfo.setValueCharset("0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,T,U,V,W,X,Y,Z");
                    seqNuInfo.setSortNo(2);
                    genArticleInfoList.add(seqNuInfo);
 
                    //  以 \ 符号合并json
                    final String json = getChartInfo() + StrUtil.SLASH + JSONArray.toJSONString(genArticleInfoList);
                    setChartInfo(json);
                }}
        );
    }
}

3、 字段说明

主表:

字段名

类型

说明

chartInfo

String

生成器

genCode

String

分类名称(必须唯一,简洁明了)

genName

String

分类描述

classId

String

所属分类

description

String

描述

子表:

字段名

类型

说明

通用属性

genId

String

所属生成器组件id

iconId

String

组件元素id

articleName

String

组件名称

articleType

String

组件类型(见SDK枚举:GenArticleTypeEnum

sortNo

String

组件序号

aimLength

String

组件长度默认值长度

defaultValue

String

默认值

日期组件属性:

format

String

日期组件:日期格式,见SDK枚举 GenInfoDateTypeEnum

dateFormatType

String

日期组件:时间代码属性,见SDK枚举 GenInfoDateTypeEnum

numIncrease

String

流水序列组件:递增数

流水序列组件属性:

minValue

String

流水序列组件:最小值

maxValue

String

流水序列组件:最大值

hexadecimalSys

String

流水序列组件:增减类型,见SDK枚举 GenArticleHexadecimalSysType

hexadecimalCharset

String

流水序列组件:进制规则,见SDK枚举 GenArticleHexadecimalCharsetType

valueCharset

String

流水序列组件:字符进制

resetIdenType

String

流水序列组件:周期重置模式,见SDK枚举 GenArticleResetIdenType

serialDataType

String

流水序列组件:默认10

4、 如何在页面获取组件属性值

要述:

蓝色部分:生成器主要节点,对于主要节点,一般只需要维护chartInfo、genCode、genName、classId四个字段 绿色部分:生成器组件节点,对于组件节点,一般需要根据不同的节点类型set不同类型的值,比如生成器=固定字符+日期代码+流水序列,三个组件组成,那么就需要构建三个GenArticleInfo对象并放入集合中,

最后以chartInfo(主节点)+ \(拼接字符) + JsonArray(组件数组Json)的方式组合成新json重新放入chartInfo字段中存储

七、 数据开发规范(类命名 + 包结构)

1、 目的

为规范种子数据(如字典、菜单、模块信息等)的定义方式,统一目录结构与类命名,便于平台自动识别、注册、维护与二次开发,提高开发效率与一致性。

 

2、 包结构规范

所有种子数据定义类必须放置在 对应业务模块下的 data 包中

package com.sie.mbm.mom.mpm.pm.data;

● com.sie.mbm.mom:基础包名

● mpm.pm:业务模块层级(如:MPM 产品线下的 PM 子模块)

● data:专用于存放种子数据定义类

 

3、 命名规范

数据类型

类名前缀

示例类名

字典定义

DictSeedData

DictSeedDataForProjectType.java

模块定义

AppInfoSeedData

AppInfoSeedDataForProcess.java

菜单/栏目/按钮

CatalogSeedData

CatalogSeedDataForEBOM.java

 

八、 初始化数据

1、 概述

“初始化数据”是指在系统部署、租户初始化或模块首次上线时,通过平台统一注册与注入的基础静态数据,用于支撑业务运行的前置配置项,例如字典项、菜单结构、模块定义等。

这些数据由业务模块提前通过代码方式定义,并在平台启动或初始化阶段通过 SDK 自动注册与落库。

 

2、 初始化流程图

初始化入口说明

步骤

描述

A1 / A2

各业务模块通过 Java 类实现 SeedDataInitial<T> 接口,在 data 包中定义种子数据(如:字典、菜单、模块)。

B

业务应用启动后 SDK自动扫描所有种子数据类,使用反射机制提取数据内容。

B2

解析后的数据通过 OpenFeign 请求发送到统一微服务(如 kernel),由平台进行统一校验与保存。

C

所有数据最终落库至 sie_sys_seed_data 表中,作为后续“发布推送”阶段的输入源。

 

 

九、 发布数据

1、 概述

发布数据指的是将业务模块定义好的种子数据(保存在 sie_sys_seed_data 表中)同步推送至 华为 MBM 系统。该过程可在系统初始化时自动执行,也可通过定时任务或手动请求触发执行。

种子数据推送过程包括以下几个步骤:

● 读取本地持久化的种子数据;

● 调用华为 MBM API 拉取当前已有数据;

● 比对差异,生成变更数据;

● 通过 MBM 原子服务接口推送新增或修改项。

 

2、 推送流程图

3、 支持的触发方式

触发方式

说明

定时任务

适合定期检查并更新已发布数据;通常配置为每日或每小时同步。

HTTP 请求

提供接口供外部调用,适合手动触发或部署后立即更新。

应用启动

启动后自动执行一次同步逻辑,适用于初次部署、开发调试等场景。

 

 

4、 应用启动自动推送

注意:enabled: true 才是开启同步到种子数据表

要在应用启动后自动进行种子数据推送,可在配置文件中启用推送功能并设置平台账户信息。

# ---------------- 华为原子 API 配置 ------------------------
hwmbm:
  : http://113.45.212.227
  service: dynamic/api
  executeService: rdm/basic/api/customservice
  commonService: rdm/common/api
  seedData:
    enabled: true 
     # 如启用种子数据自动发布功能
    renterId: 1825384265685495808    # 租户ID
    siteId: 1825408043106181120      # 工厂站点ID
    loginAccount: lizongyong         # 华为MBM登录账号
    password: xxx            # 登录密码
 

5、 接口调用说明

在种子数据推送过程中,系统会通过 调用内核微服务(kernel) 的统一发布接口 /sys-seed-data/publish,将本地缓存的差异数据推送至 MBM 平台。

发布接口定义

● URL:POST /sys-seed-data/publish

● 服务所属:kernel 微服务

● 内容类型:application/json

● Body 请求示例

{
  "renterId": "1825384265685495808",
  "siteId": "1825408043106181120",
  "loginAccount": "lizongyong",
  "loginPwd": "Mbm@2024."
}

参数说明

参数名

类型

含义

必填

示例

renterId

String

租户 ID

1825384265685495808

siteId

String

站点/工厂 ID

1825408043106181120

loginAccount

String

MBM 登录账号

lizongyong

loginPwd

String

MBM 登录密码

XXXXX

 

 

十、 架构设计

 

1、 初始化数据

● 触发点

业务系统中如 MPM、QMS 等模块,通过注解、配置文件等方式定义种子数据。流程说明

1. 各业务模块定义的种子数据由 mbm-mom-sdk 进行统一解析。

2. 解析完成后,SDK 通过 OpenFeign 调用 kernel 微服务。

3. kernel 微服务负责将解析后的种子数据持久化到 SieSysSeedData 表中。

● 目标

通过统一的 SDK 解析和微服务持久化,完成种子数据的标准化录入和存储,为后续同步打下数据基础。

流程图如下:

2、 发布数据

● 触发方式

通过定时任务、HTTP 请求或应用启动三种方式触发同步流程。流程说明

1. 触发后调用 kernel publish 服务。

2. 该服务从 SieSysSeedData 表中读取已持久化的种子数据。

3. 同步服务拉取 MBM 系统当前已有种子数据。

4. 进行差异比对,生成新增或变更数据列表。

5. 调用 MBM 系统接口,将差异数据推送发布。

● 目标

确保本地种子数据和 MBM 系统数据一致,实现数据的有效同步和发布,支持业务模块正常运行。

流程图如下:

 

十一、 二开能力

##todo

如:项目交付如下 替换、更新、删除已有的种子数据。

 

 


Comment