看别人的一开口就是企业微信文档多坑多坑不知道是不是需求不同,我看的部分还是很不错了的,在这总结一下

需求是在我们系统里面 提交审批申请 在企业微信里审批,同时监控审批流的状态完成时继续后续操作

代码: https://gitee.com/lanyanhua/wechat-flow.git

需要的参数

企业ID,审批应用ID,审批应用Secret,审批流模版ID

模版ID位置比较变态点开审批流在url里

java 提起企业微信审批 企业微信流程审批_Text

创建流程所需的参数还差三个:token,userid,审批流模版的控件ID

1.获取token

/**
     * 获取access_token
     *
     * @return token
     */
    public String getAccessToken() {
        //企业ID
        String id = "XXXXXXXXXXXXXXXXXX";
        //审批应用Secret
        String secret = "XXXXXXXXXXXXXXXXXX";
        String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET"
                .replace("ID", id).replace("SECRET", secret);
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<AccessTokenResult> responseEntity = restTemplate.getForEntity(url, AccessTokenResult.class);

        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            AccessTokenResult ac = responseEntity.getBody();
            if (ac.getErrcode() == 0) {
                return ac.getAccess_token();
            }
        }
        throw new BusinessException("获取微信token失败");
    }
import lombok.Data;
@Data
public class AccessTokenResult {
    /**
     * errcode : 0
     * errmsg : ok
     * access_token : accesstoken000001
     * expires_in : 7200
     */

    private int errcode;
    private String errmsg;
    private String access_token;
    private int expires_in;

}

2.获取userid 后台可以更改只能改一次

java 提起企业微信审批 企业微信流程审批_json_02

java 提起企业微信审批 企业微信流程审批_Text_03

3.获取审批流里面控件的ID

根据模版ID调用接口获取模版信息 找出需要赋值的 控件id

参数

说明

template_names

模板名称,若配置了多语言则会包含中英文的模板名称,默认为zh_CN中文

template_content

模板控件信息

└ controls

模板控件数组。模板详情由多个不同类型的控件组成,控件类型详细说明见附录。

└ └ property

模板控件属性,包含了模板内控件的各种属性信息

└ └ └ control

控件类型:Text-文本;Textarea-多行文本;Number-数字;Money-金额;Date-日期/日期+时间;Selector-单选/多选;Contact-成员/部门;Tips-说明文字;File-附件;Table-明细;Attendance-假勤控件;Vacation-请假控件

└ └ └ id

控件id

└ └ └ title

控件名称,若配置了多语言则会包含中英文的控件名称,默认为zh_CN中文

└ └ └ placeholder

控件说明,向申请者展示的控件填写说明,若配置了多语言则会包含中英文的控件说明,默认为zh_CN中文

└ └ └ require

是否必填:1-必填;0-非必填

└ └ └ un_print

是否参与打印:1-不参与打印;0-参与打印

└ └ config

模板控件配置,包含了部分控件类型的附加类型、属性,详见附录说明。目前有配置信息的控件类型有:Date-日期/日期+时间;Selector-单选/多选;Contact-成员/部门;Table-明细;Attendance-假勤组件(请假、外出、出差、加班)

/**
     * 获取审批模板详情
     *
     * @param templateId id
     */
    public String getTemplateDetail(String templateId) {
        String url = "https://qyapi.weixin.qq.com/cgi-bin/oa/gettemplatedetail?access_token=ACCESS_TOKEN"
                .replace("ACCESS_TOKEN", token);

        RestTemplate restTemplate = new RestTemplate();
        Map<String, String> reqParam = new HashMap<>();
        reqParam.put("template_id", templateId);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, reqParam, String.class);
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            return responseEntity.getBody();
        }
        return "失败";
    }

主要的两个接口:提交审批申请、审批申请状态变化回调通知

提交审批申请

调用接口返回流程编号需要存下后面交互时需要用到

