3.5.7.1 基础概念

模块(module)

概念

在 Oinone 系统的架构中,模块(module)是核心组成元素之一,可以被理解为域(domain)的一个具象化概念。模块的来源有两种:一种是基于后端代码定义,另一种是通过无代码新增。具体的代码定义方式,请参考“[占位符]”,而无代码定义的相关信息则可在“[占位符]”找到。在 Oinone 体系中,模块对应两种实体:模块和应用。

  • 模块: 这是一类特定能力的集合,它可以依赖其他模块,也可以被其他模块依赖。
  • 应用: 它是一种特殊的模块,具备模块的所有特性,并在此基础上可被终端用户访问。

使用

在前端开发中,module通常以应用的形式出现,它们往往对前端用户保持透明。在接下来的讨论中,我们主要围绕应用来探讨module的使用。从应用的角度出发,我们可以在前端开发中识别出以下几种典型使用场景,并通过具体的业务案例来加以说明

  • 应用菜单扩展: 实现自定义母版来定义特定应用的菜单
  • 表格布局扩展: 用于自定义布局的工具,以定义特定应用的表格布局

在这些场景中,我们着重实现了应用层面的隔离,确保每个模块都能在应用的维度上独立运作

查找

在实际业务开发中,有3个方式可以找到应用

  • 浏览器url查找(查找速度快,可能不准)

image.png

图3-5-7-1 浏览器url查找模块(module)

  • 接口返回查找

第一步找到截图类似请求

image.png

图3-5-7-2 接口找到viewActionQuery

第二步根据返回找应用

image.png

图3-5-7-3 接口返回查找模块(module)

  • vue调试器选中对应的组件查找

image.png

图3-5-7-4 vue调试器查找模块(module)

推荐使用浏览器url查找,若与预期不符,可用另外两种方式查找

模型(model)

概念

在 Oinone 系统的架构中,模型(model)是另一个关键核心组成部分。模型在业务层面主要体现之一为数据库的实体表,它是承载业务实现的基础结构。要了解模型的详细介绍,请参考“[占位符]”,前端所用的模型,对应后端代码定义来说,代表的是模型的编码。

关于模型的定义,我们提供了两种方法:

  • 代码定义: 对于需要通过编程实现的模型定义,您可以参考“[占位符]”来了解具体的代码实现方法;
  • 无代码定义:如果您倾向于使用无代码工具来定义模型,具体的操作和流程可以在“[占位符]”中找到

使用

在前端开发中,模型是前端运行的必要条件,以下场景中,模型不直接感知:

  • 视图渲染
  • 页面之间跳转交互
  • 与后端交互

以下场景中,模型会直接决定前端的渲染逻辑

  • 母版扩展:为某模型扩展母版
  • 布局扩展:为某模型扩展布局
  • 页面扩展:为某模型扩展个性化页面
  • 字段扩展: 扩展字段时加上模型的范围
  • 动作扩展: 扩展动作时加上模型的范围

以上场景中,涵盖了前端工作的方方面面,在OInone体系中,模型不止是后端运行得基础,同样也决定了前端如何运行,那这样做有什么好处呢?

  • 前后端几乎不需要联调,联调的协议用模型来承载
  • 前端无需定义路由、权限埋点

查找

在实际业务开发中,有3个方式可以找到模型

  • 浏览器url查找

image.png

图3-5-7-5 浏览器url查找模型(model)

  • 接口返回查找

第一步找到类似截图请求

image.png

图3-5-7-6 接口找到viewActionQuery

第二步根据返回找模型

image.png

图3-5-7-7 接口找到viewActionQuery

  • vue调试器选中对应的组件查找

image.png

图3-5-7-8 vue调试器查找模型(model)

动作(action)

概念

动作(action)定义了终端用户得交互,它描述了前端与前端、前端与后端之间的交互。

动作涵盖了前端以下部分:

  • 页面跳转(router)
  • 调用后端接口
  • 页内交互(打开弹窗、打开抽屉)

它有两部分的来源:

  • 模型内定义动作
  • 窗口动作(页面跳转、打开弹窗、打开抽屉)
  • 服务器动作(调接口)
  • 前端定义客户端动作,可自定义其它逻辑,例如: 把选中行的某一列数据复制一下

使用

动作的使用绝大部分的情况是由平台自动执行的,在平台执行不符合预期时可以使用自定义动作自行扩展

查找

  • vue调试器选中对应的组件查找
  • 选中服务器动作(ServerAction)

image.png

