3.5.3 Action的类型

各类动作我们都碰到过,但都没有展开讲过。这篇文章我们来系统介绍下oinone涉及到的所有Action类型。

一、动作类型

  • 服务器动作ServerAction
  • 类似于Spring MVC的控制器Controller,通过模型编码和动作名称路由,定义存储模型或代理模型将为该模型自动生成动作名称为consturct,queryOne,queryPage,create,update,delete,deleteWithFieldBatch的服务器动作。定义传输模型将为该模型自动生成动作名称为consturct的服务器动作
  • 窗口动作ViewAction
  • 站内跳转,通过模型编码和动作名称路由。系统将为存储模型和代理模型自动生成动作名称为redirectDetailPage的跳转详情页窗口动作,动作名称为redirectListPage的跳转列表页窗口动作,动作名称为redirectCreatePage的跳转新增页窗口动作,动作名称为redirectUpdatePage的跳转更新页窗口动作。
  • 跳转动作UrlAction
  • 外链跳转
  • 客户端动作ClientAction
  • 调用客户端函数

二、默认动作

  • 如果在UI层级,有开放新增语义函数,则会默认生成新增的窗口动作ViewAction,跳转到新增页面
  • 如果在UI层级,有开放更新语义函数,则会默认生成修改的窗口动作ViewAction,跳转到更新页面
  • 如果在UI层级,有开放删除语义函数,则会默认生成删除的客户端动作ClientAction,弹出删除确认对话框

三、第一个服务器动作ServerAction

回顾第一个ServerAction

第一个ServerAction是在3.3.2【模型的类型】一文中的“代理模型”部分出现的,再来看下当时的定义代码

package pro.shushi.pamirs.demo.core.action;

……引用类

@Model.model(PetShopProxy.MODEL_MODEL)
@Component
public class PetShopProxyAction extends DataStatusBehavior<PetShopProxy> {

    @Override
    protected PetShopProxy fetchData(PetShopProxy data) {
        return data.queryById();
    }
    @Action(displayName = "启用")
    public PetShopProxy dataStatusEnable(PetShopProxy data){
        data = super.dataStatusEnable(data);
        data.updateById();
        return data;
    }

……其他代码

}

图3-5-3-1 回顾第一个ServerAction

  1. @Action注解将创建服务器动作,并@Model.model绑定

  2. 自定义ServerAction请勿使用get、set、unset开头命名方法或toString命名方法

ServerAction之校验(举例)

Step1 为动作配置校验表达式

使用@Validation注解为PetShopProxyAction的dataStatusEnable服务端动作进行校验表达式配置

package pro.shushi.pamirs.demo.core.action;

……引用类

@Model.model(PetShopProxy.MODEL_MODEL)
@Component
public class PetShopProxyAction extends DataStatusBehavior<PetShopProxy> {

    @Override
    protected PetShopProxy fetchData(PetShopProxy data) {
        return data.queryById();
    }
    @Validation(ruleWithTips = {
            @Validation.Rule(value = "!IS_BLANK(data.code)", error = "编码为必填项"),
            @Validation.Rule(value = "LEN(data.shopName) < 128", error = "名称过长,不能超过128位"),
    })
    @Action(displayName = "启用")
    public PetShopProxy dataStatusEnable(PetShopProxy data){
        data = super.dataStatusEnable(data);
        data.updateById();
        return data;
    }

……其他代码

}

图3-5-3-2 为动作配置校验表达式

注:

  1. ruleWithTips可以声明多个校验规则及错误提示;

  2. IS_BLANK和LEN为内置文本函数,更多内置函数详见4.1.12【函数之内置函数与表达式】一文;

  3. 当内置函数不满足时参考4.1.13【Action之校验】一文。

Step2 重启看效果

在商店管理页面点击【启用】得到了预期返回错误信息,显示"编码为必填项"

3.5.3 Action的类型

图3-5-3-3 在商店管理页面点击启用得到了预期返回错误信息

ServerAction之前端展示规则(举例)

既然后端对ServerAction发起提交做了校验,那能不能在前端就不展示呢?当然可以,我们现在就来试下。

Step1 配置PetShopProxyAction的dataStatusEnable的前端出现规则

用注解@Action.Advanced(invisible="!(activeRecord.code !== undefined && !IS_BLANK(activeRecord.code))")来表示,注意这里配对invisible是给前端识别的,所以写法上跟后端的校验有些不一样,但如内置函数IS_BLANK这些是前后端一致实现的,activeRecord在前端用于表示当前记录。