/**
     * 提交审批申请
     *
     * @param param 参数
     * @return 编号
     */
    public String commitApprovalApply(CommitApprovalApplyParam param) {
        String url = "https://qyapi.weixin.qq.com/cgi-bin/oa/applyevent?access_token=ACCESS_TOKEN"
                .replace("ACCESS_TOKEN", token);

        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<JSONObject> responseEntity = restTemplate.postForEntity(url, param, JSONObject.class);
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            JSONObject body = responseEntity.getBody();
            if (body.getInteger("errcode") == 0) {
                return body.getString("sp_no");
            }
        }
        throw new BusinessException("提交审批流程失败");
    }

调用方法代码

@Test
    public void testCommitApprovalApply() {
        //提交审批申请
        String creator_userid = "cab";
        String template_id = "XXXXXXXXXXXXXXX";
        CommitApprovalApplyParam param = new CommitApprovalApplyParam(creator_userid, template_id);
        //添加审批人
        param.addApprover(2, "XXXXXXX");
        //审批申请数据
        param.setApplyDataContents(
                param.controlText("Text-1586447955368", "文本1"),
                param.controlText("Text-1586447964627", "文本2"),
                param.controlText("Text-1586447975810", "文本3")
        );
        //摘要信息
        param.setSummaryInfo("摘要信息1", "摘要信息2", "摘要信息3");
        //抄送人
        param.setNotifyer("XXX");
        param.setNotify_type(2);
        System.out.println(JSON.toJSONString(param));
        //调用
        String sp_no = commitApprovalApply(param);
        System.out.println(sp_no);
    }
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.experimental.Accessors;

import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName: CommitApprovalApplyParam
 * @Description:TODO ()
 * @author: lanyanhua
 * @date: 2020/10/14 2:41 下午
 * @Copyright:
 */
@Data
@Accessors(chain = true)
public class CommitApprovalApplyParam {


    /*
     * creator_userid : WangXiaoMing
     * template_id : 3Tka1eD6v6JfzhDMqPd3aMkFdxqtJMc2ZRioeFXkaaa
     * use_template_approver : 0
     * approver : [{"attr":2,"userid":["WuJunJie","WangXiaoMing"]},{"attr":1,"userid":["LiuXiaoGang"]}]
     * notifyer : ["WuJunJie","WangXiaoMing"]
     * notify_type : 1
     * apply_data : {"contents":[{"control":"Text","id":"Text-15111111111","value":{"text":"文本填写的内容"}}]}
     * summary_list : [{"summary_info":[{"text":"摘要第1行","lang":"zh_CN"}]},{"summary_info":[{"text":"摘要第2行","lang":"zh_CN"}]},{"summary_info":[{"text":"摘要第3行","lang":"zh_CN"}]}]
     */

    /**
     * 申请人userid
     */
    private String creator_userid;
    /**
     * 模板id
     */
    private String template_id;
    /**
     * 审批人模式:0-通过接口指定审批人、抄送人(此时approver、notifyer等参数可用); 1-使用此模板在管理后台设置的审批流程,支持条件审批。默认为0
     */
    private int use_template_approver;
    /**
     * 抄送方式:1-提单时抄送(默认值); 2-单据通过后抄送;3-提单和单据通过后抄送。仅use_template_approver为0时生效。
     */
    private int notify_type;
    /**
     * 抄送人节点userid列表,仅use_template_approver为0时生效。
     */
    private String[] notifyer;
    /**
     * 审批申请数据,可定义审批申请中各个控件的值,其中必填项必须有值,选填项可为空,数据结构同“获取审批申请详情”接口返回值中同名参数“apply_data”
     */
    private JSONObject apply_data;
    /**
     * 审批流程信息,用于指定审批申请的审批流程,支持单人审批、多人会签、多人或签,可能有多个审批节点,仅use_template_approver为0时生效。
     */
    private JSONArray approver;
    /**
     * 摘要信息,用于显示在审批通知卡片、审批列表的摘要信息,最多3行
     */
    private JSONArray summary_list;

    public CommitApprovalApplyParam() {
        this.use_template_approver = 0;
        this.apply_data = new JSONObject();
        this.approver = new JSONArray();
        this.summary_list = new JSONArray();
    }

    public CommitApprovalApplyParam(String creator_userid, String template_id) {
        this();
        this.creator_userid = creator_userid;
        this.template_id = template_id;
    }

