3.3.9 字段类型之关系与引用

有关系与引用类型才让oinone具备完整的描述模型与模型间关系的能力

在PetShop以及其代理模型中已经上用到了O2M、M2O字段,分别如petItems(PetItem)和create(PamrisUser)字段,但是没有过多的讲解。本文重点举例RELATED、M2M、O2M,至于M2O留给大家自行尝试。

一、引用类型(举例)

业务类型 Java类型 数据库类型 规则说明
RELATED 基本类型或关系类型 不存储或varchar、text 引用字段【数据库规则】:点表达式最后一级对应的字段类型;数据库字段值默认为Java字段的序列化值,默认使用JSON序列化【前端交互规则】:点表达式最后一级对应的字段控件类型

表3-3-9-1 字段引用类型

Step1 修改PetShopProxy类

  1. 为PetShopProxy类新增一个引用字段relatedShopName,并加上@Field.Related("shopName")注解

  2. 为PetShopProxy类新增一个引用字段createrId,并加上@Field.Related({"creater","id"})注解

package pro.shushi.pamirs.demo.api.proxy;

import pro.shushi.pamirs.demo.api.model.PetShop;
import pro.shushi.pamirs.meta.annotation.Field;
import pro.shushi.pamirs.meta.annotation.Model;
import pro.shushi.pamirs.meta.enmu.ModelTypeEnum;
import pro.shushi.pamirs.user.api.model.PamirsUser;

@Model.model(PetShopProxy.MODEL_MODEL)
@Model.Advanced(type = ModelTypeEnum.PROXY)
@Model(displayName = "宠物店铺代理模型",summary="宠物店铺代理模型")
public class PetShopProxy extends PetShop {

    public static final String MODEL_MODEL="demo.PetShopProxy";

    @Field.many2one
    @Field(displayName = "创建者",required = true)
    @Field.Relation(relationFields = {"createUid"},referenceFields = {"id"})
    private PamirsUser creater;

    @Field.Related("shopName")
    @Field(displayName = "引用字段shopName")
    private String relatedShopName;

    @Field.Related({"creater","id"})
    @Field(displayName = "引用创建者Id")
    private String createrId;

}

图3-3-9-1 修改PetShopProxy类

Step2 重启系统查看效果

我们发现商店管理-列表页面多出了两个有值字段:引用字段shopName和引用创建者Id

1711608487971-8e48aebc-e6c3-4143-a95d-ca649dfdee8f图3-3-9-2 商店管理-列表页面新增两个有值字段

二、关系类型

业务类型 Java类型 数据库类型 规则说明
O2O 模型/DataMap 不存储或varchar、text 一对一关系
M2O 模型/DataMap 不存储或varchar、text 多对一关系
O2M List<模型/DataMap> 不存储或varchar、text 一对多关系
M2M List<模型/DataMap> 不存储或varchar、text 多对多关系

表3-3-9-2 字段关系类型

多值字段或者关系字段需要存储,默认使用JSON格式序列化。多值字段数据库字段类型默认为varchar(1024);关系字段数据库字段类型默认为text。

关系字段

关联关系用于描述模型间的关联方式:

  • 多对一关系,主要用于明确从属关系
  • 一对多关系,主要用于明确从属关系
  • 多对多关系,主要用于弱依赖关系的处理,提供中间模型进行关联关系的操作
  • 一对一关系,主要用于多表继承和行内合并数据

3.3.9 字段类型之关系与引用

图3-3-9-3 字段关联关系

名词解释

关联关系比较重要的名词解释如下:

  • 关联关系:使用relation表示,模型间的关联方式的一种描述,包括关联关系类型、关联关系双边的模型和关联关系的读写
  • 关联关系字段:业务类型ttype为O2O、O2M、M2O或M2M的字段
  • 关联模型:使用references表示,自身模型关联的模型
  • 关联字段:使用referenceFields表示,关联模型的字段,表示关联模型的哪些字段与自身模型的哪些字段建立关系
  • 关系模型:自身模型
  • 关系字段:使用relationFields表示,自身模型的字段,表示自身模型的哪些字段与关联模型的哪些字段建立关系
  • 中间模型,使用through表示,只有多对多存在中间模型,模型的relationship=true