package pro.shushi.pamirs.demo.core.action;

……引用类

@Model.model(PetShopProxy.MODEL_MODEL)
@Component
public class PetShopProxyAction extends DataStatusBehavior<PetShopProxy> {

    @Override
    protected PetShopProxy fetchData(PetShopProxy data) {
        return data.queryById();
    }
    @Validation(ruleWithTips = {
            @Validation.Rule(value = "!IS_BLANK(data.code)", error = "编码为必填项"),
            @Validation.Rule(value = "LEN(data.name) < 128", error = "名称过长,不能超过128位"),
    })
    @Action(displayName = "启用")
    @Action.Advanced(invisible="!(activeRecord.code !== undefined && !IS_BLANK(activeRecord.code))")
    public PetShopProxy dataStatusEnable(PetShopProxy data){
        data = super.dataStatusEnable(data);
        data.updateById();
        return data;
    }

……其他代码

}

图3-5-3-4 配置PetShopProxyAction的dataStatusEnable的前端出现规则

Step2 重启看效果

我们发现店铺编码为空的记录,没有了【启用】的操作按钮

3.5.3 Action的类型

图3-5-3-5 店铺编码为空的记录没有启用操作按钮

ServerAction配置说明

常用配合

  1. contextType设置动作上下文类型

a. SINGLE(默认)——单行,常用于列表页(展示在每行末尾的操作栏中)和表单页(展示在页面上方)

b. BATCH——多行,常用于列表页(展示在表格上方按钮区)

c. SINGLE_AND_BATCH——单行或多行,常用于列表页(展示在表格上方按钮区)

d. CONTEXT_FREE——上下文无关,常用于列表页(展示在表格上方按钮区)

  1. bindingType设置按钮所在页面类型(以下仅说明常用类型,详见ViewTypeEnum)

a. TABLE——列表页

b. GALLERY——画廊

c. FORM——表单页

d. DETAIL——详情页

e. CUSTOM——自定义页

注解大全

@Action
├── displayName 显示名称
├── summary 摘要摘要
├── contextType 动作上下文,可选项详见ActionContextTypeEnum
├── bindingType 所在页面类型,可选项详见ViewTypeEnum
├── Advanced 更多配置
│ ├── name 技术名称,默认Java方法名
│ ├── args 参数,默认java参数
│ ├── type 方法类型,默认UPDATE,可选项详见FunctionTypeEnum
│ ├── language 方法实现语言,默认JAVA,可选项详见FunctionLanguageEnum
│ └── invisible 隐藏规则
│ └── bindingView 绑定特定视图
│ └── priority 展示顺序

四、第一个窗口动作ViewAction

回顾第一个ViewAction

第一个ViewAction是在3.3.2【模型的类型】一文中的“传输模型”部分出现的,再来看下当时的定义代码。

package pro.shushi.pamirs.demo.core.init;

……引用类

@Component
public class DemoModuleMetaDataEditor implements MetaDataEditor {
    @Override
    public void edit(AppLifecycleCommand command, Map<String, Meta> metaMap) {
        InitializationUtil util = InitializationUtil.get(metaMap, DemoModule.MODULE_MODULE,DemoModule.MODULE_NAME);
        if(util==null){
            return;
        }
        ……其他代码
        //初始化自定义前端行为
        viewActionInit(util);
        ……其他代码
    }
    private void viewActionInit(InitializationUtil util){
        util.createViewAction("demo_petShop_batch_update","批量更新数据状态", PetShopProxy.MODEL_MODEL,
                InitializationUtil.getOptions(ViewTypeEnum.TABLE), PetShopBatchUpdate.MODEL_MODEL,ViewTypeEnum.FORM, ActionContextTypeEnum.SINGLE_AND_BATCH
                , ActionTargetEnum.DIALOG,null,null);
    }
     ……其他代码
}

图3-5-3-6 回顾第一个ViewAction

createViewAction参数详解(建议更换为注解方式)

