3.3.6 枚举与数据字典

枚举是大家在系统开发中经常用的一种类型,在oinone中也对枚举类型进行了支持,同时也做了相应的加强。希望通过本文能让大家对枚举的使用,有更全面的认知

一、枚举系统与数据字典

枚举是列举出一个有穷序列集的所有成员的程序。在元数据中,我们使用数据字典进行描述。

协议约定

枚举需要实现IEnum接口和使用@Dict注解进行配置,通过配置@Dict注解的dictionary属性来设置数据字典的唯一编码。前端使用枚举的displayName来展示,枚举的name来进行交互;后端使用枚举的value来进行交互(包括默认值设置也使用枚举的value)。

枚举会存储在元数据的数据字典表中。枚举分为两类:1.异常类;2.业务类。异常类枚举用于定义程序中的错误提示,业务类枚举用于定义业务中某个字段值的有穷有序集。

编程式用法

3.3.6 枚举与数据字典

图3-3-6-1 编程式用法

如果一个字段的类型被定义为枚举,则该字段就可以使用该枚举来进行可选项约束(options)。该字段的可选项为枚举所对应数据字典的子集。

可继承枚举

继承BaseEnum可以实现java不支持的继承枚举。同时可继承枚举也可以用编程式动态创建枚举项。

可继承枚举也可以兼容无代码枚举。

3.3.6 枚举与数据字典

图3-3-6-2 可继承枚举

二进制枚举

可以通过@Dict注解设置数据字典的bit属性或者实现BitEnum接口来标识该枚举值为2的次幂。

二、enum不可继承枚举(举例)

我们在介绍抽象基类中AbstractDemoCodeModel和AbstractDemoIdModel就引入了数据状态(DataStatusEnum)字段,并设置了必填和默认值为DISABLED。DataStatusEnum实现了IEnum接口,并用@Dict(dictionary = DataStatusEnum.dictionary, displayName = "数据状态")进行了注解。为什么不能继承呢?因为JAVA语言的限制导致enum是不可继承的

package pro.shushi.pamirs.core.common.enmu;

import pro.shushi.pamirs.meta.annotation.Dict;
import pro.shushi.pamirs.meta.common.enmu.IEnum;

@Dict(dictionary = DataStatusEnum.dictionary, displayName = "数据状态")
public enum DataStatusEnum implements IEnum<String> {

    DRAFT("DRAFT", "草稿", "草稿"),
    NOT_ENABLED("NOT_ENABLED", "未启用", "未启用"),
    ENABLED("ENABLED", "已启用", "已启用"),
    DISABLED("DISABLED", "已禁用", "已禁用");

    public static final String dictionary = "partner.DataStatusEnum";

    private String value;
    private String displayName;
    private String help;

    DataStatusEnum(String value, String displayName, String help) {
        this.value = value;
        this.displayName = displayName;
        this.help = help;
    }

    public String getValue() {
        return value;
    }

    public String getDisplayName() {
        return displayName;
    }

    public String getHelp() {
        return help;
    }
}

图3-3-6-3 不可继承枚举

三、BaseEnum可继承枚举(举例)

Step1 新增CatShapeExEnum继承CatShapeEnum枚举

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

import pro.shushi.pamirs.meta.annotation.Dict;

@Dict(dictionary = CatShapeExEnum.DICTIONARY,displayName = "萌猫体型Ex")
public class CatShapeExEnum extends CatShapeEnum {

    public static final String DICTIONARY ="demo.CatShapeExEnum";
    public final static CatShapeExEnum MID =create("MID",3,"中","中");
}

图3-3-6-4 新增CatShapeExEnum继承CatShapeEnum枚举

Step2 修改PetCatType的shape字段类型为CatShapeExEnum

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

import pro.shushi.pamirs.demo.api.enumeration.CatShapeExEnum;
import pro.shushi.pamirs.meta.annotation.Field;
import pro.shushi.pamirs.meta.annotation.Model;

