MetaModelService / PageSchemaService

MetaModelServicePageSchemaService 是 AuraBoot 元数据目录的 canonical 只读 API —— 涵盖 core 与已安装插件贡献的每一个 model、field 与 page 定义。它们把磁盘上的 JSON 布局、插件 overlay 优先级以及缓存解析都隐藏在一组内存查询方法之后。

概念

在插件 import 时,宿主会从每个插件解析 models.jsonpages.jsoncommands.jsonbindingRules.jsonpermissions.json 等文件,并合并为单一的 tenant 隔离元数据目录。后续对 MetaModelService 的调用都走内存缓存查询。该元数据在运行时 只读;变更通过 import 路径执行,并触发缓存刷新。

要回答"model X 有哪些字段",应该用这些 Service —— 不要自己重新解析 JSON。

接口签名

package com.auraboot.framework.meta.service;

public interface MetaModelService {

    Optional<ModelDefinition> getModelDefinition(String modelCode);

    FieldDefinition           getFieldDefinition(String modelCode, String fieldCode);
    List<FieldDefinition>     getModelFields(String modelCode);   // model 全部字段

    /** model 对应的动态表名 —— 例如 "crm_lead" → "mt_crm_lead"。 */
    String getTableName(String modelCode);

    boolean isModelExists(String modelCode);
    boolean isFieldExists(String modelCode, String fieldCode);

    void refreshModelCache(String modelCode);
}

page 定义由独立的 PageSchemaService 提供:

package com.auraboot.framework.meta.service;

public interface PageSchemaService {

    PageSchemaDTO        findByPageKey(String pageKey);          // 如 "crm_lead-list"
    List<PageSchemaDTO>  findByModelCode(String modelCode);      // list/form/detail 三种 kind
    List<PageSchemaDTO>  findByKind(String kind);
}

ModelDefinitionFieldDefinition 都是 Lombok @Data DTO,包含原始配置加便利访问方法(isRequired()isSearchable()isDisplayField()getDefaultValue())。

实现示例

一个自定义报表 Service,从 model 的字段定义动态构造列清单:

package com.acme.report;

import com.auraboot.framework.meta.service.MetaModelService;
import com.auraboot.framework.meta.dto.FieldDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ReportColumnService {

    @Autowired private MetaModelService metaModelService;

    public List<ReportColumn> columnsFor(String modelCode) {
        return metaModelService.getModelFields(modelCode).stream()
            .filter(FieldDefinition::isSearchable)
            .map(f -> new ReportColumn(
                f.getCode(),
                f.getDisplayName(),
                f.getDataType(),
                f.isRequired()))
            .toList();
    }
}

一个 page 感知的示例 —— 为列表页解析其动态表:

PageSchemaDTO page  = pageSchemaService.findByPageKey("crm_lead-list");
String        table = metaModelService.getTableName(page.getModelCode());  // "mt_crm_lead"

注册

MetaModelServicePageSchemaService 都是宿主托管的 Spring bean。在任意插件扩展或平台 Service 中通过 @Autowired 注入即可。这里没有 SPI 可供实现 —— 它们是 Service,而不是扩展点。元数据缓存在插件 enable/disable 以及 model.published 事件触发时自动刷新。

常见陷阱

  • 调用 getTableName(modelCode) 时假设结果是 ab_dyn_<code> 真实前缀是 mt_<modelCode>(常量 SystemFieldConstants.DYNAMIC_TABLE_PREFIX,见红线 §15)。始终调用 API。
  • 跨插件 reload 缓存 ModelDefinition / FieldDefinition 引用。 缓存刷新会产生新实例;旧引用是陈旧的。请缓存 code 并按需查询。
  • 直接读取 JSON 文件。 会绕过 overlay 优先级与校验。始终走 Service。
  • 假设 findByPageKey(modelCode + "-list") 返回的是用户自定义页面。 MetaModelServiceImpl.autoCreateDefaultPages 在 model publish 时会静默生成空 stub —— 把它当成真实页面前应检查其 blocks 是否为空。

相关