    public void  setNotifyer(String... notifyer){
        this.notifyer = notifyer;
    }
    /**
     * 添加审批人
     *
     * @param attr   节点审批方式:1-或签;2-会签,仅在节点为多人审批时有效
     *               会签:指同一个审批节点设置多个人,如ABC三人,三人会同时收到审批,需全部同意之后,审批才可到下一审批节点;
     *               或签:指同一个审批节点设置多个人,如ABC三人,三人会同时收到审批,只要其中任意一人审批即可到下一审批节点;
     * @param userId 审批节点审批人userid列表,若为多人会签、多人或签,需填写每个人的userid
     */
    public void addApprover(int attr, String... userId) {
        JSONObject json = new JSONObject();
        json.put("attr", attr);
        json.put("userid", userId);
        this.approver.add(json);
    }

    /**
     * 审批申请详情
     *
     * @param contents 审批申请详情,由多个表单控件及其内容组成,其中包含需要对控件赋值的信息
     */
    public void setApplyDataContents(JSONObject... contents) {
        // 审批申请详情,由多个表单控件及其内容组成,其中包含需要对控件赋值的信息
        this.apply_data.put("contents", contents);
    }
    /**
     * 摘要信息,用于显示在审批通知卡片、审批列表的摘要信息,最多3行
     *
     * @param text 摘要行显示文字,用于记录列表和消息通知的显示,不要超过20个字符
     */
    public void setSummaryInfo(String... text) {
        for (String s : text) {
            JSONArray summaryInfoArr = new JSONArray();
            JSONObject textObj = new JSONObject();
            textObj.put("text",s);
            textObj.put("lang","zh_CN");
            summaryInfoArr.add(textObj);
            JSONObject summaryInfo = new JSONObject();
            summaryInfo.put("summary_info",summaryInfoArr);
            // 摘要信息,用于显示在审批通知卡片、审批列表的摘要信息,最多3行
            this.summary_list.add(summaryInfo);
        }
    }

    /**
     * 文本/多行文本控件(control参数为Text或Textarea)
     *
     * @param id   控件ID
     * @param text 文本内容,在此填写文本/多行文本控件的输入值
     */
    public JSONObject controlText(String id, String text) {
        JSONObject value = new JSONObject();
        value.put("text", text);

        return createControl(id, ControlType.text, value);
    }

    /**
     * 数字控件(control参数为Number)
     *
     * @param id         控件ID
     * @param new_number 数字内容,在此填写数字控件的输入值
     */
    public JSONObject controlNumber(String id, String new_number) {
        JSONObject value = new JSONObject();
        value.put("new_number", new_number);

        return createControl(id, ControlType.number, value);
    }

    /**
     * 金额控件(control参数为Money)
     *
     * @param id        控件ID
     * @param new_money 金额内容,在此填写金额控件的输入值
     */
    public JSONObject controlMoney(String id, String new_money) {
        JSONObject value = new JSONObject();
        value.put("new_money", new_money);

        return createControl(id, ControlType.money, value);
    }

    /**
     * 日期/日期+时间控件(control参数为Date)
     *
     * @param id          控件ID
     * @param type        时间展示类型:day-日期;hour-日期+时间 ,和对应模板控件属性一致
     * @param s_timestamp 时间戳-字符串类型,在此填写日期/日期+时间控件的选择值,以此为准
     */
    public JSONObject controlDate(String id, String type, String s_timestamp) {
        //{
        //    "date": {
        //        "type": "day",
        //        "s_timestamp": "1569859200"
        //    }
        //}
        JSONObject value = new JSONObject();
        JSONObject date = new JSONObject();
        value.put("date", date);
        date.put("type", type);
        date.put("s_timestamp", s_timestamp);

        return createControl(id, ControlType.date, value);
    }