@Model.MultiTableInherited(type = PetCatType.KIND_CAT)
@Model.model(PetCatType.MODEL_MODEL)
@Model(displayName="萌猫品种",labelFields = {"name"})
public class PetCatType extends PetType {

    public static final String MODEL_MODEL="demo.PetCatType";
    public static final String KIND_CAT="CAT";

    @Field(displayName = "宠物分类",defaultValue = PetCatType.KIND_CAT,invisible = true)
    private String kind;

    @Field.Enum
    @Field(displayName = "宠物体型")
    private CatShapeExEnum shape;
}

图3-3-6-5 修改PetCatType的shape字段类型为CatShapeExEnum

Step3 重启系统,查看效果

3.3.6 枚举与数据字典

图3-3-6-6 示例效果图

另:可继承枚举的Switch API

继承BaseEnum可以实现Java不支持的可变枚举,可变枚举可以在运行时增加非Java代码定义的枚举项,同时可变枚举支持枚举继承。由于可变枚举不是Java规范中的枚举,所以无法使用switch...case...语句,但是K2提供稍作变化的switches(无需返回值)与switchGet(需要返回值)方式实现相同功能与逻辑。

BaseEnum.switches(比较变量, 比较方式/*系统默认提供两种方式:caseName()和caseValue()*/,
                  cases(枚举列表1).to(() -> {/*逻辑处理*/}),
                  cases(枚举列表2).to(() -> {/*逻辑处理*/}),
                  ...
                  cases(枚举列表N).to(() -> {/*逻辑处理*/}),
                  defaults(() -> {/*默认逻辑处理*/})
);

图3-3-6-7 枚举的switches用法

BaseEnum.<比较变量类型, 返回值类型>switchGet(比较变量, 
                                  比较方式/*系统默认提供两种方式:caseName()和caseValue()*/,
                cases(枚举列表1).to(() -> {/*return 逻辑处理的结果*/}),
                cases(枚举列表2).to(() -> {/*return 逻辑处理的结果*/}),
                ...
                cases(枚举列表N).to(() -> {/*return 逻辑处理的结果*/}),
                defaults(() -> {/*return 逻辑处理的结果*/})
);

图3-3-6-8 枚举的switchGet用法

caseName()使用枚举项的name与比较变量进行匹配比较;caseValue()使用枚举项的value值与比较变量进行匹配比较。

例如以下逻辑表示当ttype的值为O2O、O2M、M2O或M2M枚举值时返回true,否则返回false。

return BaseEnum.<String, Boolean>switchGet(ttype, caseValue(),
                cases(O2O, O2M, M2O, M2M).to(() -> true),
                defaults(() -> false)
);

图3-3-6-9 枚举的switchGet用法举例

四、二进制枚举(举例)

可以通过@Dict注解设置数据字典的bit属性或者实现BitEnum接口来标识该枚举值为2的次幂。二进制枚举最大的区别在于值的序列化和反序列化方式是不一样的。更多有关序列化知识详见3.3.5【模型编码生成器】一文。

Step1 新建店铺选项枚举、并添加为PetShop的一个字段

  1. PetShopOptionEnum继承BaseEnum<PetShopOptionEnum,Long>并实现BitEnum接口,增加三个枚举,值分别是2的0次幂,2的1次幂,2的2次幂。多选枚举3位枚举都选中,字段值为7;
package pro.shushi.pamirs.demo.api.enumeration;

import pro.shushi.pamirs.meta.annotation.Dict;
import pro.shushi.pamirs.meta.common.enmu.BaseEnum;
import pro.shushi.pamirs.meta.common.enmu.BitEnum;

@Dict(dictionary = PetShopOptionEnum.DICTIONARY,displayName = "店铺选项枚举")
public class PetShopOptionEnum extends BaseEnum<PetShopOptionEnum,Long> implements BitEnum {
    public static final String DICTIONARY ="demo.PetShopOptionEnum";

