3.2.1 构建第一个Module

所有环境准备就绪,就让我们踏上oinone的奇妙之旅吧。先搞个demo模块【展示名为“oinone的Demo工程”,名称为“demoCore”,编码为“demo_core”】试试看,本节学习目的就是能把它启动起来,有个大概的认知。

一、后端工程脚手架

使用如下命令来利用项目脚手架生成启动工程:

  1. 新建archetype-project-generate.sh脚本,或者直接下载archetype-project-generate.sh
#!/bin/bash

# 项目生成脚手架
# 用于新项目的构建

# 脚手架使用目录
# 本地 local
# 本地脚手架信息存储路径 ~/.m2/repository/archetype-catalog.xml
archetypeCatalog=local

# 以下参数以pamirs-demo为例

# 新项目的groupId
groupId=pro.shushi.pamirs.demo

# 新项目的artifactId
artifactId=pamirs-demo

# 新项目的version
version=1.0.0-SNAPSHOT

# Java包名前缀
packagePrefix=pro.shushi

# Java包名后缀
packageSuffix=pamirs.demo

# 新项目的pamirs platform version
pamirsVersion=4.7.8

# Java类名称前缀
javaClassNamePrefix=Demo

# 项目名称 module.displayName
projectName=OinoneDemo

# 模块 MODULE_MODULE 常量
moduleModule=demo_core

# 模块 MODULE_NAME 常量
moduleName=DemoCore

# spring.application.name
applicationName=pamirs-demo

# 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=/demo

mvn archetype:generate \
  -DinteractiveMode=false \
  -DarchetypeCatalog=${archetypeCatalog} \
  -DarchetypeGroupId=pro.shushi.pamirs.archetype \
  -DarchetypeArtifactId=pamirs-project-archetype \
  -DarchetypeVersion=${pamirsVersion} \
  -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}

图3-2-1-1 新建archetype-project-generate.sh脚本

  1. Linux/Unix/Mac 需要执行以下命令添加执行权限
chmod +x archetype-project-generate.sh

图3-2-1-2 添加执行权限

  1. 根据脚本中的注释修改项目变量(demo工程可无需编辑)
  2. 执行脚本
./archetype-project-generate.sh

二、后端工程结构介绍

通过脚手架生成的demo工程是我们2.4.1【oinone独特性之单体与分布式的灵活切换】一文中介绍的单模块工程结构,属于入门级的一种,麻雀虽小五脏俱全,特别适合新手学习。

  1. 结构示意图(如下图3-2-4所示)

3.2.1 构建第一个Module

图3-2-1-4 结构示意图

  1. 工程结构说明
工程名 包名 说明
pamirs-demo-api 对外api包,如果有其他模块需要依赖demo模块,则可以在其pom中引入pamirs-demo-api包
constant 常量的包路径
enumeration 枚举类的包路径
model 该领域核心模型的包路径
service 该领域对外暴露接口api的包路径
tmodel 存放该领域的非存储模型如:用于传输的临时模型
DemoModule 该类是Demo模块的定义
pamirs-demo-boot demo模块的启动类
boot 启动类的包路径
DemoApplication Demo模块的应用启动类,遵循spring boot 规范
resources/config/application-dev.yml 研发环境的yml配置文件,遵循spring boot 规范
resources/bootstrap.yml 启动的yml配置文件,遵循spring boot 规范
pamirs-demo-core
action 模型对外交互的行为的包路径
init 模块初始化工作的包路径
manager manager是 service的一些公共逻辑,不会定义为独立的function的类
service service是对应api工程中service接口的实现类,是模型的function

表3-2-1-1 工程结构说明

三、pom.xml介绍

父pom的依赖管理

  1. 一个是启动包依赖
    a. pamirs-boot里是有我们多种启动模式依赖包。教程只介绍标准启动模式
    b. pamirs-base-standard

3.2.1 构建第一个Module

图3-2-1-5 父pom的依赖管理

pamirs-domo-api

一个标准java工程,可以看出只是依赖了,我们的pamirs-base-standard
3.2.1 构建第一个Module

图3-2-1-6 pamirs-domo-api

pamirs-demo-core

一个标准java工程,可以看出只是依赖了,我们的pamirs-demo-api

3.2.1 构建第一个Module

图3-2-1-7 pamirs-domo-core

pamirs-demo-boot

