4.1.18 框架之网关协议-Variables变量

我们在应用开发过程有一种特殊情况在后端逻辑编写的时候需要知道请求的发起入口,平台利用GQL协议中的Variables属性来传递信息,本文就介绍如何获取。

一、前端附带额外变量

属性名 类型 说明
scene String 菜单入口

表4-1-18-1 前端附带额外变量

image.png

图4-1-18-1 variables信息中的scene

二、后端如何接收variables信息

通过PamirsSession.getRequestVariables()可以得到PamirsRequestVariables对象。

三、第一个variable(举例)

Step1 修改PetTalentAction,获取得到前端传递的Variables

package pro.shushi.pamirs.demo.core.action;
……类引用
@Model.model(PetTalent.MODEL_MODEL)
@Component
public class PetTalentAction {
……其他代码
 @Function.Advanced(type= FunctionTypeEnum.QUERY)
 @Function.fun(FunctionConstants.queryPage)
 @Function(openLevel = {FunctionOpenEnum.API})
 public Pagination<PetTalent> queryPage(Pagination<PetTalent> page, IWrapper<PetTalent> queryWrapper){
 String scene = (String)PamirsSession.getRequestVariables().getVariables().get("scene");
 System.out.println("scene: "+ scene);
 ……其他代码
 }
……其他代码
}

图4-1-18-2 修改PetTalentAction

Step2 重启验证

点击宠物达人不同菜单入口,查看效果

image.png

图4-1-18-3 示例效果(一)

image.png

图4-1-18-4 示例效果(二)

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

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

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

