6.3 数据审计(改)

在业务应用中我们经常需要为一些核心数据的变更做审计追踪,记录字段的前后变化、操作IP、操作人、操作地址等等。数据审计模块为此提供了支撑和统一管理。它在成熟的企业的核心业务系统中,需求是比较旺盛的。接下来我们开始学习下数据审计模块

准备工作

pamirs-demo-core的pom文件中引入pamirs-data-audit-api包依赖

<dependency>
    <groupId>pro.shushi.pamirs.core</groupId>
    <artifactId>pamirs-data-audit-api</artifactId>
</dependency>

pamirs-demo-boot的pom文件中引入pamirs-data-audit-core和pamirs-third-party-map-core包依赖,数据审计会记录操作人的地址信息,所以也依赖了pamirs-third-party-map-core

<dependency>
    <groupId>pro.shushi.pamirs.core</groupId>
    <artifactId>pamirs-data-audit-core</artifactId>
</dependency>
<dependency>
    <groupId>pro.shushi.pamirs.core.map</groupId>
    <artifactId>pamirs-third-party-map-core</artifactId>
</dependency>

pamirs-demo-boot的application-dev.yml文件中增加配置pamirs.boot.modules增加data_audit 和third_party_map,即在启动模块中增加data_audit和third_party_map模块


pamirs:
    boot:
    modules:
      - data_audit
      - tp_map

为third_party_map模块增加高德接口api,下面e439dda234467b07709f28b57f0a9bd5换成自己的key

pamirs: 
    eip:
    map:
        gd:
        key: e439dda234467b07709f28b57f0a9bd5

数据审计

注解式(举例)

Step1 新增PetTalentDataAudit数据审计定义类

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

import pro.shushi.pamirs.data.audit.api.annotation.DataAudit;
import pro.shushi.pamirs.demo.api.model.PetTalent;

@DataAudit(
        model = PetTalent.MODEL_MODEL,//需要审计的模型
        modelName = "宠物达人" ,//模型名称,默认模型对应的displayName
        //操作名称
        optTypes = {PetTalentDataAudit.PETTALENT_CREATE,PetTalentDataAudit.PETTALENT_UDPATE},
        fields={"nick","picList.id","picList.url","petShops.id","petShops.shopName"}//需要审计的字段,关系字段用"."连结
)
public class PetTalentDataAudit {
    public static final String PETTALENT_CREATE ="宠物达人创建";
    public static final String PETTALENT_UDPATE ="宠物达人修改";

Step2 修改PetTalentAction的update方法

做审计日志埋点:手工调用 OperationLogBuilder.newInstance().record()方法。需要注意的是这里需要把原有记录的数据值先查出来做对比

    @Function.Advanced(type= FunctionTypeEnum.UPDATE)
    @Function.fun(FunctionConstants.update)
    @Function(openLevel = {FunctionOpenEnum.API})
    public PetTalent update(PetTalent data){
        //记录日志
        OperationLogBuilder.newInstance(PetTalent.MODEL_MODEL, PetTalentDataAudit.PETTALENT_UDPATE).record(data.queryById().fieldQuery(PetTalent::getPicList).fieldQuery(PetTalent::getPetShops),data);

        PetTalent existPetTalent = new PetTalent().queryById(data.getId());
        if(existPetTalent !=null){
            existPetTalent.fieldQuery(PetTalent::getPicList);
            existPetTalent.fieldQuery(PetTalent::getPetShops);
            existPetTalent.relationDelete(PetTalent::getPicList);
            existPetTalent.relationDelete(PetTalent::getPetShops);
        }
        data.updateById();
        data.fieldSave(PetTalent::getPicList);
        data.fieldSave(PetTalent::getPetShops);
        return data;
    }

Step3 重启看效果

修改宠物达人记录对应的字段,然后进入审计模块查看日志

image.png

image.png

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

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

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

相关推荐

  • 1.3 Oinone的生态思考