把启动的时候,需要启动的module(模块)对应的jar,进行依赖引入。这样就可以在我们的yml文件中进行启动module的配置

  1. 所需module(模块)对应的jar(如下图3-2-8所示)

3.2.1 构建第一个Module

图3-2-1-8 所需module(模块)对应的jar包依赖

  1. yml文件基础配置,boot工程的yml配置详见4.1.1【模块之yml文件结构详解】一文

3.2.1 构建第一个Module

图3-2-1-9 yml文件

四、DemoModule的定义

到此我们一个oinone中的一个module对应的工程就介绍完了。到目前为止跟一般的spring boot的工程没有太多区别,就多做了一个DemoModule的定义,oinone的所有Module都继承自PamirsModule。

3.2.1 构建第一个Module

图3-2-1-10 DemoModule的定义

配置注解

通过@Module的name属性配置模块技术名称,前端与后端交互协议使用模块技术名称来定位模块。

通过@Module的displayName属性配置模块展示名称,在产品视觉交互层展现。

通过@Module的version属性配置模块版本,系统会比较版本号来决定模块是否需要进行升级。

通过@Module的priority属性配置模块优先级(数字越小,优先级越高),系统会根据优先级取优先级最高的应用设置的首页来作为整个平台的首页。

通过@Module的dependencies属性和exclusions属性来配置模块间的依赖互斥关系,值为模块编码数组。如果模块继承了另一模块的模型或者与另一模块的模型建立了关联关系,则需要为该模块的依赖模块列表配置另一模块的模块编码。

通过@Module.module配置模块编码,模块编码是模块在系统中的唯一标识。

通过@Module.Advanced的selfBuilt属性配置模块是否为平台自建模块。

通过@Module.Advanced的application属性配置模块是否为应用(具有视觉交互页面的模块)。模块切换组件只能查看到应用。

通过@UxHomepage注解配置首页。@UxHomepage注解的model属性指定跳转页面的模型编码,name属性指定跳转页面的视图动作,默认为列表页。如果配置首页为列表页且未定义ViewAction,系统会根据首页配置自动生成。

更多Module的详细元数据描述,详见4.1.4【模块元数据详解】一文

配置扫描路径

设置扫描模型配置的包路径:

  • 使用packagePrefix方法来配置模块需要扫描模型配置的包路径

  • 使用dependentPackagePrefix方法来配置依赖模块的模型配置的包路径;如果不配置,会默认根据依赖模块的配置扫描模型配置的包路径扫描依赖模型

  • 不同模块包路径包含会导致模型加载模块出问题

命名规范

属性 默认取值规则 命名规范
module 无默认值
开发人员定义规范示例:
{项目名称}_{模块功能示意名称}
使用下划线命名法
仅支持数字、大写或小写字母、下划线
必须以字母开头
不能以下划线结尾
长度必须小于等于128个字符
name 无默认值 使用大驼峰命名法
仅支持数字、字母
必须以字母开头
长度必须小于等于128个字符

表3-2-1-2 命名规范

五、DemoModule的启动

  1. 修改yml文件中数据源配置,数据库地址与密码修改为自己本地

  2. 配置license,否则启动会报错,获取授权文件请找官方客户

3.2.1 构建第一个Module

图3-2-1-11 license未配置

  1. 需要为启动或依赖模块配置扫描路径,配置扫描路径:pmairs是我们的oinone的基础包(必选),himalaya,tanggula是我们的业务模型基础包(可选),pro.shushi.pamirs.demo是我们测试项目包路径(必选,只不过它也在pamirs路径下,不填也不错)

3.2.1 构建第一个Module

图3-2-1-12 扫描逻辑配置

  1. 启动应用,我们会发现会报错。这个错误主要因为Oinone默认的是RELOAD(重启)模式,这种模式下只会从数据库中读取已安装模块并与yml文件中配置需要加载的模块对比。如果数据库中没有则会报没有安装过**模块,而我们是第一次启动,前面必然没有安装过模块,所以我们要把模式变为INSTALL,启动参数详见4.1.2【模块之启动指令】一文。如果整个平台第一次启动则回报 'base_sequence_config' doesn't exist

3.2.1 构建第一个Module

图3-2-1-13 启动应用的报错提示

  1. 把模式变为INSTALL再次启动

3.2.1 构建第一个Module

3.2.1 构建第一个Module

图3-2-1-14 把模式变为INSTALL再次启动

  1. 查看日志,看到对应启动字样才代表启动完成,而非Spring Boot的启动完成日志。我们的oinone的启动是在Spring Boot 启动完以后异步启动的