    /**
     * 单选/多选控件(control参数为Selector)
     *
     * @param id   控件ID
     * @param type 选择方式:single-单选;multi-多选
     * @param key  选项key,可通过“获取审批模板详情”接口获得
     */
    public JSONObject controlSelector(String id, String type, String... key) {
        //{
        //    "selector": {
        //        "type": "multi",
        //        "options": [
        //            {
        //                "key": "option-15111111111",
        //            },
        //            {
        //                "key": "option-15222222222",
        //            }
        //        ]
        //    }
        //}
        JSONObject value = new JSONObject();
        JSONObject selector = new JSONObject();
        JSONArray options = new JSONArray();
        value.put("selector", selector);
        selector.put("type", type);
        selector.put("options", options);

        for (String s : key) {
            JSONObject option = new JSONObject();
            option.put("key", s);
            options.add(option);
        }

        return createControl(id, ControlType.selector, value);
    }

    /**
     * 成员控件(control参数为Contact,且value参数为members)
     *
     * @param id      控件ID
     * @param userIds 所选成员的userid
     * @param names   成员名
     */
    public JSONObject controlMembers(String id, List<String> userIds, List<String> names) {
        //{
        //    "members": [
        //        {
        //            "userid": "WuJunJie",
        //            "name": "Jackie"
        //        },
        //        {
        //            "userid": "WangXiaoMing"
        //            "name": "Tom"
        //        }
        //    ]
        //}
        JSONObject value = new JSONObject();
        JSONArray members = new JSONArray();
        value.put("members", members);
        for (int i = 0; i < userIds.size(); i++) {
            JSONObject member = new JSONObject();
            member.put("userid", userIds.get(i));
            member.put("name", names.get(i));
            members.add(member);
        }

        return createControl(id, ControlType.contact, value);
    }

    /**
     * 部门控件(control参数为Contact,且value参数为departments)
     *
     * @param id        控件ID
     * @param openapiId 所选部门id
     * @param names     所选部门名
     */
    public JSONObject controlDepartments(String id, List<String> openapiId, List<String> names) {
        //{
        //    "departments": [
        //        {
        //            "openapi_id": "2",
        //            "name": "销售部",
        //        },
        //        {
        //            "openapi_id": "3",
        //            "name": "生产部",
        //        }
        //    ]
        //}
        JSONObject value = new JSONObject();
        JSONArray members = new JSONArray();
        value.put("departments", members);
        for (int i = 0; i < openapiId.size(); i++) {
            JSONObject member = new JSONObject();
            member.put("openapi_id", openapiId.get(i));
            member.put("name", names.get(i));
            members.add(member);
        }

        return createControl(id, ControlType.contact, value);
    }

    /**
     * 附件控件(control参数为File,且value参数为files)
     *
     * @param id     控件ID
     * @param fileid 文件id,该id为临时素材上传接口返回的的media_id,注:提单后将作为单据内容转换为长期文件存储;目前一个审批申请单,全局仅支持上传6个附件,否则将失败。
     */
    public JSONObject controlFile(String id, String... fileid) {
        //{
        //    "files": [
        //        {
        //            "file_id": "1G6nrLmr5EC3MMb_-zK1dDdzmd0p7cNliYu9V5w7o8K1aaa"
        //        }
        //    ]
        //}
        JSONObject value = new JSONObject();
        JSONArray files = new JSONArray();
        value.put("files", files);
        for (String s : fileid) {

            JSONObject file = new JSONObject();
            file.put("file_id", s);
            files.add(file);
        }

        return createControl(id, ControlType.file, value);
    }

    public JSONObject createControl(String id, String type, JSONObject value) {
        JSONObject control = new JSONObject();
        control.put("id", id);
        control.put("control", type);
        control.put("value", value);
        return control;
    }

}
/**
 * @ClassName: ControlType
 * @Description:TODO ()
 * @author: lanyanhua
 * @date: 2020/10/14 3:03 下午
 * @Copyright:
 */
public class ControlType {
    //控件类型:Text-文本;Textarea-多行文本;Number-数字;Money-金额;Date-日期/日期+时间;
    // Selector-单选/多选;;Contact-成员/部门;Tips-说明文字;File-附件;Table-明细;
    public static final String text = "Text";
    public static final String textarea = "Textarea";
    public static final String number = "Number";
    public static final String money = "Money";
    public static final String date = "Date";
    public static final String selector = "Selector";
    public static final String contact = "Tips";
    public static final String file = "File";
    public static final String table = "Table";
}

审批申请状态变化回调通知 这个接口看另外一篇