    public static final PetShopOptionEnum ANCIENT = create("ANCIENT",1L<<0,"十年老店","十年老店");
    public static final PetShopOptionEnum SEVEN = create("SEVEN",1L<<1,"七天无理由退货","七天无理由退货");
    public static final PetShopOptionEnum CERTIFIED_PRODUCTS = create("CERTIFIED_PRODUCTS",1L<<2,"正品认证","正品认证");

}

图3-3-6-10 新建店铺选项枚举

  1. 修改PetShop,增加一个多选枚举字段options,枚举类型为PetShopOptionEnum
package pro.shushi.pamirs.demo.api.model;

import pro.shushi.pamirs.demo.api.enumeration.PetShopOptionEnum;
import pro.shushi.pamirs.meta.annotation.Field;
import pro.shushi.pamirs.meta.annotation.Model;

import java.sql.Time;
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)
    private String shopName;

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

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

    @Field(displayName = 店铺标志)
    private List options;

}

图3-3-6-11 修改PetShop增加一个多选枚举字段options

Step2 重启查看效果

  1. 商店管理A的编辑页面可以看到店铺标志字段可多选十年老店、七天无理由退货、正品认证

3.3.6 枚举与数据字典

图3-3-6-12 模型宠狗商店编辑页

  1. 商店管理A的列表页面可以看到【店铺标志】字段为【十年老店】、【七天无理由退货】、【正品认证】

3.3.6 枚举与数据字典

图3-3-6-13 模型宠狗商店列表页

  1. 查看数据库对应的options字段值为7

3.3.6 枚举与数据字典

图3-3-6-14 查看数据库对应的options字段值为7

五、异常枚举(举例)

作为oinone管理异常的规范,一般枚举都是用@Dict申明为数据字典,但是异常枚举会用@Error来注解,因为异常跟业务枚举有很大区别,异常往往数量非常多,如果用@Dict数据字典方式来管理,那么数据字典的量会非常大。

Step1 新建一个异常枚举类DemoExpEnumerate,实现ExpBaseEnum接口并加上@Errors(displayName = demo模块错误枚举)注解,增加对应错误枚举

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

import pro.shushi.pamirs.meta.annotation.Errors;
import pro.shushi.pamirs.meta.common.enmu.ExpBaseEnum;
@Errors(displayName = demo模块错误枚举)
public enum  DemoExpEnumerate implements ExpBaseEnum {

    SYSTEM_ERROR(ERROR_TYPE.SYSTEM_ERROR,90000000,系统异常),
    PET_SHOP_BATCH_UPDATE_SHOPLIST_IS_NULL(ERROR_TYPE.BIZ_ERROR,90000001,店铺列表不能为空);

    private ERROR_TYPE type;
    private int code;
    private String msg;

    DemoExpEnumerate(ERROR_TYPE type, int code, String msg) {
        this.type= type;
        this.code=code;
        this.msg=msg;
    }
}

图3-3-6-15 新建一个异常枚举类DemoExpEnumerate

Step2 修改宠物商店批量更新数据状态逻辑

增加一个PetShopList必选判断,如果没选则抛出异常并制定异常枚举为PET_SHOP_BATCH_UPDATE_SHOPLIST_IS_NULL

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

import org.springframework.stereotype.Component;
import pro.shushi.pamirs.demo.api.enumeration.DemoExpEnumerate;
import pro.shushi.pamirs.demo.api.proxy.PetShopProxy;
import pro.shushi.pamirs.demo.api.tmodel.PetShopBatchUpdate;
import pro.shushi.pamirs.meta.annotation.Action;
import pro.shushi.pamirs.meta.annotation.Function;
import pro.shushi.pamirs.meta.annotation.Model;
import pro.shushi.pamirs.meta.common.enmu.ExpBaseEnum;
import pro.shushi.pamirs.meta.common.exception.PamirsException;
import pro.shushi.pamirs.meta.enmu.ActionContextTypeEnum;
import pro.shushi.pamirs.meta.enmu.FunctionOpenEnum;
import pro.shushi.pamirs.meta.enmu.FunctionTypeEnum;
import pro.shushi.pamirs.meta.enmu.ViewTypeEnum;

import java.util.List;