3.2.1 构建第一个Module

图3-2-1-15 启动成功日志

  1. 打开GraphQL客户端Insomnia看对应服务是否暴露

    a. 创建一个demo项目

3.2.1 构建第一个Module

图3-2-1-16 Insomnia操作示意-创建一个新项目

3.2.1 构建第一个Module

图3-2-1-17 Insomnia操作示意-命名为demo

b. 为demo项目创建一个请求集合

3.2.1 构建第一个Module

图3-2-1-18 Insomnia操作示意-创建一个请求集合(第一步)

3.2.1 构建第一个Module

图3-2-1-19 Insomnia操作示意-创建一个请求集合(第二步)

3.2.1 构建第一个Module

图3-2-1-20 Insomnia操作示意-创建一个请求集合(第三步)

c. 创建一个请求 command+N

3.2.1 构建第一个Module

图3-2-1-21 Insomnia操作示意-创建一个请求

3.2.1 构建第一个Module

图3-2-1-22 Insomnia操作示意-选POST模式

3.2.1 构建第一个Module

图3-2-1-23 Insomnia操作示意-输入服务地址

3.2.1 构建第一个Module

图3-2-1-24 Insomnia操作示意-切换body结构为GQL

d. 检验结果,对应后端提供的服务已经有提示了

3.2.1 构建第一个Module

图3-2-1-25 Insomnia操作示意-检验结果

e. 查看schema 文档

3.2.1 构建第一个Module

图3-2-1-26 Insomnia操作示意-查看API文档

3.2.1 构建第一个Module

图3-2-1-27 Insomnia操作示意-查看API文档

3.2.1 构建第一个Module

图3-2-1-28 Insomnia操作示意-查看API文档

恭喜第一个oinone的模块已经启动完成,在下一文中我们通过页面来看看oinone的系统的庐山真面目。

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

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

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

