丽知:新增:u8c对接钉钉
This commit is contained in:
parent
4426946bdb
commit
c51f59b8ca
|
@ -0,0 +1,44 @@
|
|||
package com.hzya.frame.plugin.lets.dingtalk.callback;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.hzya.frame.plugin.lets.dingtalk.callback.service.CallBackService;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 钉钉回调u8c接口
|
||||
*/
|
||||
@Controller("ding_talk_call_back")
|
||||
@RequestMapping("/ding_talk_call_back")
|
||||
public class CallBackController {
|
||||
|
||||
protected Logger logger = LogManager.getLogger(CallBackController.class);
|
||||
|
||||
@Autowired
|
||||
private CallBackService callBackService;
|
||||
|
||||
@RequestMapping(value = "res")
|
||||
@ResponseBody
|
||||
public Map<String, String> res(@RequestParam(value = "msg_signature", required = false) String msg_signature,
|
||||
@RequestParam(value = "timestamp", required = false) String timeStamp,
|
||||
@RequestParam(value = "nonce", required = false) String nonce,
|
||||
@RequestBody(required = false) JSONObject json) {
|
||||
try {
|
||||
logger.info("=============================================================================================================================钉钉回调执行快开始》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》");
|
||||
Map<String, String> map = callBackService.saveDingTalkCallBackRes(msg_signature, timeStamp, nonce, json);
|
||||
logger.info("=============================================================================================================================钉钉回调执行结束《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《");
|
||||
return map;
|
||||
} catch (Exception e) {
|
||||
logger.error("execute", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package com.hzya.frame.plugin.lets.dingtalk.callback.service;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface CallBackService {
|
||||
Map<String, String> saveDingTalkCallBackRes(String msg_signature, String timeStamp, String nonce, JSONObject json);
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package com.hzya.frame.plugin.lets.dingtalk.callback.service.impl;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.hzya.frame.plugin.lets.dingtalk.callback.service.CallBackService;
|
||||
import com.hzya.frame.plugin.lets.dingtalk.vo.DingCallbackCrypto;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Service("callBackService")
|
||||
public class CallBackServiceImpl implements CallBackService {
|
||||
|
||||
protected static Logger logger = LogManager.getLogger(CallBackServiceImpl.class);
|
||||
|
||||
@Value("${DING.call_back_token}")
|
||||
private String token;
|
||||
@Value("${DING.call_back_aes_key}")
|
||||
private String aes_key;
|
||||
@Value("${DING.APPKEY}")
|
||||
private String corpId;
|
||||
|
||||
@Override
|
||||
public Map<String, String> saveDingTalkCallBackRes(String msg_signature, String timeStamp, String nonce, JSONObject json) {
|
||||
logger.info("=============================================================================================================================钉钉回调执行快开始》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》");
|
||||
try {
|
||||
|
||||
// 1. 从http请求中获取加解密参数
|
||||
// 2. 使用加解密类型
|
||||
// 2、调用订阅事件接口订阅的事件为企业级事件推送,此时OWNER_KEY为:开发者后台应用的Client ID(原企业内部应用 appKey )
|
||||
//token、ase_key均为钉钉开放平台后台管理,应用设置的事件订阅,http推送中设置的参数。
|
||||
DingCallbackCrypto callbackCrypto = new DingCallbackCrypto(token, aes_key, corpId);
|
||||
String encryptMsg = json.getString("encrypt");
|
||||
String decryptMsg = callbackCrypto.getDecryptMsg(msg_signature, timeStamp, nonce, encryptMsg);
|
||||
|
||||
// 3. 反序列化回调事件json数据
|
||||
JSONObject eventJson = JSON.parseObject(decryptMsg);
|
||||
|
||||
String eventType = eventJson.getString("EventType");
|
||||
|
||||
// 4. 根据EventType分类处理
|
||||
if ("check_url".equals(eventType)) {
|
||||
// 测试回调url的正确性
|
||||
logger.info("测试回调url的正确性");
|
||||
} else if ("bpms_instance_change".equals(eventType)) {
|
||||
// 处理通讯录用户增加事件
|
||||
logger.info("发生了:" + eventType + "事件");
|
||||
} else {
|
||||
// 添加其他已注册的
|
||||
logger.info("发生了:" + eventType + "事件");
|
||||
}
|
||||
|
||||
// 5. 返回success的加密数据
|
||||
Map<String, String> successMap = callbackCrypto.getEncryptedMap("success");
|
||||
logger.info("=============================================================================================================================钉钉回调执行结束《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《");
|
||||
return successMap;
|
||||
}catch (Exception e){
|
||||
logger.error("execute", e);
|
||||
Assert.state(false, "excute:{}", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.hzya.frame.plugin.lets.dingtalk.push;
|
||||
|
||||
import com.hzya.frame.plugin.lets.dingtalk.push.serivce.PushU8CService;
|
||||
import com.hzya.frame.plugin.lets.dingtalk.vo.DjzbVO;
|
||||
import com.hzya.frame.web.action.DefaultController;
|
||||
import com.hzya.frame.web.entity.JsonResultEntity;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* u8c单据推送钉钉表单
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/letsPush")
|
||||
public class PushController extends DefaultController {
|
||||
|
||||
@Autowired
|
||||
private PushU8CService pushU8CService;
|
||||
|
||||
/** 委外采购(付款单)->采购付款申请(新) **/
|
||||
@RequestMapping(value = "U8COutSourceBill")
|
||||
@ResponseBody
|
||||
public JsonResultEntity pushU8COutSourceBill(DjzbVO djzbVO, List<String> fileBase64s){
|
||||
pushU8CService.outSource(djzbVO,fileBase64s);
|
||||
System.out.println("com.hzya.frame.plugin.lets.dingtalk.push.pushController.pushU8COutSourceBill");
|
||||
return getSuccessMessageEntity("112233445566778899");
|
||||
|
||||
}
|
||||
|
||||
/** 代理采购(付款单)->采购付款申请(店群专用) **/
|
||||
@RequestMapping(value = "U8CAgencyBill")
|
||||
@ResponseBody
|
||||
public JsonResultEntity pushU8CAgencyBill(DjzbVO djzbVO, List<String> fileBase64s){
|
||||
System.out.println("com.hzya.frame.plugin.lets.dingtalk.push.pushController.pushU8CAgencyBill");
|
||||
return getSuccessMessageEntity("112233445566778899");
|
||||
}
|
||||
|
||||
/** 调拨单内部交易(付款单)->特殊业务处理(新) **/
|
||||
@RequestMapping(value = "U8CTransferBill")
|
||||
@ResponseBody
|
||||
public JsonResultEntity pushU8CTransferBill(DjzbVO djzbVO, List<String> fileBase64s){
|
||||
System.out.println("com.hzya.frame.plugin.lets.dingtalk.push.pushController.pushU8CTransferBill");
|
||||
return getSuccessMessageEntity("112233445566778899");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.hzya.frame.plugin.lets.dingtalk.push.serivce;
|
||||
|
||||
import com.hzya.frame.plugin.lets.dingtalk.vo.DjzbVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface PushU8CService {
|
||||
/** 委外采购(付款单)->采购付款申请(新) **/
|
||||
public String outSource(DjzbVO djzbVO, List<String> fileBase64s);
|
||||
/** 代理采购(付款单)->采购付款申请(店群专用) **/
|
||||
public String agency(DjzbVO djzbVO, List<String> fileBase64s);
|
||||
/** 调拨单内部交易(付款单)->特殊业务处理(新) **/
|
||||
public String transfer(DjzbVO djzbVO, List<String> fileBase64s);
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package com.hzya.frame.plugin.lets.dingtalk.push.serivce.impl;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import com.hzya.frame.plugin.lets.dingtalk.push.serivce.PushU8CService;
|
||||
import com.hzya.frame.plugin.lets.dingtalk.vo.DjzbVO;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* u8c单据推送钉钉表单
|
||||
* fileBase64s为文件转了base64之后
|
||||
*/
|
||||
@Service("PushU8CService")
|
||||
public class PushU8CServiceImpl implements PushU8CService {
|
||||
|
||||
/** 委外采购(付款单)->采购付款申请(新) */
|
||||
@Override
|
||||
public String outSource(DjzbVO djzbVO, List<String> fileBase64s) {
|
||||
checkParameter(djzbVO,fileBase64s);
|
||||
return null;
|
||||
}
|
||||
|
||||
/** 代理采购(付款单)->采购付款申请(店群专用) */
|
||||
@Override
|
||||
public String agency(DjzbVO djzbVO, List<String> fileBase64s) {
|
||||
checkParameter(djzbVO,fileBase64s);
|
||||
return null;
|
||||
}
|
||||
|
||||
/** 调拨单内部交易(付款单)->特殊业务处理(新) */
|
||||
@Override
|
||||
public String transfer(DjzbVO djzbVO, List<String> fileBase64s) {
|
||||
checkParameter(djzbVO,fileBase64s);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查参数,VO不能为空,文件不能空
|
||||
* @param djzbVO
|
||||
* @param fileBase64s
|
||||
*/
|
||||
public void checkParameter(DjzbVO djzbVO, List<String> fileBase64s){
|
||||
Assert.notNull(djzbVO,"u8c单据推送钉钉表单,检查参数,VO不能为空");
|
||||
if (fileBase64s.size() == 0) {
|
||||
Assert.state(false,"u8c单据推送钉钉表单,检查参数,文件不能空");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件转换
|
||||
* 将base64转为文件上传钉盘,并返回钉钉的 List<FileModuleVO>
|
||||
* @return
|
||||
*/
|
||||
public List<File> baseTransformFile(List<String> fileBase64s){
|
||||
List<File> fileList=new ArrayList<>();
|
||||
for (String fileBase64 : fileBase64s) {
|
||||
// 解码Base64字符串
|
||||
byte[] decodedBytes = Base64.getDecoder().decode(fileBase64);
|
||||
}
|
||||
return fileList;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,562 @@
|
|||
package com.hzya.frame.plugin.lets.dingtalk.utils;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponse;
|
||||
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponseBody;
|
||||
import com.aliyun.dingtalkstorage_1_0.models.AddPermissionResponse;
|
||||
import com.aliyun.dingtalkstorage_1_0.models.CommitFileRequest;
|
||||
import com.aliyun.dingtalkstorage_1_0.models.CommitFileResponse;
|
||||
import com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoResponse;
|
||||
import com.aliyun.dingtalkworkflow_1_0.models.*;
|
||||
import com.aliyun.tea.TeaException;
|
||||
import com.aliyun.teautil.models.RuntimeOptions;
|
||||
import com.dingtalk.api.DefaultDingTalkClient;
|
||||
import com.dingtalk.api.DingTalkClient;
|
||||
import com.dingtalk.api.request.*;
|
||||
import com.dingtalk.api.response.*;
|
||||
import com.taobao.api.ApiException;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DingTalkUtils {
|
||||
protected static Logger logger = LogManager.getLogger(DingTalkUtils.class);
|
||||
|
||||
private final static String PROTOCOL = "https";
|
||||
private final static String REGIONID = "central";
|
||||
public static com.aliyun.dingtalkworkflow_1_0.Client createClient() throws Exception {
|
||||
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
|
||||
config.protocol = PROTOCOL;
|
||||
config.regionId = REGIONID;
|
||||
return new com.aliyun.dingtalkworkflow_1_0.Client(config);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 企业内部应用
|
||||
* 获取钉钉access_token
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static GetAccessTokenResponseBody getTokenBody(String appkey, String appsecret) throws Exception {
|
||||
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
|
||||
config.protocol = PROTOCOL;
|
||||
config.regionId = REGIONID;
|
||||
com.aliyun.dingtalkoauth2_1_0.Client client = new com.aliyun.dingtalkoauth2_1_0.Client(config);
|
||||
com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest getAccessTokenRequest = new com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest()
|
||||
.setAppKey(appkey)//正式环境
|
||||
.setAppSecret(appsecret);//正式环境
|
||||
try {
|
||||
GetAccessTokenResponse accessToken = client.getAccessToken(getAccessTokenRequest);
|
||||
return accessToken.getBody();
|
||||
} catch (TeaException err) {
|
||||
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
||||
logger.error(err);
|
||||
}
|
||||
|
||||
} catch (Exception _err) {
|
||||
TeaException err = new TeaException(_err.getMessage(), _err);
|
||||
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
||||
logger.error(err);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取人员ID列表
|
||||
*
|
||||
* @param accessToken
|
||||
* @return
|
||||
*/
|
||||
public static OapiUserListidResponse getUserIdList(String accessToken) {
|
||||
try {
|
||||
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/listid");
|
||||
OapiUserListidRequest req = new OapiUserListidRequest();
|
||||
req.setDeptId(1L);
|
||||
OapiUserListidResponse rsp = client.execute(req, accessToken);
|
||||
System.out.println(rsp.getBody());
|
||||
return rsp;
|
||||
} catch (ApiException e) {
|
||||
e.printStackTrace();
|
||||
logger.error(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取部门列表
|
||||
*
|
||||
* @param accessToken
|
||||
* @return
|
||||
*/
|
||||
public static OapiV2DepartmentListsubResponse getDeptList(String accessToken, Long deptid) {
|
||||
try {
|
||||
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
|
||||
OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest();
|
||||
if (deptid != null) {
|
||||
req.setDeptId(deptid);
|
||||
}
|
||||
req.setLanguage("zh_CN");
|
||||
OapiV2DepartmentListsubResponse rsp = client.execute(req, accessToken);
|
||||
return rsp;
|
||||
} catch (ApiException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据部门ID获取部门详情
|
||||
*
|
||||
* @param accessToken
|
||||
* @param deptId
|
||||
* @return
|
||||
*/
|
||||
public static OapiV2DepartmentGetResponse getDeptByDeptId(String accessToken, Long deptId) {
|
||||
OapiV2DepartmentGetResponse oapiV2DepartmentGetResponse = new OapiV2DepartmentGetResponse();
|
||||
try {
|
||||
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/get");
|
||||
OapiV2DepartmentGetRequest req = new OapiV2DepartmentGetRequest();
|
||||
req.setDeptId(deptId);
|
||||
oapiV2DepartmentGetResponse = client.execute(req, accessToken);
|
||||
} catch (ApiException e) {
|
||||
e.printStackTrace();
|
||||
Assert.state(false, e.getMessage());
|
||||
}
|
||||
return oapiV2DepartmentGetResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据部门id查询用户id列表
|
||||
* 开发组:dept_id--》624820307L
|
||||
*
|
||||
* @param accessToken
|
||||
* @param deptId
|
||||
*/
|
||||
public static OapiUserListidResponse getUserIdListByDeptId(String accessToken, Long deptId) {
|
||||
try {
|
||||
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/listid");
|
||||
OapiUserListidRequest req = new OapiUserListidRequest();
|
||||
req.setDeptId(deptId);
|
||||
OapiUserListidResponse rsp = client.execute(req, accessToken);
|
||||
return rsp;
|
||||
} catch (ApiException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户id查询用户详情
|
||||
*
|
||||
* @param accessToken
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
public static OapiV2UserGetResponse getUserById(String accessToken, String userId) {
|
||||
try {
|
||||
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
|
||||
OapiV2UserGetRequest req = new OapiV2UserGetRequest();
|
||||
req.setUserid(userId);
|
||||
OapiV2UserGetResponse rsp = client.execute(req, accessToken);
|
||||
return rsp;
|
||||
} catch (ApiException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据手机号查询用户详情
|
||||
*
|
||||
* @param accessToken
|
||||
* @param mobile
|
||||
* @return
|
||||
*/
|
||||
public static OapiV2UserGetbymobileResponse getUserByMobile(String accessToken, String mobile) {
|
||||
try {
|
||||
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getbymobile");
|
||||
OapiV2UserGetbymobileRequest req = new OapiV2UserGetbymobileRequest();
|
||||
req.setMobile(mobile);
|
||||
OapiV2UserGetbymobileResponse rsp = client.execute(req, accessToken);
|
||||
return rsp;
|
||||
} catch (ApiException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据部门id获取用户详细列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static OapiV2UserListResponse getUserDetailsByDeptId(String accessToken, Long deptId, Long cursor, Long size) {
|
||||
try {
|
||||
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/list");
|
||||
OapiV2UserListRequest req = new OapiV2UserListRequest();
|
||||
req.setDeptId(deptId);
|
||||
req.setCursor(cursor);
|
||||
req.setSize(size);
|
||||
req.setLanguage("zh_CN");
|
||||
OapiV2UserListResponse rsp = client.execute(req, accessToken);
|
||||
return rsp;
|
||||
} catch (ApiException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据模板名称获取审批模板code
|
||||
*
|
||||
* @param accessToken
|
||||
* @param TemplateName
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static GetProcessCodeByNameResponse getProcessCode(String accessToken, String TemplateName) throws Exception {
|
||||
try {
|
||||
com.aliyun.dingtalkworkflow_1_0.Client client = createClient();
|
||||
GetProcessCodeByNameHeaders getProcessCodeByNameHeaders = new GetProcessCodeByNameHeaders();
|
||||
getProcessCodeByNameHeaders.xAcsDingtalkAccessToken = accessToken;
|
||||
GetProcessCodeByNameRequest getProcessCodeByNameRequest = new GetProcessCodeByNameRequest()
|
||||
.setName(TemplateName);
|
||||
GetProcessCodeByNameResponse processCodeByNameWithOptions = client.getProcessCodeByNameWithOptions(getProcessCodeByNameRequest, getProcessCodeByNameHeaders, new RuntimeOptions());
|
||||
return processCodeByNameWithOptions;
|
||||
} catch (TeaException err) {
|
||||
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
||||
Assert.state(false, err.getMessage());
|
||||
}
|
||||
|
||||
} catch (Exception _err) {
|
||||
TeaException err = new TeaException(_err.getMessage(), _err);
|
||||
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
||||
Assert.state(false, err.getMessage());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据模板code获取表单的具体内容
|
||||
*
|
||||
* @param accessToken
|
||||
* @param processCode
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static QuerySchemaByProcessCodeResponse getBillSchema(String accessToken, String processCode) throws Exception {
|
||||
|
||||
com.aliyun.dingtalkworkflow_1_0.Client client = createClient();
|
||||
QuerySchemaByProcessCodeHeaders querySchemaByProcessCodeHeaders = new QuerySchemaByProcessCodeHeaders();
|
||||
querySchemaByProcessCodeHeaders.xAcsDingtalkAccessToken = accessToken;
|
||||
QuerySchemaByProcessCodeRequest querySchemaByProcessCodeRequest = new QuerySchemaByProcessCodeRequest()
|
||||
.setProcessCode(processCode);
|
||||
try {
|
||||
QuerySchemaByProcessCodeResponse res = client.querySchemaByProcessCodeWithOptions(querySchemaByProcessCodeRequest, querySchemaByProcessCodeHeaders, new RuntimeOptions());
|
||||
return res;
|
||||
} catch (TeaException err) {
|
||||
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
||||
Assert.state(false, err.getMessage());
|
||||
}
|
||||
} catch (Exception _err) {
|
||||
TeaException err = new TeaException(_err.getMessage(), _err);
|
||||
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
||||
Assert.state(false, err.getMessage());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务端APIOA审批官方OA审批审批实例发起审批实例
|
||||
* 发起审批实例
|
||||
*
|
||||
* @param accessToken accessToken
|
||||
* @param originatorUserId 审批发起人的userId
|
||||
* @param processCode 审批流的唯一码,模板编码
|
||||
* @param deptId 审批发起人所在的部门ID
|
||||
* @param microappAgentId 应用标识AgentId
|
||||
* @param approverList 不使用审批流模板时,直接指定的审批人列表,
|
||||
* @param formComponentValuesList 表单数据内容,控件列表,最大列表长度:150
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static StartProcessInstanceResponse InitiateApprovalInstance(String accessToken, String originatorUserId, String processCode, Long deptId, Long microappAgentId, List<StartProcessInstanceRequest.StartProcessInstanceRequestApprovers> approverList, List<StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues> formComponentValuesList) throws Exception {
|
||||
com.aliyun.dingtalkworkflow_1_0.Client client = createClient();
|
||||
|
||||
StartProcessInstanceHeaders startProcessInstanceHeaders = new StartProcessInstanceHeaders();
|
||||
startProcessInstanceHeaders.xAcsDingtalkAccessToken = accessToken;
|
||||
StartProcessInstanceRequest startProcessInstanceRequest = new StartProcessInstanceRequest()
|
||||
.setDeptId(deptId)
|
||||
.setApprovers(approverList)
|
||||
.setMicroappAgentId(microappAgentId)
|
||||
.setOriginatorUserId(originatorUserId)
|
||||
.setProcessCode(processCode)
|
||||
.setFormComponentValues(formComponentValuesList);
|
||||
try {
|
||||
StartProcessInstanceResponse startProcessInstanceResponse = client.startProcessInstanceWithOptions(startProcessInstanceRequest, startProcessInstanceHeaders, new RuntimeOptions());
|
||||
return startProcessInstanceResponse;
|
||||
} catch (TeaException err) {
|
||||
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
||||
// err 中含有 code 和 message 属性,可帮助开发定位问题
|
||||
Assert.state(false, err.getMessage());
|
||||
}
|
||||
|
||||
} catch (Exception _err) {
|
||||
TeaException err = new TeaException(_err.getMessage(), _err);
|
||||
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
||||
// err 中含有 code 和 message 属性,可帮助开发定位问题
|
||||
Assert.state(false, err.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据审批实例ID,获取该审批表单的详情内容
|
||||
*
|
||||
* @param accessToken
|
||||
* @param processInstanceId
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static GetProcessInstanceResponse getProcessInstanceDetails(String accessToken, String processInstanceId) throws Exception {
|
||||
com.aliyun.dingtalkworkflow_1_0.Client client = createClient();
|
||||
|
||||
GetProcessInstanceHeaders getProcessInstanceHeaders = new GetProcessInstanceHeaders();
|
||||
getProcessInstanceHeaders.xAcsDingtalkAccessToken = accessToken;
|
||||
GetProcessInstanceRequest getProcessInstanceRequest = new GetProcessInstanceRequest()
|
||||
.setProcessInstanceId(processInstanceId);
|
||||
try {
|
||||
GetProcessInstanceResponse processInstanceWithOptions = client.getProcessInstanceWithOptions(getProcessInstanceRequest, getProcessInstanceHeaders, new RuntimeOptions());
|
||||
return processInstanceWithOptions;
|
||||
} catch (TeaException err) {
|
||||
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
||||
Assert.state(false, err.getMessage());
|
||||
}
|
||||
} catch (Exception _err) {
|
||||
TeaException err = new TeaException(_err.getMessage(), _err);
|
||||
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
||||
Assert.state(false, err.getMessage());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据审批实例ID,撤销审批实例
|
||||
*
|
||||
* @param accessToken accessToken
|
||||
* @param processInstanceId 审批实例ID
|
||||
* @param isSystem 是否通过系统操作。 - **true**:由系统直接终止 - **false**:由指定的操作者终止(需要传发起人才能撤销),妈的,这里有bug,不是发起人也能删除
|
||||
* @param remark 终止说明。
|
||||
* @param operatingUserId 发起人ID。
|
||||
* @throws Exception
|
||||
*/
|
||||
public static TerminateProcessInstanceResponse revocationProcessInstance(String accessToken, String processInstanceId, boolean isSystem, String remark, String operatingUserId) throws Exception {
|
||||
|
||||
TerminateProcessInstanceResponse terminateProcessInstanceResponse = new TerminateProcessInstanceResponse();
|
||||
com.aliyun.dingtalkworkflow_1_0.Client client = createClient();
|
||||
|
||||
com.aliyun.dingtalkworkflow_1_0.models.TerminateProcessInstanceHeaders terminateProcessInstanceHeaders = new com.aliyun.dingtalkworkflow_1_0.models.TerminateProcessInstanceHeaders();
|
||||
terminateProcessInstanceHeaders.xAcsDingtalkAccessToken = accessToken;
|
||||
com.aliyun.dingtalkworkflow_1_0.models.TerminateProcessInstanceRequest terminateProcessInstanceRequest = new com.aliyun.dingtalkworkflow_1_0.models.TerminateProcessInstanceRequest()
|
||||
.setIsSystem(isSystem)
|
||||
.setProcessInstanceId(processInstanceId)
|
||||
.setRemark(remark)
|
||||
.setOperatingUserId(operatingUserId);
|
||||
|
||||
try {
|
||||
terminateProcessInstanceResponse = client.terminateProcessInstanceWithOptions(terminateProcessInstanceRequest, terminateProcessInstanceHeaders, new RuntimeOptions());
|
||||
} catch (TeaException err) {
|
||||
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
||||
Assert.state(false, err.getMessage());
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception _err) {
|
||||
TeaException err = new TeaException(_err.getMessage(), _err);
|
||||
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
||||
Assert.state(false, err.getMessage());
|
||||
|
||||
}
|
||||
}
|
||||
return terminateProcessInstanceResponse;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取审批钉盘空间信息
|
||||
*
|
||||
* @param accessToken 获取审批钉盘空间信息
|
||||
* @param userId 用户的userId。
|
||||
*/
|
||||
public static GetAttachmentSpaceResponse getProcessDingPanSpaceInfo(String accessToken, String userId) throws Exception {
|
||||
com.aliyun.dingtalkworkflow_1_0.Client client = createClient();
|
||||
|
||||
com.aliyun.dingtalkworkflow_1_0.models.GetAttachmentSpaceHeaders getAttachmentSpaceHeaders = new com.aliyun.dingtalkworkflow_1_0.models.GetAttachmentSpaceHeaders();
|
||||
getAttachmentSpaceHeaders.xAcsDingtalkAccessToken = accessToken;
|
||||
com.aliyun.dingtalkworkflow_1_0.models.GetAttachmentSpaceRequest getAttachmentSpaceRequest = new com.aliyun.dingtalkworkflow_1_0.models.GetAttachmentSpaceRequest()
|
||||
.setUserId(userId);
|
||||
GetAttachmentSpaceResponse getAttachmentSpaceResponse = new GetAttachmentSpaceResponse();
|
||||
|
||||
try {
|
||||
getAttachmentSpaceResponse = client.getAttachmentSpaceWithOptions(getAttachmentSpaceRequest, getAttachmentSpaceHeaders, new RuntimeOptions());
|
||||
} catch (TeaException err) {
|
||||
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
||||
Assert.state(false, err.getMessage());
|
||||
}
|
||||
|
||||
} catch (Exception _err) {
|
||||
TeaException err = new TeaException(_err.getMessage(), _err);
|
||||
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
||||
Assert.state(false, err.getMessage());
|
||||
}
|
||||
}
|
||||
return getAttachmentSpaceResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件上传信息
|
||||
*
|
||||
* @param accessToken token
|
||||
* @param spaceId 钉盘空间id
|
||||
* @param unionId 操作者ID
|
||||
* @param protocol HEADER_SIGNATURE
|
||||
* @param multipart 是否需要分片上传。 - **true**:需要 - **false**:不需要 >- 5G以下文件,设为false,简化上传步骤。 >- 5G以上文件,必须设为true,否则会上传失败。
|
||||
*/
|
||||
public static GetFileUploadInfoResponse getFileUploadInfo(String accessToken, String spaceId, String unionId, String protocol, Boolean multipart) throws Exception {
|
||||
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
|
||||
config.protocol = PROTOCOL;
|
||||
config.regionId = REGIONID;
|
||||
com.aliyun.dingtalkstorage_1_0.Client client = new com.aliyun.dingtalkstorage_1_0.Client(config);
|
||||
GetFileUploadInfoResponse getFileUploadInfoResponse = new GetFileUploadInfoResponse();
|
||||
com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoHeaders getFileUploadInfoHeaders = new com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoHeaders();
|
||||
getFileUploadInfoHeaders.xAcsDingtalkAccessToken = accessToken;
|
||||
com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoRequest getFileUploadInfoRequest = new com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoRequest()
|
||||
.setProtocol(protocol)
|
||||
.setMultipart(multipart)
|
||||
.setUnionId(unionId);
|
||||
try {
|
||||
getFileUploadInfoResponse = client.getFileUploadInfoWithOptions(spaceId, getFileUploadInfoRequest, getFileUploadInfoHeaders, new RuntimeOptions());
|
||||
} catch (TeaException err) {
|
||||
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
||||
Assert.state(false, err.getMessage());
|
||||
}
|
||||
|
||||
} catch (Exception _err) {
|
||||
TeaException err = new TeaException(_err.getMessage(), _err);
|
||||
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
||||
Assert.state(false, err.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
return getFileUploadInfoResponse;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交文件
|
||||
*
|
||||
* @param accessToken token
|
||||
* @param spaceId 空间ID
|
||||
* @param unionId 操作者unionId
|
||||
* @param uploadKey 添加文件唯一标识。获得文件上传信息是获得
|
||||
* @param fileName 文件名称
|
||||
* @param parentId 父目录Id。根目录时,该参数是0。,传FileManager中对应的id
|
||||
* @param commitFileRequestOptionAppProperties 当前文件的应用属性信息
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static CommitFileResponse submitFile(String accessToken, String spaceId, String unionId, String uploadKey, String fileName, String parentId, CommitFileRequest.CommitFileRequestOptionAppProperties commitFileRequestOptionAppProperties) throws Exception {
|
||||
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
|
||||
config.protocol = PROTOCOL;
|
||||
config.regionId = REGIONID;
|
||||
com.aliyun.dingtalkstorage_1_0.Client client = new com.aliyun.dingtalkstorage_1_0.Client(config);
|
||||
|
||||
CommitFileResponse commitFileResponse = new CommitFileResponse();
|
||||
|
||||
com.aliyun.dingtalkstorage_1_0.models.CommitFileHeaders commitFileHeaders = new com.aliyun.dingtalkstorage_1_0.models.CommitFileHeaders();
|
||||
commitFileHeaders.xAcsDingtalkAccessToken = accessToken;
|
||||
|
||||
com.aliyun.dingtalkstorage_1_0.models.CommitFileRequest.CommitFileRequestOption option = new com.aliyun.dingtalkstorage_1_0.models.CommitFileRequest.CommitFileRequestOption()
|
||||
.setAppProperties(java.util.Arrays.asList(
|
||||
commitFileRequestOptionAppProperties
|
||||
));
|
||||
com.aliyun.dingtalkstorage_1_0.models.CommitFileRequest commitFileRequest = new com.aliyun.dingtalkstorage_1_0.models.CommitFileRequest()
|
||||
.setName(fileName)
|
||||
.setUploadKey(uploadKey)
|
||||
.setParentId(parentId)
|
||||
.setOption(option)
|
||||
.setUnionId(unionId);
|
||||
try {
|
||||
commitFileResponse = client.commitFileWithOptions(spaceId, commitFileRequest, commitFileHeaders, new RuntimeOptions());
|
||||
} catch (TeaException err) {
|
||||
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
||||
Assert.state(false, err.getMessage());
|
||||
}
|
||||
|
||||
} catch (Exception _err) {
|
||||
TeaException err = new TeaException(_err.getMessage(), _err);
|
||||
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
||||
Assert.state(false, err.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
return commitFileResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户的unionId添加权限,上传钉盘时用户总掉权限,导致上传失败,所以需要根据用户的unionId添加权限
|
||||
* 仅限审批实例中有附件时。
|
||||
* @param accessToken 调用企业接口凭证
|
||||
* @param spaceId 空间Id
|
||||
* @param unionId 操作用户的unionId
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static AddPermissionResponse addFileStorageByUnionId(String accessToken, String spaceId, String unionId) throws Exception {
|
||||
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
|
||||
config.protocol = "https";
|
||||
config.regionId = "central";
|
||||
com.aliyun.dingtalkstorage_1_0.Client client = new com.aliyun.dingtalkstorage_1_0.Client(config);
|
||||
|
||||
AddPermissionResponse addPermissionResponse = new AddPermissionResponse();
|
||||
|
||||
com.aliyun.dingtalkstorage_1_0.models.AddPermissionHeaders addPermissionHeaders = new com.aliyun.dingtalkstorage_1_0.models.AddPermissionHeaders();
|
||||
addPermissionHeaders.xAcsDingtalkAccessToken = accessToken;
|
||||
com.aliyun.dingtalkstorage_1_0.models.AddPermissionRequest.AddPermissionRequestMembers members0 = new com.aliyun.dingtalkstorage_1_0.models.AddPermissionRequest.AddPermissionRequestMembers()
|
||||
.setType("USER")
|
||||
.setId(unionId);
|
||||
com.aliyun.dingtalkstorage_1_0.models.AddPermissionRequest addPermissionRequest = new com.aliyun.dingtalkstorage_1_0.models.AddPermissionRequest()
|
||||
.setUnionId(unionId)
|
||||
.setRoleId("MANAGER")
|
||||
.setMembers(java.util.Arrays.asList(
|
||||
members0
|
||||
));
|
||||
try {
|
||||
addPermissionResponse = client.addPermissionWithOptions(spaceId, "0", addPermissionRequest, addPermissionHeaders, new RuntimeOptions());
|
||||
} catch (TeaException err) {
|
||||
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
||||
Assert.state(false, err.getMessage());
|
||||
}
|
||||
|
||||
} catch (Exception _err) {
|
||||
TeaException err = new TeaException(_err.getMessage(), _err);
|
||||
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
||||
Assert.state(false, err.getMessage());
|
||||
}
|
||||
}
|
||||
return addPermissionResponse;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
package com.hzya.frame.plugin.lets.dingtalk.utils;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import com.aliyun.dingtalkstorage_1_0.models.AddPermissionResponse;
|
||||
import com.aliyun.dingtalkstorage_1_0.models.CommitFileRequest;
|
||||
import com.aliyun.dingtalkstorage_1_0.models.CommitFileResponse;
|
||||
import com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoResponse;
|
||||
import com.hzya.frame.plugin.lets.dingtalk.vo.FileModuleVO;
|
||||
import com.hzya.frame.plugin.lets.dingtalk.vo.SysFileVO;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class FileUtil {
|
||||
protected static Logger logger = LogManager.getLogger(FileUtil.class);
|
||||
|
||||
@Value("${DING.SPACEID}")
|
||||
private static String spaceId;
|
||||
|
||||
/**
|
||||
* 审批文件上传钉盘
|
||||
* @param accessToken 应用Token
|
||||
* @param unionid 钉钉用户unionid
|
||||
* @param dingFileUrlID 钉盘审批实例中附件地址
|
||||
* @param fileVO 的文件信息
|
||||
* @param stream 文件读取的字节流
|
||||
* @return
|
||||
*/
|
||||
public static FileModuleVO get4DingDileModuleVO(String accessToken, String unionid, String dingFileUrlID, SysFileVO fileVO, ByteArrayOutputStream stream){
|
||||
FileModuleVO fileModuleVO = new FileModuleVO();
|
||||
try {
|
||||
//钉钉--上传附件
|
||||
//1.调用服务端API-获取审批钉盘空间信息接口,获取审批空间spaceId。
|
||||
System.out.println(spaceId);
|
||||
//2.调用服务端API-获取文件上传信息接口,获取审批空间文件上传信息并执行上传。
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////此处很容易调权限,钉钉问题。添加权限
|
||||
AddPermissionResponse addPermissionResponse = DingTalkUtils.addFileStorageByUnionId(accessToken, spaceId, unionid);
|
||||
if(addPermissionResponse.getBody().getSuccess()!=true){
|
||||
Assert.state(false,"钉钉添加审批实例附件到钉盘权限失败");
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////此处很容易调权限,钉钉问题。添加权限
|
||||
//2.1调用本接口,获取上传文件需要的resourceUrls和headers参数值。
|
||||
GetFileUploadInfoResponse headerSignature = DingTalkUtils.getFileUploadInfo(accessToken, spaceId, unionid, "HEADER_SIGNATURE", false);
|
||||
String uploadKey = headerSignature.getBody().getUploadKey();
|
||||
List<String> resourceUrls = headerSignature.getBody().getHeaderSignatureInfo().getResourceUrls();
|
||||
if (resourceUrls.size() > 1) {
|
||||
Assert.state(false, "获取文件上传信息接口中resourceUrls不唯一!!!");
|
||||
}
|
||||
Map<String, String> headers = headerSignature.getBody().getHeaderSignatureInfo().getHeaders();
|
||||
//2.2使用OSS的header加签方式上传文件,参考示例:
|
||||
// 从接口返回信息中拿到headers
|
||||
URL url = new URL(resourceUrls.get(0));
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
if (headers != null) {
|
||||
for (Map.Entry<String, String> entry : headers.entrySet()) {
|
||||
connection.setRequestProperty(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
connection.setDoOutput(true);
|
||||
connection.setRequestMethod("PUT");
|
||||
connection.setUseCaches(false);
|
||||
connection.setReadTimeout(10000);
|
||||
connection.setConnectTimeout(10000);
|
||||
connection.connect();
|
||||
OutputStream out = connection.getOutputStream();
|
||||
out.write(stream.toByteArray());
|
||||
out.flush();
|
||||
out.close();
|
||||
int responseCode = connection.getResponseCode();
|
||||
connection.disconnect();
|
||||
if (responseCode == 200) {
|
||||
logger.info("审批实例附件上传审批钉盘成功,UploadKey:-->" + headerSignature.getBody().getUploadKey());
|
||||
} else {
|
||||
Assert.state(false,"审批实例附件上传审批钉盘失败");
|
||||
}
|
||||
//2.3调用提交文件接口,完成文件上传。
|
||||
CommitFileRequest.CommitFileRequestOptionAppProperties commitFileRequestOptionAppProperties = new CommitFileRequest.CommitFileRequestOptionAppProperties();
|
||||
commitFileRequestOptionAppProperties.setName(fileVO.getFileName());
|
||||
commitFileRequestOptionAppProperties.setValue(fileVO.getFileName());
|
||||
commitFileRequestOptionAppProperties.setVisibility("PUBLIC");//属性可见性。 - PUBLIC:所有应用都可见 - PRIVATE:仅限当前应用可见
|
||||
|
||||
//3.提交文件
|
||||
CommitFileResponse commitFileResponse = DingTalkUtils.submitFile(accessToken, spaceId, unionid, uploadKey, fileVO.getFileName(), dingFileUrlID, commitFileRequestOptionAppProperties);
|
||||
|
||||
//钉盘文件唯一id
|
||||
String dingFileUniqueId = commitFileResponse.getBody().getDentry().getId();
|
||||
|
||||
//4.组装钉钉文件控件-->"[{\"spaceId\": \"163xxxx658\", \"fileName\": \"2644.JPG\", \"fileSize\": \"333\", \"fileType\": \"jpg\", \"fileId\": \"643xxxx140\"}]"
|
||||
fileModuleVO.setSpaceId(spaceId);
|
||||
fileModuleVO.setFileName(fileVO.getFileName());
|
||||
fileModuleVO.setFileSize(String.valueOf(fileVO.getFileSize()));
|
||||
String s = StringUtils.substringAfter(fileVO.getFileName(), ".");
|
||||
fileModuleVO.setFileType(s);//取后缀
|
||||
fileModuleVO.setFileId(dingFileUniqueId);
|
||||
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
logger.error(e);
|
||||
Assert.state(false,"文件存钉盘失败,失败信息:{}",e.getMessage());
|
||||
}
|
||||
return fileModuleVO;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.hzya.frame.plugin.lets.dingtalk.utils;
|
||||
|
||||
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponseBody;
|
||||
import com.aliyun.dingtalkworkflow_1_0.models.GetAttachmentSpaceResponse;
|
||||
import com.dingtalk.api.response.OapiUserListidResponse;
|
||||
import com.dingtalk.api.response.OapiV2UserGetResponse;
|
||||
import com.dingtalk.api.response.OapiV2UserGetbymobileResponse;
|
||||
|
||||
public class Test {
|
||||
public static void main(String[] args) throws Exception {
|
||||
String appKey="ding5qfifcktfqfjlem0";
|
||||
String appSecret="BVuLOy_K0F8f5np69VuBeKdb1zfwqhuPsAV49lNbYVbx5TnfSTHjwEcad9Vwzfq1";
|
||||
|
||||
//获取token
|
||||
GetAccessTokenResponseBody tokenBody = DingTalkUtils.getTokenBody(appKey, appSecret);
|
||||
System.out.println(tokenBody.getAccessToken());
|
||||
|
||||
//获取用户列表
|
||||
// OapiUserListidResponse userIdList = DingTalkUtils.getUserIdList(tokenBody.getAccessToken());
|
||||
// System.out.println(userIdList);
|
||||
|
||||
//根据手机号查询用户详情,userid:6715600736721738
|
||||
// OapiV2UserGetbymobileResponse userByMobile = DingTalkUtils.getUserByMobile(tokenBody.getAccessToken(), "13783530043");
|
||||
// System.out.println(userByMobile.getBody());
|
||||
|
||||
//查询用户详情,unionId:xXpSQXdGCyYNcQXxrgezOwiEiE
|
||||
// OapiV2UserGetResponse userById = DingTalkUtils.getUserById(tokenBody.getAccessToken(), "6715600736721738");
|
||||
// System.out.println(userById.getBody());
|
||||
|
||||
//获取审批钉盘空间信息,spaceId:20852670637
|
||||
// GetAttachmentSpaceResponse processDingPanSpaceInfo = DingTalkUtils.getProcessDingPanSpaceInfo(tokenBody.getAccessToken(), "6715600736721738");
|
||||
// System.out.println(processDingPanSpaceInfo.getBody().getResult().getSpaceId());
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,395 @@
|
|||
package com.hzya.frame.plugin.lets.dingtalk.vo;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.Permission;
|
||||
import java.security.PermissionCollection;
|
||||
import java.security.Security;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
public class DingCallbackCrypto {
|
||||
|
||||
private static final Charset CHARSET = Charset.forName("utf-8");
|
||||
private static final Base64 base64 = new Base64();
|
||||
private byte[] aesKey;
|
||||
private String token;
|
||||
private String corpId;
|
||||
/**
|
||||
* ask getPaddingBytes key固定长度
|
||||
**/
|
||||
private static final Integer AES_ENCODE_KEY_LENGTH = 43;
|
||||
/**
|
||||
* 加密随机字符串字节长度
|
||||
**/
|
||||
private static final Integer RANDOM_LENGTH = 16;
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*
|
||||
* @param token 钉钉开放平台上,开发者设置的token
|
||||
* @param encodingAesKey 钉钉开放台上,开发者设置的EncodingAESKey
|
||||
* @param corpId 企业自建应用-事件订阅, 使用appKey
|
||||
* 企业自建应用-注册回调地址, 使用corpId
|
||||
* 第三方企业应用, 使用suiteKey
|
||||
* @throws DingTalkEncryptException 执行失败,请查看该异常的错误码和具体的错误信息
|
||||
*/
|
||||
public DingCallbackCrypto(String token, String encodingAesKey, String corpId) throws DingTalkEncryptException {
|
||||
if (null == encodingAesKey || encodingAesKey.length() != AES_ENCODE_KEY_LENGTH) {
|
||||
throw new DingTalkEncryptException(DingTalkEncryptException.AES_KEY_ILLEGAL);
|
||||
}
|
||||
this.token = token;
|
||||
this.corpId = corpId;
|
||||
aesKey = Base64.decodeBase64(encodingAesKey + "=");
|
||||
}
|
||||
|
||||
public Map<String, String> getEncryptedMap(String plaintext) throws DingTalkEncryptException {
|
||||
return getEncryptedMap(plaintext, System.currentTimeMillis(), Utils.getRandomStr(16));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将和钉钉开放平台同步的消息体加密,返回加密Map
|
||||
*
|
||||
* @param plaintext 传递的消息体明文
|
||||
* @param timeStamp 时间戳
|
||||
* @param nonce 随机字符串
|
||||
* @return
|
||||
* @throws DingTalkEncryptException
|
||||
*/
|
||||
public Map<String, String> getEncryptedMap(String plaintext, Long timeStamp, String nonce)
|
||||
throws DingTalkEncryptException {
|
||||
if (null == plaintext) {
|
||||
throw new DingTalkEncryptException(DingTalkEncryptException.ENCRYPTION_PLAINTEXT_ILLEGAL);
|
||||
}
|
||||
if (null == timeStamp) {
|
||||
throw new DingTalkEncryptException(DingTalkEncryptException.ENCRYPTION_TIMESTAMP_ILLEGAL);
|
||||
}
|
||||
if (null == nonce) {
|
||||
throw new DingTalkEncryptException(DingTalkEncryptException.ENCRYPTION_NONCE_ILLEGAL);
|
||||
}
|
||||
// 加密
|
||||
String encrypt = encrypt(Utils.getRandomStr(RANDOM_LENGTH), plaintext);
|
||||
String signature = getSignature(token, String.valueOf(timeStamp), nonce, encrypt);
|
||||
Map<String, String> resultMap = new HashMap<String, String>();
|
||||
resultMap.put("msg_signature", signature);
|
||||
resultMap.put("encrypt", encrypt);
|
||||
resultMap.put("timeStamp", String.valueOf(timeStamp));
|
||||
resultMap.put("nonce", nonce);
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 密文解密
|
||||
*
|
||||
* @param msgSignature 签名串
|
||||
* @param timeStamp 时间戳
|
||||
* @param nonce 随机串
|
||||
* @param encryptMsg 密文
|
||||
* @return 解密后的原文
|
||||
* @throws DingTalkEncryptException
|
||||
*/
|
||||
public String getDecryptMsg(String msgSignature, String timeStamp, String nonce, String encryptMsg)
|
||||
throws DingTalkEncryptException {
|
||||
//校验签名
|
||||
String signature = getSignature(token, timeStamp, nonce, encryptMsg);
|
||||
if (!signature.equals(msgSignature)) {
|
||||
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_SIGNATURE_ERROR);
|
||||
}
|
||||
// 解密
|
||||
String result = decrypt(encryptMsg);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* 对明文加密.
|
||||
* @param text 需要加密的明文
|
||||
* @return 加密后base64编码的字符串
|
||||
*/
|
||||
private String encrypt(String random, String plaintext) throws DingTalkEncryptException {
|
||||
try {
|
||||
byte[] randomBytes = random.getBytes(CHARSET);
|
||||
byte[] plainTextBytes = plaintext.getBytes(CHARSET);
|
||||
byte[] lengthByte = Utils.int2Bytes(plainTextBytes.length);
|
||||
byte[] corpidBytes = corpId.getBytes(CHARSET);
|
||||
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
|
||||
byteStream.write(randomBytes);
|
||||
byteStream.write(lengthByte);
|
||||
byteStream.write(plainTextBytes);
|
||||
byteStream.write(corpidBytes);
|
||||
byte[] padBytes = PKCS7Padding.getPaddingBytes(byteStream.size());
|
||||
byteStream.write(padBytes);
|
||||
byte[] unencrypted = byteStream.toByteArray();
|
||||
byteStream.close();
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
|
||||
SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
|
||||
IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
|
||||
byte[] encrypted = cipher.doFinal(unencrypted);
|
||||
String result = base64.encodeToString(encrypted);
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_ENCRYPT_TEXT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 对密文进行解密.
|
||||
* @param text 需要解密的密文
|
||||
* @return 解密得到的明文
|
||||
*/
|
||||
private String decrypt(String text) throws DingTalkEncryptException {
|
||||
byte[] originalArr;
|
||||
try {
|
||||
// 设置解密模式为AES的CBC模式
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
|
||||
SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
|
||||
IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
|
||||
cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
|
||||
// 使用BASE64对密文进行解码
|
||||
byte[] encrypted = Base64.decodeBase64(text);
|
||||
// 解密
|
||||
originalArr = cipher.doFinal(encrypted);
|
||||
} catch (Exception e) {
|
||||
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_ERROR);
|
||||
}
|
||||
|
||||
String plainText;
|
||||
String fromCorpid;
|
||||
try {
|
||||
// 去除补位字符
|
||||
byte[] bytes = PKCS7Padding.removePaddingBytes(originalArr);
|
||||
// 分离16位随机字符串,网络字节序和corpId
|
||||
byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
|
||||
int plainTextLegth = Utils.bytes2int(networkOrder);
|
||||
plainText = new String(Arrays.copyOfRange(bytes, 20, 20 + plainTextLegth), CHARSET);
|
||||
fromCorpid = new String(Arrays.copyOfRange(bytes, 20 + plainTextLegth, bytes.length), CHARSET);
|
||||
} catch (Exception e) {
|
||||
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_LENGTH_ERROR);
|
||||
}
|
||||
|
||||
// corpid不相同的情况
|
||||
if (!fromCorpid.equals(corpId)) {
|
||||
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_CORPID_ERROR);
|
||||
}
|
||||
return plainText;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数字签名
|
||||
*
|
||||
* @param token isv token
|
||||
* @param timestamp 时间戳
|
||||
* @param nonce 随机串
|
||||
* @param encrypt 加密文本
|
||||
* @return
|
||||
* @throws DingTalkEncryptException
|
||||
*/
|
||||
public String getSignature(String token, String timestamp, String nonce, String encrypt)
|
||||
throws DingTalkEncryptException {
|
||||
try {
|
||||
String[] array = new String[]{token, timestamp, nonce, encrypt};
|
||||
Arrays.sort(array);
|
||||
System.out.println(JSON.toJSONString(array));
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
sb.append(array[i]);
|
||||
}
|
||||
String str = sb.toString();
|
||||
System.out.println(str);
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-1");
|
||||
md.update(str.getBytes());
|
||||
byte[] digest = md.digest();
|
||||
|
||||
StringBuffer hexstr = new StringBuffer();
|
||||
String shaHex = "";
|
||||
for (int i = 0; i < digest.length; i++) {
|
||||
shaHex = Integer.toHexString(digest[i] & 0xFF);
|
||||
if (shaHex.length() < 2) {
|
||||
hexstr.append(0);
|
||||
}
|
||||
hexstr.append(shaHex);
|
||||
}
|
||||
return hexstr.toString();
|
||||
} catch (Exception e) {
|
||||
throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_SIGNATURE_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Utils {
|
||||
public Utils() {
|
||||
}
|
||||
|
||||
public static String getRandomStr(int count) {
|
||||
String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
Random random = new Random();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
int number = random.nextInt(base.length());
|
||||
sb.append(base.charAt(number));
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static byte[] int2Bytes(int count) {
|
||||
byte[] byteArr = new byte[]{(byte) (count >> 24 & 255), (byte) (count >> 16 & 255), (byte) (count >> 8 & 255),
|
||||
(byte) (count & 255)};
|
||||
return byteArr;
|
||||
}
|
||||
|
||||
public static int bytes2int(byte[] byteArr) {
|
||||
int count = 0;
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
count <<= 8;
|
||||
count |= byteArr[i] & 255;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PKCS7Padding {
|
||||
private static final Charset CHARSET = Charset.forName("utf-8");
|
||||
private static final int BLOCK_SIZE = 32;
|
||||
|
||||
public PKCS7Padding() {
|
||||
}
|
||||
|
||||
public static byte[] getPaddingBytes(int count) {
|
||||
int amountToPad = 32 - count % 32;
|
||||
if (amountToPad == 0) {
|
||||
amountToPad = 32;
|
||||
}
|
||||
|
||||
char padChr = chr(amountToPad);
|
||||
String tmp = new String();
|
||||
|
||||
for (int index = 0; index < amountToPad; ++index) {
|
||||
tmp = tmp + padChr;
|
||||
}
|
||||
|
||||
return tmp.getBytes(CHARSET);
|
||||
}
|
||||
|
||||
public static byte[] removePaddingBytes(byte[] decrypted) {
|
||||
int pad = decrypted[decrypted.length - 1];
|
||||
if (pad < 1 || pad > 32) {
|
||||
pad = 0;
|
||||
}
|
||||
|
||||
return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
|
||||
}
|
||||
|
||||
private static char chr(int a) {
|
||||
byte target = (byte) (a & 255);
|
||||
return (char) target;
|
||||
}
|
||||
}
|
||||
|
||||
public static class DingTalkEncryptException extends Exception {
|
||||
public static final int SUCCESS = 0;
|
||||
public static final int ENCRYPTION_PLAINTEXT_ILLEGAL = 900001;
|
||||
public static final int ENCRYPTION_TIMESTAMP_ILLEGAL = 900002;
|
||||
public static final int ENCRYPTION_NONCE_ILLEGAL = 900003;
|
||||
public static final int AES_KEY_ILLEGAL = 900004;
|
||||
public static final int SIGNATURE_NOT_MATCH = 900005;
|
||||
public static final int COMPUTE_SIGNATURE_ERROR = 900006;
|
||||
public static final int COMPUTE_ENCRYPT_TEXT_ERROR = 900007;
|
||||
public static final int COMPUTE_DECRYPT_TEXT_ERROR = 900008;
|
||||
public static final int COMPUTE_DECRYPT_TEXT_LENGTH_ERROR = 900009;
|
||||
public static final int COMPUTE_DECRYPT_TEXT_CORPID_ERROR = 900010;
|
||||
private static Map<Integer, String> msgMap = new HashMap();
|
||||
private Integer code;
|
||||
|
||||
static {
|
||||
msgMap.put(0, "成功");
|
||||
msgMap.put(900001, "加密明文文本非法");
|
||||
msgMap.put(900002, "加密时间戳参数非法");
|
||||
msgMap.put(900003, "加密随机字符串参数非法");
|
||||
msgMap.put(900005, "签名不匹配");
|
||||
msgMap.put(900006, "签名计算失败");
|
||||
msgMap.put(900004, "不合法的aes key");
|
||||
msgMap.put(900007, "计算加密文字错误");
|
||||
msgMap.put(900008, "计算解密文字错误");
|
||||
msgMap.put(900009, "计算解密文字长度不匹配");
|
||||
msgMap.put(900010, "计算解密文字corpid不匹配");
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
public DingTalkEncryptException(Integer exceptionCode) {
|
||||
super((String) msgMap.get(exceptionCode));
|
||||
this.code = exceptionCode;
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
try {
|
||||
Security.setProperty("crypto.policy", "limited");
|
||||
RemoveCryptographyRestrictions();
|
||||
} catch (Exception var1) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void RemoveCryptographyRestrictions() throws Exception {
|
||||
Class<?> jceSecurity = getClazz("javax.crypto.JceSecurity");
|
||||
Class<?> cryptoPermissions = getClazz("javax.crypto.CryptoPermissions");
|
||||
Class<?> cryptoAllPermission = getClazz("javax.crypto.CryptoAllPermission");
|
||||
if (jceSecurity != null) {
|
||||
setFinalStaticValue(jceSecurity, "isRestricted", false);
|
||||
PermissionCollection defaultPolicy = (PermissionCollection) getFieldValue(jceSecurity, "defaultPolicy", (Object) null, PermissionCollection.class);
|
||||
if (cryptoPermissions != null) {
|
||||
Map<?, ?> map = (Map) getFieldValue(cryptoPermissions, "perms", defaultPolicy, Map.class);
|
||||
map.clear();
|
||||
}
|
||||
|
||||
if (cryptoAllPermission != null) {
|
||||
Permission permission = (Permission) getFieldValue(cryptoAllPermission, "INSTANCE", (Object) null, Permission.class);
|
||||
defaultPolicy.add(permission);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Class<?> getClazz(String className) {
|
||||
Class clazz = null;
|
||||
|
||||
try {
|
||||
clazz = Class.forName(className);
|
||||
} catch (Exception var3) {
|
||||
}
|
||||
|
||||
return clazz;
|
||||
}
|
||||
|
||||
private static void setFinalStaticValue(Class<?> srcClazz, String fieldName, Object newValue) throws Exception {
|
||||
Field field = srcClazz.getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||
modifiersField.setAccessible(true);
|
||||
modifiersField.setInt(field, field.getModifiers() & -17);
|
||||
field.set((Object) null, newValue);
|
||||
}
|
||||
|
||||
private static <T> T getFieldValue(Class<?> srcClazz, String fieldName, Object owner, Class<T> dstClazz) throws Exception {
|
||||
Field field = srcClazz.getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
return dstClazz.cast(field.get(owner));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,253 @@
|
|||
package com.hzya.frame.plugin.lets.dingtalk.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* arap_djzb 单据主表
|
||||
* arap_djfb 单据辅表
|
||||
*/
|
||||
@Data
|
||||
public class DjzbVO {
|
||||
private Arap_djzb parentvo;
|
||||
private List<Arap_djfb> children;
|
||||
|
||||
@Data
|
||||
public static class Arap_djzb {
|
||||
private String bbje;//本币金额合计
|
||||
private String bzbm;//币种主键
|
||||
private String bzbm_code;//币种编码
|
||||
private String bzbm_name;//币种名称
|
||||
private String def1;//自定义项名称1
|
||||
private String def10;//自定义项名称10
|
||||
private String def11;//自定义项名称11
|
||||
private String def12;//自定义项名称12
|
||||
private String def13;//自定义项名称13
|
||||
private String def14;//自定义项名称14
|
||||
private String def15;//自定义项名称15
|
||||
private String def16;//自定义项名称16
|
||||
private String def17;//自定义项名称17
|
||||
private String def18;//自定义项名称18
|
||||
private String def19;//自定义项名称19
|
||||
private String def2;//自定义项名称2
|
||||
private String def20;//自定义项名称20
|
||||
private String def21;//自定义项名称21
|
||||
private String def22;//自定义项名称22
|
||||
private String def23;//自定义项名称23
|
||||
private String def24;//自定义项名称24
|
||||
private String def25;//自定义项名称25
|
||||
private String def26;//自定义项名称26
|
||||
private String def27;//自定义项名称27
|
||||
private String def28;//自定义项名称28
|
||||
private String def29;//自定义项名称29
|
||||
private String def3;//自定义项名称3
|
||||
private String def30;//自定义项名称30
|
||||
private String def4;//自定义项名称4
|
||||
private String def5;//自定义项名称5
|
||||
private String def6;//自定义项名称6
|
||||
private String def7;//自定义项名称7
|
||||
private String def8;//自定义项名称8
|
||||
private String def9;//自定义项名称9
|
||||
private String deptid;//部门主键
|
||||
private String deptid_code;//部门编码
|
||||
private String deptid_name;//部门名称
|
||||
private String dfyhzh;//付款银行帐号
|
||||
private String djbh;//单据编号
|
||||
private String djdl;//单据大类
|
||||
private String djkjnd;//会计年度
|
||||
private String djkjqj;//会计期间
|
||||
private String djrq;//单据日期
|
||||
private String djzt;//单据状态
|
||||
private String dwbm;//公司主键
|
||||
private String dwbm_code;//公司编码
|
||||
private String dwbm_name;//公司名称
|
||||
private String dzrq;//对帐日期
|
||||
private String enduser;//最终修改人(5.1开始支持)
|
||||
private String hbbm;//客商主键
|
||||
private String hbbm_code;//客商编码
|
||||
private String hbbm_name;//客商名称
|
||||
private String lrr;//录入人主键
|
||||
private String lrr_code;//录入人编码
|
||||
private String lrr_name;//录入人名称
|
||||
private String paydate;//支付日期(5.1及以后版本支持)
|
||||
private String prepay;//预收付标志
|
||||
private String qcbz;//是期初
|
||||
private String qrr;//确认人主键
|
||||
private String qrr_code;//确认人编码
|
||||
private String qrr_name;//确认人名称
|
||||
private String scomment;//备注
|
||||
private String shr;//审核人主键
|
||||
private String shr_code;//审核人编码
|
||||
private String shr_name;//审核人名称
|
||||
private String shrq;//审核日期
|
||||
private String spzt;//审批状态
|
||||
private String szxmid;//收支项目主键
|
||||
private String szxmid_code;//收支项目编码
|
||||
private String szxmid_name;//收支项目名称
|
||||
private String ts;//时间戳(V5.1开始支持)
|
||||
private String vouchid;//主表主键
|
||||
private String wldx;//往来对象标识
|
||||
private String xslxbm;//业务流程主键
|
||||
private String xslxbm_code;//业务流程编码
|
||||
private String xslxbm_name;//业务流程名称
|
||||
private String ybje;//原币金额合计
|
||||
private String ywbm;//交易类型主键
|
||||
private String ywbm_code;//交易类型编码
|
||||
private String ywbm_name;//交易类型名称
|
||||
private String ywybm;//业务员主键
|
||||
private String ywybm_code;//业务员编码
|
||||
private String ywybm_name;//业务员名称
|
||||
private String zdr;//制单人主键
|
||||
private String zdr_code;//制单人编码
|
||||
private String zdr_name;//制单人名称
|
||||
private String zdrq;//制单日期
|
||||
private String zyx1;//自定义项1
|
||||
private String zyx10;//自定义项10
|
||||
private String zyx11;//自定义项11
|
||||
private String zyx12;//自定义项12
|
||||
private String zyx13;//自定义项13
|
||||
private String zyx14;//自定义项14
|
||||
private String zyx15;//自定义项15
|
||||
private String zyx16;//自定义项16
|
||||
private String zyx17;//自定义项17
|
||||
private String zyx18;//自定义项18
|
||||
private String zyx19;//自定义项19
|
||||
private String zyx2;//自定义项2
|
||||
private String zyx20;//自定义项20
|
||||
private String zyx21;//自定义项21
|
||||
private String zyx22;//自定义项22
|
||||
private String zyx23;//自定义项23
|
||||
private String zyx24;//自定义项24
|
||||
private String zyx25;//自定义项25
|
||||
private String zyx26;//自定义项26
|
||||
private String zyx27;//自定义项27
|
||||
private String zyx28;//自定义项28
|
||||
private String zyx29;//自定义项29
|
||||
private String zyx3;//自定义项3
|
||||
private String zyx30;//自定义项30
|
||||
private String zyx4;//自定义项4
|
||||
private String zyx5;//自定义项5
|
||||
private String zyx6;//自定义项6
|
||||
private String zyx7;//自定义项7
|
||||
private String zyx8;//自定义项8
|
||||
private String zyx9;//自定义项9
|
||||
private String zzzt;//支付状态
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class Arap_djfb {
|
||||
private String bbhl;//本币汇率
|
||||
private String bfyhzh;//本方银行帐号主键
|
||||
private String bzbm;//币种主键
|
||||
private String bzbm_code;//币种编码
|
||||
private String bzbm_name;//币种名称
|
||||
private String cinventoryid;//存货主键
|
||||
private String cinventoryid_code;//存货编码
|
||||
private String cinventoryid_name;//存货名称
|
||||
private String contractno;//采购合同号 5.1开始支持
|
||||
private String ddh;//订单号 5.0sp开始支持
|
||||
private String def1;//自定义项名称1
|
||||
private String def10;//自定义项名称10
|
||||
private String def11;//自定义项名称11
|
||||
private String def12;//自定义项名称12
|
||||
private String def13;//自定义项名称13
|
||||
private String def14;//自定义项名称14
|
||||
private String def15;//自定义项名称15
|
||||
private String def16;//自定义项名称16
|
||||
private String def17;//自定义项名称17
|
||||
private String def18;//自定义项名称18
|
||||
private String def19;//自定义项名称19
|
||||
private String def2;//自定义项名称2
|
||||
private String def20;//自定义项名称20
|
||||
private String def21;//自定义项名称21
|
||||
private String def22;//自定义项名称22
|
||||
private String def23;//自定义项名称23
|
||||
private String def24;//自定义项名称24
|
||||
private String def25;//自定义项名称25
|
||||
private String def26;//自定义项名称26
|
||||
private String def27;//自定义项名称27
|
||||
private String def28;//自定义项名称28
|
||||
private String def29;//自定义项名称29
|
||||
private String def3;//自定义项名称3
|
||||
private String def30;//自定义项名称30
|
||||
private String def4;//自定义项名称4
|
||||
private String def5;//自定义项名称5
|
||||
private String def6;//自定义项名称6
|
||||
private String def7;//自定义项名称7
|
||||
private String def8;//自定义项名称8
|
||||
private String def9;//自定义项名称9
|
||||
private String deptid;//部门主键
|
||||
private String deptid_code;//部门编码
|
||||
private String deptid_name;//部门名称
|
||||
private String dfbbje;//贷方本币金额
|
||||
private String dfbbsj;//贷方本币税金
|
||||
private String dfbbwsje;//贷方本币无税金额
|
||||
private String dfybje;//贷方原币金额
|
||||
private String dfybsj;//贷方原币税金
|
||||
private String dfybwsje;//贷方原币无税金额
|
||||
private String dfyhzh;//对方银行帐号主键
|
||||
private String dj;//单价
|
||||
private String djlxbm;//单据类型编码
|
||||
private String fb_oid;//子表主键
|
||||
private String fkyhmc;//付款银行帐号名称
|
||||
private String fkyhzh;//付款银行帐号编码
|
||||
private String fph;//发票号 5.0sp开始支持
|
||||
private String hbbm;//客商主键
|
||||
private String hbbm_code;//客商编码
|
||||
private String hbbm_name;//客商名称
|
||||
private String hsdj;//含税单价
|
||||
private String jfbbje;//借方本币金额
|
||||
private String jfbbsj;//借方本币税金
|
||||
private String jfshl;//借方数量
|
||||
private String jfybje;//借方原币金额
|
||||
private String jfybsj;//借方原币税金
|
||||
private String jfybwsje;//借方原币无税金额
|
||||
private String jobid;//专项基本档案id(项目)
|
||||
private String kslb;//扣税类别
|
||||
private String skyhmc;//收款银行帐号名称
|
||||
private String skyhzh;//收款银行帐号编码
|
||||
private String sl;//税率
|
||||
private String szxmid;//收支项目主键
|
||||
private String szxmid_code;//收支项目编码
|
||||
private String szxmid_name;//收支项目名称
|
||||
private String ts;//时间戳(V5.1开始支持)
|
||||
private String vouchid;//主表主键
|
||||
private String wbfbbje;//借方本币无税金额
|
||||
private String wldx;//往来对象标识 0:客户;1:供应商;2:部门;3:业务员
|
||||
private String ywybm;//业务员主键
|
||||
private String ywybm_code;//业务员编码
|
||||
private String ywybm_name;//业务员名称
|
||||
private String zy;//摘要
|
||||
private String zyx1;//自定义项1
|
||||
private String zyx10;//自定义项10
|
||||
private String zyx11;//自定义项11
|
||||
private String zyx12;//自定义项12
|
||||
private String zyx13;//自定义项13
|
||||
private String zyx14;//自定义项14
|
||||
private String zyx15;//自定义项15
|
||||
private String zyx16;//自定义项16
|
||||
private String zyx17;//自定义项17
|
||||
private String zyx18;//自定义项18
|
||||
private String zyx19;//自定义项19
|
||||
private String zyx2;//自定义项2
|
||||
private String zyx20;//自定义项20
|
||||
private String zyx21;//自定义项21
|
||||
private String zyx22;//自定义项22
|
||||
private String zyx23;//自定义项23
|
||||
private String zyx24;//自定义项24
|
||||
private String zyx25;//自定义项25
|
||||
private String zyx26;//自定义项26
|
||||
private String zyx27;//自定义项27
|
||||
private String zyx28;//自定义项28
|
||||
private String zyx29;//自定义项29
|
||||
private String zyx3;//自定义项3
|
||||
private String zyx30;//自定义项30
|
||||
private String zyx4;//自定义项4
|
||||
private String zyx5;//自定义项5
|
||||
private String zyx6;//自定义项6
|
||||
private String zyx7;//自定义项7
|
||||
private String zyx8;//自定义项8
|
||||
private String zyx9;//自定义项9
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.hzya.frame.plugin.lets.dingtalk.vo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class FileModuleVO {
|
||||
private String spaceId;
|
||||
private String fileName;
|
||||
private String fileSize;
|
||||
private String fileType;
|
||||
private String fileId;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.hzya.frame.plugin.lets.dingtalk.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class SysFileVO {
|
||||
/** 文件名称 */
|
||||
private String fileName;
|
||||
/** 文件类型 */
|
||||
private String type;
|
||||
/** 文件大小(kb) */
|
||||
private Long fileSize;
|
||||
/** base64编码 */
|
||||
private String baseCode;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.hzya.frame.plugin.lets.plugin.dingtalk;
|
||||
|
||||
/**
|
||||
* 为避免回调超时,每天定时检查所有未审批完成的审批实例。
|
||||
*/
|
||||
public class DingCallBackPluginInitializer {
|
||||
}
|
|
@ -49,4 +49,26 @@ OA:
|
|||
letsofs:
|
||||
url: http://39.98.168.188:30002/api/edi/u8c/ofs/in
|
||||
appKey: 2097046829
|
||||
secret: 35282f251476a3af4f00c7b36
|
||||
secret: 35282f251476a3af4f00c7b36
|
||||
|
||||
#钉钉
|
||||
DING:
|
||||
CorpId: dingc5b16c82b7f25e64acaaa37764f94726
|
||||
APIToken: c5530fb4faed387593ee17f4e6bb748d
|
||||
#钉钉回调
|
||||
call_back_token: q9llHUSJnD3br9iOSHcJh2I5qa4l3lau29vfv3Kwud9ExEKC1dWLQP2RQT9
|
||||
call_back_aes_key: tMcQS7SdmvyeuFB6iKaxYG46WmbTfU2CjBDr3IRCqci
|
||||
#Client ID (原 AppKey 和 SuiteKey)
|
||||
APPKEY: ding5qfifcktfqfjlem0
|
||||
#Client Secret (原 AppSecret 和 SuiteSecret)
|
||||
AppSecret: BVuLOy_K0F8f5np69VuBeKdb1zfwqhuPsAV49lNbYVbx5TnfSTHjwEcad9Vwzfq1
|
||||
#钉盘审批空间
|
||||
SPACEID: 20852670637
|
||||
#审批表单空间
|
||||
APPROVE:
|
||||
#特殊业务处理(新)
|
||||
SPECIAL_SERVICE_PROCESSING_FILE_ID: 1
|
||||
#采购付款申请(新)
|
||||
PURCHASE_PAYMENT_REQUEST_NEW_FILE_ID: 1
|
||||
#采购付款申请(店群专用)
|
||||
PURCHASE_PAYMENT_REQUEST_SHOP_FILE_ID: 1
|
|
@ -41,4 +41,26 @@ OA:
|
|||
letsofs:
|
||||
url: http://39.98.168.188:30002/api/edi/u8c/ofs/in
|
||||
appKey: 2097046829
|
||||
secret: 35282f251476a3af4f00c7b36
|
||||
secret: 35282f251476a3af4f00c7b36
|
||||
|
||||
#钉钉
|
||||
DING:
|
||||
CorpId: dingc5b16c82b7f25e64acaaa37764f94726
|
||||
APIToken: c5530fb4faed387593ee17f4e6bb748d
|
||||
#钉钉回调
|
||||
call_back_token: q9llHUSJnD3br9iOSHcJh2I5qa4l3lau29vfv3Kwud9ExEKC1dWLQP2RQT9
|
||||
call_back_aes_key: tMcQS7SdmvyeuFB6iKaxYG46WmbTfU2CjBDr3IRCqci
|
||||
#Client ID (原 AppKey 和 SuiteKey)
|
||||
APPKEY: ding5qfifcktfqfjlem0
|
||||
#Client Secret (原 AppSecret 和 SuiteSecret)
|
||||
AppSecret: BVuLOy_K0F8f5np69VuBeKdb1zfwqhuPsAV49lNbYVbx5TnfSTHjwEcad9Vwzfq1
|
||||
#钉盘审批空间
|
||||
SPACEID: 20852670637
|
||||
#审批表单空间
|
||||
APPROVE:
|
||||
#特殊业务处理(新)
|
||||
SPECIAL_SERVICE_PROCESSING_FILE_ID: 1
|
||||
#采购付款申请(新)
|
||||
PURCHASE_PAYMENT_REQUEST_NEW_FILE_ID: 1
|
||||
#采购付款申请(店群专用)
|
||||
PURCHASE_PAYMENT_REQUEST_SHOP_FILE_ID: 1
|
|
@ -30,7 +30,7 @@ public class BaseTest {
|
|||
@Test
|
||||
public void t01(){
|
||||
// skuPluginInitializer.start("test0717001");
|
||||
skuPluginInitializer.start("gdkfc778");
|
||||
skuPluginInitializer.start("3664454000268");
|
||||
// skuPluginInitializer.start("6971229882248");
|
||||
}
|
||||
@Test
|
||||
|
|
|
@ -95,7 +95,7 @@ public class TransferTest {
|
|||
}
|
||||
@Test
|
||||
public void t41(){
|
||||
adjustOutPluginInitializer.start("LETS-SH2024092000000004");
|
||||
adjustOutPluginInitializer.start("LETS-SH2024101800017063");
|
||||
}
|
||||
@Test
|
||||
public void t42(){
|
||||
|
@ -138,7 +138,8 @@ public class TransferTest {
|
|||
|
||||
@Test
|
||||
public void t81(){
|
||||
refundOnlyPluginInitializer.start("2023-08-20","2023-08-25");
|
||||
// refundOnlyPluginInitializer.start("2023-08-20","2023-08-25");
|
||||
refundOnlyPluginInitializer.start("2024-09-30","2024-09-30");
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////仅退款
|
||||
|
||||
|
|
Loading…
Reference in New Issue