参数名 类型 说明
name String 技术名称,唯一建要求
displayName String 展示名称
originModel String ViewAction的绑定模型
originViewTypes List ViewAction在绑定模型的哪些视图类型上展示
targetModel String ViewAction跳转到的目标模型
targetViewType ViewTypeEnum ViewAction跳转到的目标模型的什么类型视图
contextType ActionContextTypeEnum ViewAction在绑定模型视图上设置展示的动作上下文类型SINGLE(默认)——单行,常用于列表页(展示在每行末尾的操作栏中)和表单页(展示在页面上方)BATCH——多行,常用于列表页(展示在表格上方按钮区)SINGLE_AND_BATCH——单行或多行,常用于列表页(展示在表格上方按钮区)CONTEXT_FREE——上下文无关,常用于列表页(展示在表格上方按钮区)
pageTarget ActionTargetEnum 页面打开方式 ROUTER:页面路由 DIALOG:页面弹窗 OPEN_WINDOW:打开新窗口DRAWER:打开抽屉
resViewName String ViewAction跳转到的目标模型的指定视图的名称,该视图的类型需要跟targetViewType一致
title String 页面标题
非createViewAction方法的参数,但是ViewAction模型有的属性,可在调用createViewAction以后,在通过setXX属性方法来设置对应属性字段值
priority Intget 展示顺序
bindingView String 绑定特定视图
invisible String 隐藏规则
load String 对于特殊模型的窗口动作进行定制化的加载方式
filter String 代表后端过滤,是一定会加上的过滤条件,用户无感知
domain String 代表前端过滤,是默认会加上的过滤条件,用户可以去除该搜索条件

表3-5-3-1 createViewAction参数详解

注解见:@UxRouteButton(action = @UxAction(),value = @UxRoute())

ViewAction高级参数-Load(下个版本支持)

一般用于以下场景:

  1. 对于特殊模型的窗口动作进行定制化的加载方式。

  2. 不同模型间跳转时,可根据上一个模型的数据内容加载另一个模型的数据内容。

使用初始化工具类设置Load函数:

util.modifyViewAction(TestModele.MODEL_MODEL, InitializationUtil.DEFAULT_CREATE,
        viewAction -> viewAction.setLoad("createPageLoad"));

图3-5-3-7 使用初始化工具类设置Load函数

注:

所示修改窗口动作方法将TestModel模型的默认创建页的加载函数从construct函数改为了createPageLoad函数。

替代方案:构建模型子类,通过子类来重写construct方法

ViewAction高级参数filter和domain(举例)

filter当前版本支持,domain下个版本支持,之所以放一起讲是因为这是过滤的两种形态。

  1. filter代表后端过滤,是一定会加上的过滤条件,用户无感知

  2. domain代表前端过滤,是默认会加上的过滤条件,用户可以去除该搜索条件

Step1 修改自定义pet_talent_table.xml查询条件增加name字段

<view name="tableView" model="demo.PetTalent" cols="1" type="TABLE" enableSequence="true" layout="petTalentTableLayout">
    ……其他代码
    <template slot="search"  cols="4">
        <field data="name" label="达人"/>
        <field data="dataStatus" label="数据状态">
            <options>
                <option name="DRAFT" displayName="草稿" value="DRAFT" state="ACTIVE"/>
                <option name="NOT_ENABLED" displayName="未启用" value="NOT_ENABLED" state="ACTIVE"/>
                <option name="ENABLED" displayName="已启用" value="ENABLED" state="ACTIVE"/>
                <option name="DISABLED" displayName="已禁用" value="DISABLED" state="ACTIVE"/>
            </options>
        </field>
        <field data="createDate" label="创建时间"/>
    </template>
</view>

图3-5-3-8 修改自定义pet_talent_table.xml查询条件增加name字段

Step2 为宠物达人模型的两个菜单入口分配置filter和domain

把【宠物达人】菜单调整为三个菜单【宠物达人1】、【宠物达人2】、【宠物达人3】分别设置filter和domain

  1. 修改以菜单【宠物达人1】为入口的ViewAction的filter:

    1. @UxRoute(filter = "name =like= \'老\'")字符串要符合RSQL
  2. 修改以菜单【宠狗达人2】为入口的ViewAction的domain:

    1. @UxRoute(domain = "name =like= \'老\'") 字符串要符合RSQL
  3. 修改以菜单【宠狗达人3】跟函数结合,设置时间默认过滤条件:

    1. @UxRoute(domain = "createDate =ge= \'${ADD_DAY(NOW_STR(),-7)}\' and createDate =lt= \'${NOW_STR()}\'") 字符串要符合RSQL

    2. createDate =ge= \'${ADD_DAY(NOW_STR(),-7)}\' and createDate =lt= \'${NOW_STR()}\'

      1. 用到函数需要用${}装饰;

      2. 更多函数详见4.1.12【函数之内置函数与表达式】一文。

  4. domain的操作符需要跟页面搜索字段定义的操作符一致,比如name字符串字段搜索默认操作符是=like=,如果配置成其他则无效。