举例M2M关系类型

多对多关系,主要用于弱依赖关系的处理,提供中间模型进行关联关系的操作。这也是在业务开发中很常见用于描述单据间关系,该例子会举例两种方式描述多对多关系中间表,一是中间表没有在系统显示定义模型,二种是中间表显示定义模型。第一种往往仅是维护多对多关系,第二种往往用于多对多关系中间表自身也需要管理有业务含义,中间表模型还经常额外增加其他字段。

一是中间表没有在系统显示定义模型:如果出现跨模块的场景,在分布式环境下两个模块独立启动,有可能会导致系统关系表被删除的情况发生,因为没有显示定义中间表模型,中间表的模型所属模块会根据两边模型的名称计算,如果刚好被计算到非关系字段所属模型的模块。那么单独启动非关系字段所属模型的模块,则会导致删除关系表。

为什么不直接把中间表的模型所属模块设置为关系字段所属模型的模块?因为如果这样做,当模型两边都定义了多对多关系字段则会导致M2M关系表的所属模块出现混乱。

所以这里建议大家都选用:第二种中间表显示定义模型,不论扩展性还是适应性都会好很多。请用:through=XXXRelationModel.MODEL_MODEL 或者 throughClass=XXXRelationModel.class

Step1 新建宠物达人模型,并分别为宠物商品和宠物商店增加

到宠物达人模型的字段

  1. 新建宠物达人模型PetTalent
package pro.shushi.pamirs.demo.api.model;

import pro.shushi.pamirs.meta.annotation.Field;
import pro.shushi.pamirs.meta.annotation.Model;

@Model.model(PetTalent.MODEL_MODEL)
@Model(displayName = "宠物达人",summary="宠物达人",labelFields ={"name"})
public class PetTalent extends AbstractDemoIdModel{
    public static final String MODEL_MODEL="demo.PetTalent";

    @Field(displayName = "达人")
    private String name;

}

图3-3-9-4 新建宠物达人模型PetTalent

  1. 修改宠物商品模型,新增many2many字段petTalents,类型为List ,并加上注解@Field.many2many(relationFields = {"petItemId"},referenceFields = {"petTalentId"},through = PetItemRelPetTalent.MODEL_MODEL),through为指定关联中间表。
package pro.shushi.pamirs.demo.api.model;

import pro.shushi.pamirs.demo.api.tmodel.PetItemDetail;
import pro.shushi.pamirs.meta.annotation.Field;
import pro.shushi.pamirs.meta.annotation.Model;
import pro.shushi.pamirs.meta.enmu.NullableBoolEnum;

import java.math.BigDecimal;
import java.util.List;

@Model.model(PetItem.MODEL_MODEL)
@Model(displayName = "宠物商品",summary="宠物商品",labelFields = {"itemName"})
public class PetItem  extends AbstractDemoCodeModel{

    public static final String MODEL_MODEL="demo.PetItem";

    @Field(displayName = "商品名称",required = true)
    private String itemName;

    @Field(displayName = "商品价格",required = true)
    private BigDecimal price;

    @Field(displayName = "店铺",required = true)
    @Field.Relation(relationFields = {"shopId"},referenceFields = {"id"})
    private PetShop shop;

    @Field(displayName = "店铺Id",invisible = true)
    private Long shopId;

    @Field(displayName = "品种")
    @Field.many2one
    @Field.Relation(relationFields = {"typeId"},referenceFields = {"id"})
    private PetType type;

    @Field(displayName = "品种类型",invisible = true)
    private Long typeId;

