界面设计器的导入导出

目录

依赖包
安装GraphQL的工具
登录gql
导出生成json文件子
业务工程中导入示例代码

简介

通过调用导出接口,将设计器的设计数据与元数据打包导出到文件中。
提供了download/export两类接口。

依赖包

<dependency>
    <groupId>pro.shushi.pamirs.metadata.manager</groupId>
    <artifactId>pamirs-metadata-manager</artifactId>
</dependency>

安装GraphQL的工具

下载官网地址:https://github.com/Kong/insomnia/releases

登录gql

界面设计器的导入导出

示例调用代码

mutation {
    pamirsUserTransientMutation {
        login(user: { login: "admin", password: "admin" }) {
            needRedirect
            broken
            errorMsg
            errorCode
            errorField
        }
    }
}

导出生成json文件

执行GraphQL,直接返回导出数据。适用于通过浏览器直接下载文件。
界面设计器的导入导出

按模块示例调用代码

请求示例:
mutation {
    uiDesignerExportReqMutation {
        download/export(
            data: { module: "demo_core", fileName: "demo_meta", moduleBasics: false }
        ) {
            jsonUrl
        }
    }
}
  • module参数:模块编码;
  • fileName参数:指定⽣成的json⽂件名称;
  • moduleBasics参数:指定是否只导出模块基础数据,如果为true,只导出内置布局、模块菜单、菜单关联的动作。 如果为false,还会导出模块内的所有页⾯,以及页⾯关联的动作元数据、页⾯设计数据 等等。 默认值为false。

按菜单导出

mutation {
    uiDesignerExportReqMutation {
        download/export(
            data: {
                menu: { name: "uiMenu0000000000048001" }
                fileName: "demo_meta"
                relationViews: true
            }
        ) {
            jsonUrl
        }
    }
}
  • menu参数:菜单对象,指定菜单的name。只会导出该菜单及其绑定页⾯,不会递归查询⼦菜单
  • fileName参数:指定⽣成的json⽂件名称
  • relationViews参数:指定是否导出关联页⾯,默认为false,只导出菜单关联的页⾯。如果为true,还会导出该页⾯通过跳转动作关联的⾃定义页⾯。

指定页⾯导出

mutation {
    uiDesignerExportReqMutation {
        download/export(
            data: {
                view: {
                    name: "xx_TABLE_0000000000119001"
                    model: "ui.designer.TestUiDesigner"
                }
                fileName: "demo_meta"
                relationViews: true
            }
        ) {
            jsonUrl
        }
    }
}
  • view参数:视图对象,指定视图的name和model
  • fileName参数:指定⽣成的json⽂件名称
  • relationViews参数:指定是否导出关联页⾯,默认为false,只导出菜单关联的页⾯。如果为true,还会导出该页⾯通过跳转动作关联的⾃定义页⾯。

导出组件

导出全部组件数据

mutation {
    uiDesignerExportReqMutation {
        downloadWidget/exportWidget(data: { fileName: "demo_widget" }) {
            jsonUrl
        }
    }
}
  • fileName参数:指定⽣成的json⽂件名称
  • 注意:⾃定义组件的元数据归属于页⾯设计器(ui_designer) 因此导⼊元数据的模块(module)并不是业务模块。组件导⼊建议使⽤pro.shushi.pamirs.metadata.manager.core.helper.WidgetInstallHelper

导出全部组件⽂件

当开发环境,和导⼊环境的oss不互通时,可通过⼀下⽅法导出⾃定义组件的css和js⽂件压缩包,在导⼊时⽀持指定zip⽂件上传到oss,并替换导⼊组件数据中的css和js⽂件路径。

mutation {
    uiDesignerExportReqMutation {
        downloadWidgetFile/exportWidgetFile(data: { fileName: "demo_widget" }) {
            jsonUrl
        }
    }
}

业务工程中导入示例代码

导入元数据示例代码

@Slf4j
@Order(Integer.MAX_VALUE-1)
@Component
public class DemoAppMetaInstall implements MetaDataEditor {

    @Autowired
    private ApplicationContext applicationContext;