图3-5-7-9 vue调试器查找服务器动作(ServerAction)

  • 选中窗口动作(ViewAction)

image.png

图3-5-7-10 vue调试器查找窗口动作(ViewAction)

字段(field)

概念

在我们的后端模型中,字段(Field)是核心的定义元素,它们在数据库中表现为数据表的列。更重要的是,这些字段在前端应用中发挥着数据传输的关键作用。例如,当前端需要调用后端接口时,它会发送如下结构的数据:

图3-5-7-11 name字段数据举例

这里的 "name" 是一个字段实例,它连接了前后端的交互。在后端,该字段不仅用于数据存储,也参与逻辑运算。

字段在 Oinone 系统中的加强应用

在 Oinone 系统中,字段的功能得到了扩展。除了基本的前后端数据交互,字段的定义还直接影响前端的用户界面(UI)交互。例如:

  1. 前端交互组件的选择:前端交互组件的类型取决于字段的数据类型。对于 String 类型的 "name" 字段,前端会使用输入框来收集用户输入的 "张三"。

  2. 数据存储和类型定义:在后端,"name" 字段被明确定义为 String 类型,这决定了它如何存储和处理数据。

字段与前端组件定义的解耦

一个关键的设计原则是,前端组件的定义与具体的字段值或字段名(如 "name" 或 "张三")不直接相关,而是基于字段的数据类型(此例中为 String)。这种设计实现了:

  • 前端组件的一致性:确保所有组件的输入输出遵循同一数据类型(如 String)。
  • 高度的组件复用性:在满足 UI 要求的前提下,任何 String 类型的字段都可以使用这种通用的组件设计。

使用

Oinone 系统中的视图与字段交互的灵活性

Oinone 系统为每种视图和字段类型(Ttype)提供了默认的交互模式。这不仅保证了前端工程启动时所有界面的即时展示,也为开发者带来了高度的灵活性和扩展能力。以下是这一设计理念的关键点:

1. 视图与字段交互的默认实现

每种视图都有对应字段类型(Ttype)的默认交互实现,确保用户界面一致且直观。这使得在前端工程启动时,所有界面能够无需额外配置即可正常展示。

2. 灵活性与扩展能力

尽管系统提供了默认的交互方式,开发者仍然拥有自定义这些交互方式的能力。这意味着开发者可以根据应用需求,设计更加贴合业务逻辑和用户体验的交互模式。

3. 覆盖和替换默认组件

最为重要的是,开发者不仅可以添加新的交互方式,还可以完全覆盖和替换系统的默认组件。这提供了极大的自由度,使开发者能够根据具体场景重新设计和实现界面组件,从而达到完全定制化的用户体验。

查找

  • vue调试器选中对应的组件查找

image.png

图3-5-7-12 vue调试器查找字段(field)

视图类型(viewType)

概念

在 Oinone 系统中,视图是模型在前端的具体表现形式。视图的核心组成和功能如下:

1. 组成要素

  • 字段:视图中的字段代表了模型的数据结构,它们是界面上数据显示和交互的基础。
  • 动作:视图包含的动作定义了用户可以进行的操作,如添加、编辑、删除等。
  • 前端UI:视图的界面设计,包括布局、元素样式等,决定了用户的交互体验。

2. 数据源与交互

  • 数据源:视图的数据直接来源于后端模型。这意味着前端视图展示的内容是根据后端模型中定义的数据结构动态生成的。
  • 交互:视图不仅展示数据,还提供与数据交互的能力。这些交互也是基于后端模型定义的,包括数据的增删改查等操作。

3. 灵活性

  • 视图可以灵活选择是否采用模型的交互。这意味着开发者可以根据需求决定视图仅展示模型的数据,或者同时提供与数据的交互功能。

使用

在 Oinone 系统中,用户可以通过无代码界面设计器轻松配置视图。系统内置了以下主要视图类型:

  1. 表格(Table)

  2. 表单(Form)

  3. 详情(Detail)

  4. 搜索(Search)

  5. 画廊(Gallery)

  6. 树(Tree)

界面设计器配置

  • 简便配置:系统提供无代码界面设计器,使用户能够轻松配置内置视图。
  • 系统支持视图:表格、表单、详情等内置视图类型可以直接通过设计器进行配置,包括字段的展示和交互。

自定义页面

  • 个性化需求:如果用户需求超出系统内置视图的范围,可以选择创建自定义页面。
  • 高级专家认证:高级专家认证的用户,理解透前端元数据,可以将自定义页面转化为内置视图之一。
  • 与无代码结合:高级专家认证用户可以结合无代码界面设计器,将个性化的页面与系统内置视图深度融合。