    @Field(displayName = "详情", serialize = Field.serialize.JSON, store = NullableBoolEnum.TRUE)
    @Field.Advanced(columnDefinition = "varchar(1024)")
    private List<PetItemDetail> petItemDetails;

    @Field(displayName = "商品标签",serialize = Field.serialize.COMMA,store = NullableBoolEnum.TRUE,multi = true)
    @Field.Advanced(columnDefinition = "varchar(1024)")
    private List<String> tags;

    @Field.many2many(relationFields = {"petItemId"},referenceFields = {"petTalentId"},through = PetItemRelPetTalent.MODEL_MODEL)
    @Field(displayName = "推荐达人",summary = "推荐该商品的达人们")
    private List<PetTalent> petTalents;

}

图3-3-9-5 修改宠物商品模型

  1. 修改宠物商店模型

    a. 新增many2many关联模型PetShopRelPetTalent并继承BaseRelation,BaseRelation为关系模型抽象基类用于承载多对多关系,是多对多关系的中间模型,数据模型主键可以不是ID。更多类似抽象基类详见3.3.2【模型的类型】一文中关于模型快捷继承相关内容。

package pro.shushi.pamirs.demo.api.model;

import pro.shushi.pamirs.meta.annotation.Field;
import pro.shushi.pamirs.meta.annotation.Model;
import pro.shushi.pamirs.meta.base.BaseRelation;

@Model.model(PetShopRelPetTalent.MODEL_MODEL)
@Model(displayName = "宠物店铺与达人关联表",summary="宠物店铺与达人关联表")
public class PetShopRelPetTalent extends BaseRelation {

    public static final String MODEL_MODEL="demo.PetShopRelPetTalent";
    @Field(displayName = "店铺Id")
    private Long petShopId;

    @Field(displayName = "达人Id")
    private Long petTalentId;

}

图3-3-9-6 新增many2many关联模型PetShopRelPetTalent

b. 修改宠物商店模型,新增many2many字段petTalents,类型为List ,并加上注解@Field.many2many(relationFields = {"petShopId"},referenceFields = {"petTalentId"},throughClass =PetShopRelPetTalent.class) ,throughClass为指定关联模型类

package pro.shushi.pamirs.demo.api.model;

import pro.shushi.pamirs.core.common.enmu.DataStatusEnum;
import pro.shushi.pamirs.demo.api.enumeration.PetShopOptionEnum;
import pro.shushi.pamirs.meta.annotation.Field;
import pro.shushi.pamirs.meta.annotation.Model;
import pro.shushi.pamirs.meta.enmu.DateFormatEnum;
import pro.shushi.pamirs.meta.enmu.DateTypeEnum;

import java.math.BigDecimal;
import java.sql.Time;
import java.util.Date;
import java.util.List;

@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,immutable=true)
    private String shopName;

    @Field(displayName = "开店时间",required = true)
    @Field.Advanced(readonly = true)
    private Time openTime;

    @Field(displayName = "闭店时间",required = true)
    private Time closeTime;

    @Field.Enum
    @Field(displayName = "数据状态",defaultValue = "DISABLED",required = true,summary = "枚举可选项举例")
    private DataStatusEnum dataStatus;

    @Field(displayName = "店铺标志")
    private List<PetShopOptionEnum> options;

    @Field(displayName = "一年内新店")
    private Boolean oneYear;

    @Field.Float
    @Field(displayName = "店内员工平均年龄")
    private BigDecimal averageAge;

    @Field.Text
    @Field(displayName = "描述")
    private String description;

    @Field.Html
    @Field(displayName = "html描述")
    private String descHtml;

    @Field.Date(type = DateTypeEnum.DATE,format = DateFormatEnum.DATE)
    @Field(displayName = "店庆")
    private Date anniversary;