    @Override
    public void edit(AppLifecycleCommand command, Map<String, Meta> metaMap) {
        if (!doImport()) {
            return;
        }
        log.info("[设计器业务元数据导⼊]");
        InitializationUtil bizInitializationUtil = InitializationUtil.get(metaMap, DemoModule.MODULE_MODULE/***改成⾃⼰的Module*/, DemoModule.MODULE_NAME/***改成⾃⼰的Module*/);
        DesignerInstallHelper.mateInitialization(bizInitializationUtil, "install/meta.json");

        log.info("[⾃定义组件元数据导⼊]");
        // 写法1: 将组件元数据导⼊到⻚⾯设计器. 只有在安装设计器的服务中执⾏才有效果
        WidgetInstallHelper.mateInitialization(metaMap, "install/widget.json");

        // 写法2: 与写法1相同效果. 只有在安装设计器的服务中执⾏才有效果
        //InitializationUtil uiInitializationUtil = InitializationUtil.get(metaMap, "ui_designer", "uiDesigner");
        //if (uiInitializationUtil != null) {
        //    DesignerInstallHelper.mateInitialization(uiInitializationUtil, "install/widget.json");
        //}
        // 写法3: 业务⼯程和设计器分布式部署,且希望通过业务⼯程导⼊⾃定义组件元数据. 业务模块需要依赖⻚⾯设计器模块,然后指定业务模块导⼊
        DesignerInstallHelper.mateInitialization(bizInitializationUtil, "install/widget.json");
    }

    private boolean doImport() {
        // ⾃定义导⼊判断. 避免⽤于设计的开发环境执⾏导⼊逻辑
        String[] envs = applicationContext.getEnvironment().getActiveProfiles();
        List<String> envList = Lists.newArrayList(envs);
        return CollectionUtils.isNotEmpty(envList) && (envList.contains("prod"));
    }
}

Oinone社区 作者:数式-海波原创文章,如若转载,请注明出处:https://doc.oinone.top/designer/uidesigner/7294.html

访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验

(0)
数式-海波的头像数式-海波数式管理员
上一篇 2024年5月16日 am10:30
下一篇 2024年5月16日 pm2:29

