关键词:开放平台,接口api二开
一、需求
现在有个需求,在苍穹系统有一张业务单据,它的来源,主要是在苍穹系统人工手动填写或者是外部系统通过接口来生成的。该单据主要包括了创建人,创建人的组织这两个字段和其他繁多的业务数据,而在外部系统里面只有创建人的编码工号和其他业务数据,因为外部系统组织和苍穹的组织编码方式不一样,所以传过来我们也不能转换成苍穹的组织。
所以创建人的组织需要在调用接口的时候,自动把外部系统创建人的组织数据补齐。
二、思路与方案
在做实际开发的时候,最开始是有两个方案,
1 提供一个自定义API,根据接口传参,先做一系列校验,然后根据参数生成部分业务数据,组装成DynamicObject,再通过SaveServiceHelper来保存。
2 配置一个保存操作API,只要通过配置就能实现,苍穹自带的API基础资料校验也可以搞定业务数据繁多的校验,而且一些数据的生成也可以自动借助业务规则中的创建时自动生成,省去很多代码逻辑。
考虑到开发的效率性,我们选择了第二种方案,
但是在开发中,碰到了一个问题,就是组织的生成。
在页面上注册了一个插件,就是根据登录用户生成,最初的代码是这样写的
@Override public void afterCreateNewData(EventObject e) { super.afterCreateNewData(e); //默认带出申请人的主职部门及公司 long userId = RequestContext.get().getCurrUserId(); long deptId = UserServiceHelper.getUserMainOrgId(userId); this.getModel().setValue("bidt_orgfield",deptId); }
在测试中发现,在苍穹系统手动生成是没有问题的。
而在接口调用时,却发现组织生成的是不正确的,原来在接口调用前,获取accessToken的时候,此时传入的手机号就对应着苍穹的操作人,也就是苍穹上下文中,RequestContext.get().getCurrUserId()此时取的,不是我们参数传入的创建人,而是根据accessToken手机号的人,
所以在afterCreateNewData这个方法获取的组织就是获取accessToken的人的组织,自然会不一样。
这里也说句,虽然这里也可以通过每换一个创建人,就获取一次accessToken,但是一般系统之间的交互都是:获取一次accessToken,放入缓存中,直到快到期了,再获取一次,所以这个方法也是不可取的。
下面是获取accessToken的图片
目前操作API目前没有二开入口,那我们就要在保存的时候做干预,通过保存操作插件来修改组织的值,
三、实现过程
1 创建测试数据表单
为了聚焦方案本身,只加了组织,来源系统。
2 在页面上配置插件
针对最初的页面插件代码,我们做了小小改动,当不是api调用的才设置组织信息
public class ApiOrgPlugin extends AbstractBillPlugIn { @Override public void afterCreateNewData(EventObject e) { super.afterCreateNewData(e); //获取调用方法的client String callClient =RequestContext.get().getClient(); //如果不是api调用的才设置组织信息 if(!"api".equals(callClient)) { //默认带出申请人的主职部门及公司 long userId = RequestContext.get().getCurrUserId(); long deptId = UserServiceHelper.getUserMainOrgId(userId); this.getModel().setValue("bidt_orgfield",deptId); } } }
3 配置操作api
在这里配置好api。
4 页面保存操作上加个插件
代码如下:
import kd.bos.dataentity.entity.DynamicObject; import kd.bos.entity.plugin.AbstractOperationServicePlugIn; import kd.bos.entity.plugin.PreparePropertysEventArgs; import kd.bos.entity.plugin.args.BeginOperationTransactionArgs; import kd.bos.servicehelper.user.UserServiceHelper; public class ApiSaveOpPlugin extends AbstractOperationServicePlugIn{ @Override public void onPreparePropertys(PreparePropertysEventArgs e) { // TODO Auto-generated method stub super.onPreparePropertys(e); e.getFieldKeys().add("bidt_sourcesys"); e.getFieldKeys().add("creator"); e.getFieldKeys().add("bidt_orgfield"); } public void beginOperationTransaction(BeginOperationTransactionArgs e) { DynamicObject[] dataEntities = e.getDataEntities(); DynamicObject formData = dataEntities[0]; String sourcesys=(String) formData.get("bidt_sourcesys"); if("api".equals(sourcesys)) { DynamicObject creator =(DynamicObject) formData.get("creator"); //默认带出申请人的主职部门及公司 long userId = creator.getLong("id"); long deptId = UserServiceHelper.getUserMainOrgId(userId); formData.set("bidt_orgfield_id", deptId);//基础资料设置值为id的时候需要加_id } } }
四、效果图
1 首先在人员列表上可以看到工号为 ID-005001 的隶属于一车间这个组织
2 在postman发起请求, 在这里我们并没有传入组织数据
3 接口调用完成后,可以看到,组织的数据已经补全了。
4 作为对比,这个就是之前接口未写保存插件,通过RequestContext.get().getCurrUserId()获取人员,再获取组织的截图
五、开发环境版本
COSMICV5.0.003.0
六、参考资料
java插件.rar(1.17KB)
bidt_devtset-bidt_yanzheng-202 …(7.54KB)