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的模块

脚步执行生成工程如下:

image.png

图4-3-2 SecondModule的工程结构

Step2 调整配置

修改application-dev.yml文件

修改SecondModule的application-dev.yml的内容

  1. 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
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      poolPreparedStatements: true
      asyncInit: true

图4-3-3 base库换成与DemoModule一样的配置

  1. 修改后端Server的启动端口号为9091
server:
  address: 0.0.0.0
  port: 9091
  sessionTimeout: 3600

图4-3-4 修改后端Server的启动端口号为9091

修改bootstrap.yml文件

  1. 设置dubbo序列化方式为pamirs,记得DemoModule也要改。
spring:
  profiles:
    active: dev
  application:
    name: pamirs-second

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-second
    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-second
    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-3-5 修改bootstrap.yml文件

Step3 构建一个RemoteTestModel

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

import pro.shushi.pamirs.meta.annotation.Field;
import pro.shushi.pamirs.meta.annotation.Model;
import pro.shushi.pamirs.meta.base.common.CodeModel;

@Model.model(RemoteTestModel.MODEL_MODEL)
@Model(displayName = "远程测试模型",labelFields = "name")
public class RemoteTestModel extends CodeModel {

    public static final String MODEL_MODEL="second.RemoteTestModel";

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

}

新建RemoteTestModel模型,用于远程调用体验:

图4-3-6 构建一个RemoteTestMode

Step4 新增SecondSessionHook

@Hook(module= SecondModule.MODULE_MODULE), 规定只有增对SecondModule模块访问的请求该拦截器才会生效,不然其他模块的请求都会被SecondSessionHook拦截。

package pro.shushi.pamirs.second.core.hook;

import org.springframework.stereotype.Component;
import pro.shushi.pamirs.meta.annotation.Hook;
import pro.shushi.pamirs.meta.annotation.fun.extern.Slf4j;
import pro.shushi.pamirs.meta.api.core.faas.HookBefore;
import pro.shushi.pamirs.meta.api.dto.fun.Function;
import pro.shushi.pamirs.second.api.SecondModule;

@Component
@Slf4j
public class SecondSessionHook implements HookBefore {
    @Override
    @Hook(priority = 1,module= SecondModule.MODULE_MODULE)
    public Object run(Function function, Object... args) {
        log.info("second hook");
        return function;
    }
}

图4-3-7 新增SecondSessionHook

Step5 新建RemoteTestModelAction

在SecondModule中新建RemoteTestModelAction,自定义RemoteTestModel模型的queryPage函数。方便debug,看看效果

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

import pro.shushi.pamirs.meta.annotation.Function;
import pro.shushi.pamirs.meta.annotation.Model;
import pro.shushi.pamirs.meta.api.dto.condition.Pagination;
import pro.shushi.pamirs.meta.api.dto.wrapper.IWrapper;
import pro.shushi.pamirs.meta.constant.FunctionConstants;
import pro.shushi.pamirs.meta.enmu.FunctionOpenEnum;
import pro.shushi.pamirs.meta.enmu.FunctionTypeEnum;
import pro.shushi.pamirs.second.api.model.RemoteTestModel;

@Model.model(RemoteTestModel.MODEL_MODEL)
public class RemoteTestModelAction {

    @Function.Advanced(type= FunctionTypeEnum.QUERY)
    @Function.fun(FunctionConstants.queryPage)
    @Function(openLevel = {FunctionOpenEnum.API})
    public Pagination<RemoteTestModel> queryPage(Pagination<RemoteTestModel> page, IWrapper<RemoteTestModel> queryWrapper){
        return new RemoteTestModel().queryPage(page,queryWrapper);
    }

}

图4-3-8 新建RemoteTestModelAction

Step6 boot工程需要引入Oinone的RPC包

  1. 父pom的依赖管理中先加入pamirs-distribution-faas的依赖
