refactor: jira缺陷描述支持图片

This commit is contained in:
chenjianxing 2021-07-06 17:05:08 +08:00 committed by jianxing
parent bc133e8fd0
commit 628f75141f
5 changed files with 68 additions and 11 deletions

View File

@ -13,6 +13,7 @@ import java.util.UUID;
public class FileUtils {
public static final String BODY_FILE_DIR = "/opt/metersphere/data/body";
public static final String MD_IMAGE_DIR = "/opt/metersphere/data/image/markdown";
private static void create(List<String> bodyUploadIds, List<MultipartFile> bodyFiles, String path) {
String filePath = BODY_FILE_DIR;

View File

@ -17,15 +17,12 @@ import java.util.Date;
@Transactional(rollbackFor = Exception.class)
public class ResourceService {
// private static final String RESOURCE_DIR = "/opt/metersphere/data/resource/";
private static final String MD_IMAGE_DIR = "/opt/metersphere/data/image/markdown";
public void mdUpload(MdUploadRequest request, MultipartFile file) {
FileUtils.uploadFile(file, MD_IMAGE_DIR, request.getId() + "_" + file.getOriginalFilename());
FileUtils.uploadFile(file, FileUtils.MD_IMAGE_DIR, request.getId() + "_" + file.getOriginalFilename());
}
public ResponseEntity<FileSystemResource> getMdImage(String name) {
File file = new File(MD_IMAGE_DIR + "/" + name);
File file = new File(FileUtils.MD_IMAGE_DIR + "/" + name);
HttpHeaders headers = new HttpHeaders();
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Content-Disposition", "attachment; filename=" + file.getName());
@ -41,6 +38,6 @@ public class ResourceService {
}
public void mdDelete(String fileName) {
FileUtils.deleteFile(MD_IMAGE_DIR + "/" + fileName);
FileUtils.deleteFile(FileUtils.MD_IMAGE_DIR + "/" + fileName);
}
}

View File

@ -36,6 +36,7 @@ import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.SSLContext;
import java.io.File;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
@ -219,12 +220,12 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
* @return
*/
protected String htmlDesc2MsDesc(String htmlDesc) {
Document document = Jsoup.parse(htmlDesc);
String desc = htmlImg2MsImg(htmlDesc);
Document document = Jsoup.parse(desc);
document.outputSettings(new Document.OutputSettings().prettyPrint(false));
document.select("br").append("\\n");
document.select("p").prepend("\\n\\n");
String s = document.html().replaceAll("\\\\n", "\n");
String desc = htmlImg2MsImg(s);
desc = document.html().replaceAll("\\\\n", "\n");
desc = Jsoup.clean(desc, "", Whitelist.none(), new Document.OutputSettings().prettyPrint(false));
return desc.replace("&nbsp;", "");
}
@ -247,9 +248,19 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
return result;
}
protected String removeImage(String input) {
String regex = "(\\!\\[.*?\\]\\((.*?)\\))";
Matcher matcher = Pattern.compile(regex).matcher(input);
while (matcher.find()) {
matcher.group();
return matcher.replaceAll("");
}
return input;
}
protected String htmlImg2MsImg(String input) {
// <img src="xxx/resource/md/get/a0b19136_中心主题.png"/> -> ![中心主题.png](/resource/md/get/a0b19136_中心主题.png)
String regex = "(<img\\s*src=\\\"(.*?)\\\"/?>)";
String regex = "(<img\\s*src=\\\"(.*?)\\\".*?>)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
String result = input;
@ -257,7 +268,7 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
String url = matcher.group(2);
if (url.contains("/resource/md/get/")) {
String path = url.substring(url.indexOf("/resource/md/get/"));
String name = path.substring(path.lastIndexOf("/") + 10);
String name = path.substring(path.indexOf("/resource/md/get/") + 26);
String mdLink = "![" + name + "](" + path + ")";
result = matcher.replaceFirst(mdLink);
matcher = pattern.matcher(result);
@ -266,6 +277,25 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
return result;
}
public List<File> getImageFiles(String input) {
List<File> files = new ArrayList<>();
String regex = "(\\!\\[.*?\\]\\((.*?)\\))";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
try {
String path = matcher.group(2);
if (path.contains("/resource/md/get/")) {
String name = path.substring(path.indexOf("/resource/md/get/") + 17);
files.add(new File(FileUtils.MD_IMAGE_DIR + "/" + name));
}
} catch (Exception e) {
LogUtil.error(e.getMessage(), e);
}
}
return files;
}
protected UserDTO.PlatformInfo getUserPlatInfo(String orgId) {
return userService.getCurrentPlatformInfo(orgId);
}

View File

@ -33,6 +33,7 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@ -197,6 +198,8 @@ public class JiraPlatform extends AbstractIssuePlatform {
JSONObject project = new JSONObject();
String desc = issuesRequest.getDescription();
List<File> imageFiles = getImageFiles(desc);
desc = removeImage(desc);
fields.put("project", project);
project.put("key", jiraKey);
@ -231,6 +234,10 @@ public class JiraPlatform extends AbstractIssuePlatform {
});
JiraAddIssueResponse result = jiraClientV2.addIssue(JSONObject.toJSONString(addJiraIssueParam));
JiraIssue issues = jiraClientV2.getIssues(result.getId());
imageFiles.forEach(img -> {
jiraClientV2.uploadAttachment(result.getKey(), img);
});
String status = getStatus(issues.getFields());
issuesRequest.setPlatformStatus(status);

View File

@ -7,9 +7,12 @@ import io.metersphere.track.issue.domain.Jira.JiraConfig;
import io.metersphere.track.issue.domain.Jira.JiraField;
import io.metersphere.track.issue.domain.Jira.JiraIssue;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import java.io.File;
import java.util.List;
public abstract class JiraAbstractClient extends BaseClient {
@ -49,6 +52,25 @@ public abstract class JiraAbstractClient extends BaseClient {
return (JiraAddIssueResponse) getResultForObject(JiraAddIssueResponse.class, response);
}
public void uploadAttachment(String issueKey, File file) {
HttpHeaders authHeader = getAuthHeader();
authHeader.add("X-Atlassian-Token", "no-check");
authHeader.setContentType(MediaType.parseMediaType("multipart/form-data; charset=UTF-8"));
MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<>();
FileSystemResource fileResource = new FileSystemResource(file);
paramMap.add("file", fileResource);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(paramMap, authHeader);
ResponseEntity<String> response = null;
try {
response = restTemplate.exchange(getBaseUrl() + "/issue/" + issueKey + "/attachments", HttpMethod.POST, requestEntity, String.class);
} catch (Exception e) {
LogUtil.error(e.getMessage(), e);
MSException.throwException(e.getMessage());
}
System.out.println(response);
}
public void auth() {
try {
restTemplate.exchange(getBaseUrl() + "/myself", HttpMethod.GET, getAuthHttpEntity(), String.class);