相关推荐

  • 工作台

    有工作台权限的用户,默认登录页为工作台,也可以通过APP Finder进入工作台。 1. 快捷处理 右上角消息中会气泡展示未处理或未读的操作,点击展开后可以点过去进行快捷处理。 2. 查看、处理流程 2.1 流程查看 流程管理页面共同点: 1包含选项分类筛选 2包含标签筛选 3包含应用下拉选筛选 4包含根据流程名称搜素 流程管理页面名词解释: 待办:当前登录用户未处理的流程节点 我发起的:当前登录用户人为触发的流程(模型触发) 抄送:抄送给当前登录用户的节点(审批/填写) 我已办结:由当前登录用户完成人工/自动同意、人工拒绝或人工填写的节点 无需办理:当前登录用户转交的任务/被退回、被撤销、被或签、被其他分支任务拒绝的还未办理的任务 站内信:当前登录用户收到的站内信 2.2 流程处理 每条流程数据下方有动作,点击进入流程处理页面,大致分为详情页和操作页。 待办中点击“审批/填写”会进入流程操作页。审批操作页可能包含“同意、拒绝、退回、加签、转交、返回”,填写操作页可能包含“提交、暂存”,审批操作页包含哪些动作由流程设计决定。 我发起的、抄送、我已办结、无需处理点击“查看”会进入流程详情页。 3. 应用快捷入口 应用中心中星标的收藏应用会展示在此处,点击可快捷进入应用。 应用中心中已安装的应用点击星标即可收藏。

    2024年6月20日
    77500
  • 3.5.3 Action的类型

    各类动作我们都碰到过,但都没有展开讲过。这篇文章我们来系统介绍下oinone涉及到的所有Action类型。 一、动作类型 服务器动作ServerAction 类似于Spring MVC的控制器Controller,通过模型编码和动作名称路由,定义存储模型或代理模型将为该模型自动生成动作名称为consturct,queryOne,queryPage,create,update,delete,deleteWithFieldBatch的服务器动作。定义传输模型将为该模型自动生成动作名称为consturct的服务器动作 窗口动作ViewAction 站内跳转,通过模型编码和动作名称路由。系统将为存储模型和代理模型自动生成动作名称为redirectDetailPage的跳转详情页窗口动作,动作名称为redirectListPage的跳转列表页窗口动作,动作名称为redirectCreatePage的跳转新增页窗口动作,动作名称为redirectUpdatePage的跳转更新页窗口动作。 跳转动作UrlAction 外链跳转 客户端动作ClientAction 调用客户端函数 二、默认动作 如果在UI层级,有开放新增语义函数,则会默认生成新增的窗口动作ViewAction,跳转到新增页面 如果在UI层级,有开放更新语义函数,则会默认生成修改的窗口动作ViewAction,跳转到更新页面 如果在UI层级,有开放删除语义函数,则会默认生成删除的客户端动作ClientAction,弹出删除确认对话框 三、第一个服务器动作ServerAction 回顾第一个ServerAction 第一个ServerAction是在3.3.2【模型的类型】一文中的“代理模型”部分出现的,再来看下当时的定义代码 package pro.shushi.pamirs.demo.core.action; ……引用类 @Model.model(PetShopProxy.MODEL_MODEL) @Component public class PetShopProxyAction extends DataStatusBehavior<PetShopProxy> { @Override protected PetShopProxy fetchData(PetShopProxy data) { return data.queryById(); } @Action(displayName = "启用") public PetShopProxy dataStatusEnable(PetShopProxy data){ data = super.dataStatusEnable(data); data.updateById(); return data; } ……其他代码 } 图3-5-3-1 回顾第一个ServerAction @Action注解将创建服务器动作,并@Model.model绑定 自定义ServerAction请勿使用get、set、unset开头命名方法或toString命名方法。 ServerAction之校验(举例) Step1 为动作配置校验表达式 使用@Validation注解为PetShopProxyAction的dataStatusEnable服务端动作进行校验表达式配置 package pro.shushi.pamirs.demo.core.action; ……引用类 @Model.model(PetShopProxy.MODEL_MODEL) @Component public class PetShopProxyAction extends DataStatusBehavior<PetShopProxy> { @Override protected PetShopProxy fetchData(PetShopProxy data) { return data.queryById(); } @Validation(ruleWithTips = { @Validation.Rule(value = "!IS_BLANK(data.code)", error = "编码为必填项"), @Validation.Rule(value = "LEN(data.shopName) < 128", error = "名称过长,不能超过128位"), }) @Action(displayName = "启用") public PetShopProxy dataStatusEnable(PetShopProxy data){ data = super.dataStatusEnable(data); data.updateById(); return data; } ……其他代码 } 图3-5-3-2 为动作配置校验表达式 注: ruleWithTips可以声明多个校验规则及错误提示; IS_BLANK和LEN为内置文本函数,更多内置函数详见4.1.12【函数之内置函数与表达式】一文; 当内置函数不满足时参考4.1.13【Action之校验】一文。 Step2 重启看效果 在商店管理页面点击【启用】得到了预期返回错误信息,显示"编码为必填项" 图3-5-3-3 在商店管理页面点击启用得到了预期返回错误信息 ServerAction之前端展示规则(举例) 既然后端对ServerAction发起提交做了校验,那能不能在前端就不展示呢?当然可以,我们现在就来试下。 Step1 配置PetShopProxyAction的dataStatusEnable的前端出现规则 用注解@Action.Advanced(invisible="!(activeRecord.code !== undefined && !IS_BLANK(activeRecord.code))")来表示,注意这里配对invisible是给前端识别的,所以写法上跟后端的校验有些不一样,但如内置函数IS_BLANK这些是前后端一致实现的,activeRecord在前端用于表示当前记录。 package pro.shushi.pamirs.demo.core.action; ……引用类 @Model.model(PetShopProxy.MODEL_MODEL) @Component public class PetShopProxyAction extends DataStatusBehavior<PetShopProxy> { @Override protected PetShopProxy fetchData(PetShopProxy data) { return data.queryById(); } @Validation(ruleWithTips = { @Validation.Rule(value = "!IS_BLANK(data.code)", error = "编码为必填项"), @Validation.Rule(value = "LEN(data.name) < 128", error = "名称过长,不能超过128位"), }) @Action(displayName = "启用") @Action.Advanced(invisible="!(activeRecord.code !== undefined…

    2024年5月23日
    1.2K00
  • 2.3 Oinone独特性之源,元数据与设计原则

    让我们来揭开Oinone元数据的神秘面纱,了解它的核心组成、获取方式、面向对象特性以及带来的好处。您或许会想,这些特性能否解决企业数字化转型中互联网架构遇到的挑战呢? 元数据是本文多次提到的重要概念。作为LCDP的基础,元数据支持企业所有研发范式。它数字化描述了软件本身,包括数据、行为和视图等方面。在描述数据时,元数据本身就是数据的数据;在描述行为时,它就是行为的数据;在描述视图时,它就是视图的数据。只有深入理解元数据,才能全面了解Oinone的其他特性。 本章节将介绍元数据的整体概览(如下图2-3所示),带领您了解其核心组成、面向对象特性以及组织方式。请注意,本章节将不会详细展开元数据的细节,这些细节将在后续的相关章程中深入介绍。 图2-3 元数据整体视图 一:以下是元数据的核心组成介绍: 模块(Module):它是将程序划分成若干个子功能,每个模块完成了一个子功能,再把这些模块总起来组成一个整体。它是按业务领域划分和管理的最小单元,是一组功能、界面的集合。 模型(Model):Oinone一切从模型出发,是数据及对行为的载体。它是对所需要描述的实体进行必要的简化,并用适当的变现形式或规则把它的主要特征描述出来所得到的系统模仿品。它包括元信息、字段、数据管理器和自定义函数。同时遵循面向对象设计原则,包括封装、继承和多态。 交互组件(UI Componment):它用菜单、视图和Action来勾绘出模块的前端交互拓扑,并且用组件化的方式统一管理、布局和视图。它用Action来描述所有可操作行为。 函数(Function):它是Oinone可执行逻辑单元,跟模型绑定则对应模型的方法。它描述满足数学领域函数定义,含有三个要素:定义域A、值域C{f(x),x属于A}和对应法则f。其中核心是对应法则f,它是函数关系的本质特征。它满足面向对象原则,可以设置不同开放级别,本地与远程智能切换。 元数据注册表:它以模块为单位的安装记录,在模块安装时,相关的元数据都会在元数据注册表中记录。 二:元数据的产生方式,既可以通过代码注解扫描获取,也可以通过可视化编辑器直接添加。 从代码注解中扫描获取,示例如下代码(如下图2-4所示)。 @Model.model(ResourceBank.MODEL_MODEL) @Model(displayName = "银行",labelFields = "name") public class ResourceBank extends IdModel { public static final String MODEL_MODEL = "resource.ResourceBank"; @Field.String @Field(required = true, displayName = "名称") private String name; @Field.String @Field(required = true, displayName = "银行识别号码", summary = "Bank Identifier Code, BIC 或者 Swift") private String bicCode; …… } 图2-4 从代码注解中扫描获取元数据 可视化的编辑器添加元数据,具体介绍详见7.1《Oinone的设计器》章节 三:Oinone是一种通用低代码开发平台,其元数据设计满足应用开发所需的所有元素,并支持所有研发范式。 它基于元数据的具体实现秉承以下原则: 部署与研发无关; 以模型驱动,符合面向对象设计原则; 代码与数据相互融合,编辑器产生的元数据以面向对象的方式继承扩展标准产品的元数据。 这些原则的集合使整个平台能够实现以下功能特性: 开发分布式应用与单体应用一样简单,部署方式由后期决定。如果要部署为分布式应用,则需要在boot工程中引入Oinone的rpc包。详见4.3《Oinone的分布式体验》一章节; 面向对象的特性使得每个需求都可以是独立模块,独立安装与卸载,让系统像乐高积木一样搭建; 支持两种元数据产生方式,融合的原则确保标准产品迭代与个性化保持独立,真正做到低无一体。 四:这些特性刚好也解决了2.2《互联网架构作为最佳实践为何失效》一章节中客户挑战的三个刺眼问题 互联网架构落地企业数字化转型面临的问题 Oinone应对的策略 不是说敏捷响应吗?为什么改个需求这么慢,不单时间更长,付出的成本也更高了? 特性1、特性2、特性3 不是说能力中心吗?当引入新供应商或有新场景开发的时候,为什么前期做的能力中心不能支撑了? 特性2、特性3 不是说性能好吗?为什么我投入的物理资源更多了? 特性1 表2-2互联网架构落地企业数字化转型面临的问题及Oinone应对策略

    2024年5月23日
    1.0K00
  • 4.5 研发辅助

    这里都是一些提升研发效率的小工具

    Oinone 7天入门到精通 2024年5月23日
    1.2K00
  • 接口日志

    记录每个PAPI接口执行日志,接口的响应结果、执行时间、执行时长等信息,可查看接口详情。 接口详情

    2023年5月23日
    1.1K00

Leave a Reply

登录后才能评论