3.4.1 构建第一个Function

Function做为oinone的可管理的执行逻辑单元,是无处不在的

在3.3.3【模型的数据管理器】和3.3.2【模型类型】一文中的代理模型部分,涉及到包括在Action中自定义函数(action背后都对应一个Function)、重写queryPage的函数、以及独立抽取的公共逻辑函数,Function做为oinone的可管理的执行逻辑单元,是无处不在的。这也是为什么说oinone以函数为内在的原因。

一、构建第一个Function

因为数据管理器和数据构造器是oinone为模型自动赋予的Function,是内在数据管理能力。模型其他Function都需要用以下四种方式主动定义

伴随模型新增函数(举例)

它是跟模型的java类定义在一起,复用模型的命名空间。

Step1 为PetShop增加一个名为sayHello的Function

package pro.shushi.pamirs.demo.api.model;
…… //import

@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";
    …… //省略其他代码
    @Function(openLevel = FunctionOpenEnum.API)
    @Function.Advanced(type=FunctionTypeEnum.QUERY)
    public PetShop sayHello(PetShop shop){
        PamirsSession.getMessageHub().info("Hello:"+shop.getShopName());
        return shop;
    }
}

图3-4-1-1 代码示例

Step2 重启看效果

用graphQL工具Insomnia查看效果

  1. 用Insomnia模拟登陆

a. 创建一个login请求,用于保存login请求,为后续模拟登陆保留快捷方式

1632290598998-aa0d9386-2ed6-426a-bf33-e87d04227092

图3-4-1-2 创建一个login请求

b. 下面为登陆请求的GraphQL,请在post输入框中输入。如果请求输入框提示错误可以,可以点击schema 的Refresh Schema来刷新文档


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

图3-4-1-3 登陆请求的GraphQL

c. 点击Send按钮,我们可以看到登陆成功的反馈信息

1632291332648-2fcfd998-64d3-4fce-a860-aad07668d165

图3-4-1-4 登陆成功的反馈信息

  1. 用Insomnia模拟访问PetShop的sayHello方法,gql的返回中,我们可以看到两个核心返回

a. 一是方法正常返回的shopName

b. 二是“PamirsSession.getMessageHub().info("Hello:"+shop.getShopName())”代码执行的结果,在messages中有一个消息返回,更多消息机制详见4.1.23【框架之信息传递

query{
  petShopQuery{
    sayHello(shop:{shopName:"cpc"}){
    shopName
    }
  }
}

图3-4-1-5 用Insomnia模拟访问PetShop的sayHello

1632292001565-50717613-1337-442c-a10f-8cbafa2c2db2

图3-4-1-6 代码执行结果

  1. 用Insomnia模拟访问PetShopProxy的sayHello方法

效果同用Insomnia模拟访问PetShop的sayHello方法,体现Function的继承特性。

独立新增函数绑定到模型(举例)

独立方法定义类,并采用Model.model或Fun注解,但是value都必须是模型的编码,如@Model.model(PetShop.MODEL_MODEL)或@Fun(PetShop.MODEL_MODEL)

Step1 提取PetShop的sayHello方法独立到PetShopService中

  1. 注释掉PetShop的sayHello方法
package pro.shushi.pamirs.demo.api.model;
…… //import

@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";
    …… //省略其他代码
//    @Function(openLevel = FunctionOpenEnum.API)
//    @Function.Advanced(type=FunctionTypeEnum.QUERY)
//    public PetShop sayHello(PetShop shop){
//        PamirsSession.getMessageHub().info("Hello:"+shop.getShopName());
//        return shop;
//    }
}

图3-4-1-7 注释掉PetShop的sayHello

  1. 新增PetShopService接口类

接口的方法上要加上@Function注解,这样另模块依赖api包的时候,会自动注册远程服务的消费者

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

import pro.shushi.pamirs.demo.api.model.PetShop;
import pro.shushi.pamirs.meta.annotation.Fun;
import pro.shushi.pamirs.meta.annotation.Function;

@Fun(PetShop.MODEL_MODEL)
//@Model.model(PetShop.MODEL_MODEL)
public interface PetShopHelloService {
    @Function
    PetShop sayHello(PetShop shop);
}