通过这种深度的整合和自定义的能力,系统提供了更灵活、更个性化的前端界面配置和设计体验。

查找

  • 浏览器url查找

image.png

图3-5-7-13 浏览器url查找视图类型(viewType)

-vue调试器查找

image.png

图3-5-7-14 vue调试器查找视图类型(viewType)

-代码查找

-找到如下代码,点击后看所有类型的定义

image.png

图3-5-7-15 SPI中找到注册的视图类型(viewType)

image.png

图3-5-7-16 点击查看所有视图类型(viewType)定义

字段类型(ttype)

概念

在 Oinone 系统中,每个字段的数据类型都与后端的 ttype(类型)一一对应。这意味着每个前端字段类型都有其对应的后端数据类型。开发者可以根据这些 ttype 定义某类类型的组件,以便在前端实现对应类型的数据展示和交互

使用

在 Oinone 系统中,字段类型的前后端协议已经枚举了所有存在的业务类型,满足了多样化的业务场景需求。这些字段类型在前端是只读的,前端开发者只能查看,而不能定义和变更。

内置字段类型包括:

  1. 字符串(String)

  2. 文本(Text)

  3. HTML

  4. 电话号码(Phone)

  5. 电子邮件(Email)

  6. 整数(Integer)

  7. 长整数(Long)

  8. 浮点数(Float)

  9. 货币(Currency)

  10. 日期时间(DateTime)

  11. 日期(Date)

  12. 时间(Time)

  13. 年份(Year)

  14. 布尔(Boolean)

  15. 枚举(Enum)

  16. 映射(Map)

  17. 关联(Related)

  18. 一对一(OneToOne)

  19. 一对多(OneToMany)

  20. 多对一(ManyToOne)

  21. 多对多(ManyToMany)

  22. 对象(Object)

这些内置字段类型涵盖了多种业务场景,同时在前端上的只读特性确保了数据类型的一致性和稳定性。

查找

  • 每一个字段必然有ttype,选中字段查看对应的ttype

image.png

图3-5-7-17 vue调试器查找字段ttype

部件(widget)

概念

在 Oinone 系统中,widget 是字段组件的另一个筛选条件,可以被理解为组件的别名。当字段没有指定别名时,该组件将覆盖所有符合 ttype 和 viewType 条件的组件。widget 适用于在特定页面中定义组件的出现,提供了更灵活的定制能力。

使用

使用场景:

  1. 组件别名:widget 可以被视为字段组件的别名,用于在配置中标识和引用特定的组件。

  2. 条件筛选:通过 widget,可以在部分页面中定义组件的出现,而不影响其他页面的配置。

注意事项:

  • 默认覆盖:当字段未指定 widget 时,该组件将覆盖所有符合 ttype 和 viewType 条件的组件。

  • 页面定制:使用 widget,开发者可以更精细地定制组件在不同页面中的呈现方式。

通过合理使用 widget,系统提供了更加灵活和个性化的组件配置方式,使得不同页面可以呈现不同的组件。

查找

在 Oinone 系统中,用户可以选择查看当前字段对应的 widget。这个操作并非必选项,若未选择,系统将使用默认的字段渲染方式。然而,若用户选择了 widget,它必须与当前字段相同,以确保正确覆盖当前字段的渲染方式。

操作步骤:

  1. 选中字段:在字段配置界面,用户可以选择特定字段进行配置。

  2. 查看 Widget:用户可以查看当前字段对应的 widget,以了解当前字段的渲染方式。

  3. 非必选项:查看当前字段的 widget 是一个非必选项,用户可以选择使用默认的字段渲染方式。

  4. Widget 一致性:如果用户选择了 widget,确保它与当前字段相同,以便正确覆盖当前字段的渲染方式。

通过这种设计,系统提供了灵活的字段配置选项,同时保证了渲染方式的一致性和准确性。

image.png

图3-5-7-18 vue调试器查找部件(widget)

多值(multi)

概念

在 Oinone 系统中,multi 是字段的一个扩充选项,主要解决普通数据类型字段存储多个值的情况。举例来说,如果某个字段定义为 String 类型,后端存储的是单个图片的地址,而需要上传多张图片时,后端需要将该字段定义为 List<String> 类型。在前端,multi 允许将普通数据类型的 String 转换为 Array<String> 进行传输。

使用

