跳转到内容

业务上下文开发指南

业务侧希望有一套机制,可以获取当前用户、所属组织等上下文信息。目前用户上下文是可以通过 TContext 获取到的, 不过所属组织等上下文信息暂不可以。

在这之前业务实现组织上下文的方式,一般是通过 HttpFilter 将该信息提前放到上下文中的,然后其他模块用到该上下文的地方,都需要引入这个filter及对应的实现逻辑,这可能会引入不必要的过大依赖。

通过以下方式可以定义业务上下文,其他模块需要使用到该上下文的地方,仅需引入该接口便可。

在线编辑上下文

进入 制品中心->配置->业务域->业务上下文,业务上下文:

创建业务上下文

  1. 关于业务上下文的在线化创建方式跟扩展点差不多,点击左侧的业务上下文菜单,打开管理列表

img

  1. 点击右上角的【创建】按钮打开创建窗口

填写资源标识、名称、过期时间以及方法声明列表后,点击【提交】即可在线创建业务上下文资源

img

其中

字段类型规则
资源原标识string必填,50字以内的大写字母、小写字母或数字组合,必须大写字母开头,编辑时不可修改
名称string必填,50个字以内的无限制字符
过期时间int必填,单位秒,默认300
描述string非必填,200个字以内的无限制格式字符
方法名String方法名必须以get开头,支持字母、数字和下划线_的组合,且长度不能超出50个字符
eg:getUserId、getCurrentContext135
出参类型dictionary非必填,不填出参为void。枚举为:模型、模型数组、模型分页、List(集合)、Map(映射)、自定义
默认为:模型
出参模型link 模型入参模型、常见数据类型、自定义类型全限定名三者之一必填
可选范围为当前应用版本下所有模型
常见数据类型dictionary入参模型、常见数据类型、自定义类型全限定名三者之一必填
自定义类型全限定类名string入参模型、常见数据类型、自定义类型全限定名三者之一必填
必须填写Java类全限定名,
eg:java.lang.String、io.terminus.trantor.base.User
当出/入参类型为映射(Map)时,只能在这里填写参数化类型列表,且必须使用英文字符逗号作为分隔符
eg:java.lang.String, java.lang.Long

img

定义上下文实现

一般来说, 声明了业务上下文的模块, 也会声明其实现, 以描述获取上下文真实逻辑:

  1. 业务上下文实现是一个 Java Class
  2. 该 Class 需要实现对应 业务上下文声明的 Interface
  3. 需要在该 Class 打上 @BusinessContextImpl 的注解, 并声明相关信息
  4. 实现相关获取上下文的方法, 方法内可以使用 TContext.getCurrentUser()
  5. 实现需要使用其他 LogicFlow 或者 LogicFunction, 可以直接使用成员声明, 通过构造器注入的方式使用
  6. 特别注意方法必须无参,且以 getXxx() 开头, 另外可以多个方法
@BusinessContextImpl(name = "Trade context")
@AllArgsConstructor
public class TradeContextImpl implements TradeContext {
private final LoadCurrentBusinessEntityFunc loadCurrentBusinessEntityFunc;
// 获取业务主体
public BusinessEntityBO getBusinessEntity() {
User user = TContext.getCurrentUser();
return loadCurrentBusinessEntityFunc.execute(user);
}
}

使用业务上下文

使用时, 在 LogicFunction 中注入相应 业务上下文声明, 在合适的时机调用方法即可.

基本逻辑是, 每个请求会有一个贯穿全局的请求 ID, 注入的是上下文声明的代理, 会根据规则去 Redis 中, 根据请求 ID 和上下文的 Key 等, 查找相关缓存的内容, 如果缓存内容不存在, 则发起调用找业务上下文的实现, 之后将结果放入上下文并返回. 放入上下文的内容, 会自动被清理.

@FunctionImpl(name = "创建商品默认实现")
@AllArgsConstructor
public class CreateItemFuncImpl implements CreateItemFunc {
private final TradeContext tradeContext;
@Override
public ItemBO execute(ItemBO item) {
BusinessEntity businessEntity = tradeContext.getBusinessEntity();
// 处理业务 ...
return itemOptional;
}
}

使用上下文进行数据过滤

dataParams 支持使用用户上下文和业务上下文。

  • 获取当前用户id固定为 @currentUserId
  • 获取业务上下为格式固定为 @context.${key}.${method}.${propertyPath}
    • 第一部分固定 @context
    • 第二部分为业务上下文接口的key, 如 md_TradeContext
    • 第三部分为业务上下文的方法,如 getBusinessEntity/businessEntity
    • 第四部分为表达式,目前仅支持较为简单方式, 可空
<View title="公司列表">
<Table key="company" model="base_Company"
dataCondition="createdBy.id = ? and company.id = ?"
dataParams="[@currentUserId, @context.md_TradeContext.getBusinessEntity.companyId]">
<Fields>
<Field name="code"/>
<Field name="name" />
</Fields>
</Table>
</View>

业务上下文缓存问题

业务上下文目前缓存是请求级别的,请求结束之后缓存就自动清理了。 后续会加上session级别和暴露手动清理缓存的接口。