自定义createorupdate方法时,关联模型数据怎么保存?

需要自己手动增加保存关联模型数据的逻辑。

  • 多对一、一对一以及一对多

可直接用fieldSave进行保存即可

//如 data.fieldSave(PamirsEmployee::getPositions);
  • 多对多

需要对数据进行处理,前端提交过来的数据,进行判断,是新增还是修改,或者删除

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

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

(0)
oinone的头像oinone
上一篇 2023年6月20日 pm4:07
下一篇 2023年11月2日 pm1:58

相关推荐

  • 工作流审核撤回/回退/拒绝/同意/反悔钩子使用

    目录 1. 流程撤回、拒绝和回退调用自定义函数1.1 工作流【撤销】回调钩子1.2 撤销【回退】回调钩子1.3 工作流【拒绝】回调钩子1.4 工作流【同意】回调钩子1.4 工作流【反悔】回调钩子1.4 回调钩子在业务系统中的调用示例2. 自定义审批方式、自定义审批节点名称 1.流程撤回、拒绝和回退调用自定义函数 1.1工作流【撤销】回调钩子 使用方式:把该方法放置到XXX模型的Action下面,或@Fun(XXX.MODEL_MODEL)触发方式:当流程实例被撤销时调用入口:pro.shushi.pamirs.workflow.app.core.service.impl.WorkflowInstanceServiceImpl#undoInstance /** * XXX为当前流程触发方式为模型触发时对应的触发模型、 * 对应返回不影响流程上下文 * @param data 入参为触发时的业务数据,数据的JsonString * @return */ @Function public XXX recall(String data) { // TODO: 根据实际的业务逻辑把data转换为对象 WorkRecord workRecord = JsonUtils.parseObject(data, new TypeReference<WorkRecord>(){}); // TODO: 增加自定义业务逻辑 return new XXX(); } 1.2撤销【回退】回调钩子 使用方式:把该方法放置到XXX模型的Action下面,或@Fun(XXX.MODEL_MODEL)触发方式:流程待办进行回退操作时调用入口:pro.shushi.pamirs.workflow.app.core.service.operator.ApprovalFallbackOperatorService /** * XXX为当前流程触发方式为模型触发时对应的触发模型 * 对应返回不影响流程上下文 * @param data 入参为触发时的业务数据,数据的JsonString * @return */ @Function public XXX fallBack(String data) { // TODO: 根据实际的业务逻辑把data转换为对象 WorkRecord workRecord = JsonUtils.parseObject(data, new TypeReference<WorkRecord>(){}); // TODO: 增加自定义业务逻辑 return new XXX(); } 1.3工作流【拒绝】回调钩子 使用方式:把该方法放置到XXX模型的Action下面,或@Fun(XXX.MODEL_MODEL)触发方式:流程待办进行拒绝操作时调用入口:pro.shushi.pamirs.workflow.app.core.service.operator.ApprovalFallbackOperatorService /** * XXX为当前流程触发方式为模型触发时对应的触发模型 * 对应返回不影响流程上下文 * @param data 入参为触发时的业务数据,数据的JsonString * @return */ @Function public XXX reject(String data) { // TODO: 根据实际的业务逻辑把data转换为对象 WorkRecord workRecord = JsonUtils.parseObject(data, new TypeReference<WorkRecord>(){}); // TODO: 增加自定义业务逻辑 return new XXX(); } 1.4 工作流【同意】回调钩子 使用方式:把该方法放置到XXX模型的Action下面,或@Fun(XXX.MODEL_MODEL)触发方式:流程待办进行同意操作时调用入口:pro.shushi.pamirs.workflow.app.core.util.ArtificialTaskUtils @Function(summary = "发起的审批同意时会自动调用此方法") @Function.Advanced(displayName = "审批同意") public Teacher agree(String data) { // TODO: 根据实际的业务逻辑把data转换为对象 // WorkRecord workRecord = JsonUtils.parseObject(data, new TypeReference<WorkRecord>(){}); // TODO: 增加自定义业务逻辑 return new Teacher(); } 1.4 工作流【反悔】回调钩子 使用方式:把该方法放置到XXX模型的Action下面,或@Fun(XXX.MODEL_MODEL)触发方式:流程待办进行反悔操作时使用场景:流程待办进行反悔操作时,需要额外更改其他的业务数据逻辑时可用该回调钩子。 注意:该函数的namespace需要设置为流程触发模型。 调用入口:pro.shushi.pamirs.workflow.app.core.service.operator.ArtificialRetractOperatorService @Function @Function.fun(WorkflowBizCallConstants.retract) public void retract(WorkflowUserTask workflowUserTask) { // 获取流程实例 workflowUserTask.fieldQuery(WorkflowUserTask::getInstance); WorkflowInstance instance = workflowUserTask.getInstance(); // 获取用户任务实例 WorkflowUserInstance userInstance = new WorkflowUserInstance() .setId(workflowUserTask.getWorkflowUserInstanceId()) .queryById(); // 反悔的用户id…

    2023年11月15日
    1.4K00
  • action 和 function 有什么区别

    在 Oinone(开源低代码 / 企业应用开发平台) 里,Action 和 Function 都是“可被调用的逻辑单元”,但它们的定位和使用场景不同。可以简单理解为: Function = 纯逻辑函数(偏后端能力) Action = 面向业务操作的动作(偏应用行为 / UI触发) 下面给你详细对比一下。 1️⃣ Function:函数(逻辑能力) Function 更像是一个 可复用的服务方法。 特点 通常是 纯逻辑处理 不直接绑定 UI 可以被 Action / Service / 其他 Function 调用 用来封装 业务计算或工具逻辑 常见用途 比如: 价格计算 数据校验 数据转换 调用第三方 API 复杂业务规则 示例 @Function(openLevel = FunctionOpenEnum.API) @Function.Advanced(type = FunctionTypeEnum.QUERY) public TradeOrder computePrice(TradeOrder data) { return data; } 用途: 订单金额计算逻辑 然后可能被多个地方调用: Action -> 调用 Function Service -> 调用 Function Workflow -> 调用 Function 📌 核心:可复用业务逻辑 2️⃣ Action:动作(业务操作) Action 是一个 业务动作,通常是 用户触发的行为。 特点 通常绑定 UI 可以在 按钮 / 菜单 / API / 工作流 中触发 通常操作 模型数据 可以调用 Function 常见用途 例如: 创建订单 提交审批 发布文章 批量删除 导入数据 示例 @Action public void submitOrder(Order order){ order.setStatus("SUBMITTED"); } UI 可能是: 订单详情页 [提交订单] 按钮 点击按钮 → 调用 Action。 📌 核心:业务行为入口 3️⃣ 核心区别总结 维度 Action Function 定位 业务动作 逻辑函数 是否绑定 UI 通常是 否 是否直接给用户操作 是 否 是否可复用 一般 很高 是否操作模型 常见 不一定 调用关系 可调用 Function 不调用 Action 4️⃣ 调用关系(典型架构) 通常推荐的结构: UI按钮 ↓ Action(业务入口) ↓ Function(业务逻辑) ↓ DAO / Repository 例如: 提交订单按钮 ↓ submitOrderAction ↓ checkInventoryFunction calcPriceFunction createOrderFunction 这样: Action 只负责 流程 Function 负责 逻辑 代码会更清晰。 5️⃣…

    前端 1天前
    600
  • Oinone平台可视化调试工具

    为方便开发者定位问题,我们提供了可视化的调试工具。
    该文档将介绍可视化调试工具的基本使用方法。

    2024年4月13日
    1.4K00
  • 后端代码规范

    前言 虽然oinone框架减少了很多的代码,但是低代码部分的代码质量也需要高度关注,不管是写的代码bug多,或者说被吐槽代码不行,还是说写的代码经常被重构,核心点还是没有代码规范的意识和技巧,下面摘录了一些常见的规范要求,去提高后端的代码质量,代码质量提高后,自然效率也会提升。 常见代码规范 **1、规范命名** 命名是写代码中最频繁的操作,比如类、属性、方法、参数等。好的名字应当能遵循以下几点: **见名知意** 比如需要定义一个变量需要来计数 int i = 0; 名称 i 没有任何的实际意义,没有体现出数量的意思,所以我们应当指明数量的名称 int count = 0; **能够读的出来** 如下代码: private String sfzh; private String dhhm; 这些变量的名称,根本读不出来,更别说实际意义了。 所以我们可以使用正确的可以读出来的英文来命名 private String idCardNo; private String phone; **2、规范代码格式** 好的代码格式能够让人感觉看起来代码更加舒适。 好的代码格式应当遵守以下几点: 合适的空格 代码对齐,比如大括号要对齐 及时换行,一行不要写太多代码 好在现在开发工具支持一键格式化,可以帮助美化代码格式,大家统一使用idea的规范即可。 **3、写好代码注释** 在《代码整洁之道》这本书中作者提到了一个观点,注释的恰当用法是用来弥补我们在用代码表达意图时的失败。换句话说,当无法通过读代码来了解代码所表达的意思的时候,就需要用注释来说明。 书的作者之所以这么说,是因为作者觉得随着时间的推移,代码可能会变动,如果不及时更新注释,那么注释就容易产生误导,偏离代码的实际意义。而不及时更新注释的原因是,程序员不喜欢写注释。😒 但是这不意味着可以不写注释,当通过代码如果无法表达意思的时候,就需要注释,比如如下代码: for (Integer id : ids) { if (id == 0) { continue; } //做其他事 } 为什么 id == 0 需要跳过,代码是无法看出来了,就需要注释了。 好的注释应当满足一下几点: 解释代码的意图,说明为什么这么写,用来做什么 对参数和返回值注释,入参代表什么,出参代表什么 有警示作用,比如说入参不能为空,或者代码是不是有坑 当代码还未完成时可以使用 todo 注释来标记 代码review发现漏洞时 可以使用 fixme 注释来标记 **4、try catch 内部代码抽成一个方法** try catch代码有时会干扰我们阅读核心的代码逻辑,这时就可以把try catch内部主逻辑抽离成一个单独的方法 如下图是Eureka服务端源码中服务下线的实现中的一段代码 整个方法非常长,try中代码是真正的服务下线的代码实现,finally可以保证读锁最终一定可以释放。 所以这段代码其实就可以对核心的逻辑进行抽取。 protected boolean internalCancel(String appName, String id, boolean isReplication) { try { read.lock(); doInternalCancel(appName, id, isReplication); } finally { read.unlock(); } // 剩余代码 } private boolean doInternalCancel(String appName, String id, boolean isReplication) { //真正处理下线的逻辑 } **5、方法别太长** 方法别太长就是字面的意思。一旦代码太长,给人的第一眼感觉就很复杂,让人不想读下去; 同时方法太长的代码可能读起来容易让人摸不着头脑,不知道哪一些代码是同一个业务的功能。 比如代码中有那种2000+行大类,各种if else判断,光理清代码思路就需要用很久时间。🤷🏻‍♀️ 所以一旦方法过长,可以尝试将相同业务功能的代码单独抽取一个方法,最后在主方法中调用即可。 **6、抽取重复代码** 当一份代码重复出现在程序的多处地方,就会造成程序又臭又长,当这份代码的结构要修改时,每一处出现这份代码的地方都得修改,导致程序的扩展性很差。 所以一般遇到这种情况,可以抽取成一个工具类,还可以抽成一个公共的父类。 **7、多用return** 在有时我们平时写代码的情况可能会出现if条件套if的情况,当if条件过多的时候可能会出现如下情况: if (条件1) { if (条件2) { if (条件3) { if (条件4) { if (条件5) { System.out.println("11111"); } } } } } 面对这种情况,可以换种思路,使用return来优化 if (!条件1) { return; } if (!条件2) { return; } if (!条件3) { return; } if (!条件4) { return; } if (!条件5) { return; } System.out.println("11111"); 这样优化就感觉看起来更加直观 **8、if条件表达式不要太复杂**…

    2024年12月11日
    2.7K00
  • Oinone协同开发使用手册

    概述 Oinone平台为开发人员提供了本地环境 – 测试环境之间的协同开发模式,可以使得开发人员在本地环境中设计的模型、函数等元数据实时被测试环境使用并设计。开发人员开发完成对应页面和功能后,可以部署至测试环境直接进行测试。 本篇文章将详细介绍协同开发模式在实际开发中的应用及相关内容。 名词解释 本地环境: 开发人员的本地启动环境 测试环境: 在测试服务器上部署的业务测试环境,业务工程服务和设计器服务共用中间件 业务工程服务:在测试服务器上部署的业务工程 设计器服务: 在测试服务器上部署的设计器镜像 一套环境:以测试环境为例,业务工程服务和设计器服务共同组成一套环境 生产环境: 在生产服务器上部署的业务生产环境 环境准备 部署了一个可用的设计器服务,并能正常访问。(需参照下文启动设计器环境内容进行相应修改) 准备一个用于开发的java工程。 准备一个用于部署测试环境的服务器。 协同参数介绍 用于测试环境的参数 -PmetaProtected=${value} 启用元数据保护,只有配置相同启动参数的服务才允许对元数据进行更新。通常该命令用于设计器服务和业务工程服务,并且两个环境需使用相同的元数据保护标记(value)进行启动。本地环境不使用该命令,以防止本地环境在协同开发时意外修改测试环境元数据,导致元数据混乱。 用法 java -jar boot.jar -PmetaProtected=pamirs 用于本地环境的配置 使用命令配置ownSign(推荐) java -jar boot.jar –pamirs.distribution.session.ownSign=demo 使用yaml配置ownSign pamirs: distribution: session: allMetaRefresh: false # 启用元数据全量刷新(备用配置,如遇元数据错误或混乱,启用该配置可进行恢复,使用一次后关闭即可) ownSign: demo # 协同开发元数据隔离标记,用于区分不同开发人员的本地环境,其他环境不允许使用 启动设计器环境 docker-run启动 -e PROGRAM_ARGS=-PmetaProtected=pamirs docker-compose启动 services: backend: container_name: designer-backend image: harbor.oinone.top/oinone/designer-backend-v5.0 restart: always environment: # 指定spring.profiles.active ARG_ENV: dev # 指定-Plifecycle ARG_LIFECYCLE: INSTALL # jvm参数 JVM_OPTIONS: "" # 程序参数 PROGRAM_ARGS: "-PmetaProtected=pamirs" PS: java [JVM_OPTIONS?] -jar boot.jar [PROGRAM_ARGS?] 开发流程示例图 具体使用步骤详见协同开发支持

    2024年7月24日
    2.1K00

Leave a Reply

登录后才能评论