用户注册后启动审批流程
案例需求
系统开放用户注册。用户注册后,成为外部用户,同时发起外部用户审批流程。在审批流程中,选择加入的组织,流程审批后,外部用户变成内部用户
知识点
- 在流程结束后调用后端服务
- 在 Java 代码中,实现先登录后启动流程
- 使用企业门户中的用户注册后扩展点
开发过程
开发内容涉及两个应用,内容及调用关系见下表
| 内容 | 企业门户应用 | 企业应用 |
|---|---|---|
| 数据 | 外部用户审批记录,作为流程数据 | |
| 服务 | ② 启动加入组织流程,启动外部用户审批流程 | ④ 外部用户转内部用户,调用企业门户提供的 API |
| 流程 | ③ 外部用户审批流程,流程结束前调用外部用户转内部用户 | |
| 门户自定义组件 | ① 在用户注册后扩展点中,调用启动加入组织流程 |
实现审批流程
目前企业门户中不支持流程,因此添加一个企业应用,实现审批流程
添加企业应用
在我的开发→企业应用中,创建企业应用,这个应用可以专门用于实现门户中的扩展需求
添加数据集
在应用中,添加一个动态数据集,用来记录外部用户信息和要加入的组织信息,如下图所示
添加后端服务
在应用中,增加一个后端服务,用于流程结束时调用。在服务中调用门户的服务 /opm/orgmanager/joinorg?personId=&orgId= 将外部用户转为内部用户。由于要被流程调用,请求方法必须是 POST,不需要设置请求参数,如下图所示
如果需要组织同步,可以在调用外部用户加入组织后,调用组织同步,服务的代码如下
package main.service.impl;
import java.util.*;
import java.math.BigDecimal;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import com.justep.cloud.data.*;
import com.justep.util.process.ProcessUtil;
import com.justep.util.net.ServiceUtil;
import main.entity.*;
import main.service.*;
import main.mapper.*;
import main.vo.*;
import uaa.model.*;
@Service("main-FuwuUserService")
public class FuwuUserServiceImpl implements FuwuService {
@Autowired
private JoinOrgMapper joinOrgMapper;
//系统生成代码,请不要修改或删除 <actionStart:joinOrg>
public String joinOrg() throws Exception {
String sData1 = ProcessUtil.getVar("sData1");
JoinOrg joinOrg = joinOrgMapper.findByPrimaryKey(sData1);
//外部用户加入组织
ServiceUtil.post("entry","/opm/orgmanager/joinorg?personId=" + joinOrg.getPersonId() + "&orgId=" + joinOrg.getOrgId(), null);
//组织同步
ServiceUtil.get("entry","/misc/org/syncOrg");
return "OK";
}
//系统生成代码,请不要修改或删除 <actionEnd:joinOrg>
}
添加审批流程
在应用中,添加页面,使用“单表流程”向导,添加外部用户审批流程,如下图所示
向导生成的加入组织的输入框改为“组织选择”组件,属性设置如下图所示
切换到流程设计界面,添加流程的流程事件(点击流程图空白处,相当于选中流程,切换到高级设置,点击流程事件)
在流程级事件中,新增结束前事件,事件处理方式选择调用服务,调用在上一步中添加的“外部用户转内部用户”服务,操作过程如下图所示
记录下流程编码,写 Java 代码启动流程时需要使用
用户注册后发起流程
定制企业门户
定制企业门户应用,参考《门户定制》
添加后端服务
在企业门户的门户自定义组件中,添加一个后端服务,用于发起“外部用户审批”流程。服务定义如下图所示
只有组织内的用户才能发起流程,本例中使用了用户名为 liyun 的人发起流程。ProcessUtil.startProcess 方法的第二个参数是流程编码,其中 /SA/wf/default/ 是固定部分,sbr_waibuyhsp 是流程编码,来自于流程定义,服务的代码如下
package comp.portalconfig.service;
import java.util.*;
import java.math.BigDecimal;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.justep.util.process.ProcessUtil;
import com.justep.util.SpringWebUtil;
import com.justep.util.ContextUtil;
import com.justep.util.net.ServiceUtil;
import com.justep.util.net.AuthUtil;
import com.justep.util.db.TransactionUtil;
import com.justep.tools.mybatis.*;
import com.justep.tools.DbrestResult;
import comp.portalconfig.model.*;
import comp.portalconfig.dao.*;
import comp.portalconfig.vo.*;
@Service("comp.portalconfig-FuwuUserService")
public class FuwuUserService {
private String getIdByUsername(String username) throws Exception {
DbrestWrapper<?> wrapper = new DbrestWrapper<>("entry","uaa","users");
wrapper.eq("username",username);
DbrestResult ret = DbrestUtil.get(wrapper, null);
JSONObject userObj = ret.toJson();
JSONArray userArr = userObj.getJSONArray("result");
if(userArr.size() == 0){
throw new RuntimeException("没有组织用户" + username + ",不能启动流程");
}
JSONObject user = userArr.getJSONObject(0);
return user.getString("id");
}
//系统生成代码,请不要修改或删除 <actionStart:startJoinOrgFlow>
public String startJoinOrgFlow(String user) throws Exception {
JSONObject userObj = JSON.parseObject(user);
String outerUsername = userObj.getString("userName");
//获取外部用户ID
String outerUserId = getIdByUsername(outerUsername);
//添加业务数据
String id = UUID.randomUUID().toString();
JSONObject joinOrg = new JSONObject();
joinOrg.put("fid", id);
joinOrg.put("personId", outerUserId);
joinOrg.put("personName", userObj.getString("name"));
JSONArray joinOrgs = new JSONArray();
joinOrgs.add(joinOrg);
DbrestUtil.upsert("sbr", "main", "joinOrg", joinOrgs);
//指定启动流程的用户
String flowUserName = "liyun";
String flowUserId = getIdByUsername(flowUserName);
//获取系统环境变量
String credentialToken = ContextUtil.getEnv("CREDENTIAL_TOKEN");
//获取指定用户token
String token = ServiceUtil.post(SpringWebUtil.getRequest(), "entry",
"/uaa/sso/token?username=" + flowUserName + "&credentialToken=" + credentialToken, null, String.class);
//使用用户token登录
String userSession = AuthUtil.tokenLogin(ServiceUtil.getServiceUrl("entry"), token);
//设置发起流程所需参数
Map<String, String> headers = new HashMap<>();
headers.put("Cookie", "user_session=" + userSession);
//获取并设置分布式事务信息
String trans = TransactionUtil.getTransExtHeaderValue();
headers.put("X-DBPROXY-TRANS-INFO", trans);
//设置启动流程用户信息
headers.put("x-credential-user-id", flowUserId);
headers.put("x-credential-username", flowUserName);
//启动流程
ProcessUtil.startProcess(headers, "/SA/wf/default/sbr_waibuyhsp", id, null);
return "OK";
}
//系统生成代码,请不要修改或删除 <actionEnd:startJoinOrgFlow>
}
扩展用户注册
在门户中的门户自定义组件中,添加用户注册后扩展点,在扩展点中调用在上一步中添加的“启动加入组织流程”服务,发起“外部用户审批”流程。这里调用的服务需要设置为匿名访问,参考最后一节“设置匿名访问”
portalConfig.config.pc.js 中的代码如下
import { merge } from "lodash";
import ConfigContextProcessor from 'core/framework/ConfigContextProcessor';
import React from 'react';
export default {
processConfigContext(configContext) {
},
//自定义
async onConfigContextInit(configContextProcessor) {
//获取当前页
let _this = configContextProcessor.page;
//按照需要处理的文件路径及方法进行自定义
//@after:方法执行后执行;参数:(result,...args),其中result是方法返回数据,args是原方法自带参数
//@before:方法执行前执行;参数:(...args),其中args是原方法自带参数
//@replace:替换原方法;参数:(...args),其中args是原方法自带参数
//注意:上述3种方法,async标识必须与原方法同步,即原方法是异步,现在自定义方法才能使用异步,否则不能使用
//详细使用案例可以参考“帮助中心”下门户v2定制下相关案例
let portalConfig = {
"config": {
"/entry": {
"/pcxapp": {
"/pcx": {
"/user": {
"/login.w": {
"onAfterRegist": (user) => {
_this.request({
method: "POST",
url: "/portalconfig/fuwu/startjoinorgflow",
data: user
})
}
}
}
}
}
}
}
};
//处理自定义内容
merge(_this.configContext, portalConfig);
ConfigContextProcessor.enhancePageAdvice(_this);
}
}
发布企业门户
测试时,直接发布企业门户应用,进行测试。
测试后,下载门户自定义组件,更新市场中的门户自定义组件,发布企业门户模版,参考《门户定制》中的更新市场组件
设置匿名访问
在应用资源管理中,选择企业门户应用,添加匿名用户角色的 API 权限,选择“门户定制-服务-启动加入组织流程”,如下图所示,确定后,点击保存并且发布,使之生效