@UxMenu("宠物达人1")@UxRoute(value = PetTalent.MODEL_MODEL,filter = "name =like= '老'") class PetTalentMenu{}
@UxMenu("宠物达人2")@UxRoute(value = PetTalent.MODEL_MODEL,domain = "name =like= '老'") class PetTalent2Menu{}
@UxMenu("宠物达人3")@UxRoute(value = PetTalent.MODEL_MODEL,domain = "createDate =ge= '${ADD_DAY(NOW_STR(),-7)}' and createDate =lt= '${NOW_STR()}'") class PetTalent3Menu{}

图3-5-3-9 两个菜单入口分配置filter和domain

Step3 重启看效果

因为【宠物达人1】对应ViewAction加的是Filter,所以只能看到达人名称带“老”字的记录

3.5.3 Action的类型

图3-5-3-10 宠物达人1搜索记录

因为【宠物达人2】对应ViewAction加的是Domain,前端搜索栏里【达人】字段搜索条件为“老”字,达人名称带“老”字的记录,可以手工删除再次搜索全部数据

3.5.3 Action的类型

图3-5-3-11 宠物达人2搜索记录

因为【宠物达人3】对应ViewAction加的是Domain,前端搜索栏里【创建时间】字段带近7天过滤条件,可以手工删除再次搜索全部数据

3.5.3 Action的类型

图3-5-3-12 宠物达人3搜索记录

五、第一个跳转动作UrlAction

回顾第一个UrlAction

在3.5.1【构建第一个Menu】一文中用@UxMenu.url定义了一个百度的菜单,该菜单背后就是一个普通的UrlAction

@UxMenu("Oinone官网")@UxLink(value = "http://www.oinone.top",openType= ActionTargetEnum.OPEN_WINDOW) class SsLink{}

图3-5-3-13 回顾第一个UrlAction

URL计算表达式(暂不支持)

@UxMenu("百度") @UxLink(value = "http://www.baidu.com?wd=${activeRecord.technicalName}",openType= ActionTargetEnum.OPEN_WINDOW) class BaiduLink{}

图3-5-3-14 URL计算表达式

Compute函数(暂不支持)

@UxMenu("百度") @UxLink(value = "http://www.baidu.com",openType= ActionTargetEnum.OPEN_WINDOW,context = {@Prop(name="wd",value= "activeRecord.technicalName"),compute="computeSearchUrl"}) class BaiduLink{}

@Model.model(PetTalent.MODEL_MODEL)
public class PetTalentAction {

    @Function(openLevel = FunctionOpenEnum.API, summary = "计算搜索Url")
    @Function.Advanced(type = FunctionTypeEnum.QUERY)
    public String computeSearchUrl(TestModel data) {
        return "https://www.baidu.com/s?wd=" + data.getName();
    }
}

图3-5-3-15 Compute函数

注:

  1. 代码所示创建链接动作含义为:以新标签页方式跳转至指定URL,该URL值来自于调用后端computeSearchUrl方法的返回值。

六、第一个客户端动作ClientAction

基础客户端动作(举例)

给批量修改店铺状态弹出页面增加一个【自定义返回】和【自定义关闭】按钮,这里注意contextType只能配置为“ActionContextTypeEnum.SINGLE”,因为Form默认只展示contextType为SINGLE的Action

Step1 在PetShopBatchUpdateAction增加@UxClientButton注解

@Model.model(PetShopBatchUpdate.MODEL_MODEL)
@UxClientButton(action = @UxAction(name = "demo_back_test", label = "自定义返回",contextType = ActionContextTypeEnum.SINGLE,bindingType = ViewTypeEnum.FORM),value = @UxClient(value = "$$internal_GotoListTableRouter"))
@UxClientButton(action = @UxAction(name = "demo_close_test", label = "自定义关闭",contextType = ActionContextTypeEnum.SINGLE,bindingType = ViewTypeEnum.FORM),value = @UxClient(value = "$$internal_DialogCancel"))
@Component
public class PetShopBatchUpdateAction {
}

