2.1 数字化时代软件业的另一个本质变化

随着企业从信息化向数字化转变,软件公司提供的产品也由传统的企业管理软件向企业商业支撑软件发展。这一变化带来了许多技术上的挑战和机遇。在之前的章节中,我们提到企业的视角已经从内部管理转向业务在线和生态在线协同,这也带来了一系列新的需求。但是,我们常常会忽视这一变化所带来的对系统要求的变化。在本章中,我们将探讨这些技术上的变化,以及这些变化所带来的机遇和挑战。

image.png

图2-1 从信息化到数字化软件本质变化

在信息化时代,企业的业务围绕着内部管理效率展开,借鉴国外优秀的管理经验,企业将其管理流程固化下来,典型的例子是ERP项目。这类项目上线后往往长期稳定,不轻易更改,因此信息化时代软件的技术流派侧重于通过模型对业务进行全面支持。例如,SAP具有丰富的配置能力,将已有企业管理思想抽象到极致。其功能基本上可以通过配置来实现,因此其模型设计特别复杂。但是,我们也应该清楚地了解到,配置是面向已知问题的。在数字化时代,创新和业务迭代速度非常快,这种方法可能就不太适合了。我们知道,模型抽象是在设计时具有前瞻性的,一旦不适合,修改起来就会异常困难。

随着数字化时代的到来,企业主的关注点已经从单一企业内部管理转变为了围绕企业上下游价值链的协同展开。这种变化给企业信息化系统提出了更高的要求,例如业务需求的响应速度、系统性能和用户体验等方面。现在,企业对软件不仅是管理需求的承载,更是业务在线化的承载。传统的重模型设计软件模式已经不再适用,因为业务本身不断创新和变化。因此,数字化时代需要新的软件技术流派,这种流派必须是轻模型加上低代码技术的结合体。通过模型抽象80%的通用场景,剩余的20%个性化需求可以通过技术手段来完成。这样的设计可以让每家企业的研发人员轻松理解模型,而不像ERP模型那样异常复杂,无法进行修改。此外,配合低代码技术可以快速研发和上线。如果说配置化是面向已知问题的,那么低代码就是面向未知问题设计的。虽然低代码的概念可以追溯到上个世纪80年代,当时是为了满足企业内部部门之间有协同需求,但又没有专业软件支撑,定制化开发又不划算的辅助场景。但现在它的核心原因是企业数字化的核心场景不稳定,变化很快,每家企业都有强烈的个性化需求。因此,低代码成为解决这些问题的核心手段,数字化时代的低代码需要具备处理复杂场景的能力,而不仅仅是围绕着内部管理展开。

企业在数字化转型的过程中需要考虑到不仅是成熟的全链路业务解决方案,还要应对数字化场景的快速变化和持续创新的需求。为此,Oinone打造了一站式低代码商业支撑平台,从业务与技术两个维度来帮助企业建立开放、链接、安全的数字化平台。这将在水平和垂直两个维度上全面推动企业数字化转型。

另外,低代码的另一个好处是完成了软件本身的数字化建设。通过基于元数据设计,元数据成为软件中数据、逻辑和交互的数据,软件结合AI可以有更多的创造可能。想象一下,AI了解软件的元数据后可以自我运作,人在极少情况下才需要参与,人机交互也会发生大的改变。未来的软件交互不再需要研发提前预设,而是能够实现用户所需即所呈现的效果。作为一家帮助企业进行数字化转型的软件公司,请问您的数字化转型是否已经完成呢?

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

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

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

