1. 概述
配置项模块(OptionItem)用于管理全局/租户/工厂等多级生效范围的配置参数,提供:
- 种子数据机制:业务模块实现
OptionItemSeedInitial<T>接口,调用初始化接口后自动同步入库。 - 取值接口:通过
OptionItemApi(openapi 接口)或 HTTP 接口按生效范围优先级获取配置值。
分层结构:
| 层 | 位置 | 说明 |
|---|---|---|
| 接口定义(sys-api) | com.sie.imom.sys.api.optionitem |
OptionItemApi、OptionItemSeedInitial、OptionItemGetValueDTO |
| 实现(sys-biz) | com.sie.imom.sys.optionitem |
实体、服务、控制器、种子数据示例 |
2. 种子数据机制
2.1 种子数据接口
// 位于 sys-api 层,实现此接口的 Spring Bean 会被 OptionItemInitService 自动收集
public interface OptionItemSeedInitial<T> {
List<T> getSeedData();
}
配置项支持两种种子数据类型,对应两张表:
| 类型 | 对应表 | 说明 | 示例实现 |
|---|---|---|---|
OptionItemNode |
sys_option_item_node |
配置项节点(分组) | DemoOptionItemNodeSeedInitial |
OptionItem |
sys_option_item |
配置项 | DemoOptionItemSeedInitial |
2.2 节点种子数据 OptionItemSeedInitial<OptionItemNode>
节点用于给配置项分组,例如系统、主数据、工艺、生产、质量等。示例:
@Component
public class MyOptionItemNodeSeedInitial implements OptionItemSeedInitial<OptionItemNode> {
@Override
public List<OptionItemNode> getSeedData() {
return List.of(
new OptionItemNode()
.setNodeCode("mesConfig") // 节点编码(唯一)
.setNodeName("生产") // 节点名称
.setParentPath(null) // 父路径,一级节点为 null
.setSortCode(1) // 排序码
);
}
}
字段说明:
| 字段 | 是否必填 | 说明 |
|---|---|---|
nodeCode |
是 | 节点编码,全局唯一 |
nodeName |
是 | 节点名称 |
parentPath |
否 | 父节点完整路径;null 表示一级节点,多级用 . 连接(如 sysConfig.child),父节点须先定义 |
sortCode |
否 | 排序码 |
2.3 配置项种子数据 OptionItemSeedInitial<OptionItem>
@Component
public class MyOptionItemSeedInitial implements OptionItemSeedInitial<OptionItem> {
@Override
public List<OptionItem> getSeedData() {
return List.of(
new OptionItem()
.setNodeCode("mesConfig") // 关联的节点编码(必须已存在)
.setItemCode("mesLineSpeed") // 配置项编码(唯一)
.setItemName("产线节拍") // 配置项名称
.setDescription("产线目标节拍(秒)") // 说明
.setDefaultScopeType(OptionItemScopeEnum.SYS.getCode()) // 默认生效范围类型
.setDefaultValue("60") // 默认值
.setSortCode(1) // 排序码
);
}
}
字段说明:
| 字段 | 是否必填 | 说明 |
|---|---|---|
nodeCode |
是 | 关联的节点编码,初始化时自动映射为 nodeId(初始化后该字段会被置空),对应节点必须先初始化 |
itemCode |
是 | 配置项编码,全局唯一 |
itemName |
是 | 配置项名称 |
description |
否 | 配置项说明 |
defaultScopeType |
是 | 默认生效范围类型,取值见生效范围枚举 |
defaultValue |
是 | 默认值,无更细范围配置时返回该值 |
sortCode |
否 | 排序码 |
2.4 调用初始化接口
POST /sys/v1/option-item/node/init
系统自动完成:
- 收集所有
OptionItemSeedInitial<OptionItemNode>种子,按nodeCode去重插入节点(父节点先于子节点处理,自动生成parentId/path)。 - 收集所有
OptionItemSeedInitial<OptionItem>种子,按itemCode去重,通过nodeCode映射nodeId后插入。 - 清空节点树与配置项缓存(影响全部租户)。
幂等:多次调用不会产生重复数据(按 nodeCode/itemCode 去重)。
2.5 初始化校验规则
| 场景 | 结果 |
|---|---|
种子数据的 nodeCode 为空 |
抛业务异常「配置项[xx]的节点编码(nodeCode)不能为空」 |
| 种子数据关联的节点不存在 | 抛业务异常「配置项[xx]关联的节点编码[xx]不存在,请先初始化节点数据」 |
已存在的 itemCode/nodeCode |
跳过,不重复插入 |
3. 使用 OptionItemApi 获取配置值
3.1 接口说明
OptionItemApi 位于 sys-api 层,是 openapi 接口,由 sys-biz 的 OptionItemApiImpl 实现(Spring Bean)。调用方注入 OptionItemApi 后直接方法调用即可,无需走 HTTP。
public interface OptionItemApi {
String getValue(OptionItemGetValueDTO dto);
}
3.2 请求参数 OptionItemGetValueDTO
| 字段 | 是否必填 | 说明 |
|---|---|---|
itemCode |
是 | 配置项编码 |
scopeIdList |
是 | 生效范围 ID 列表,按优先级从高到低排序(如 [工位ID, 线体ID, 工作中心ID, 车间ID, 工厂ID, 租户ID, 0],全局固定传 0) |
3.3 取值规则
按生效范围优先级返回配置值:
工位 > 工作中心 > 线体 > 车间 > 工厂 > 租户 > 全局 > 主表默认值
具体逻辑:
- 按
itemCode查询配置项,不存在则抛业务异常。 scopeIdList为空 → 直接返回默认值defaultValue。- 查询该配置项下
scopeId命中scopeIdList的所有配置值。 - 没有命中任何配置值 → 返回默认值
defaultValue。 - 命中多个配置值时,取
scopeType优先级最高的(priority 数值越小优先级越高)返回其value。
3.4 Java 调用示例
@Autowired
private OptionItemApi optionItemApi;
public String getLineSpeed(Long stationId, Long lineId, Long factoryId, Long tenantId) {
OptionItemGetValueDTO dto = new OptionItemGetValueDTO();
dto.setItemCode("mesLineSpeed");
// 按优先级从高到低传范围ID,全局固定传 0L
dto.setScopeIdList(List.of(stationId, lineId, factoryId, tenantId, OptionItemConstant.SCOPE_ID_GLOBAL));
return optionItemApi.getValue(dto);
}
3.5 HTTP 调用示例(等价接口)
POST /sys/v1/option-item/get-value
Content-Type: application/json
{
"itemCode": "mesLineSpeed",
"scopeIdList": [1001, 2002, 3003, 0]
}
响应:
{
"code": 0,
"msg": "成功",
"data": "60"
}
4. 新增一个业务配置项完整步骤
- 定义节点:若目标节点不存在,实现
OptionItemSeedInitial<OptionItemNode>提供节点种子。 - 定义配置项:实现
OptionItemSeedInitial<OptionItem>提供配置项种子,nodeCode指向已存在节点。 - 调用初始化:
POST /sys/v1/option-item/node/init,自动同步入库。 - 按需配置范围值:通过
sys/v1/option-item/value接口为各生效范围创建OptionItemValue(scopeType + scopeCode + scopeId + value)。 - 获取配置值:注入
OptionItemApi调用getValue,传入当前上下文的生效范围 ID 列表。
5. 其他管理接口
| 接口 | 方法 | 说明 |
|---|---|---|
sys/v1/option-item/page |
POST | 分页查询配置项 |
sys/v1/option-item |
GET | 获取配置项详情(body 传 {id}) |
sys/v1/option-item |
POST | 创建配置项 |
sys/v1/option-item |
PUT | 更新配置项 |
sys/v1/option-item |
DELETE | 删除配置项 |
sys/v1/option-item/node/tree |
GET | 获取配置项节点树 |
sys/v1/option-item/node/init |
POST | 初始化种子数据 |
sys/v1/option-item/value |
GET | 根据 optionItemId 获取配置值列表 |
sys/v1/option-item/value |
POST/PUT/DELETE | 创建/更新/删除配置值 |
6. 参考
6.1 生效范围枚举
OptionItemScopeEnum 取值与优先级(数值越小优先级越高):
| Code | 名称 | priority |
|---|---|---|
station |
工位 | 1 |
workcenter |
工作中心 | 2 |
line |
线体 | 3 |
workshop |
车间 | 4 |
factory |
工厂 | 5 |
tenant |
租户 | 6 |
sys |
全局 | 7 |
6.2 配置值实体字段
| 字段 | 说明 |
|---|---|
optionItemId |
配置项 ID |
scopeType |
生效范围类型,见上方枚举 |
scopeCode |
生效范围编码 |
scopeId |
生效范围 ID(全局固定 0) |
value |
配置值 |
sortCode |
排序码 |