<dependency>
  <groupId>pro.shushi.pamirs.distribution</groupId>
  <artifactId>pamirs-distribution-faas</artifactId>
  <version>${pamirs.boot.version}</version>
</dependency>

图4-3-9 父pom的依赖管理中先加入pamirs-distribution-faas的依赖

  1. 在pamirs-second-boot中增加入pamirs-distribution-faas的依赖
<dependency>
  <groupId>pro.shushi.pamirs.distribution</groupId>
  <artifactId>pamirs-distribution-faas</artifactId>
</dependency>

图4-3-10 在pamirs-second-boot中增加入pamirs-distribution-faas的依赖

  1. 为SecondApplication类增加类注解@EnableDubbo
@EnableDubbo
public class SecondApplication {
}

图4-3-11 为SecondApplication类增加类注解@EnableDubbo

Step7 启动SecondModule

别忘了启动指令要为INSTALL,参考DemoModule的启动说明

Step8 Second工程本地mvn install,方便DemoModule包依赖

二、DemoModule模块准备

Step1 DemoModule引入Oinone的RPC包和Second的API包

  1. 父pom的依赖管理中先加入pamirs-second-api和pamirs-distribution-faas的依赖
<dependency>
  <groupId>pro.shushi.pamirs.second</groupId>
  <artifactId>pamirs-second-api</artifactId>
  <version>1.0.0-SNAPSHOT</version>
</dependency>

<dependency>
  <groupId>pro.shushi.pamirs.distribution</groupId>
  <artifactId>pamirs-distribution-faas</artifactId>
  <version>${pamirs.boot.version}</version>
</dependency>

图4-3-12 依赖管理增加对应依赖包配置

  1. 在pamirs-demo-api中增加入pamirs-second-api的依赖
<dependency>
  <groupId>pro.shushi.pamirs.second</groupId>
  <artifactId>pamirs-second-api</artifactId>
</dependency>

图4-3-13 增加pamirs-second-api的依赖配置

  1. 在pamirs-demo-boot中增加入pamirs-distribution-faas的依赖
<dependency>
  <groupId>pro.shushi.pamirs.distribution</groupId>
  <artifactId>pamirs-distribution-faas</artifactId>
</dependency>

图4-3-14 增加pamirs-distribution-faas的依赖配置

  1. 为DemoApplication类增加类注解@EnableDubbo
@EnableDubbo
public class DemoApplication {
}

图4-3-15 为DemoApplication类增加类注解@EnableDubbo

Step2 修改DemoModule定义

修改DemoModule的依赖注解,增加SecondModule.MODULE_MODULE

@Module(dependencies = {SecondModule.MODULE_MODULE})

图4-3-16 注解方式申明DemoModule对SecondModule的依赖

Step3 修改pamirs-demo-boot的bootstrap.yml文件

参考SecondModule修改dubbo的序列化方式为pamirs

Step4 修改pamirs-demo-boot的DemoApplication

为依赖模块配置扫描包路径,修改DemoApplication增加second的扫描包,在日常开发中小伙伴的应用肯定不是以pamirs开头,所以大家别忘了SpringBoot的基本配置。在3.2.1【构建第一个Module】一文也提到我们在启动工程中需要配置启动模块和依赖模块的扫描路径。

image.png

图4-3-17 修改DemoApplication中关于SpringBoot的扫描包路径

三、分布式部署体验

以上工作准备好以后,我们就可以通过DemoModule来远程调用SecondModule。

第一个Case(前端把请求分别打到DemoModule、SecondModule)

在日常研发中,不同模块的菜单整合也是非常常见的,比如把B模块的菜单挂在A模块中。这个Case就是在讲解如何做到跨模块的菜单整合

Step1 修改前端工程的vue.config.js

利用node的proxy,分别把DemoCore转发到8090端口,把SecondCore转发到8091端口,把默认其他模块转发到8090端口。localhost还是127.0.0.1跟浏览器地址框输入保持一致

const WidgetLoaderPlugin = require('@kunlun/widget-loader/dist/plugin.js').default;
const Dotenv = require('dotenv-webpack');