图3-4-1-8 新增PetShopService接口类

  1. 新增PetShopServiceImpl实现类
package pro.shushi.pamirs.demo.core.service;

import org.springframework.stereotype.Component;
import pro.shushi.pamirs.demo.api.model.PetShop;
import pro.shushi.pamirs.demo.api.service.PetShopHelloService;
import pro.shushi.pamirs.meta.annotation.Fun;
import pro.shushi.pamirs.meta.annotation.Function;
import pro.shushi.pamirs.meta.api.session.PamirsSession;
import pro.shushi.pamirs.meta.enmu.FunctionOpenEnum;
import pro.shushi.pamirs.meta.enmu.FunctionTypeEnum;

@Fun(PetShop.MODEL_MODEL)
//@Model.model(PetShop.MODEL_MODEL)
@Component
public class PetShopHelloServiceImpl implements PetShopHelloService {

    @Override
    @Function(openLevel = FunctionOpenEnum.API)
    @Function.Advanced(type= FunctionTypeEnum.QUERY)
    public PetShop sayHello(PetShop shop) {
        PamirsSession.getMessageHub().info("Hello:"+shop.getShopName());
        return shop;
    }
}

图3-4-1-9 新增PetShopServiceImpl实现

Step2 重启看效果

同上文【伴随模型新增函数(举例)】的效果一致,同样具备继承特性。

独立新增函数只作公共逻辑单元(举例)

只能java后端访问,不生成GraphQL的schema,即使配置 @Function(openLevel = FunctionOpenEnum.API),也相当于FunctionOpenEnum.LOCAL 。如同3.3.4【模型的继承】一文中的PetCatItemQueryService的作用,提取公共的逻辑,并且可管理。

Step1 修改PetShopService和PetShopServiceImpl的命名空间

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

import pro.shushi.pamirs.demo.api.model.PetShop;
import pro.shushi.pamirs.meta.annotation.Fun;
import pro.shushi.pamirs.meta.annotation.Function;

@Fun(PetShopHelloService.FUN_NAMESPACE)
public interface PetShopHelloService {

    String FUN_NAMESPACE = demo.PetShopHelloService;

    @Function
    PetShop sayHello(PetShop shop);
}

图3-4-1-10 修改PetShopService命名空间

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

import org.springframework.stereotype.Component;
import pro.shushi.pamirs.demo.api.model.PetShop;
import pro.shushi.pamirs.demo.api.service.PetShopHelloService;
import pro.shushi.pamirs.meta.annotation.Fun;
import pro.shushi.pamirs.meta.annotation.Function;
import pro.shushi.pamirs.meta.api.session.PamirsSession;
import pro.shushi.pamirs.meta.enmu.FunctionOpenEnum;
import pro.shushi.pamirs.meta.enmu.FunctionTypeEnum;

@Fun(PetShopHelloService.FUN_NAMESPACE)
@Component
public class PetShopHelloServiceImpl implements PetShopHelloService {

    @Override
    @Function(openLevel = FunctionOpenEnum.API)
    @Function.Advanced(type= FunctionTypeEnum.QUERY)
    public PetShop sayHello(PetShop shop) {
        PamirsSession.getMessageHub().info(Hello:+shop.getShopName());
        return shop;
    }
}

图3-4-1-11 修改PetShopServiceImpl的命名空间

Step2 重启看效果

刷新GraphQL schema,原先的post请求输入框会报错,点击提交结果也会报GraphQL未定义

1632294623181-4fe3d4f5-a63a-4dea-a605-f3cd0b643a48

图3-4-1-12 刷新GraphQL schema看效果

伴随ServerAction新增函数

ServerAction我们前面也多此提到过,比如在3.3.2【模型的类型】一文中关于代理模型传输模型的内容中都定义过ServerAction,其背后都默认定义了一个Function。如PetShopBatchUpdate模型在PetShopBatchUpdateAction类中定义了一个名为“conform”的ServerAction,背后就定义了一个namespace为demo.PetShopBatchUpdate,fun为conform的Function,而且开放级别为API。

二、java同名不同参数方法(不建议)

