# 流程中心表单数据存储场景说明。
流程中心表单数据存储功能是为了兼容表单外部url相关数据存储在第三方服务中,数据和表单页面由三方服务提供的场景。
流程中心表单数据存储场景分为前端调用三方保存接口、后端rest调用三方保存接口两种方式。(查询表单数据接口两种场景均统一由前端触发调用)
区别:1、事务数据一致性: 前端调用方式不能保证流程引擎和表单数据保存在同一事务下进行,无法通过事务层面保证数据一致性。需要自行对数据进行回滚操作,具体方式在前端调用三方保存接口中有说明。
后端调用方式可保证流程引擎和表单数据在同一事务下进行。
2、调用方式: 前端调用体现在由前端触发三方保存接口数据,成功后再进行submit提交流程接口调用。
后端调用由前端直接触发submit提交流程接口调用,三方数据保存接口在后端submit接口逻辑中进行rest远程调用。
# 前端调用三方保存接口
前端调用方式不能保证流程引擎和表单数据保存在同一事务下,如需事务一致则通过监听message事件来回滚事务,如下
三方应用提交接口失败时需要做回滚处理
- rollbackFormDataHandle(bfpContext, processContext)
afc的提交接口失败时,监听message消息
- 当msg为afterSaveFormDataStart时,根据 isFailed 字段判断做表单回滚或保存后处理
# 后端rest调用三方保存接口
前端调用submit提交流程接口时,由后端rest远程调用三方保存接口。三方服务应用地址以AFC应用管理中三方地址为主,没有配置时则获取前端调用submit接口时BfpContext对象中传入三方保存接口相关信息参数,该参数值由demo-ui中配置文件中获取,具体在开发三方应用—demo前端资源开发中有介绍。
后端调用方式可保证流程引擎和表单数据在同一事务下进行。
后端调用时submit接口参数BfpContext中有对应保存接口url和header头信息,header头信息用于三方接口请求认证头,防止接口被认证拦截。
# 安装介质和三方应用创建开发部署
# 1、获取介质包
流程中心使用EOS相关介质包(${VERSION}为对应版本)
bps引擎后端介质包 | BPS_Standalone__${VERSION}.tar.gz |
---|---|
bps引擎前端介质包 | BPS_Standalone_UI_${VERSION}.tar.gz |
# 2、创建三方应用
如下图。创建应用选择是否三方应用和三方应用地址,使用nacos注册中心时,三方应用地址可配置三方应用注册在nacos中的服务名。
# 3、开发三方应用
流程设计阶段活动绑定表单url为三方应用开发页面,该页面由三方应用提供,即有独立后端服务和前端资源。以下说明均用demo名来作为三方应用名,修改文件目录以示例demo项目为准。
# demo后端接口开发
# 接口规范
# 保存接口:
接口请求path | 自定义 |
---|---|
请求方式 | post |
入参 | Map<String, Object> params |
出参 | String[] (必要) |
说明:
Params入参中有formData、processContext两个key值属性。
formData为表单提交数据数组格式 List<Map<String, Object>>类型
processContext为流程上下文json对象 Object类型
String[] 出参为保存表单数据后返回的主键值
示例:
@PostMapping("/save")
public String[] saveFormData(@RequestBody Map<String, Object> params){
List<Map<String, Object>> formData = (List<Map<String, Object>>)params.get("formData");
Object processContext = params.get("processContext");
return formDataService.saveFormData(formData,processContext);
}
# 查询接口:
请求接口path | 自定义 |
---|---|
请求方式 | post |
入参 | Map<String, Object> params |
出参 | Map<String,Object> (必要) |
说明:
Params入参中有bizPrimaryKeyId、bizPrimaryKeyValue、processContext三个key值属性。bizPrimaryKeyId为查询主键属性 String类型(如值为id)
bizPrimaryKeyValue 为业务主键值 List
processContext为流程上下文json对象 Object类型
Map<String,Object> 出参为查询返回的表单数据集
示例:
@PostMapping("/query")
public Map<String,Object> queryFormData(@RequestBody Map<String, Object> params){
String bizPrimaryKeyId = (String)params.get("bizPrimaryKeyId");
List<String> bizPrimaryKeyValue = (List) params.get("bizPrimaryKeyValue");
Object processContext = params.get("processContext");
return formDataService.queryFormData(bizPrimaryKeyId,bizPrimaryKeyValue,processContext);
}
# demo前端资源开发
# 前端调用保存查询相关配置
前端通过postmessage实现跨域通信和页面间数据通信,实现三方系统表单页面来触发保存接口,该过程由前端调用。
表单demo修改配置
\demo_vue\config.js
- 配置 demo 应用流程中心 postMessage 收发消息地址
// postMessage 消息相关地址 const postMessageConfig = { // afc(bfp)地址, 即iframe表单发消息的目标地址 targetOrigin: "http://localhost:8000", // targetOrigin: "http://127.0.0.1:14082", // 可接收的afc页面地址 acceptableUrlList: [ "http://localhost:8000", "http://127.0.0.1:14082", ], };
- 是否调用三方应用提交接口
const isTrilateralSubmit = true; // bfp前端提交 // const isTrilateralSubmit = false; // bfp后端提交
- 配置三方应用接口地址
const dataUrl = { save: "http://127.0.0.1:28082/demo-formdata/api/form-data/save", // 保存表单 query: "http://127.0.0.1:28082/demo-formdata/api/form-data/query", // 加载表单 };
- 配置三方应用认证头
const headers = { apple: "11", baby: "22", canon: "33" };
BPS_Standalone_UI包中修改配置
- 配置流程中心 postMessage 接收消息地址
static\js\iframeConfig.js
window.iframeFormMessageConfig = { // 三方表单页面所在地址 acceptableUrlList: [ "http://127.0.0.1:5500", "http://127.0.0.1:5501", "http://127.0.0.1:5502", ], }
- 配置流程中心 postMessage 接收消息地址
# 后端调用保存相关配置
bfp后端接口rest远程调用三方保存数据接口来实现,该场景修改配置步骤和前端调用保存查询相关配置一致,区别在于以下
- 是否调用三方应用提交接口
// const isTrilateralSubmit = false; // bfp前端提交
const isTrilateralSubmit = true; // bfp后端提交
# demo前后端示例资源包
# 4、三方应用部署
# nginx配置修改
其中proxy_set_header X-BPS-TenantId 设置被代理服务器接收到的header信息,X-BPS-TenantId为多租户场景时bps的租户id。
当存在多个不同三方应用对应不同租户场景时,需要在对应nginx配置中添加此配置。
server {
listen 28082;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-Port $remote_port;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
root /opt/taskcenter/web/nginxweb-data;
# 配置页面不缓存html和htm结尾的文件
if ($request_filename ~* .*\.(?:htm|html)$)
{
add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
}
index index.html index.htm;
try_files $uri /index.html;
}
location /afc/{
proxy_pass http://127.0.0.1:28083/;
}
location /AFCENTER/{
proxy_pass http://127.0.0.1:28083/;
}
#三方应用路由地址
location /demo1 {
proxy_set_header X-BPS-TenantId bbbbb111;
proxy_pass http://127.0.0.1:28083/;
}
#三方应用路由地址
location /demo2 {
proxy_set_header X-BPS-TenantId bbbbb222;
proxy_pass http://127.0.0.1:28083/;
}
}
# 三方表单页面使用
三方应用开发部署完成后提供具体三方表单页面url,流程引擎中创建流程环节绑定对应url以实现表单数据三方保存场景。如下图为在afc中资源管理里针对三方应用可以新建流程。
流程引擎接口以表单url为http或https开头来确定是三方表单请求,具体体现在接口参数processContext对象的actionURL属性中。
示例:
# 特殊说明
# demo表单开发规范参考
# 页面风格
主体风格参考 element-ui,组件为mini 尺寸, 字体14px。
为避免出现横竖滚动条,不要设置页面的宽度和高度, 不要设置背景色,避免嵌套多层iframe,尽量不要使用弹窗组件。
# 安全问题
推荐将第三方表单和afcenter 部署在同域下
如二者不同域, 需在afcenter代理服务器上设置 X-Frame-Options ALLOW-FROM, 指定受信域名列表。
# 表单开发
vue示例,需引入vue、element-ui资源
jquery示例,需引入jquery、jquery.validate资源
表单页面使用以下钩子函数和 bfp 交互数据
getAnchors(bfpContext, processContext)
处理表单的分隔符锚点数据数据,表单页面左侧显示纵向导航条
在页面上添加带有class和id序号的分隔符组件
<el-divider content-position="left"> <span class="anchor" id="anchor-1">活动名称</span> </el-divider>
loadFormData(bfpContext, processContext)
- 载入表单时的动作
beforeSaveFormData(bfpContext, processContext)
- 保存前的动作,可以在此对表单内容做校验
saveFormData(bfpContext, processContext)
- 保存时的动作,需要返回表单数据
- 根据 isTrilateralSubmit 的值决定是否调用三方应用保存接口
- 三方应用提交接口失败时需要做回滚处理
- rollbackFormDataHandle(bfpContext, processContext)
afterSaveFormData(bfpContext, processContext)
- 保存后的动作
- 根据 isFailed 字段判断做表单回滚或保存后处理
bfp与iframe表单页面通信
- 通信建议使用 window.parent.postMessage,尽量不要使用window.top, window.history ,window.location 等对象刷新页面, 建议使用内部路由实现页面切换。
- targetOrigin
- 表单页面postMessage可发送消息地址,即bfp地址
- acceptableUrlList
- postMessage可接收消息地址列表,至少包含bfp地址
消息接收处理方法 msgReceiveHandler
- 根据msg的做不同处理
消息发送处理方法 msgSendHandler
- 通过postMessage发送消息数据给父页面bfp
监听消息
发起消息
mounted() { const msgJson = JSON.stringify({ msg: "iframeFormIsLoaded", }); window.parent.postMessage(msgJson, postMessageConfig.targetOrigin); },
iframe表单调用提交、加载表单接口
- 提交和加载需要另外完成,分别在saveFormData 和 loadFormData中
- demo中设置变量 isTrilateralSubmit,表示是否采用三方应用提交接口
- isTrilateralSubmit 置为 true 时
- 采用三方应用提交保存接口(bfp前端提交),且需要将接口返回的bizPrimaryKeyValue值塞入form表单中
- 采用三方应用加载表单接口
- isTrilateralSubmit 置为 false 时
- 不调用三方应用提交保存接口(bfp后端提交),需要将表单页面设置的dataSaveUrl、headers值塞入form表单中
- 采用三方应用加载表单接口
主键ID数组 bizPrimaryKeyValue
- 流程的发起环节和中间环节
- saveFormData方法将三方提交接口返回的主键数组 bizPrimaryKeyValue发送给bfp,bfp加入参数后再调用自己的提交接口
- 流程表单load加载时
- 需要将 bizPrimaryKeyValue 参数加入后再调用加载接口
- bizPrimaryKeyValue获取路径,bfpContext.formData. bizPrimaryKeyValue
- 流程的发起环节和中间环节