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

函数的触发和定时在很多场景中会用到,也是一个oinone的基础能力。比如我们的流程产品中在定义流程触发时就会让用户选择模型触发还是时间触发,就是用到了函数的触发与定时能力。

整体链路示意图(如下图4-1-10-1 所示),本文只讲trigger里的两类任务,一个是触发任务,一个是定时任务,异步任务放在4.1.11【函数之异步执行】一文中单独去介绍。

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

图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 函数之触发与定时(改)

图4-1-10-2 下载canal中间件

Step2 引入依赖pamirs-core-trigger模块

  1. 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依赖包

  1. 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模块

  1. 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的依赖

  1. 修改pamirs-demo-boot的applcation-dev.yml

    1. 修改pamris.event.enabled和pamris.event.schedule.enabled为true

    2. 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中间件

  1. 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 COMMENT 'binlog应用的时间戳',
  `data` longtext DEFAULT NULL COMMENT '表结构数据',
  `extra` text DEFAULT NULL COMMENT '额外的扩展信息',
  PRIMARY KEY (`id`),
  UNIQUE KEY binlog_file_offest(`destination`,`binlog_master_id`,`binlog_file`,`binlog_offest`),
  KEY `destination` (`destination`),
  KEY `destination_timestamp` (`destination`,`binlog_timestamp`),
  KEY `gmt_modified` (`gmt_modified`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='表结构记录表快照表';

CREATE TABLE IF NOT EXISTS `meta_history` (
  `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 COMMENT 'binlog应用的时间戳',
  `use_schema` varchar(1024) DEFAULT NULL COMMENT '执行sql时对应的schema',
  `sql_schema` varchar(1024) DEFAULT NULL COMMENT '对应的schema',
  `sql_table` varchar(1024) DEFAULT NULL COMMENT '对应的table',
  `sql_text` longtext DEFAULT NULL COMMENT '执行的sql',
  `sql_type` varchar(256) DEFAULT NULL COMMENT 'sql类型',
  `extra` text DEFAULT NULL COMMENT '额外的扩展信息',
  PRIMARY KEY (`id`),
  UNIQUE KEY binlog_file_offest(`destination`,`binlog_master_id`,`binlog_file`,`binlog_offest`),
  KEY `destination` (`destination`),
  KEY `destination_timestamp` (`destination`,`binlog_timestamp`),
  KEY `gmt_modified` (`gmt_modified`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='表结构变化明细表';

CREATE TABLE IF NOT EXISTS `canal_filter` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `destination` varchar(128) NOT NULL COMMENT '通道名称',
  `filter` text NOT NULL COMMENT '过滤表达式',
  `create_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `write_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY destination(`destination`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='通道过滤';

CREATE TABLE IF NOT EXISTS `canal_destination` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `destination` varchar(128) NOT NULL COMMENT '通道名称',
  `content` text NOT NULL COMMENT '通道配置内容',
  `create_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `write_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `destination` (`destination`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='通道配置'

图4-1-10-8 canal的建表语句

  1. 修改canal的启动配置

    1. canal_tsdb就是上面建库,用户名和密码换成本机的

    2. 配置filter: demo.demo_core_pet_talent,监听PetTalent模型数据变化,filter为canal第一次启动默认监听的表。如果数据库中canal_filter表有数据这个修改无效

    3. filter目前需要手工配置,在下个版本中已经去掉了手工配置,而且文中的canal中间件已经是2.2.2版本了,兼容当前教程的版本

pamirs:
  middleware:
    data-source:
      jdbc-url: jdbc:mysql://localhost:3306/canal_tsdb?useUnicode=true&characterEncoding=utf-8&verifyServerCertificate=false&useSSL=false&requireSSL=false
      driver-class-name: com.mysql.cj.jdbc.Driver
      username: root
      password: oinone
  canal:
    ip: 127.0.0.1
    port: 1111
    metricsPort: 1112
    zkClusters:
      - 127.0.0.1:2181
    destinations:
      - destinaion: pamirschangedata
        name: pamirschangedata
        desc: pamirschangedata
        slaveId: 1235
        filter: demo\.demo_core_pet_talent
        dbUserName: root
        dbPassword: oinone
        memoryStorageBufferSize: 65536
        topic: CHANGE_DATA_EVENT_TOPIC
        dynamicTopic: false
        dbs:
          - { address: 127.0.0.1, port: 3306 }
    tsdb:
      enable: true
      jdbcUrl: "jdbc:mysql://127.0.0.1:3306/canal_tsdb"
      userName: root
      password: oinone
    mq: rocketmq
    rocketmq:
      namesrv: 127.0.0.1:9876
      retryTimesWhenSendFailed: 5
dubbo:
  application:
    name: canal-server
    version: 1.0.0
  registry:
    address: zookeeper://127.0.0.1:2181
  protocol:
    name: dubbo
    port: 20881
  scan:
    base-packages: pro.shushi  
server:
  address: 0.0.0.0
  port: 10010
  sessionTimeout: 3600

图4-1-10-9 修改canal的启动配置

pamirs.canal相关配置说明

canal.ip: 运行时ip

canal.port: 运行时端口

canal.zkClusters: 连接zookeeper集群地址

canal.destinations: 运行时Canal的所有实例

canal.destinations.destinaion: Canal的单个实例配置值为所有实例唯一

canal.destinations.destinaion.id: 与canal.destinations.destinaion.slaveId配置一致

canal.destinations.destinaion.slaveId: 为Canal的实例ID

canal.destinations.destinaion.filter: 为Canal监听过滤正则

canal.destinations.destinaion.dbUserName: 为Canal监听的MySQL的用户名

canal.destinations.destinaion.dbPassword: 为Canal监听的MySQL的用户密码

canal.destinations.destinaion.topic: 为监听到数据后往RocketMQ的指定Topic发送消息

canal.destinations.destinaion.dbs: 为连接的MySQL实例的ip和端口,如果为主从配置且主从都开启了Binlog同步功能则可以配置两个地址

canal.destinations.destinaion.memoryStorageBufferSize与canal.destinations.destinaion.dynamicTopic为固定值不需要更改

canal.tsdb: 用来保存canal运行时的元数据,配置为canal_tsdb库相关的连接信息

  1. 启动canal中间件

    1. 进入canal中间件解压目录执行下面命令就可以启动

    2. --spring.config.location请配置绝对路径,换成自己本机的就可以

java -jar  pamirs-middleware-canal-deployer-3.0.1-SNAPSHOT.jar --spring.config.location=/Users/oinone/Documents/oinone/canel/pamirs-middleware-canal-deployer-3.0.1/canal-config/application-dev.yml --spring.profiles.active=dev

图4-1-10-10 启动canal中间件

Step4 新建触发任务

新建PetTalentTrigger类,当PetTalent模型的数据记录被新建时触发系统做一些事情

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

import pro.shushi.pamirs.demo.api.model.PetTalent;
import pro.shushi.pamirs.meta.annotation.Fun;
import pro.shushi.pamirs.meta.annotation.Function;
import pro.shushi.pamirs.meta.annotation.fun.extern.Slf4j;
import pro.shushi.pamirs.trigger.annotation.Trigger;
import pro.shushi.pamirs.trigger.enmu.TriggerConditionEnum;

@Fun(PetTalent.MODEL_MODEL)
@Slf4j
public class PetTalentTrigger {
    @Function
    @Trigger(displayName = "PetTalent创建时触发",name = "PetTalent#Trigger#onCreate",condition = TriggerConditionEnum.ON_CREATE)
    public PetTalent onCreate(PetTalent data){
        log.info(data.getName() + ",被创建");
        //可以增加逻辑
        return data;
    }
}

图4-1-10-11 新建触发任务

Step5 重启应用看效果

  1. 解决启动是dubbo报错

启动过程中会报如下错误,虽然不影响结果,但是还是要把它消灭掉。修改bootstarp.yml文件关闭SpringCloud的自动注册就好了

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

图4-1-10-12 解决启动是dubbo报错

spring:
  profiles:
    active: dev
  application:
    name: pamirs-demo
  cloud:
    service-registry:
        auto-registration:
        enabled: false
pamirs:
  default:
    environment-check: true
    tenant-check: true

---
spring:
  profiles: dev
  cloud:
    config:
      enabled: false
      uri: http://127.0.0.1:7001
      label: master
      profile: dev
    nacos:
      server-addr: http://127.0.0.1:8848
      discovery:
        enabled: false
        namespace:
        prefix: application
        file-extension: yml
      config:
        enabled: false
        namespace:
        prefix: application
        file-extension: yml

dubbo:
  application:
    name: pamirs-demo
    version: 1.0.0
  registry:
    address: zookeeper://127.0.0.1:2181
  protocol:
    name: dubbo
    port: -1
  #    serialization: pamirs
  scan:
    base-packages: pro.shushi
  cloud:
    subscribed-services:

---
spring:
  profiles: test
  cloud:
    config:
      enabled: false
      uri: http://127.0.0.1:7001
      label: master
      profile: test
    nacos:
      server-addr: http://127.0.0.1:8848
      discovery:
        enabled: false
        namespace:
        prefix: application
        file-extension: yml
      config:
        enabled: false
        namespace:
        prefix: application
        file-extension: yml

dubbo:
  application:
    name: pamirs-demo
    version: 1.0.0
  registry:
    address: zookeeper://127.0.0.1:2181
  protocol:
    name: dubbo
    port: -1
  #    serialization: pamirs
  scan:
    base-packages: pro.shushi
  cloud:
    subscribed-services:

图4-1-10-13 关闭SpringCloud的自动注册

  1. 再次重启查看效果

前端新增一个宠物达人,在后台Console搜索“被创建”,我们就看到对应由触发器打印出来的日志

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

图4-1-10-14 示例效果

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

图4-1-10-15 示例效果

Step6 修改canal的Topic

在分布式环境下可以通过修改canal的topic(canal.destinations.destinaion.topic)来个隔离多个应用的触发消息。

  1. 新建DemoNotifyTopicEdit利用Topic修改api,增加后缀【"_"+ DemoModule.MODULE_MODULE】

  2. canal的配置canal.destinations.destinaion.topic改为:CHANGE_DATA_EVENT_TOPIC_demo_core

  3. 小伙伴自行测试

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

import org.springframework.stereotype.Component;
import pro.shushi.pamirs.demo.api.DemoModule;
import pro.shushi.pamirs.framework.connectors.event.spi.NotifyTopicEditorApi;
import pro.shushi.pamirs.trigger.constant.NotifyConstant;

@Component
public class DemoNotifyTopicEdit  implements NotifyTopicEditorApi {
    @Override
    public String handlerTopic(String topic) {
        if(NotifyConstant.AUTO_TRIGGER_TOPIC.equals(topic)){
            return NotifyConstant.AUTO_TRIGGER_TOPIC +"_"+ DemoModule.MODULE_MODULE;
        }
        return topic;
    }
}

图4-1-10-16 修改canal的Topic

pamirs:
  middleware:
    data-source:
      jdbc-url: jdbc:mysql://localhost:3306/canal_tsdb?useUnicode=true&characterEncoding=utf-8&verifyServerCertificate=false&useSSL=false&requireSSL=false
      driver-class-name: com.mysql.cj.jdbc.Driver
      username: root
      password: oinone
  canal:
    ip: 127.0.0.1
    port: 1111
    metricsPort: 1112
    zkClusters:
      - 127.0.0.1:2181
    destinations:
      - destinaion: pamirschangedata
        name: pamirschangedata
        desc: pamirschangedata
        slaveId: 1235
        filter: demo\.demo_core_pet_talent
        dbUserName: root
        dbPassword: oinone
        memoryStorageBufferSize: 65536
        topic: CHANGE_DATA_EVENT_TOPIC_demo_core
        dynamicTopic: false
        dbs:
          - { address: 127.0.0.1, port: 3306 }
    tsdb:
      enable: true
      jdbcUrl: "jdbc:mysql://127.0.0.1:3306/canal_tsdb"
      userName: root
      password: oinone
    mq: rocketmq
    rocketmq:
      namesrv: 127.0.0.1:9876
      retryTimesWhenSendFailed: 5
dubbo:
  application:
    name: canal-server
    version: 1.0.0
  registry:
    address: zookeeper://127.0.0.1:2181
  protocol:
    name: dubbo
    port: 20881
  scan:
    base-packages: pro.shushi  
server:
  address: 0.0.0.0
  port: 10010
  sessionTimeout: 3600

图4-1-10-17 修改canal.destinations.destinaion.topic配置

二、定时任务

定时任务是一种非常常见的模式,这里就不介绍概念了,直接进入示例环节

Step1 新建PetTalentAutoTask实现ScheduleAction

注:

  1. getInterfaceName()需要跟taskAction.setExecuteNamespace定义保持一致,都是函数的命名空间

  2. taskAction.setExecuteFun("execute");跟执行函数名“execute”一致

  3. TaskType需配置为CYCLE_SCHEDULE_NO_TRANSACTION_TASK,把定时任务的schedule线程分开,要不然有一个时间长的任务会导致普通异步或触发任务全部延时

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import pro.shushi.pamirs.core.common.enmu.TimeUnitEnum;
import pro.shushi.pamirs.demo.api.model.PetTalent;
import pro.shushi.pamirs.meta.annotation.Fun;
import pro.shushi.pamirs.meta.annotation.Function;
import pro.shushi.pamirs.meta.annotation.fun.extern.Slf4j;
import pro.shushi.pamirs.meta.domain.fun.FunctionDefinition;
import pro.shushi.pamirs.middleware.schedule.api.ScheduleAction;
import pro.shushi.pamirs.middleware.schedule.common.Result;
import pro.shushi.pamirs.middleware.schedule.domain.ScheduleItem;
import pro.shushi.pamirs.middleware.schedule.eunmeration.TaskType;
import pro.shushi.pamirs.trigger.enmu.TriggerTimeAnchorEnum;
import pro.shushi.pamirs.trigger.model.ScheduleTaskAction;
import pro.shushi.pamirs.trigger.service.ScheduleTaskActionService;

@Slf4j
@Component
@Fun(PetTalent.MODEL_MODEL)
public class PetTalentAutoTask implements ScheduleAction {

    @Autowired
    private ScheduleTaskActionService scheduleTaskActionService;

    public void initTask(){
        ScheduleTaskAction taskAction = new ScheduleTaskAction();
        taskAction.setDisplayName("定时任务测试"); //定时任务描述
        taskAction.setDescription("定时任务测试");
        taskAction.setTechnicalName(PetTalent.MODEL_MODEL+"#"+PetTalentAutoTask.class.getSimpleName()+"#"+"testAutoTask");       //设置定时任务技术名
        taskAction.setLimitExecuteNumber(-1);   //设置执行次数
        taskAction.setPeriodTimeValue(1);       //设置执行周期规则
        taskAction.setPeriodTimeUnit(TimeUnitEnum.MINUTE);
        taskAction.setPeriodTimeAnchor(TriggerTimeAnchorEnum.START);
        taskAction.setLimitRetryNumber(1);      //设置失败重试规则
        taskAction.setNextRetryTimeValue(1);
        taskAction.setNextRetryTimeUnit(TimeUnitEnum.MINUTE);
        taskAction.setExecuteNamespace(PetTalent.MODEL_MODEL);
        taskAction.setExecuteFun("execute");
        taskAction.setExecuteFunction(new FunctionDefinition().setTimeout(5000));
        taskAction.setTaskType(TaskType.CYCLE_SCHEDULE_NO_TRANSACTION_TASK.getValue()); //设置定时任务,执行任务类型
        taskAction.setContext(null);            //用户传递上下文参数
        taskAction.setActive(true);             //定时任务是否生效
        taskAction.setFirstExecuteTime(System.currentTimeMillis());
        scheduleTaskActionService.submit(taskAction);//初始化任务,幂等可重复执行
    }

    @Override
    public String getInterfaceName() {return PetTalent.MODEL_MODEL;}

    @Override
    @Function
    public Result<Void> execute(ScheduleItem item) {
        log.info("testAutoTask,上次执行时间"+item.getLastExecuteTime());
        return new Result<>();
    }
}

图4-1-10-18 新建PetTalentAutoTask实现ScheduleAction

Step2 修改DemoModuleBizInit,进行定时任务初始化

模块更新的时候调用
petTalentAutoTask.initTask(),initTask本身是幂等的所以多掉几次没有关系。在4.1.3【模块之生命周期】一文介绍过InstallDataInit、UpgradeDataInit、ReloadDataInit,您有兴趣可以去回顾下。

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import pro.shushi.pamirs.boot.common.api.command.AppLifecycleCommand;
import pro.shushi.pamirs.boot.common.api.init.InstallDataInit;
import pro.shushi.pamirs.boot.common.api.init.ReloadDataInit;
import pro.shushi.pamirs.boot.common.api.init.UpgradeDataInit;
import pro.shushi.pamirs.demo.api.DemoModule;
import pro.shushi.pamirs.demo.api.enumeration.DemoExpEnumerate;
import pro.shushi.pamirs.demo.core.task.PetTalentAutoTask;
import pro.shushi.pamirs.meta.common.exception.PamirsException;

import java.util.Collections;
import java.util.List;

@Component
public class DemoModuleBizInit implements InstallDataInit,
    UpgradeDataInit, ReloadDataInit {

    @Autowired
    private PetTalentAutoTask petTalentAutoTask;

    @Override
    public boolean upgrade(AppLifecycleCommand command, String version, 
                           String existVersion) {
        petTalentAutoTask.initTask(); //初始化petTalent的定时任务
        return Boolean.TRUE;
    }

    @Override
    public List<String> modules() {
        return Collections.singletonList(DemoModule.MODULE_MODULE);
    }

    @Override
    public int priority() {return 0;}
}

图4-1-10-19 修改DemoModuleBizInit,进行定时任务初始化

Step3 重启看效果

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

图4-1-10-20 示例效果

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

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

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

相关推荐

  • 3.5.6.2 视图的配置

    ,视图的大致配置在3.5.2.2【构建View的Template】一文中已经介绍过,这里主要介绍视图层的基本属性配置,这些配置会透传给视图内的组件Widget,组件会根据配置内容做出不同的呈现样式 视图的配置 Table的配置 配置项 可选值 默认值 作用 activeCount number 5 表格上方动作区默认展示操作的数量,超过个数的操作将被折叠收起 inlineActiveCount number 3 表格最右侧操作列默认展示操作的数量,超过个数的操作将被折叠收起 defaultPageSize number 30 表格默认分页条数 表3-5-6-9 Table的配置 Form/Detail的配置 配置项 可选值 默认值 作用 direction horizontal/vertical(大小写不明感) vertical 表单标题排列方式 表3-5-6-10 Form/Detail的配置 Table的配置项举例 Step1 修改宠物达人的表格视图 我们在宠物达人的自定义表格视图的Template文件中增加三个属性配置activeCount="1" 、inlineActiveCount="1"、 defaultPageSize="1" <view name=tableView model=demo.PetTalent cols=1 activeCount=1 inlineActiveCount=1 defaultPageSize=1 type=TABLE enableSequence=true > </view> 图3-5-6-15 在宠物达人的自定义表格视图的Template文件中增加三个属性配置 Step2 重启看效果 图3-5-6-16 示例效果 Form的配置举例 Step1 修改宠物达人的表单视图 我们在宠物达人的自定义表格视图的Template文件中增加一个属性配置direction = horizontal 。 另:宠物达人在之前的教程中增加了一些字段,大家利用默认视图把新增字段也展示出来。还是通过数据库查看默认页面定义,找到base_view表,过滤条件设置为model =\’demo.PetTalent\’ and name =\’formView\’,查看template字段,把里面涉及新增字段复制到pet_talent_form.xml文件中。 <view name=formView1 model=demo.PetTalent cols=2 type=FORM priority=1 direction = horizontal> </view> 图3-5-6-17 增加一个属性配置direction = "horizontal" Step2 重启看效果 图3-5-6-18 示例效果

    2024年5月23日
    1.9K00
  • 李强

    我们常说“在今天所有的不确定性当中,数字化是最大的确定性”,数字化一定会全面改造所有的行业更是确定的。在菜鸟九年的探索中,我们最大的感受是“未来,任何一个物流企业都会是一个技术公司,真正拉开差距的是:技术与实体产业的结合有多深”。菜鸟“简单极致,贴地疾飞”的技术文化也深刻体现了这一点——好的技术要能解决实际问题。数字化并不是简单地上线一个或几个系统,这是一个贴近业务持续迭代的过程,伴随着这个过程,我相信会诞生非常多的创新技术。 在本书中我看到了工程思维在推进技术创新的缩影,把难的问题转化为简单的问题,用成熟实用的技术分而解之。高性能的微服务框架、CDM、元数据、低代码、无代码等,都是当下非常热门的技术课题,Oinone把这一切都有机地结合起来,形成了一种具备先进理念的全新一代软件产品,每一个特性都贴合企业数字化遇到的实际问题。Oinone的产品设计,把“大道至简,软件自造”贯穿始终,用最简单的方式,帮助企业驾驭数字化,相信会给企业带来不一样的体验。 就跟本书提到的“「企业视角由内部管理转向业务在线、生态在线(协同)带来一系列新的诉求」这一大背景下,以及云、端等新技术的发展,对研发人员的需求越来越大,同时要求越来越高,低代码平台是提升研发效率,降低研发成本的核心手段”,低代码已经不是需不需要的问题,而是怎么选的问题。菜鸟网络自身也在推进自有低代码开发平台,我们有幸邀请本书作者陈鹏程来到菜鸟网络进行了分享交流,收获非常大。如您正在选型低代码开发平台,向您推荐这本书,低无一体的Oinone肯定会打动您。 菜鸟网络CTO李强(在宽)

    Oinone 7天入门到精通 2024年5月23日
    2.5K00
  • 4.3 Oinone的分布式体验

    在oinone的体系中分布式比较独特,boot工程中启动模块中包含就走本地,不包含就走远程,本文带您体验下分布式部署以及分布式部署需要注意点。 看下面例子之前先把话术统一下:启动或请求SecondModule代表启动或请求pamirs-second-boot工程,启动或请求DemoModule代表启动或请求pamirs-demo-boot工程,并没有严格意义上启动哪个模块之说,只有启动工程包含哪个模块。 一、构建SecondModule模块 Step1 构建模块工程 参考3.2.1【构建第一个Module】一文,利用脚手架工具构建一个SecondModule,记住需要修改脚本。 脚本修改如下: #!/bin/bash # 项目生成脚手架 # 用于新项目的构建 # 脚手架使用目录 # 本地 local # 本地脚手架信息存储路径 ~/.m2/repository/archetype-catalog.xml archetypeCatalog=local # 以下参数以pamirs-second为例 # 新项目的groupId groupId=pro.shushi.pamirs.second # 新项目的artifactId artifactId=pamirs-second # 新项目的version version=1.0.0-SNAPSHOT # Java包名前缀 packagePrefix=pro.shushi # Java包名后缀 packageSuffix=pamirs.second # 新项目的pamirs platform version pamirsVersion=4.6.0 # Java类名称前缀 javaClassNamePrefix=Second # 项目名称 module.displayName projectName=OinoneSecond # 模块 MODULE_MODULE 常量 moduleModule=second_core # 模块 MODULE_NAME 常量 moduleName=SecondCore # spring.application.name applicationName=pamirs-second # tomcat server address serverAddress=0.0.0.0 # tomcat server port serverPort=8090 # redis host redisHost=127.0.0.1 # redis port redisPort=6379 # 数据库名 db=demo # zookeeper connect string zkConnectString=127.0.0.1:2181 # zookeeper rootPath zkRootPath=/second mvn archetype:generate \ -DinteractiveMode=false \ -DarchetypeCatalog=${archetypeCatalog} \ -DarchetypeGroupId=pro.shushi.pamirs.archetype \ -DarchetypeArtifactId=pamirs-project-archetype \ -DarchetypeVersion=4.6.0 \ -DgroupId=${groupId} \ -DartifactId=${artifactId} \ -Dversion=${version} \ -DpamirsVersion=${pamirsVersion} \ -Dpackage=${packagePrefix}.${packageSuffix} \ -DpackagePrefix=${packagePrefix} \ -DpackageSuffix=${packageSuffix} \ -DjavaClassNamePrefix=${javaClassNamePrefix} \ -DprojectName="${projectName}" \ -DmoduleModule=${moduleModule} \ -DmoduleName=${moduleName} \ -DapplicationName=${applicationName} \ -DserverAddress=${serverAddress} \ -DserverPort=${serverPort} \ -DredisHost=${redisHost} \ -DredisPort=${redisPort} \ -Ddb=${db} \ -DzkConnectString=${zkConnectString} \ -DzkRootPath=${zkRootPath} 图4-3-1 构建一个名为SecondModule的模块 脚步执行生成工程如下: 图4-3-2 SecondModule的工程结构 Step2 调整配置 修改application-dev.yml文件 修改SecondModule的application-dev.yml的内容 base库换成与DemoModule一样的配置,配置项为:pamirs.datasource.base pamirs: datasource: base: driverClassName: com.mysql.cj.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://127.0.0.1:3306/demo_base?useSSL=false&allowPublicKeyRetrieval=true&useServerPrepStmts=true&cachePrepStmts=true&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&autoReconnect=true&allowMultiQueries=true username: root # 数据库用户 password: oinone # 数据库用户对应的密码 initialSize: 5 maxActive: 200 minIdle: 5 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000…

    2024年5月23日
    2.0K00
  • 业务审计

    整体介绍 业务审计是指通过跟踪用户在平台业务应用中的各类行为操作以及关联的数据变化,支撑企业业务审计所需。平台提供可视化审计规则配置,根据审计规则记录行为日志,其中日志包括登录日志、应用日志; 登录日志:记录平台用户登录行为。 应用日志:针对已订阅的审计规则记录用户操作信息,是用户在各应用中操作行为留痕记录。 审计规则:业务审计中,数据变化订阅记录的规则,是记录应用日志的规则。 操作入口:应用中心——业务审计应用。

    Oinone 7天入门到精通 2024年6月20日
    2.4K00
  • 1.2 Oinone的致敬

    占在巨人的肩膀上,天地孤影任我行 1.2.1 数字化时代Oinone接棒Odoo 在数字化时代,中国在互联网化的应用、技术的领先毋庸置疑,但在软件的工程化、产品化输出方面仍有许多改进的空间。这时,我了解到了Odoo——一个国外非常优秀的开源ERP厂商,全球ERP用户数量排名第一,百级别员工服务全球客户。Odoo的工程化能力和商业模式深深吸引了我,它是软件行业典型的产品制胜和长期主义者的胜利之一。 在2019年,也就是数式刚成立的时候,我们跟很多投资人聊起公司的对标是谁,我不是要成为数字化时代的SAP,而是要成为Odoo。然而,当时大部分国内投资人并不了解Odoo,尽管它已经是全球最大的ERP厂商之一,因为当时Odoo还没有明确的估值。直到2021年7月份获得Summit Partners的2.15亿美元投资后,Odoo才正式成为IT独角兽企业。 Odoo对我们提供了极大的启示,因此我们致敬Odoo,同样选择开源,每年对产品进行升级发布。如今,Odoo15已经发布,而Oinone也已推出第三版,恰好相隔12年,这是一个时代的接棒,从信息化升迁至数字化。 1.2.2Oinone与Odoo的不同之处 技术方面的不同 在技术上,Oinone和Odoo有相同之处,也有不同之处。它们都基于元数据驱动的软件系统,但是它们在如何让元数据运作的机制上存在巨大差异。Odoo是企业管理场景的单体应用,而Oinone则致力于企业商业场景的云原生应用。因此,它们在技术栈的选择、前后端协议设计、架构设计等方面存在差异。 场景方面的不同 在场景上,Oinone和Odoo呈现许多差异。相对于SAP这些老牌ERP厂商,Odoo算是西方在企业级软件领域的后起之秀,其软件构建方式、开源模式和管理理念在国外取得了非凡的成就。然而,在国内,Odoo并没有那么成功或者并没有那么知名。国内做Odoo的伙伴普遍认为,Odoo与中国用户的交互风格不符,收费模式设计以及外汇管制使商业活动受到限制,本地化服务不到位,国内生态没有形成合力,伙伴们交流合作都非常少。另外,Odoo在场景方面主要围绕内部流程管理,与国内老牌ERP如用友、金蝶重叠,市场竞争激烈。相比之下,Oinone看准了企业视角由内部管理转向业务在线、生态在线(协同)带来的新变化,聚焦新场景,利用云、端等新技术的发展,从企业内外部协同入手,以业务在线驱动企业管理流程升级。它先立足于国内,做好国内生态服务,再着眼未来的国际化。 无代码设计器的定位 在无代码设计器的定位上,Odoo的无代码设计器是一个非常轻量的辅助工具,因为ERP场景下,一个企业实施完以后基本几年不会变,流程稳定度非常高。相反,Oinone为适应"企业业务在线化后,所有的业务变化与创新都需要通过系统来触达上下游,从而敏捷响应快速创新"的时代背景,重点打造出五大设计器。(如下图1-2所示)。 图1-2 Oinone五大设计器 在数字化时代中国软件将接棒世界,而Oinone也要接棒Odoo,把数字化业务与技术的最佳实践赋能给企业,帮助企业数字化转型不走弯路!

    2024年5月23日
    2.5K00

Leave a Reply

Please Login to Comment