java的同名不同参数,在很多远程调用框架如dubbo也是不支持的,在oinone中也需要特殊处理,要以不同的name和fun来区别。

Step1 为PetShop定义两个同名方法,并加上Function注解

我们把PetShop模型下的sayHello函数代码恢复下,并增加一个同名方法sayHello,但注解上@Function(name = "sayHello2")和@Function.fun("sayHello2")。修改完以后sayHello和sayHello2都能在Insomnia通过GQL来访问

package pro.shushi.pamirs.demo.api.model;
…… //import

@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;
    …… //省略其他代码
    @Function(openLevel = FunctionOpenEnum.API)
    @Function.Advanced(type= FunctionTypeEnum.QUERY)
    public PetShop sayHello(PetShop shop){
        PamirsSession.getMessageHub().info(Hello:+shop.getShopName());
        return shop;
    }
    @Function(name = sayHello2,openLevel = FunctionOpenEnum.API)
    @Function.Advanced(type= FunctionTypeEnum.QUERY)
    @Function.fun(sayHello2)
    public PetShop sayHello(PetShop shop, String s) {
        PamirsSession.getMessageHub().info(Hello:+shop.getShopName()+,s:+s);
        return shop;
    }
}

图3-4-1-13 为PetShop定义两个同名方法并加上Function注解

Step2 重启看效果

query{
  petShopQuery{
    sayHello(shop:{shopName:cpc}){
      shopName
    }
    sayHello2(shop:{shopName:cpc},s:sss){
      shopName
    }
  }
}

图3-4-1-14 示例执行效果

1653208575877-bae8d0fd-ccbf-4d9a-886f-c673a987affe

图3-4-1-15 示例执行效果

配置

非模型但带有函数的类必需使用@Fun注解来标识当前类为非模型带函数的类。如果需要提供远程服务,需要在API包中声明注解了@Fun注解的函数接口,并在接口的方法上加上@Function注解。

函数配置

函数定义可以无返回值,也允许定义无参函数。如果入参为原始类型请使用对应封装类型声明。命名空间和函数编码相同的覆盖函数有且仅有一个生效,在模型类中定义优先级高于在模型类外定义,在模型类中靠后优先级越高。

可以使用@Model.model、@Fun注解函数的命名空间。先取@Model.model注解值,先在本类查找注解,如果本类未配置或注解值为空则在父类或接口上查找;若为空则取@Fun注解值,先在本类查找注解,如果本类未配置或注解值为空则在父类或接口上查找;若皆为空则取全限定类名。

可以使用@Function.fun注解配置函数编码。取函数编码先在本类方法查找注解,如果本类方法未配置或注解值为空则在父类或接口方法上查找,若皆为空则取方法名。

如果接口或者父类配置了命名空间和函数编码并且有多个实现类或继承类,如果实现方法使用缺省的方法名作为函数编码,则会导致多个实现方法函数编码冲突,需要使用@Function.fun为每个实现类的对应方法配置唯一的函数编码。但大多数场景一个接口只有一个实现类。

推荐为函数声明接口,并在接口上进行注解(@Fun或@Model.model,@Function),函数实现接口即可;如果需要为函数开启远程服务,必须为函数声明接口并注解,接口须放在api工程中。系统会根据函数开放级别是否是REMOTE来自动注册服务提供者和消费者。

命名空间和函数编码的注解方式适用于所有函数。

函数命名规范

模型属性 默认取值规范 命名规则规范
namespace 先取@Model.model注解值,先在本类查找注解,如果本类未配置或注解值为空则在父类或接口上查找;若为空则取@Fun注解值,先在本类查找注解,如果本类未配置或注解值为空则在父类或接口上查找;若皆为空则取全限定类名 长度必须小于等于128个字符
name 默认使用java方法名 仅支持数字、字母必须以字母开头长度必须小于等于128个字符不能以get、set为开头作为函数名称
fun 默认使用name属性 长度必须小于等于128个字符
summary 默认使用displayName属性 不能使用分号长度必须小于等于500个字符
descripition NULL,注解无法定义 长度必须小于等于65535个字符
openLevel 函数的开放等级默认值:{FunctionOpenEnum.LOCAL, FunctionOpenEnum.REMOTE} FunctionOpenEnum枚举值LOCAL(2L, "本地调用", "本地调用"), REMOTE(4L, "远程调用", "远程调用"), API(8L, "开放接口", "开放接口");
Advanced.displayName 默认使用name属性 长度必须小于等于128个字符
Advanced.timeout 超时时间默认:5秒,远程调用时配置生效