@Model.model(PetShopBatchUpdate.MODEL_MODEL)
@Component
public class PetShopBatchUpdateAction {

    @Function(openLevel = FunctionOpenEnum.API)
    @Function.Advanced(type= FunctionTypeEnum.QUERY)
    public PetShopBatchUpdate construct(PetShopBatchUpdate petShopBatchUpdate, List petShopList){
        PetShopBatchUpdate result = new PetShopBatchUpdate();
        result.setPetShopList(petShopList);
        return result;
    }

    @Action(displayName = 确定,bindingType = ViewTypeEnum.FORM,contextType = ActionContextTypeEnum.SINGLE)
    public PetShopBatchUpdate conform(PetShopBatchUpdate data){
        if(data.getPetShopList() == null || data.getPetShopList().size()==0){
            throw  PamirsException.construct(DemoExpEnumerate.PET_SHOP_BATCH_UPDATE_SHOPLIST_IS_NULL).errThrow();
        }
        List proxyList = data.getPetShopList();
        for(PetShopProxy petShopProxy:proxyList){
            petShopProxy.setDataStatus(data.getDataStatus());
        }
        new PetShopProxy().updateBatch(proxyList);
        return data;
    }

}

图3-3-6-16 增加一个PetShopList必选判断

Step3 重启系统看效果

3.3.6 枚举与数据字典

图3-3-6-17 重启系统看效果

平台的异常枚举如下:

pamirs-framework异常枚举

每一个模块都可以包含一个或多个异常枚举类,枚举项定义了应用中异常的错误编码与描述。在应用需要抛出异常的位置,可在抛出异常的时候附带对应的错误枚举。我们使用@Errors注解来定义错误枚举类。

工程名 定义位置 编码起始值
pamirs-meta-model MetaExpEnumerate 10010000
pamirs-meta-dsl DslExpEnumerate 10020000
pamirs-framework-common FwExpEnumerate 10050000
pamirs-framework-configure-annotation AnnotationExpEnumerate 10060000
pamirs-framework-configure-db MetadExpEnumerate 10070000
pamirs-framework-compute ComputeExpEnumerate 10080000
pamirs-framework-compare CompareExpEnumerate 10090000
pamirs-framework-faas FaasExpEnumerate 10100000
pamirs-framework-orm OrmExpEnumerate 10110000
pamirs-connectors-data DataExpEnumerate 10150000
pamirs-connectors-data-dialect DialectExpEnumerate 10160000
pamirs-connectors-data-sql SqlExpEnumerate 10170000
pamirs-connectors-data-ddl DdlExpEnumerate 10180000
pamirs-connectors-data-infrastructure InfExpEnumerate 10190000
pamirs-connectors-data-tx TxExpEnumerate 10200000
pamirs-gateways-rsql RsqlExpEnumerate 10500000
pamirs-gateways-graph-java GqlExpEnumerate 10510000
pamirs-boot-api BootExpEnumerate 11000000
pamirs-boot-uxd BootUxdExpEnumerate 11040000
pamirs-boot-standard BootStandardExpEnumerate 11050000
pamirs-base-api BaseExpEnumerate 11500000
pamirs-sid SidExpEnumerate 11510000

表3-3-6-1 pamirs-framework异常枚举

通用异常码

错误 错误描述 定义位置 编码
BASE_USER_NOT_LOGIN_ERROR 用户未登录 BaseExpEnumerate 11500001
BASE_CHECK_DATA_ERROR 校验失败,数据错误 FwExpEnumerate 10050009

表3-3-6-2 通用异常码

pamirs-core异常枚举(20010000-20290000)

