4.1.19 框架之网关协议-后端占位符

在我们日常开发中会有碰到一些特殊场景,需要由前端来传一些如“当前用户Id”、“当前用户code”诸如此类只有后端才知道值的参数,那么后端占位符就是来解决类似问题的。如前端传${currentUserId},后端会自动替换为当前用户Id。

Step1 后端定义占位符

我们新建一个UserPlaceHolder继承AbstractPlaceHolderParser,用namespace来定义一个“currentUserId”的占位符,其对应值由value()决定为“PamirsSession.getUserId().toString()”,active要为真才有效,priority为优先级

package pro.shushi.pamirs.demo.core.placeholder;

import org.springframework.stereotype.Component;
import pro.shushi.pamirs.meta.api.session.PamirsSession;
import pro.shushi.pamirs.user.api.AbstractPlaceHolderParser;

@Component
public class UserPlaceHolder extends AbstractPlaceHolderParser {
    @Override
    protected String value() {
        return PamirsSession.getUserId().toString();
    }

    @Override
    public Integer priority() {
        return 10;
    }

    @Override
    public Boolean active() {
        return Boolean.TRUE;
    }

    @Override
    public String namespace() {
        return "currentUserId";
    }
}

图4-1-19-1 后端定义占位符

Step2 前端使用后端占位符

我们经常在o2m和m2m中会设置domain来过滤数据,这里案例就是在field中设置来过滤条件,domain="createUid == $#{currentUserId}",注意这里用的是$#{currentUserId} 而不是${currentUserId},这是前端为了区分真正变量和后端占位符,提交的时候会把#过滤掉提交。修改宠物达人表格视图的Template中search部分

<template slot="search"  cols="4">
    <field data="name" label="达人"/>
    <field data="petTalentSex" multi="true" label="达人性别"/>
    <field data="creater" />
<!--        <field data="petShops" label="宠物商店" domain="createUid == ${activeRecord.creater.id}"/>-->
    <field data="petShops" label="宠物商店" domain="createUid == $#{currentUserId}"/>
    <field data="dataStatus" label="数据状态" multi="true">
        <options>
            <option name="DRAFT" displayName="草稿" value="DRAFT" state="ACTIVE"/>
            <option name="NOT_ENABLED" displayName="未启用" value="NOT_ENABLED" state="ACTIVE"/>
            <option name="ENABLED" displayName="已启用" value="ENABLED" state="ACTIVE"/>
            <option name="DISABLED" displayName="已禁用" value="DISABLED" state="ACTIVE"/>
        </options>
    </field>
    <field data="createDate" label="创建时间"/>
    <field data="unStore" />
</template>

图4-1-19-2 前端使用后端占位符

Step3 重启看效果

请求上都带上了createUid==${currentUserId}

image.png

图4-1-19-3 示例效果

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

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

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