相关推荐

  • 3.5.7.9 自定义多Tab

    在业务中,可能会遇到需要对多tab的交互或UI做全新设计的需求,这个时候可以自定义多tab组件支持。 首先继承平台的MultiTabsWidget组件,将自己vue文件设置到component处 import { MultiTabsWidget, SPI, ViewWidget } from '@kunlun/dependencies'; import Component from './CustomMultiTabs.vue'; @SPI.ClassFactory( ViewWidget.Token({ // 这里的tagName跟平台的组件一样,这样才能覆盖平台的组件 tagName: ['multi-tabs', 'MultiTabs'] }) ) export class CustomMultiTabsWidget extends MultiTabsWidget{ public initialize(props) { super.initialize(props); // 设置自定义的vue组件 this.setComponent(Component); return this; } } vue文件中继承平台的props,编写自定义页面代码 export const MultiTabsProps = { /** * 组件是否可见 */ invisible: { type: Boolean }, /** * tab列表数据 */ tabs: { type: Array as PropType<MultiTab[]> }, /** * 当前激活的tab */ activeTab: { type: Object as PropType<MultiTab> }, /** * 鼠标悬浮所在的tab */ hoverTab: { type: Object as PropType<MultiTab> }, /** * 鼠标经过tab事件回调 */ onMouseenterTab: { type: Function as PropType<(tab: MultiTab) => void> }, /** * 鼠标离开tab事件回调 */ onMouseleaveTab: { type: Function as PropType<(tab: MultiTab) => void> }, /** * 点击tab */ onClickTab: { type: Function as PropType<(tab: MultiTab) => void> }, /** * 刷新当前tab */ onRefreshCurrentTab: { type: Function as PropType<(tab: MultiTab) => void> }, /** * 关闭当前tab */ onCloseCurrentTab: { type: Function as PropType<(tab: MultiTab) => void> }, /** * 关闭除当前tab外的其他所有tab */ onCloseOtherTabs: { type: Function as PropType<(tab: MultiTab) => void> }, /** * 关闭当前tab左侧的所有tab */ onCloseLeftTabs: { type: Function as…

    2024年5月23日
    78100
  • 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日
    78800
  • 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日
    1.2K00
  • 数据大屏

    1. 业务场景 数据大屏是利用相应的系统来分析数据,通过图形的形式为企业提供客观、直接的数据分析结果,让业务人员和企业决策者直观面对数据背后的信息,实时监测企业数据,给予更直观的决策场景体验,助力企业数字化运营升级。 2. 操作流程 1)进入数据可视化,进入数据大屏tab,维护分组信息; 2)在二级分组名称后点击“+”【添加数据大屏】,对数据大屏进行设计; 3)创建完成后可以【编辑】数据大屏; 4)数据大屏完善后,可以点击【发布】数据大屏,则数据大屏此时可以被显示器引用播放; 5)如果数据大屏有更新,则可以点击【更新发布】; 6)如果数据大屏数据不再可以公开使用,则需要通过【隐藏】功能将数据大屏的引用权限收起,但不影响已被使用的数据大屏; 7)隐藏后可以【取消隐藏】,数据大屏恢复隐藏前的状态和功能,可以被引用 。 3. 操作流程图解 3.1 创建分组 1)操作流程:创建分组 2)操作路径:数据可视化-数据大屏-创建分组 3)点击搜索框后的「+」创建一级分组,输入一级分组名称后,点击一级分组后的「+」创建二级分组,输入二级分组名称后,此时分组创建完成,可以在二级分组下创建数据大屏 3.2 编辑分组名称 1)操作流程:选择分组-编辑分组名称 2)操作路径:数据可视化-数据大屏-编辑分组名称 3)鼠标移动至需要修改的分组上,点击出现的「编辑图标」,可以修改分组名称,修改后分组名称实时更新 3.3 删除分组 1)操作流程:选择分组-删除分组 2)操作路径:数据可视化-数据大屏-删除分组 3)鼠标移动至需要删除的分组上,当分组下无报表时出现「删除图标」,可以点击图标后删除分组,删除一级分组时对应所有的二级分组也会被删除,删除后消失,只有分组下没有数据大屏的分组才能直接删除成功 3.4 创建数据大屏 1)操作流程:选择二级分组-创建数据大屏 2)操作路径:数据可视化-数据大屏-二级分组-创建数据大屏 3)鼠标移动至需要创建数据大屏的二级分组上,出现「+」,点击图标后=需要填写数据大屏标题 a数据大屏标题:最大支持20个字,支持汉字、数字、大小写字母、-;同个一级分组下不允许重复; 4)输入标题后进入设计页面 3.5 编辑数据大屏 1)操作流程:选择数据大屏-编辑数据大屏 2)操作路径:数据可视化-数据大屏-二级分组-数据大屏-编辑数据大屏 3)只能编辑未发布或者已发布但没有被隐藏的数据大屏,且存在三种编辑情况 a. 第一种:点击数据大屏标题后的编辑图标,仅能编辑数据大屏标题; b. 第二种:点击数据大屏中的数据大屏标题、备注后的编辑图标,可以直接编辑数据大屏标题; c. 第三种:点击【编辑】按钮,进入数据大屏设计页面,带出已有的组件内容,编辑时的规则与创建时一致,编辑后可以点击保存进行更新,如果未保存直接返回,则编辑无效; 4)编辑后实时生效,数据大屏信息保持展示最新效果 3.6 删除数据大屏 1)操作流程:选择数据大屏-删除数据大屏 2)操作路径:数据可视化-数据大屏-二级分组-数据大屏-删除数据大屏 3)未发布或者已发布但没有被隐藏的数据大屏,并且没被引用,才展示数据大屏菜单名称后的删除图标 4)删除后数据大屏消失 3.7 复制 1)操作流程:选择数据大屏-复制数据大屏 2)操作路径:数据可视化-数据大屏-二级分组-数据大屏-复制数据大屏 3)点击【复制】按钮,复制成功,名称为copy of 原数据大屏标题,展示在原数据大屏分组的最后一个 3.8 发布 1)操作流程:选择数据大屏-发布数据大屏 2)操作路径:数据可视化-数据大屏-二级分组-数据大屏-发布 3)选择单个未发布且没有被隐藏的数据大屏,点击【发布】按钮,数据大屏状态变为已发布,展示最近发布时间; 4)如果数据大屏发布后有更新内容,会展示的更新类型:更新数据大屏信息/更新数据大屏内容 3.9 查看最近一次发布的版本 1)操作流程:选择数据大屏-查看最近一次发布的版本 2)操作路径:数据可视化-数据大屏-二级分组-数据大屏-更新发布数据大屏 3)当数据大屏发布后有更新,在最近发布时间左侧展示【查看】,在最近发布时间下展示更新的类型,点击查看可以查看最近发布的版本 3.10 更新发布 1)操作流程:选择数据大屏-更新发布数据大屏 2)操作路径:数据可视化-数据大屏-二级分组-数据大屏-更新发布数据大屏 3)选择单个已发布且没有被隐藏的数据大屏,并且该数据大屏在上次发布后有所更新,可以点击【更新发布】按钮,将最新的数据大屏内容发布至业务系统,业务系统引用的数据大屏为最新内容; 4)如果更新了内容,但未点击更新发布,则展示的仍是上次发布的数据大屏 3.11 隐藏 1)操作流程:选择数据大屏-隐藏数据大屏 2)操作路径:数据可视化-数据大屏-二级分组-数据大屏-隐藏数据大屏 3)数据大屏默认不隐藏,点击数据大屏左侧的是否隐藏可以切换 a. 未发布的数据大屏,较隐藏前,不可以操作【发布】,可以【取消隐藏】; b. 已发布的数据大屏,较隐藏前,只能操作【导出图片、导出excel、取消隐藏】; 4)隐藏后的数据大屏不可以被用于展示在其他大屏上,但不影响已经被引用的数据 3.12 取消隐藏 1)操作流程:选择数据大屏-取消隐藏数据大屏 2)操作路径:数据可视化-数据大屏-二级分组-数据大屏-取消隐藏数据大屏 3)隐藏后的数据大屏可以取消隐藏,切换是否隐藏=否,取消隐藏后,数据大屏恢复隐藏前的状态和功能,可以被引用 3.13 查看引用 1)流程:选择图表-查看被哪些报表/数据大屏/页面引用 2)操作路径:数据可视化-数据大屏-二级分组-数据大屏-更多-查看引用 3)选择具体的数据大屏,查看当前数据大屏被引用的所有信息 3.14 不允许别人编辑 1)流程:选择数据大屏-不允许别人编辑 2)操作路径:数据可视化-数据大屏-二级分组-数据大屏-更多-不允许别人编辑 3)选择自己创建的数据大屏,对数据大屏是否允许其他人编辑进行设置;如果设置为不允许,则其他人无法编辑数据大屏 3.15 不允许别人引用 1)流程:选择图表-更多-不允许别人引用 2)操作路径:数据可视化-数据大屏-二级分组-数据大屏-更多-不允许别人引用 3)选择自己创建的数据大屏,对数据大屏是否允许他人引用进行设置;如果设置为不允许,则其他人无法选择到 3.16 导出图片 1)操作流程:选择数据大屏-导出图片 2)操作路径:数据可视化-数据大屏-二级分组-数据大屏-导出图片 3)选择数据大屏后,点击【导出图片】按钮可以将当前数据大屏导出为图片 3.17 导出EXCEL 1)操作流程:选择数据大屏-导出EXCEL 2)操作路径:数据可视化-数据大屏-二级分组-数据大屏-数据大屏导出EXCEL 3)选择数据大屏后,点击【导出EXCEL】按钮可以将当前数据大屏包含的图表导出为EXCEL 4. 数据大屏设计页面 4.1 缩放自适应 1)流程:创建数据大屏-进入数据大屏设计页面 2)操作路径:数据可视化-数据大屏-创建/编辑-设计页面 3)进入页面后,默认按照当前屏幕展示最适合的数据大屏尺寸,可以通过+、-进行自定义缩放,每次缩放10% 4.2 全屏 1)流程:创建数据大屏-进入数据大屏设计页面 2)操作路径:数据可视化-数据大屏-创建/编辑-设计页面 3)进入页面后,设置完成,可以【全屏】查看效果,按esc退出全屏 4.3 保存 1) 流程:创建数据大屏-进入数据大屏设计页面 2) 操作路径:数据可视化-数据大屏-创建/编辑-设计页面 3) 进入页面后,设置完成后进行保存,数据大屏保持最新内容 4.4 添加、编辑、删除组件 1)流程:创建数据大屏-进入数据大屏设计页面 2)操作路径:数据可视化-数据大屏-创建/编辑-设计页面 3)可以添加图表、文本、通用标题、倒计时、时间器、图片、轮播图、视频、边框等组件;图表组件中,一个图表只能添加一次,其他组件不限制数量; 4)所有组件添加后均可进行设置样式,有编辑权限的图表组件可以通过【编辑】图标直接进入图表设计页面; 5)添加后均可删除,删除后组件不再展示在数据大屏画布中,可以重新添加 4.5 数据大屏设置 1)操作流程:创建数据大屏-进入数据大屏设计页面 2)操作路径:数据可视化-数据大屏-创建/编辑-设计页面 3)设置数据大屏时可以设置屏幕的宽高、背景颜色、背景图片、主题 a. 宽高:根据数据大屏需要投放的屏幕大小进行设置; b. 背景颜色:当数据大屏无图片背景时可以调整背景颜色; c. 背景图片:支持为数据大屏上传一张图片作为背景; d. 主题模版:可任选其一,需要先选定模版后再进行设计,不然设计完后再修改模版,会清空已选组件。 4.6 图表组件设置 1)操作流程:创建数据大屏-进入数据大屏设计页面 2)操作路径:数据可视化-数据大屏-创建/编辑-设计页面 3)拖入图表组件,可与边框合为一体,可以设置图表的显示内容、边框信息、动画效果、刷新频率 a. 图表显示内容:展示标题、副标题、描述、标签、图例,一屏展示条数,原图表有的内容在设置展示后展示在数据大屏,原图表没有的内容设置展示后不生效; b. 边框信息:包括边框样式、背景颜色、边框线条颜色、展示边框标题、边框标题内容、边框标题颜色、边框标题字体大小; c. 动画效果:可以设置自动轮播,为是时可以设置结束后停顿时长、速度、切换形式; d. 刷新频率:设置图表获取数据的频率,自动刷新、刷新频率。 4.7 文本组件设置 1)操作流程:创建数据大屏-进入数据大屏设计页面 2)操作路径:数据可视化-数据大屏-创建/编辑-设计页面 3)拖入文本组件后,可以输入多行文本,可以设置内容、对齐方式、字体大小、字体加粗、字体颜色、背景颜色、边框样式、文字滚动、结束后停顿、速度 4)当文字滚动开启时,文字会按照一行展示,通过设置结束后停顿和速度来控制文字滚动的效果 4.8 通用标题组件设置…

    2024年6月20日
    75800
  • 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日
    89700

Leave a Reply

登录后才能评论