module.exports = {
  lintOnSave: false,
  configureWebpack: {
    module: {
      rules: [
        {
          test: /\.widget$/,
          loader: '@kunlun/widget-loader',
        },
      ],
    },
    plugins: [new WidgetLoaderPlugin(), new Dotenv()],
    resolveLoader: {
      alias: {
        '@kunlun/widget-loader': require.resolve('@kunlun/widget-loader'),
      },
    },
  },
  devServer: {
    port: 8080,
    disableHostCheck: true,
    progress: false,
    proxy: {
      'pamirs/DemoCore': {
        // 支持跨域
        changeOrigin: true,
        target: 'http://localhost:8090',
      },
      'pamirs/SecondCore': {
          // 支持跨域
        changeOrigin: true,
        target: 'http://localhost:8091',
      },
      pamirs: {
          // 支持跨域
        changeOrigin: true,
        target: 'http://localhost:8090',
      },
    },
  },
};

图4-3-18 修改前端工程的vue.config.js

Step2 修改DemoMenus

增加一个RemoteTestModel的管理入口,这里需要指定菜单的module为DemoModule,不然应用会切换到SecondModule

@UxMenu("远程模型")@UxRoute(model = RemoteTestModel.MODEL_MODEL,module= DemoModule.MODULE_MODULE) class RemoteTestModelMenu{}

图4-3-19 修改DemoMenus

Step3 重启前端应用看效果

  1. 点击远程模型菜单,可以正常进行增、删、改、查操作。

image.png

图4-3-20 示例效果

  1. SecondSessionHook起作用

“second hook”并打印出来,前端请求没有再进过DemoModule再远程调用SecondModule,而是直接打到了SecondModule上。

image.png

图4-3-21 SecondSessionHook对应日志

第二个Case(跨模块代理,自动走远程)

Step1 新建RemoteTestModelProxy

在DemoModule中新建RemoteTestModelProxy代理继承RemoteTestModel

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

import pro.shushi.pamirs.meta.annotation.Model;
import pro.shushi.pamirs.meta.enmu.ModelTypeEnum;
import pro.shushi.pamirs.second.api.model.RemoteTestModel;

@Model.model(RemoteTestModelProxy.MODEL_MODEL)
@Model.Advanced(type = ModelTypeEnum.PROXY)
@Model(displayName = "远程模型的代理",summary="远程模型的代理")
public class RemoteTestModelProxy extends RemoteTestModel {

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

}

图4-3-22 新建RemoteTestModelProxy

Step2 修改DemoMenus

增加一个RemoteTestModelProxy的管理入口

@UxMenu("远程代理")@UxMenu.route(RemoteTestModelProxy.MODEL_MODEL) class RemoteTestModelProxyMenu{}

图4-3-23 增加一个RemoteTestModelProxy的管理入口

Step3 重启看效果

  1. 点击菜单【远程代理】

image.png

图4-3-24 示例效果

  1. 在SecondModule的RemoteTestModelAction中debug,会发现DemoModule会自动调用RemoteTestModel模型的queryPage。

image.png

图4-3-25 DemoModule远程调用RemoteTestModel模型的queryPage

  1. 但不走SecondSessionHook

“second hook”并没有打印出来,为什么?在3.4.3.2【面向切面-拦截器】一文中介绍到“不是前端直接发起的请求不会生效”,可能小伙伴有疑问,我不是前端点击的吗?是的,但经过DemoModule再调用SecondModule,系统会判定为后端调用。

第三个Case(远程调用自定义函数)

Step1 新增函数RemoteTestModelService和RemoteTestModelServiceImpl

SecondModule定义RemoteTestModelService,用于DemoModule的调用。SecondModule记得再次mvn install

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