相关推荐

  • 6.1 文件与导入导出(改)

    导入导出在一定程度上是企业级软件和效率工具(office工具)的桥梁 文件的上传下载以及业务数据的导入导出是企业级软件一个比较常规的需求,甚至是巨量的需求。业务有管理需要一般都伴随有导入导出需求,导入导出在一定程度上是企业级软件和效率工具(office工具)的桥梁。oinone的文件模块就提供了通用的导入导出实现方案,以简单、一致、可扩展为目标,简单是快速入门,一致是用户操作感知一致、可扩展是满足用户最大化的自定义需求。 下图为文件导入导出的实现示意图,大家可以做一个整体了解 图6-1-1 文件导入导出实现示意图 一、基础能力 准备工作 pamirs-demo-api的pom文件中引入pamirs-file2-api包依赖 <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-file2-api</artifactId> </dependency> 图6-1-2 引入pamirs-file2-api包依赖 DemoModule增加对FileModule的依赖 @Module(dependencies = {FileModule.MODULE_MODULE}) 图6-1-3 DemoModule增加对FileModule的依赖 pamirs-demo-boot的pom文件中引入pamirs-file2-core包依赖 <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-file2-core</artifactId> </dependency> 图6-1-4 启动工程引入pamirs-file2-core包依赖 pamirs-demo-boot的application-dev.yml文件中增加配置pamirs.boot.modules增加file,即在启动模块中增加file模块 pamirs: boot: modules: – file 图6-1-5 pamirs-demo-boot的application-dev.yml文件中增加配置 pamirs-demo-boot的application-dev.yml文件中增加oss的配置。更多有关文件相关配置详见4.1.1【模块之yml文件结构详解】一文 cdn: oss: name: 阿里云 type: OSS bucket: demo uploadUrl: #换成自己的oss上传服务地址 downUrl: #换成自己的oss下载服务地址 accessKeyId: #阿里云oss的accessKeyId accessKeySecret: #阿里云oss的accessKeySecret mairDir: upload/demo #换成自己的目录 validTime: 360000 timeout: 60000 active: true referer: www.shushi.pro 图6-1-6 application-dev.yml文件中增加oss的配置 其他文件系统支持 a. 文件系统类型 类型 服务 OSS 阿里云 UPYUN 又拍云 MINIO Minio HUAWEI_OBS 华为云 LOCAL 本地文件存储 表6-1-1 支持的文件系统类型 b. OSS配置示例 ⅰ. 华为云OBS cdn: oss: name: 华为云 type: HUAWEI_OBS bucket: pamirs #(根据实际情况修改) uploadUrl: obs.cn-east-2.myhuaweicloud.com downloadUrl: obs.cn-east-2.myhuaweicloud.com accessKeyId: 你的accessKeyId accessKeySecret: 你的accessKeySecret # 根据实际情况修改 mainDir: upload/ validTime: 3600000 timeout: 600000 active: true allowedOrigin: http://192.168.95.31:8888,https://xxxx.xxxxx.com referer: 图6-1-7 OBS的配置说明 ⅱ. MINIO cdn: oss: name: minio type: MINIO bucket: pamirs #(根据实际情况修改) uploadUrl: http://192.168.243.6:32190 #(根据实际情况修改) downloadUrl: http://192.168.243.6:9000 #(根据实际情况修改) accessKeyId: 你的accessKeyId accessKeySecret: 你的accessKeySecret # 根据实际情况修改 mainDir: upload/ validTime: 3600000 timeout: 600000 active: true referer: localFolderUrl: 图6-1-8 MINIO的配置说明 ⅲ. 又拍云 cdn: oss: name: 又拍云 type: UPYUN bucket: pamirs #(根据实际情况修改) uploadUrl: v0.api.upyun.com downloadUrl: v0.api.upyun.com accessKeyId: 你的accessKeyId accessKeySecret: 你的accessKeySecret # 根据实际情况修改 mainDir: upload/ validTime: 3600000 timeout: 600000…

    2024年5月23日
    1.7K00
  • 资源

    翻译应用是管理翻译规则的应用,以模型为基础、维护字段的翻译值,支持导入、导出 1. 操作步骤 Step1:导出所有翻译项; Step2:线下翻译; Step3:导入翻译项; Step4:刷新远程资源; Step5:页面右上角可切换语言,查看翻译效果。 2. 新增翻译 翻译是具体到模型字段,其中需要区分出是否字典; 源语言、目标语言,是在资源中维护的语言,可在资源中维护需要翻译的语言; 翻译项则是模型字段,默认翻译项为激活状态,关闭后维护的翻译项无效。 3. 导出、导入 不勾选导出:导出所有需要翻译的翻译项,包括模块、字段,源术语、翻译值等,其中如果已经翻译过的内容,会体现在翻译值中; 勾选导出:导出勾选模型的翻译项。 导入:导入翻译项,平台会根据模型拆分为多条数据。 4. 刷新远程资源 导入翻译项后,点击“刷新远程资源”按钮。 5. 查看翻译内容 页面右上角切换语言,查看翻译效果。

    2024年6月20日
    1.5K00
  • 3.5.1 构建第一个Menu

    在前面章节中我们也涉及到菜单,因为菜单我们模块就是地图、导航,没有地图、导航就无法畅游模块并进行相关业务操作。在3.3.4【模块的继承】一文关于多表继承的内容就有涉及到菜单的初始化,本文将展开介绍初始化Menu的两种方式分别是:注解式、数据初始化式。 注解式(举例) Step1 分析现有菜单注解 用@UxMenus声明DemoMenus为菜单初始化入口,同时该类在DemoModule配置扫描路径中,那么通过DemoMenus初始化的菜单都挂在demo_core这个模块上。 如果采用这种模式,建议同一个模块的菜单都只配置在一处 package pro.shushi.pamirs.demo.core.init; import pro.shushi.pamirs.boot.base.constants.ViewActionConstants; import pro.shushi.pamirs.boot.base.ux.annotation.action.UxRoute; import pro.shushi.pamirs.boot.base.ux.annotation.navigator.UxMenu; import pro.shushi.pamirs.boot.base.ux.annotation.navigator.UxMenus; import pro.shushi.pamirs.demo.api.model.*; import pro.shushi.pamirs.demo.api.proxy.PetShopProxy; import pro.shushi.pamirs.demo.api.proxy.PetShopProxyA; import pro.shushi.pamirs.demo.api.proxy.PetShopProxyB; @UxMenus public class DemoMenus implements ViewActionConstants { @UxMenu("商店管理")@UxRoute(PetShopProxy.MODEL_MODEL) class PetShopProxyMenu{} @UxMenu("商店管理A")@UxRoute(PetShopProxyA.MODEL_MODEL) class PetShopProxyAMenu{} @UxMenu("商店管理B")@UxRoute(PetShopProxyB.MODEL_MODEL) class PetShopProxyBMenu{} @UxMenu("商品管理")@UxRoute(PetItem.MODEL_MODEL) class ItemMenu{} @UxMenu("宠狗商品")@UxRoute(PetDogItem.MODEL_MODEL) class DogItemMenu{} @UxMenu("萌猫商品")@UxRoute(PetCatItem.MODEL_MODEL) class CatItemMenu{} @UxMenu("宠物品种")@UxRoute(PetType.MODEL_MODEL) class PetTypeMenu{} @UxMenu("萌猫品种")@UxRoute(PetCatType.MODEL_MODEL) class CatTypeMenu{} @UxMenu("宠狗品种")@UxRoute(PetDogType.MODEL_MODEL) class DogTypeMenu{} @UxMenu("宠物达人")@UxRoute(PetTalent.MODEL_MODEL) class PetTalentMenu{} } 图3-5-1-1 菜单注解 Step2 改造现有菜单注解 菜单的层级关系通过@UxMenu的嵌套进行描述 菜单点击效果有三种分别对应不同的Action的类型,关于Action的类型详见3.5.3【Action的类型】一文。 通过@UxRoute定义一个与菜单绑定的viewAction,@UxMenu("创建商店")@UxRoute(value = PetShop.MODEL_MODEL,viewName = "redirectCreatePage",viewType = ViewTypeEnum.FORM),其中viewName代表视图的name(其默认值为redirectListPage,也就是跳转到列表也),value代码视图所属模型的编码,viewType代表view类型(其默认值为ViewTypeEnum.TABLE) @UxServer定义一个与菜单绑定的serverAction,@UxMenu("UxServer")@UxServer(model = PetCatItem.MODEL_MODEL,name = "uxServer") ,其中name代表serverAction的name,model或value代码serverAction所属模型的编码 @UxLink定义一个与菜单绑定的UrlAction,@UxMenu("Oinone官网")@UxLink(value = "http://www.oinone.top”,openType= ActionTargetEnum.OPEN_WINDOW) ,其中value为跳转url,openType为打开方式默认为ActionTargetEnum.ROUTER,打开方式有以下几种 ROUTER("router", "页面路由", "页面路由") DIALOG("dialog", "页面弹窗", "页面弹窗") DRAWER("drawer", "打开抽屉", "打开抽屉") OPEN_WINDOW("openWindow", "打开新窗口", "打开新窗口") 配合菜单演示,PetCatItemAction增加一个uxServer的ServerAction package pro.shushi.pamirs.demo.core.action; ……包引用 @Model.model(PetCatItem.MODEL_MODEL) @Component public class PetCatItemAction extends DataStatusBehavior<PetCatItem> { ……省略其他代码 @Action(displayName = "uxServer") public PetCatItem uxServer(PetCatItem data){ PamirsSession.getMessageHub().info("uxServer"); return data; } } 图3-5-1-2 示例代码 新的菜单初始化代码如下 package pro.shushi.pamirs.demo.core.init; import pro.shushi.pamirs.boot.base.constants.ViewActionConstants; import pro.shushi.pamirs.boot.base.enmu.ActionTargetEnum; import pro.shushi.pamirs.boot.base.ux.annotation.action.UxLink; import pro.shushi.pamirs.boot.base.ux.annotation.action.UxRoute; import pro.shushi.pamirs.boot.base.ux.annotation.action.UxServer; import pro.shushi.pamirs.boot.base.ux.annotation.navigator.UxMenu; import pro.shushi.pamirs.boot.base.ux.annotation.navigator.UxMenus; import pro.shushi.pamirs.demo.api.model.*; import pro.shushi.pamirs.demo.api.proxy.PetShopProxy; import pro.shushi.pamirs.demo.api.proxy.PetShopProxyA; import pro.shushi.pamirs.demo.api.proxy.PetShopProxyB; import pro.shushi.pamirs.meta.enmu.ViewTypeEnum; @UxMenus public class DemoMenus implements ViewActionConstants { @UxMenu("商店") class ShopMenu{ @UxMenu("UxServer")@UxServer(model = PetCatItem.MODEL_MODEL,name = "uxServer") class ShopSayHelloMenu{ } @UxMenu("创建商店")@UxRoute(value = PetShop.MODEL_MODEL,viewName = "redirectCreatePage",viewType = ViewTypeEnum.FORM) class ShopCreateMenu{ }…

    2024年5月23日
    2.0K00
  • 3.4.3.1 面向对象-继承与多态

    本节为小伙伴们介绍,Function的面向对象的特性:继承与多态; 一、继承 我们在3.4.1【构建第一个Function】一文中伴随模型新增函数和独立类新增函数绑定到模型部分都是在父模型PetShop新增了sayHello的Function,同样其子模型都具备sayHello的Function。因为我们是通过Function的namespace来做依据的,子模型在继承父模型的sayHello函数后会以子模型的编码为namespace,名称则同样为sayHello。 二、多态(举例) oinone的多态,我们只提供覆盖功能,不提供重载,因为oinone相同name和fun的情况下不会去识别参数个数和类型。 Step1 为PetShop新增hello函数 package pro.shushi.pamirs.demo.api.model; …… //import @Model.model(PetShop.MODEL_MODEL) @Model(displayName = "宠物店铺",summary="宠物店铺",labelFields ={"shopName"} ) @Model.Code(sequence = "DATE_ORDERLY_SEQ",prefix = "P",size=6,step=1,initial = 10000,format = "yyyyMMdd") public class PetShop extends AbstractDemoIdModel { public static final String MODEL_MODEL="demo.PetShop"; …… //省略其他代码 @Function(openLevel = FunctionOpenEnum.API) @Function.Advanced(type= FunctionTypeEnum.QUERY) public PetShop sayHello(PetShop shop){ PamirsSession.getMessageHub().info("Hello:"+shop.getShopName()); return shop; } @Function(name = "sayHello2",openLevel = FunctionOpenEnum.API) @Function.Advanced(type= FunctionTypeEnum.QUERY) @Function.fun("sayHello2") public PetShop sayHello(PetShop shop, String s) { PamirsSession.getMessageHub().info("Hello:"+shop.getShopName()+",s:"+s); return shop; } @Function(openLevel = FunctionOpenEnum.API) @Function.Advanced(type= FunctionTypeEnum.QUERY) public PetShop hello(PetShop shop){ PamirsSession.getMessageHub().info("Hello:"+shop.getShopName()); return shop; } } 图3-4-3-1 为PetShop新增hello函数 Step2 为PetShopProxyB新增对应的三个函数 其中PetShopProxyB新增的hello函数,在java中是重载了hello,在代码中new PetShopProxyB()是可以调用父类的sayHello单参方法,也可以调用本类的双参方法。但在oinone的体系中对于PetShopProxyB只有一个可识别的Function就是双参的sayHello package pro.shushi.pamirs.demo.api.proxy; import pro.shushi.pamirs.demo.api.model.PetCatItem; import pro.shushi.pamirs.demo.api.model.PetShop; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Function; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.api.session.PamirsSession; import pro.shushi.pamirs.meta.enmu.FunctionOpenEnum; import pro.shushi.pamirs.meta.enmu.FunctionTypeEnum; import pro.shushi.pamirs.meta.enmu.ModelTypeEnum; import java.util.List; @Model.model(PetShopProxyB.MODEL_MODEL) @Model.Advanced(type = ModelTypeEnum.PROXY,inherited ={PetShopProxy.MODEL_MODEL,PetShopProxyA.MODEL_MODEL} ) @Model(displayName = "宠物店铺代理模型B",summary="宠物店铺代理模型B") public class PetShopProxyB extends PetShop { public static final String MODEL_MODEL="demo.PetShopProxyB"; @Field.one2many @Field(displayName = "萌猫商品列表") @Field.Relation(relationFields = {"id"},referenceFields = {"shopId"}) private List<PetCatItem> catItems; @Function(openLevel = FunctionOpenEnum.API) @Function.Advanced(type= FunctionTypeEnum.QUERY) public PetShop sayHello(PetShop shop){ PamirsSession.getMessageHub().info("PetShopProxyB Hello:"+shop.getShopName()); return shop; } @Function(name = "sayHello2",openLevel = FunctionOpenEnum.API) @Function.Advanced(type= FunctionTypeEnum.QUERY) @Function.fun("sayHello2") public PetShop sayHello(PetShop shop,String hello){ PamirsSession.getMessageHub().info("PetShopProxyB say:"+hello+","+shop.getShopName()); return shop; } @Function(openLevel = FunctionOpenEnum.API)…

    2024年5月23日
    1.6K00
  • 3.5.3 Action的类型

    各类动作我们都碰到过,但都没有展开讲过。这篇文章我们来系统介绍下oinone涉及到的所有Action类型。 一、动作类型 服务器动作ServerAction 类似于Spring MVC的控制器Controller,通过模型编码和动作名称路由,定义存储模型或代理模型将为该模型自动生成动作名称为consturct,queryOne,queryPage,create,update,delete,deleteWithFieldBatch的服务器动作。定义传输模型将为该模型自动生成动作名称为consturct的服务器动作 窗口动作ViewAction 站内跳转,通过模型编码和动作名称路由。系统将为存储模型和代理模型自动生成动作名称为redirectDetailPage的跳转详情页窗口动作,动作名称为redirectListPage的跳转列表页窗口动作,动作名称为redirectCreatePage的跳转新增页窗口动作,动作名称为redirectUpdatePage的跳转更新页窗口动作。 跳转动作UrlAction 外链跳转 客户端动作ClientAction 调用客户端函数 二、默认动作 如果在UI层级,有开放新增语义函数,则会默认生成新增的窗口动作ViewAction,跳转到新增页面 如果在UI层级,有开放更新语义函数,则会默认生成修改的窗口动作ViewAction,跳转到更新页面 如果在UI层级,有开放删除语义函数,则会默认生成删除的客户端动作ClientAction,弹出删除确认对话框 三、第一个服务器动作ServerAction 回顾第一个ServerAction 第一个ServerAction是在3.3.2【模型的类型】一文中的“代理模型”部分出现的,再来看下当时的定义代码 package pro.shushi.pamirs.demo.core.action; ……引用类 @Model.model(PetShopProxy.MODEL_MODEL) @Component public class PetShopProxyAction extends DataStatusBehavior<PetShopProxy> { @Override protected PetShopProxy fetchData(PetShopProxy data) { return data.queryById(); } @Action(displayName = "启用") public PetShopProxy dataStatusEnable(PetShopProxy data){ data = super.dataStatusEnable(data); data.updateById(); return data; } ……其他代码 } 图3-5-3-1 回顾第一个ServerAction @Action注解将创建服务器动作,并@Model.model绑定 自定义ServerAction请勿使用get、set、unset开头命名方法或toString命名方法。 ServerAction之校验(举例) Step1 为动作配置校验表达式 使用@Validation注解为PetShopProxyAction的dataStatusEnable服务端动作进行校验表达式配置 package pro.shushi.pamirs.demo.core.action; ……引用类 @Model.model(PetShopProxy.MODEL_MODEL) @Component public class PetShopProxyAction extends DataStatusBehavior<PetShopProxy> { @Override protected PetShopProxy fetchData(PetShopProxy data) { return data.queryById(); } @Validation(ruleWithTips = { @Validation.Rule(value = "!IS_BLANK(data.code)", error = "编码为必填项"), @Validation.Rule(value = "LEN(data.shopName) < 128", error = "名称过长,不能超过128位"), }) @Action(displayName = "启用") public PetShopProxy dataStatusEnable(PetShopProxy data){ data = super.dataStatusEnable(data); data.updateById(); return data; } ……其他代码 } 图3-5-3-2 为动作配置校验表达式 注: ruleWithTips可以声明多个校验规则及错误提示; IS_BLANK和LEN为内置文本函数,更多内置函数详见4.1.12【函数之内置函数与表达式】一文; 当内置函数不满足时参考4.1.13【Action之校验】一文。 Step2 重启看效果 在商店管理页面点击【启用】得到了预期返回错误信息,显示"编码为必填项" 图3-5-3-3 在商店管理页面点击启用得到了预期返回错误信息 ServerAction之前端展示规则(举例) 既然后端对ServerAction发起提交做了校验,那能不能在前端就不展示呢?当然可以,我们现在就来试下。 Step1 配置PetShopProxyAction的dataStatusEnable的前端出现规则 用注解@Action.Advanced(invisible="!(activeRecord.code !== undefined && !IS_BLANK(activeRecord.code))")来表示,注意这里配对invisible是给前端识别的,所以写法上跟后端的校验有些不一样,但如内置函数IS_BLANK这些是前后端一致实现的,activeRecord在前端用于表示当前记录。 package pro.shushi.pamirs.demo.core.action; ……引用类 @Model.model(PetShopProxy.MODEL_MODEL) @Component public class PetShopProxyAction extends DataStatusBehavior<PetShopProxy> { @Override protected PetShopProxy fetchData(PetShopProxy data) { return data.queryById(); } @Validation(ruleWithTips = { @Validation.Rule(value = "!IS_BLANK(data.code)", error = "编码为必填项"), @Validation.Rule(value = "LEN(data.name) < 128", error = "名称过长,不能超过128位"), }) @Action(displayName = "启用") @Action.Advanced(invisible="!(activeRecord.code !== undefined…

    2024年5月23日
    1.8K00

Leave a Reply

Please Login to Comment