图3-5-3-16 在PetShopBatchUpdateAction增加@UxClientButton注解

Step2 重启看效果

3.5.3 Action的类型

图3-5-3-17 示例效果

前端动作之组合动作(举例)

通过自定义View的Template来设置组合动作,同时学习下自定义视图时如何设置需要展示Action,还是以批量修改店铺状态弹出页面为例子,我们只展示一个组合动作按钮【组合动作】,它包含表单校验、提交、关闭并刷新主视图等行为动作

Step1 自定义弹出框View

  1. 在views/demo_core/template路径下增加一个名为pet_shop_batch_update_form.xml文件

  2. 再通过数据库查看默认页面定义,找到base_view表,过滤条件设置为model =\'demo.PetShopBatchUpdate\',我们就看到该模型下对应的所有view,这些是系统根据该模型的ViewAction对应生成的默认视图,找到类型为【表单(type = FORM)】的记录,查看template字段,复制给pet_shop_batch_update_form.xml文件

  3. 把【<template slot="actions" autoFill="true"/>】替换成以下内容

    <template slot="actions" >
        <action actionType="composition" label="组合动作">
            <action actionType="client" name="$$internal_ValidateForm" />
            <action name="conform" />
            <action actionType="client" name="$$internal_GotoListTableRouter" />
        </action>
    </template>

图3-5-3-18 替换

Step2 重启看效果

这个页面只保留了【组合动作】一个按钮,其他没有配置的按钮就会隐藏掉。

3.5.3 Action的类型

图3-5-3-19 未配置的按钮均会被隐藏

平台默认前端动作:

有元数据定义名的建议最好用元数据名,比如平台默认前端导入动作“$$internal_GotoListImportDialog”可以用“internalGotoListImportDialog”来替代,这样的好处是管理一致,比如权限等功能设置.

<!-- <action name="$$internal_GotoListImportDialog" label="导入" /> 可以用下面方式替代,可以用于权限 -->
<action name="internalGotoListImportDialog" label="导入" />

图3-5-3-20 “$$internal_GotoListImportDialog”可用“internalGotoListImportDialog”替代

name 适用场景 功能描述 元数据定义名
$$internal_GotoListTableRouter 通用 返回上一个页面 internalGotoListTableRouter
$$internal_DeleteOne 关系字段表格 删除绑定的表格的选中数据 internalDeleteOne
$$internal_DialogCancel 弹窗 关闭当前弹窗
$$internal_ReloadData 弹窗 刷新当前主视图组件
$$internal_ListInsertOneAndCloseDialog 通用 打开一个创建弹窗
$$internal_GotoM2MListDialog 多对多关系 表格 打开M2M表格的创建弹窗
$$internal_GotoO2MCreateDialog 一对多关系 表格 打开O2M表格的创建弹窗
$$internal_GotoO2MEditDialog 一对多关系 表格 打开O2M表格的编辑弹窗
$$internal_ListInsertOneAndBackToList 表单 校验表单数据,提交到后端,返回表格(新建)
$$internal_ListUpdateOneAndBackToList 表单 校验表单数据,提交到后端,返回表格(更新)
$$internal_ValidateForm 表单 校验当前表单
$$internal_GotoListExportDialog 一般用于表格 数据导出的action internal_GotoListImportDialog
$$internal_GotoListImportDialog 一般用于表格 数据导入的action internalGotoListImportDialog

表3-5-3-2 平台默认前端动作

Oinone社区 作者:史, 昂原创文章,如若转载,请注明出处:https://doc.oinone.top/oio4/9255.html

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

(0)
史, 昂的头像史, 昂数式管理员
上一篇 2024年5月23日 am9:23
下一篇 2024年5月23日 am9:25