import pro.shushi.pamirs.meta.annotation.Fun;
import pro.shushi.pamirs.meta.annotation.Function;
import pro.shushi.pamirs.meta.api.dto.condition.Pagination;
import pro.shushi.pamirs.meta.api.dto.wrapper.IWrapper;
import pro.shushi.pamirs.second.api.model.RemoteTestModel;

@Fun(RemoteTestModelService.FUN_NAMESPACE)
public interface RemoteTestModelService {

    String FUN_NAMESPACE ="second.RemoteTestModelService";
    @Function
    Pagination<RemoteTestModel> queryPage(Pagination<RemoteTestModel> page, IWrapper<RemoteTestModel> queryWrapper);
    @Function
    String hello(String name);
    @Function
    String remoteTest(RemoteTestModel remoteTest);
}

图4-3-26 新增RemoteTestModelService接口类

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

import org.springframework.stereotype.Component;
import pro.shushi.pamirs.meta.annotation.Fun;
import pro.shushi.pamirs.meta.annotation.Function;
import pro.shushi.pamirs.meta.api.dto.condition.Pagination;
import pro.shushi.pamirs.meta.api.dto.wrapper.IWrapper;
import pro.shushi.pamirs.second.api.model.RemoteTestModel;
import pro.shushi.pamirs.second.api.service.RemoteTestModelService;

@Fun(RemoteTestModelService.FUN_NAMESPACE)
@Component
public class RemoteTestModelServiceImpl implements RemoteTestModelService {

    @Override
    @Function
    public Pagination<RemoteTestModel> queryPage(Pagination<RemoteTestModel> page, IWrapper<RemoteTestModel> queryWrapper) {
        return new RemoteTestModel().queryPage(page,queryWrapper);
    }
    @Override
    @Function
    public String hello(String name) {
        return "hello" + name ;
    }

    @Override
    @Function
    public String remoteTest(RemoteTestModel remoteTest) {
        return "remoteTest" + remoteTest.getName() ;
    }
}

图4-3-27 新增RemoteTestModelServiceImpl实现类

Step2 新增RemoteTestModelProxyAction

  1. 新增RemoteTestModelProxyAction,并定义queryPage、hello、remoteTest等Action,方便前端点击测试

  2. 引入RemoteTestModelService,分别调用queryPage、hello、remoteTest方法

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import pro.shushi.pamirs.demo.api.proxy.RemoteTestModelProxy;
import pro.shushi.pamirs.framework.faas.utils.ArgUtils;
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.annotation.fun.extern.Slf4j;–
import pro.shushi.pamirs.meta.api.dto.condition.Pagination;
import pro.shushi.pamirs.meta.api.dto.wrapper.IWrapper;
import pro.shushi.pamirs.meta.constant.FunctionConstants;
import pro.shushi.pamirs.meta.enmu.FunctionOpenEnum;
import pro.shushi.pamirs.meta.enmu.FunctionTypeEnum;
import pro.shushi.pamirs.second.api.model.RemoteTestModel;
import pro.shushi.pamirs.second.api.service.RemoteTestModelService;

@Model.model(RemoteTestModelProxy.MODEL_MODEL)
@Component
@Slf4j
public class RemoteTestModelProxyAction {
    @Autowired
    private RemoteTestModelService remoteTestModelService;

    @Function.Advanced(type= FunctionTypeEnum.QUERY)
    @Function.fun(FunctionConstants.queryPage)
    @Function(openLevel = {FunctionOpenEnum.API})
    public Pagination<RemoteTestModelProxy> queryPage(Pagination<RemoteTestModelProxy> page, IWrapper<RemoteTestModelProxy> queryWrapper){

        Pagination<RemoteTestModel> pageConvert = ArgUtils.convert(RemoteTestModelProxy.MODEL_MODEL,RemoteTestModel.MODEL_MODEL,page);
        IWrapper<RemoteTestModel> queryWrapperConvert = ArgUtils.convert(RemoteTestModelProxy.MODEL_MODEL,RemoteTestModel.MODEL_MODEL,queryWrapper);
        Pagination<RemoteTestModel> resultTmp=  remoteTestModelService.queryPage(pageConvert,queryWrapperConvert);
        Pagination<RemoteTestModelProxy> result = ArgUtils.convert(RemoteTestModel.MODEL_MODEL,RemoteTestModelProxy.MODEL_MODEL,resultTmp);
        return result;
    }