//    前端未提供默认支持,演示不了。这个留在我们自定义前端页面时演示
//    @Field.Date(type = DateTypeEnum.YEAR,format = DateFormatEnum.YEAR)
//    @Field(displayName = "开店年份")
//    private Date shopYear;

    @Field.Money
    @Field(displayName = "收入",priority = 1)
    private BigDecimal income;

    @Field.many2many(relationFields = {"petShopId"},referenceFields = {"petTalentId"},throughClass =PetShopRelPetTalent.class)
    @Field(displayName = "推荐达人",summary = "推荐该商品的达人们")
    private List<PetTalent> petTalents;

}

图3-3-9-7 新增many2many字段petTalents

Step2 重启看效果

  1. 进入宠物商品-编辑页面,可以看到多了推荐达人字段,点击添加选择达人记录。至于达人数据管理这里就不赘述了,只要为达人模型配一个菜单入口进去新增就好了

3.3.9 字段类型之关系与引用

图3-3-9-8 新增many2many字段petTalents

  1. 进入宠物商品-列表页面,就可以看到达人字段所选的记录

3.3.9 字段类型之关系与引用

图3-3-9-9 进入宠物商品-列表页面

  1. 宠物商店的效果参考宠狗商品的编辑路径

  2. 查看数据库表,对应的表和字段都已经生成了

3.3.9 字段类型之关系与引用

图3-3-9-10 数据库表对应的表和字段都已生成

举例O2M

O2M跟M2O和M2M不一样,O2M的交互方式新建关联模型记录并一把提交,而M2O和M2M而是通过添加方式选择已有关联模型记录。

Step1 把PetShopProxyA的items字段提取到父类PetShop中去

为什么要把PetShopProxyA的items提取到PetShop中去呢?因为代理模型新增的字段都是非存储字段,如果需要保存需要自己覆盖模型的create和update方法手工保存关联对象。这个在3.3.2【模型的类型】一文中关于代理模型的内容中有详细介绍,大家忘了可以去温习下。

  1. 去除PetShopProxyA的items字段
package pro.shushi.pamirs.demo.api.proxy;

import pro.shushi.pamirs.demo.api.model.PetShop;
import pro.shushi.pamirs.meta.annotation.Model;
import pro.shushi.pamirs.meta.enmu.ModelTypeEnum;

@Model.model(PetShopProxyA.MODEL_MODEL)
@Model.Advanced(type = ModelTypeEnum.PROXY)
@Model(displayName = "宠物店铺代理模型A",summary="宠物店铺代理模型A")
public class PetShopProxyA extends PetShop {
    public static final String MODEL_MODEL="demo.PetShopProxyA";

}

图3-3-9-11 去除PetShopProxyA的items字段

  1. 在PetShop中增加items字段
package pro.shushi.pamirs.demo.api.model;

import pro.shushi.pamirs.core.common.enmu.DataStatusEnum;
import pro.shushi.pamirs.demo.api.enumeration.PetShopOptionEnum;
import pro.shushi.pamirs.meta.annotation.Field;
import pro.shushi.pamirs.meta.annotation.Model;
import pro.shushi.pamirs.meta.enmu.DateFormatEnum;
import pro.shushi.pamirs.meta.enmu.DateTypeEnum;

import java.math.BigDecimal;
import java.sql.Time;
import java.util.Date;
import java.util.List;

