Skip to content

Commit

Permalink
Merge pull request #121 from yimfeng/master
Browse files Browse the repository at this point in the history
修复带有图片xmind导入问题
  • Loading branch information
gitxiaofeng authored Nov 3, 2021
2 parents d3a0217 + ec64721 commit 25923a9
Show file tree
Hide file tree
Showing 7 changed files with 332 additions and 114 deletions.
10 changes: 10 additions & 0 deletions case-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,16 @@
<version>0.4.11</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>

</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,17 @@ public class UploadController {
* @param requirementId 需求idStr
* @return 响应体
*/

@Value("${web.upload-path}")
private String uploadPath;

@PostMapping(value = "/import", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Response<Long> importXmind(@RequestParam MultipartFile file, String creator, String bizId,
Long productLineId, String title, String description, Integer channel, String requirementId) {
Long productLineId, String title, String description, Integer channel, String requirementId, HttpServletRequest request) {
FileImportReq req = new FileImportReq(file, creator, productLineId, title, description, channel, requirementId, bizId);
req.validate();
try {
return Response.success(fileService.importXmindFile(req));
return Response.success(fileService.importXmindFile(req, request, uploadPath));
} catch (CaseServerException e) {
throw new CaseServerException(e.getLocalizedMessage(), e.getStatus());
} catch (Exception e) {
Expand All @@ -76,8 +80,7 @@ public Response<Long> importXmind(@RequestParam MultipartFile file, String creat
}
}

@Value("${web.upload-path}")
private String uploadPath;


@PostMapping(value = "/uploadAttachment", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public JSONObject uploadAttachment(@RequestParam MultipartFile file, HttpServletRequest request) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ protected void broadcastRoomMessage(CaseMessageType type, String content) {
}

private void internalHandleMessage(Player p, String msg,
long msgId) {
long msgId) {
p.setLastReceivedMessageId(msgId);

//todo: testCase.apply(msg) 新增如上的方法.
Expand Down Expand Up @@ -406,7 +406,7 @@ public static final class Player {

private Integer pingCount;

// private Integer undoPosition;
// private Integer undoPosition;
// private Integer redoPosition;
private Integer undoCount;
private Integer redoCount;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,10 @@ public static Room getRoom(boolean create, long id) {
if (rooms.get(id) == null) {
synchronized (roomLock) { // TODO: 2021/9/2 此处使用的全局锁,可以优化为局部锁
if (rooms.get(id) == null) {
if (id > Integer.MAX_VALUE) {
if (id > Integer.MAX_VALUE) { // 查看id的大小,如果大于最大值,则表示此id是record,room将recordroom加入
rooms.put(id, new RecordRoom(id));
} else {
rooms.put(id, new CaseRoom(id));
rooms.put(id, new CaseRoom(id)); // 否则将caseRoom加入到rooms
}
LOGGER.info(Thread.currentThread().getName() + ": 新建Room成功,caseid=" + BitBaseUtil.getLow32(id) + ", record id: " + BitBaseUtil.getHigh32(id));
}
Expand All @@ -111,12 +111,14 @@ public void onOpen(@PathParam(value = "caseId") String caseId,
this.recordId = recordId;
this.isCore = isCore;


// 连基本的任务都不是,直接报错
if (CaseWsMessages.UNDEFINED.getMsg().equals(caseId)) {
throw new CaseServerException("用例id为空", StatusCode.WS_UNKNOWN_ERROR);
}

LOGGER.info(Thread.currentThread().getName() + ": [websocket-onOpen 开启新的session][{}]", toString());
// 开启新的session,下面是创建新的client,record以及room
final Client client = new Client(session, recordId, user);
long record = recordId.equals(CaseWsMessages.UNDEFINED.getMsg()) ? 0l : Long.valueOf(recordId);
final Room room = getRoom(true, BitBaseUtil.mergeLong(record, Long.valueOf(caseId)));
Expand All @@ -126,9 +128,9 @@ long record = recordId.equals(CaseWsMessages.UNDEFINED.getMsg()) ? 0l : Long.val
public void run() {
try {
try {
player = room.createAndAddPlayer(client);
if (room.getLock()) {
player.sendRoomMessageAsync("2lock");
player = room.createAndAddPlayer(client); // 给room添加一个新的client
if (room.getLock()) { // 如果room被锁住了
player.sendRoomMessageAsync("2lock"); // 异步的发送lock的消息
}
LOGGER.info(Thread.currentThread().getName() + ": player " + client.getClientName() + " 加入: " + player);
} catch (IllegalStateException e) {
Expand Down Expand Up @@ -192,17 +194,17 @@ public void run() {
char messageType = message.charAt(0);
String messageContent = message.substring(1);
switch (messageType) {
case '0': // 处理ping/pong消息
if (messageContent.equals(CaseWsMessages.PING.getMsg())) {
case '0': // 处理ping/pong消息,这个是一直在进行的
if (messageContent.equals(CaseWsMessages.PING.getMsg())) { // 如果messageContent是ping
room.cs.get(session).sendMessage(CaseMessageType.PING, CaseWsMessages.PONG.getMsg());
} else if (messageContent.equals(CaseWsMessages.PONG.getMsg())) {
} else if (messageContent.equals(CaseWsMessages.PONG.getMsg())) { // 如果messageContent是pong
player.clearPingCount();
} else {
LOGGER.error(Thread.currentThread().getName() + "ping pong 信息有误。消息是:" + message);
}
break;

case '1': // 处理编辑消息
case '1': // 处理编辑消息,包括对信息的编辑以及撤销等操作
LOGGER.info(Thread.currentThread().getName() + ": 收到消息... onMessage: " + message.trim());
if (player != null) {
//todo:此处分隔符待优化
Expand All @@ -212,7 +214,7 @@ public void run() {
}
break;

case '2': // 处理控制消息
case '2': // 处理控制消息,进行对case加锁
LOGGER.info(Thread.currentThread().getName() + ": 收到控制消息... onMessage: " + message.trim());

if (messageContent.equals("lock")) { // lock消息
Expand Down Expand Up @@ -281,5 +283,7 @@ public void onError(Session session, Throwable e) {
}
}



}

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.xiaoju.framework.entity.request.cases.FileImportReq;
import com.xiaoju.framework.entity.response.cases.ExportXmindResp;

import javax.servlet.http.HttpServletRequest;

/**
* 文件上传与导出服务接口
*
Expand All @@ -15,10 +17,11 @@ public interface FileService {
* 导入x-mind文件生成case
*
* @param req 请求体
* @param request
* @return 生成的case-id
* @throws Exception 任何可能的异常
*/
Long importXmindFile(FileImportReq req) throws Exception;
Long importXmindFile(FileImportReq req, HttpServletRequest request, String uploadPath) throws Exception;

/**
* 导出xmind内容
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.xiaoju.framework.entity.request.cases.CaseCreateReq;
import com.xiaoju.framework.entity.request.cases.FileImportReq;
import com.xiaoju.framework.entity.response.cases.ExportXmindResp;
import com.xiaoju.framework.handler.RecordRoom;
import com.xiaoju.framework.mapper.TestCaseMapper;
import com.xiaoju.framework.service.CaseService;
import com.xiaoju.framework.service.FileService;
Expand All @@ -27,11 +28,9 @@
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.print.Doc;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;

import static com.xiaoju.framework.constants.SystemConstant.POINT;
import static com.xiaoju.framework.constants.XmindConstant.*;
Expand All @@ -45,6 +44,8 @@
@Service
public class FileServiceImpl implements FileService {

private static final Logger LOGGER = LoggerFactory.getLogger(FileServiceImpl.class);

@Resource
private CaseService caseService;

Expand All @@ -55,9 +56,8 @@ public class FileServiceImpl implements FileService {

@Override
@Transactional(rollbackFor = Exception.class)
public Long importXmindFile(FileImportReq req) throws Exception {
public Long importXmindFile(FileImportReq req, HttpServletRequest request, String uploadPath) throws Exception {
String fileName = req.getFile().getOriginalFilename();

if (!StringUtils.isEmpty(fileName)) {
// 得到上传文件的扩展名
String suffix = fileName.substring(fileName.lastIndexOf(POINT) + 1).toLowerCase();
Expand Down Expand Up @@ -92,7 +92,8 @@ public Long importXmindFile(FileImportReq req) throws Exception {

// 导入用例
File jsonFile = new File((desc + CONTENT_JSON).replace("/", File.separator));
CaseCreateReq caseCreateReq = jsonFile.exists() ? buildCaseByJson(req, desc) : buildCaseByXml(req, desc);
LOGGER.info("[jsonFile是否存在]" + jsonFile.exists());
CaseCreateReq caseCreateReq = jsonFile.exists() ? buildCaseByJson(req, desc, request, uploadPath) : buildCaseByXml(req, desc, request, uploadPath);
return caseService.insertOrDuplicateCase(caseCreateReq);
}
throw new CaseServerException("传入的文件名非法", StatusCode.FILE_IMPORT_ERROR);
Expand Down Expand Up @@ -158,7 +159,7 @@ private void writeManifestXml(String path){
Document document = DocumentHelper.createDocument();
// 2、创建根节点root
Element root = document.addElement("manifest").addAttribute("xmlns",XMIND_MAINFEST_XMLNS);
// 3、生成子节点及子节点内容
// 3、生成子节点及子节点内容,此处应该添加图片属性(2021/09/06)
root.addElement("file-entry")
.addAttribute("full-path","content.xml")
.addAttribute("media-type","text/xml");
Expand Down Expand Up @@ -214,7 +215,7 @@ private Map<String,String> createFile(Long id)
writeContentXml(testCase,path);
//写Meta文件
writeMetaXml(path);
//写MainFest文件
//写MainFest文件,需要在此处添加文件夹中的问题信息
writeManifestXml(path);

Map<String,String> pathMap = new HashMap<>();
Expand All @@ -223,12 +224,19 @@ private Map<String,String> createFile(Long id)
return pathMap;
}


//拼接xml内容
private void writeContentXml(TestCase testCase,String path){
// 1、创建document对象
Document document = DocumentHelper.createDocument();
// 2、创建根节点root
Element root = document.addElement("xmap-content");
Element root = document.addElement("xhtml:image")
.addAttribute("xmlns:xhtml", "http://www.w3.org/1999/xhtml")
.addNamespace("fo", "http://www.w3.org/1999/XSL/Format")
.addNamespace("svg", "http://www.w3/org/2000/svg") // 在此处svg:添加命名空间
.addNamespace("xhtml", "http://www.w3.org/1999/xhtml") // 在此为xhtml:添加命名空间
.addNamespace("xlink", "http://www.w3.org/1999/xlink"); // 在此为xlink:添加命名空间

// 3、生成子节点及子节点内容
Element sheet = root.addElement("sheet")
.addAttribute("id",ZEN_ROOT_VERSION) // 给sheet添加属性id
Expand All @@ -237,11 +245,12 @@ private void writeContentXml(TestCase testCase,String path){
.addAttribute("timestamp",XMIND_CREATED_VERSION); // 给sheet添加属性timestamp
// 获得全部json数据,此时的json数据中有图片的链接地址,需要把image取出来
JSONObject rootObj = JSON.parseObject(testCase.getCaseContent()).getJSONObject(ROOT);
LOGGER.info("case中的内容:" + testCase.getCaseContent());
Element topic = sheet.addElement("topic") // 给sheet添加新的节点topic
.addAttribute("id",rootObj.getJSONObject(DATA).getString("id")) // 获得id
.addAttribute("modified-by","didi") // 获得用户名
.addAttribute("timestamp",rootObj.getJSONObject(DATA).getString("created")) // 获得创建时间戳
.addAttribute("image",rootObj.getJSONObject(DATA).getString("image")); // 新加的,获得图片2021/08/12
.addAttribute("timestamp",rootObj.getJSONObject(DATA).getString("created")); // 获得创建时间戳


Element title = topic.addElement("title");
String text = rootObj.getJSONObject(DATA).getString("text");
Expand All @@ -252,7 +261,7 @@ private void writeContentXml(TestCase testCase,String path){
}
title.setText(text); // 加入标题
// 在xml里面的children添加数据,但是对于图片来说,它的key是image,而不是children
TreeUtil.exportDataToXml(rootObj.getJSONArray("children"), topic);
TreeUtil.exportDataToXml(rootObj.getJSONArray("children"), topic, path);
String targetPath = path + "/content.xml";
//写入xml
writeXml(targetPath,document);
Expand All @@ -275,25 +284,30 @@ private String creteFolder(TestCase testCase){
return desPath;
}

private CaseCreateReq buildCaseByJson(FileImportReq request, String fileName) {
private CaseCreateReq buildCaseByJson(FileImportReq request, String fileName, HttpServletRequest requests, String uploadPath) throws IOException {
// 开始读取文件中的json内容了
String s = FileUtil.readJsonFile(fileName);
JSONArray parseArray = JSONObject.parseArray(s);
JSONObject getObj = parseArray.getJSONObject(0);
JSONObject rootTopic = getObj.getJSONObject("rootTopic");

String picXml = "resources";
String picName = (fileName + picXml).replace("/", File.separator);

// case-content设置
JSONArray jsonArray = new JSONArray();
TreeUtil.importDataByJson(jsonArray, rootTopic);
TreeUtil.importDataByJson(jsonArray, rootTopic, picName, requests, uploadPath);

return buildCaseCreateReq(request, jsonArray);
}

//xmind8从content文件读取用例内容
public CaseCreateReq buildCaseByXml(FileImportReq request, String fileName) throws Exception {
public CaseCreateReq buildCaseByXml(FileImportReq request, String fileName, HttpServletRequest requests, String uploadPath) throws Exception {

JSONArray jsonArray = new JSONArray();
String fileXml = "content.xml";
String picXml = "attachments"; // 存放图片的文件夹
String picName = (fileName + picXml).replace("/", File.separator);
fileName = (fileName + fileXml).replace("/", File.separator);
File file = new File(fileName);
if(!file.exists()) // 判断文件是否存在
Expand All @@ -306,7 +320,7 @@ public CaseCreateReq buildCaseByXml(FileImportReq request, String fileName) thro
String eleName = childElement.getName();
if(eleName.equalsIgnoreCase("sheet"))
{
jsonArray = TreeUtil.importDataByXml(childElement);
jsonArray = TreeUtil.importDataByXml(request, childElement, picName, requests, uploadPath);
}
return buildCaseCreateReq(request, jsonArray);
}
Expand Down Expand Up @@ -339,4 +353,5 @@ private CaseCreateReq buildCaseCreateReq(FileImportReq request, JSONArray jsonAr
testCase.setBizId(request.getBizId());
return testCase;
}

}
Loading

0 comments on commit 25923a9

Please sign in to comment.