工程名 编码起始值 数据字典名
pamirs-core-common 20010000 error.core.common.exceptions
pamirs-sequence(原pamirs-bid) 20020000 error.core.sequence.exceptions
pamirs-data-audit 20030000 error.core.data.audit.exceptions
pamirs-channel 20040000 error.core.channel.exceptions
pamirs-resource 20050000 error.core.resource.exceptions
pamirs-user 20060000 error.core.user.exceptions
pamirs-auth 20070000 error.core.auth.exceptions
pamirs-message 20080000 error.core.message.exceptions
pamirs-international 20090000 error.core.international.exceptions(未正确定义)
pamirs-translate 20100000 error.core.translate.exceptions(未正确定义)
pamirs-scheduler(已作废)pamirs-data-audit 20110000 error.core.schedule.exceptions(已作废)error.core.data.audit.exceptions
pamirs-trigger 20120000 error.core.trigger.exceptions(未正确定义)
pamirs-file2(原pamirs-file) 20130000 error.core.file.exceptions(未正确定义)
pamirs-eip2(原pamirs-eip2) 20140000 error.core.eip.exceptions(未正确定义)
pamirs-third-party-communication 20150000 error.core.third-party-communication.exceptions(未定义)
pamirs-third-party-map 20160000 error.core.third-party-map.exceptions(未定义)
pamirs-business 20170000 error.core.business.exceptions(未定义)
pamirs-web 20180000 error.core.web.exceptions
pamirs-studio(已作废) 20190000 error.core.studio.exceptions(未正确定义)
pamirs-workflow 20200000 error.core.workflow.exceptions
pamirs-apps 20210000 AppsExpEnumerate
pamirs-paas 20220000 PaasExpEnumerate

表3-3-6-3 pamirs-core异常枚举

pamirs-model-designer异常枚举(20300000)

pamirs-model-designer 20300000 ModelDesignerExp

表3-3-6-4 pamirs-Model-designer异常枚举

pamirs-workflow异常枚举(20310000-20320000)

pamirs-workflow 20310000 WorkflowExpEnumerate
pamirs-workflow-designer 20320000 WorkflowDesignerExpEnumerate

表3-3-6-5 pamirs-workflow异常枚举

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

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

Like (0)
史, 昂's avatar史, 昂数式管理员
Previous 2024年5月23日 am9:40
Next 2024年5月23日 am9:42

