|
@@ -1,5 +1,6 @@
|
|
|
package com.malk.zhongche.service.impl;
|
|
package com.malk.zhongche.service.impl;
|
|
|
|
|
|
|
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.auth0.jwt.JWT;
|
|
import com.auth0.jwt.JWT;
|
|
|
import com.auth0.jwt.algorithms.Algorithm;
|
|
import com.auth0.jwt.algorithms.Algorithm;
|
|
@@ -7,6 +8,7 @@ import com.malk.server.aliwork.YDConf;
|
|
|
import com.malk.server.aliwork.YDParam;
|
|
import com.malk.server.aliwork.YDParam;
|
|
|
import com.malk.server.common.McR;
|
|
import com.malk.server.common.McR;
|
|
|
import com.malk.server.teambition.TBConf;
|
|
import com.malk.server.teambition.TBConf;
|
|
|
|
|
+import com.malk.server.teambition.TBR;
|
|
|
import com.malk.service.aliwork.YDClient;
|
|
import com.malk.service.aliwork.YDClient;
|
|
|
import com.malk.service.dingtalk.DDClient;
|
|
import com.malk.service.dingtalk.DDClient;
|
|
|
import com.malk.service.dingtalk.DDClient_Contacts;
|
|
import com.malk.service.dingtalk.DDClient_Contacts;
|
|
@@ -18,9 +20,17 @@ import com.malk.zhongche.service.ZhongcheService;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.apache.logging.log4j.util.Strings;
|
|
import org.apache.logging.log4j.util.Strings;
|
|
|
|
|
+import org.slf4j.MDC;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
|
|
+import java.io.*;
|
|
|
|
|
+import java.net.HttpURLConnection;
|
|
|
|
|
+import java.net.URL;
|
|
|
|
|
+import java.nio.file.Files;
|
|
|
|
|
+import java.nio.file.Path;
|
|
|
|
|
+import java.nio.file.Paths;
|
|
|
import java.text.SimpleDateFormat;
|
|
import java.text.SimpleDateFormat;
|
|
|
import java.time.Instant;
|
|
import java.time.Instant;
|
|
|
import java.time.ZoneId;
|
|
import java.time.ZoneId;
|
|
@@ -46,6 +56,9 @@ public class ZhongcheServiceImpl implements ZhongcheService {
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private TBConf tbConf;
|
|
private TBConf tbConf;
|
|
|
|
|
|
|
|
|
|
+ @Value("${file.path}")
|
|
|
|
|
+ private String filePath;
|
|
|
|
|
+
|
|
|
@Override
|
|
@Override
|
|
|
public McR getTaskInfo(String taskId,String projectId) {
|
|
public McR getTaskInfo(String taskId,String projectId) {
|
|
|
Map taskInfo = tbClient.queryTaskDetail(taskId,null,null).get(0);
|
|
Map taskInfo = tbClient.queryTaskDetail(taskId,null,null).get(0);
|
|
@@ -126,6 +139,8 @@ public class ZhongcheServiceImpl implements ZhongcheService {
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public McR updateTaskDelayInfo(Map map) {
|
|
public McR updateTaskDelayInfo(Map map) {
|
|
|
|
|
+ MDC.put("MDC_KEY_PID","1001");
|
|
|
|
|
+
|
|
|
String formInstId = UtilMap.getString(map, "formInstId");
|
|
String formInstId = UtilMap.getString(map, "formInstId");
|
|
|
|
|
|
|
|
Map formData = ydClient.queryData(YDParam.builder()
|
|
Map formData = ydClient.queryData(YDParam.builder()
|
|
@@ -199,7 +214,7 @@ public class ZhongcheServiceImpl implements ZhongcheService {
|
|
|
|
|
|
|
|
Map map2 = tbClient.updateTaskCustomField(taskId, tbConf.getOperatorId(), body2);
|
|
Map map2 = tbClient.updateTaskCustomField(taskId, tbConf.getOperatorId(), body2);
|
|
|
|
|
|
|
|
- log.info("map1:{}",JSONObject.toJSONString(map1));
|
|
|
|
|
|
|
+ log.info("map2:{}",JSONObject.toJSONString(map2));
|
|
|
|
|
|
|
|
return McR.success();
|
|
return McR.success();
|
|
|
}
|
|
}
|
|
@@ -230,8 +245,8 @@ public class ZhongcheServiceImpl implements ZhongcheService {
|
|
|
String id = UtilMap.getString(resultMap, "id");
|
|
String id = UtilMap.getString(resultMap, "id");
|
|
|
|
|
|
|
|
switch (name){
|
|
switch (name){
|
|
|
- case "任务(企业)":sfcId2 = id;break;
|
|
|
|
|
- case "末级任务(企业)":sfcId3 = id;break;
|
|
|
|
|
|
|
+ case "任务企业":sfcId2 = id;break;
|
|
|
|
|
+ case "末级任务企业":sfcId3 = id;break;
|
|
|
default:break;
|
|
default:break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -292,6 +307,192 @@ public class ZhongcheServiceImpl implements ZhongcheService {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public McR finishTask(Map map) {
|
|
|
|
|
+ MDC.put("MDC_KEY_PID","1002");
|
|
|
|
|
+
|
|
|
|
|
+ String formInstId = UtilMap.getString(map, "formInstId");
|
|
|
|
|
+
|
|
|
|
|
+ Map formData = ydClient.queryData(YDParam.builder()
|
|
|
|
|
+ .formInstanceId(formInstId)
|
|
|
|
|
+ .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
|
|
|
|
|
+
|
|
|
|
|
+ String taskId = UtilMap.getString(formData, "textField_mkkrgg8y");
|
|
|
|
|
+ String projectId = UtilMap.getString(formData, "textField_mkkrgg8u");
|
|
|
|
|
+
|
|
|
|
|
+ if (Objects.nonNull(formData.get("attachmentField_mpzbe3w8"))){
|
|
|
|
|
+ List<Map> addValues = new ArrayList<>();
|
|
|
|
|
+
|
|
|
|
|
+ List<Map> fileList = (List<Map>) JSONArray.parse(String.valueOf(formData.get("attachmentField_mpzbe3w8")));
|
|
|
|
|
+ for (Map fileMap : fileList) {
|
|
|
|
|
+ String ydDownloadUrl = fileMap.get("downloadUrl").toString();
|
|
|
|
|
+ String fileName = fileMap.get("name").toString();
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ //下载宜搭附件
|
|
|
|
|
+ downloadYdFile(ydDownloadUrl, filePath + fileName);
|
|
|
|
|
+ System.out.println("文件下载成功!");
|
|
|
|
|
+
|
|
|
|
|
+ //TB文件创建文件上传凭证
|
|
|
|
|
+ Path path = Paths.get(filePath + fileName);
|
|
|
|
|
+ String mimeType = Files.probeContentType(path);
|
|
|
|
|
+ System.out.println(mimeType); // application/pdf
|
|
|
|
|
+
|
|
|
|
|
+ File file = new File(fileName);
|
|
|
|
|
+ long fileSize = file.length();
|
|
|
|
|
+
|
|
|
|
|
+ Map body = new HashMap();
|
|
|
|
|
+ body.put("scope", "task:"+taskId+"/attachment");
|
|
|
|
|
+ body.put("fileSize", fileSize);
|
|
|
|
|
+ body.put("fileType", mimeType);
|
|
|
|
|
+ body.put("fileName", fileName);
|
|
|
|
|
+ body.put("category", "attachment");
|
|
|
|
|
+
|
|
|
|
|
+ TBR tbr = (TBR) UtilHttp.doPost("https://open.teambition.com/api/v3/awos/upload-token", initHeaderToken(), null, body, TBR.class);
|
|
|
|
|
+ Map result = (Map) tbr.getResult();
|
|
|
|
|
+ String uploadUrl = UtilMap.getString(result, "uploadUrl");
|
|
|
|
|
+ String token = UtilMap.getString(result, "token");
|
|
|
|
|
+
|
|
|
|
|
+ //上传文件
|
|
|
|
|
+ uploadFile(filePath + fileName, uploadUrl, mimeType);
|
|
|
|
|
+
|
|
|
|
|
+ Map value = new HashMap();
|
|
|
|
|
+ value.put("title",fileName);
|
|
|
|
|
+ value.put("metaString",JSONObject.toJSONString(UtilMap.map("fileToken",token)));
|
|
|
|
|
+
|
|
|
|
|
+ addValues.add(value);
|
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //更新tb任务附件
|
|
|
|
|
+ Map body = new HashMap();
|
|
|
|
|
+ body.put("customfieldId", "67e372b0142aea12588c2d22");
|
|
|
|
|
+ body.put("addValues",addValues);
|
|
|
|
|
+
|
|
|
|
|
+ Map map2 = tbClient.updateTaskCustomField(taskId, tbConf.getOperatorId(), body);
|
|
|
|
|
+ log.info("map2:{}",JSONObject.toJSONString(map2));
|
|
|
|
|
+
|
|
|
|
|
+ //查询任务所在工作流的任务状态列表
|
|
|
|
|
+ TBR tbr = (TBR) UtilHttp.doGet("https://open.teambition.com/api/v3/task/" + taskId + "/tfs", initHeaderToken(), null, TBR.class);
|
|
|
|
|
+
|
|
|
|
|
+ List<Map> tfsList = (List<Map>) tbr.getResult();
|
|
|
|
|
+
|
|
|
|
|
+ for (Map tfsMap : tfsList) {
|
|
|
|
|
+ String tfsName = UtilMap.getString(tfsMap, "name");
|
|
|
|
|
+
|
|
|
|
|
+ if ("已完成".equals(tfsName)){
|
|
|
|
|
+ String tfsId = UtilMap.getString(tfsMap, "id");
|
|
|
|
|
+ //完成tb任务
|
|
|
|
|
+ tbClient.updateTaskFlowStatus(taskId, tbConf.getOperatorId(), tfsId,null);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return McR.success();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 上传文件(核心方法)
|
|
|
|
|
+ * @param filePath 本地文件路径(如"2.png")
|
|
|
|
|
+ * @param uploadUrl 接口地址(如Postman中的PUT URL)
|
|
|
|
|
+ * @param contentType 文件类型(如"image/png",可留空由服务端自动识别)
|
|
|
|
|
+ * @return 服务端响应内容
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String uploadFile(String filePath, String uploadUrl, String contentType) throws IOException {
|
|
|
|
|
+ File file = new File(filePath);
|
|
|
|
|
+ if (!file.exists()) {
|
|
|
|
|
+ throw new FileNotFoundException("文件不存在:" + filePath);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 1. 创建URL并打开连接
|
|
|
|
|
+ URL url = new URL(uploadUrl);
|
|
|
|
|
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 2. 配置请求属性(必须为PUT,允许写入请求体)
|
|
|
|
|
+ conn.setRequestMethod("PUT");
|
|
|
|
|
+ conn.setDoOutput(true);
|
|
|
|
|
+ conn.setDoInput(true);
|
|
|
|
|
+ conn.setConnectTimeout(30000); // 连接超时30秒
|
|
|
|
|
+ conn.setReadTimeout(30000); // 读取超时30秒
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 设置请求头(关键:Content-Type需与文件类型匹配)
|
|
|
|
|
+// if (contentType != null && !contentType.isEmpty()) {
|
|
|
|
|
+// conn.setRequestProperty("Content-Type", contentType);
|
|
|
|
|
+// }
|
|
|
|
|
+ // 可选:添加其他头信息(如鉴权Token)
|
|
|
|
|
+ // conn.setRequestProperty("Authorization", "Bearer your_token");
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 读取文件并写入请求体(分块读取,避免大文件内存溢出)
|
|
|
|
|
+ try (FileInputStream fis = new FileInputStream(file);
|
|
|
|
|
+ OutputStream os = conn.getOutputStream()) {
|
|
|
|
|
+
|
|
|
|
|
+ byte[] buffer = new byte[4096]; // 4KB缓冲区
|
|
|
|
|
+ int bytesRead;
|
|
|
|
|
+ long totalBytes = 0;
|
|
|
|
|
+
|
|
|
|
|
+ while ((bytesRead = fis.read(buffer)) != -1) {
|
|
|
|
|
+ os.write(buffer, 0, bytesRead);
|
|
|
|
|
+ totalBytes += bytesRead;
|
|
|
|
|
+ // 可选:打印上传进度(每1MB打印一次)
|
|
|
|
|
+ if (totalBytes % (1024 * 1024) == 0) {
|
|
|
|
|
+ System.out.println("已上传:" + (totalBytes / (1024 * 1024)) + " MB");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 获取响应码并读取响应内容
|
|
|
|
|
+ int responseCode = conn.getResponseCode();
|
|
|
|
|
+ System.out.println("响应码:" + responseCode);
|
|
|
|
|
+
|
|
|
|
|
+ // 读取响应内容(服务端返回的数据)
|
|
|
|
|
+ try (BufferedReader in = new BufferedReader(
|
|
|
|
|
+ new InputStreamReader(conn.getInputStream()))) {
|
|
|
|
|
+ StringBuilder response = new StringBuilder();
|
|
|
|
|
+ String line;
|
|
|
|
|
+ while ((line = in.readLine()) != null) {
|
|
|
|
|
+ response.append(line);
|
|
|
|
|
+ }
|
|
|
|
|
+ return response.toString();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ // 6. 断开连接(确保资源释放)
|
|
|
|
|
+ conn.disconnect();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //下载宜搭附件
|
|
|
|
|
+ private void downloadYdFile(String fileURL, String savePath) throws IOException {
|
|
|
|
|
+ //若是宜搭附件url 则需获得附件临时免登地址
|
|
|
|
|
+ fileURL = ydClient.convertTemporaryUrl(fileURL);
|
|
|
|
|
+
|
|
|
|
|
+ URL url = new URL(fileURL);
|
|
|
|
|
+ HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
|
|
|
|
|
+ int responseCode = httpConn.getResponseCode();
|
|
|
|
|
+
|
|
|
|
|
+ // 检查HTTP响应代码是否为200
|
|
|
|
|
+ if (responseCode == HttpURLConnection.HTTP_OK) {
|
|
|
|
|
+ InputStream inputStream = httpConn.getInputStream();
|
|
|
|
|
+ FileOutputStream outputStream = new FileOutputStream(savePath);
|
|
|
|
|
+
|
|
|
|
|
+ byte[] buffer = new byte[4096];
|
|
|
|
|
+ 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();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private Map getRootTask(String taskId) {
|
|
private Map getRootTask(String taskId) {
|
|
|
Map taskInfo = tbClient.queryTaskDetail(taskId, null, null).get(0);
|
|
Map taskInfo = tbClient.queryTaskDetail(taskId, null, null).get(0);
|
|
|
|
|
|
|
@@ -353,6 +554,8 @@ public class ZhongcheServiceImpl implements ZhongcheService {
|
|
|
header.put("Authorization", getAccessToken());
|
|
header.put("Authorization", getAccessToken());
|
|
|
header.put("X-Tenant-Id", tbConf.getTenantId());
|
|
header.put("X-Tenant-Id", tbConf.getTenantId());
|
|
|
header.put("X-Tenant-Type", "organization");
|
|
header.put("X-Tenant-Type", "organization");
|
|
|
|
|
+ header.put("X-Operator-Id", tbConf.getOperatorId());
|
|
|
|
|
+
|
|
|
return header;
|
|
return header;
|
|
|
}
|
|
}
|
|
|
|
|
|