@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,immutable=true)
        private String shopName;

        @Field(displayName = "开店时间",required = true)
        private Time openTime;

        @Field(displayName = "闭店时间",required = true)
        private Time closeTime;

        @Field.Enum
        @Field(displayName = "数据状态",defaultValue = "DRAFT",required = true,summary = "枚举可选项举例")
        private DataStatusEnum dataStatus;

        @Field(displayName = "店铺标志")
        private List<PetShopOptionEnum> options;

        @Field(displayName = "一年内新店")
        private Boolean oneYear;

        @Field.Float
        @Field(displayName = "店内员工平均年龄")
        private BigDecimal averageAge;

        @Field.Text
        @Field(displayName = "描述")
        private String description;

        @Field.Html
        @Field(displayName = "html描述")
        private String descHtml;

        @Field.Date(type = DateTypeEnum.DATE,format = DateFormatEnum.DATE)
        @Field(displayName = "店庆")
        private Date anniversary;

        @Field.Date(type = DateTypeEnum.YEAR,format = DateFormatEnum.YEAR)
        @Field(displayName = "开店年份")
        private Date publishYear;

        @Field.Money
        @Field(displayName = "收入",priority = 1)
        private BigDecimal income;

        @Field.many2many(relationFields = {"petShopId"},referenceFields = {"petTalentId"},throughClass =PetShopRelPetTalent.class)
        @Field(displayName = "推荐达人",summary = "推荐该商品的达人们")
        private List<PetTalent> petTalents;

        @Field.one2many
        @Field(displayName = "商品列表")
        @Field.Relation(relationFields = {"id"},referenceFields = {"shopId"})
        private List<PetItem> items;

    }

图3-3-9-12 在PetShop中增加items字段

Step2 重启应用查看效果

前文中PetShopProxyB代理模型扩展了catItems萌猫商品列表字段,因为该字段是代理模型的非存储字段。但上一步操作中原本PetShopProxyB从PetShopProxyA继承的非存储字段items,转而变成了从PetShop继承的存储字段。那么我们试下catItems和items都添加记录的效果吧。

  1. 点击菜单商店管理B进入PetShopProxyB代理模型的管理页,选择商店记录点编辑进入商店管理B-编辑页,商品列表字段处新增两个商品分别是萌猫商品1005,宠狗商品1006;

3.3.9 字段类型之关系与引用

图3-3-9-13 示例效果图

3.3.9 字段类型之关系与引用

图3-3-9-14 示例效果图

  1. 萌猫商品列表处字段新增商品“代理模型萌猫商品1007”

3.3.9 字段类型之关系与引用

图3-3-9-15 示例效果图

3.3.9 字段类型之关系与引用

图3-3-9-16 示例效果图

  1. 保存查看商品管理页面发现商品只是创建了萌猫商品1005和宠狗商品1006,而没有代理模型萌猫商品

3.3.9 字段类型之关系与引用

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

O2O

O2O与M2O相比,在从前端交互体验上跟M2O一样都是下拉单选,但有一个区别在于目标对象只能被一个操作对象绑定。

限制:同时模型的O2O字段关联的模型与本模型必须要在同一模块中,否则会报错。因为O2O字段需要两边对等建立关系字段

O2M,O2O字段的提交策略(该版本还未支持)

注解的onUpdate和onDelete属性指定在删除模型或更新模型关系字段值时,对关联模型进行的相应操作。操作包括RESTRICT、NO ACTION、SET NULL和CASCADE,默认值为SET NULL。

  • RESTRICT是指模型与关联模型有关联记录的情况下,引擎会阻止模型关系字段的更新或删除模型记录;

  • NO ACTION是指不作约束(这里与数据库约束的定义不相同);

  • CASCADE表示在更新模型关系字段或者删除模型时,级联更新关联模型对应记录的关联字段值或者级联删除关联模型对应记录;

  • SET NULL则是表示在更新模型关系字段或者删除模型的时候,关联模型的对应关联字段将被SET NULL(该字段值允许为null的情况下,若不允许为null,则引擎阻止对模型的操作)。

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

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

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

