集成设计器

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

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

Like (0)
史, 昂's avatar史, 昂数式管理员
Previous 2024年6月20日 am9:49
Next 2024年6月20日 am9:49

相关推荐

  • 6.5 权限体系(改)

    做好企业级软件,首先得过权限这一关 在企业的IT部门沟通中,权限是避免不了。自嘲下在我们刚出来创业时,为了收获客户对我们技术能力的信任,每每与跟客户沟通时都会说我们是阿里出来的,但在权限设计这个环节不那么灵验,反而被打上了不懂B端权限设计的标签,会问很多问题。我就很奇怪难道大厂就没有内部管理系统了?大厂只有C端交易,没有B端交易?但从侧面说明权限不简单还特别重要。做好企业级软件,首先得过权限这一关。 整体介绍 对于平台运行来说,权限是必须,但我们的auth模块不是必须的,auth模块只是我们提供的一种默认实现,客户可以根据平台的spi机制进行替换。auth模块利用了平台的Hook特性做到与业务无关,在我们开发上层应用的时,是不用感知它的存在的。 auth模块涉及:功能权限、数据权限 数据权限:行权限和列权限。备注:数据权限的控制只能用于【存储模型】 表级权限:表达的语义是:是否该表可读/写(修改和新增) 列权限:表达的语义是:是否该列可读/写(修改和新增) 行权限:表达的语义是:是否对该行可读/写(修改)/删除 功能权限:表达的语义是ServerAction/Function是否可执行/展示,viewAction是否可展示,菜单是否可以显示 范围说明: 配置多个权限项的时候,取并集 配置多个角色的时候,取并集 模型设计 产品体验 Step1 创建角色 通过App Finder 切换至【权限】应用,点击新增按钮创建一个名为oinone的角色 Step2 创建数据权限项 在【权限项列表】菜单,点击【创建】按钮新增一个名为【宠物达人数据权限项】,同时宠物达人的数据权限设置为只能查看性别为男的记录 配置说明: 名称: 代表该项配置的权限的名字(必填)(必须是全系统唯一) 权限模型: 选择需要拦截的数据所在的表,即为模型,可以搜索使用 描述:对该权限项的描述 权限条件的配置: 满足全部:对条件一和条件二要同时满足的数据才能被看见 满足任一:对条件一和条件二要任意满足的数据都能被看见 读权限:对该数据是否有读取的权限 写权限:对该数据是否有修改的权限 删除权限:对该条件内的数据是否有删除的权限 Step3 为角色配置权限 编辑oinone角色,只开通oinoneDemo工程应用 选中【数据权限】选项卡点击【添加】按钮,勾选宠物达人数据权限项点击【确定】按钮 整体点击保存,回到列表页记得点击【权限生效】按钮 Step4 新建用户绑定角色 切换到用户中心模块,点击【创建】按钮填写必要信息,并在角色选中oinone权限组。 退出admin用户,用oinone登陆,权限效果: 只能看见demo模块 oinone登陆只能看到性别为男的宠物达人记录 admin用户登陆 oinone用户登陆 因为宠物达人的页面没有把性别字段放出来,我们看下数据库数据 auth模块扩展 在日常项目开发中,难免会碰到一些针对权限管理的特殊需求,或是为提升性能做的特殊逻辑。接下来我给大家介绍auth模块扩展性。 权限全局配置 对所有权限角色都做限制,而且不想让用户感知,可以实现PermissionFunApi接口,API接口实现的配置方式【只能用于支持全局的数据权限配置】 实现接口PermissionFunApi 将实现托管给SpringAOP 接口的具体实现看下图的代码 package pro.shushi.pamirs.demo.core.service; import org.springframework.stereotype.Component; import pro.shushi.pamirs.auth.api.service.PermissionFunApi; import pro.shushi.pamirs.demo.api.model.PetTalent; @Component public class PetTalentPermissionFunApi implements PermissionFunApi { @Override public String permissionDomain(Object… args) { //获取当前组织中 return "name == '张学友'"; } @Override public String nameSpace() { return PetTalent.MODEL_MODEL; } } 不参与权限控制 如果某一接口不想做权限控制,则可以在启动工程的application-dev.yml文件中配置不需要权限过滤的接口 pamirs: auth: fun-filter: – namespace: demo.PetTalent fun: queryPage 换一个没有配置宠物达人权限的用户(除管理员以外)进入系统,则也可以看到数据。注意【权限全局控制】还是生效的 API 1. 获取当前用户对该模型的行权限 Result<String> result = CommonApiFactory.getApi(AuthApi.class).canReadAccessData("Model"); 返回值为 { 'data':"name=in=('hahaha')" 'success':true … } 用法 : 场景:前端发起的请求都会经过权限拦截,后端代码逻辑发起的数据请求都是不经过任何权限的过滤,但是某些特殊情况需要在后端代码逻辑发起的数据请求也带上权限过滤 入参:请求的模型 出参:Result 数据结构中data会存储一段字符串,该字符串为Rsql 将该Rsql追加到wrapper中 Result<String> result = CommonApiFactory.getApi(AuthApi.class).canReadAccessData("base.UeModule"); String data=result.getData(); QueryWrapper<UeModule> wrapper = Pops.query(); wrapper.setEntity(ueModule); if (!StringUtils.isBlank(data)) { wrapper.apply(data); }

    2024年5月23日
    1.9K00
  • 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 重启看效果 修改宠物达人记录对应的字段,然后进入审计模块查看日志

    2024年5月23日
    1.6K00
  • 4.1.5 模型之持久层配置

    一、批量操作 批量操作包括批量创建与批量更新。批量操作的提交类型系统默认值为batchCommit。 批量提交类型: useAffectRows,循环单次单条脚本提交,返回实际影响行数 useAndJudgeAffectRows,循环单次单条脚本提交,返回实际影响行数,若实际影响行数与输入不一致,抛出异常 collectionCommit,将多个单条更新脚本拼接成一个脚本提交,不能返回实际影响行数 batchCommit,使用单条更新脚本批量提交,不能返回实际影响行数。 全局配置 pamirs: mapper: batch: batchCommit 图4-1-5-1 全局配置 运行时配置 非乐观锁模型系统默认采用batchCommit提交更新操作;乐观锁模型默认采用useAndJudgeAffectRows提交更新操作。也可以使用以下方式在运行时改变批量提交方式。 Spider.getDefaultExtension(BatchApi.class).run(() -> { 更新逻辑 }, 批量提交类型枚举); 图4-1-5-2 运行时配置 运行时校正 如果模型配置了数据库自增主键,而批量新增的批量提交类型为batchCommit,则系统将批量提交类型变更为collectionCommit(如果使用batchCommit,则需要单条提交以获得正确的主键返回值,性能有所损失)。 如果模型配置了乐观锁,而批量更新的批量提交类型为collectionCommit或者batchCommit,则系统将批量提交类型变更为useAndJudgeAffectRows。也可以失效乐观锁,让系统不做批量提交类型变更处理。 二、乐观锁(举例) 在一些会碰到并发修改的数据,往往需要进行并发控制,一般数据库层面有两种一种是悲观锁、一种是乐观锁。oinone对乐观锁进行了良好支持 定义方式 乐观锁的两种定义方式: 通过快捷继承VersionModel,构建带有乐观锁,唯一编码code且主键为id的模型。 可以在字段上使用@Field.Version注解来标识该模型更新数据时使用乐观锁 如果更新的实际影响行数与入参数量不一致,则会抛出异常,错误码为10150024。如果是批量更新数据,为了返回准确的实际影响行数,批量更新由批量提交改为循环单条数据提交更新,性能有所损失。 失效乐观锁 一个模型在某些场景下需要使用乐观锁来更新数据,而另一些场景不需要使用乐观锁来更新数据,则可以使用以下方式在一些场景下失效乐观锁。更多元位指令用法详见4.1.9【函数之元位指令】一文。 PamirsSession.directive().disableOptimisticLocker(); try{ 更新逻辑 } finally { PamirsSession.directive().enableOptimisticLocker(); } 图4-1-5-3 失效乐观锁 不抛乐观锁异常 将批量提交类型设置为useAffectRows即可,这样可改由外层逻辑对返回的实际影响行数进行自主判断。 Spider.getDefaultExtension(BatchApi.class).run(() -> { 更新逻辑,返回实际影响行数 }, BatchCommitTypeEnum.useAffectRows); 图4-1-5-4 将批量提交类型设置为useAffectRows 构建第一个VersionModel Step1 新建PetItemInventroy模型,继承快捷模型VersionModel 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.common.VersionModel; import java.math.BigDecimal; @Model.model(PetItemInventroy.MODEL_MODEL) @Model(displayName = "宠物商品库存",summary="宠物商品库存",labelFields = {"itemName"}) public class PetItemInventroy extends VersionModel { public static final String MODEL_MODEL="demo.PetItemInventroy"; @Field(displayName = "商品名称") private String itemName; @Field(displayName = "库存数量") private BigDecimal quantity; } 图4-1-5-5 新建PetItemInventroy模型 Step2 修改DemoMenu,增加访问入口 @UxMenu("商品库存")@UxRoute(PetItemInventroy.MODEL_MODEL) class PetItemInventroyMenu{} 图4-1-5-6 修改DemoMenu Step3 重启看效果 体验一:页面上新增、修改数据库字段中的opt_version会自动加一 图4-1-5-7 示例效果一 图4-1-5-8 示例效果二 图4-1-5-9 示例效果三 图4-1-5-10 示例效果四 体验二:同时打两个页面,依次点击,您会发现一个改成功,一个没有改成功。但页面都没有报错,只是update返回影响行数一个为1,另一个为0而已。 图4-1-5-11 编辑宠物商品库存 图4-1-5-12 宠物商品库存列表 注:增加了乐观锁,我们在写代码的时候一定要注意,单记录更新操作的时候要去判断返回结果(影响行数),不然没改成功,程序是不会抛错的。不像batch接口默认会报错 Step4 预留任务:重写PetItemInventroy的update函数 留个任务,请各位小伙伴自行测试玩玩,这样会更有体感 package pro.shushi.pamirs.demo.core.action; import org.springframework.stereotype.Component; import pro.shushi.pamirs.demo.api.enumeration.DemoExpEnumerate; import pro.shushi.pamirs.demo.api.model.PetItemInventroy; import pro.shushi.pamirs.demo.api.model.PetTalent; import pro.shushi.pamirs.meta.annotation.Function; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.common.exception.PamirsException; import pro.shushi.pamirs.meta.constant.FunctionConstants; import pro.shushi.pamirs.meta.enmu.FunctionOpenEnum; import pro.shushi.pamirs.meta.enmu.FunctionTypeEnum; import java.util.ArrayList; import java.util.List; @Model.model(PetItemInventroy.MODEL_MODEL) @Component public class PetItemInventroyAction { @Function.Advanced(type= FunctionTypeEnum.UPDATE) @Function.fun(FunctionConstants.update) @Function(openLevel = {FunctionOpenEnum.API}) public PetItemInventroy update(PetItemInventroy data){ List<PetItemInventroy> inventroys = new ArrayList<>(); inventroys.add(data); //批量更新会,自动抛错 int i =…

    2024年5月23日
    1.8K00
  • 5.5 基础支撑之结算域

    一、基础介绍 随着企业的业务不断进行数字化改造、业务越来越在线化,给企业财务工作带来几个明显的变化和挑战: 变化: 业务在线后,不同类收费、预售、授信模式的创新层出不穷,需要财务不仅只从事单一传统的会计核算工作,还需要积极地参与到业务中去。 从事后算账事后报账,变成财务业务一体化信息的实时处理 挑战: 业务系统与财务系统明显割裂,业务部门与财务部门各自采用一套软件处理其数据,不能及时沟通信息和协同更正信息。 财务系统往往都是单体的传统架构,凭证处理能力无法适应今天企业的不断爆棚的业务发展。 财务的严谨性与业务的灵活性中间有巨大的鸿沟,导致业务要做一种创新的模式,财务可能是最大阻碍。 不论是传统软件公司喜欢说的业财一体化还是互联网平台公司喜欢说的结算平台,都是为了解决以上变化和挑战的。业财一体化主要是从财务部门角度出发进行,在业务支撑上化被动为主动。结算中心往往是结合财务部门和业务运营部门的需求。如果拿我们下面介绍的,计费、账务、会计三个领域来说,业财一体化项目往往只包括账务和会计,结算中心往往包括:计费、账务、会计。或者说业财一体化弱化了计费,没有纳入企业统一管理,把如何计价给到了业务系统自行决定或者简单处理只要产生应收应付单据(计费详单)就好了。 结算域的是一个相对比较专业的领域,没有一定背景知识甚至连一些专业名词都很难理解,更不用说模型设计了,这里我尽快地简单去描述定位而不是描述细节。而且2.1.9版本的结算领域相对还是没有那么完善,这里介绍的是下个版本的内容,所以大家看当前版本的时候会有一些对不上。 二、子领域职责 图5-5-1 子领域职责 计费 计费的价值 随着企业多业务发展以及融合计费需求,我们需要引入计费模型,对灵活计价模式进行支持,快速支撑未来可能的计费方式等 计费的核心设计理念 所有的计算器都继承自虚函数计算器y=f(x) 平滑兼容-默认斜率计算器y=a+bxY – 求值结果(用下标描述结果是什么)A – 偏移量(计算固定值)B – 斜率(费率值)X – 变量(数量)任何计算都是通过一组斜率组合出来的 利用区间限定定义各种斜率组合出各种算法交易额0-100w:y=0.03x >100w:y=0.02x;时间0:00-6:00:y=0.02x 6:00-24:00:y=0.03xX- 变量,数量 图5-5-2 计费的核心设计理念 更灵活多维区间组合,时间维度、计数器维度、其它属性维度计数器区间斜率限定,比如交易额、空间、使用月份数… 计费的核心功能 通过产品定义运营方案 通过订购产品完成商务合同的签订来决定客户计费策略,或者通过系统产品定义通用计费策略 支撑各类产品的模拟计费 以事件驱动,根据事件、产品、订购关系完成产品路由,并实时产生计费详单 根据计费科目与账务科目,打通账务进行核销 账务 账务的价值 以账户账本为中心,提供记账、账户管理,以及账务的实时监控与持续对账。如果计费是对接业务,那么账务的价值是对接财务系统 账务的核心设计理念 不依赖计费,可独立对接,所有业务最终都需要反馈到帐户账本的操作上,并通过账本明细记录所有操作 账务的核心功能 记账:充值、转账、提现,冻结、解冻,差错处理 账务管理:开户、科目维护 账务查询:对账 会计(暂不在计划内) 会计的价值 结算平台的会计模块不是严格意义上的会计系统,它主要是衔接其他的财务系统,做凭证前置处理。在于汇总凭证,产出业务帐,对接到财务总帐系统,缓解财务系统压力。 三、模型介绍 图5-5-3 模型介绍 四、结算基础流程 图5-5-4 结算基础流程

    2024年5月23日
    1.3K00
  • 3.5.6.4 动作的配置

    在3.5.3【Action的类型】一文中,我们介绍Action的几种类型,以及组合动作。 通用配置 配置项 可选值 默认值 作用 name 动作名称 label 显示名称 icon 图标 type primary defaultlink primary 按钮类型样式,支持主要样式、次要样式以及链接样式。 bizStyle defaultsuccesswarningdangerinfo default 按钮业务样式,支持成功(green)、警告(yellow)、危险(red)、信息(grey)四种样式。 invisible truefalse condition false 展示规则,有简单的true/false显隐,也支持复杂的表达式 disabled truefalse condition 根据动作上下文类型进行自动推断 是否禁用自动推断规则:当上下文类型为【单行】时,相当于使用表达式LIST_COUNT(context.activeRecords) != 1当上下文类型为【多行】时,相当于使用表达式LIST_COUNT(context.activeRecords) <= 1当上下文类型为【单行或多行】时,相当于使用表达式LIST_COUNT(context.activeRecords) == 0 disabledTitle string 根据动作上下文类型进行自动推断 禁用悬浮提示 表3-5-6-12 动作通用配置 二次确认配置 二次确认框默认支持两种模式,对话框和气泡框; 对话框 图3-5-6-51 对话框提示 气泡框 图3-5-6-52 气泡框警告 配置项 配置项 可选值 默认值 作用 备注 confirm string 二次确认提示文字 配置后开启二次确认 confirmType POPPER(气泡提示框) MODAL(对话框) POPPER 确认框类型 confirmPosition TM(按钮上方) BM(按钮下方) LM(按钮左侧) RM(按钮右侧) BM 确认框位置 气泡框该配置生效 enterText 确定 确定按钮文字 cancelText 取消 取消按钮文字 表3-5-6-13 配置项 弹出层动作配置(窗口动作ViewAction) 目前平台对于弹出层支持了两种展示形式。弹窗(modal/dialog)和抽屉(drawer) 支持两种配置方式【内嵌视图配置】和【引用已有页面】,内嵌视图配置优先于引用已有页面。 内嵌视图配置 该配置对于弹窗和抽屉均适用。 <action name="窗口动作名称" label="创建"> <view model="模型编码" type="form"> <template slot="form" widget="form"> <field data="id" invisible="true" /> <field data="code" label="编码" widget="Input" /> <field data="name" label="名称" widget="Input" /> </template> <template slot="footer"> <action name="$$internal_DialogCancel" label="关闭" type="default" /> <action name="create" label="确定" /> </template> </view> </action> 图3-5-6-53 内嵌视图配置 引用已有页面配置 该配置对于弹窗和抽屉均适用。 <view model="模型编码" type="form"> <template slot="form" widget="form"> <field data="id" invisible="true" /> <field data="code" label="编码" widget="Input" /> <field data="name" label="名称" widget="Input" /> </template> <template slot="footer"> <action name="$$internal_DialogCancel" label="关闭" type="default" /> <action name="create" label="确定" /> </template> </view> 图3-5-6-54 引用已有页面示例 <action name="窗口动作名称" label="创建" resViewName="$viewName$" /> 图3-5-6-55 引用已有页面 弹窗 当窗口动作的路由方式(target)为dialog时,内嵌视图/引用页面将以弹窗形式展示在页面上。 配置项 配置项 可选值 默认值 作用 title…

    2024年5月23日
    1.4K00

Leave a Reply

Please Login to Comment