相关推荐

  • 工作流

    1. 查看、处理流程 1.1 流程查看 流程管理页面共同点: 选项分类筛选 标签筛选 应用下拉选筛选 根据流程名称搜索 流程管理页面名词解释: 任务待办:当前登录用户未处理的流程节点 我发起的:当前登录用户人为触发的流程(模型触发) 抄送:抄送给当前登录用户的节点(审批/填写) 我已办结:由当前登录用户完成人工/自动同意、人工拒绝或人工填写的节点 无需办理:当前登录用户转交的任务/被退回、被撤销、被或签、被其他分支任务拒绝的还未办理的任务 1.2 流程处理 1.2.1 任务待办 任务待办中点击“审批/填写”会进入流程详情处理页面,主要展示 1. 操作区 2. 流程发起人及状态 3. 模型视图内容 4. 流程时间线及其他记录。 审批代办操作区可能包含“分享、同意、拒绝、退回、加签、转交、返回”,填写代办操作区可能包含“分享、转交、提交、暂存、返回”,审批/填写操作区包含哪些动作由流程设计决定。 1.2.2 我发起的 我发起的流程列表中主要分为进行中和已完成的流程。进行中的流程可以进行查看、催办、撤销的操作,已完成的流程可以进行查看操作。 查看我发起的流程,进入流程详情页面,也是根据流程状态展示对应操作功能,进行中的流程有分享、催办、撤销、返回按钮,已完成的流程有分享、返回按钮。 1.2.3 抄送 抄送列表中每条抄送只可以进行查看操作,查看进入流程的详情页面,有分享和返回的操作。 1.2.4 我已办结 我已办结列表中可以进行查看操作,查看进入代办的详情页面,可以进行分享和返回的操作。 1.2.5 无需办理 无需办理列表中可以进行查看操作,查看进入代办的详情页面,可以进行分享和返回的操作。 2. 流程运行记录查看 所有运行流程都会记录在流程运行记录中,可以根据流程的所属应用,流程名称,触发方式和状态进行搜索,流程运行记录详情中展示流程运行的具体节点,运行时间,当前运行节点,异常信息等。

    2024年6月20日
    2.2K00
  • 4.1.20 框架之Session

    在日常开发中,我们经常需要把一些通用的信息放入程序执行的上下文中,以便业务开发人员快速获取。那么oinone的PamirsSession就是来解决此类问题的。 一、PamirsSession介绍 在oinone的体系中PamirsSession是执行上下文的承载,您能从中获取业务基础信息、指令信息、元数据信息、环境信息、请求参数,以及前后端MessageHub等。在前面的学习过程中我们已经多次接触到了如何使用PamirsSession: 在4.1.19【框架之网关协议-后端占位符】一文中,使用PamirsSession.getUserId()来获取当前登入用户Id,诸如此类的业务基础信息; 在4.1.18【框架之网关协议-variables变量】一文中,使用PamirsSession.getRequestVariables()得到PamirsRequestVariables对象,进而获取前端请求的相关信息; 在4.1.5【模型之持久层配置】一文中,使用PamirsSession.directive(),来操作元位指令系统,进而影响执行策略; 在4.1.13【Action之校验】、3.4.1【构建第一个Function】等文章中,都用到PamirsSession.getMessageHub()来设置返回消息。 二、构建模块自身Session(举例) 不同的应用场景对PamirsSession的诉求是不一样的,这个时候我们就可以去扩展PamirsSession来达到我们的目的 构建模块自身Session的步骤 构建自身特有的数据结构XSessionData 对XSessionData进行线程级缓存封装 利用Hook机制初始化XSessionData并放到ThreadLocal中 定义自身XSessionApi 实现XSessionApi接口、SessionClearApi。在请求结束时会调用SessionClearApi的clear方法 定义XSession继承PamirsSession 扩展PamirsSession的经典案例设计图 图4-1-20-1 扩展PamirsSession的经典案例设计图 构建Demo应用自身Session 下面的例子为给Session放入当前登陆用户 Step1 新建DemoSessionData类 构建自身特有的数据结构DemoSessionData,增加一个模型为PamirsUser的字段user,DemoSessionData用Data注解,注意要用Oinone平台提供的@Data package pro.shushi.pamirs.demo.core.session; import pro.shushi.pamirs.meta.annotation.fun.Data; import pro.shushi.pamirs.user.api.model.PamirsUser; @Data public class DemoSessionData { private PamirsUser user; } 图4-1-20-2 新建DemoSessionData类 Step2 新建DemoSessionCache 对DemoSessionData进行线程级缓存封装 package pro.shushi.pamirs.demo.core.session; import pro.shushi.pamirs.meta.api.CommonApiFactory; import pro.shushi.pamirs.meta.api.session.PamirsSession; import pro.shushi.pamirs.user.api.model.PamirsUser; import pro.shushi.pamirs.user.api.service.UserService; public class DemoSessionCache { private static final ThreadLocal<DemoSessionData> BIZ_DATA_THREAD_LOCAL = new ThreadLocal<>(); public static PamirsUser getUser(){ return BIZ_DATA_THREAD_LOCAL.get()==null?null:BIZ_DATA_THREAD_LOCAL.get().getUser(); } public static void init(){ if(getUser()!=null){ return ; } Long uid = PamirsSession.getUserId(); if(uid == null){ return; } PamirsUser user = CommonApiFactory.getApi(UserService.class).queryById(uid); if(user!=null){ DemoSessionData demoSessionData = new DemoSessionData(); demoSessionData.setUser(user); BIZ_DATA_THREAD_LOCAL.set(demoSessionData); } } public static void clear(){ BIZ_DATA_THREAD_LOCAL.remove(); } } 图4-1-20-3 对DemoSessionData进行线程级缓存封装 Step3 新建DemoSessionHook 利用Hook机制,调用DemoSessionCache的init方法初始化DemoSessionData并放到ThreadLocal中。 @Hook(module= DemoModule.MODULE_MODULE), 规定只有增对DemoModule模块访问的请求该拦截器才会生效,不然其他模块的请求都会被DemoSessionHook拦截。 package pro.shushi.pamirs.demo.core.hook; import org.springframework.stereotype.Component; import pro.shushi.pamirs.demo.api.DemoModule; import pro.shushi.pamirs.demo.core.session.DemoSessionCache; import pro.shushi.pamirs.meta.annotation.Hook; import pro.shushi.pamirs.meta.api.core.faas.HookBefore; import pro.shushi.pamirs.meta.api.dto.fun.Function; @Component public class DemoSessionHook implements HookBefore { @Override @Hook(priority = 1,module = DemoModule.MODULE_MODULE) public Object run(Function function, Object… args) { DemoSessionCache.init(); return function; } } 图4-1-20-4 新建DemoSessionHook Step4 新建DemoSessionApi package pro.shushi.pamirs.demo.core.session; import pro.shushi.pamirs.meta.api.CommonApi; import pro.shushi.pamirs.user.api.model.PamirsUser; public interface DemoSessionApi extends CommonApi { PamirsUser getUser(); } 图4-1-20-5 新建DemoSessionApi Step5…

    2024年5月23日
    1.8K00
  • 3.4.3 函数的相关特性

    本小章会从oinone的函数拥有三方面特性,展开介绍 面向对象,继承与多态 面向切面编程,拦截器 SPI机制,扩展点

    Oinone 7天入门到精通 2024年5月23日
    1.4K00
  • 7.3.2 原业务加审批流程

    场景说明 场景描述:全员营销标准产品的功能并未有任务发放的审批流,在实际执行中,当营销专员配置好任务后,需部门领导对整个活动如该任务内容、形式、参与人员进行审批。 业务需求:在发布任务这个流程中增加审批节点。 实战训练 Step1 原业务分析 点击菜单【任务中心】通过URL上的model参数找到对应模型编码为【gemini.biz.GeminiTaskProxy】 进入模型设计器主页面,应用选择【全员营销】、选择【系统模型】、通过搜索关键字【任务】选择【Gemini任务代理】,展示方式从图模式切换到表单模式,对比【模型编码】 但目前模型为代理模型,代理模型是用于代理存储模型的数据管理器能力,同时又可以扩展出非存储数据信息的交互功能的模型。因为在代理模型中新增的字段都是非存储字段,所以如果要增加【审核状态】的字段一定以要在存储模型增加。其父模型的查看有两种方式 表单模式下可以直接看父模型 在图模式和表单模式下点击继承关系 点击【Gemini任务】,进入【Gemini任务】的模型设计界面,可以看出该模型所在模块为【全员营销核心业务】,从【系统字段】中找到【任务状态】字段,点击查看字段详情,我们可以看到【业务类型】为数据字典,字典类型为【任务状态】。 在模型设计器的管理页面上方点击【数字字典】选项卡,模块选择为【全员营销核心业务】,选择【系统字典】就可以查看到【任务状态】数字字典 总结如下: 给【Gemini任务】模型增加一个【任务审批状态】,记录审批状态 在任务创建的时候,修改【任务状态】为【关闭】确保任务未审批通过的时,用户无法操作该任务。 审批通过后,恢复【任务状态】为【初始化】 我们先来整理下核心流程即:任务审批流程。 Step2 利用模型设计器设计模型 在模型设计器的管理页面上方点击【数字字典】选项卡,模块选择为【全员营销核心业务】,点击添加【数据字典】按钮,设置对应数据项 设置【字典名称】为【审批状态】 设置【字典项类型】为【文本】 通过【添加数据字典项】按钮增加对应数据字典项,如审核中、审核失败、审核成功 在模型设计器的管理页面上方点击【模型】选项卡,模块选择为【全员营销核心业务】,选择【系统模型】、搜索任务选择【Gemini任务】,点击添加字段 为模型【Gemini任务】添加字段 设置【字段名称】为【任务审批状态】 设置【字段业务类型】为数据字典,并选择关联数据字典为【任务审批状态】 最后点击【创建】按钮完成操作 回到【Gemini任务】设计区,我们可以看到在模型的【自定义字段】选项卡下方多了一个【任务审批状态】字段 Step3 利用界面设计器,设计出必要的审核页面 进入界面设计器,应用选择全员营销,模型选择【Gemini任务】,点击添加页面下的直接创建 设置页面标题、模型(自动带上可切换)、业务类型(运营管理后续会扩展其他类型)、视图类型(表单)后点击确认按钮进入【Gemini任务】表单设计页面 进入页面设计器,对【Gemini任务】表单页面进行设计(更多细节介绍,请参考界面设计产品使用手册) 左侧为物料区:分为组件、模型。 【组件】选项卡下为通用物料区,我们可以为页面增加对应布局、字段(如同在模型设计器增加字段)、动作、数据、多媒体等等 【模型】选项卡下为页面对应模型的自定义字段、系统字段、以及模型已有动作 中间是设计区域 右侧为属性面板,在设计区域选择中组件会显示对应组件的可配置参数 在左侧【组件】选项卡下,拖入布局组件【分组】,并设置组件【标题属性】为基础信息 在左侧【模型】选项卡下,分别系统字段中的【任务标题】、【任务开始时间】、【任务结束时间】、【视频标题】、【视频风格】、【任务描述】拖入【基础信息】分组,并点击【任务描述】,在右侧属性面板的【交互】分组中设置宽度为1。最后别忘了点击【发布】按钮完成页面的发布 Step4 通过流程设计器,设计对应业务流程 进入流程设计器,点击【创建】按钮 注意:流程中需要获取【关系字段】的除关联字段(一般为ID)以外的字段需要通过【数据获取】节点单独获取【关系字段】的对象数据。所以在流程设计中经常会用到【数据获取】节点 左上角编辑流程名称为【任务审批流程】,点击第一个【触发】节点,触发方式选择模型触发,模型选择【Gemini任务】,触发场景选择【新增或更新数据时】,【筛选条件】设置为【任务审批状态】为空或【任务审批状态】等于【审核中】,点击该节点的【保存】按钮 点击流程图节点间的【+】图标选择增加【获取数据】节点,或者拖动左侧物料区【获取数据】到特定的【+】图标 点击【获取数据】,在右侧属性面板中设置【获取数据条数】为多条,选择模型为【Gemini用户任务实例】,点击【筛选条件】的【{X}】图标,进行数据获取的条件设置 选择条件字段为【任务ID】条件操作符为【等于】,条件为变量的导购字段的ID。当上下文只有一个变量时默认不需要选择,这里默认的是【模型触发:[Gemini任务]】,设置好以后点击确认,回到属性面板设置【未获取到数据时执行方式】为【终止流程】,并点击节点【保持】按钮 增加【更新数据】节点,在右侧属性面板中 【更新模型】选择【模型触发:[Gemini任务]】 【字段列表】点击【创建】按钮 字段选择 更新【任务状态】字段 表达式设置为:【已关闭】。 【字段列表】点击【创建】按钮 字段选择 更新【任务审核状态】字段 表达式设置为:【审核中】。 最终完成的【模型触发:[Gemini任务]】更新设置 a. 【模型触发:[Gemini任务]】的【任务状态】字段等于数字字典的【已关闭】,任务审核状态为【审核中】 b. 最后点击节点【保持】按钮。 再增加【更新数据】节点,在右侧属性面板中 【更新模型】选择【获取数据[Gemini用户任务实例]】 【字段列表】点击【创建】按钮 字段选择 更新【任务状态】字段 表达式设置为:【已关闭】。 最终完成的【获取数据[Gemini用户任务实例]】更新设置 a. 【获取数据[Gemini用户任务实例]】的【任务状态】字段等于数字字典的【已关闭】 b. 最后点击节点【保持】按钮。 增加【审批】节点,在右侧属性面板中 【审批模型】选择模型为【模型触发:[Gemini任务]】 【选择视图】选择前面新建的页面【流程中的任务编辑页】 【审批人】选择角色为【超级管理员】 【数据】权限全部设置为【查看】 其他配置项默认,需要了解更多请查看产品使用手册 最后点击节点【保持】按钮。 新增【审核分支】,在【通过】分支中增加两个数据更新节点,跟审核前的两个数据更新节点对应 【模型触发:[Gemini任务]】的【任务状态】字段等于数字字典的【初始化】,任务审核状态为【审核通过】 【获取数据[Gemini用户任务实例]】的【任务状态】字段等于数字字典的【初始化】 流程确保保持并发布过,点击右上角【发布流程】完成流程的保存与发布 Step5 检验效果 创建任务后,任务状态为【关闭】状态,任务列表中的任务状态为多个状态的计算值 审核通过后,任务状态为【进行中】状态,任务列表中的任务状态为多个状态的计算值

    2024年5月23日
    1.7K00

Leave a Reply

Please Login to Comment