在 Oinone 系统中,前端使用时需要在字段注册上标记 multi。这个标记的取值(true 或 false)并非由前端决定,而是由后端在定义字段时确定的。前端只具有查看权限,无法变更这个标记。

操作步骤:

  1. multi 标记:multi 标记表示该字段是否支持存储多个值,由后端在字段定义时决定,缺省时默认为false。

  2. 前端权限:前端只有查看权限,不能在字段注册时变更 multi标记的取值。

查找

  • 每一个字段必然有multi,选中字段查看对应的multi,若没有声明,默认为false

image.png

图3-5-7-19 vue调试器查找多值(multi)

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

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

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

相关推荐

  • 5.1 CDM的背景介绍

    如果说低代码开发框架输出技术标准,CDM则是结合oinone技术特性和软件工程设计,让输出数据标准变成可能。 一、背景介绍 无法照搬的最佳实践 要了解引入CDM的初衷,得从互联网架构的演进开始,了解其过程,就知道为什么说Oinone的CDM是中台架构的最佳技术实践的核心!我们在2.2【互联架构做为最佳实践为何失效】一文中介绍过互联网技术发展的四个阶段,特别平台化到中台化的阶段,目的是在一套规范下让听的见炮火声音的团队自行决定业务系统发展,适用多业务线(或多场景应用)独立发展。 互联网架构在演进过程中碰到的问题跟企业数字化转型过程中碰到的问题是非常类似: 随着企业业务在线化后对系统性能、稳定都提出了更高的要求,而且大部分企业的内部很多系统相互割裂导致,导致很多重复建设,所以我们需要服务化、平台化。 同时没有一个供应商能解决企业所有商业场景问题,又需要多个供应商共同参与,所以把供应商类类比成各个业务线,在一套规范下让供应商自行决定业务系统发展 既然跟阿里当初在架构演进过程中碰到的问题非常类似,那么是不是照搬阿里中台架构方案到企业就好了?当然不是,因为历史原因阿里的中台架构是采用的平台共建模式:“让业务线研发以平台设计好的规范进来共同开发”,其本质还是平台主导模式,它是有非常大的历史包袱。我们想象各个供应商的共建一个交易平台或商品平台,那是多么荒唐的事情,平台化已经足够的复杂了,还让不同背景、不同企业的研发一起共建,最后往往导致企业架构负载过重,这时对企业来说便不再是赋能而是“内耗”。 那么如果没有历史包袱,我们重新设计,站在上帝视角去看有没有更好的方式呢?当然有 借鉴微软的CDM 这里我们借鉴微软的CDM理念,CDM这个概念最早是2016年微软宣布“以Dynamics 365的形式改造其CRM和ERP”战略时提出的。微软给它的定义是“用于存储和管理业务实体的业务数据库,而且是开箱即用的”。CDM不仅仅提供标准实体,它还允许用户建立个性化的实体,用户可以扩展标准实体也可以增加和标准实体相关的新实体。 CDM可能并不性感,但绝对是非常必要的。它成为了微软的很多产品的基础,是构建了无数业务领域的原型。同时微软也期望它能成为快速实现数据交换和迁移的标准,这个有点像菜鸟网络推出的奇门,让所有TMS、OMS、WMS都基于一套数据接口API进行互通,一套标准是为了解决一个行业问题,而不是具体某一个企业一个集团的问题。 我们发现CDM的理念跟我们想要的“企业级的数据标准”是非常吻合的。但是我们也不能照搬照抄,虽然微软的CDM很好的解决了数据割裂问题,但就模型来说就够大家喝一壶了,模型库非常庞大而且复杂,学习成本巨高。 数字化时代软件会产生新的技术流派 我们知道传统软件的设计理念:侧重在模型对业务支撑全面性上。优点体现为配置丰富,缺点模型设计过于复杂,刚开始有前瞻性,但在理解、维护都非常困难,随着业务发展系统原先的设计逐渐腐化,异常笨重。 而Oinone的CDM设计理念:侧重在简单、灵活、统一上,体现为在上层应用开发时,每一业务领域保持独立,模型简单易懂,并结合Oinone的低代码开发机制进行快速开发,灵活应对业务变化。 所以我更想说Oinone的CDM是微软CDM的在原有基础上,与互联网架构结合,利用Oinone低代码开发平台特性形成新的工程化建议。Oinone-CDM不以把模型抽象到极致,支撑“所有业务可能性”为目标,而是抽象80%通用的设计,保持模型简单可复用,来解决数据割裂问题,并保持业务线独立自主性,快速创新的能力。 图5-1-1 Oinone-CDM要解决的问题 二、Oinone的CDM本质是创新的工程化建议 引入CDM以后系统工程结构会有什么变化,跟大家认知的互联网架构有什么区别。 原本上层的业务线系统,需要调用各个业务平台提供的功能,增加CDM以后也就是我们右的图,每个业务线就像一个独立右边。看上去复杂了,其实对业务线来说更加简单了。 互联网整体平台化带来的问题: 业务线每次业务调整都需要给各个平台提需求 业务平台研发需要了解所有业务线的知识再做设计,对研发要求非常高 各个业务域的不同需求相互影响包括系统稳定性、研发对需求响应的及时性 结合oinone特性提出的新工程建议: 一些通用性模块继续以平台化的方式存在,能力完全复用。 业务线自建业务平台,保持业务线的独立性和敏捷性 业务线以CDM为原型,保证核心数据不割裂,形成一致的数据规范 图5-1-2 引入CDM概念后的工程结构对比 三、CDM思路示意图 该示例中OinoneCDM的商品域不仅仅提供标准实体,保证各个业务系统的对商品的通用需求、简单易懂,在我们星空系列业务产品中如全渠道运营、B2B交易等系统以此为基础建立属于自身个性化的实体,可以扩展标准实体也可以增加和标准实体相关的新实体。 带来的好处: 通过多种继承方式,继承后的模型可扩展模型本身、模型行为等,从而解决业务独立性问题。 通过CDM层统一数据模型,从而解决多应用数据割裂问题 图5-1-3 Oinone-CDM思路示意图

    2024年5月23日
    1.4K00
  • 3.5.5.1 设计器数据导出

    简介 通过调用导出接口,将设计器的设计数据与运动数据打包导出到文件中。 提供了download/export两类接口。 export 导出到OSS。导出的文件会上传到文件服务,通过返回的url下载导出文件。 请求示例: mutation { uiDesignerExportReqMutation { export( data: { module: "gemini_core", fileName: "meta", moduleBasics: true } ) { jsonUrl } } } 响应示例: { "data": { "uiDesignerExportReqMutation": { "export": { "jsonUrl": "https://xxx/meta.json" } } }, "errors": [], "extensions": {} } download 直接返回导出数据。适用于通过浏览器直接下载文件。 请求示例: mutation { uiDesignerExportReqMutation { download( data: { module: "gemini_core", fileName: "meta", moduleBasics: true } ) { jsonUrl } } } 如何构造url protocol :// hostname[:port] / path ? query=URLEncode(GraphQL) 例: http://127.0.0.1:8080/pamirs/base?query=mutation%20%7B%0A%09uiDesignerExportReqMutation%20%7B%0A%09%09download(%0A%09%09%09data%3A%20%7B%20module%3A%20%22gemini_core%22%2C%20fileName%3A%20%22meta%22%2C%20moduleBasics%3A%20true%20%7D%0A%09%09)%20%7B%0A%09%09%09jsonUrl%0A%09%09%7D%0A%09%7D%0A%7D 在浏览器中访问构造后的url,可直接下载文件 接口列表 模型设计器 指定模块导出 query { modelMetaDataExporterQuery { export/download(query: { module: "模块编码" }) { module url } } } module参数:指定导出的模块编码 url返回结果:export方式导出的文件url 页面设计器 导出页面 指定模块导出 mmutation { uiDesignerExportReqMutation { download/export( data: { module: "gemini_core", fileName: "meta", moduleBasics: false } ) { jsonUrl } } } module参数:模块编码 fileName参数:指定生成的json文件名称 moduleBasics参数:指定是否只导出模块基础数据,如果为true,只导出内置布局、模块菜单、菜单关联的动作。 如果为false,还会导出模块内的所有页面,以及页面关联的动作元数据、页面设计数据 等等。 默认值为false。 指定菜单导出 mutation { uiDesignerExportReqMutation { download/export( data: { menu: { name: "uiMenu0000000000048001" } fileName: "meta" relationViews: true } ) { jsonUrl } } } menu参数:菜单对象,指定菜单的name。只会导出该菜单及其绑定页面,不会递归查询子菜单 fileName参数:指定生成的json文件名称 relationViews参数:指定是否导出关联页面,默认为false,只导出菜单关联的页面。如果为true,还会导出该页面通过跳转动作关联的自定义页面。 指定页面导出 mutation { uiDesignerExportReqMutation { download/export( data: { view: { name: "xx_TABLE_0000000000119001" model: "ui.designer.TestUiDesigner" } fileName: "meta" relationViews: true } ) { jsonUrl } } }…

    Oinone 7天入门到精通 2024年5月23日
    2.1K00
  • 3.6 问题排查工具

    当前端发起对应用的访问时,如果出现错误,那么我们可以通过以下方式进行简易排查,如果排查不出来,则也可以把排查工具给出的信息发送给Oinone官方售后进行进一步分析。本文将通过模拟异常信息,来介绍排查工具,提供了哪些辅助信息帮我们来快速定位问题。 排查工具基础介绍 通过前端页面的 /debug 路由路径访问调试工具的页面,假设我们的前端页面访问地址为http://localhost:6800,那么我们的排查工具请求路径就是 http://localhost:6800/debug排查工具可以帮我们排查前端页面元数据异常和后端接口的异常 排查前端页面元数据 将问题页面浏览器地址栏内 page 后的部分复制到调试工具的 debug 路由后重新发起请求,如图可以看到调试工具展示的信息,可以根据这些信息排查问题。 排查后端接口 后端接口出现问题后,打开(在原页面)浏览器的调试工具,切换到“网络”的标签页,在左侧的历史请求列表中找到需要调试的请求,右键会弹出菜单,点击菜单中的 “复制”,再次展开该菜单,点击二级菜单中的“以 fetch 格式复制”,这样可以复制到调试所需要的信息 2.复制调试信息到“接口调试”标签页内的文本框内,点击“发起请求”按钮获取调试结果 我们可以看到页面展示了该接口的各种调试信息,我们可以据此排查问题。 场景化的排查思路 业务代码中存在代码bug 报错后发起调试请求,我们可以看到,调试工具直接给出了异常抛出的具体代码所在位置,此时再切换到“全部堆栈”下,可以看到是业务类的233行导致的空指针异常,查看代码后分析可得是data.getName().eqauls方法在调用前未做条件判断补全该判断后代码可以正常执行 业务代码中没有直接的错误,异常在平台代码中抛出 报错后发起调试请求可以看到异常不在业务代码内再切换到“全部堆栈”,可以看到具体异常信息,提示core_demo_item表出现了重复的主键,该表是DemoItem模型的我们还可以切换到“sql调试”的标签页,可以看到出错的具体sql语句经过分析可以得知是240行的data.create()�重复创建数据导致的。 三、排查工具无法定位怎么办 当我们通过排查工具还是没有定位到问题的时候,可以通过调试页面的“下载全部调试数据”和“下载调试数据”按钮将调试信息的数据发送给官方售后人员帮助我们定位排查问题。 点击页面最顶部的“下载全部调试数据”按钮,可以下载页面调试数据和接口调试数据点击“调试接口”标签页内的“下载调试数据”按钮,可以下载接口调试数据 四、排查工具细节

    2024年5月23日
    2.5K00
  • 流程

    1. 流程介绍 日常工作和生活中到处都存在各种各样的流程,例如业务开展中的产品研发流程、产品制作流程、订单发货流程等,也有管控分险的费用报销流程、员工请假审批流程、项目立项流程等。流程设计器可以帮助公司实现流程的数字化,规范流程操作,减少人工操作并留存痕迹,提高工作效率和安全性。 2. 流程的组成 流程设计器主要包含基本操作和流程设计两个部分。前者包含了流程的新增、删除、复制、停用/启用、编辑、搜索。后者包含单一流程的基础信息修改、流程设计、参数配置、保存、发布。 2.1 流程的基本操作 流程页面有两种显示方式,默认为平铺显示的模式,可以点击切换为列表详情显示的模式。 2.1.1 新增 平铺显示和列表详情模式下点击左上角的创建按钮即可新增一个流程,点击后进入流程设计页面,流程名默认为“未命名流程”,可自行修改。 2.1.2 删除 遇到流程创建有误,没有使用过且将来也不会使用该流程,可以删除流程。需要注意的是,删除流程的前提是该流程已停用,并且该流程从未执行过。 2.1.3 复制 遇到流程节点动作相似度较高的情况可以使用复制流程的功能,点击按钮后生成一个“原流程名-复制”的流程,并且进入新流程的流程设计界面。 2.1.4 停用/启用 流程需要更新或暂时不用时可以使用停用功能。流程停用后将不会执行流程中的动作,正在执行中的流程不受停用影响,会正常执行直到流程结束。 点击启用按钮,流程恢复启用状态,可正常触发。 2.1.5 编辑 点击编辑进入该流程的设计页面。 2.1.6 搜索 页面最上方的是搜索区,可以按照流程名称、触发方式、启用状态、更新状态进行筛选搜素,点击重置按钮修改搜索条件。

    2024年1月20日
    2.4K00
  • 3.3.4 模型的继承

    在我们的很多项目中,客户都是有个性化需求的,就像我们不能找到两件一模一样的东西,何况是企业的经营与管理思路,多少都会有差异。常规的方式只能去修改标准产品的逻辑来适配客户的需求。导致后续标品维护非常困难。而在介绍完这节以后是不是让你更加清晰认知到我们2.4.2【oinone独特性之每一个需求都可以是一个模块】一文中所表达的特性带来的好处呢? 一、继承方式 继承方式可以分为五种: 抽象基类ABSTRACT,只保存不希望为每个子模型重复键入的信息的模型,抽象基类模型不生成数据表存储数据,只供其他模型继承模型可继承域使用,抽象基类可以继承抽象基类。 扩展继承EXTENDS,子模型与父模型的数据表相同,子模型继承父模型的字段与函数。存储模型之间的继承默认为扩展继承。 多表继承MULTI_TABLE,父模型不变,子模型获得父模型的可继承域生成新的模型;父子模型不同表,子模型会建立与父模型的一对一关联关系字段(而不是交叉表),使用主键关联,同时子模型会通过一对一关联关系引用父模型的所有字段。多表继承父模型需要使用@Model.MultiTable来标识,子模型需要使用@Model.MultiTableInherited来标识。 代理继承PROXY,为原始模型创建代理,可以增删改查代理模型的实体数据,就像使用原始(非代理)模型一样。不同之处在于代理继承并不关注更改字段,可以更改代理中的元信息、函数和动作,而无需更改原始内容。一个代理模型必须仅能继承一个非抽象模型类。一个代理模型可以继承任意数量的没有定义任何模型字段的抽象模型类。一个代理模型也可以继承任意数量继承相同父类的代理模型。 临时继承TRANSIENT,将父模型作为传输模型使用,并可以添加传输字段。 二、继承约束 通用约束 对于扩展继承,查询的时候,父模型只能查询到父模型字段的数据,子模型可以查询出父模型及子模型的字段数据(因为派生关系所以子模型复刻了一份父模型的字段到子模型中)。 系统不会为抽象基类创建实际的数据库表,它们也没有默认的数据管理器,不能被实例化也无法直接保存,它们就是用来被继承的。抽象基类完全就是用来保存子模型们共有的内容部分,达到重用的目的。当它们被继承时,它们的字段会全部复制到子模型中。 系统不支持非jar包依赖模型的继承。 多表继承具有阻断效应,子模型无法继承多表继承父模型的存储父模型的字段,需要使用@Model.Advanced注解的inherited属性显示声明继承父模型的父模型。但是可以继承多表继承父模型的抽象父模型的字段。 可以使用@Model.Advanced的unInheritedFields和unInheritedFunctions属性设置不从父类继承的字段和函数。 跨模块继承约束 如果模型间的继承是跨模块继承,应该与模型所属模块建立依赖关系;如果模块间有互斥关系,则不允许建立模块依赖关系,同理模型间也不允许存在继承关系。 跨模块代理继承,对代理模型的非inJvm函数调用将使用远程调用方式;跨模块扩展(同表)继承将使用本地调用方式,如果是数据管理器函数,将直连数据源。 模型类型与继承约束 抽象模型可继承:抽象模型(Abstract) 临时模型可继承:抽象模型(Abstract)、传输模型(Transient) 存储模型可继承:抽象模型(Abstract)、存储模型(Store)、存储模型(多表,Multi-table Store),不可继承多个Store或Multi-table Store 多表存储模型(父)可继承:同扩展继承 多表存储模型(子)在继承单个Multi-table Store后可继承:抽象模型(Abstract)、存储模型(Store),不可继承多个Store 代理模型可继承: 抽象模型(Abstract),须搭配继承Store、Multi-table Store或Proxy 存储模型(Store),不可继承多个Store或Multi-table Store 存储模型(多表,Multi-table Store),不可继承多个Store或Multi-table Store 代理模型(Proxy),可继承多个Proxy,但多个父Proxy须继承自同一个Store或Multi-table Store,且不能再继承其他Store或Multi-table Store 同名字段以模型自身字段为有效配置,若模型自身不存在该字段,继承字段以第一个加载的字段为有效配置,所以在多重继承的情况下,未避免继承同名父模型字段的不确定性,在自身模型配置同名字段来确定生效配置。 三、继承的使用场景 模型的继承可以继承父模型的元信息、字段、数据管理器和函数 抽象基类 解决公用字段问题 扩展继承 解决开放封闭原则、跨模块扩展等问题 多表继承 解决多型派生类字段差异问题和前端多存储模型组合外观问题 代理继承 解决同一模型在不同场景下的多态问题(一表多态) 临时继承 解决使用现有模型进行数据传输问题 举例,前端多存储模型组合外观问题可通过多表继承的子模型,并一对一关联到关联模型,同时使用排除继承字段去掉不需要继承的字段。子模型通过默认模型管理器提供查询功能给前端,默认查询会查询子模型数据列表并在列表行内根据一对一关系查出关联模型数据合并,关联模型数据展现形态在行内是平铺还是折叠,在详情是分组还是选项卡可以自定义view进行配置 扩展继承 父子同表,模型在所有场景都有一致化的表现,意味着原模型被扩展成了新模型,父子模型的表名一致,模型编码不同,可覆盖父模型的模型管理器、数据排序规则、函数 多表继承 父子多表,父子间有隐式一对一关系,即父子模型都增加了一对一关联关系字段,同时父模型的字段被引用到子模型,且引用字段为只读字段,意味着子模型不可以直接更改父模型的字段值,子模型不继承父模型的模型管理器、数据排序规则、函数,子模型拥有自己的默认模型管理器、数据排序规则、函数。多表继承具有阻断效应,子模型无法自动多表继承父模型的存储父模型,需要显式声明多表继承父模型的存储父模型。 代理继承 代理模型继承并可覆盖父模型的模型管理器、数据排序规则、函数,同时可以使用排除继承字段和函数来达到不同场景不同视觉交互的效果。 图3-3-4-1 继承的使用场景 四、抽象基类(举例) 参考前文中3.3.2【模型的类型】一文中关于抽象模型的介绍 五、多表继承(举例) 场景设计如下 图3-3-4-2 多表继承设计场景 Step1 新建宠物品种、宠狗品种和萌猫品种模型 新建宠物品种模型,用@Model.MultiTable(typeField = "kind"),申明为可多表继承父类,typeField指定为kind字段 package pro.shushi.pamirs.demo.api.model; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.base.IdModel; @Model.MultiTable(typeField = "kind") @Model.model(PetType.MODEL_MODEL) @Model(displayName="品种",labelFields = {"name"}) public class PetType extends IdModel { public static final String MODEL_MODEL="demo.PetType"; @Field(displayName = "品种名") private String name; @Field(displayName = "宠物分类") private String kind; } 图3-3-4-3 多表继承示例代码 新建宠狗品种模型,用@Model.MultiTableInherited(type = PetDogType.KIND_DOG),申明以多表继承模式继承PetType,覆盖kind字段(用defaultValue设置默认值,用invisible = true设置为前端不展示),更多模块元数据以及模型字段元数据配置详见4.1.6【模型之元数据详解】一文 package pro.shushi.pamirs.demo.api.model; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; @Model.MultiTableInherited(type = PetDogType.KIND_DOG) @Model.model(PetDogType.MODEL_MODEL) @Model(displayName="宠狗品种",labelFields = {"name"}) public class PetDogType extends PetType { public static final String MODEL_MODEL="demo.PetDogType"; public static final String KIND_DOG="DOG"; @Field(displayName = "宠物分类",defaultValue = PetDogType.KIND_DOG,invisible = true) private String kind; } 图3-3-4-4 多表继承示例代码 新建萌猫品种模型,用@Model.MultiTableInherited(type = PetCatType.KIND_CAT),申明以多表继承模式继承PetType,覆盖kind字段(用defaultValue设置默认值,用invisible = true设置为前端不展示),并新增一个CatShapeEnum枚举类型的字段shape package pro.shushi.pamirs.demo.api.enumeration; import pro.shushi.pamirs.meta.annotation.Dict; import pro.shushi.pamirs.meta.common.enmu.BaseEnum; @Dict(dictionary = CatShapeEnum.DICTIONARY,displayName = "萌猫体型") public class CatShapeEnum extends BaseEnum<CatShapeEnum,Integer>…

    2024年5月23日
    1.9K00

Leave a Reply

Please Login to Comment