    @Action(displayName = "hello")
    public RemoteTestModelProxy hello(RemoteTestModelProxy data){
        String hello = remoteTestModelService.hello(data.getName());
        log.info(hello);
        return data;
    }
    @Action(displayName = "remoteTest")
    public RemoteTestModelProxy remoteTest(RemoteTestModelProxy data){
        RemoteTestModel s = ArgUtils.convert(RemoteTestModelProxy.MODEL_MODEL,RemoteTestModel.MODEL_MODEL,data);
        String testRemote = remoteTestModelService.remoteTest(s);
        log.info(testRemote);
        return data;
    }
}

图4-3-28 新增RemoteTestModelProxyAction

Step3 重启看效果

点击remoteTest按钮看看效果

image.png

图4-3-29 示例效果

总结一、二 、三 Case

把SecondModule模块停掉,则上面一、二 、三 Case都会报错。如果DemoModule的pamirs-demo-boot中依赖加上pamirs-second-core,同时application-dev.yml文件中pamirs.boot.modules加上second_core的配置,则DemoModule和SecondModule部署在一起,再把前端node请求代理都转发到DemoModule模块上。则只需要启动pamirs-demo-boot就可以了。这个留给小伙伴们自己实验。

分布式不分布式只是部署方式的差异,代码层面没有差异,有了体感以后再去看2.4.1【Oinone独特性之单体与分布式的灵活切换】一文可能会有更深的体会。

注意点:

  1. 【编码】远程调用服务时要确保入参和服务端定义的一样,可以用平台提供ArgUtils.convert进行转换

  2. 【部署】分布式情况下部署要用ng或其他方式进行转发,针对前端发起的请求,根据请求url中带的模块信息转发到对应有启动该模块的boot应用中

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

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

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