相关推荐

  • 3.2.3 应用中心

    在App Finder 中点击应用中心可以进入oinone的应用中心,可以看到oinone平台所有应用列表、应用大屏、以及技术可视化。 一、应用列表 标准版本不支持在线安装,只能通过boot工程的yml文件来配置安装模块。在 www.oinone.top 官方SaaS平台客户可以在线管理应用生命周期如:安装、升级、卸载。同时针对已安装应用可以进行无代码设计(前提安装了设计器),针对应用类的模块则可进行收藏,收藏后会在App Finder中的我收藏的应用中出现。在应用列表中可以看到我们已经安装的应用以及模块,我们oinoneDemo工程也在其中。 图3-2-35 Oinone的应用列表 图3-2-36 应用收藏后会在App Finder的【我收藏的应用】中出现 二、应用大屏 但我们的测试应用没有设置应用类目,则无法在应用大屏中呈现。 图3-2-37 未设置应用类目则无法在应用大屏中呈现 三、技术可视化 在技术可视化页面,出展示已经安装模块的元数据,并进行分类呈现 图3-2-38 云数据分类呈现

    2024年5月23日
    1.3K00
  • 3.5.7.6 自定义字段

    字段是什么 字段的基本概念 定义:字段通常指的是数据的一个单独项,它可以是一个文本框、下拉菜单、复选框等,用于在用户界面上收集或展示数据。 用途:在表单中,字段用于收集用户输入;在表格或列表中,字段用于显示数据。 类型:字段可以有不同的类型,如文本、数字、日期等,这些类型通常由数据模型定义。 Oinone框架中的字段 在Oinone框架中,字段的设计和实现遵循以下原则: 后端模型驱动:前端的字段直接由后端的数据模型决定。这意味着后端定义了哪些数据应该展示,以及如何展示。 减少前后端联调:由于字段的定义和行为是由后端控制的,前后端的联调需求大大减少。前端开发者主要关注于如何呈现这些字段,而后端则负责数据的逻辑和结构。 灵活性与规范性:虽然Oinone推荐所有场景都遵循后端模型驱动字段的原则,以保持前后端的一致性和减少沟通成本,但它也为高度定制化的前端页面提供了灵活性。 元数据使用:Oinone可能还使用元数据来进一步定义字段的行为,例如它们是否可见、如何验证用户输入等。 结合前后端 在使用Oinone时,理解前后端如何合作来定义和展示字段是很重要的。这种方法不仅提高了开发效率,而且有助于确保数据的一致性和应用程序的可维护性。同时,对于那些需要特定定制或特殊处理的场景,开发团队能够灵活地适应这些需求,在遵守总体架构原则的同时进行一些特定的调整和优化。 作用场景 在Oinone框架中,字段扮演着连接后端数据模型和前端用户界面的重要角色。其作用场景包括但不限于以下几点: 业务组件的核心: Oinone集成了AntdDesignVue的全部UI组件,将它们转化为业务组件。这些业务组件以字段的形式存在,使得前端开发变得简单高效。开发人员可以直接使用这些现成的业务组件来构建用户界面,大大减少了开发工作量。 无代码开发支持: 字段的设计使得Oinone支持无代码开发。开发者可以通过拖拉拽的方式在前端快速构建界面,而后端模型的定义直接决定了这些界面的生成。这种模式简化了传统的前端开发流程,提升了开发效率。 个性化定制: 虽然标准的UI组件可以满足大部分需求,但复杂多变的业务场景往往需要更多个性化的处理。在Oinone中,开发者可以根据具体业务需求和公司的UI指南,定义专门针对特定行业或客户的定制化字段和组件。 与无代码平台的结合: Oinone允许将个性化的字段和组件与无代码平台相结合。这意味着即使在进行个性化定制时,也能保持使用无代码工具的便利性,实现更灵活、更高效的前端开发。 适应多维度业务需求: 由于字段在Oinone中的灵活性和可定制性,它们能够适应多维度的业务需求,无论是从UI设计、用户体验还是业务逻辑的角度,字段都能提供合适的解决方案 自定义字段 示例工程目录 以下是需关注的工程目录示例,main.ts更新导入./field: 图3-5-7-24 自定义字段工程目录示例 示例代码 创建自定义字段组件: 使用Vue框架创建一个新的组件(例如 CustomStringFieldVue),并定义其模板、脚本和样式。 在模板中定义字段的HTML结构。 在脚本中使用 defineComponent 来定义Vue组件。 字段类的定义: 导入必要的模块,如 FormFieldWidget, ModelFieldType, SPI, ViewType 等。 使用 @SPI.ClassFactory 装饰器来注册自定义字段。 在类内部初始化并设置组件。 SPI注册参数解释: viewType: 指定视图类型,如表单视图或搜索视图。 widget: 可以指定组件名称。 ttype: 字段的业务类型,例如字符串、数字等。 multi: 指明字段是否支持多值。 model: 定义字段所属的模型。 viewName: 指定视图名称。 name: 定义所属字段的名称。 import {FormFieldWidget, ModelFieldType, SPI, ViewType} from '@kunlun/dependencies'; import CustomStringFieldVue from './CustomStringField.vue'; @SPI.ClassFactory( FormFieldWidget.Token({ viewType: [ViewType.Form, ViewType.Search], ttype: ModelFieldType.String }) ) export class CustomStringField extends FormFieldWidget { public initialize(props) { super.initialize(props); this.setComponent(CustomStringFieldVue); return this; } } 图3-5-7-24 自定义字段组件(TS)示例 <template> <div class="custom-string-filed-wrapper"> 字段组件 </div> </template> <script lang="ts"> import { defineComponent } from 'vue' export default defineComponent({ inheritAttrs: false, name: 'CustomStringFieldVue' }) </script> <style lang="scss"> .custom-string-filed-wrapper { } </style> 图3-5-7-24 自定义字段组件(Vue)示例 效果 图3-5-7-24 自定义字段效果示例

    2024年5月23日
    1.1K00
  • 3.5.7.4 自定义页面

    页面是什么 在Oinone前端体系中,页面是一个核心概念,它代表着终端用户所看到的当前视图。这个视图可以有多种形式,主要取决于页面是如何定义和构建的。在深入理解页面之前,我们需要了解两个关键的功能:自定义布局 和 自定义母版。 作用场景 自定义布局 提供了布局调整的强大功能,但在某些情况下,它可能无法完全满足特定的需求。这时,自定义页面就显得尤为重要。自定义页面是对 自定义布局 的补充,允许开发者从更深层次自由地控制和设计用户界面。 当标准布局无法实现所需的视觉效果或功能时,自定义页面提供了更高的灵活性。开发者可以通过自定义页面来实现独特的布局设计,添加特定的交互元素,或者整合复杂的业务逻辑,以创造独特且丰富的用户体验。 自定义页面 自定义视图组件允许开发者定义和使用特定于业务需求的视图布局。下面是一个具体的示例,展示了如何定义、注册和使用通过 setComponent 结合 TypeScript 和 Vue 的自定义视图组件。 示例工程目录 以下是需关注的工程目录示例,main.ts更新导入./view: 图3-5-7-48 自定义页面工程目录示例 1. 定义 TypeScript 组件 首先,我们定义了一个名为 CustomViewWidget 的 TypeScript 组件,并在该组件中通过 setComponent 结合 Vue 单文件组件。 import { BaseElementWidget, BaseElementViewWidget, SPI, ViewWidget } from '@kunlun/dependencies'; import CustomViewVue from './CustomView.vue'; @SPI.ClassFactory(BaseElementWidget.Token({ widget: 'CustomViewWidget' })) export class CustomViewWidget extends BaseElementViewWidget { public initialize(props) { super.initialize(props); this.setComponent(CustomViewVue); return this; } } 图3-5-7-49 定义TypeScript组件代码示例 2. Vue 单文件组件 其次,我们创建了对应的 Vue 单文件组件 CustomView.vue,用于展示自定义视图的具体内容。 <template> <div class="custom-view-wrapper"> <h1>自定义视图</h1> </div> </template> <script lang="ts"> import { defineComponent } from 'vue'; export default defineComponent({ inheritAttrs: false, name: 'ViewComponentVue' }); </script> <style lang="scss"> .custom-view-wrapper {} </style> 图3-5-7-50 定义Vue组件代码示例 3. 注册自定义视图布局 接下来,我们使用 registerLayout 函数注册了一个表格视图布局,并在其中引入了通过 setComponent 结合的自定义视图组件。 import { registerLayout, ViewType } from "@kunlun/dependencies"; export const registerCustomView = () => { registerLayout( ` <view type="TABLE"> <element widget="CustomViewWidget" /> </view> `, { viewType: ViewType.Table, moduleName: 'resource', model: 'resource.ResourceCountryGroup' } ); }; registerCustomView(); 图3-5-7-51 注册自定义视图布局代码示例 效果 图3-5-7-52 自定义页面效果示例 4. 自定义视图在表格中的应用 当我们注册了自定义视图后,它就可以在表格视图中被使用。在表格视图的布局中,我们通过 标签将自定义视图嵌套在表格中,从而覆盖了表格的默认布局 5. 入参一致性 值得强调的是,registerLayout 函数和自定义布局的规则是一致的,这意味着开发者可以在自定义布局中使用与 registerLayout 相同的入参规则,从而实现更加灵活和统一的视图布局设计 与内置组件结合 1. 注册视图元素布局 首先,我们使用 registerLayout 函数注册了一个表格视图的布局。这个布局包含了搜索框、操作栏、以及一个自定义视图组件。 import { registerLayout, ViewType } from "@kunlun/dependencies"; import { CustomViewWidget } from…

    2024年5月23日
    1.2K00
  • 3.3.5 模型编码生成器

    在我们日常开发中经常要一些单据生成指定格式的编码,而且现在分布式环境下要考虑的事情会特别多。oinone提供了简易的编码生成能力 一、编码生成器 可以在模型或者字段上配置编码自动生成规则。在进行数据存储时,如果配置了编码自动生成规则的字段值为空,则系统将根据规则自动生成编码。编码自动生成功能是通过序列生成器来支持的。可以在序列生成器生成的序列编码基础上再进行组合配置的功能编码生成最终的编码。序列生成器可以配置初始序列,步长,日期格式,长度。 模型序列生成器(举例) 使用模型编码生成器,需要继承CodeModel或者有Code字段,那么使用Model.Code注解即可。 Step1 为PetShop增加一个@Model.Code注解,并增加一个店铺编码(Code)字段 package pro.shushi.pamirs.demo.api.model; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; import java.sql.Time; @Model.model(PetShop.MODEL_MODEL) @Model(displayName = "宠物店铺",summary="宠物店铺",labelFields = {"shopName"}) @Model.Code(sequence = "DATE_ORDERLY_SEQ",prefix = "P",size=6,step=1,initial = 10000,format = "yyyyMMdd") public class PetShop extends AbstractDemoIdModel { public static final String MODEL_MODEL="demo.PetShop"; @Field(displayName = "店铺编码") private String code; @Field(displayName = "店铺名称",required = true) private String shopName; @Field(displayName = "开店时间",required = true) private Time openTime; @Field(displayName = "闭店时间",required = true) private Time closeTime; } 图3-3-5-1 为PetShop增加一个@Model.Code注解 Step2 重启查看效果 进入店铺新增页面新增一个oinone宠物店铺003 图3-3-5-2 示例操作效果图 查看店铺列表页面,新增的记录中店铺编码一列,已经按Model.Code注解要求地生成了 图3-3-5-3 示例操作效果图 Step3 小结 在我们日常开发中经常要一些单据生成指定格式的编码,而且现在分布式环境下要考虑的事情会特别多。oinone提供了简易的编码生成能力,大家可以根据编码注解说明,自行对PetShop模型进行不同配置,来学习编码生成器的知识 字段序列生成器 字段编码生成器,在对应的字段上增加,并使用Field.Sequence注解即可 Step1 为PetShop增加一个字段codeTwo并增加@Field.Sequence注解 package pro.shushi.pamirs.demo.api.model; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; import java.sql.Time; @Model.model(PetShop.MODEL_MODEL) @Model(displayName = "宠物店铺",summary="宠物店铺",labelFields = {"shopName"}) @Model.Code(sequence = "DATE_ORDERLY_SEQ",prefix = "P",size=6,step=1,initial = 10000,format = "yyyyMMdd") public class PetShop extends AbstractDemoIdModel { public static final String MODEL_MODEL="demo.PetShop"; @Field(displayName = "店铺编码") private String code; @Field(displayName = "店铺编码2") @Field.Sequence(sequence = "DATE_ORDERLY_SEQ",prefix = "C",size=6,step=1,initial = 10000,format = "yyyyMMdd") private String codeTwo; @Field(displayName = "店铺名称",required = true) private String shopName; @Field(displayName = "开店时间",required = true) private Time openTime; @Field(displayName = "闭店时间",required = true) private Time closeTime; } 图3-3-5-4 为PetShop增加一个字段codeTwo Step2 重启查看效果 进入店铺新增页面新增一个oinone宠物店铺004 图3-3-5-5 示例操作效果图 查看店铺列表页面,新增的记录中店铺编码2一列,已经按Field.Sequence注解要求地生成了 图3-3-5-6 示例操作效果图 二、编码注解说明,模型更多其他注解详见4.1.6【模型之元数据详解】…

    2024年5月23日
    1.3K00

Leave a Reply

登录后才能评论