相关推荐

  • 弹窗或抽屉表单视图rootRecord获取不到对应的数据

    在平台默认的实现中,rootRecord 代表的是根视图的数据。比如,在表格页面点击按钮打开了弹窗,弹窗里面包含一个表单视图,但是该视图获取 rootRecord 却是最外层的视图数据。 如果期望 rootRecord 数据是弹窗的视图数据,需要手动修改表单的 rootRecord。下面的代码演示了如何重写 rootData 以确保其数据是弹窗的数据: @SPI.ClassFactory( BaseElementWidget.Token({ viewType: ViewType.Form, widget: 'MyCustomFormWidgetFormWidget' }) ) export class MyCustomFormWidgetFormWidget extends FormWidget { @Widget.Reactive() @Widget.Provide() public get rootData(): any[] | undefined { return this.activeRecords; } } 上述代码重写了 rootData,这样就可以确保 rootData 的数据是弹窗的数据。 接下来就是注册: registerLayout( ` <view type="FORM"> <element widget="actionBar" slot="actionBar" slotSupport="action"> <xslot name="actions" slotSupport="action" /> </element> <element widget="MyCustomFormWidgetFormWidget" slot="form"> <xslot name="fields" slotSupport="pack,field" /> </element> </view> `, { viewType: ViewType.Form, model: '弹窗模型', viewName: '弹窗视图名称' } )

    2023年11月13日
    76800
  • 上下文在字段和动作中的应用

    上下文在字段和动作中的应用 在业务场景中,常常需要在打开弹窗或跳转到新页面时携带当前页面数据。此时,我们需要配置相关「动作」中的上下文信息。 在 oinone 平台中,上下文主要分为以下三种: activeRecord:当前视图数据 rootRecord:主视图数据 openerRecord:触发弹窗的对象 参考文档:oinone内的主视图数据和当前视图数据使用介绍 activeRecord 表示当前视图的数据。例如,若动作配置在表单上,则指代当前表单的数据;若配置在 o2m、m2m 字段表格上,则指代选中的行数据。 rootRecord 表示根视图的数据。若当前视图是表单页,则代表表单的数据;若为表格页,则代表表格的数据。 openerRecord 表示触发弹窗的对象。例如,在弹窗内的字段或动作中,可通过 openerRecord 获取触发弹窗的信息。 这三者均为对象 (Object) 类型。 界面设计器配置 在 o2m、m2m 表格字段弹窗中携带当前视图数据 假设我们设计了一个包含 o2m、m2m 表格字段的表单页面。打开相关弹窗时,需将表单中的 code 数据传递至弹窗中。 选择相应的「动作」,如创建或添加。在右侧属性面板底部找到「上下文」,添加格式为对象 {} 的上下文信息。 以键值对的格式添加上下文信息:{code: rootRecord.code}。 设计弹窗时,将 code 字段拖入弹窗中。 完成设计后保存并发布。 大家可以看到,上下文中的key是 code,但是value是rootRecord.code,这里取的是rootRecord而不是activeRecord,因为我们上面讲过如果当前动作配置在o2m、m2m的字段表格上面,那么activeRecord就是表格选中的行,我们现在要取的是表单上的code字段,所以需要用rootRecord。 注意点:key需要是提交模型【前端视图】存在的字段才能传递。

    2023年11月8日
    1.0K10
  • 如何把平台功能菜单加到项目中?

    概述 在使用Oinone低代码平台进行项目开发的过程中,会存在把平台默认提供的菜单加到自己的项目中。这篇文章介绍实现方式,以角色管理为例。 1. 低代码情况 即项目是通过后端代码初始化菜单的方式。 通常在 XXXMenu.java类通过@UxMenu注解的方式,代码片段如下: 此种情况与添加项目本地的菜单无区别,具体代码: @UxMenu(value = "账号管理", icon = "icon-yonghuguanli") class AccountManage { @UxMenu("用户管理") @UxRoute(value = CustomerCompanyUserProxy.MODEL_MODEL, title = "用户管理") class CompanyUserManage { } @UxMenu("角色管理") @UxRoute(value = AuthRole.MODEL_MODEL, module = AdminModule.MODULE_MODULE, title = "角色管理") class RoleManage { } @UxMenu("操作日志") @UxRoute(value = OperationLog.MODEL_MODEL, module = AdminModule.MODULE_MODULE/***菜单所挂载的模块**/) class OperateLog { } } 2. 无代码情况 在界面设计器中,新建菜单–>选择绑定已有页面,进行发布即可。

    2024年4月19日
    1.1K00
  • 【界面设计器】左树右表

    阅读之前 你应该: 熟悉模型的增删改查相关内容。【界面设计器】模型增删改查基础 名词解释 主体:在视图中提供数据源的主要组件,并且所有动作都围绕着该主体展开。 一级搜索:在表格视图中,上方直观可见的搜索区,为表格提供筛选功能。 二级搜索:与一级搜索不同的是,其搜索条件是通过某些组件的行为追加到一级搜索条件之上的筛选功能。 概述 平台中对于左树右表提供了两种类型的展示形式。 在表格视图中的左树右表,是以表格为主体,树组件为表格提供了二级搜索功能。选中树节点时将对表格追加节点的搜索条件,并重新执行查询。 在树视图中,是以树为主体,其展开的视图可以是表格、表单、详情等其他视图。 PS:不论是树、级联这些视图组件,还是树选择、级联这些字段组件,其配置数据结构的方式是不尽相同的。唯一的区别在于最终到达的目标模型来源不同。 场景1 为了方便接下来的描述,我们需要先构建一个基本的业务场景,这个场景中包含【商品】和【商品类目】两个模型。 在【商品】的表格左侧添加【商品类目】树,选择某个商品类目后,可以根据商品类目进行筛选,查询所属类目下的全部商品。 其中【商品类目】使用【卡片级联】的展示方式进行管理。 其模型定义如下: 商品(Item) 名称 API名称 业务类型 是否多值 长度(单值长度) 关联模型 关联字段 ID id 整数 否 – – – – 编码 code 文本 否 128 – – – 名称 name 文本 否 128 – – 所属类目 category 多对一 否 – 商品类目(ItemCategory) categoryId – id 所属类目ID categoryId 整数 否 – – – 商品类目(ItemCategory) 名称 API名称 业务类型 是否多值 长度(单值长度) 关联模型 关联字段 ID id 整数 否 128 – – 编码 code 文本 否 128 – – – 名称 name 文本 否 128 – – 上级类目 parent 多对一 是 – 商品类目(ItemCategory) parentId – id 上级类目ID parentId 整数 否 – – – PS:实际业务场景中,【商品类目】通常使用编码进行关联,即parentCode – code;不仅如此,通常还会添加treeCode字段,以此来实现高效查询当前节点的所有子节点的能力。在演示模型中,我们不必关注这些内容。 创建【商品】视图 设置联动关系 这里我们需要配置的是【商品类目】的树结构,因此,在【第1级关联】中的模型选择【商品类目】。 在【商品类目】中是通过【上级类目】进行的自关联,因此,在【第1级关联】中的【自关联关系字段】选择【上级类目】。 在选中【商品类目】节点后,需要对右侧表格发起查询。其筛选条件是通过【商品】中的【所属类目】进行筛选的。因此,在【第1级关联】中的【表格关联关系字段】选择【所属类目】。那么,在表格发起查询前,会根据【所属类目】字段的关联关系配置自动添加筛选条件。 配置如下图所示: 创建【商品类目】视图 设置联动关系 这里我们需要配置的是【商品类目】的树结构(级联只是树结构的另一种表现形式) 细心的同学可能发现这里没有【表格关联关系字段】,因此,我们仅需配置【自关联关系字段】即可。 配置如下图所示: 为【商品类目】添加增删改查基础功能 与表格视图不同的是,行内动作区被放在了第一个卡片中的动作区,其他配置方式完全一致。 在这里需要理解的是,一个树节点对应的是表格中的一行。 【商品类目】使用展开视图进行编辑(可选) 打开【支持展开视图】开关,并设置展开视图。这里我们用表单视图进行编辑操作。 和其他表单一样,我们将必要的字段和动作拖入对应区域即可。 由于展开视图只会在选中节点时出现,因此我们仅需提供更新功能即可。 这里需要注意: 提交动作默认打开了【返回上一页】的功能,在当前场景中,更新动作提交数据后,没有上一页需要返回,因此需要关闭【返回上一页】的开关。 提交动作默认打开了【刷新当前视图】的功能,在当前场景中,更新按钮处于【展开视图】中,仅刷新当前视图是不够的,当数据发生变更时,我们需要将级联组件一并刷新,因此需要打开【刷新主视图】的开关。 PS:【编辑】动作和【展开视图编辑】功能是重复的,在使用时应该只选择其中一种。 【商品类目】限制仅支持四级,并为每一个卡片添加标题(可选) 移除【第1级关联】中的【自关联关系字段】,依次添加2、3、4级关联,选择【商品类目】模型,将自动选中【层级关联关系字段】为【上级类目】,并输入每一级关联的标题即可。 这里需要注意的是,在【第1级关联】中需要添加筛选条件,使其只能查询到根节点。 PS:这里的限制仅为交互上的限制,在创建/更新时,如果可以在服务端限制上级类目的选择,以及数据提交时的校验,效果更佳。 【商品类目】的【创建/编辑】使用弹窗打开(可选) 有时我们希望用户在页面中的操作尽可能的流畅,在表单规模较小的情况下,我们也可以使用【弹窗/抽屉】这类交互来优化用户体验。 小贴士: 弹窗打开的方式提供三种页面设计模式,绑定已有页面、使用新页面、复制已有页面。 使用新页面和复制已有页面的方式只能进行一次性的视图设计,无法进行复用。 使用绑定已有页面的方式可以使得视图进行复用,但复用的视图也只能同步弹窗的内容部分,弹窗底部的动作仅会在创建动作时复制一次。 跳转动作的打开方式以及页面设计模式等属于元数据信息,无法通过属性面板进行修改,因此只能通过重新创建新动作的方式进行修改。 鉴于业务的复杂和多变,通常情况下我们只采用【绑定已有页面】的方式为弹窗设计内容部分。这样在交互发生变更时,可以更好的适应变化。 场景2 为了方便接下来的描述,我们需要再构建一个基本的业务场景,这个场景中包含【公司】和【部门】两个模型。 【公司】模型的管理能力使用标准的【增删改查】视图。(此处不进行演示) 在【部门】的表格左侧添加【公司】-【部门】树,在选择某个公司后,可以根据所属公司进行筛选,查询所属公司下的全部部门。在选择某个部门后,可以根据上级部门进行筛选,查询该部门下的子部门(不包含子部门的子部门)。 PS:如这里要求查询该部门下的全部子部门,需要服务端配合。 其模型定义如下: 公司(Company) 名称 API名称 业务类型 是否多值 长度(单值长度) 关联模型 关联字段 ID id 整数 否 – – – – 编码 code 文本 否 128 – – – 名称 name 文本…

    2023年11月1日
    1.6K00
  • 自定义字段的数据联动

    某种情况下,开发人员期望自定以的字段发生变化后,需要修改其他的字段,这篇文章从两个维度来讲解如果处理数据的联动 界面设计器配置 1: 在界面设计器页面中的的组件区域找到自定义的字段,设计元件 2: 在模型区域,搜索提交方式,如果找到了,就把该字段拖拽进来, 如果找不到,就在元件中的组件区域,拖拽一个文本字段,按照下面的配置进行配置,然后保存 图一是找到了对应的字段图二是找不到对应的字段 【图一】 【图二】 图二的字段编码必须是constructDataTrigger 3: 从模型区搜索联动函数,将其拖拽进来 3: 从模型区搜索提交数据,将其拖拽进来4: 从模型区搜索提交字段,将其拖拽进来 5: 发布 (记得刷新页面哦) 最后再到对应的设计器页面,选中该字段,进行配置 提交方式为blur或者change , 需要开发者手动调用该方法 this.blur()或者this.change(value) // 字段对应的ts文件 class MyField extends FormFieldWidget { onChangeValue(val) { // this.change(val) // this.blur() } } 联动函数就是要调用的后端函数 提交数据分为:变更字段 -> 发生变化后的字段当前视图字段 -> 当前视图所有的字段指定字段 -> 指定字段,如果配置的指定字段,那么提交字段的配置就要输入对应的字段 代码配置 平台也支持通过代码的方式修改字段 // 字段对应的ts文件 class MyField extends FormFieldWidget { onChangeValue(val) { // 修改字段本身的值 this.change(val) // 修改其他字段的值 this.formData.otherField = 'value' this.reloadFormData$.subject.next(true); } }

    2023年11月9日
    87900

Leave a Reply

登录后才能评论