第7章 Oinone的设计器们(改)

章节7.jpg

章节7.jpg

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

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

(1)
史, 昂的头像史, 昂数式管理员
上一篇 2024年5月23日 am8:06
下一篇 2024年5月23日 am8:09

相关推荐

  • 3.4.3.1 面向对象-继承与多态

    本节为小伙伴们介绍,Function的面向对象的特性:继承与多态; 一、继承 我们在3.4.1【构建第一个Function】一文中伴随模型新增函数和独立类新增函数绑定到模型部分都是在父模型PetShop新增了sayHello的Function,同样其子模型都具备sayHello的Function。因为我们是通过Function的namespace来做依据的,子模型在继承父模型的sayHello函数后会以子模型的编码为namespace,名称则同样为sayHello。 二、多态(举例) oinone的多态,我们只提供覆盖功能,不提供重载,因为oinone相同name和fun的情况下不会去识别参数个数和类型。 Step1 为PetShop新增hello函数 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; } @Function(openLevel = FunctionOpenEnum.API) @Function.Advanced(type= FunctionTypeEnum.QUERY) public PetShop hello(PetShop shop){ PamirsSession.getMessageHub().info("Hello:"+shop.getShopName()); return shop; } } 图3-4-3-1 为PetShop新增hello函数 Step2 为PetShopProxyB新增对应的三个函数 其中PetShopProxyB新增的hello函数,在java中是重载了hello,在代码中new PetShopProxyB()是可以调用父类的sayHello单参方法,也可以调用本类的双参方法。但在oinone的体系中对于PetShopProxyB只有一个可识别的Function就是双参的sayHello package pro.shushi.pamirs.demo.api.proxy; import pro.shushi.pamirs.demo.api.model.PetCatItem; import pro.shushi.pamirs.demo.api.model.PetShop; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Function; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.api.session.PamirsSession; import pro.shushi.pamirs.meta.enmu.FunctionOpenEnum; import pro.shushi.pamirs.meta.enmu.FunctionTypeEnum; import pro.shushi.pamirs.meta.enmu.ModelTypeEnum; import java.util.List; @Model.model(PetShopProxyB.MODEL_MODEL) @Model.Advanced(type = ModelTypeEnum.PROXY,inherited ={PetShopProxy.MODEL_MODEL,PetShopProxyA.MODEL_MODEL} ) @Model(displayName = "宠物店铺代理模型B",summary="宠物店铺代理模型B") public class PetShopProxyB extends PetShop { public static final String MODEL_MODEL="demo.PetShopProxyB"; @Field.one2many @Field(displayName = "萌猫商品列表") @Field.Relation(relationFields = {"id"},referenceFields = {"shopId"}) private List<PetCatItem> catItems; @Function(openLevel = FunctionOpenEnum.API) @Function.Advanced(type= FunctionTypeEnum.QUERY) public PetShop sayHello(PetShop shop){ PamirsSession.getMessageHub().info("PetShopProxyB 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 hello){ PamirsSession.getMessageHub().info("PetShopProxyB say:"+hello+","+shop.getShopName()); return shop; } @Function(openLevel = FunctionOpenEnum.API)…

    2024年5月23日
    1.1K00
  • 4.5.2 研发辅助之SQL优化

    Oinone体系中是不需要针对模型写SQL的,默认提供了通用的数据管理器。在带来便利的情况下,也导致传统的sql审查就没办法开展。但是我们可以以技术的手段收集慢SQL和限制问题SQL执行。 慢SQL搜集目的:去发现非原则性问题的慢SQL,并进行整改 限制问题SQL执行:对应一些不规范的SQL系统上直接做限制,如果有特殊情况手动放开 一、发现慢SQL 这个功能并没有直接加入到oinone的版本中,需要业务自行写插件,插件代码如下。大家可以根据实际情况进行改造比如: 堆栈入口,例子中只是放了pamirs,可以根据实际情况改成业务包路径 对慢SQL的定义是5s还是3s,根据实际情况变 package pro.shushi.pamirs.demo.core.plugin; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.plugin.*; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; import org.springframework.stereotype.Component; import pro.shushi.pamirs.meta.annotation.fun.extern.Slf4j; @Intercepts({ @Signature(type = Executor.class,method = "query",args = {MappedStatement.class,Object.class, RowBounds.class, ResultHandler.class}) }) @Component @Slf4j public class SlowSQLAnalysisInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { long start = System.currentTimeMillis(); Object result = invocation.proceed(); long end = System.currentTimeMillis(); if (end – start > 10000) {//大于10秒 try { StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); StringBuffer slowLog = new StringBuffer(); slowLog.append(System.lineSeparator()); for (StackTraceElement element : stackTraceElements) { if (element.getClassName().indexOf("pamirs") > 0) { slowLog.append(element.getClassName()).append(":").append(element.getMethodName()).append(":").append(element.getLineNumber()).append(System.lineSeparator()); } } Object parameter = null; if (invocation.getArgs().length > 1) { parameter = invocation.getArgs()[1]; } MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; BoundSql boundSql = mappedStatement.getBoundSql(parameter); Configuration configuration = mappedStatement.getConfiguration(); String originalSql = showSql(configuration, boundSql); originalSql = originalSql.replaceAll("\'", "").replace("\"", ""); log.warn("检测到的慢SQL为:" + originalSql); log.warn("业务慢SQL入口为:" + slowLog.toString()); } catch (Throwable e1) { //忽略 } } return result; } public String showSql(Configuration configuration, BoundSql boundSql) { Object parameterObject = boundSql.getParameterObject(); List<ParameterMapping> parameterMappings = boundSql.getParameterMappings(); String sql = boundSql.getSql().replaceAll("[\\s]+", " "); if (parameterMappings.size() > 0 && parameterObject != null) { TypeHandlerRegistry typeHandlerRegistry…

  • 4.1.22 框架之分布式缓存

    分布式缓存Oinone平台主要用到了Redis,为了让业务研发时可以无感使用RedisTemplate和StringRedisTemplate,已经提前注册好了redisTemplate和stringRedisTemplate,而且内部会自动处理相关特殊逻辑以应对多租户环境,小伙伴不能自己重新定义Redis的相关bean。 使用说明 配置说明 spring: redis: database: 0 host: 127.0.0.1 port: 6379 timeout: 2000 # cluster: # nodes: # – 127.0.0.1:6379 # timeout: 2000 # max-redirects: 7 jedis: pool: # 连接池中的最大空闲连接 默认8 max-idle: 8 # 连接池中的最小空闲连接 默认0 min-idle: 0 # 连接池最大连接数 默认8 ,负数表示没有限制 max-active: 8 # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认-1 max-wait: -1 图4-1-22-1 分布式缓存配置说明 代码示例 package pro.shushi.pamirs.demo.core.service; import org.springframework.stereotype.Component; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; @Component public class Test { @Autowired private RedisTemplate redisTemplate; @Autowired private StringRedisTemplate stringRedisTemplate } 图4-1-22-2 代码示例

  • 4.1.10 函数之触发与定时(改)

    函数的触发和定时在很多场景中会用到,也是一个oinone的基础能力。比如我们的流程产品中在定义流程触发时就会让用户选择模型触发还是时间触发,就是用到了函数的触发与定时能力。 整体链路示意图(如下图4-1-10-1 所示),本文只讲trigger里的两类任务,一个是触发任务,一个是定时任务,异步任务放在4.1.11【函数之异步执行】一文中单独去介绍。 图4-1-10-1 整体链路示意图 一、触发任务TriggerTaskAction(举例) 触发任务的创建,使用pamirs-middleware-canal监听mysql的binlog事件,通过rocketmq发送变更数据消息,收到MQ消息后,创建TriggerAutoTask。 触发任务的执行,使用TBSchedule拉取触发任务后,执行相应函数。 注意:pamirs-middleware-canal监听的数据库表必须包含触发模型的数据库表。 Step1 下载canal中间件 下载pamirs-middleware-canal-deployer-3.0.1.zip,去.txt后缀为pamirs-middleware-canal-deployer-3.0.1.zip,解压文件如下: 图4-1-10-2 下载canal中间件 Step2 引入依赖pamirs-core-trigger模块 pamirs-demo-api增加pamirs-trigger-api <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-trigger-api</artifactId> </dependency> 图4-1-10-3 pamirs-trigger-api依赖包 DemoModule在模块依赖定义中增加@Module(dependencies={TriggerModule.MODULE_MODULE}) @Component @Module( name = DemoModule.MODULE_NAME, displayName = "oinoneDemo工程", version = "1.0.0", dependencies = {ModuleConstants.MODULE_BASE, CommonModule.MODULE_MODULE, UserModule.MODULE_MODULE, TriggerModule.MODULE_MODULE} ) @Module.module(DemoModule.MODULE_MODULE) @Module.Advanced(selfBuilt = true, application = true) @UxHomepage(PetShopProxy.MODEL_MODEL) public class DemoModule implements PamirsModule { ……其他代码 } 图4-1-10-4 模块依赖中增加Trigger模块 pamirs-demo-boot 增加pamirs-trigger-core和pamirs-trigger-bridge-tbschedule的依赖 <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-trigger-core</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-trigger-bridge-tbschedule</artifactId> </dependency> 图4-1-10-5 增加pamirs-trigger-core和pamirs-trigger-bridge-tbschedule的依赖 修改pamirs-demo-boot的applcation-dev.yml 修改pamris.event.enabled和pamris.event.schedule.enabled为true pamirs_boot_modules增加启动模块:trigger pamirs: event: enabled: true schedule: enabled: true rocket-mq: namesrv-addr: 127.0.0.1:9876 boot: init: true sync: true modules: – base – common – sequence – resource – user – auth – message – international – business – trigger – demo_core 图4-1-10-6 启动模块中增加trigger模块 Step3 启动canal中间件 canal的库表需要手工建 create schema canal_tsdb collate utf8mb4_bin 图4-1-10-7 canal的建库语句 CREATE TABLE IF NOT EXISTS `meta_snapshot` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', `gmt_create` datetime NOT NULL COMMENT '创建时间', `gmt_modified` datetime NOT NULL COMMENT '修改时间', `destination` varchar(128) DEFAULT NULL COMMENT '通道名称', `binlog_file` varchar(64) DEFAULT NULL COMMENT 'binlog文件名', `binlog_offest` bigint(20) DEFAULT NULL COMMENT 'binlog偏移量', `binlog_master_id` varchar(64) DEFAULT NULL COMMENT 'binlog节点id', `binlog_timestamp` bigint(20) DEFAULT NULL…

    2024年5月23日
    1.1K00
  • 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.1K00

Leave a Reply

登录后才能评论