相关推荐

  • 2.4.2 Oinone独特性之每一个需求都可以是一个模块

    我们的Oinone平台采用模型驱动的方式,并符合面向对象设计原则,每个需求都可以是一个独立模块,可以独立安装、升级和卸载。这让系统真正像乐高积木一样搭建,具有高度的灵活性和可维护性。 与大部分低代码或无代码平台不同的是,它们的应用市场上的应用往往是模板式的,也就是说,这是一个拷贝,个性化只能在应用上直接修改,而且一旦修改就不能升级。这对于软件公司和客户来说都非常痛苦。客户无法享受到软件公司产品的升级功能,而软件公司在服务大量客户时,也会面临不同版本的维护问题,成本也非常高。而我们的Oinone平台完全避免了这些问题,让客户和软件公司都可以从中受益(如下图2-9、2-10所示)。 图2-9软件公司与客户项目的关系-让标准与个性化共存 图2-10 软件公司与客户项目的关系-让升级无忧 实现原理 在满足客户个性化定制需求时,传统的方法通常是直接修改标准产品源码,但这样做会带来一个问题:标准产品无法持续升级。相反,无论是在OP模式还是SaaS模式下,Oinone都采用全新的模块为客户进行个性化开发,保持标准产品和个性化模块的独立维护和升级。这是因为在元数据设计时,Oinone采用了面向对象的设计原则,实现了元数据设计与面向对象设计思想的完美融合。 面向对象设计的核心特征包括封装、继承、多态,而Oinone的元数据设计完全融入了这些思想。下面是几个例子,说明Oinone的元数据设计如何体现面向对象设计的核心特征,并带来了什么好处: 继承:在继承原有模型的字段、逻辑、展示的情况下,增加一段代码来扩展模型的字段、逻辑、展示。 多态:在继承原有模型的字段、逻辑、展示的情况下,增加一段代码来覆盖模型的原有字段、逻辑、展示。 封装:外部无需关心模型内部如何实现,只需按照不同场景调用模型对应开放级别的字段、逻辑、展示。 这些特征和优势使得Oinone在满足客户个性化需求时更加灵活和可持续,同时使得标准产品的维护和升级变得更加容易和高效。 在Java语言设计中,万物皆对象,一切都以对象为基础。而Oinone的元数据设计则是以模型为出发点,作为数据和行为的承载体。如下图2-11清晰地描述了Java面向对象编程中封装、继承、多态在Oinone元数据中的对应关系。Oinone元数据描述了B对象继承A对象并拥有其所有属性和方法,并覆盖了A对象的属性1和方法1,同时新增了属性3和方法3。 此外,Oinone的面向对象特性是用元数据来描述的。一方面,我们基于Java编码规范收集相关元数据,以保持不改变Java编程习惯。另一方面,方法和对象的挂载是松耦合的,只要按照元数据规范进行挂载,就能轻松地将其附加到模型上。在不改变原有A对象的情况下,我们可以直接增加方法和属性(如下图2-12所示)。 图2-11 java面向对象在Oinone元数据中对应 图2-12 java对象的修改 VS Oinone元数据模型的修改 Oinone函数不仅支持面向对象的继承和多态特性,还提供了面向切面的拦截器和SPI机制的扩展点,以应对方法逻辑的覆盖和扩展,以及系统层面的逻辑扩展(如下图2-13所示)。这些扩展功能可以独立地在模块中维护。 其中,拦截器可以在不侵入函数逻辑的情况下,根据优先级为满足条件的函数添加执行前和执行后的逻辑。 扩展点是一种类似于SPI机制的逻辑扩展机制,用于扩展函数的逻辑。通过这一机制,可以对函数逻辑进行灵活的扩展,以满足不同的业务需求。 图2-13 Oinone函数拦截与扩展机制 不管是对象、属性还是方法,都可以以独立的模块方式来扩展,这就使得每一个需求都可以成为一个独立的模块,方便我们在研发标准产品时进行模块化的划分,同时也让我们在以低代码模式为客户进行二次开发时,能够更好地支持“标准产品迭代与个性化保持独立”的需求。在2.4.3【oinone独特性之低无一体】一文中,我们也提到了这个特性,但那是在低无一体的情况下,通过元数据融合来实现的。让我们看看基于低代码开发模式下,典型的Oinone二次开发工程结构(如下图2-14所示),就可以更好地理解这个特性啦! 图2-14 Oinone典型的二开工程结构

    2024年5月23日
    1.3K00
  • 3.2 Oinone以模块为组织

    模块(module):是按业务领域划分和管理的最小单元,是一组功能、界面的集合。 带大家快速认识下如何构建一个oinone的模块并启动它。我会从以下几个维度去介绍模块的构建与启动方式、模块详解。让大家直观且全方位地了解oinone的模块所包含的内容 构建第一个Module 启动前端工程 应用中心

    Oinone 7天入门到精通 2024年5月23日
    1.8K00
  • 3.5.6.4 动作的配置

    在3.5.3【Action的类型】一文中,我们介绍Action的几种类型,以及组合动作。 通用配置 配置项 可选值 默认值 作用 name 动作名称 label 显示名称 icon 图标 type primary defaultlink primary 按钮类型样式,支持主要样式、次要样式以及链接样式。 bizStyle defaultsuccesswarningdangerinfo default 按钮业务样式,支持成功(green)、警告(yellow)、危险(red)、信息(grey)四种样式。 invisible truefalse condition false 展示规则,有简单的true/false显隐,也支持复杂的表达式 disabled truefalse condition 根据动作上下文类型进行自动推断 是否禁用自动推断规则:当上下文类型为【单行】时,相当于使用表达式LIST_COUNT(context.activeRecords) != 1当上下文类型为【多行】时,相当于使用表达式LIST_COUNT(context.activeRecords) <= 1当上下文类型为【单行或多行】时,相当于使用表达式LIST_COUNT(context.activeRecords) == 0 disabledTitle string 根据动作上下文类型进行自动推断 禁用悬浮提示 表3-5-6-12 动作通用配置 二次确认配置 二次确认框默认支持两种模式,对话框和气泡框; 对话框 图3-5-6-51 对话框提示 气泡框 图3-5-6-52 气泡框警告 配置项 配置项 可选值 默认值 作用 备注 confirm string 二次确认提示文字 配置后开启二次确认 confirmType POPPER(气泡提示框) MODAL(对话框) POPPER 确认框类型 confirmPosition TM(按钮上方) BM(按钮下方) LM(按钮左侧) RM(按钮右侧) BM 确认框位置 气泡框该配置生效 enterText 确定 确定按钮文字 cancelText 取消 取消按钮文字 表3-5-6-13 配置项 弹出层动作配置(窗口动作ViewAction) 目前平台对于弹出层支持了两种展示形式。弹窗(modal/dialog)和抽屉(drawer) 支持两种配置方式【内嵌视图配置】和【引用已有页面】,内嵌视图配置优先于引用已有页面。 内嵌视图配置 该配置对于弹窗和抽屉均适用。 <action name="窗口动作名称" label="创建"> <view model="模型编码" type="form"> <template slot="form" widget="form"> <field data="id" invisible="true" /> <field data="code" label="编码" widget="Input" /> <field data="name" label="名称" widget="Input" /> </template> <template slot="footer"> <action name="$$internal_DialogCancel" label="关闭" type="default" /> <action name="create" label="确定" /> </template> </view> </action> 图3-5-6-53 内嵌视图配置 引用已有页面配置 该配置对于弹窗和抽屉均适用。 <view model="模型编码" type="form"> <template slot="form" widget="form"> <field data="id" invisible="true" /> <field data="code" label="编码" widget="Input" /> <field data="name" label="名称" widget="Input" /> </template> <template slot="footer"> <action name="$$internal_DialogCancel" label="关闭" type="default" /> <action name="create" label="确定" /> </template> </view> 图3-5-6-54 引用已有页面示例 <action name="窗口动作名称" label="创建" resViewName="$viewName$" /> 图3-5-6-55 引用已有页面 弹窗 当窗口动作的路由方式(target)为dialog时,内嵌视图/引用页面将以弹窗形式展示在页面上。 配置项 配置项 可选值 默认值 作用 title…

    2024年5月23日
    98800
  • 3.5.7.9 自定义多Tab

    在业务中,可能会遇到需要对多tab的交互或UI做全新设计的需求,这个时候可以自定义多tab组件支持。 首先继承平台的MultiTabsWidget组件,将自己vue文件设置到component处 import { MultiTabsWidget, SPI, ViewWidget } from '@kunlun/dependencies'; import Component from './CustomMultiTabs.vue'; @SPI.ClassFactory( ViewWidget.Token({ // 这里的tagName跟平台的组件一样,这样才能覆盖平台的组件 tagName: ['multi-tabs', 'MultiTabs'] }) ) export class CustomMultiTabsWidget extends MultiTabsWidget{ public initialize(props) { super.initialize(props); // 设置自定义的vue组件 this.setComponent(Component); return this; } } vue文件中继承平台的props,编写自定义页面代码 export const MultiTabsProps = { /** * 组件是否可见 */ invisible: { type: Boolean }, /** * tab列表数据 */ tabs: { type: Array as PropType<MultiTab[]> }, /** * 当前激活的tab */ activeTab: { type: Object as PropType<MultiTab> }, /** * 鼠标悬浮所在的tab */ hoverTab: { type: Object as PropType<MultiTab> }, /** * 鼠标经过tab事件回调 */ onMouseenterTab: { type: Function as PropType<(tab: MultiTab) => void> }, /** * 鼠标离开tab事件回调 */ onMouseleaveTab: { type: Function as PropType<(tab: MultiTab) => void> }, /** * 点击tab */ onClickTab: { type: Function as PropType<(tab: MultiTab) => void> }, /** * 刷新当前tab */ onRefreshCurrentTab: { type: Function as PropType<(tab: MultiTab) => void> }, /** * 关闭当前tab */ onCloseCurrentTab: { type: Function as PropType<(tab: MultiTab) => void> }, /** * 关闭除当前tab外的其他所有tab */ onCloseOtherTabs: { type: Function as PropType<(tab: MultiTab) => void> }, /** * 关闭当前tab左侧的所有tab */ onCloseLeftTabs: { type: Function as…

    2024年5月23日
    1.1K00
  • 企业个性化配置

    平台除了帮助企业快速解决业务需求外,还提供了企业文化、风格个性化能力,本章节详细介绍个性化配置。包括:登陆页配置、企业形象配置、系统风格配置。 系统配置 配置入口 配置入口:右上角登陆账号——系统配置——全局配置——登陆页配置、企业形象配置、系统风格配置。 登陆页配置 用户自定义登陆页的主题,一共有六个主题可选择,分别为: 图一:左侧是图片,右侧是登录输入框,Logo在左上角; 图二:右左侧是图片,右侧是登录输入框,Logo在左上角; 图三:底图是图片,登录输入框浮在页面左侧,Logo在左上角; 图四:底图是图片,登录输入框浮在页面中间,Logo在左上角; 图五:底图是图片,登录输入框浮在页面右侧,Logo在左上角; 图六:底图是图片,登录输入框浮在页面中间,Logo在登录框上方。 页面背景 上传登录页背景,支持上传jpg、png格式的图片或mp4、mov、avi格式视频。尺寸建议为1920*1080px,文件大小不超过50MB。 登录页logo:指配置登录页左上角的logo图标。 预览:配置后可在右侧电脑中点击全屏预览效果。 配置示例 企业形象配置 企业形象配置:可设置企业信息、业务应用导航栏logo、浏览器logo,设置完成之后,点击发布之后设置生效。 系统风格配置 系统风格配置,可设置主题(浅色、深色)、尺寸(大、中、小),配置后可全屏预览,发布后即可更换成对应的风格。 下载代码可进行自定义风格。

    2024年6月20日
    1.2K00

Leave a Reply

登录后才能评论