|
|
@@ -0,0 +1,718 @@
|
|
|
+package com.malk.guangdian.service.Impl;
|
|
|
+
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.malk.guangdian.entity.Content.ContentFile;
|
|
|
+import com.malk.guangdian.entity.Content.ZhiYuanDTO;
|
|
|
+import com.malk.guangdian.service.PayService;
|
|
|
+import com.malk.server.dingtalk.DDConf;
|
|
|
+import com.malk.server.dingtalk.DDR_New;
|
|
|
+import com.malk.service.aliwork.YDClient;
|
|
|
+import com.malk.service.dingtalk.DDClient;
|
|
|
+import com.malk.service.dingtalk.DDClient_Personnel;
|
|
|
+import com.malk.service.dingtalk.DDClient_Workflow;
|
|
|
+import com.malk.service.dingtalk.DDService;
|
|
|
+import com.malk.utils.UtilFile;
|
|
|
+import com.malk.utils.UtilHttp;
|
|
|
+import com.malk.utils.UtilMap;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.io.*;
|
|
|
+import java.lang.reflect.Field;
|
|
|
+import java.net.HttpURLConnection;
|
|
|
+import java.net.URL;
|
|
|
+import java.net.URLDecoder;
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.ConcurrentHashMap;
|
|
|
+
|
|
|
+@Service
|
|
|
+@Slf4j
|
|
|
+public class PayServiceImpl implements PayService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private DDClient ddClient;
|
|
|
+ @Autowired
|
|
|
+ private DDClient_Workflow ddClient_workflow;
|
|
|
+ @Autowired
|
|
|
+ private DDClient_Personnel ddClientPersonnel;
|
|
|
+ @Value(value = "${dingtalk.appKey}")
|
|
|
+ private String APP_EKY;
|
|
|
+ @Value(value = "${dingtalk.appSecret}")
|
|
|
+ private String APP_SECRET;
|
|
|
+ @Value(value = "${dingtalk.agentId}")
|
|
|
+ private Long agentId;
|
|
|
+ @Value(value = "${dingtalk.unionId}")
|
|
|
+ private String unionId;
|
|
|
+ @Value(value = "${dingtalk.spaceId}")
|
|
|
+ private String spaceId;
|
|
|
+ @Value(value = "${dingtalk.parentId}")
|
|
|
+ private String parentId;
|
|
|
+ @Value(value = "${saveFile.path}")
|
|
|
+ private String saveFilePath;
|
|
|
+ @Value(value = "${dingtalk.parentUuid}")
|
|
|
+ private String parentDentryUuid;
|
|
|
+ @Autowired
|
|
|
+ private DDConf ddConf;
|
|
|
+ @Autowired
|
|
|
+ DDService ddService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private YDClient ydClient;
|
|
|
+
|
|
|
+ private static final String API_TOKEN = "/common/unAuth/tokens/generate";
|
|
|
+ private static final String POST_DATA_URL = "/common/document";
|
|
|
+ private static final String FIND_BY_CODES = "/common/users/v2/findByCodes";
|
|
|
+ private static final String FIND_COMPANY = "/common/departments/v2/findByCode";
|
|
|
+ private ConcurrentHashMap<String, LocalDateTime> tokenStore = new ConcurrentHashMap<>();
|
|
|
+ //出差类型枚举
|
|
|
+ private static final Map<String, String> BUSINESS_TYPE = new HashMap<>();
|
|
|
+
|
|
|
+ static {
|
|
|
+ BUSINESS_TYPE.put("境内", "01");
|
|
|
+ BUSINESS_TYPE.put("境外", "02");
|
|
|
+ BUSINESS_TYPE.put("短期培训", "03");
|
|
|
+ }
|
|
|
+ private static final Map<String, String> ATTACHMENT_ENUM = new HashMap<>();
|
|
|
+ static {
|
|
|
+ ATTACHMENT_ENUM.put("attachmentUrl","附件");
|
|
|
+ ATTACHMENT_ENUM.put("contractTextUrl","合同正文");
|
|
|
+ ATTACHMENT_ENUM.put("contractScanUrl","上传生效的合同扫描件");
|
|
|
+ ATTACHMENT_ENUM.put("contractPreApprovalFlow","合同前置审批流程");
|
|
|
+ ATTACHMENT_ENUM.put("procurementResult","oa请示、采购结果");
|
|
|
+ ATTACHMENT_ENUM.put("decisionDocument","决策文件、会议纪要、中标通知书等");
|
|
|
+ }
|
|
|
+ //所有的枚举
|
|
|
+ private static final Map<String, String> ALLENUM = new HashMap<>();
|
|
|
+
|
|
|
+ static {
|
|
|
+ //签署法人实体
|
|
|
+ ALLENUM.put("option_aoscience_bio_nantong_co_l__c", "澳斯康生物(南通)股份有限公司");
|
|
|
+ ALLENUM.put("option_gansu_jianshun_biotech_co__c", "甘肃健顺生物科技有限公司");
|
|
|
+ ALLENUM.put("option_jianshun_bio_tech_nantong__c", "健顺生物科技(南通)有限公司");
|
|
|
+ ALLENUM.put("option_shanghai_aoskang_bio_pharm__c", "上海澳斯康生物制药有限公司");
|
|
|
+ ALLENUM.put("option_shanghai_jianshiba_biotech__c", "上海健士拜生物科技有限公司");
|
|
|
+ ALLENUM.put("option_group_research_center__c", "集团研发中心");
|
|
|
+ ALLENUM.put("i5r85d5r8", "集团部门");
|
|
|
+ //区域
|
|
|
+ ALLENUM.put("option_international__c", "国际");
|
|
|
+ ALLENUM.put("cD2b3f", "国内");
|
|
|
+ //合同事宜
|
|
|
+ ALLENUM.put("x8luwTHo7", "合同签订");
|
|
|
+ ALLENUM.put("kptFZ7XFr", "合同变更");
|
|
|
+ ALLENUM.put("8D36ieItP", "合同解除");
|
|
|
+ //是否设计法人章、是否涉密
|
|
|
+ ALLENUM.put("option_yes__c", "是");
|
|
|
+ ALLENUM.put("option_no__c", "否");
|
|
|
+ //合同总价是否为固定金额、客户是否需求赔偿
|
|
|
+ ALLENUM.put("true", "是");
|
|
|
+ ALLENUM.put("false", "否");
|
|
|
+ //原币类型
|
|
|
+ ALLENUM.put("option_example_options__c", "欧元EUR");
|
|
|
+ ALLENUM.put("option_usd_currency__c", "美元USD");
|
|
|
+ ALLENUM.put("option_cny__c", "人民币CNY");
|
|
|
+ //是否加盖公章
|
|
|
+ ALLENUM.put("wSZ3tbp4m", "否");
|
|
|
+ ALLENUM.put("option1", "是");
|
|
|
+ //投诉等级
|
|
|
+ ALLENUM.put("option_B__c", "一般质量投诉");
|
|
|
+ ALLENUM.put("option_A__c", "重大质量投诉");
|
|
|
+ //申请类型
|
|
|
+ ALLENUM.put("1kRYAt2So", "细胞株");
|
|
|
+ ALLENUM.put("9V9fvk5j1", "原材料");
|
|
|
+ ALLENUM.put("5U6yt12hf", "耗材");
|
|
|
+ ALLENUM.put("evF26O4He", "产品");
|
|
|
+ ALLENUM.put("other", "其他");
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //所有的枚举
|
|
|
+ private static final Map<String, String> AFTER_SALE = new HashMap<>();
|
|
|
+
|
|
|
+ static {
|
|
|
+ //售后管理
|
|
|
+ AFTER_SALE.put("option_example_options__c", "投诉处理(非质量投诉)");
|
|
|
+ AFTER_SALE.put("option_quality_complaint_handling__c", "投诉处理(质量投诉)");
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 从Content-Disposition头获取文件名
|
|
|
+ */
|
|
|
+ private static String getFileNameFromConnection(HttpURLConnection connection) {
|
|
|
+ String contentDisposition = connection.getHeaderField("Content-Disposition");
|
|
|
+ if (contentDisposition != null) {
|
|
|
+ // 查找filename=后面的内容
|
|
|
+ String[] parts = contentDisposition.split(";");
|
|
|
+ for (String part : parts) {
|
|
|
+ if (part.trim().startsWith("filename=")) {
|
|
|
+ String fileName = part.substring(part.indexOf('=') + 1).trim();
|
|
|
+ // 去除引号并解码URL编码
|
|
|
+ fileName = fileName.replace("\"", "");
|
|
|
+ try {
|
|
|
+ return URLDecoder.decode(fileName, StandardCharsets.UTF_8.name());
|
|
|
+ } catch (UnsupportedEncodingException e) {
|
|
|
+ return fileName;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ //下载宜搭附件
|
|
|
+ private String downloadFile(String fileURL, String contractName, String type, String savePath) throws IOException {
|
|
|
+ //若是宜搭附件url 则需获得附件临时免登地址
|
|
|
+// fileURL = ydClient.convertTemporaryUrl(fileURL);
|
|
|
+
|
|
|
+ URL url = new URL(fileURL);
|
|
|
+ HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
|
|
|
+ httpConn.setRequestMethod("GET");
|
|
|
+ httpConn.setInstanceFollowRedirects(true); // 强制跟随重定向(必加!)
|
|
|
+ httpConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
|
|
|
+ httpConn.setConnectTimeout(10000);
|
|
|
+ httpConn.setReadTimeout(20000);
|
|
|
+ httpConn.setDoInput(true);
|
|
|
+ httpConn.setDoOutput(false);
|
|
|
+ int responseCode = httpConn.getResponseCode();
|
|
|
+
|
|
|
+ // 获取文件名
|
|
|
+// String fileName = getFileNameFromConnection(httpConn);
|
|
|
+ String fileName = contractName + "." + type;
|
|
|
+ // 检查HTTP响应代码是否为200
|
|
|
+ if (responseCode == HttpURLConnection.HTTP_OK) {
|
|
|
+ InputStream inputStream = httpConn.getInputStream();
|
|
|
+ FileOutputStream outputStream = new FileOutputStream(savePath + fileName);
|
|
|
+
|
|
|
+ byte[] buffer = new byte[8192];
|
|
|
+ int bytesRead = -1;
|
|
|
+
|
|
|
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
|
|
|
+ outputStream.write(buffer, 0, bytesRead);
|
|
|
+ }
|
|
|
+
|
|
|
+ outputStream.close();
|
|
|
+ inputStream.close();
|
|
|
+ } else {
|
|
|
+ System.out.println("无法下载文件。HTTP响应代码: " + responseCode);
|
|
|
+ }
|
|
|
+ httpConn.disconnect();
|
|
|
+ return fileName;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 上传文件至钉盘
|
|
|
+ * @param filePath 文件存储地址
|
|
|
+ * @param conflictStrategy 覆盖或其他上传方式
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private Map uploadToDingTalk(String filePath,String conflictStrategy) {
|
|
|
+ //获取当前时间戳
|
|
|
+ long beginTimestamp = System.currentTimeMillis();
|
|
|
+ System.out.println("开始上传附件:" + DateUtil.format(new Date(beginTimestamp), "yyyy-MM-dd HH:mm:ss"));
|
|
|
+
|
|
|
+ //文件
|
|
|
+ File file = new File(filePath);
|
|
|
+
|
|
|
+ //获取文件上传信息
|
|
|
+ Map param = new HashMap();
|
|
|
+ param.put("unionId",unionId);
|
|
|
+ Map body = new HashMap();
|
|
|
+ body.put("protocol","HEADER_SIGNATURE");
|
|
|
+ body.put("multipart",false);
|
|
|
+
|
|
|
+ DDR_New ddr = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v1.0/storage/spaces/" + spaceId + "/files/uploadInfos/query", ddConf.initTokenHeader(ddClient.getAccessToken()), param, body, DDR_New.class);
|
|
|
+ String uploadKey = ddr.getUploadKey();
|
|
|
+ Map headerSignatureInfo = ddr.getHeaderSignatureInfo();
|
|
|
+ Map<String,String> headers = (Map<String,String>) headerSignatureInfo.get("headers");
|
|
|
+ List<String> resourceUrls = (List<String>) headerSignatureInfo.get("resourceUrls");
|
|
|
+ String resourceUrl = resourceUrls.get(0);
|
|
|
+
|
|
|
+ Map dentry = new HashMap();
|
|
|
+ //使用OSS的header加签方式上传文件
|
|
|
+ try {
|
|
|
+ URL url = new URL(resourceUrl);
|
|
|
+ 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();
|
|
|
+ InputStream is = new FileInputStream(file);
|
|
|
+ byte[] b =new byte[1024];
|
|
|
+ int temp;
|
|
|
+ while ((temp=is.read(b))!=-1){
|
|
|
+ out.write(b,0,temp);
|
|
|
+ }
|
|
|
+ out.flush();
|
|
|
+ out.close();
|
|
|
+ int responseCode = connection.getResponseCode();
|
|
|
+ connection.disconnect();
|
|
|
+ if (responseCode == 200) {
|
|
|
+ System.out.println("上传成功");
|
|
|
+ } else {
|
|
|
+ System.out.println("上传失败");
|
|
|
+ }
|
|
|
+ //提交文件
|
|
|
+ Map body2 = new HashMap();
|
|
|
+ Map option = new HashMap();
|
|
|
+ option.put("conflictStrategy",conflictStrategy);
|
|
|
+ body2.put("uploadKey",uploadKey);
|
|
|
+ body2.put("name",file.getName());
|
|
|
+ body2.put("option",option);
|
|
|
+ DDR_New ddrNew = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v2.0/storage/spaces/files/"+parentDentryUuid+"/commit", ddClient.initTokenHeader(), param, body2, DDR_New.class);
|
|
|
+ dentry = ddrNew.getDentry();
|
|
|
+
|
|
|
+ }catch (IOException e){
|
|
|
+ log.info("上传文件异常:{}",e);
|
|
|
+ }
|
|
|
+
|
|
|
+ long endTimestamp = System.currentTimeMillis();
|
|
|
+ System.out.println("上传文件结束:" + DateUtil.format(new Date(endTimestamp), "yyyy-MM-dd HH:mm:ss"));
|
|
|
+ System.out.println("上传文件耗时:" + (endTimestamp - beginTimestamp)/1000.0 + "s");
|
|
|
+ return dentry;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<String, Object> convert(Object object) throws Exception {
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ Class<?> clazz = object.getClass();
|
|
|
+ for (Field field : clazz.getDeclaredFields()) {
|
|
|
+ field.setAccessible(true);
|
|
|
+ String value = field.get(object) != null ? field.get(object).toString() : "";
|
|
|
+ map.put(field.getName(), value);
|
|
|
+ }
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void testGet(String filePath,String parentId,String conflictStrategy) {
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String createContract(ZhiYuanDTO zhiYuanDTO) throws Exception {
|
|
|
+ String downloadUrl = zhiYuanDTO.getDownloadUrl();
|
|
|
+ List<Map<String, Object>> resultList = new ArrayList<>();
|
|
|
+
|
|
|
+ List<ContentFile> contentFileList = new ArrayList<>();
|
|
|
+ List<Map> formValue = new ArrayList<>();
|
|
|
+ //遍历入参所有文件下载地址进行下载文件
|
|
|
+// downloadUrls.forEach(e->{
|
|
|
+/* String fileName = null;
|
|
|
+ try {
|
|
|
+ fileName = downloadFile(downloadUrl, zhiYuanDTO.getContractName(), zhiYuanDTO.getType(), saveFilePath);
|
|
|
+ } catch (IOException ex) {
|
|
|
+ throw new RuntimeException(ex);
|
|
|
+ }*/
|
|
|
+/* Map overwrite = uploadToDingTalk(saveFilePath + fileName, "OVERWRITE");
|
|
|
+ log.info("附件回参:{}",overwrite);
|
|
|
+ ContentFile contentFile = new ContentFile();
|
|
|
+ contentFile.setSpaceId(spaceId);
|
|
|
+ contentFile.setFileId(overwrite.get("uuid").toString());
|
|
|
+ contentFile.setFileName(fileName);
|
|
|
+ contentFile.setFileType(overwrite.get("extension").toString());
|
|
|
+ contentFile.setFileSize(overwrite.get("size").toString());
|
|
|
+
|
|
|
+ contentFileList.add(contentFile);*/
|
|
|
+ Map map = ddService.uploadFileFormUrlForOverflow(ddClient.getAccessToken(), "603864663125953014", downloadUrl, zhiYuanDTO.getContractName(), zhiYuanDTO.getType());
|
|
|
+ Map<String, Object> result = UtilMap.map("spaceId, fileName, fileSize, fileType, fileId", UtilMap.getString(map, "spaceId"), zhiYuanDTO.getContractName(),
|
|
|
+ UtilMap.getString(map, "size"), UtilMap.getString(map, "extension"), UtilMap.getString(map, "id"));
|
|
|
+ resultList.add(result);
|
|
|
+ formValue.add(UtilMap.map("name, value","合同正文",JSON.toJSONString(resultList)));
|
|
|
+ List<Object> objects = new ArrayList<>();
|
|
|
+ formValue.add(UtilMap.map("name, value","合同名称, 测试合同"));
|
|
|
+ formValue.add(UtilMap.map("name, value","合同期限类型, 固定期限"));
|
|
|
+ formValue.add(UtilMap.map("name, value","签署方式, 纸质签署"));
|
|
|
+ formValue.add(UtilMap.map("name, value","金额类型, 无金额"));
|
|
|
+// formValue.add(UtilMap.map("name, value","合同名称, 测试接口"));
|
|
|
+ formValue.add(UtilMap.map("name, value","合同编号生成方式, 选择已有合同编号"));
|
|
|
+ formValue.add(UtilMap.map("name, value","合同编号规则, 测试合同编号"));
|
|
|
+ Map<String, String> map11 = UtilMap.map("name, value, bizAlias", "我方主体名称, 待补充, contract_mine_company_name");
|
|
|
+ Map<String, String> map12 = UtilMap.map("name, value", "我方负责人, 待补充");
|
|
|
+ List<Map<String,String>> mapList1 = new ArrayList<>();
|
|
|
+ mapList1.add(map11);
|
|
|
+ mapList1.add(map12);
|
|
|
+ objects.add(mapList1);
|
|
|
+ formValue.add(UtilMap.map("name, value","我方信息",JSON.toJSONString(objects)));
|
|
|
+
|
|
|
+ objects.clear();
|
|
|
+
|
|
|
+ Map<String, String> map21 = UtilMap.map("name, value, bizAlias", "对方主体名称, 待补充, contract_opposite_company_name");
|
|
|
+ Map<String, String> map22 = UtilMap.map("name, value", "对方负责人, 待补充");
|
|
|
+ List<Map<String,String>> mapList2 = new ArrayList<>();
|
|
|
+ mapList2.add(map21);
|
|
|
+ mapList2.add(map22);
|
|
|
+ objects.add(mapList2);
|
|
|
+ formValue.add(UtilMap.map("name, value","对方信息",JSON.toJSONString(objects)));
|
|
|
+
|
|
|
+ List<String> workingEmployeeIds = new ArrayList<>();
|
|
|
+ workingEmployeeIds.add("603864663125953014");
|
|
|
+ List<String> deptIdByUserId = getDeptIdByUserId(workingEmployeeIds);
|
|
|
+
|
|
|
+// formValue.add(UtilMap.map("name, value","我方信息, [[{\"name\":\"我方主体名称\",\"value\":\"测试我方主体名称1\",\"bizAlias\":\"contract mine company_name\"},{\"name\":\"我方负责人\",\"value\":\"林晔1\"}]]"));
|
|
|
+// formValue.add(UtilMap.map("name, value","对方信息, [[\"name\":\"对方主体名称\",\"value\":\"测试对方主体名称1\",\"bizAlias\":\"contract opposite company name\"},{\"name\":\"对方负责人\",\"value\":\"方1\"}]]"));
|
|
|
+// PROC-B5E48D42-87FA-4C4E-9CD8-9178EEF1F0D3
|
|
|
+// PROC-51DCBCDA-1F51-4C5A-80E7-FFDDACEAD6A9
|
|
|
+ ddClient_workflow.doProcessInstancesNew(ddClient.getAccessToken(), "603864663125953014", "PROC-B5E48D42-87FA-4C4E-9CD8-9178EEF1F0D3", formValue, deptIdByUserId.get(0));
|
|
|
+// });
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 获取钉钉员工手机号
|
|
|
+ * @param workingEmployeeIds 钉钉人员id
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public List<String> getDeptIdByUserId(List<String> workingEmployeeIds) {
|
|
|
+ log.info("根据钉钉人员id获取员工部门id:{}",workingEmployeeIds.toString());
|
|
|
+ List<String> filterList = new ArrayList<>();
|
|
|
+ filterList.add("sys00-mainDeptId");
|
|
|
+ List<Map> employeeInfos = ddClientPersonnel.getEmployeeInfos(ddClient.getAccessToken(), workingEmployeeIds, agentId, filterList);
|
|
|
+ List<String> personList = new ArrayList<>();
|
|
|
+ employeeInfos.forEach(e -> {
|
|
|
+ List<Map> mapList = (List<Map>) e.get("field_data_list");
|
|
|
+ mapList.forEach(m -> {
|
|
|
+ List<Map> valueList = (List<Map>) m.get("field_value_list");
|
|
|
+ String value = valueList.get(0).get("value").toString();
|
|
|
+ personList.add(value);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ return personList;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void testupload() {
|
|
|
+ uploadToDingTalk(saveFilePath + "合印强制验收.jpg","OVERWRITE");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> startProcessContract(String code, Map data) {
|
|
|
+ Map overwrite = uploadToDingTalk(saveFilePath + "合印强制验收.jpg", "OVERWRITE");
|
|
|
+ System.out.println(overwrite);
|
|
|
+ List<Map> formValue = new ArrayList<>();
|
|
|
+ log.info("code:{} ",code);
|
|
|
+ formValue.add(UtilMap.map("name, value","合同名称, 测试合同"));
|
|
|
+ formValue.add(UtilMap.map("name, value","合同期限类型, 固定期限"));
|
|
|
+ formValue.add(UtilMap.map("name, value","签署方式, 纸质签署"));
|
|
|
+ formValue.add(UtilMap.map("name, value","金额类型, 收入"));
|
|
|
+ formValue.add(UtilMap.map("name, value","合同正文",overwrite));
|
|
|
+ formValue.add(UtilMap.map("name, value","我方信息, [[{\"name\":\"我方主体名称\",\"value\":\"测试我方主体名称1\",\"bizAlias\":\"contract mine company_name\"},{\"name\":\"我方负责人\",\"value\":\"林晔1\"}]]"));
|
|
|
+ formValue.add(UtilMap.map("name, value","对方信息, [[\"name\":\"对方主体名称\",\"value\":\"测试对方主体名称1\",\"bizAlias\":\"contract opposite company name\"},{\"name\":\"对方负责人\",\"value\":\"方1\"}]]"));
|
|
|
+ List<String> workingEmployeeIds = new ArrayList<>();
|
|
|
+ workingEmployeeIds.add("603864663125953014");
|
|
|
+ List<String> deptIdByUserId = getDeptIdByUserId(workingEmployeeIds);
|
|
|
+ ddClient_workflow.doProcessInstancesNew(ddClient.getAccessToken(), "603864663125953014", "PROC-51DCBCDA-1F51-4C5A-80E7-FFDDACEAD6A9", formValue, deptIdByUserId.get(0));
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void sendToU8Payment(String processInstanceId) {
|
|
|
+ log.info("开始向用友推送付款合同台账");
|
|
|
+ String token = ddClient.getAccessToken(APP_EKY, APP_SECRET);
|
|
|
+ Map processData = ddClient_workflow.getProcessInstanceId(token, processInstanceId);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void sendToU8Income(String processInstanceId) {
|
|
|
+ log.info("开始向用友推送收款合同台账");
|
|
|
+ String token = ddClient.getAccessToken(APP_EKY, APP_SECRET);
|
|
|
+ Map processData = ddClient_workflow.getProcessInstanceId(token, processInstanceId);
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map MATE;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 加载json
|
|
|
+ */
|
|
|
+ private Map _getMeta() {
|
|
|
+ if (ObjectUtil.isNull(MATE)) {
|
|
|
+ MATE = (Map) UtilFile.readJsonObjectFromResource("json/form.json"); // 本地匹配宜搭组件ID
|
|
|
+// MATE = (Map) UtilFile.readJsonObjectFromResource("static/json/formtest.json"); // 本地匹配宜搭组件ID
|
|
|
+ }
|
|
|
+ return MATE;
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 整合传参数据为OA审批 name - value 数据格式
|
|
|
+ * @param code 单据类型
|
|
|
+ * @param data 传参
|
|
|
+ * @param meta json
|
|
|
+ * @param formValue OA审批数据格式
|
|
|
+ */
|
|
|
+ private void IntegrationData(String code, Map data, Map meta, List<Map> formValue) {
|
|
|
+ log.info("开始处理接口参数数据转为OA审批接口数据格式");
|
|
|
+ //json数据列
|
|
|
+ Map<String, ?> component = (Map) ((Map) meta.get(code)).get("compIds");
|
|
|
+ for (String key : component.keySet()) {
|
|
|
+ Map formData = UtilMap.empty();
|
|
|
+ if (key.startsWith("tableField_")) {
|
|
|
+ String[] split = key.split("_");
|
|
|
+ List<Map> rows = UtilMap.getList(data,split[1]);
|
|
|
+ List<List<Map>> lastList = new ArrayList<>();
|
|
|
+ Map<String, String> compIds = (Map) component.get(key);
|
|
|
+ if (rows.size() > 0 ){
|
|
|
+ for (Map row : rows) {
|
|
|
+ List<Map> details = new ArrayList<>();
|
|
|
+ for (String prop : compIds.keySet()) {
|
|
|
+ Map detail = UtilMap.empty();
|
|
|
+ detail.put("value", row.get(compIds.get(prop)));
|
|
|
+ detail.put("name", prop);
|
|
|
+ if (prop.contains("我方主体名称")){
|
|
|
+ detail.put("bizAlias","contract_mine_company_name");
|
|
|
+ } else if (prop.contains("对方主体名称")) {
|
|
|
+ detail.put("bizAlias","contract_opposite_company_name");
|
|
|
+ }
|
|
|
+ details.add(detail);
|
|
|
+ }
|
|
|
+ lastList.add(details);
|
|
|
+ }
|
|
|
+ formData.put( "value", JSON.toJSONString(lastList));
|
|
|
+ formData.put( "name",((Map) meta.get(code)).get(split[1]).toString());
|
|
|
+ }else {
|
|
|
+ List<Map> details = new ArrayList<>();
|
|
|
+ for (String prop : compIds.keySet()) {
|
|
|
+ Map detail = UtilMap.empty();
|
|
|
+ if ("quantity".equals(compIds.get(prop))){
|
|
|
+ detail.put("value", "0");
|
|
|
+ detail.put("name", prop);
|
|
|
+ }else {
|
|
|
+ detail.put("value", "无");
|
|
|
+ detail.put("name", prop);
|
|
|
+ }
|
|
|
+ details.add(detail);
|
|
|
+ }
|
|
|
+ lastList.add(details);
|
|
|
+ formData.put( "value", JSON.toJSONString(lastList));
|
|
|
+ formData.put( "name",((Map) meta.get(code)).get(split[1]).toString());
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (data.containsKey(component.get(key))){
|
|
|
+ if (ObjectUtil.isNotNull(data.get(component.get(key)))){
|
|
|
+ Object value = data.get(component.get(key));
|
|
|
+ formData.put("name", key);
|
|
|
+ formData.put("value",value.toString());
|
|
|
+ if ("RelatedReceipt".equals(component.get(key))){
|
|
|
+ List<String> ids = new ArrayList<>();
|
|
|
+ ids.add(value.toString());
|
|
|
+ formData.put("name", key);
|
|
|
+ formData.put("value",JSON.toJSONString(ids));
|
|
|
+ }
|
|
|
+ if (ALLENUM.containsKey(value.toString())){
|
|
|
+ formData.put("value",ALLENUM.get(value.toString()));
|
|
|
+ }
|
|
|
+ if (AFTER_SALE.containsKey(value.toString()) && "KS".equals(code) && "售后管理".equals(key)) {
|
|
|
+ formData.put("value",AFTER_SALE.get(value.toString()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (formData.size()>0){
|
|
|
+ formValue.add(formData);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ final String[] token = {""};
|
|
|
+ final boolean[] isHave = {false};
|
|
|
+ ATTACHMENT_ENUM.forEach((k,v)->{
|
|
|
+ if (data.containsKey(k) && hasValid(data,k)){
|
|
|
+ tokenStore.forEach((k1, v1) -> {
|
|
|
+ if (validateToken(k1)) {
|
|
|
+ token[0] = k1;
|
|
|
+ isHave[0] = true;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (!isHave[0]) {
|
|
|
+ token[0] = getOAToken();
|
|
|
+ }
|
|
|
+ log.info("开始处理附件上传");
|
|
|
+ List<Map> attachment = (List<Map>) data.get(k);
|
|
|
+ List<Map<String, Object>> resultList = new ArrayList<>();
|
|
|
+ attachment.forEach(e->{
|
|
|
+ String[] split = UtilMap.getString(e, "name").split("\\.");
|
|
|
+ String fileName = split[0];
|
|
|
+ if (split.length > 2){
|
|
|
+ for (int i = 1; i < split.length -1; i++) {
|
|
|
+ fileName = fileName + "." + split[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ String fileType = split[split.length-1];
|
|
|
+ Map map = ddService.uploadFileFormUrlForOverflow(ddClient.getAccessToken(), "603864663125953014", e.get("downloadUrl").toString() + "?token=" + token[0], fileName, fileType);
|
|
|
+// Map map = ddService.uploadFileFormUrlForOverflow(ddClient.getAccessToken(), data.get(((Map) meta.get(code)).get("creator")).toString(), e.get("downloadUrl").toString() + "?token=" + token[0], fileName, fileType);
|
|
|
+ Map<String, Object> result = UtilMap.map("spaceId, fileName, fileSize, fileType, fileId", UtilMap.getString(map, "spaceId"), fileName,
|
|
|
+ UtilMap.getString(map, "size"), UtilMap.getString(map, "extension"), UtilMap.getString(map, "id"));
|
|
|
+ resultList.add(result);
|
|
|
+ });
|
|
|
+ formValue.add(UtilMap.map("name, value",v,JSON.toJSONString(resultList)));
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 整合传参及OA数据格式
|
|
|
+ * @param code 单据类型
|
|
|
+ * @param data 传参
|
|
|
+ * @return 流程实例id
|
|
|
+ */
|
|
|
+ private String dataProcessing(String code, Map data){
|
|
|
+ //加载json映射
|
|
|
+ Map meta = _getMeta();
|
|
|
+ //表单字段映射
|
|
|
+ List<Map> formValue = new ArrayList<>();
|
|
|
+ log.info("code:{} ",code);
|
|
|
+ IntegrationData(code, data, meta, formValue);
|
|
|
+ List<String> workingEmployeeIds = new ArrayList<>();
|
|
|
+ workingEmployeeIds.add(data.get(((Map) meta.get(code)).get("creator")).toString());
|
|
|
+ List<String> deptIdByUserId = getDeptIdByUserId(workingEmployeeIds);
|
|
|
+ if (code.startsWith("HTSPD")){
|
|
|
+ formValue.add(UtilMap.map("name, value","发起部门",deptIdByUserId.get(0)));
|
|
|
+ formValue.add(UtilMap.map("name, value","合同编号生成方式, 选择已有合同编号"));
|
|
|
+// formValue.add(UtilMap.map("name, value","合同编号规则, 测试合同编号"));
|
|
|
+ return ddClient_workflow.doProcessInstancesNew(ddClient.getAccessToken(), data.get(((Map) meta.get(code)).get("creator")).toString(),((Map) meta.get(code)).get("processCode").toString(), formValue, deptIdByUserId.get(0));
|
|
|
+// return ddClient_workflow.doProcessInstancesNew(ddClient.getAccessToken(), data.get(((Map) meta.get(code)).get("creator")).toString(), "PROC-B5E48D42-87FA-4C4E-9CD8-9178EEF1F0D3", formValue, deptIdByUserId.get(0));
|
|
|
+ }
|
|
|
+ return ddClient_workflow.doProcessInstancesNew(ddClient.getAccessToken(), data.get(((Map) meta.get(code)).get("creator")).toString(), ((Map) meta.get(code)).get("processCode").toString(), formValue, deptIdByUserId.get(0));
|
|
|
+// return code;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 发起流程审批
|
|
|
+ * @param code
|
|
|
+ * @param data
|
|
|
+ * @return 流程实例id和地址
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> startProcess(String code, Map data) {
|
|
|
+ String instanceId = dataProcessing(code, data);
|
|
|
+ JSONObject jsonObject = JSONObject.parseObject(instanceId);
|
|
|
+ if (!ObjectUtil.isNotNull(jsonObject.get("instanceId"))){
|
|
|
+ return UtilMap.map("ddProcessId, dtUrl, reqMsg", jsonObject.get("instanceId"), "error", instanceId);
|
|
|
+ }
|
|
|
+ String url = "https://applink.dingtalk.com/approval/detail?corpId=ding226da4276814d290a1320dcb25e91351&instanceId=" + jsonObject.get("instanceId");
|
|
|
+ return UtilMap.map("ddProcessId, dtUrl, reqMsg", jsonObject.get("instanceId"), url, instanceId);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * object附件判空
|
|
|
+ * @param data
|
|
|
+ * @param key
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean hasValid(Map data,String key) {
|
|
|
+
|
|
|
+ Object flowObj = data.get(key);
|
|
|
+ if (ObjectUtil.isNull(flowObj)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!(flowObj instanceof List)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ List<?> flowList = (List<?>) flowObj;
|
|
|
+ if (flowList.isEmpty()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ for (Object item : flowList) {
|
|
|
+ if (item instanceof Map) {
|
|
|
+ Map<?, ?> itemMap = (Map<?, ?>) item;
|
|
|
+ Object url = itemMap.get("downloadUrl");
|
|
|
+ if (url != null && !url.toString().trim().isEmpty()) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String getOAToken(){
|
|
|
+ String urlStr = "https://oa.cbyun.com.cn/seeyon/rest/token";
|
|
|
+ String jsonInput = "{\"userName\":\"restDing\",\"password\":\"507228d7-8768-4a2d-a1c3-5b49af9b30de\"}";
|
|
|
+
|
|
|
+ HttpURLConnection connection = null;
|
|
|
+ try {
|
|
|
+ // 1. 创建连接
|
|
|
+ URL url = new URL(urlStr);
|
|
|
+ connection = (HttpURLConnection) url.openConnection();
|
|
|
+ connection.setRequestMethod("POST");
|
|
|
+ connection.setRequestProperty("Content-Type", "application/json");
|
|
|
+ connection.setDoOutput(true); // 允许输出
|
|
|
+ connection.setDoInput(true); // 允许输入
|
|
|
+ connection.setConnectTimeout(5000);
|
|
|
+ connection.setReadTimeout(5000);
|
|
|
+
|
|
|
+ // 2. 写入请求体
|
|
|
+ try (OutputStream os = connection.getOutputStream()) {
|
|
|
+ byte[] input = jsonInput.getBytes(StandardCharsets.UTF_8);
|
|
|
+ os.write(input, 0, input.length);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 获取响应码
|
|
|
+ int responseCode = connection.getResponseCode();
|
|
|
+ if (responseCode == HttpURLConnection.HTTP_OK) {
|
|
|
+ // 4. 读取响应内容
|
|
|
+ StringBuilder response = new StringBuilder();
|
|
|
+ try (BufferedReader br = new BufferedReader(
|
|
|
+ new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {
|
|
|
+ String line;
|
|
|
+ while ((line = br.readLine()) != null) {
|
|
|
+ response.append(line);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ String jsonResponse = response.toString();
|
|
|
+ System.out.println("响应原始内容: " + jsonResponse);
|
|
|
+ JSONObject jsonObject = JSONObject.parseObject(jsonResponse);
|
|
|
+
|
|
|
+ // 5. 解析 id 字段(手动提取,避免依赖 JSON 库)
|
|
|
+ String id = jsonObject.getString("id");
|
|
|
+ if (id != null) {
|
|
|
+ log.info("获取到的 id:{} ",id);
|
|
|
+ addToken(id, 14);
|
|
|
+ return id;
|
|
|
+ } else {
|
|
|
+ log.info("未找到 id 字段");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ log.error("请求失败,HTTP 状态码:{} " , responseCode);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } finally {
|
|
|
+ if (connection != null) {
|
|
|
+ connection.disconnect();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * token存储
|
|
|
+ * @param token
|
|
|
+ * @param expireMinutes
|
|
|
+ */
|
|
|
+ public void addToken(String token, int expireMinutes) {
|
|
|
+ LocalDateTime expirationTime = LocalDateTime.now().plusMinutes(expireMinutes);
|
|
|
+ tokenStore.put(token, expirationTime);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 清理过期token
|
|
|
+ * @param token
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean validateToken(String token) {
|
|
|
+ LocalDateTime expirationTime = tokenStore.get(token);
|
|
|
+ if (expirationTime == null || expirationTime.isBefore(LocalDateTime.now())) {
|
|
|
+ tokenStore.remove(token); // 清理过期 Token
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+}
|