com.hn.dingtalk.DingProcessInstanceUtil Maven / Gradle / Ivy
package com.hn.dingtalk;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import cn.jiguang.common.utils.StringUtils;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.hn.dingtalk.annotation.Process;
import com.hn.dingtalk.constant.DingConstant;
import com.hn.dingtalk.constant.DingURLConstant;
import com.hn.dingtalk.constant.ProcessFormType;
import com.hn.dingtalk.exception.DingTalkException;
import com.hn.dingtalk.domain.DingExt;
import com.hn.dingtalk.domain.ProcessForm;
import com.hn.dingtalk.domain.ProcessListIdsVo;
import com.hn.dingtalk.domain.ProcessModel;
import com.taobao.api.ApiException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 审批流工具类
*
* @author admin
*/
public class DingProcessInstanceUtil {
private static final Log log = LogFactory.get();
public static void main(String[] args) throws Exception {
/* DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/workrecord/getbyuserid");
OapiWorkrecordGetbyuseridRequest req = new OapiWorkrecordGetbyuseridRequest();
req.setUserid("0502101558117240531");
req.setOffset(0L);
req.setLimit(50L);
req.setStatus(0L);
OapiWorkrecordGetbyuseridResponse rsp = client.execute(req, AccessTokenUtil.getToken());
System.out.println(rsp.getBody());*/
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/processinstance/get");
OapiProcessinstanceGetRequest request = new OapiProcessinstanceGetRequest();
request.setProcessInstanceId("15558dda-5a5a-494f-9126-cf9ab9818391");
OapiProcessinstanceGetResponse response = client.execute(request,AccessTokenUtil.getToken());
System.out.println(response.getBody());
/* DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/process/listbyuserid");
OapiProcessListbyuseridRequest request = new OapiProcessListbyuseridRequest();
// request.setUserid("manager7078");
request.setOffset(0L);
request.setSize(100L);
OapiProcessListbyuseridResponse response = client.execute(request, AccessTokenUtil.getToken());
System.out.println(response.getResult());*/
/*ProcessListIdsVo processListIdsVo = new ProcessListIdsVo();
processListIdsVo.setProcessCode(DingConstant.PROCESS_CODE);
processListIdsVo.setStartTime(DateUtils.parseDate("2018-06-27 8:00:00").getTime());
processListIdsVo.setEndTime(System.currentTimeMillis());
processListIdsVo.setCursor(0L);
processListIdsVo.setSize(10L);
// processListIdsVo.setUserIdList("manager447");
OapiProcessinstanceListidsResponse.PageResult result = listids(processListIdsVo);
List list = result.getList();
for (String processId : list) {
OapiProcessinstanceGetResponse.ProcessInstanceTopVo processInstanceTopVo = get(processId);
String title = processInstanceTopVo.getTitle();
String originatorUserid = processInstanceTopVo.getOriginatorUserid();
List operationRecords = processInstanceTopVo.getOperationRecords();
System.out.println(originatorUserid);
}*/
/*OapiProcessinstanceCreateRequest request = new OapiProcessinstanceCreateRequest();
request.setProcessCode(DingConstant.PROCESS_CODE);
ProcessForm processForm = new ProcessForm();
processForm.put("请假类型","事假")
.put("开始时间","2019-06-27 10:39")
.put("结束时间","2019-06-29 10:39")
.put("时长","5")
.put("请假事由","测试请假事由2019-06-27 14:06");
List formComponentValues = processForm.getList();
request.setFormComponentValues(formComponentValues);
request.setApprovers("manager447");
request.setOriginatorUserId("manager447");
request.setDeptId(-1L);
request.setCcList("manager447");
request.setCcPosition("FINISH");
create(request);
*/
}
/**
* 发起审批实例
* @param request {@link OapiProcessinstanceCreateRequest}
* @return ProcessInstanceId
*/
public static String create(OapiProcessinstanceCreateRequest request) {
String originatorUserId = request.getOriginatorUserId();
if(StrUtil.isBlank(originatorUserId)){
throw new DingTalkException("当前用户未绑定钉钉用户");
}
DefaultDingTalkClient client = new DefaultDingTalkClient(DingURLConstant.URL_PROCESSINSTANCE_START);
OapiProcessinstanceCreateResponse response = null;
try {
response = client.execute(request, AccessTokenUtil.getToken());
} catch (ApiException e) {
throw new DingTalkException("发起审批实例异常," + e.getErrMsg());
}
if (DingConstant.SUCCESS_CODE.equals(response.getErrcode())) {
log.debug("发起审批实例 success,{}", response.getProcessInstanceId());
log.debug("发起审批实例 success,{}", response.getParams());
return response.getProcessInstanceId();
}
throw new DingTalkException("发起审批实例异常," + response.getMsg());
}
/**
* 获取审批实例详情
* @param processInstanceId 审批实例ID
* @return {@link OapiProcessinstanceGetResponse.ProcessInstanceTopVo}
*/
public static OapiProcessinstanceGetResponse.ProcessInstanceTopVo get(String processInstanceId) {
DingTalkClient client = new DefaultDingTalkClient(DingURLConstant.PROCESS_INSTANCE_GET);
OapiProcessinstanceGetRequest request = new OapiProcessinstanceGetRequest();
request.setProcessInstanceId(processInstanceId);
OapiProcessinstanceGetResponse response = null;
try {
response = client.execute(request, AccessTokenUtil.getToken());
} catch (ApiException e) {
throw new DingTalkException("获取审批实例详情异常," + e.getErrMsg());
}
if (DingConstant.SUCCESS_CODE.equals(response.getErrcode())) {
log.debug("获取审批实例详情 success,{}", JSONUtil.toJsonStr(response.getProcessInstance()));
return response.getProcessInstance();
}
throw new DingTalkException("获取审批实例详情异常," + response.getMsg());
}
/**
* 批量获取审批实例id
*
* @param processListIdsVo {@link ProcessListIdsVo}
* @return {@link OapiProcessinstanceListidsResponse.PageResult}
*/
public static OapiProcessinstanceListidsResponse.PageResult listIds(ProcessListIdsVo processListIdsVo) {
DingTalkClient client = new DefaultDingTalkClient(DingURLConstant.LIST_IDS);
OapiProcessinstanceListidsRequest req = new OapiProcessinstanceListidsRequest();
req.setProcessCode(processListIdsVo.getProcessCode());
req.setStartTime(processListIdsVo.getStartTime());
req.setEndTime(processListIdsVo.getEndTime());
req.setSize(processListIdsVo.getSize());
req.setCursor(processListIdsVo.getCursor());
// manager1,manager2
req.setUseridList(processListIdsVo.getUserIdList());
OapiProcessinstanceListidsResponse response = null;
try {
response = client.execute(req, AccessTokenUtil.getToken());
} catch (ApiException e) {
throw new DingTalkException("批量获取审批实例id异常," + e.getErrMsg());
}
if (DingConstant.SUCCESS_CODE.equals(response.getErrcode())) {
log.debug("批量获取审批实例id success,{}", JSONUtil.toJsonStr(response.getResult()));
return response.getResult();
}
throw new DingTalkException("批量获取审批实例id异常," + response.getMsg());
}
/**
* 获取用户待审批数量
*
* @param userId 用户ID
* @return 审批数量
*/
public static Long gettodonum(String userId) {
DingTalkClient client = new DefaultDingTalkClient(DingURLConstant.GET_TODO_NUM);
OapiProcessGettodonumRequest req = new OapiProcessGettodonumRequest();
req.setUserid(userId);
OapiProcessGettodonumResponse response = null;
try {
response = client.execute(req, AccessTokenUtil.getToken());
} catch (ApiException e) {
throw new DingTalkException("获取用户待审批数量异常," + e.getErrMsg());
}
if (DingConstant.SUCCESS_CODE.equals(response.getErrcode())) {
log.debug("获取用户待审批数量success,{}", response.getCount());
return response.getCount();
}
throw new DingTalkException("获取用户待审批数量异常," + response.getMsg());
}
/**
* 获取用户可见的审批模板
*
* @param userId 用户id
* @param offset 分页游标,从0开始。根据返回结果里的next_cursor是否为空来判断是否还有下一页,且再次调用时offset设置成next_cursor的值
* @param size 分页大小,最大可设置成100
* @return {@link OapiProcessListbyuseridResponse.HomePageProcessTemplateVo }
*/
public static OapiProcessListbyuseridResponse.HomePageProcessTemplateVo listbyuserid(String userId, Long offset, Long size) {
DingTalkClient client = new DefaultDingTalkClient(DingURLConstant.LIST_BY_USER_ID);
OapiProcessListbyuseridRequest request = new OapiProcessListbyuseridRequest();
request.setUserid(userId);
request.setOffset(offset);
request.setSize(size);
OapiProcessListbyuseridResponse response = null;
try {
response = client.execute(request, AccessTokenUtil.getToken());
} catch (ApiException e) {
throw new DingTalkException("获取用户可见的审批模板异常," + e.getErrMsg());
}
if (DingConstant.SUCCESS_CODE.equals(response.getErrcode())) {
log.debug("获取用户可见的审批模板success,{}", response.getResult());
return response.getResult();
}
throw new DingTalkException("获取用户可见的审批模板异常," + response.getMsg());
}
/**
* 获取审批钉盘空间信息
*
* 返回结果:
* {
* "result":{
* "space_id":12344546 审批钉盘空间id
* },
* "errcode":0,
* "errmsg":"成功",
* "success":true
* }
* @param userId 用户id
* @return {@link OapiProcessinstanceCspaceInfoResponse.AppSpaceResponse}
*/
public static OapiProcessinstanceCspaceInfoResponse.AppSpaceResponse cspaceInfo(String userId) {
DingTalkClient client = new DefaultDingTalkClient(DingURLConstant.CSPACE_INFO);
OapiProcessinstanceCspaceInfoRequest request = new OapiProcessinstanceCspaceInfoRequest();
request.setUserId(userId);
OapiProcessinstanceCspaceInfoResponse response = null;
try {
response = client.execute(request, AccessTokenUtil.getToken());
} catch (ApiException e) {
throw new DingTalkException("获取审批钉盘空间信息异常," + e.getErrMsg());
}
if (DingConstant.SUCCESS_CODE.equals(response.getErrcode())) {
log.debug("获取审批钉盘空间信息success,{}", response.getResult());
return response.getResult();
}
throw new DingTalkException("获取审批钉盘空间信息异常," + response.getMsg());
}
/**
* 创建审批模板
*
* @param modelName 审批模板名称
* @param processCode 审批模板的唯一码。在本接口中,如不传,表示新建一个模板。如传值了,表示更新所传值对应的审批模板
* @param clazz 审批模板对象
* @return processCode 审批模板code
*/
public static String saveProcessModel(String modelName, String processCode, Class clazz) {
DingTalkClient client = new DefaultDingTalkClient(DingURLConstant.SAVE_PROCESS_MODEL);
OapiProcessSaveRequest request = new OapiProcessSaveRequest();
OapiProcessSaveRequest.SaveProcessRequest saveProcessRequest = new OapiProcessSaveRequest.SaveProcessRequest();
// 是否允许表单在审批管理后台可编辑。true表示不可以
saveProcessRequest.setDisableFormEdit(false);
// 审批模板名称
saveProcessRequest.setName(modelName);
// 审批模板的唯一码。在本接口中,如不传,表示新建一个模板。如传值了,表示更新所传值对应的审批模板
saveProcessRequest.setProcessCode(processCode);
saveProcessRequest.setAgentid(Long.valueOf(DingConstant.AGENTID));
// 实体类转成模板
ProcessModel processModel = ProcessModel.convert(clazz);
List formComponentList = processModel.getFormComponentList();
System.out.println(JSONUtil.toJsonStr(formComponentList));
saveProcessRequest.setFormComponentList(formComponentList);
request.setSaveProcessRequest(saveProcessRequest);
OapiProcessSaveResponse response = null;
try {
response = client.execute(request, AccessTokenUtil.getToken());
} catch (ApiException e) {
throw new DingTalkException("创建审批模板异常," + e.getErrMsg());
}
if (DingConstant.SUCCESS_CODE.equals(response.getErrcode())) {
log.debug("创建审批模板success,{}", response.getResult());
return response.getResult().getProcessCode();
}
throw new DingTalkException("创建审批模板异常," + response.getMsg());
}
/**
* 删除模板
* @param processCode 审批模板code
*/
public static void delProcessModel(String processCode) {
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/process/delete");
OapiProcessDeleteRequest req = new OapiProcessDeleteRequest();
OapiProcessDeleteRequest.DeleteProcessRequest processRequest = new OapiProcessDeleteRequest.DeleteProcessRequest();
processRequest.setAgentid(Long.valueOf(DingConstant.AGENTID));
processRequest.setProcessCode(processCode);
req.setRequest(processRequest);
OapiProcessDeleteResponse response = null;
try {
response = client.execute(req, AccessTokenUtil.getToken());
} catch (ApiException e) {
// throw new DingTalkException("删除审批模板异常," + e.getErrMsg());
log.debug("删除审批模板success,{}", e.getErrMsg());
}
if (DingConstant.SUCCESS_CODE.equals(response.getErrcode())) {
log.debug("删除审批模板success,{}", response.getSuccess());
}
}
public static ProcessForm convert(Object obj) {
// 有数据时才处理 得到类的所有field.
Class> clazz = obj.getClass();
Field[] allFields = clazz.getDeclaredFields();
// 定义一个map用于存放列的序号和field.
ProcessForm processForm = new ProcessForm();
for (int col = 0; col < allFields.length; col++) {
Field field = allFields[col];
Process process = field.getAnnotation(Process.class);
if (process != null) {
// 设置类的私有字段属性可访问.
field.setAccessible(true);
Object value = null;
try {
value = field.get(obj);
} catch (IllegalAccessException e) {
throw new DingTalkException("审批流:获取属性值错误");
}
if (value != null) {
if(value instanceof String){
if(StrUtil.isBlank(String.valueOf(value))){
continue;
}
}
// 取得表单类型
ProcessFormType formType = process.formType();
if(ProcessFormType.DDDateField.equals(formType)){
Date val = (Date) value;
value = DateUtil.formatDate(val);
}else if(ProcessFormType.DDPhotoField.equals(formType)){
String val = String.valueOf(value);
String[] imgUrls = val.split(";");
value = JSONUtil.toJsonStr(imgUrls);
}else if(ProcessFormType.DDAttachment.equals(formType)){
String val = String.valueOf(value);
String[] files = val.split(";");
JSONArray array = new JSONArray();
for (String file : files) {
JSONObject attachmentJson = JSONUtil.parseObj(file);
array.add(attachmentJson);
}
value = array.toString();
}else if(ProcessFormType.TableField.equals(formType)){
if(value instanceof List){
// 子组件
List list = (ArrayList)value;
List childrens = new ArrayList();
for (Object o : list) {
ProcessForm childrenProcessForm = convert(o);
childrens.add(childrenProcessForm.getList().toArray());
}
value = JSONUtil.toJsonStr(childrens);
}else if(value instanceof String){
String str = String.valueOf(value);
String[] split = str.split(";");
List childrens = new ArrayList();
for (String s : split) {
DingExt dingExt = JSONUtil.toBean(s,DingExt.class);
ProcessForm childrenProcessForm = convert(dingExt);
childrens.add(childrenProcessForm.getList().toArray());
}
value = JSONUtil.toJsonStr(childrens);
}
}
if (StringUtils.isNotEmpty(process.readConverterExp())) {
try {
value = reverseByExp(String.valueOf(value), process.readConverterExp());
} catch (Exception e) {
throw new DingTalkException("审批流:类型转换错误");
}
}
String valStr = String.valueOf(value);
if (StrUtil.isNotBlank(valStr)) {
processForm.put(process.name(), valStr);
log.info("name={},value={}", process.name(), valStr);
}
}
}
}
return processForm;
}
/**
* 反向解析值 男=0,女=1,未知=2
*
* @param propertyValue 参数值
* @param converterExp 翻译注解
* @return 解析后值
*/
public static String reverseByExp(String propertyValue, String converterExp){
try {
String[] convertSource = converterExp.split(",");
for (String item : convertSource) {
String[] itemArray = item.split("=");
if (itemArray[0].equals(propertyValue)) {
return itemArray[1];
}
}
} catch (Exception e) {
log.error("反向解析值失败:{}",e.getMessage());
throw new DingTalkException("反向解析值失败");
}
return propertyValue;
}
}