相关推荐

  • 4.1.23 框架之信息传递

    在4.1.13【Action之校验】、3.4.1【构建第一个Function】等文章中,都用到PamirsSession.getMessageHub()来设置返回消息,基本上都是在传递后端逻辑判断的异常信息,而且在系统报错时也会通过它来返回错误信息,前端接收到错误信息则会以提示框的方式进行错误提示。其实后端除了可以返回错误信息以外,还可以返回调试、告警、成功、信息等级别的信息给前端。但是默认情况下前端只提示错误信息,可以通过前端的统一配置放开提示级别,有点类似后端的日志级别。 一、不同信息类型的举例 Step1 新建PetTypeAction 借用PetType模型的表格页做为信息传递的测试入口,为PetType模型新增一个ServerAction,在代码中对信息的所有类型进行模拟 package pro.shushi.pamirs.demo.core.action; import org.springframework.stereotype.Component; import pro.shushi.pamirs.demo.api.model.PetCatItem; import pro.shushi.pamirs.demo.api.model.PetType; import pro.shushi.pamirs.meta.annotation.Action; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.api.dto.common.Message; import pro.shushi.pamirs.meta.api.session.PamirsSession; import pro.shushi.pamirs.meta.enmu.ActionContextTypeEnum; import pro.shushi.pamirs.meta.enmu.InformationLevelEnum; import pro.shushi.pamirs.meta.enmu.ViewTypeEnum; @Model.model(PetType.MODEL_MODEL) @Component public class PetTypeAction { @Action(displayName = "消息",bindingType = ViewTypeEnum.TABLE,contextType = ActionContextTypeEnum.CONTEXT_FREE) public PetType message(PetType data){ PamirsSession.getMessageHub().info("info1"); PamirsSession.getMessageHub().info("info2"); PamirsSession.getMessageHub().error("error1"); PamirsSession.getMessageHub().error("error2"); PamirsSession.getMessageHub().msg(new Message().msg("success1").setLevel(InformationLevelEnum.SUCCESS)); PamirsSession.getMessageHub().msg(new Message().msg("success2").setLevel(InformationLevelEnum.SUCCESS)); PamirsSession.getMessageHub().msg(new Message().msg("debug1").setLevel(InformationLevelEnum.DEBUG)); PamirsSession.getMessageHub().msg(new Message().msg("debug2").setLevel(InformationLevelEnum.DEBUG)); PamirsSession.getMessageHub().msg(new Message().msg("warn1").setLevel(InformationLevelEnum.WARN)); PamirsSession.getMessageHub().msg(new Message().msg("warn2").setLevel(InformationLevelEnum.WARN)); return data; } } 图4-1-23-1 为PetType模型新增一个ServerAction Step2 (前端)修改提示级别 在项目初始化时使用CLI构建初始化前端工程,在src/middleware有拦截器的默认实现,修改信息提示的默认级别为【ILevel.SUCCESS】 图4-1-23-2(前端)修改提示级别 const DEFAULT_MESSAGE_LEVEL = ILevel.SUCCESS; 图4-1-23-3(前端)修改提示级别 Step3 重启系统看效果 从页面效果中看到已经不在是只提示错误信息。从协议端看错误级别的信息是在errors下,其他级别的信息是在extensions下。 图4-1-23-4 示例效果 图4-1-23-5 系统提示的返回结果 二、MessageHub的其他说明 是实现上看MessageHub是基于GQL协议,前后端都有配套实现。同时前端还提供了订阅MessageHub的信息功能,以满足前端更多交互要求,前端MessageHub提供的订阅能力使用教程详见4.2.2前端高级特性之【框架之MessageHub】一文。

    2024年5月23日
    1.8K00
  • 流程触发

    1. 流程触发 新增的流程设计页面默认包含两个节点,一个是流程的触发节点:确定流程开始的条件;另一个是流程结束的节点。 流程触发方式有模型触发、定时触发、日期触发三种方式,未设置流程触发方式时无法继续添加后续流程节点,同时无法进行流程发布,如左下图。触发方式设置完成后,可从左侧菜单栏拖入或流程箭头中的加号点击添加节点动作,如右下图。 1.1 模型触发 模型触发适用于模型中的数据字段变化开始流程的场景,比如员工请假审批流程。 模型触发的场景有数据的增删改,也可以对模型中的单个或多个字段进行条件筛选,若包含更新数据的场景可以设置选择更新字段,只有设置的字段更新才会触发流程,若不设置选择更新字段或者筛选条件,则模型中任一字段发生设置场景的变化时都会触发流程。 1.2 定时触发 定时触发适用于周期性调用流程的场景,比如仓库周期性盘点的流程。 需要设置一个流程第一次执行的时间,配置好循环的周期间隔。特殊的是选择周为周期时,当前周选中的日期也会执行流程。例:开始时间:2022-01-14(周四) 循环周期间隔:1周 自定义设置为周一到周五,则2022-01-15(本周五)也会执行流程操作。 1.3 日期触发 日期触发适用于模型中的日期时间字段引发流程的场景,比如给员工发生日祝福短信的流程。 设置日期触发时,若指定字段只包含日期,则必须要指定时刻,如左下图。例如给员工发生日祝福短信时根据模型中的员工生日数据获取到了执行流程的日期,需要制定开始该流程执行的具体时刻。若指定字段包含日期和时间,则不填写指定时刻时默认按照字段中的时刻开始执行流程,如右下图。例如办理业务后短信回访收集评价时根据模型中的业务完成时间,立即或延时发送短息。

    2024年6月20日
    2.3K00
  • 节点动作

    节点动作为触发和结束结点中间的动作,点击节点名称可以进行修改。

    Oinone 7天入门到精通 2024年6月20日
    2.0K00
  • 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.4K00

Leave a Reply

Please Login to Comment