    以“企业级软件生态”的方式去帮助企业建立“一站式的商业智能软件”。 通过观察信息化到数字化的软件行业发展历程(如下图1-3所示),我们可以发现,企业真正需要的是一站式的软件产品。然而,一站式的软件产品往往都是从单个领域的需求满足开始,这在信息化时代和数字化时代都是如此。在信息化时代,以ERP为终点的一站式趋势逐渐形成;而在数字化时代,中台概念的提出则标志着一站式的趋势重新开始。本文将从企业数字化转型所面临的困境出发,探讨Oinone的生态思考。 图1-3 从信息化到数字化软件行业发展历程 1.3.1 与中台的渊源 中台概念的提出标志着企业数字化改造进入了一个新的时代。随着数字化转型不断深入,企业面临着严重的数据割裂、系统隔离等问题。在这样的背景下,“敏捷响应,低成本地快速创新”成为了推动一站式商业智能软件的内在诉求。需要澄清的是,互联网中台架构只是一种企业解决数据割裂、系统隔离,建立一站式商业智能软件的技术概念之一,并不是技术标准。而且这种方式只适用于企业自建模式。在多供应商环境下,则会适得其反,导致建立更复杂的烟囱系统。 阿里于15年提出中台架构概念,抓住了企业数字化转型的核心诉求,即“敏捷响应,低成本快速创新”。然而,阿里作为一家生态公司,在16年时基本上是带着合作伙伴来给企业交付,但由于伙伴对互联网技术的理解和能力的限制,基本上都做得不好,甚至失败。在2017年,阿里成立了原生交付团队,希望能够树立一些标杆案例。我和公司的核心成员也都来自于这个团队。在做完几个客户后,我发现阿里也做不好,但这次做不好的原因不是技术不行或项目上不了线,而是上线以后预期的效果没有达到,其本质是企业的IT组织能力无法驾驭复杂的互联网中台架构。当无法驾驭的时候,所谓的目标“敏捷响应,快速创新”就无从说起了。结果客户会反馈以下三类问题: 不是说敏捷响应吗?为什么改个需求这么慢,不但时间更长,付出的成本也更高了?是因为中台架构需要一定的技术能力和经验才能有效地应用,就像一个只会骑自行车的人给他一辆汽车或者飞机,他也不能驾驭它们,更不用说是手动挡的。 不是说能力中心吗?当引入新供应商或有新场景开发的时候,为什么前期做的能力中心不能支撑了?是因为能力中心是一种面向业务的能力组织方式,它将不同的业务能力抽象出来,以服务的形式对内提供。然而,由于业务场景的差异,不同的业务需要的能力也会不同,因此能力中心需要不断迭代和升级。对于新引入的供应商或新场景开发,需要根据实际情况对能力中心进行定制化和扩展化,但谁来负责呢?新项目的供应商还是客户自己? 不是说性能好吗?为什么我投入的物理资源更多了?是因为中台架构采用微服务来解决单点瓶颈问题,提高系统性能和可用性,但是在初始阶段,投入的资源可能会更多。每个模块至少需要两个实例来保障高可用性,因此物理资源的投入量可能会比以前更多。 1.3.2 找解决方案 在考虑解决方案之前,我们需要思考企业数字化软件的最终状态将是什么样子。目前有两种主要的方案(如下图1-4所示): 第一种是以自建研发团队为核心。中国的大型企业已经开始尝试这种模式,看起来似乎是一个时下比较流行的可行性方案。然而,绝大多数企业由于成本、人才团队等原因而难以坚持下去,只能与供应商合作开发。 第二种是以供应商为核心。由于大多数企业无法选择第一种路径,他们必须接受目前分散的情况,并通过系统集成尽可能拉通各个系统。尽管如此,在数字化时代中,真正意义上的一站式商业智能软件供应商还未出现。 图1-4 企业数字化桎梏和囹圄 对企业来说,这两种方案都非常艰难,但在大规模数字化历程中又不得不做出选择。此外,我们还能清晰看到以下几点: "敏捷响应,低成本地快速创新"成为企业推动一站式商业智能软件的内在诉求 目前没有一家软件供应商能满足企业所有外围商业场景,也不可能有这样的供应商 绝大部分企业需要软件供应商,而不是自建 如何突破这种局面也成为中国软件行业发展的一个机遇。因此,我的思考是: 我们的目标不是依托于提升研发人员的能力,而是降低互联网架构的门槛,让更多企业真正拥有“敏捷响应,低成本快速创新”的能力。 我们的目标不是输出中台方法论,而是提供中台建设的技术平台。 我们的目标不是只服务大企业,而是真正赋能不同IT组织能力的企业,让它们都具备持续创新的能力。 今天,许多中台软件公司告诉企业:“中台是持续演进和快速迭代的过程,因此企业需要组建中台架构团队来实现,而他们则通过中台项目落地将中台建设方法论传授给企业。”这句话的前半部分是正确的,因为我们之前提到企业需要具备敏捷响应业务的能力,即应变能力,因为应变是不断变化的。然而,后半部分是不正确的,因为今天的企业已经有能力组建团队,那么这些中台软件公司到底有什么用呢?企业真的缺少方法论吗?在19年,我就提出了自己的看法:没有低代码能力的中台公司都在收取智商税,都在欺诈,因为很多企业根本找不到足够懂互联网架构的人才。明白流氓在哪里了吗?这些流氓公司赚了很多钱,最后责怪企业无法招到人才,这是企业的责任。因此,仍然认为“最好的赋能是降低门槛,而不是让客户提高技术水平”。 最终,我们得出了一个服务模式的想法:构建企业级的软件生态。企业级软件生态的确切定义是:通过开放的方式,让企业本身以及不同的软件供应商共同参与,遵循相同的技术和数据规范,打造一体化、无需集成的各类企业级软件。如果要打造企业级软件生态,我们列出了六个要点(如下图1-5所示)。 图1-5 打造企业级软件生态需要具备的六大能力 我很幸运地有机会通过“企业级软件生态”的方式,为企业建立“一站式的商业支持平台”提供帮助。我们的Oinone平台结合了低代码开发、通用数据模型和业务产品的优势(如下图1-6所示)。 图1-6 Oinone = 低代码开发平台 + 通用数据模型 + 业务产品 我们对Oinone一站式低代码商业支撑平台展开介绍,它大致分为4部分: 以低代码开发平台为基础,输出具备互联网架构下的软件快速开发标准。这可以帮助企业快速构建符合互联网架构标准的应用程序,从而实现快速响应和低成本创新。 以通用数据模型为基础,满足不同软件基于同一套数据标准的扩展能力。这可以确保不同软件系统之间的数据兼容性和互操作性,避免数据孤岛和信息隔离。 在业务产品层面上,企业和伙伴基于相同的技术标准和数据标准共同提供解决方案。这可以帮助企业和伙伴共同开发出符合标准的商业支撑平台,以提高业务效率和创新能力。 最后是无代码设计器,用于满足项目开展中,超出业务标品范围之外的需求,或者针对标品的临时需求。这可以帮助业务人员在不需要专业软件支持的情况下,自主解决业务需求,并支持部门间的协同工作。 1.3.3 生态建设 Oinone致力于打造全球最大的无需集成的商业应用程序及其生态系统,通过开源内核、汇集数千名开发人员和业务专家,为企业提供成本效益、一体化、模块化的解决方案,解决所有商业需求,让不同技术之间的合作变得简单易行,摆脱烦恼的集成问题。 在客户和场景领域,我们严格限定了自身的专注领域。针对超大型头部企业,我们专注于树立标杆,而对于大、中、小型企业,则交由我们的伙伴来支持。小微企业可以通过我们的开源社区版获得覆盖。在企业数字化转型的核心领域中,我们的解决方案涵盖了数字化交易场景、全渠道订单履约场景、数字化采购场景、数字化营销等产品。在其他领域,我们完全交由伙伴来建设。由于我们自身在企业协同商务领域拥有深厚的背景,因此在该领域提供的产品拥有特别的优势。 企业数字化转型核心领域 图1-7 企业数字化转型核心领域