表3-4-1-1 函数命名规范

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

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

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

相关推荐

  • 4.1.4 模块之元数据详解

    介绍Module相关元数据,以及对应代码注解方式。大家还是可以通读下,以备不时之需 如您还不了解Module的定义,可以先看下2.3【oinone独特之源,元数据与设计原则】一文对Module的描述,本节主要带大家了解Module元数据构成,能让小伙伴非常清楚oinone从哪些维度来描述Module, 一、元数据说明 ModuleDefinition 元素数据构成 含义 对应注解 备注 displayName 显示名称 @Module( displayName=””, name=””, version=””, category=””, summary=””, dependencies={“”,””}, exclusions={“”,””}, priority=1L ) name 技术名称 latestVersion 安装版本 category 分类编码 summary 描述摘要 moduleDependencies 依赖模块编码列表 moduleExclusions 互斥模块编码列表 priority 排序 module 模块编码 @Module.module(“”) dsKey 逻辑数据源名 @Module.Ds(“”) excludeHooks 排除拦截器列表 @Module.Hook(excludes={“”,””}) website 站点 @Module.Advanced( website=”http://www.oinone.top”, author=”oinone”, description=”oinone”, application=false, demo=false, web=false, toBuy=false, selfBuilt=true, license=SoftwareLicenseEnum.PEEL1, maintainer=”oinone”, contributors=”oinone”, url=”http://git.com” ) author module的作者 description 描述 application 是否应用 demo 是否演示应用 web 是否web应用 toBuy 是否需要跳转到website去购买 selfBuilt 自建应用 license 许可证 默认PEEL1 可选范围: GPL2 GPL2ORLATER GPL3 GPL3ORLATER AGPL3 LGPL3 ORTHEROSI PEEL1 PPL1 ORTHERPROPRIETARY maintainer 维护者 contributors 贡献者列表 url 代码库的地址 boot 是否自动安装的引导启动项 @Boot 加上该注解代表: 启动时会自动安装,不管yml文件的modules是否配置 moduleClazz 模块定义所在类 只有用代码编写的模块才有 packagePrefix 包路径,用于扫描该模块下的其他元数据 dependentPackagePrefix 依赖模块列对应的扫描路径 state 状态 系统自动计算,无需配置 metaSource 元数据来源 publishCount 发布总次数 platformVersion 最新平台版本 本地与中心平台的版本对应。做远程更新时会用到 publishedVersion 最新发布版本 表4-1-4-1 ModuleDefinition UeModule 是对ModuleDefinition的继承,并扩展了跟前端交互相关的元数据 元素数据构成 含义 对应注解 备注 homePage Model 跳转模型编码 @UxHomepage(@UxRoute() 对应一个ViewAction,如果UxRoute只配置了模型,则默认到该模型的列表页 homePage Name 视图动作或者链接动作名称 logo 图标 @UxAppLogo(logo=””) 表4-1-4-2 UeModule 二、元数据,代码注解方式 Module Module ├── displayName 显示名称 ├── name 技术名称 ├── version 安装版本 ├── category 分类编码 ├── summary 描述摘要 ├── dependencies 依赖模块编码列表 ├── exclusions 互斥模块编码列表 ├── priority 排序 ├── module 模块编码 │ └── value ├── Ds 逻辑数据源名 │ └── value ├── Hook 排除拦截器列表…

  • 7.4 Oinone的低无一体

    基础介绍 前面我们学习了基于低代码开发平台进行快速开发,以及通过oinone的设计器进行零代码开发两种模式。当然低无一体不是简单地说两种模式还指:低无两种模式可以融合。 在做核心产品的时候以低代码开发为主,以无代码为辅助。见低代码开发的基础入门篇中设计器的结合一文 在做实施或临时性需求则是以无代码为主,以低代码为辅助 本文主要介绍第二种模式,它是www.oinone.top官网在SaaS模式下的专有特性。满足客户安装标品后通过设计器进行适应性修改后,但对于一些特殊场景还是需要通过代码进行完善或开发 在该模式下,我们提供了jar模式和代码托管两种模式,客户只要选择需要进行代码开发的模块,点击生产SDK,下载扩展工程模版,按Oinone低代码开发平台规范进行研发,后上传扩展工程即可。 操作手册 低无一体这个模块是连接无代码设计器的桥梁,可以为一个模块或应用设计低代码的逻辑,可以在界面设计器或流程设计器中使用低代码的逻辑。 1.选择模块 首先需要在下拉单选中选择需要低代码的模块或应用。 下拉选中只展示在「应用中心」中已安装的模块或应用,可前往「应用中心」安装后继续低代码操作。 选择模块中不展示系统的基础模块或应用,因为这些模块或应用无法自定义模型。 2.模块信息 模块信息展示的是选择模块的基础信息:模块名称、模块编码、模块作者、模块版本、包的前缀、工程模板下载地址,下载地址仅在上传jar包模式时候用到。 3.低无一体操作 低无一体支持了两种使用模式:上传jar包模式、源码托管模式。 上传控制工程或创建研发分支动作完成会生成一条数据,可以对单条数据进行部署、卸载、修改、删除。 3.1 上传jar包模式 在这个模式下,需要做四步动作。 生成SDK,点击按钮之后,会把模块的当前模型状态打成一个SDK包,SDK最新生成时间更新。当模型变更但未生成SDK时,使用低无一体就会出错,请重新生成SDK并修改扩展工程。生成SDK通常需要1分钟左右,若第一次使用低无一体模块,可能需要更长时间,请耐心等待。 下载扩展工程模板,点击按钮之后,会将SDK包和工程模板生成一个下载链接,复制模块信息中的卸载地址打开即可下载。 技术人员在工程模板的基础上写低代码逻辑。 上传扩展工程,点击按钮展开弹窗,在弹窗中设置标签、备注,并将最终的jar包上传,完成上传之后表格中就会新增一条数据。 上传jar包模式下,模板工程中代码需要注意的点参考下图: 3.2 源码托管模式 在这个模式下,需要做三步动作。 生成SDK,点击按钮之后,会把模块的当前模型状态打成一个SDK包,SDK最新生成时间更新。当模型变更但未生成SDK时,使用低无一体就会出错,请重新生成SDK并修改扩展工程。生成SDK通常需要1分钟左右,若第一次使用低无一体模块,可能需要更长时间,请耐心等待。 创建研发分支,点击按钮展开弹窗。首次创建时需要设置git账号名称、git账号邮箱来创建一个账号,另外在弹窗中设置分支名称、标签、备注,完成创建后表格中就会新增一条数据。 通过表格中的Gitlab地址,技术人员写低代码逻辑。 3.3 行内操作 部署:工程状态为未部署、部署失败、已卸载时展示行内的部署按钮,点击之后进行部署,工程状态变为部署中。部署过程大致需要5-10分钟,请耐心等待。部署完成之后,会生成一个新的模块:“原模块名称”扩展工程。 卸载:工程状态为已部署时展示行内的卸载按钮,点击之后会卸载这个已部署的工程,工程状态变为已卸载。同一模块只能有一个已部署的工程(与选择的模式无关),若需要使用新的工程请先卸载已部署的工程。 修改:行内操作修改按钮始终展示,只允许修改标签、备注。 删除:工程状态为未部署、部署失败、已卸载时展示行内的删除按钮,点击之后删除这一条工程记录。 3.4 部署效果 低无一体部署成功之后,可以进入对应模块的模型页面中使用提交动作来使用低代码逻辑,也可以在流程设计器中的引用逻辑节点中使用低代码逻辑。

    2024年5月23日
    1.1K00
  • 3.3.10 字段类型之关系描述的特殊场景

    在3.3.9【字段类型之关系与引用】一文中已经描述了各种关系字段的常规写法,还有一些特殊场景如:关系映射中存在常量,或者M2M中间表是大于两个字段构成。 举例说明关系字段-高级用法 场景描述 PetTalent模型增加talentType字段,PetItem与PetTalent的多对多关系增加talentType(达人类型),PetItemRelPetTalent 中间表维护petItemId、petTalentId以及talentType,PetDogItem和PetCatItem分别重写petTalents 字段,关系中增加常量描述。示意图如下 实际操作步骤: Step1 新增 TalentTypeEnum package pro.shushi.pamirs.demo.api.enumeration; import pro.shushi.pamirs.meta.annotation.Dict; import pro.shushi.pamirs.meta.common.enmu.BaseEnum; @Dict(dictionary = TalentTypeEnum.DICTIONARY,displayName = "达人类型") public class TalentTypeEnum extends BaseEnum<TalentTypeEnum,Integer> { public static final String DICTIONARY ="demo.TalentTypeEnum"; public final static TalentTypeEnum DOG =create("DOG",1,"狗达人","狗达人"); public final static TalentTypeEnum CAT =create("CAT",2,"猫达人","猫达人"); } Step2 PetTalent模型增加talentType字段 package pro.shushi.pamirs.demo.api.model; import pro.shushi.pamirs.demo.api.enumeration.TalentTypeEnum; 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; @Field(displayName = "达人类型") private TalentTypeEnum talentType; } Step3 修改PetItem的petTalents字段,在关系描述中增加talentType(达人类型) @Field.many2many(relationFields = {"petItemId"},referenceFields = {"petTalentId","talentType"},through = "PetItemRelPetTalent") @Field.Relation(relationFields = {"id"}, referenceFields = {"id","talentType"}) @Field(displayName = "推荐达人",summary = "推荐该商品的达人们") private List<PetTalent> petTalents; Step4 PetDogItem增加petTalents字段,重写父类PetItem的关系描述 talentType配置为常量,填入枚举的值 增加domain描述用户页面选择的时候自动过滤出特定类型的达人,RSQL用枚举的name @Field.many2many(relationFields = {"petItemId"},referenceFields = {"petTalentId","talentType"},through = "PetItemRelPetTalent") @Field.Relation(relationFields = {"id"}, referenceFields = {"id","talentType"}) @Field(displayName = "推荐达人",summary = "推荐该商品的达人们") private List<PetTalent> petTalents; Step5 PetCatItem增加petTalents字段,重写父类PetItem的关系描述 talentType配置为常量,填入枚举的值 增加domain描述用户页面选择的时候自动过滤出特定类型的达人,RSQL用枚举的name @Field(displayName = "推荐达人") @Field.many2many( through = "PetItemRelPetTalent", relationFields = {"petItemId"}, referenceFields = {"petTalentId","talentType"} ) @Field.Relation(relationFields = {"id"}, referenceFields = {"id", "#2#"}, domain = " talentType == CAT") private List<PetTalent> petTalents; Step6 清除中间表demo_core_pet_item_rel_pet_talent的数据记录 清除PetItem与PetTalent的多对多中间表demo_core_pet_item_rel_pet_talent的数据记录 Step7 重启看效果 修改达人记录,选择不同达人类型 PetItem、PetCatItem、PetDogItem不同的交互页面

    2024年5月23日
    1.0K00
  • 4.2.7 框架之翻译工具

    一、说明 Oinone目前的默认文案是中文,如果需要使用其他语言,Oinone也提供一系列的翻译能力。 二、定义语言文件 在src/local下新增一个名为zh_cn.ts文件: 图4-2-7-1 语言文件 编辑zh_cn.ts文件,增加以下内容: const zhCN = { demo: { test: '这是测试' } } export default zhCN 图4-2-7-2 语言内容格式示意 在mian.ts注册语言资源: import { LanguageType, registryLanguage} from '@kunlun/dependencies'; import Zh_cn from './local/zh_cn' registryLanguage(LanguageType['zh-CN'], Zh_cn); 图4-2-7-3 注册语言 三、Vue模板使用 <template> <div class="petFormWrapper"> <form :model="formState" @finish="onFinish"> <a-form-item :label="translate('demo.test')" id="name" name="kind" :rules="[{ required: true, message: '请输入品种种类!', trigger: 'focus' }]"> <a-input v-model:value="formState.kind" @input="(e) => onNameChange(e, 'kind')" /> <span style="color: red">{{ getServiceError('kind') }}</span> </a-form-item> <a-form-item label="品种名" id="name" name="name" :rules="[{ required: true, message: '请输入品种名!', trigger: 'focus' }]"> <a-input v-model:value="formState.name" @input="(e) => onNameChange(e, 'name')" /> <span style="color: red">{{ getServiceError('name') }}</span> </a-form-item> </form> </div> </template> <script lang="ts"> import { defineComponent, reactive } from 'vue'; import { Form } from 'ant-design-vue'; export default defineComponent({ // 引入translate props: ['onChange', 'reloadData', 'serviceErrors', 'translate'], components: { Form }, setup(props) { const formState = reactive({ kind: '', name: '', }); const onFinish = () => { console.log(formState); }; const onNameChange = (event, name) => { props.onChange(name, event.target.value); }; const reloadData = async () => { await props.reloadData(); }; const getServiceError = (name: string) => { const error = props.serviceErrors.find(error => error.name === name);…

    2024年5月23日
    41500
  • 3.5.6.1 字段的配置

    字段组件类型 ttype可以配置哪些widget?本文这里把oinone平台默认支持的所有widget都进行了罗列,方便大家查阅。 字段组件匹配规则 字段组件没有严格的按组件名(widget)、字段类型(ttype)、视图组件类型(viewType)限定,而是一个匹配规则 按widget 最优先匹配 按最大匹配原则 ttype、viewType。每个属性权重一分 按后注册优先原则 通用属性 属性 属性描述 属性name 默认值 类型 标题 字段的标题名称 label – string 占位提示 一个字段的描述信息,常用于说明当前字典的范围、注意事项等 placeholder – string 描述说明 组件描述信息 hint – string 数据校验 与表单其他数据联动校验 validator – 表达式 数据校验不通过提示 数据校验不通过提示 validatorMessage 校验失败 string 只读 字段的状态,可见,不可编辑 readonly false boolean或者表达式 隐藏 字段的状态,不,不可编辑 invisible false boolean或者表达式 必填 字段是否必填 required false boolean或者表达式 禁用 字段是否禁用 disabled false boolean或者表达式 宽度 属性在页面中的宽度 colSpan 01/02 标题排列方式 标题排列方式: 水平 , 横向 layout vertical vertical | horizontal 默认值 默认值,多值逗号分割 defaultValue – 根据不同ttype有不同的默认值类型 表3-5-6-1 字段通用属性 字段组件大全 widget为"-"表明不需要指定,是该ttype默认widget 组件名称 widget 对应ttype 属性 属性描述 属性name 默认值 类型 单行文本 – STRING 通用属性 文本类型 密码:password; 文本: text type text string 最小长度 输入框填写数据时最少输入的长度值 minLength – number 最大长度 输入框填写数据时最多输入的长度值 maxLength – number 输入格式 单行文本组件特有的属性,通过规则校验内容,提供一些常用的,也支持自定义校验正则 pattern – 正则表达式 输入格式不通过 输入格式不通过提示语 tips 校验失败 string 显示计数器 设置输入框是否显示字数计数器 showCount FALSE boolean 显示清除按钮 设置输入框是否有一键清除的按钮及功能 allowClear TRUE TRUE 支持前缀 开启前缀 showPrefix FALSE boolean 支持后缀 开启后缀 showSuffix FALSE boolean 前缀类型 ICON: 图标; TEXT:文本 prefixType – string 后缀类型 ICON: 图标; TEXT:文本 suffixType – string 前缀内容 文本内容或者图标引用名 prefix – string 后缀内容 文本内容或者图标引用名 suffix – string 前缀存储 前缀存储, 仅前缀类型为文本可用 prefixStore – boolean 后缀存储 后缀存储, 仅后缀类型为文本可用 suffixStore – boolean 多行文本 -…

    2024年5月23日
    65000

Leave a Reply

登录后才能评论