用户注册后启动审批流程

案例需求

系统开放用户注册。用户注册后,成为外部用户,同时发起外部用户审批流程。在审批流程中,选择加入的组织,流程审批后,外部用户变成内部用户

知识点

  1. 在流程结束后调用后端服务
  2. 在 Java 代码中,实现先登录后启动流程
  3. 使用企业门户中的用户注册后扩展点

开发过程

开发内容涉及两个应用,内容及调用关系见下表

内容 企业门户应用 企业应用
数据 外部用户审批记录,作为流程数据
服务 ② 启动加入组织流程,启动外部用户审批流程 ④ 外部用户转内部用户,调用企业门户提供的 API
流程 ③ 外部用户审批流程,流程结束前调用外部用户转内部用户
门户自定义组件 ① 在用户注册后扩展点中,调用启动加入组织流程

实现审批流程

目前企业门户中不支持流程,因此添加一个企业应用,实现审批流程

添加企业应用

在我的开发→企业应用中,创建企业应用,这个应用可以专门用于实现门户中的扩展需求

添加数据集

在应用中,添加一个动态数据集,用来记录外部用户信息和要加入的组织信息,如下图所示

1760001706690

添加后端服务

在应用中,增加一个后端服务,用于流程结束时调用。在服务中调用门户的服务 /opm/orgmanager/joinorg?personId=&orgId= 将外部用户转为内部用户。由于要被流程调用,请求方法必须是 POST,不需要设置请求参数,如下图所示

1760001611456

如果需要组织同步,可以在调用外部用户加入组织后,调用组织同步,服务的代码如下

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>

}

添加审批流程

在应用中,添加页面,使用“单表流程”向导,添加外部用户审批流程,如下图所示

1760001833928

向导生成的加入组织的输入框改为“组织选择”组件,属性设置如下图所示

1760003813115

切换到流程设计界面,添加流程的流程事件(点击流程图空白处,相当于选中流程,切换到高级设置,点击流程事件)

1760003994071

在流程级事件中,新增结束前事件,事件处理方式选择调用服务,调用在上一步中添加的“外部用户转内部用户”服务,操作过程如下图所示

1760003970668

记录下流程编码,写 Java 代码启动流程时需要使用

1760082392081

用户注册后发起流程

定制企业门户

定制企业门户应用,参考《门户定制

添加后端服务

在企业门户的门户自定义组件中,添加一个后端服务,用于发起“外部用户审批”流程。服务定义如下图所示

1760008668886

只有组织内的用户才能发起流程,本例中使用了用户名为 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>
}

扩展用户注册

在门户中的门户自定义组件中,添加用户注册后扩展点,在扩展点中调用在上一步中添加的“启动加入组织流程”服务,发起“外部用户审批”流程。这里调用的服务需要设置为匿名访问,参考最后一节“设置匿名访问”

1760008617388

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 权限,选择“门户定制-服务-启动加入组织流程”,如下图所示,确定后,点击保存并且发布,使之生效

1760065124868

results matching ""

    No results matching ""