    2024年5月23日
    2.4K00
  • 报表

    1. 业务场景 报表不局限于表格的样式,还能以各式各样的图表形式展现各项汇总数据 这有利于管理者更为直观地了解公司的经营情况,便于后续进行分析,提高对公司的管理水平。 2. 操作流程 1)进入数据可视化,进入报表tab,维护分组信息; 2)在二级分组名称后点击“+”【添加报表】,对报表进行编辑设计; 3)创建完成后可以【编辑】报表标题、备注; 4)需要通过【选择图表、创建图表】完善报表内容; 5)完善后可以点击【发布】报表,则报表此时可以被引用; 6)如果报表有更新,则可以点击【更新发布】,使业务系统引用对报表变为最新的报表信息; 7)如果报表数据不再可以公开使用,则需要通过【隐藏】功能将报表的引用权限收起,此时数据大屏、前端业务系统均不可再引用该报表,但不影响已被引用的报表; 8)隐藏后可以【取消隐藏】,报表恢复隐藏前的状态和功能,可以被引用。 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)未发布或者已发布但没有被隐藏的报表,并且没被前端或者数据大屏引用,才展示报表菜单名称后的删除图标 4)删除报表后报表消失 3.6 选择图表 1)操作流程:选择报表-为报表选择图表 2)操作路径:数据可视化-报表-二级分组-报表名称-选择图表 3)选择单个未发布或者已发布但没有被隐藏的报表,点击【选择图表】,弹出“选择图表”弹窗,对该报表需要展示的图表进行选择 a. 需要选择图表的一级分组后才能选择图表; b. 可以多选图表,选择的图表只能是已选一级分组下的未隐藏的未被选择的图表;选择一个二级分组时,默认该二级分组下的图表会全部被选中,图表会按照选中的顺序展示在报表列表; 4)选择图表后,报表信息保持展示图表的最新效果;如果图表更新了,但是报表没有发布最新,则报表在前端展示的仍为最近发布的版本; 5)如果图表中存在超过一行的图内筛选项,则在报表处原始的图表尺寸只能查看一行图内筛选项,需要根据图表在报表处的等比拖动效果展示更多的图内筛选项 3.7 创建图表 1)操作流程:选择报表-创建图表 2)操作路径:数据可视化-报表-二级分组-创建图表 3)选择单个未发布或者已发布但没有被隐藏的报表,点击【创建图表】,弹出“创建图表”弹窗,需要填写图表标题、模型、方法; a. 图表标题:最大支持20个字,支持汉字、数字、大小写字母、-;同个一级分组下不允许重复; b. 模型:需要选择来源数据对应的模型; c. 方法:选择模型后需要选择方法,方法是用来提取模型数据的逻辑; 4)选择成功后进入图表设计页面,创建图表保存后返回,返回到当前报表页面,新创建的图表展示在报表的第一个位置 3.8 拖拽图表 1)操作流程:选择报表-拖拽图表 2) 操作路径:数据可视化-报表-二级分组-报表名称-拖拽图表 3)所有的报表均可拖拽图表,拖拽时需要选择图表,可以上下左右等比拖动,图表的内容也会根据拖动的比例进行缩放,展示全部的被遮挡图表内容 4)拖拽后实时生效,报表信息保持展示最新效果 3.9 移除图表 1)操作流程:选择报表-移除图表 2)操作路径:数据可视化-报表-二级分组-报表名称-移除图表 3)未发布或者已发布但没有被隐藏的报表,并且没被前端或者数据大屏引用,此时可以针对不需要的图表进行移除 4)选择移除后不展示在报表中,不影响原图表 5)报表移除图表后实时更新,更新发布后,前端可以展示最新的报表信息,如果未发布,则仅数据大屏可展示最新的报表信息,前端仍为最近发布的报表 3.10 设置报表筛选项 1)操作流程:选择报表-设置报表筛选项 2)操作路径:数据可视化-报表-二级分组-报表名称-更多-报表筛选项-添加 3)添加时选择筛选项字段的类型,关联每个图表对应的字段,一个图表只能关联一个 4)关联后可以按关联字段查询图表数据 3.11 发布 1)操作流程:选择报表-发布报表 2)操作路径:数据可视化-图表-二级分组-报表-发布 3)选择单个未发布且没有被隐藏的报表,点击【发布】按钮,报表发布后可以被前端引用,报表状态变为已发布,展示最近发布时间; 4)如果报表发布后有更新内容,会展示的更新类型:更新报表信息/更新图表内容/选择图表/移除图表 3.12 查看最近一次发布的版本 1)操作流程:选择报表-查看最近一次发布的版本 2)操作路径:数据可视化-报表-二级分组-报表名称-查看最近一次发布的版本 3)当报表发布后有更新,在最近发布时间左侧展示【查看】,在最近发布时间下展示更新的类型,点击查看可以查看最近发布的版 3.13 更新发布 1)操作流程:选择报表-更新发布报表 2)操作路径:数据可视化-报表-二级分组-报表名称-更新发布报表 3)选择单个已发布且没有被隐藏的报表,并且该报表在上次发布后有所更新,可以点击【更新发布】按钮,将最新的报表内容发布至业务系统,业务系统引用的报表为最新内容; 4)如果更新了内容,但未点击更新发布,则前端业务系统查看的报表仍为最近发布的报表 3.14 隐藏 1)操作流程:选择报表-隐藏报表 2)操作路径:数据可视化-报表-二级分组-报表名称-隐藏报表 3)报表默认不隐藏,可以切换是否隐藏=是 a. 未发布的报表,较隐藏前,不可以操作【发布】,可以【取消隐藏】; b. 已发布的图表,较隐藏前,只能操作【导出图片、导出excel、取消隐藏】; c. 隐藏后的报表不可以被引用,但不影响已经被引用的数据 3.15 取消隐藏 1) 操作流程:选择报表-取消隐藏报表 2) 操作路径:数据可视化-报表-二级分组-报表名称-取消隐藏报表 3) 隐藏后的报表可以取消隐藏,切换是否隐藏=否,取消隐藏后,报表恢复隐藏前的状态和功能,可以被引用 3.16 查看引用 1)流程:选择报表-查看被哪些页面引用 2)操作路径:数据可视化-报表-二级分组-报表-更多-查看引用 3)选择具体的报表,查看当前报表被引用的所有信息 3.17 不允许别人编辑 1)流程:选择报表-不允许别人编辑 2)操作路径:数据可视化-报表-二级分组-报表-更多-不允许别人编辑 3)选择自己创建的报表,对报表是否允许其他人编辑进行设置;如果设置为不允许,则其他人无法编辑报表 3.18 不允许别人引用 1)流程:选择图表-更多-不允许别人引用 2)操作路径:数据可视化-报表-二级分组-报表-更多-不允许别人引用 3)选择自己创建的报表,对报表是否允许他人引用进行设置;如果设置为不允许,则其他人无法引用到该报表 3.19 导出图片 1) 操作流程:选择报表-导出图片 2) 操作路径:数据可视化-报表-二级分组-报表名称-导出图片 3) 选择报表后,点击【导出图片】按钮可以将当前报表导出为图片 3.20 导出EXCEL 1)操作流程:选择报表-导出EXCEL 2)操作路径:数据可视化-报表-二级分组-报表名称-报表导出EXCEL 3)选择报表后,点击【导出EXCEL】按钮可以将当前报表导出为EXCEL

    2024年6月20日
    2.1K00
  • 3.3.1 构建第一个Model

    定义模型,并配上相应的菜单或配置模块的homepage为该模型,模块就具备了可访问的该模型对应的列表页、新增页、修改页、删除记录和导入导出功能。 都说oinone是以model为驱动,对于模型的理解,希望通过本节跟给大家带来一个初步的认识。 一、构建宠物店铺模型 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; import java.sql.Time; @Model.model(PetShop.MODEL_MODEL) @Model(displayName = "宠物店铺",summary="宠物店铺") public class PetShop extends IdModel { public static final String MODEL_MODEL="demo.PetShop"; @Field(displayName = "店铺名称",required = true) private String shopName; @Field(displayName = "开店时间",required = true) private Time openTime; @Field(displayName = "闭店时间",required = true) private Time closeTime; } 图3-3-1-1 构建宠物店铺模型 配置注解 模型类必需使用@Model注解来标识当前类为模型类。 可以使用@Model.model、@Fun注解模型的模型编码(也表示命名空间),先取@Model.model注解值,若为空则取@Fun注解值,若皆为空则取全限定类名。 使用@Model.model注解配置模型编码,模型编码唯一标识一个模型。 请勿使用Query和Mutation作为模型编码和技术名称的结尾。 上方示例使用Model注解和Field注解来定义一个实体模型。displayName属性最终会作为label展现在前端界面上。 更多Model的详细元数据描述介绍参见4.1.6【模型元数据详解】一文 模型命名规范 模型属性 默认取值规范 命名规则规范 name 默认取model.model的点分割最后一位 1仅支持数字、字母2必须以字母开头3长度必须小于等于128个字符 module 无默认值开发人员定义规范示例:{项目名称}_{模块功能示意名称} 1仅支持数字、大写或小写字母、下划线2必须以字母开头3不能以下划线结尾4长度必须小于等于128个字符 model 默认使用全类名,取lname的值开发人员定义规范示例:{项目名称}.{模块功能示意名称}.{简单类名} 1仅支持数字、字母、点2必须以字母开头3不能以点结尾4长度必须小于等于128个字符 display_name 空字符串 1长度必须小于等于128个字符 lname 符合java命名规范,真实的java全类名,无法指定,要符合model的约束,即为包名+类名 lname是不能定义的,为全类名:包名+类名,和model一样的校验规则:包名和类名的校验 summary 默认使用displayName属性 1不能使用分号2长度必须小于等于128个字符 descripition NULL,注解无法定义 1长度必须小于等于65535个字符 table 默认使用name字段生成表名时,table字段的命名规则约束同样生效(大小驼峰命名转为下划线分割的表名称) 1仅支持数字、字母、下划线2长度必须小于等于128个字符(此限制为系统存储约束,与数据库本身无关) type java属性类型与数据库存储类型可执行转换即可 ModelTypeEnum枚举值 表3-3-1-1 模型命名规范 字段命名规范 字段属性 默认取值规范 命名规则规范 name 默认使用java属性名 1仅支持数字、字母2必须以小写字母开头3长度必须小于等于128个字符 field 默认使用java属性名 与name使用相同命名规则约束 display_name 默认使用name属性 1长度必须小于等于128个字符 lname 使用java属性名,符合java命名规范,真实的属性名称,无法指定 与name使用相同命名规则约束 column 列名为属性名的小驼峰转下划线格式 1仅支持数字、字母、下划线2长度必须小于等于128个字符(此限制为系统存储约束,与数据库本身无关) summary 默认使用displayName属性 1不能使用分号2长度必须小于等于500个字符 表3-3-1-2 字段命名规范 我们重启Demo应用以后,打开Insomnia刷新GraphQL的schema,就可以看到PetShop默认对应的读写服务了 图3-3-1-2 PetShopQuery默认读写服务 图3-3-1-3 PetShopMutatiom默认读写服务 配置模块的主页为宠物商店的列表页 为了方便大家对模型有个更加直观的了解,接下来我们通过前端交互来感受下。 在3.2.2【启动前端工程】一文中,在模块下拉列表中“oinoneDemo工程”还是不能点击的。是因为该模块没有配置主页,我们现在把主页设置为宠物商店的列表页,只需要在DemoModule这个类上增加一个注解@UxHomepage(@UxRoute(PetShop.MODEL_MODEL)),关于该注解的更多说明请查看4.1.4一文中的【UxHomepage注解详解】部分 package pro.shushi.pamirs.demo.api; import org.springframework.stereotype.Component; import pro.shushi.pamirs.boot.base.ux.annotation.action.UxRoute; import pro.shushi.pamirs.boot.base.ux.annotation.navigator.UxHomepage; import pro.shushi.pamirs.demo.api.model.PetShop; import pro.shushi.pamirs.meta.annotation.Module; import pro.shushi.pamirs.meta.base.PamirsModule; import pro.shushi.pamirs.meta.common.constants.ModuleConstants; @Component @Module( name = DemoModule.MODULE_NAME, displayName = "oinoneDemo工程", version = "1.0.0", dependencies = {ModuleConstants.MODULE_BASE} ) @Module.module(DemoModule.MODULE_MODULE) @Module.Advanced(selfBuilt = true, application = true) @UxHomepage(@UxRoute(PetShop.MODEL_MODEL)) public class DemoModule implements PamirsModule { public static final String MODULE_MODULE = "demo_core"; public…

    2024年5月23日
    1.9K00
  • 2.4.1 Oinone独特性之单体与分布式的灵活切换

    企业数字化转型需要处理分布式带来的复杂性和成本问题。尽管这些问题令人望而却步,但分布式架构对于大部分企业仍然是必须的选择。如果一个低代码平台缺乏分布式能力,那么它的性能就无法满足客户的要求。相比之下,Oinone平台通过对部署的创新(如图2-6所示),成功实现了分布式架构的支持,而且能够按照客户的业务发展需求,灵活选择不同的部署模式,同时节约企业成本,提升创新效率。这一创新是Oinone平台与其他低代码平台的重要区别,能够满足客户预期发展并兼顾成本效益。 图2-6 传统部署方式VS Oinone部署方式 实现原理 要实现灵活部署的特性,必须满足两个基本要求: 开发过程中不需要过多关注分布式技术,就像开发单体应用一样简单。代码在运行时应该能够根据模块是否在运行容器中,来决定路由走本地还是远程。这样可以大大减少研发人员的工作量和技术复杂度。 研发与部署要分离,即"开发单体应用一样开发分布式应用,而部署形式由后期决定"。为此,我们的工程结构支持多种启动模式,并逐一介绍了针对不同场景的工程结构类型(如下图2-7所示)。这样可以让客户在后期根据业务发展情况和需求,选择最适合的部署模式,从而达到灵活部署的目的。 图2-7 Oinone工程结构梳理 在整个工程结构上,我们秉承了Spring Boot的规范,不会改变大家的工程习惯。而Oinone的部署能力则可以让我们更灵活地应对各种情况。现在,我们来逐一介绍几种常规的工程结构以及它们适用的场景: 单模块工程结构(常规操作) a. 这是非常标准的Spring Boot工程,适用于简单的应用场景开发以及入门学习。 多模块工程结构(常规操作) a. 这是非常标准的多Spring Boot工程,可以实现分布式独立启动,适用于常规的分布式应用场景开发。 多模块工程结构-独立boot工程模式 a. 这种工程结构在多模块工程的基础上,通过独立的boot工程来支撑多部署方式。适用于中大型分布式应用场景开发。 b. 然而,随着工程越来越多,我们也会面临一些问题: ⅰ研发:环境准备非常困难,每个模块都要单独启动,研发调试跟踪困难。 ⅱ部署:分布式的高可靠性保证需要每个模块至少有两个部署节点,但在模块较多的情况下,起步成本非常高。同时,企业初期业务不稳定且规模较小,使用多模块工程的第二种模式会增加问题排查难度和成本。 c. 此时,Oinone的多模块工程下的独立boot工程模式部署就可以发挥其灵活性,让研发和业务起步阶段可以选择all-in-one模式,等到业务发展到一定规模的时候,只需要把线上部署模式切换成模块独立部署,而研发还可以保留all-in-one模式的优势。 d. 值得注意的是,分分合合的部署模式在传统互联网架构和低代码或无代码平台上都是有代价的,但是Oinone却可以灵活适配,只需要在boot工程的yml文件中写入需要加载的模块就可以解决。此处我们仅介绍多模块加载配置,选择性忽略其他无关配置,具体配置(如下图2-8所示)。 pamirs: boot: init: true sync: true modules: – base – resource – sequence – user – auth – web tenants: – pamirs 图2-8 Oinone yml配置图大型多场景工程结构-独立boot工程模式: a. 在多模块工程结构基础上的加强版,增加CDM层设计,让不同场景即保持数据统一,又保持逻辑独立。这种工程结构特别适用于大型企业软件开发,其中涉及到多个场景的情况,例如B端和C端的应用,或者跨不同业务线的应用,能够保证数据的一致性,同时也能够保持逻辑独立,避免不同场景间的代码冲突。 b. 这种工程结构是我们Oinone支撑“企业级软件生态”的核心,我们可以把场景A当作我们官方应用,场景B当作其他第三方伙伴应用。在这个工程结构下,我们的客户可以定制化开发自己的应用,同时我们也可以通过这种模式来支持我们的伙伴们进行开发,实现多方共赢。 c. 基于独立boot工程模式,我们同样对应多种部署模式应对不同情况,并统一管理所有伙伴应用。这种工程结构的优点是扩展性好,可以支持不同规模的应用,并且可以根据需要进行快速扩展或缩小规模,具有很高的灵活性。 基于标准产品的二开工程结构,是指基于标准产品进行二次开发,满足客户特定需求的工程结构。这种模式下,Oinone提供标准产品,客户可以根据自己的需求进行二次开发,实现定制化需求,同时可以利用我们的模块化开发特性,将每一个需求作为一个模块进行开发和管理。这种工程结构的优点是能够快速满足客户特定需求,同时也具有很好的可维护性和可扩展性,因为每个需求都是一个独立的模块,可以方便地进行维护和扩展。在下一篇“Oinone独特性之每一个需求都是一个模块”文章中有详细介绍。

    2024年5月23日
    2.3K00
  • 4.2.5 框架之网络请求-Request

    在中后台业务场景中,大部分的请求时候是可以被枚举的,比如创建、删除、更新、查询。在上文中,我们讲了httpClient如何自定义请求,来实现自己的业务诉求。本文中讲到的Request是离业务更近一步的封装,他提供了开箱即用的API,比如insertOne、updateOne,它是基于HttpClient做的二次封装,当你熟悉Request时,在中后台的业务场景中,所有的业务接口自定义将事半功倍。 一、Request详细介绍 元数据-model 获取模型实例 import { getModel } from '@kunlun/dependencies' getModel('modelName'); 图4-2-5-1 获取模型实例 清除所有缓存的模型 import { cleanModelCache } from '@kunlun/dependencies' cleanModelCache(); 图4-2-5-2 清除所有缓存的模型 元数据-module 获取应用实例,包含应用入口和菜单 import { queryModuleByName } from '@kunlun/dependencies' queryModuleByName('moduleName') 图4-2-5-3 获取应用实例 查询当前用户所有的应用 import { loadModules } from '@kunlun/dependencies' loadModules() 图4-2-5-4 查询当前用户所有的应用 query 分页查询 import { queryPage } from '@kunlun/dependencies' queryPage(modelName, { pageSize: 15, // 一次查询几条 currentPage, 1, // 当前页码 condition?: '' // 查询条件 maxDepth?: 1, // 查几层模型出来,如果有2,会把所有查询字段的关系字段都查出来 sort?: []; // 排序规则 }, fields, variables, context) 图4-2-5-5 分页查询 自定义分页查询-可自定义后端接口查询数据 import { customQueryPage } from '@kunlun/dependencies' customQueryPage(modelName, methodName, { pageSize: 15, // 一次查询几条 currentPage, 1, // 当前页码 condition?: '' // 查询条件 maxDepth?: 1, // 查几层模型出来,如果有2,会把所有查询字段的关系字段都查出来 sort?: []; // 排序规则 }, fields, variables, context) 图4-2-5-6 自定义分页查询 查询一条-根据params匹配出一条数据 import { queryOne } from '@kunlun/dependencies' customQueryPage(modelName, params, fields, variables, context) 图4-2-5-7 根据params匹配出一条数据 自定义查询 import { customQuery } from '@kunlun/dependencies' customQuery(methodName, modelName, record, fields, variables, context) 图4-2-5-8 自定义查询 update import { updateOne } from '@kunlun/dependencies' updateOne(modelName, record, fields, variables, context) 图4-2-5-9 update insert import { insertOne } from '@kunlun/dependencies' insertOne(modelName, record, fields, variables, context) 图4-2-5-10 insert delete import { deleteOne } from '@kunlun/dependencies'…

    2024年5月23日
    1.7K00

Leave a Reply

Please Login to Comment