相关推荐

  • 4.1.12 函数之内置函数与表达式

    本文意在列全所有内置函数与表达式,方便大家查阅。 一、内置函数 内置函数是系统预先定义好的函数,并且提供表达式调用支持。 通用函数 数学函数 表达式 名称 说明 ABS 绝对值 函数场景: 表达式函数示例: ABS(number)函数说明: 获取number的绝对值 FLOOR 向下取整 函数场景: 表达式函数示例: FLOOR(number)函数说明: 对number向下取整 CEIL 向上取整 函数场景: 表达式函数示例: CEIL(number)函数说明: 对number向上取整 ROUND 四舍五入 函数场景: 表达式函数示例: ROUND(number)函数说明: 对number四舍五入 MOD 取余 函数场景: 表达式函数示例: MOD(A,B)函数说明: A对B取余 SQRT 平方根 函数场景: 表达式函数示例: SQRT(number) 函数说明: 对number平方根 SIN 正弦 函数场景: 表达式函数示例: SIN(number)函数说明: 对number取正弦 COS 余弦 函数场景: 表达式函数示例: COS(number)函数说明: 对number取余弦 PI 圆周率 函数场景: 表达式函数示例: PI() 函数说明: 圆周率 ADD 相加 函数场景: 表达式函数示例: ADD(A,B)函数说明: A与B相加 SUBTRACT 相减 函数场景: 表达式函数示例: SUBTRACT(A,B)函数说明: A与B相减 MULTIPLY 乘积 函数场景: 表达式函数示例: MULTIPLY(A,B)函数说明: A与B相乘 DIVIDE 相除 函数场景: 表达式函数示例: DIVIDE(A,B)函数说明: A与B相除 MAX 取最大值 函数场景: 表达式函数示例: MAX(collection) 函数说明: 返回集合中的最大值,参数collection为集合或数组 MIN 取最小值 函数场景: 表达式函数示例: MIN(collection) 函数说明: 返回集合中的最小值,参数collection为集合或数组 SUM 求和 函数场景: 表达式函数示例: SUM(collection)函数说明: 返回对集合的求和,参数collection为集合或数组 AVG 取平均值 函数场景: 表达式函数示例: AVG(collection)函数说明: 返回集合的平均值,参数collection为集合或数组 COUNT 计数 函数场景: 表达式函数示例: COUNT(collection)函数说明: 返回集合的总数,参数collection为集合或数组 UPPER_MONEY 大写金额 函数场景: 表达式函数示例: UPPER_MONEY(number)函数说明: 返回金额的大写,参数number为数值或数值类型的字符串 表4-1-12-1 数学函数 文本函数 表达式 名称 说明 TRIM 空字符串过滤 函数场景: 表达式函数示例: TRIM(text)函数说明: 去掉文本字符串text中的首尾空格,文本为空时,返回空字符串 IS_BLANK 是否为空字符串 函数场景: 表达式函数示例: IS_BLANK(text)函数说明: 判断文本字符串text是否为空 STARTS_WITH 是否以指定字符串开始 函数场景: 表达式函数示例: STARTS_WITH(text,start)函数说明: 判断文本字符串text是否以文本字符串start开始,文本为空时,按照空字符串处理 ENDS_WITH 是否以指定字符串结束 函数场景: 表达式函数示例: ENDS_WITH(text,start)函数说明: 判断文本字符串text是否以文本字符串end结束,文本为空时,按照空字符串处理 CONTAINS 包含 函数场景: 表达式函数示例: CONTAINS(text,subtext)函数说明: 判断文本字符串text是否包含文本字符串subtext,文本text为空时,按照空字符串处理 LOWER 小写 函数场景: 表达式函数示例: LOWER(text)函数说明: 小写文本字符串text,文本为空时,按照空字符串处理 UPPER 大写 函数场景: 表达式函数示例: UPPER(text)函数说明: 大写文本字符串text,文本为空时,按照空字符串处理 REPLACE 替换字符串 函数场景: 表达式函数示例: REPLACE(text,oldtext,newtext)函数说明: 使用文本字符串newtext替换文本字符串text中的文本字符串oldtext…

    Oinone 7天入门到精通 2024年5月23日
    1.4K00
  • 3.5.2.1 整体介绍

    虽然我们有小眼睛可以让用户自定义展示字段和排序喜好,以及通过权限控制行、列展示,但在我们日常业务开发中还是会对页面进行调整,以满足业务方的对交互友好和便捷性的要求。本节会在如何自定义之前我们先介绍页面结构与逻辑,再带小伙伴一起完成自定义view的Template和Layout,以及整个母版的Template和Layout 页面的构成讲解 页面交互拓扑图 页面交互拓扑图 图3-5-2-1 页面交互拓扑图 注:页面逻辑交互拓扑图说明 模块作为主切换入口 模块决定菜单列表 菜单切换触发点击action 前端根据Mask、View进行渲染, a. Mask是母版是确定了主题、非主内容分发区域所使用组件和主内容分发区域联动方式的页面模板。全局、应用、视图动作、视图都可以通过mask属性指定母版 bMask和View都是有layout定义和template定义合并而成,系统会提供默认母版,以及为每种视图提供默认layout c. layout与template通过插槽进行匹配 Action根据不同类型做出不同访问后端服务、url跳转、页面路由、发起客户端动作等 Aciton路由可以指定Mask、视图组件的layout、template a. 当layout没有指定的时候则用系统默认的 b. 当template没有指定的时候,且视图组件相同类型有多条记录时,根据优先级选取 Mask和视图组件的layout优先级(视图组件>视图动作 > 应用 > 全局) 默认母版以及各类视图组件 母版布局 默认母版基础布局base-layout <mask layout="default"> <header slot="header"/> <container slot="main" name="main"> <sidebar slot="sidebar"/> <container slot="content"/> </container> <footer slot="footer"/> </mask> 图3-5-2-2 默认母版基础布局base-layout 母版template <mask layout="default"> <mask name="defaultMask"> <template slot="header"> <container name="appBar"> <element widget="logo"/> <element widget="appFinder"/> </container> <container name="operationBar"> <element widget="notification"/> <element widget="dividerVertical"/> <element widget="languages"/> </container> <element widget="userProfile"/> </template> <template slot="sidebar"> <element widget="navMenu"/> </template> <template slot="content"> <element widget="breadcrumb"/> <element widget="mainView"/> </template> </mask> 图3-5-2-3 母版template 注: 上例中因为名称为main的插槽不需要设置更多的属性,所以在template中缺省了main插槽的template标签。 最终可执行视图 <mask name="defaultMask"> <header> <container name="appBar"> <element widget="logo"/> <element widget="appFinder"/> </container> <container name="operationBar"> <element widget="notification"/> <element widget="dividerVertical"/> <element widget="languages"/> </container> <element widget="userProfile"/> </header> <container name="main"> <sidebar name="sidebar"> <element widget="navMenu"/> </sidebar> <container name="content"> <element widget="breadcrumb"/> <element widget="mainView"/> </container> </container> <footer/> </mask> 图3-5-2-4 最终可执行视图 表格视图布局 默认表格视图基础布局base-layout <view type="table"> <view type="search"> <element widget="search" slot="search"> <xslot name="fields" slotSupport="field" /> </element> </view> <pack widget="fieldset"> <element widget="actionBar" slot="actions" slotSupport="action" /> <element widget="table" slot="table"> <xslot name="fields" slotSupport="field" /> <element widget="actionsColumn" slot="actionsColumn"> <xslot name="rowActions" slotSupport="action" /> </element> </element> </pack> </view> 图3-5-2-5 默认表格视图基础布局base-layout 注:table标签的子标签为column组件,如果field填充到元数据插槽fields没有column组件将自动包裹column组件。 表格视图template <view type="table" model="xxx" name="tableViewExample">…

    2024年5月23日
    1.5K00
  • 4.2.5 框架之网络请求-Request

    在中后台业务场景中,大部分的请求时候是可以被枚举的,比如创建、删除、更新、查询。在上文中,我们讲了httpClient如何自定义请求,来实现自己的业务诉求。本文中讲到的Request是离业务更近一步的封装,他提供了开箱即用的API,比如insertOne、updateOne,它是基于HttpClient做的二次封装,当你熟悉Request时,在中后台的业务场景中,所有的业务接口自定义将事半功倍。 一、Request详细介绍 元数据-model 获取模型实例 import { getModel } from '@kunlun/dependencies' getModel('modelName'); 图4-2-5-1 获取模型实例 清除所有缓存的模型 import { cleanModelCache } from '@kunlun/dependencies' cleanModelCache(); 图4-2-5-2 清除所有缓存的模型 元数据-module 获取应用实例,包含应用入口和菜单 import { queryModuleByName } from '@kunlun/dependencies' queryModuleByName('moduleName') 图4-2-5-3 获取应用实例 查询当前用户所有的应用 import { loadModules } from '@kunlun/dependencies' loadModules() 图4-2-5-4 查询当前用户所有的应用 query 分页查询 import { queryPage } from '@kunlun/dependencies' queryPage(modelName, { pageSize: 15, // 一次查询几条 currentPage, 1, // 当前页码 condition?: '' // 查询条件 maxDepth?: 1, // 查几层模型出来,如果有2,会把所有查询字段的关系字段都查出来 sort?: []; // 排序规则 }, fields, variables, context) 图4-2-5-5 分页查询 自定义分页查询-可自定义后端接口查询数据 import { customQueryPage } from '@kunlun/dependencies' customQueryPage(modelName, methodName, { pageSize: 15, // 一次查询几条 currentPage, 1, // 当前页码 condition?: '' // 查询条件 maxDepth?: 1, // 查几层模型出来,如果有2,会把所有查询字段的关系字段都查出来 sort?: []; // 排序规则 }, fields, variables, context) 图4-2-5-6 自定义分页查询 查询一条-根据params匹配出一条数据 import { queryOne } from '@kunlun/dependencies' customQueryPage(modelName, params, fields, variables, context) 图4-2-5-7 根据params匹配出一条数据 自定义查询 import { customQuery } from '@kunlun/dependencies' customQuery(methodName, modelName, record, fields, variables, context) 图4-2-5-8 自定义查询 update import { updateOne } from '@kunlun/dependencies' updateOne(modelName, record, fields, variables, context) 图4-2-5-9 update insert import { insertOne } from '@kunlun/dependencies' insertOne(modelName, record, fields, variables, context) 图4-2-5-10 insert delete import { deleteOne } from '@kunlun/dependencies'…

    2024年5月23日
    1.6K00
  • 3.5.6.3 布局的配置

    布局是将页面拆分成一个一个的小单元,按照上下中左右进行排列。 前沿 在前端领域中,布局可以分为三大块「Float、Flex、Grid 」,Float可以说的上是上古时期的布局了,如今市面还是很少见的,除了一些古老的网站。 目前,平台主要支持通过配置XML上面的cols和span来进行布局。平台也同样支持自由布局,合理的使用row、col、containers和container四个布局容器相关组件,将可以实现各种类型的布局样式,换句话说,平台实现的自由布局功能是Flex和Grid的结合体。 这里主要是讲解Flex和Grid布局,以及目前新的模板布局实现的思路。 Flex布局 Flex布局采用的是一维布局,那么什么是一维布局呢,所谓的一维布局就是只有一个方向、没有体积、面积,比如一条直线。它适合做局部布局,就像我们原来的顶部菜单、面包屑导航,以及现在的主视图字段配置。 图3-5-6-19 Flex布局示意 图3-5-6-20 Flex布局示意 图3-5-6-21 Flex布局示意 从上图可以看看出,Flex布局只能在X、Y轴进行转换,它无法对上下左右四个方向同时处理,因为它没“面积”的概念。所以它最适合做局部布局。 优点 图3-5-6-22 Flex兼容性 Flex的兼容性,可以看得出来,目前主流的浏览器都支持该属性。所以Flex兼容性强,如果你想对局部做布局处理,Flex是最好选择。 缺陷 刚刚也提到了,用户想要的布局是千奇百怪的,如果他想要的布局在现有的功能中无法实现怎么办?让用户放弃?还是说服他使用现在的布局。 Grid布局 Grid布局系统采用的是二维布局,二维布局有四个方向:上、下、左、右,它只有面积没有体积,比如一张纸、网格。 Grid布局 <div id="grid-container-one"> <div class="one-1">Grid Item 1</div> <div>Grid Item 2</div> <div>Grid Item 3</div> <div>Grid Item 4</div> <div>Grid Item 5</div> <div class="one-6">Grid Item 6</div> </div> <div id="grid-container-two"> <div class="tow-1">Grid Item 1</div> <div class="tow-2">Grid Item 2</div> <div>Grid Item 3</div> <div>Grid Item 4</div> <div>Grid Item 5</div> <div>Grid Item 6</div> </div> <div id="grid-container-three"> <div>Grid Item 1</div> <div>Grid Item 2</div> <div class="grid">Grid Item 3</div> <div class="grid-column">Grid Item 4</div> <div>Grid Item 5</div> <div>Grid Item 6</div> <div>Grid Item 7</div> <div class="grid-column">Grid Item 8</div> </div> HTML CSSResult Skip Results Iframe EDIT ON * { box-sizing: border-box; padding: 0; margin: 0; line-height: 1.5; font-weight: bold; text-align: center; } #grid-container-one{ background-color: black; display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(2, 50px); gap: 10px; border: solid black 2px; margin-bottom: 20px; color: salmon; } #grid-container-one div { border: solid white 2px; padding: 10px; } #grid-container-one .one-1 { grid-area: span 1/span 3; text-aligin: center } #grid-container-one .one-6 { grid-column: 3 /4; } #grid-container-two{ background-color: CADETBLUE; display: grid; grid-template-columns: 15% repeat(2, 1fr);…

    2024年5月23日
    1.5K00
  • 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日
    2.1K00

Leave a Reply

Please Login to Comment