feat(项目设置): 文件管理支持对接第三方仓库
--task=1009630 --user=宋天阳 文件管理支持对接第三方仓库 https://www.tapd.cn/55049933/s/1243850
This commit is contained in:
parent
531f007e2f
commit
1d534e7efd
|
@ -26,6 +26,7 @@
|
|||
<java-websocket.version>1.5.3</java-websocket.version>
|
||||
<xmlbeans.version>5.1.0</xmlbeans.version>
|
||||
<poi.version>5.1.0</poi.version>
|
||||
<jgit.version>6.2.0.202206071550-r</jgit.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
@ -403,6 +404,12 @@
|
|||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>${poi.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jgit</groupId>
|
||||
<artifactId>org.eclipse.jgit</artifactId>
|
||||
<version>${jgit.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package io.metersphere.api.dto;
|
||||
|
||||
import io.metersphere.base.domain.FileMetadata;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class HashTreeInfoDTO {
|
||||
private String jmx;
|
||||
private HashTree hashTree;
|
||||
private List<FileMetadata> repositoryFiles;
|
||||
}
|
|
@ -3,10 +3,12 @@ package io.metersphere.api.dto;
|
|||
import io.metersphere.base.domain.FileMetadata;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author song.tianyang
|
||||
|
@ -33,4 +35,14 @@ public class JmxInfoDTO {
|
|||
this.name = StringUtils.replace(name, "/", "");
|
||||
}
|
||||
|
||||
public void addFileMetadataLists(List<FileMetadata> list) {
|
||||
if (CollectionUtils.isNotEmpty(list)) {
|
||||
List<String> fileMetadataIds = fileMetadataList.stream().map(FileMetadata::getId).collect(Collectors.toList());
|
||||
list.forEach(item -> {
|
||||
if (!fileMetadataIds.contains(item.getId())) {
|
||||
fileMetadataList.add(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import io.metersphere.api.dto.scenario.request.BodyFile;
|
|||
import io.metersphere.api.service.ApiTestEnvironmentService;
|
||||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
|
||||
import io.metersphere.base.domain.FileMetadata;
|
||||
import io.metersphere.base.mapper.ApiScenarioMapper;
|
||||
import io.metersphere.commons.constants.DelimiterConstants;
|
||||
import io.metersphere.commons.constants.LoopConstants;
|
||||
|
@ -29,6 +30,7 @@ import io.metersphere.commons.utils.LogUtil;
|
|||
import io.metersphere.constants.RunModeConstants;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.jmeter.utils.ScriptEngineUtils;
|
||||
import io.metersphere.metadata.service.FileMetadataService;
|
||||
import io.metersphere.plugin.core.MsParameter;
|
||||
import io.metersphere.plugin.core.MsTestElement;
|
||||
import io.metersphere.service.EnvironmentGroupProjectService;
|
||||
|
@ -106,6 +108,7 @@ public class ElementUtil {
|
|||
list = config.getTransferVariables().stream().filter(ScenarioVariable::isCSVValid).filter(ScenarioVariable::isEnable).collect(Collectors.toList());
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(list)) {
|
||||
FileMetadataService fileMetadataService = CommonBeanFactory.getBean(FileMetadataService.class);
|
||||
list.forEach(item -> {
|
||||
CSVDataSet csvDataSet = new CSVDataSet();
|
||||
csvDataSet.setEnabled(true);
|
||||
|
@ -116,15 +119,28 @@ public class ElementUtil {
|
|||
if (CollectionUtils.isEmpty(item.getFiles())) {
|
||||
MSException.throwException(StringUtils.isEmpty(item.getName()) ? "CSVDataSet" : item.getName() + ":[ " + Translator.get("csv_no_exist") + " ]");
|
||||
} else {
|
||||
boolean isRef = false;
|
||||
String fileId = null;
|
||||
boolean isRepository = false;
|
||||
BodyFile file = item.getFiles().get(0);
|
||||
String path = BODY_FILE_DIR + "/" + item.getFiles().get(0).getId() + "_" + item.getFiles().get(0).getName();
|
||||
if (StringUtils.equalsIgnoreCase(file.getStorage(), StorageConstants.FILE_REF.name())) {
|
||||
isRef = true;
|
||||
fileId = file.getFileId();
|
||||
if (fileMetadataService != null) {
|
||||
FileMetadata fileMetadata = fileMetadataService.getFileMetadataById(fileId);
|
||||
if (fileMetadata != null && StringUtils.equals(fileMetadata.getStorage(), StorageConstants.GIT.name())) {
|
||||
isRepository = true;
|
||||
}
|
||||
}
|
||||
path = FileUtils.getFilePath(file);
|
||||
}
|
||||
if (!config.isOperating() && !new File(path).exists()) {
|
||||
if (!config.isOperating() && !isRepository && !new File(path).exists()) {
|
||||
MSException.throwException(StringUtils.isEmpty(item.getName()) ? "CSVDataSet" : item.getName() + ":[ " + Translator.get("csv_no_exist") + " ]");
|
||||
}
|
||||
csvDataSet.setProperty("filename", path);
|
||||
csvDataSet.setProperty("isRef", isRef);
|
||||
csvDataSet.setProperty("fileId", fileId);
|
||||
}
|
||||
csvDataSet.setIgnoreFirstLine(false);
|
||||
csvDataSet.setProperty("shareMode", shareMode);
|
||||
|
|
|
@ -148,9 +148,13 @@ public class Body {
|
|||
KeyValue keyValue, String requestId, boolean isBinary) {
|
||||
if (files != null) {
|
||||
files.forEach(file -> {
|
||||
boolean isRef = false;
|
||||
String fileId = null;
|
||||
String paramName = keyValue.getName() == null ? requestId : keyValue.getName();
|
||||
String path = null;
|
||||
if (StringUtils.equalsIgnoreCase(file.getStorage(), StorageConstants.FILE_REF.name())) {
|
||||
isRef = true;
|
||||
fileId = file.getFileId();
|
||||
path = FileUtils.getFilePath(file);
|
||||
} else if (StringUtils.isNotBlank(file.getId()) && !isBinary) {
|
||||
// 旧数据
|
||||
|
@ -164,7 +168,10 @@ public class Body {
|
|||
if (StringUtils.isBlank(mimetype)) {
|
||||
mimetype = ContentType.APPLICATION_OCTET_STREAM.getMimeType();
|
||||
}
|
||||
list.add(new HTTPFileArg(path, isBinary ? "" : paramName, mimetype));
|
||||
HTTPFileArg fileArg = new HTTPFileArg(path, isBinary ? "" : paramName, mimetype);
|
||||
fileArg.setProperty("isRef", isRef);
|
||||
fileArg.setProperty("fileId", fileId);
|
||||
list.add(fileArg);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import org.apache.commons.lang.StringUtils;
|
|||
public class BodyFile {
|
||||
private String id;
|
||||
private String name;
|
||||
// LOCAL 和 引用(FILE_REF)
|
||||
// LOCAL 和 引用(FILE_REF) / GIT
|
||||
private String storage;
|
||||
private String fileId;
|
||||
private String projectId;
|
||||
|
|
|
@ -28,7 +28,9 @@ import io.metersphere.commons.constants.APITestStatus;
|
|||
import io.metersphere.commons.constants.ApiRunMode;
|
||||
import io.metersphere.commons.constants.ReportTriggerMode;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.commons.utils.FileUtils;
|
||||
import io.metersphere.commons.utils.ServiceUtils;
|
||||
import io.metersphere.constants.RunModeConstants;
|
||||
import io.metersphere.dto.JmeterRunRequestDTO;
|
||||
import io.metersphere.dto.MsExecResponseDTO;
|
||||
|
|
|
@ -7,7 +7,10 @@ import io.metersphere.api.exec.utils.RequestParamsUtil;
|
|||
import io.metersphere.api.jmeter.JMeterService;
|
||||
import io.metersphere.api.jmeter.utils.SmoothWeighted;
|
||||
import io.metersphere.api.service.ApiTestEnvironmentService;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.domain.ApiExecutionQueueDetail;
|
||||
import io.metersphere.base.domain.ApiScenarioReport;
|
||||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||
import io.metersphere.base.domain.TestPlanApiScenario;
|
||||
import io.metersphere.base.mapper.ApiScenarioMapper;
|
||||
import io.metersphere.base.mapper.ApiScenarioReportMapper;
|
||||
import io.metersphere.base.mapper.TestPlanApiScenarioMapper;
|
||||
|
|
|
@ -8,6 +8,7 @@ import io.metersphere.api.jmeter.utils.SmoothWeighted;
|
|||
import io.metersphere.api.service.RemakeReportService;
|
||||
import io.metersphere.commons.constants.ApiRunMode;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.HashTreeUtil;
|
||||
import io.metersphere.config.JmeterProperties;
|
||||
import io.metersphere.config.KafkaConfig;
|
||||
import io.metersphere.constants.BackendListenerConstants;
|
||||
|
@ -189,6 +190,8 @@ public class JMeterService {
|
|||
if (request.getPool().isPool() && StringUtils.isNotBlank(request.getRunMode()) && !request.getRunMode().startsWith("UI")) {
|
||||
this.runNode(request);
|
||||
} else {
|
||||
//解析hashTree,是否含有文件库文件
|
||||
HashTreeUtil.initRepositoryFiles(request);
|
||||
CommonBeanFactory.getBean(ExecThreadPoolExecutor.class).addTask(request);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import io.metersphere.api.service.ApiExecutionQueueService;
|
|||
import io.metersphere.api.service.TestResultService;
|
||||
import io.metersphere.cache.JMeterEngineCache;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.FileUtils;
|
||||
import io.metersphere.constants.BackendListenerConstants;
|
||||
import io.metersphere.constants.RunModeConstants;
|
||||
import io.metersphere.dto.ResultDTO;
|
||||
|
@ -82,6 +83,7 @@ public class MsApiBackendListener extends AbstractBackendListenerClient implemen
|
|||
} catch (Exception e) {
|
||||
LoggerUtil.error("结果集处理异常", dto.getReportId(), e);
|
||||
} finally {
|
||||
FileUtils.deleteBodyFiles(dto.getReportId());
|
||||
if (FileServer.getFileServer() != null) {
|
||||
LoggerUtil.info("进入监听,开始关闭CSV", dto.getReportId());
|
||||
FileServer.getFileServer().closeCsv(dto.getReportId());
|
||||
|
|
|
@ -23,7 +23,9 @@ import io.metersphere.api.dto.RequestResultExpandDTO;
|
|||
import io.metersphere.api.dto.RunningParamKeys;
|
||||
import io.metersphere.api.exec.queue.PoolExecBlockingQueueUtil;
|
||||
import io.metersphere.api.exec.utils.ResultParseUtil;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.commons.utils.FileUtils;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.commons.utils.ResponseUtil;
|
||||
import io.metersphere.dto.RequestResult;
|
||||
import io.metersphere.jmeter.JMeterBase;
|
||||
import io.metersphere.utils.JMeterVars;
|
||||
|
@ -108,6 +110,7 @@ public class MsDebugListener extends AbstractListenerElement implements SampleLi
|
|||
WebSocketUtils.sendMessageSingle(dto);
|
||||
WebSocketUtils.onClose(this.getName());
|
||||
PoolExecBlockingQueueUtil.offer(this.getName());
|
||||
FileUtils.deleteBodyFiles(this.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -890,8 +890,10 @@ public class ApiAutomationService {
|
|||
}
|
||||
|
||||
|
||||
private String generateJmx(ApiScenarioWithBLOBs apiScenario) {
|
||||
private HashTreeInfoDTO generateJmx(ApiScenarioWithBLOBs apiScenario) {
|
||||
String jmx = null;
|
||||
HashTree jmeterHashTree = new ListedHashTree();
|
||||
List<FileMetadata> repositoryMetadata = new ArrayList<>();
|
||||
MsTestPlan testPlan = new MsTestPlan();
|
||||
// 获取自定义JAR
|
||||
String projectId = apiScenario.getProjectId();
|
||||
|
@ -931,7 +933,8 @@ public class ApiAutomationService {
|
|||
if (isUseElement) {
|
||||
scenario.toHashTree(jmeterHashTree, scenario.getHashTree(), config);
|
||||
ElementUtil.accuracyHashTree(jmeterHashTree);
|
||||
return scenario.getJmx(jmeterHashTree);
|
||||
repositoryMetadata = FileUtils.getRepositoryFileMetadata(jmeterHashTree);
|
||||
jmx = scenario.getJmx(jmeterHashTree);
|
||||
} else {
|
||||
MsThreadGroup group = new MsThreadGroup();
|
||||
group.setLabel(apiScenario.getName());
|
||||
|
@ -942,13 +945,22 @@ public class ApiAutomationService {
|
|||
this.add(scenario);
|
||||
}});
|
||||
testPlan.getHashTree().add(group);
|
||||
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), config);
|
||||
repositoryMetadata = FileUtils.getRepositoryFileMetadata(jmeterHashTree);
|
||||
jmx = testPlan.getJmx(jmeterHashTree);
|
||||
}
|
||||
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), config);
|
||||
|
||||
} catch (Exception ex) {
|
||||
LogUtil.error(ex);
|
||||
MSException.throwException(ex.getMessage());
|
||||
}
|
||||
return testPlan.getJmx(jmeterHashTree);
|
||||
|
||||
|
||||
HashTreeInfoDTO returnDTO = new HashTreeInfoDTO();
|
||||
returnDTO.setJmx(jmx);
|
||||
returnDTO.setHashTree(jmeterHashTree);
|
||||
returnDTO.setRepositoryFiles(repositoryMetadata);
|
||||
return returnDTO;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1143,7 +1155,11 @@ public class ApiAutomationService {
|
|||
MsTestPlan testPlan = new MsTestPlan();
|
||||
testPlan.setHashTree(new LinkedList<>());
|
||||
ApiScenarioDTO scenario = apiScenarios.get(0);
|
||||
JmxInfoDTO jmxInfo = apiTestService.updateJmxString(generateJmx(scenario), scenario.getProjectId(), true);
|
||||
|
||||
HashTreeInfoDTO hashTreeInfoDTO = generateJmx(scenario);
|
||||
JmxInfoDTO jmxInfo = apiTestService.updateJmxString(hashTreeInfoDTO.getJmx(), scenario.getProjectId(), true);
|
||||
jmxInfo.addFileMetadataLists(hashTreeInfoDTO.getRepositoryFiles());
|
||||
|
||||
String name = request.getName() + ".jmx";
|
||||
jmxInfo.setName(name);
|
||||
jmxInfo.setId(id);
|
||||
|
@ -1677,10 +1693,11 @@ public class ApiAutomationService {
|
|||
|
||||
apiScenarioWithBLOBs.forEach(item -> {
|
||||
if (StringUtils.isNotEmpty(item.getScenarioDefinition())) {
|
||||
String jmx = generateJmx(item);
|
||||
if (StringUtils.isNotEmpty(jmx)) {
|
||||
ApiScenarioExportJmxDTO scenariosExportJmx = new ApiScenarioExportJmxDTO(item.getName(), apiTestService.updateJmxString(jmx, item.getProjectId(), false).getXml());
|
||||
JmxInfoDTO dto = apiTestService.updateJmxString(jmx, item.getProjectId(), true);
|
||||
HashTreeInfoDTO hashTreeInfoDTO = generateJmx(item);
|
||||
if (StringUtils.isNotEmpty(hashTreeInfoDTO.getJmx())) {
|
||||
ApiScenarioExportJmxDTO scenariosExportJmx = new ApiScenarioExportJmxDTO(item.getName(), apiTestService.updateJmxString(hashTreeInfoDTO.getJmx(), item.getProjectId(), false).getXml());
|
||||
JmxInfoDTO dto = apiTestService.updateJmxString(hashTreeInfoDTO.getJmx(), item.getProjectId(), true);
|
||||
dto.addFileMetadataLists(hashTreeInfoDTO.getRepositoryFiles());
|
||||
scenariosExportJmx.setId(item.getId());
|
||||
scenariosExportJmx.setVersion(item.getVersion());
|
||||
//扫描需要哪些文件
|
||||
|
@ -1713,9 +1730,9 @@ public class ApiAutomationService {
|
|||
Map<String, byte[]> files = new LinkedHashMap<>();
|
||||
scenarios.forEach(item -> {
|
||||
if (StringUtils.isNotEmpty(item.getScenarioDefinition())) {
|
||||
String jmx = generateJmx(item);
|
||||
if (StringUtils.isNotEmpty(jmx)) {
|
||||
ApiScenarioExportJmxDTO scenariosExportJmx = new ApiScenarioExportJmxDTO(item.getName(), apiTestService.updateJmxString(jmx, item.getProjectId(), false).getXml());
|
||||
HashTreeInfoDTO hashTreeInfoDTO = generateJmx(item);
|
||||
if (StringUtils.isNotEmpty(hashTreeInfoDTO.getJmx())) {
|
||||
ApiScenarioExportJmxDTO scenariosExportJmx = new ApiScenarioExportJmxDTO(item.getName(), apiTestService.updateJmxString(hashTreeInfoDTO.getJmx(), item.getProjectId(), false).getXml());
|
||||
String fileName = item.getName() + ".jmx";
|
||||
String jmxStr = scenariosExportJmx.getJmx();
|
||||
files.put(fileName, jmxStr.getBytes(StandardCharsets.UTF_8));
|
||||
|
@ -2032,7 +2049,9 @@ public class ApiAutomationService {
|
|||
apiScenarioList.forEach(item -> {
|
||||
MsTestPlan testPlan = new MsTestPlan();
|
||||
testPlan.setHashTree(new LinkedList<>());
|
||||
JmxInfoDTO dto = apiTestService.updateJmxString(generateJmx(item), item.getProjectId(), true);
|
||||
HashTreeInfoDTO hashTreeInfoDTO = generateJmx(item);
|
||||
JmxInfoDTO dto = apiTestService.updateJmxString(hashTreeInfoDTO.getJmx(), item.getProjectId(), true);
|
||||
dto.setFileMetadataList(hashTreeInfoDTO.getRepositoryFiles());
|
||||
String name = item.getName() + ".jmx";
|
||||
dto.setId(item.getId());
|
||||
dto.setName(name);
|
||||
|
|
|
@ -11,11 +11,13 @@ import io.metersphere.base.mapper.ApiExecutionQueueDetailMapper;
|
|||
import io.metersphere.base.mapper.ApiScenarioMapper;
|
||||
import io.metersphere.base.mapper.TestPlanApiScenarioMapper;
|
||||
import io.metersphere.commons.constants.ApiRunMode;
|
||||
import io.metersphere.commons.constants.StorageConstants;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.FileUtils;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.dto.JmeterRunRequestDTO;
|
||||
import io.metersphere.metadata.service.FileMetadataService;
|
||||
import io.metersphere.metadata.vo.repository.FileInfoDTO;
|
||||
import io.metersphere.service.EnvironmentGroupProjectService;
|
||||
import io.metersphere.service.PluginService;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
|
@ -46,6 +48,8 @@ public class ApiJMeterFileService {
|
|||
private ApiExecutionQueueDetailMapper executionQueueDetailMapper;
|
||||
@Resource
|
||||
private EnvironmentGroupProjectService environmentGroupProjectService;
|
||||
@Resource
|
||||
private FileMetadataService fileMetadataService;
|
||||
// 接口测试 用例/接口
|
||||
private static final List<String> CASE_MODES = new ArrayList<>() {{
|
||||
this.add(ApiRunMode.DEFINITION.name());
|
||||
|
@ -211,21 +215,34 @@ public class ApiJMeterFileService {
|
|||
return jarFiles;
|
||||
}
|
||||
|
||||
private Map<String, byte[]> getMultipartFiles(HashTree hashTree) {
|
||||
private Map<String, byte[]> getMultipartFiles(String reportId, HashTree hashTree) {
|
||||
Map<String, byte[]> multipartFiles = new LinkedHashMap<>();
|
||||
// 获取附件
|
||||
List<BodyFile> files = new LinkedList<>();
|
||||
FileUtils.getFiles(hashTree, files);
|
||||
FileUtils.getExecuteFiles(hashTree, reportId, files);
|
||||
if (CollectionUtils.isNotEmpty(files)) {
|
||||
Map<String, String> repositoryFileMap = new HashMap<>();
|
||||
for (BodyFile bodyFile : files) {
|
||||
File file = new File(bodyFile.getName());
|
||||
if (file != null && file.exists()) {
|
||||
byte[] fileByte = FileUtils.fileToByte(file);
|
||||
if (fileByte != null) {
|
||||
multipartFiles.put(file.getAbsolutePath(), fileByte);
|
||||
if (StringUtils.equals(bodyFile.getStorage(), StorageConstants.GIT.name())
|
||||
&& StringUtils.isNotBlank(bodyFile.getFileId())) {
|
||||
repositoryFileMap.put(bodyFile.getFileId(), bodyFile.getName());
|
||||
} else {
|
||||
File file = new File(bodyFile.getName());
|
||||
if (file != null && file.exists()) {
|
||||
byte[] fileByte = FileUtils.fileToByte(file);
|
||||
if (fileByte != null) {
|
||||
multipartFiles.put(file.getAbsolutePath(), fileByte);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
List<FileInfoDTO> fileInfoDTOList = fileMetadataService.downloadFileByIds(repositoryFileMap.keySet());
|
||||
fileInfoDTOList.forEach(repositoryFile -> {
|
||||
if (repositoryFile.getFileByte() != null) {
|
||||
multipartFiles.put(FileUtils.BODY_FILE_DIR + File.separator + repositoryFileMap.get(repositoryFile.getId()), repositoryFile.getFileByte());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
return multipartFiles;
|
||||
}
|
||||
|
@ -242,6 +259,10 @@ public class ApiJMeterFileService {
|
|||
private byte[] zipFilesToByteArray(String testId, HashTree hashTree) {
|
||||
String bodyFilePath = FileUtils.BODY_FILE_DIR;
|
||||
String fileName = testId + ".jmx";
|
||||
|
||||
// 获取JMX使用到的附件
|
||||
Map<String, byte[]> multipartFiles = this.getMultipartFiles(testId, hashTree);
|
||||
|
||||
String jmx = new MsTestPlan().getJmx(hashTree);
|
||||
// 处理dubbo请求生成jmx文件
|
||||
if (StringUtils.isNotEmpty(jmx)) {
|
||||
|
@ -250,8 +271,7 @@ public class ApiJMeterFileService {
|
|||
Map<String, byte[]> files = new HashMap<>();
|
||||
// 每个测试生成一个文件夹
|
||||
files.put(fileName, jmx.getBytes(StandardCharsets.UTF_8));
|
||||
// 获取JMX使用到的附件
|
||||
Map<String, byte[]> multipartFiles = this.getMultipartFiles(hashTree);
|
||||
|
||||
if (multipartFiles != null && !multipartFiles.isEmpty()) {
|
||||
for (String k : multipartFiles.keySet()) {
|
||||
byte[] v = multipartFiles.get(k);
|
||||
|
|
|
@ -35,7 +35,9 @@ public class FileMetadata implements Serializable {
|
|||
|
||||
private String resourceType;
|
||||
|
||||
private String description;
|
||||
private Boolean latest;
|
||||
|
||||
private String refId;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
|
@ -1113,6 +1113,136 @@ public class FileMetadataExample {
|
|||
addCriterion("resource_type not between", value1, value2, "resourceType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLatestIsNull() {
|
||||
addCriterion("latest is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLatestIsNotNull() {
|
||||
addCriterion("latest is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLatestEqualTo(Boolean value) {
|
||||
addCriterion("latest =", value, "latest");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLatestNotEqualTo(Boolean value) {
|
||||
addCriterion("latest <>", value, "latest");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLatestGreaterThan(Boolean value) {
|
||||
addCriterion("latest >", value, "latest");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLatestGreaterThanOrEqualTo(Boolean value) {
|
||||
addCriterion("latest >=", value, "latest");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLatestLessThan(Boolean value) {
|
||||
addCriterion("latest <", value, "latest");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLatestLessThanOrEqualTo(Boolean value) {
|
||||
addCriterion("latest <=", value, "latest");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLatestIn(List<Boolean> values) {
|
||||
addCriterion("latest in", values, "latest");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLatestNotIn(List<Boolean> values) {
|
||||
addCriterion("latest not in", values, "latest");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLatestBetween(Boolean value1, Boolean value2) {
|
||||
addCriterion("latest between", value1, value2, "latest");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLatestNotBetween(Boolean value1, Boolean value2) {
|
||||
addCriterion("latest not between", value1, value2, "latest");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdIsNull() {
|
||||
addCriterion("ref_id is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdIsNotNull() {
|
||||
addCriterion("ref_id is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdEqualTo(String value) {
|
||||
addCriterion("ref_id =", value, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdNotEqualTo(String value) {
|
||||
addCriterion("ref_id <>", value, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdGreaterThan(String value) {
|
||||
addCriterion("ref_id >", value, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("ref_id >=", value, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdLessThan(String value) {
|
||||
addCriterion("ref_id <", value, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdLessThanOrEqualTo(String value) {
|
||||
addCriterion("ref_id <=", value, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdLike(String value) {
|
||||
addCriterion("ref_id like", value, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdNotLike(String value) {
|
||||
addCriterion("ref_id not like", value, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdIn(List<String> values) {
|
||||
addCriterion("ref_id in", values, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdNotIn(List<String> values) {
|
||||
addCriterion("ref_id not in", values, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdBetween(String value1, String value2) {
|
||||
addCriterion("ref_id between", value1, value2, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRefIdNotBetween(String value1, String value2) {
|
||||
addCriterion("ref_id not between", value1, value2, "refId");
|
||||
return (Criteria) this;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Criteria extends GeneratedCriteria {
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package io.metersphere.base.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class FileMetadataWithBLOBs extends FileMetadata implements Serializable {
|
||||
private String description;
|
||||
|
||||
private String attachInfo;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
|
@ -23,5 +23,15 @@ public class FileModule implements Serializable {
|
|||
|
||||
private String createUser;
|
||||
|
||||
private String moduleType;
|
||||
|
||||
private String repositoryPath;
|
||||
|
||||
private String repositoryToken;
|
||||
|
||||
private String repositoryUserName;
|
||||
|
||||
private String repositoryDesc;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
|
@ -693,6 +693,286 @@ public class FileModuleExample {
|
|||
addCriterion("create_user not between", value1, value2, "createUser");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModuleTypeIsNull() {
|
||||
addCriterion("module_type is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModuleTypeIsNotNull() {
|
||||
addCriterion("module_type is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModuleTypeEqualTo(String value) {
|
||||
addCriterion("module_type =", value, "moduleType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModuleTypeNotEqualTo(String value) {
|
||||
addCriterion("module_type <>", value, "moduleType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModuleTypeGreaterThan(String value) {
|
||||
addCriterion("module_type >", value, "moduleType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModuleTypeGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("module_type >=", value, "moduleType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModuleTypeLessThan(String value) {
|
||||
addCriterion("module_type <", value, "moduleType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModuleTypeLessThanOrEqualTo(String value) {
|
||||
addCriterion("module_type <=", value, "moduleType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModuleTypeLike(String value) {
|
||||
addCriterion("module_type like", value, "moduleType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModuleTypeNotLike(String value) {
|
||||
addCriterion("module_type not like", value, "moduleType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModuleTypeIn(List<String> values) {
|
||||
addCriterion("module_type in", values, "moduleType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModuleTypeNotIn(List<String> values) {
|
||||
addCriterion("module_type not in", values, "moduleType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModuleTypeBetween(String value1, String value2) {
|
||||
addCriterion("module_type between", value1, value2, "moduleType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModuleTypeNotBetween(String value1, String value2) {
|
||||
addCriterion("module_type not between", value1, value2, "moduleType");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryPathIsNull() {
|
||||
addCriterion("repository_path is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryPathIsNotNull() {
|
||||
addCriterion("repository_path is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryPathEqualTo(String value) {
|
||||
addCriterion("repository_path =", value, "repositoryPath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryPathNotEqualTo(String value) {
|
||||
addCriterion("repository_path <>", value, "repositoryPath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryPathGreaterThan(String value) {
|
||||
addCriterion("repository_path >", value, "repositoryPath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryPathGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("repository_path >=", value, "repositoryPath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryPathLessThan(String value) {
|
||||
addCriterion("repository_path <", value, "repositoryPath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryPathLessThanOrEqualTo(String value) {
|
||||
addCriterion("repository_path <=", value, "repositoryPath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryPathLike(String value) {
|
||||
addCriterion("repository_path like", value, "repositoryPath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryPathNotLike(String value) {
|
||||
addCriterion("repository_path not like", value, "repositoryPath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryPathIn(List<String> values) {
|
||||
addCriterion("repository_path in", values, "repositoryPath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryPathNotIn(List<String> values) {
|
||||
addCriterion("repository_path not in", values, "repositoryPath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryPathBetween(String value1, String value2) {
|
||||
addCriterion("repository_path between", value1, value2, "repositoryPath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryPathNotBetween(String value1, String value2) {
|
||||
addCriterion("repository_path not between", value1, value2, "repositoryPath");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryTokenIsNull() {
|
||||
addCriterion("repository_token is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryTokenIsNotNull() {
|
||||
addCriterion("repository_token is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryTokenEqualTo(String value) {
|
||||
addCriterion("repository_token =", value, "repositoryToken");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryTokenNotEqualTo(String value) {
|
||||
addCriterion("repository_token <>", value, "repositoryToken");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryTokenGreaterThan(String value) {
|
||||
addCriterion("repository_token >", value, "repositoryToken");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryTokenGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("repository_token >=", value, "repositoryToken");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryTokenLessThan(String value) {
|
||||
addCriterion("repository_token <", value, "repositoryToken");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryTokenLessThanOrEqualTo(String value) {
|
||||
addCriterion("repository_token <=", value, "repositoryToken");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryTokenLike(String value) {
|
||||
addCriterion("repository_token like", value, "repositoryToken");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryTokenNotLike(String value) {
|
||||
addCriterion("repository_token not like", value, "repositoryToken");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryTokenIn(List<String> values) {
|
||||
addCriterion("repository_token in", values, "repositoryToken");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryTokenNotIn(List<String> values) {
|
||||
addCriterion("repository_token not in", values, "repositoryToken");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryTokenBetween(String value1, String value2) {
|
||||
addCriterion("repository_token between", value1, value2, "repositoryToken");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryTokenNotBetween(String value1, String value2) {
|
||||
addCriterion("repository_token not between", value1, value2, "repositoryToken");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryUserNameIsNull() {
|
||||
addCriterion("repository_user_name is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryUserNameIsNotNull() {
|
||||
addCriterion("repository_user_name is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryUserNameEqualTo(String value) {
|
||||
addCriterion("repository_user_name =", value, "repositoryUserName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryUserNameNotEqualTo(String value) {
|
||||
addCriterion("repository_user_name <>", value, "repositoryUserName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryUserNameGreaterThan(String value) {
|
||||
addCriterion("repository_user_name >", value, "repositoryUserName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryUserNameGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("repository_user_name >=", value, "repositoryUserName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryUserNameLessThan(String value) {
|
||||
addCriterion("repository_user_name <", value, "repositoryUserName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryUserNameLessThanOrEqualTo(String value) {
|
||||
addCriterion("repository_user_name <=", value, "repositoryUserName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryUserNameLike(String value) {
|
||||
addCriterion("repository_user_name like", value, "repositoryUserName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryUserNameNotLike(String value) {
|
||||
addCriterion("repository_user_name not like", value, "repositoryUserName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryUserNameIn(List<String> values) {
|
||||
addCriterion("repository_user_name in", values, "repositoryUserName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryUserNameNotIn(List<String> values) {
|
||||
addCriterion("repository_user_name not in", values, "repositoryUserName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryUserNameBetween(String value1, String value2) {
|
||||
addCriterion("repository_user_name between", value1, value2, "repositoryUserName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andRepositoryUserNameNotBetween(String value1, String value2) {
|
||||
addCriterion("repository_user_name not between", value1, value2, "repositoryUserName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Criteria extends GeneratedCriteria {
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.metersphere.base.mapper;
|
|||
|
||||
import io.metersphere.base.domain.FileMetadata;
|
||||
import io.metersphere.base.domain.FileMetadataExample;
|
||||
import io.metersphere.base.domain.FileMetadataWithBLOBs;
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
|
@ -12,25 +13,25 @@ public interface FileMetadataMapper {
|
|||
|
||||
int deleteByPrimaryKey(String id);
|
||||
|
||||
int insert(FileMetadata record);
|
||||
int insert(FileMetadataWithBLOBs record);
|
||||
|
||||
int insertSelective(FileMetadata record);
|
||||
int insertSelective(FileMetadataWithBLOBs record);
|
||||
|
||||
List<FileMetadata> selectByExampleWithBLOBs(FileMetadataExample example);
|
||||
List<FileMetadataWithBLOBs> selectByExampleWithBLOBs(FileMetadataExample example);
|
||||
|
||||
List<FileMetadata> selectByExample(FileMetadataExample example);
|
||||
|
||||
FileMetadata selectByPrimaryKey(String id);
|
||||
FileMetadataWithBLOBs selectByPrimaryKey(String id);
|
||||
|
||||
int updateByExampleSelective(@Param("record") FileMetadata record, @Param("example") FileMetadataExample example);
|
||||
int updateByExampleSelective(@Param("record") FileMetadataWithBLOBs record, @Param("example") FileMetadataExample example);
|
||||
|
||||
int updateByExampleWithBLOBs(@Param("record") FileMetadata record, @Param("example") FileMetadataExample example);
|
||||
int updateByExampleWithBLOBs(@Param("record") FileMetadataWithBLOBs record, @Param("example") FileMetadataExample example);
|
||||
|
||||
int updateByExample(@Param("record") FileMetadata record, @Param("example") FileMetadataExample example);
|
||||
|
||||
int updateByPrimaryKeySelective(FileMetadata record);
|
||||
int updateByPrimaryKeySelective(FileMetadataWithBLOBs record);
|
||||
|
||||
int updateByPrimaryKeyWithBLOBs(FileMetadata record);
|
||||
int updateByPrimaryKeyWithBLOBs(FileMetadataWithBLOBs record);
|
||||
|
||||
int updateByPrimaryKey(FileMetadata record);
|
||||
}
|
|
@ -17,9 +17,12 @@
|
|||
<result column="load_jar" jdbcType="BIT" property="loadJar" />
|
||||
<result column="path" jdbcType="VARCHAR" property="path" />
|
||||
<result column="resource_type" jdbcType="VARCHAR" property="resourceType" />
|
||||
<result column="latest" jdbcType="BIT" property="latest" />
|
||||
<result column="ref_id" jdbcType="VARCHAR" property="refId" />
|
||||
</resultMap>
|
||||
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.FileMetadata">
|
||||
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.FileMetadataWithBLOBs">
|
||||
<result column="description" jdbcType="LONGVARCHAR" property="description" />
|
||||
<result column="attach_info" jdbcType="LONGVARCHAR" property="attachInfo" />
|
||||
</resultMap>
|
||||
<sql id="Example_Where_Clause">
|
||||
<where>
|
||||
|
@ -81,10 +84,10 @@
|
|||
</sql>
|
||||
<sql id="Base_Column_List">
|
||||
id, `name`, `type`, `size`, create_time, update_time, project_id, `storage`, create_user,
|
||||
update_user, tags, module_id, load_jar, `path`, resource_type
|
||||
update_user, tags, module_id, load_jar, `path`, resource_type, latest, ref_id
|
||||
</sql>
|
||||
<sql id="Blob_Column_List">
|
||||
description
|
||||
description, attach_info
|
||||
</sql>
|
||||
<select id="selectByExampleWithBLOBs" parameterType="io.metersphere.base.domain.FileMetadataExample" resultMap="ResultMapWithBLOBs">
|
||||
select
|
||||
|
@ -134,21 +137,23 @@
|
|||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
</delete>
|
||||
<insert id="insert" parameterType="io.metersphere.base.domain.FileMetadata">
|
||||
<insert id="insert" parameterType="io.metersphere.base.domain.FileMetadataWithBLOBs">
|
||||
insert into file_metadata (id, `name`, `type`,
|
||||
`size`, create_time, update_time,
|
||||
project_id, `storage`, create_user,
|
||||
update_user, tags, module_id,
|
||||
load_jar, `path`, resource_type,
|
||||
description)
|
||||
latest, ref_id, description,
|
||||
attach_info)
|
||||
values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR},
|
||||
#{size,jdbcType=BIGINT}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
|
||||
#{projectId,jdbcType=VARCHAR}, #{storage,jdbcType=VARCHAR}, #{createUser,jdbcType=VARCHAR},
|
||||
#{updateUser,jdbcType=VARCHAR}, #{tags,jdbcType=VARCHAR}, #{moduleId,jdbcType=VARCHAR},
|
||||
#{loadJar,jdbcType=BIT}, #{path,jdbcType=VARCHAR}, #{resourceType,jdbcType=VARCHAR},
|
||||
#{description,jdbcType=LONGVARCHAR})
|
||||
#{latest,jdbcType=BIT}, #{refId,jdbcType=VARCHAR}, #{description,jdbcType=LONGVARCHAR},
|
||||
#{attachInfo,jdbcType=LONGVARCHAR})
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.FileMetadata">
|
||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.FileMetadataWithBLOBs">
|
||||
insert into file_metadata
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">
|
||||
|
@ -196,9 +201,18 @@
|
|||
<if test="resourceType != null">
|
||||
resource_type,
|
||||
</if>
|
||||
<if test="latest != null">
|
||||
latest,
|
||||
</if>
|
||||
<if test="refId != null">
|
||||
ref_id,
|
||||
</if>
|
||||
<if test="description != null">
|
||||
description,
|
||||
</if>
|
||||
<if test="attachInfo != null">
|
||||
attach_info,
|
||||
</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">
|
||||
|
@ -246,9 +260,18 @@
|
|||
<if test="resourceType != null">
|
||||
#{resourceType,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="latest != null">
|
||||
#{latest,jdbcType=BIT},
|
||||
</if>
|
||||
<if test="refId != null">
|
||||
#{refId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="description != null">
|
||||
#{description,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
<if test="attachInfo != null">
|
||||
#{attachInfo,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<select id="countByExample" parameterType="io.metersphere.base.domain.FileMetadataExample" resultType="java.lang.Long">
|
||||
|
@ -305,9 +328,18 @@
|
|||
<if test="record.resourceType != null">
|
||||
resource_type = #{record.resourceType,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.latest != null">
|
||||
latest = #{record.latest,jdbcType=BIT},
|
||||
</if>
|
||||
<if test="record.refId != null">
|
||||
ref_id = #{record.refId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.description != null">
|
||||
description = #{record.description,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
<if test="record.attachInfo != null">
|
||||
attach_info = #{record.attachInfo,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
|
@ -330,7 +362,10 @@
|
|||
load_jar = #{record.loadJar,jdbcType=BIT},
|
||||
`path` = #{record.path,jdbcType=VARCHAR},
|
||||
resource_type = #{record.resourceType,jdbcType=VARCHAR},
|
||||
description = #{record.description,jdbcType=LONGVARCHAR}
|
||||
latest = #{record.latest,jdbcType=BIT},
|
||||
ref_id = #{record.refId,jdbcType=VARCHAR},
|
||||
description = #{record.description,jdbcType=LONGVARCHAR},
|
||||
attach_info = #{record.attachInfo,jdbcType=LONGVARCHAR}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
|
@ -351,12 +386,14 @@
|
|||
module_id = #{record.moduleId,jdbcType=VARCHAR},
|
||||
load_jar = #{record.loadJar,jdbcType=BIT},
|
||||
`path` = #{record.path,jdbcType=VARCHAR},
|
||||
resource_type = #{record.resourceType,jdbcType=VARCHAR}
|
||||
resource_type = #{record.resourceType,jdbcType=VARCHAR},
|
||||
latest = #{record.latest,jdbcType=BIT},
|
||||
ref_id = #{record.refId,jdbcType=VARCHAR}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
<update id="updateByPrimaryKeySelective" parameterType="io.metersphere.base.domain.FileMetadata">
|
||||
<update id="updateByPrimaryKeySelective" parameterType="io.metersphere.base.domain.FileMetadataWithBLOBs">
|
||||
update file_metadata
|
||||
<set>
|
||||
<if test="name != null">
|
||||
|
@ -401,13 +438,22 @@
|
|||
<if test="resourceType != null">
|
||||
resource_type = #{resourceType,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="latest != null">
|
||||
latest = #{latest,jdbcType=BIT},
|
||||
</if>
|
||||
<if test="refId != null">
|
||||
ref_id = #{refId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="description != null">
|
||||
description = #{description,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
<if test="attachInfo != null">
|
||||
attach_info = #{attachInfo,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
<update id="updateByPrimaryKeyWithBLOBs" parameterType="io.metersphere.base.domain.FileMetadata">
|
||||
<update id="updateByPrimaryKeyWithBLOBs" parameterType="io.metersphere.base.domain.FileMetadataWithBLOBs">
|
||||
update file_metadata
|
||||
set `name` = #{name,jdbcType=VARCHAR},
|
||||
`type` = #{type,jdbcType=VARCHAR},
|
||||
|
@ -423,7 +469,10 @@
|
|||
load_jar = #{loadJar,jdbcType=BIT},
|
||||
`path` = #{path,jdbcType=VARCHAR},
|
||||
resource_type = #{resourceType,jdbcType=VARCHAR},
|
||||
description = #{description,jdbcType=LONGVARCHAR}
|
||||
latest = #{latest,jdbcType=BIT},
|
||||
ref_id = #{refId,jdbcType=VARCHAR},
|
||||
description = #{description,jdbcType=LONGVARCHAR},
|
||||
attach_info = #{attachInfo,jdbcType=LONGVARCHAR}
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
<update id="updateByPrimaryKey" parameterType="io.metersphere.base.domain.FileMetadata">
|
||||
|
@ -441,7 +490,9 @@
|
|||
module_id = #{moduleId,jdbcType=VARCHAR},
|
||||
load_jar = #{loadJar,jdbcType=BIT},
|
||||
`path` = #{path,jdbcType=VARCHAR},
|
||||
resource_type = #{resourceType,jdbcType=VARCHAR}
|
||||
resource_type = #{resourceType,jdbcType=VARCHAR},
|
||||
latest = #{latest,jdbcType=BIT},
|
||||
ref_id = #{refId,jdbcType=VARCHAR}
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
</mapper>
|
|
@ -16,15 +16,21 @@ public interface FileModuleMapper {
|
|||
|
||||
int insertSelective(FileModule record);
|
||||
|
||||
List<FileModule> selectByExampleWithBLOBs(FileModuleExample example);
|
||||
|
||||
List<FileModule> selectByExample(FileModuleExample example);
|
||||
|
||||
FileModule selectByPrimaryKey(String id);
|
||||
|
||||
int updateByExampleSelective(@Param("record") FileModule record, @Param("example") FileModuleExample example);
|
||||
|
||||
int updateByExampleWithBLOBs(@Param("record") FileModule record, @Param("example") FileModuleExample example);
|
||||
|
||||
int updateByExample(@Param("record") FileModule record, @Param("example") FileModuleExample example);
|
||||
|
||||
int updateByPrimaryKeySelective(FileModule record);
|
||||
|
||||
int updateByPrimaryKeyWithBLOBs(FileModule record);
|
||||
|
||||
int updateByPrimaryKey(FileModule record);
|
||||
}
|
|
@ -11,6 +11,13 @@
|
|||
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
|
||||
<result column="pos" jdbcType="DOUBLE" property="pos" />
|
||||
<result column="create_user" jdbcType="VARCHAR" property="createUser" />
|
||||
<result column="module_type" jdbcType="VARCHAR" property="moduleType" />
|
||||
<result column="repository_path" jdbcType="VARCHAR" property="repositoryPath" />
|
||||
<result column="repository_token" jdbcType="VARCHAR" property="repositoryToken" />
|
||||
<result column="repository_user_name" jdbcType="VARCHAR" property="repositoryUserName" />
|
||||
</resultMap>
|
||||
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.FileModule">
|
||||
<result column="repository_desc" jdbcType="LONGVARCHAR" property="repositoryDesc" />
|
||||
</resultMap>
|
||||
<sql id="Example_Where_Clause">
|
||||
<where>
|
||||
|
@ -71,8 +78,28 @@
|
|||
</where>
|
||||
</sql>
|
||||
<sql id="Base_Column_List">
|
||||
id, project_id, `name`, parent_id, `level`, create_time, update_time, pos, create_user
|
||||
id, project_id, `name`, parent_id, `level`, create_time, update_time, pos, create_user,
|
||||
module_type, repository_path, repository_token, repository_user_name
|
||||
</sql>
|
||||
<sql id="Blob_Column_List">
|
||||
repository_desc
|
||||
</sql>
|
||||
<select id="selectByExampleWithBLOBs" parameterType="io.metersphere.base.domain.FileModuleExample" resultMap="ResultMapWithBLOBs">
|
||||
select
|
||||
<if test="distinct">
|
||||
distinct
|
||||
</if>
|
||||
<include refid="Base_Column_List" />
|
||||
,
|
||||
<include refid="Blob_Column_List" />
|
||||
from file_module
|
||||
<if test="_parameter != null">
|
||||
<include refid="Example_Where_Clause" />
|
||||
</if>
|
||||
<if test="orderByClause != null">
|
||||
order by ${orderByClause}
|
||||
</if>
|
||||
</select>
|
||||
<select id="selectByExample" parameterType="io.metersphere.base.domain.FileModuleExample" resultMap="BaseResultMap">
|
||||
select
|
||||
<if test="distinct">
|
||||
|
@ -87,9 +114,11 @@
|
|||
order by ${orderByClause}
|
||||
</if>
|
||||
</select>
|
||||
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
|
||||
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="ResultMapWithBLOBs">
|
||||
select
|
||||
<include refid="Base_Column_List" />
|
||||
,
|
||||
<include refid="Blob_Column_List" />
|
||||
from file_module
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</select>
|
||||
|
@ -106,12 +135,14 @@
|
|||
<insert id="insert" parameterType="io.metersphere.base.domain.FileModule">
|
||||
insert into file_module (id, project_id, `name`,
|
||||
parent_id, `level`, create_time,
|
||||
update_time, pos, create_user
|
||||
)
|
||||
update_time, pos, create_user,
|
||||
module_type, repository_path, repository_token,
|
||||
repository_user_name, repository_desc)
|
||||
values (#{id,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
|
||||
#{parentId,jdbcType=VARCHAR}, #{level,jdbcType=INTEGER}, #{createTime,jdbcType=BIGINT},
|
||||
#{updateTime,jdbcType=BIGINT}, #{pos,jdbcType=DOUBLE}, #{createUser,jdbcType=VARCHAR}
|
||||
)
|
||||
#{updateTime,jdbcType=BIGINT}, #{pos,jdbcType=DOUBLE}, #{createUser,jdbcType=VARCHAR},
|
||||
#{moduleType,jdbcType=VARCHAR}, #{repositoryPath,jdbcType=VARCHAR}, #{repositoryToken,jdbcType=VARCHAR},
|
||||
#{repositoryUserName,jdbcType=VARCHAR}, #{repositoryDesc,jdbcType=LONGVARCHAR})
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.FileModule">
|
||||
insert into file_module
|
||||
|
@ -143,6 +174,21 @@
|
|||
<if test="createUser != null">
|
||||
create_user,
|
||||
</if>
|
||||
<if test="moduleType != null">
|
||||
module_type,
|
||||
</if>
|
||||
<if test="repositoryPath != null">
|
||||
repository_path,
|
||||
</if>
|
||||
<if test="repositoryToken != null">
|
||||
repository_token,
|
||||
</if>
|
||||
<if test="repositoryUserName != null">
|
||||
repository_user_name,
|
||||
</if>
|
||||
<if test="repositoryDesc != null">
|
||||
repository_desc,
|
||||
</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">
|
||||
|
@ -172,6 +218,21 @@
|
|||
<if test="createUser != null">
|
||||
#{createUser,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="moduleType != null">
|
||||
#{moduleType,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="repositoryPath != null">
|
||||
#{repositoryPath,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="repositoryToken != null">
|
||||
#{repositoryToken,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="repositoryUserName != null">
|
||||
#{repositoryUserName,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="repositoryDesc != null">
|
||||
#{repositoryDesc,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<select id="countByExample" parameterType="io.metersphere.base.domain.FileModuleExample" resultType="java.lang.Long">
|
||||
|
@ -210,11 +271,46 @@
|
|||
<if test="record.createUser != null">
|
||||
create_user = #{record.createUser,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.moduleType != null">
|
||||
module_type = #{record.moduleType,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.repositoryPath != null">
|
||||
repository_path = #{record.repositoryPath,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.repositoryToken != null">
|
||||
repository_token = #{record.repositoryToken,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.repositoryUserName != null">
|
||||
repository_user_name = #{record.repositoryUserName,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.repositoryDesc != null">
|
||||
repository_desc = #{record.repositoryDesc,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
<update id="updateByExampleWithBLOBs" parameterType="map">
|
||||
update file_module
|
||||
set id = #{record.id,jdbcType=VARCHAR},
|
||||
project_id = #{record.projectId,jdbcType=VARCHAR},
|
||||
`name` = #{record.name,jdbcType=VARCHAR},
|
||||
parent_id = #{record.parentId,jdbcType=VARCHAR},
|
||||
`level` = #{record.level,jdbcType=INTEGER},
|
||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||
update_time = #{record.updateTime,jdbcType=BIGINT},
|
||||
pos = #{record.pos,jdbcType=DOUBLE},
|
||||
create_user = #{record.createUser,jdbcType=VARCHAR},
|
||||
module_type = #{record.moduleType,jdbcType=VARCHAR},
|
||||
repository_path = #{record.repositoryPath,jdbcType=VARCHAR},
|
||||
repository_token = #{record.repositoryToken,jdbcType=VARCHAR},
|
||||
repository_user_name = #{record.repositoryUserName,jdbcType=VARCHAR},
|
||||
repository_desc = #{record.repositoryDesc,jdbcType=LONGVARCHAR}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
<update id="updateByExample" parameterType="map">
|
||||
update file_module
|
||||
set id = #{record.id,jdbcType=VARCHAR},
|
||||
|
@ -225,7 +321,11 @@
|
|||
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||
update_time = #{record.updateTime,jdbcType=BIGINT},
|
||||
pos = #{record.pos,jdbcType=DOUBLE},
|
||||
create_user = #{record.createUser,jdbcType=VARCHAR}
|
||||
create_user = #{record.createUser,jdbcType=VARCHAR},
|
||||
module_type = #{record.moduleType,jdbcType=VARCHAR},
|
||||
repository_path = #{record.repositoryPath,jdbcType=VARCHAR},
|
||||
repository_token = #{record.repositoryToken,jdbcType=VARCHAR},
|
||||
repository_user_name = #{record.repositoryUserName,jdbcType=VARCHAR}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
|
@ -257,9 +357,41 @@
|
|||
<if test="createUser != null">
|
||||
create_user = #{createUser,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="moduleType != null">
|
||||
module_type = #{moduleType,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="repositoryPath != null">
|
||||
repository_path = #{repositoryPath,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="repositoryToken != null">
|
||||
repository_token = #{repositoryToken,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="repositoryUserName != null">
|
||||
repository_user_name = #{repositoryUserName,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="repositoryDesc != null">
|
||||
repository_desc = #{repositoryDesc,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
<update id="updateByPrimaryKeyWithBLOBs" parameterType="io.metersphere.base.domain.FileModule">
|
||||
update file_module
|
||||
set project_id = #{projectId,jdbcType=VARCHAR},
|
||||
`name` = #{name,jdbcType=VARCHAR},
|
||||
parent_id = #{parentId,jdbcType=VARCHAR},
|
||||
`level` = #{level,jdbcType=INTEGER},
|
||||
create_time = #{createTime,jdbcType=BIGINT},
|
||||
update_time = #{updateTime,jdbcType=BIGINT},
|
||||
pos = #{pos,jdbcType=DOUBLE},
|
||||
create_user = #{createUser,jdbcType=VARCHAR},
|
||||
module_type = #{moduleType,jdbcType=VARCHAR},
|
||||
repository_path = #{repositoryPath,jdbcType=VARCHAR},
|
||||
repository_token = #{repositoryToken,jdbcType=VARCHAR},
|
||||
repository_user_name = #{repositoryUserName,jdbcType=VARCHAR},
|
||||
repository_desc = #{repositoryDesc,jdbcType=LONGVARCHAR}
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
<update id="updateByPrimaryKey" parameterType="io.metersphere.base.domain.FileModule">
|
||||
update file_module
|
||||
set project_id = #{projectId,jdbcType=VARCHAR},
|
||||
|
@ -269,7 +401,11 @@
|
|||
create_time = #{createTime,jdbcType=BIGINT},
|
||||
update_time = #{updateTime,jdbcType=BIGINT},
|
||||
pos = #{pos,jdbcType=DOUBLE},
|
||||
create_user = #{createUser,jdbcType=VARCHAR}
|
||||
create_user = #{createUser,jdbcType=VARCHAR},
|
||||
module_type = #{moduleType,jdbcType=VARCHAR},
|
||||
repository_path = #{repositoryPath,jdbcType=VARCHAR},
|
||||
repository_token = #{repositoryToken,jdbcType=VARCHAR},
|
||||
repository_user_name = #{repositoryUserName,jdbcType=VARCHAR}
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
</mapper>
|
|
@ -1,6 +1,6 @@
|
|||
package io.metersphere.base.mapper.ext;
|
||||
|
||||
import io.metersphere.base.domain.FileMetadata;
|
||||
import io.metersphere.base.domain.FileMetadataWithBLOBs;
|
||||
import io.metersphere.metadata.vo.MoveFIleMetadataRequest;
|
||||
import io.metersphere.performance.request.QueryProjectFileRequest;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
@ -9,7 +9,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
public interface ExtFileMetadataMapper {
|
||||
List<FileMetadata> getProjectFiles(@Param("projectId") String projectId, @Param("request") QueryProjectFileRequest request);
|
||||
List<FileMetadataWithBLOBs> getProjectFiles(@Param("projectId") String projectId, @Param("request") QueryProjectFileRequest request);
|
||||
|
||||
List<String> getTypes();
|
||||
|
||||
|
@ -17,5 +17,7 @@ public interface ExtFileMetadataMapper {
|
|||
|
||||
List<Map<String, Object>> moduleCountByMetadataIds(@Param("ids") List<String> ids);
|
||||
|
||||
void updateModuleIdByProjectId(@Param("moduleId")String moduleId, @Param("projectId")String projectId);
|
||||
void updateModuleIdByProjectId(@Param("moduleId") String moduleId, @Param("projectId") String projectId);
|
||||
|
||||
List<String> selectRefIdsByIds(@Param("ids") List<String> nodeIds);
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="io.metersphere.base.mapper.ext.ExtFileMetadataMapper">
|
||||
<select id="getProjectFiles" resultType="io.metersphere.base.domain.FileMetadata">
|
||||
<select id="getProjectFiles" resultType="io.metersphere.base.domain.FileMetadataWithBLOBs">
|
||||
SELECT file_metadata.* FROM file_metadata
|
||||
WHERE project_id = #{projectId,jdbcType=VARCHAR} AND type != 'RSA_KEY'
|
||||
WHERE project_id = #{projectId,jdbcType=VARCHAR} AND type != 'RSA_KEY' AND latest IS TRUE
|
||||
<if test="request.name != null and request.name !=''">
|
||||
AND ( file_metadata.name LIKE CONCAT('%', #{request.name}, '%')
|
||||
OR file_metadata.tags LIKE CONCAT('%', #{request.name}, '%')
|
||||
|
@ -69,7 +69,7 @@
|
|||
|
||||
<update id="move">
|
||||
update file_metadata set module_id = #{request.moduleId}
|
||||
where id in
|
||||
where storage != 'GIT' AND id in
|
||||
<foreach collection="request.metadataIds" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
|
@ -83,6 +83,15 @@
|
|||
</foreach>
|
||||
GROUP BY module_id
|
||||
</select>
|
||||
|
||||
<select id="selectRefIdsByIds" resultType="java.util.Map">
|
||||
select ref_id from file_metadata
|
||||
where ref_id IS NOT NULL AND id in
|
||||
<foreach collection="ids" item="value" separator="," open="(" close=")">
|
||||
#{value}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<update id="updateModuleIdByProjectId">
|
||||
update file_metadata set module_id = #{moduleId}
|
||||
where project_id = #{projectId} and module_id is null
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#{emp.updateTime,jdbcType=BIGINT})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<select id="getNodeTreeByProjectId" resultType="io.metersphere.metadata.vo.FileModuleVo">
|
||||
select
|
||||
<include refid="io.metersphere.base.mapper.FileModuleMapper.Base_Column_List"/>
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package io.metersphere.commons.constants;
|
||||
|
||||
public enum FileModuleTypeConstants {
|
||||
MODULE("module"),REPOSITORY("repository");
|
||||
|
||||
private String value;
|
||||
|
||||
FileModuleTypeConstants(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
package io.metersphere.commons.constants;
|
||||
|
||||
public enum StorageConstants {
|
||||
LOCAL, MINIO, FILE_REF
|
||||
LOCAL, MINIO, FILE_REF, GIT
|
||||
}
|
||||
|
|
|
@ -3,8 +3,10 @@ package io.metersphere.commons.utils;
|
|||
import io.metersphere.api.dto.scenario.request.BodyFile;
|
||||
import io.metersphere.base.domain.FileMetadata;
|
||||
import io.metersphere.base.domain.JarConfig;
|
||||
import io.metersphere.commons.constants.StorageConstants;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.metadata.service.FileMetadataService;
|
||||
import io.metersphere.service.JarConfigService;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
@ -52,6 +54,33 @@ public class FileUtils {
|
|||
return new byte[10];
|
||||
}
|
||||
|
||||
public static void createFile(String filePath, byte[] fileBytes) {
|
||||
File file = new File(filePath);
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
try {
|
||||
File dir = file.getParentFile();
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
file.createNewFile();
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
|
||||
try (InputStream in = new ByteArrayInputStream(fileBytes); OutputStream out = new FileOutputStream(file)) {
|
||||
final int MAX = 4096;
|
||||
byte[] buf = new byte[MAX];
|
||||
for (int bytesRead = in.read(buf, 0, MAX); bytesRead != -1; bytesRead = in.read(buf, 0, MAX)) {
|
||||
out.write(buf, 0, bytesRead);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LogUtil.error(e);
|
||||
MSException.throwException(Translator.get("upload_fail"));
|
||||
}
|
||||
}
|
||||
|
||||
private static void create(List<String> bodyUploadIds, List<MultipartFile> bodyFiles, String path) {
|
||||
String filePath = BODY_FILE_DIR;
|
||||
if (StringUtils.isNotEmpty(path)) {
|
||||
|
@ -123,7 +152,7 @@ public class FileUtils {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void copyBodyFiles(String sourceId, String targetId) {
|
||||
try {
|
||||
String sourcePath = BODY_FILE_DIR + File.separator + sourceId;
|
||||
|
@ -309,6 +338,10 @@ public class FileUtils {
|
|||
BodyFile file = new BodyFile();
|
||||
file.setId(arg.getParamName());
|
||||
file.setName(arg.getPath());
|
||||
if (arg.getPropertyAsBoolean("isRef")) {
|
||||
file.setStorage(StorageConstants.FILE_REF.name());
|
||||
file.setFileId(arg.getPropertyAsString("fileId"));
|
||||
}
|
||||
files.add(file);
|
||||
}
|
||||
}
|
||||
|
@ -327,6 +360,58 @@ public class FileUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前jmx 涉及到的文件 执行时
|
||||
*
|
||||
* @param tree
|
||||
*/
|
||||
public static void getExecuteFiles(HashTree tree, String reportId, List<BodyFile> files) {
|
||||
FileMetadataService fileMetadataService = CommonBeanFactory.getBean(FileMetadataService.class);
|
||||
for (Object key : tree.keySet()) {
|
||||
HashTree node = tree.get(key);
|
||||
if (key instanceof HTTPSamplerProxy) {
|
||||
HTTPSamplerProxy source = (HTTPSamplerProxy) key;
|
||||
if (source != null && source.getHTTPFiles().length > 0) {
|
||||
for (HTTPFileArg arg : source.getHTTPFiles()) {
|
||||
BodyFile file = new BodyFile();
|
||||
file.setId(arg.getParamName());
|
||||
file.setName(arg.getPath());
|
||||
if (arg.getPropertyAsBoolean("isRef") && fileMetadataService != null) {
|
||||
FileMetadata fileMetadata = fileMetadataService.getFileMetadataById(arg.getPropertyAsString("fileId"));
|
||||
if (fileMetadata != null && StringUtils.equals(StorageConstants.GIT.name(), fileMetadata.getStorage())) {
|
||||
file.setStorage(StorageConstants.GIT.name());
|
||||
file.setFileId(arg.getPropertyAsString("fileId"));
|
||||
file.setName(reportId + File.separator + fileMetadata.getName());
|
||||
arg.setPath(BODY_FILE_DIR + File.separator + reportId + File.separator + fileMetadata.getName());
|
||||
}
|
||||
}
|
||||
files.add(file);
|
||||
}
|
||||
}
|
||||
} else if (key instanceof CSVDataSet) {
|
||||
CSVDataSet source = (CSVDataSet) key;
|
||||
if (source != null && StringUtils.isNotEmpty(source.getPropertyAsString("filename"))) {
|
||||
BodyFile file = new BodyFile();
|
||||
file.setId(source.getPropertyAsString("filename"));
|
||||
file.setName(source.getPropertyAsString("filename"));
|
||||
if (source.getPropertyAsBoolean("isRef") && fileMetadataService != null) {
|
||||
FileMetadata fileMetadata = fileMetadataService.getFileMetadataById(source.getPropertyAsString("fileId"));
|
||||
if (fileMetadata != null && StringUtils.equals(StorageConstants.GIT.name(), fileMetadata.getStorage())) {
|
||||
file.setStorage(StorageConstants.GIT.name());
|
||||
file.setFileId(source.getPropertyAsString("fileId"));
|
||||
file.setName(reportId + File.separator + fileMetadata.getName());
|
||||
source.setFilename(BODY_FILE_DIR + File.separator + reportId + File.separator + fileMetadata.getName());
|
||||
}
|
||||
}
|
||||
files.add(file);
|
||||
}
|
||||
}
|
||||
if (node != null) {
|
||||
getExecuteFiles(node, reportId, files);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] fileToByte(File tradeFile) {
|
||||
byte[] buffer = null;
|
||||
try (FileInputStream fis = new FileInputStream(tradeFile);
|
||||
|
@ -392,6 +477,44 @@ public class FileUtils {
|
|||
return buffer;
|
||||
}
|
||||
|
||||
public static List<FileMetadata> getRepositoryFileMetadata(HashTree tree) {
|
||||
FileMetadataService fileMetadataService = CommonBeanFactory.getBean(FileMetadataService.class);
|
||||
List<FileMetadata> list = new ArrayList<>();
|
||||
for (Object key : tree.keySet()) {
|
||||
HashTree node = tree.get(key);
|
||||
if (key instanceof HTTPSamplerProxy) {
|
||||
HTTPSamplerProxy source = (HTTPSamplerProxy) key;
|
||||
if (source != null && source.getHTTPFiles().length > 0) {
|
||||
for (HTTPFileArg arg : source.getHTTPFiles()) {
|
||||
if (arg.getPropertyAsBoolean("isRef") && fileMetadataService != null) {
|
||||
FileMetadata fileMetadata = fileMetadataService.getFileMetadataById(arg.getPropertyAsString("fileId"));
|
||||
if (fileMetadata != null && StringUtils.equals(StorageConstants.GIT.name(), fileMetadata.getStorage())) {
|
||||
list.add(fileMetadata);
|
||||
arg.setPath(fileMetadata.getName());
|
||||
arg.setName(fileMetadata.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (key instanceof CSVDataSet) {
|
||||
CSVDataSet source = (CSVDataSet) key;
|
||||
if (source != null && StringUtils.isNotEmpty(source.getPropertyAsString("filename"))) {
|
||||
if (source.getPropertyAsBoolean("isRef") && fileMetadataService != null) {
|
||||
FileMetadata fileMetadata = fileMetadataService.getFileMetadataById(source.getPropertyAsString("fileId"));
|
||||
if (fileMetadata != null && StringUtils.equals(StorageConstants.GIT.name(), fileMetadata.getStorage())) {
|
||||
list.add(fileMetadata);
|
||||
source.setFilename(fileMetadata.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node != null) {
|
||||
list.addAll(getRepositoryFileMetadata(node));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<Object> getZipJar() {
|
||||
List<Object> jarFiles = new LinkedList<>();
|
||||
// jar 包
|
||||
|
|
|
@ -13,9 +13,14 @@ import io.metersphere.api.dto.definition.request.ParameterConfig;
|
|||
import io.metersphere.api.dto.definition.request.assertions.MsAssertionRegex;
|
||||
import io.metersphere.api.dto.definition.request.assertions.MsAssertions;
|
||||
import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
|
||||
import io.metersphere.api.dto.scenario.request.BodyFile;
|
||||
import io.metersphere.api.service.ApiTestEnvironmentService;
|
||||
import io.metersphere.api.service.ExtErrorReportLibraryService;
|
||||
import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
|
||||
import io.metersphere.commons.constants.StorageConstants;
|
||||
import io.metersphere.dto.JmeterRunRequestDTO;
|
||||
import io.metersphere.metadata.service.FileMetadataService;
|
||||
import io.metersphere.metadata.vo.repository.FileInfoDTO;
|
||||
import io.metersphere.plugin.core.MsTestElement;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -26,6 +31,7 @@ import org.apache.jmeter.modifiers.JSR223PreProcessor;
|
|||
import org.apache.jmeter.protocol.java.sampler.JSR223Sampler;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
|
@ -34,6 +40,39 @@ import java.util.*;
|
|||
*/
|
||||
public class HashTreeUtil {
|
||||
|
||||
public static void initRepositoryFiles(JmeterRunRequestDTO runRequest) {
|
||||
if (runRequest.getPool().isPool() || runRequest.getPool().isK8s()) {
|
||||
return;
|
||||
}
|
||||
List<BodyFile> files = new LinkedList<>();
|
||||
FileUtils.getExecuteFiles(runRequest.getHashTree(), runRequest.getReportId(), files);
|
||||
if (CollectionUtils.isNotEmpty(files)) {
|
||||
Map<String, String> repositoryFileMap = new HashMap<>();
|
||||
for (BodyFile bodyFile : files) {
|
||||
if (StringUtils.equals(bodyFile.getStorage(), StorageConstants.GIT.name())
|
||||
&& StringUtils.isNotBlank(bodyFile.getFileId())) {
|
||||
repositoryFileMap.put(bodyFile.getFileId(), bodyFile.getName());
|
||||
}
|
||||
}
|
||||
FileMetadataService fileMetadataService = CommonBeanFactory.getBean(FileMetadataService.class);
|
||||
if (fileMetadataService != null) {
|
||||
Map<String, byte[]> multipartFiles = new LinkedHashMap<>();
|
||||
List<FileInfoDTO> fileInfoDTOList = fileMetadataService.downloadFileByIds(repositoryFileMap.keySet());
|
||||
fileInfoDTOList.forEach(repositoryFile -> {
|
||||
if (repositoryFile.getFileByte() != null) {
|
||||
multipartFiles.put(FileUtils.BODY_FILE_DIR + File.separator + repositoryFileMap.get(repositoryFile.getId()), repositoryFile.getFileByte());
|
||||
}
|
||||
});
|
||||
for (Map.Entry<String, byte[]> fileEntry : multipartFiles.entrySet()) {
|
||||
String fileName = fileEntry.getKey();
|
||||
byte[] fileBytes = fileEntry.getValue();
|
||||
FileUtils.createFile(fileName, fileBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Map<String, Map<String, String>> getEnvParamsDataByHashTree(HashTree hashTree, ApiTestEnvironmentService apiTestEnvironmentService) {
|
||||
Map<String, Map<String, String>> returnMap = new HashMap<>();
|
||||
Map<String, List<String>> envParamMap = this.getEnvParamsMapByHashTree(hashTree);
|
||||
|
@ -85,7 +124,7 @@ public class HashTreeUtil {
|
|||
return returnMap;
|
||||
}
|
||||
|
||||
public void setEnvParamsMapToHashTree(HashTree hashTree, Map<String, Map<String, String>> envParamsMap) {
|
||||
public void setEnvParamsMapToHashTree(HashTree hashTree, Map<String, Map<String, String>> envParamsMap) {
|
||||
if (hashTree != null) {
|
||||
Map<String, String> allParamMap = new HashMap<>();
|
||||
for (Map<String, String> paramMap : envParamsMap.values()) {
|
||||
|
@ -239,9 +278,9 @@ public class HashTreeUtil {
|
|||
return target;
|
||||
}
|
||||
|
||||
public static List<MsAssertions> getErrorReportByProjectId(String projectId,boolean higherThanSuccess,boolean higherThanError) {
|
||||
public static List<MsAssertions> getErrorReportByProjectId(String projectId, boolean higherThanSuccess, boolean higherThanError) {
|
||||
ExtErrorReportLibraryService service = CommonBeanFactory.getBean(ExtErrorReportLibraryService.class);
|
||||
return service.getAssertionByProjectIdAndStatusIsOpen(projectId,higherThanSuccess,higherThanError);
|
||||
return service.getAssertionByProjectIdAndStatusIsOpen(projectId, higherThanSuccess, higherThanError);
|
||||
}
|
||||
|
||||
public static void addPositive(EnvironmentConfig envConfig, HashTree samplerHashTree, ParameterConfig config, String projectId) {
|
||||
|
@ -249,7 +288,7 @@ public class HashTreeUtil {
|
|||
return;
|
||||
}
|
||||
if (!config.isOperating() && envConfig.isUseErrorCode()) {
|
||||
List<MsAssertions> errorReportAssertion = HashTreeUtil.getErrorReportByProjectId(projectId,envConfig.isHigherThanSuccess(),envConfig.isHigherThanError());
|
||||
List<MsAssertions> errorReportAssertion = HashTreeUtil.getErrorReportByProjectId(projectId, envConfig.isHigherThanSuccess(), envConfig.isHigherThanError());
|
||||
for (MsAssertions assertion : errorReportAssertion) {
|
||||
assertion.toHashTree(samplerHashTree, assertion.getHashTree(), config);
|
||||
}
|
||||
|
@ -266,7 +305,8 @@ public class HashTreeUtil {
|
|||
JSONObject element = JSON.parseObject(scenarioDefinition, Feature.DisableSpecialKeyDetect);
|
||||
ElementUtil.dataFormatting(element);
|
||||
try {
|
||||
return mapper.readValue(element.getString("hashTree"), new TypeReference<>() {});
|
||||
return mapper.readValue(element.getString("hashTree"), new TypeReference<>() {
|
||||
});
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.metadata.controller;
|
|||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import io.metersphere.base.domain.FileMetadata;
|
||||
import io.metersphere.base.domain.FileMetadataWithBLOBs;
|
||||
import io.metersphere.commons.constants.OperLogConstants;
|
||||
import io.metersphere.commons.constants.OperLogModule;
|
||||
import io.metersphere.commons.utils.PageUtils;
|
||||
|
@ -11,7 +12,10 @@ import io.metersphere.log.annotation.MsAuditLog;
|
|||
import io.metersphere.metadata.service.FileMetadataService;
|
||||
import io.metersphere.metadata.vo.DownloadRequest;
|
||||
import io.metersphere.metadata.vo.DumpFileRequest;
|
||||
import io.metersphere.metadata.vo.FileMetadataCreateRequest;
|
||||
import io.metersphere.metadata.vo.MoveFIleMetadataRequest;
|
||||
import io.metersphere.metadata.vo.repository.FileRelevanceCaseDTO;
|
||||
import io.metersphere.metadata.vo.repository.FileVersionDTO;
|
||||
import io.metersphere.performance.request.QueryProjectFileRequest;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
|
@ -34,21 +38,27 @@ public class FileMetadataController {
|
|||
}
|
||||
|
||||
@PostMapping("/project/{projectId}/{goPage}/{pageSize}")
|
||||
public Pager<List<FileMetadata>> getProjectFiles(@PathVariable String projectId,
|
||||
@PathVariable int goPage, @PathVariable int pageSize,
|
||||
@RequestBody QueryProjectFileRequest request) {
|
||||
public Pager<List<FileMetadataWithBLOBs>> getProjectFiles(@PathVariable String projectId,
|
||||
@PathVariable int goPage, @PathVariable int pageSize,
|
||||
@RequestBody QueryProjectFileRequest request) {
|
||||
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
|
||||
return PageUtils.setPageInfo(page, fileMetadataService.getProjectFiles(projectId, request));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/create")
|
||||
@MsAuditLog(module = OperLogModule.PROJECT_FILE_MANAGEMENT, type = OperLogConstants.CREATE, title = "#request.name", content = "#msClass.getLogDetails(#request.id)", msClass = FileMetadataService.class)
|
||||
public List<FileMetadata> create(@RequestPart("request") FileMetadata request, @RequestPart(value = "file", required = false) List<MultipartFile> files) {
|
||||
public List<FileMetadata> create(@RequestPart("request") FileMetadataCreateRequest request, @RequestPart(value = "file", required = false) List<MultipartFile> files) {
|
||||
return fileMetadataService.create(request, files);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/git/pull")
|
||||
@MsAuditLog(module = OperLogModule.PROJECT_FILE_MANAGEMENT, type = OperLogConstants.CREATE, title = "#request.name", content = "#msClass.getLogDetails(#request.id)", msClass = FileMetadataService.class)
|
||||
public FileMetadata pullFromRepository(@RequestPart("request") FileMetadata request) {
|
||||
return fileMetadataService.pullFromRepository(request);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/upload")
|
||||
public FileMetadata upload(@RequestPart("request") FileMetadata request, @RequestPart(value = "file", required = false) List<MultipartFile> files) {
|
||||
public FileMetadata upload(@RequestPart("request") FileMetadataWithBLOBs request, @RequestPart(value = "file", required = false) List<MultipartFile> files) {
|
||||
return fileMetadataService.reLoad(request, files);
|
||||
}
|
||||
|
||||
|
@ -94,7 +104,7 @@ public class FileMetadataController {
|
|||
|
||||
@PostMapping(value = "/update")
|
||||
@MsAuditLog(module = OperLogModule.PROJECT_FILE_MANAGEMENT, type = OperLogConstants.UPDATE, beforeEvent = "#msClass.getLogDetails(#request.id)", title = "#request.name", content = "#msClass.getLogDetails(#request.id)", msClass = FileMetadataService.class)
|
||||
public void update(@RequestBody FileMetadata request) {
|
||||
public void update(@RequestBody FileMetadataWithBLOBs request) {
|
||||
fileMetadataService.update(request);
|
||||
}
|
||||
|
||||
|
@ -117,4 +127,20 @@ public class FileMetadataController {
|
|||
public List<String> exist(@RequestBody List<String> fileIds) {
|
||||
return fileMetadataService.exists(fileIds);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/fileVersion/{refId}")
|
||||
public List<FileVersionDTO> selectFileVersion(@PathVariable String refId) {
|
||||
return fileMetadataService.selectFileVersion(refId);
|
||||
}
|
||||
|
||||
@PostMapping("/file/relevance/case/{refId}/{goPage}/{pageSize}")
|
||||
public Pager<List<FileRelevanceCaseDTO>> getFileRelevanceCase(@PathVariable String refId, @PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryProjectFileRequest request) {
|
||||
return fileMetadataService.getFileRelevanceCase(refId, goPage, pageSize);
|
||||
}
|
||||
|
||||
@PostMapping("/case/version/update/{refId}")
|
||||
public String updateCaseVersion(@PathVariable String refId, @RequestBody QueryProjectFileRequest request) {
|
||||
return fileMetadataService.updateCaseVersion(refId, request);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
package io.metersphere.metadata.controller;
|
||||
|
||||
import io.metersphere.base.domain.FileModule;
|
||||
import io.metersphere.commons.constants.FileModuleTypeConstants;
|
||||
import io.metersphere.commons.constants.OperLogConstants;
|
||||
import io.metersphere.commons.constants.OperLogModule;
|
||||
import io.metersphere.log.annotation.MsAuditLog;
|
||||
import io.metersphere.metadata.service.FileModuleService;
|
||||
import io.metersphere.metadata.utils.GitRepositoryUtils;
|
||||
import io.metersphere.metadata.vo.DragFileModuleRequest;
|
||||
import io.metersphere.metadata.vo.FileModuleVo;
|
||||
import io.metersphere.service.CheckPermissionService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
@ -34,6 +37,15 @@ public class FileModuleController {
|
|||
return fileModuleService.addNode(node);
|
||||
}
|
||||
|
||||
@PostMapping("/connect")
|
||||
public String connect(@RequestBody FileModule node) {
|
||||
if (StringUtils.equalsIgnoreCase(node.getModuleType(),FileModuleTypeConstants.REPOSITORY.getValue())){
|
||||
GitRepositoryUtils utils = new GitRepositoryUtils(node.getRepositoryPath(),node.getRepositoryUserName(),node.getRepositoryToken());
|
||||
utils.getBranches();
|
||||
}
|
||||
return "suucess";
|
||||
}
|
||||
|
||||
@PostMapping("/edit")
|
||||
@MsAuditLog(module = OperLogModule.PROJECT_FILE_MANAGEMENT, type = OperLogConstants.UPDATE, beforeEvent = "#msClass.getLogDetails(#node)", title = "#node.name", content = "#msClass.getLogDetails(#node)", msClass = FileModuleService.class)
|
||||
public int editNode(@RequestBody DragFileModuleRequest node) {
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package io.metersphere.metadata.repository;
|
||||
|
||||
import io.metersphere.metadata.vo.FileRequest;
|
||||
import io.metersphere.metadata.vo.repository.FileInfoDTO;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public interface FileRepository {
|
||||
String saveFile(MultipartFile file, FileRequest request) throws IOException;
|
||||
|
@ -14,6 +16,8 @@ public interface FileRepository {
|
|||
|
||||
byte[] getFile(FileRequest request) throws Exception;
|
||||
|
||||
List<FileInfoDTO> getFileBatch(List<FileRequest> requestList) throws Exception;
|
||||
|
||||
boolean reName(FileRequest request) throws Exception;
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
package io.metersphere.metadata.repository;
|
||||
|
||||
import io.metersphere.commons.constants.StorageConstants;
|
||||
import io.metersphere.metadata.utils.GitRepositoryUtils;
|
||||
import io.metersphere.metadata.utils.MetadataUtils;
|
||||
import io.metersphere.metadata.vo.FileRequest;
|
||||
import io.metersphere.metadata.vo.repository.FileInfoDTO;
|
||||
import io.metersphere.metadata.vo.repository.GitFileAttachInfo;
|
||||
import io.metersphere.metadata.vo.repository.RepositoryRequest;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class GitFileRepository implements FileRepository {
|
||||
@Override
|
||||
public String saveFile(MultipartFile multipartFile, FileRequest request) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String saveFile(byte[] bytes, FileRequest request) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(FileRequest request) throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getFile(FileRequest request) throws Exception {
|
||||
byte[] buffer = new byte[0];
|
||||
if (request.getFileAttachInfo() != null && request.getFileAttachInfo() instanceof GitFileAttachInfo) {
|
||||
GitFileAttachInfo gitFileInfo = (GitFileAttachInfo) request.getFileAttachInfo();
|
||||
GitRepositoryUtils repositoryUtils = new GitRepositoryUtils(
|
||||
gitFileInfo.getRepositoryPath(), gitFileInfo.getUserName(), gitFileInfo.getToken());
|
||||
buffer = repositoryUtils.getSingleFile(gitFileInfo.getFilePath(), gitFileInfo.getCommitId());
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FileInfoDTO> getFileBatch(List<FileRequest> allRequests) throws Exception {
|
||||
List<FileInfoDTO> list = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(allRequests)) {
|
||||
Map<String, List<FileRequest>> requestGroupByRepository = new HashMap<>();
|
||||
for (FileRequest request : allRequests) {
|
||||
if (request.getFileAttachInfo() != null && request.getFileAttachInfo() instanceof GitFileAttachInfo) {
|
||||
GitFileAttachInfo gitFileInfo = (GitFileAttachInfo) request.getFileAttachInfo();
|
||||
if (requestGroupByRepository.containsKey(gitFileInfo.getRepositoryInfo())) {
|
||||
requestGroupByRepository.get(gitFileInfo.getRepositoryInfo()).add(request);
|
||||
} else {
|
||||
requestGroupByRepository.put(gitFileInfo.getRepositoryInfo(), new ArrayList<>() {{
|
||||
this.add(request);
|
||||
}});
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Map.Entry<String, List<FileRequest>> entry : requestGroupByRepository.entrySet()) {
|
||||
List<FileRequest> requestList = entry.getValue();
|
||||
GitFileAttachInfo baseGitFileInfo = null;
|
||||
|
||||
List<RepositoryRequest> repositoryRequestList = new ArrayList<>();
|
||||
for (FileRequest fileRequest : requestList) {
|
||||
GitFileAttachInfo gitFileInfo = (GitFileAttachInfo) fileRequest.getFileAttachInfo();
|
||||
if (baseGitFileInfo == null) {
|
||||
baseGitFileInfo = gitFileInfo;
|
||||
}
|
||||
repositoryRequestList.add(new RepositoryRequest() {{
|
||||
this.setCommitId(gitFileInfo.getCommitId());
|
||||
this.setFilePath(gitFileInfo.getFilePath());
|
||||
this.setFileMetadataId(fileRequest.getResourceId());
|
||||
}});
|
||||
}
|
||||
|
||||
GitRepositoryUtils repositoryUtils = new GitRepositoryUtils(
|
||||
baseGitFileInfo.getRepositoryPath(), baseGitFileInfo.getUserName(), baseGitFileInfo.getToken());
|
||||
|
||||
|
||||
Map<String, byte[]> fileByteMap = repositoryUtils.getFiles(repositoryRequestList);
|
||||
repositoryRequestList.forEach(repositoryFile -> {
|
||||
if (fileByteMap.get(repositoryFile.getFileMetadataId()) != null) {
|
||||
FileInfoDTO repositoryFileDTO = new FileInfoDTO(
|
||||
repositoryFile.getFileMetadataId(), MetadataUtils.getFileNameByRemotePath(repositoryFile.getFilePath()), StorageConstants.GIT.name(), fileByteMap.get(repositoryFile.getFileMetadataId()));
|
||||
list.add(repositoryFileDTO);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reName(FileRequest request) throws Exception {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -5,11 +5,15 @@ import io.metersphere.commons.utils.FileUtils;
|
|||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.metadata.vo.FileRequest;
|
||||
import io.metersphere.metadata.vo.repository.FileInfoDTO;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.aspectj.util.FileUtil;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class LocalFileRepository implements FileRepository {
|
||||
@Override
|
||||
|
@ -80,6 +84,18 @@ public class LocalFileRepository implements FileRepository {
|
|||
return buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FileInfoDTO> getFileBatch(List<FileRequest> requestList) throws Exception {
|
||||
List<FileInfoDTO> list = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(requestList)) {
|
||||
for (FileRequest fileRequest : requestList) {
|
||||
FileInfoDTO fileInfoDTO = new FileInfoDTO(fileRequest.getResourceId(), fileRequest.getFileName(), fileRequest.getStorage(), this.getFile(fileRequest));
|
||||
list.add(fileInfoDTO);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reName(FileRequest request) throws Exception {
|
||||
File file = new File(StringUtils.join(FileUtils.BODY_FILE_DIR, "/", request.getProjectId(), "/", request.getBeforeName()));
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
package io.metersphere.metadata.repository;
|
||||
|
||||
import io.metersphere.metadata.vo.FileRequest;
|
||||
import io.metersphere.metadata.vo.repository.FileInfoDTO;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MinIOFileRepository implements FileRepository {
|
||||
|
||||
|
@ -27,6 +31,18 @@ public class MinIOFileRepository implements FileRepository {
|
|||
return new byte[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FileInfoDTO> getFileBatch(List<FileRequest> requestList) throws Exception {
|
||||
List<FileInfoDTO> list = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(requestList)) {
|
||||
for (FileRequest fileRequest : requestList) {
|
||||
FileInfoDTO fileInfoDTO = new FileInfoDTO(fileRequest.getResourceId(), fileRequest.getFileName(), fileRequest.getStorage(), this.getFile(fileRequest));
|
||||
list.add(fileInfoDTO);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reName(FileRequest request) throws Exception {
|
||||
return false;
|
||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.metadata.service;
|
|||
import io.metersphere.commons.constants.StorageConstants;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.metadata.repository.FileRepository;
|
||||
import io.metersphere.metadata.repository.GitFileRepository;
|
||||
import io.metersphere.metadata.repository.LocalFileRepository;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
|
@ -11,6 +12,9 @@ public class FileCenter {
|
|||
if (StringUtils.equals(StorageConstants.MINIO.name(), storage)) {
|
||||
LogUtil.info("NAS文件处理");
|
||||
return null;
|
||||
} else if (StringUtils.equals(StorageConstants.GIT.name(), storage)) {
|
||||
LogUtil.info("Git文件处理");
|
||||
return new GitFileRepository();
|
||||
} else {
|
||||
LogUtil.info("LOCAL文件处理");
|
||||
return new LocalFileRepository();
|
||||
|
|
|
@ -3,11 +3,17 @@ package io.metersphere.metadata.service;
|
|||
import io.metersphere.commons.constants.StorageConstants;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.metadata.vo.FileRequest;
|
||||
import io.metersphere.metadata.vo.repository.FileInfoDTO;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class FileManagerService {
|
||||
|
@ -79,4 +85,20 @@ public class FileManagerService {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public List<FileInfoDTO> downloadFileBatch(List<FileRequest> requestList) {
|
||||
List<FileInfoDTO> list = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(requestList)) {
|
||||
Map<String, List<FileRequest>> requestByStorage = requestList.stream().collect(Collectors.groupingBy(FileRequest::getStorage));
|
||||
for (Map.Entry<String, List<FileRequest>> requestByStorageEntry : requestByStorage.entrySet()) {
|
||||
try {
|
||||
list.addAll(FileCenter.getRepository(requestByStorageEntry.getKey()).getFileBatch(requestByStorageEntry.getValue()));
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,33 +1,40 @@
|
|||
package io.metersphere.metadata.service;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.nacos.common.utils.ByteUtils;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.*;
|
||||
import io.metersphere.base.mapper.ext.ExtFileMetadataMapper;
|
||||
import io.metersphere.commons.constants.ApiTestConstants;
|
||||
import io.metersphere.commons.constants.FileAssociationType;
|
||||
import io.metersphere.commons.constants.FileModuleTypeConstants;
|
||||
import io.metersphere.commons.constants.StorageConstants;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.FileUtils;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.controller.request.OrderRequest;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.log.utils.ReflexObjectUtil;
|
||||
import io.metersphere.log.vo.DetailColumn;
|
||||
import io.metersphere.log.vo.OperatingLogDetails;
|
||||
import io.metersphere.log.vo.system.SystemReference;
|
||||
import io.metersphere.metadata.utils.GitRepositoryUtils;
|
||||
import io.metersphere.metadata.utils.MetadataUtils;
|
||||
import io.metersphere.metadata.vo.DownloadRequest;
|
||||
import io.metersphere.metadata.vo.DumpFileRequest;
|
||||
import io.metersphere.metadata.vo.FileRequest;
|
||||
import io.metersphere.metadata.vo.MoveFIleMetadataRequest;
|
||||
import io.metersphere.metadata.vo.*;
|
||||
import io.metersphere.metadata.vo.repository.FileInfoDTO;
|
||||
import io.metersphere.metadata.vo.repository.FileRelevanceCaseDTO;
|
||||
import io.metersphere.metadata.vo.repository.FileVersionDTO;
|
||||
import io.metersphere.metadata.vo.repository.GitFileAttachInfo;
|
||||
import io.metersphere.performance.request.QueryProjectFileRequest;
|
||||
import io.metersphere.service.UserService;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
@ -53,24 +60,75 @@ public class FileMetadataService {
|
|||
private FileContentMapper fileContentMapper;
|
||||
@Resource
|
||||
private FileAssociationMapper fileAssociationMapper;
|
||||
@Resource
|
||||
private UserService userService;
|
||||
@Resource
|
||||
private ApiDefinitionMapper apiDefinitionMapper;
|
||||
@Resource
|
||||
private ApiTestCaseMapper apiTestCaseMapper;
|
||||
@Resource
|
||||
private ApiScenarioMapper apiScenarioMapper;
|
||||
@Resource
|
||||
private TestCaseMapper testCaseMapper;
|
||||
|
||||
public List<FileMetadata> create(FileMetadata fileMetadata, List<MultipartFile> files) {
|
||||
public List<FileMetadata> create(FileMetadataCreateRequest fileMetadata, List<MultipartFile> files) {
|
||||
List<FileMetadata> result = new ArrayList<>();
|
||||
if (fileMetadata == null) {
|
||||
fileMetadata = new FileMetadata();
|
||||
fileMetadata = new FileMetadataCreateRequest();
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(files)) {
|
||||
if (StringUtils.equals(StorageConstants.GIT.name(), fileMetadata.getStorage())) {
|
||||
fileMetadata.setPath(StringUtils.trim(fileMetadata.getPath()));
|
||||
this.validateGitFile(fileMetadata);
|
||||
FileModule fileModule = fileModuleService.get(fileMetadata.getModuleId());
|
||||
GitRepositoryUtils repositoryUtils = new GitRepositoryUtils(
|
||||
fileModule.getRepositoryPath(), fileModule.getRepositoryUserName(), fileModule.getRepositoryToken());
|
||||
GitFileAttachInfo gitFileInfo = repositoryUtils.selectLastCommitIdByBranch(fileMetadata.getRepositoryBranch(), fileMetadata.getRepositoryPath());
|
||||
if (gitFileInfo != null) {
|
||||
fileMetadata.setName(MetadataUtils.getFileNameByRemotePath(fileMetadata.getRepositoryPath()));
|
||||
fileMetadata.setType(MetadataUtils.getFileType(fileMetadata.getRepositoryPath()));
|
||||
fileMetadata.setPath(fileMetadata.getRepositoryPath());
|
||||
fileMetadata.setSize(Long.valueOf(0));
|
||||
fileMetadata.setAttachInfo(JSONObject.toJSONString(gitFileInfo));
|
||||
result.add(this.save(fileMetadata));
|
||||
} else {
|
||||
MSException.throwException("File not found!");
|
||||
}
|
||||
} else if (!CollectionUtils.isEmpty(files)) {
|
||||
for (MultipartFile file : files) {
|
||||
QueryProjectFileRequest request = new QueryProjectFileRequest();
|
||||
request.setName(file.getOriginalFilename());
|
||||
result.add(this.saveFile(file, fileMetadata));
|
||||
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public FileMetadata saveFile(MultipartFile file, FileMetadata fileMetadata) {
|
||||
private void validateGitFile(FileMetadataCreateRequest fileMetadata) {
|
||||
if (StringUtils.isEmpty(fileMetadata.getModuleId())) {
|
||||
MSException.throwException(Translator.get("test_case_module_not_null"));
|
||||
} else {
|
||||
FileMetadataExample example = new FileMetadataExample();
|
||||
example.createCriteria().andModuleIdEqualTo(fileMetadata.getModuleId())
|
||||
.andStorageEqualTo(fileMetadata.getStorage())
|
||||
.andPathEqualTo(fileMetadata.getRepositoryPath())
|
||||
.andIdNotEqualTo(fileMetadata.getId());
|
||||
if (fileMetadataMapper.countByExample(example) > 0) {
|
||||
MSException.throwException(Translator.get("project_file_already_exists"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public FileMetadata save(FileMetadataWithBLOBs fileMetadata) {
|
||||
long createTime = System.currentTimeMillis();
|
||||
fileMetadata.setCreateTime(createTime);
|
||||
fileMetadata.setUpdateTime(createTime);
|
||||
fileMetadata.setLatest(true);
|
||||
fileMetadata.setRefId(fileMetadata.getId());
|
||||
fileMetadataMapper.insert(fileMetadata);
|
||||
return fileMetadata;
|
||||
}
|
||||
|
||||
public FileMetadata saveFile(MultipartFile file, FileMetadataWithBLOBs fileMetadata) {
|
||||
this.initBase(fileMetadata);
|
||||
if (StringUtils.isEmpty(fileMetadata.getName())) {
|
||||
fileMetadata.setName(file.getOriginalFilename());
|
||||
|
@ -84,6 +142,8 @@ public class FileMetadataService {
|
|||
String path = fileManagerService.upload(file, request);
|
||||
fileMetadata.setPath(path);
|
||||
if (fileMetadataMapper.selectByPrimaryKey(fileMetadata.getId()) == null) {
|
||||
fileMetadata.setLatest(true);
|
||||
fileMetadata.setRefId(fileMetadata.getId());
|
||||
fileMetadataMapper.insert(fileMetadata);
|
||||
} else {
|
||||
fileMetadataMapper.updateByPrimaryKeyWithBLOBs(fileMetadata);
|
||||
|
@ -94,12 +154,12 @@ public class FileMetadataService {
|
|||
|
||||
|
||||
public FileMetadata saveFile(MultipartFile file, String projectId) {
|
||||
FileMetadata fileMetadata = new FileMetadata();
|
||||
FileMetadataWithBLOBs fileMetadata = new FileMetadataWithBLOBs();
|
||||
fileMetadata.setProjectId(projectId);
|
||||
return saveFile(file, fileMetadata);
|
||||
}
|
||||
|
||||
public List<FileMetadata> getProjectFiles(String projectId, QueryProjectFileRequest request) {
|
||||
public List<FileMetadataWithBLOBs> getProjectFiles(String projectId, QueryProjectFileRequest request) {
|
||||
if (CollectionUtils.isEmpty(request.getOrders())) {
|
||||
OrderRequest req = new OrderRequest();
|
||||
req.setName("update_time");
|
||||
|
@ -108,7 +168,8 @@ public class FileMetadataService {
|
|||
this.add(req);
|
||||
}});
|
||||
}
|
||||
return extFileMetadataMapper.getProjectFiles(projectId, request);
|
||||
List<FileMetadataWithBLOBs> fileMetadataList = extFileMetadataMapper.getProjectFiles(projectId, request);
|
||||
return fileMetadataList;
|
||||
}
|
||||
|
||||
public void deleteFile(String fileId) {
|
||||
|
@ -136,6 +197,14 @@ public class FileMetadataService {
|
|||
// 删除文件,历史遗留数据保留附件只删除关系
|
||||
FileMetadata fileMetadata = fileMetadataMapper.selectByPrimaryKey(fileId);
|
||||
fileMetadataMapper.deleteByPrimaryKey(fileId);
|
||||
|
||||
if (StringUtils.isNotEmpty(fileMetadata.getRefId())) {
|
||||
//删除其余版本的文件
|
||||
FileMetadataExample fileMetadataExample = new FileMetadataExample();
|
||||
fileMetadataExample.createCriteria().andRefIdEqualTo(fileMetadata.getRefId());
|
||||
fileMetadataMapper.deleteByExample(fileMetadataExample);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotEmpty(fileMetadata.getStorage()) && StringUtils.isEmpty(fileMetadata.getResourceType())) {
|
||||
FileRequest request = new FileRequest(fileMetadata.getProjectId(), fileMetadata.getName(), fileMetadata.getType());
|
||||
fileManagerService.delete(request);
|
||||
|
@ -155,8 +224,14 @@ public class FileMetadataService {
|
|||
}
|
||||
|
||||
public void move(MoveFIleMetadataRequest request) {
|
||||
if (!CollectionUtils.isEmpty(request.getMetadataIds()) && StringUtils.isNotEmpty(request.getModuleId())) {
|
||||
extFileMetadataMapper.move(request);
|
||||
//不可移动到存储库模块节点
|
||||
FileModule fileModule = fileModuleService.get(request.getModuleId());
|
||||
if (fileModule != null && !CollectionUtils.isEmpty(request.getMetadataIds()) && StringUtils.isNotEmpty(request.getModuleId())) {
|
||||
if (StringUtils.equals(fileModule.getModuleType(), FileModuleTypeConstants.REPOSITORY.getValue())) {
|
||||
MSException.throwException(Translator.get("can_not_move_to_repository_node"));
|
||||
} else {
|
||||
extFileMetadataMapper.move(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,14 +244,14 @@ public class FileMetadataService {
|
|||
}
|
||||
|
||||
public byte[] loadFileAsBytes(String id) {
|
||||
FileMetadata fileMetadata = fileMetadataMapper.selectByPrimaryKey(id);
|
||||
FileMetadataWithBLOBs fileMetadata = fileMetadataMapper.selectByPrimaryKey(id);
|
||||
if (fileMetadata == null) {
|
||||
return new byte[0];
|
||||
}
|
||||
return this.loadFileAsBytes(fileMetadata);
|
||||
}
|
||||
|
||||
private byte[] loadFileAsBytes(FileMetadata fileMetadata) {
|
||||
private byte[] loadFileAsBytes(FileMetadataWithBLOBs fileMetadata) {
|
||||
byte[] bytes = new byte[0];
|
||||
// 兼容历史数据
|
||||
if (StringUtils.isEmpty(fileMetadata.getStorage()) && StringUtils.isEmpty(fileMetadata.getResourceType())) {
|
||||
|
@ -186,6 +261,8 @@ public class FileMetadataService {
|
|||
FileRequest request = new FileRequest(fileMetadata.getProjectId(), fileMetadata.getName(), fileMetadata.getType());
|
||||
request.setResourceType(fileMetadata.getResourceType());
|
||||
request.setPath(fileMetadata.getPath());
|
||||
request.setStorage(fileMetadata.getStorage());
|
||||
request.setFileAttachInfoByString(fileMetadata.getAttachInfo());
|
||||
bytes = fileManagerService.downloadFile(request);
|
||||
}
|
||||
return bytes;
|
||||
|
@ -193,7 +270,7 @@ public class FileMetadataService {
|
|||
|
||||
public ResponseEntity<byte[]> getFile(String fileId) {
|
||||
MediaType contentType = MediaType.parseMediaType("application/octet-stream");
|
||||
FileMetadata fileMetadata = fileMetadataMapper.selectByPrimaryKey(fileId);
|
||||
FileMetadataWithBLOBs fileMetadata = fileMetadataMapper.selectByPrimaryKey(fileId);
|
||||
if (fileMetadata == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -233,7 +310,7 @@ public class FileMetadataService {
|
|||
return fileMetadataMapper.selectByPrimaryKey(fileMetadata.getId()).getName();
|
||||
}
|
||||
|
||||
public void update(FileMetadata fileMetadata) {
|
||||
public void update(FileMetadataWithBLOBs fileMetadata) {
|
||||
this.checkName(fileMetadata);
|
||||
String beforeName = getBeforeName(fileMetadata);
|
||||
if (!StringUtils.equalsIgnoreCase(beforeName, fileMetadata.getName())
|
||||
|
@ -252,7 +329,7 @@ public class FileMetadataService {
|
|||
fileMetadataMapper.updateByPrimaryKeySelective(fileMetadata);
|
||||
}
|
||||
|
||||
public FileMetadata reLoad(FileMetadata fileMetadata, List<MultipartFile> files) {
|
||||
public FileMetadata reLoad(FileMetadataWithBLOBs fileMetadata, List<MultipartFile> files) {
|
||||
if (CollectionUtils.isEmpty(files)) {
|
||||
return fileMetadata;
|
||||
}
|
||||
|
@ -284,7 +361,7 @@ public class FileMetadataService {
|
|||
public List<FileMetadata> uploadFiles(String projectId, List<MultipartFile> files) {
|
||||
List<FileMetadata> result = new ArrayList<>();
|
||||
if (!CollectionUtils.isEmpty(files)) {
|
||||
FileMetadata fileMetadata = new FileMetadata();
|
||||
FileMetadataWithBLOBs fileMetadata = new FileMetadataWithBLOBs();
|
||||
fileMetadata.setProjectId(projectId);
|
||||
fileMetadata.setStorage(StorageConstants.LOCAL.name());
|
||||
files.forEach(file -> {
|
||||
|
@ -301,7 +378,7 @@ public class FileMetadataService {
|
|||
}
|
||||
|
||||
public FileMetadata updateFile(String fileId, MultipartFile file) {
|
||||
FileMetadata fileMetadata = fileMetadataMapper.selectByPrimaryKey(fileId);
|
||||
FileMetadataWithBLOBs fileMetadata = fileMetadataMapper.selectByPrimaryKey(fileId);
|
||||
reLoad(fileMetadata, new ArrayList<>() {{
|
||||
this.add(file);
|
||||
}});
|
||||
|
@ -325,7 +402,7 @@ public class FileMetadataService {
|
|||
this.saveFile(file);
|
||||
}
|
||||
} else {
|
||||
FileMetadata fileMetadata = new FileMetadata();
|
||||
FileMetadataCreateRequest fileMetadata = new FileMetadataCreateRequest();
|
||||
fileMetadata.setProjectId(request.getProjectId());
|
||||
fileMetadata.setModuleId(request.getModuleId());
|
||||
this.create(fileMetadata, files);
|
||||
|
@ -386,7 +463,7 @@ public class FileMetadataService {
|
|||
}
|
||||
|
||||
public FileMetadata saveFile(byte[] fileByte, String fileName, Long fileSize) {
|
||||
final FileMetadata fileMetadata = new FileMetadata();
|
||||
final FileMetadataWithBLOBs fileMetadata = new FileMetadataWithBLOBs();
|
||||
this.initBase(fileMetadata);
|
||||
fileMetadata.setName(fileName);
|
||||
fileMetadata.setSize(fileSize);
|
||||
|
@ -396,6 +473,8 @@ public class FileMetadataService {
|
|||
FileRequest request = new FileRequest(fileMetadata.getProjectId(), fileMetadata.getName(), fileMetadata.getType());
|
||||
String path = fileManagerService.upload(fileByte, request);
|
||||
fileMetadata.setPath(path);
|
||||
fileMetadata.setLatest(true);
|
||||
fileMetadata.setRefId(fileMetadata.getId());
|
||||
fileMetadataMapper.insert(fileMetadata);
|
||||
return fileMetadata;
|
||||
}
|
||||
|
@ -440,4 +519,207 @@ public class FileMetadataService {
|
|||
List<FileMetadata> fileMetadataList = fileMetadataMapper.selectByExample(example);
|
||||
return fileMetadataList.stream().map(FileMetadata::getId).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<FileInfoDTO> downloadFileByIds(Collection<String> fileIdList) {
|
||||
if (CollectionUtils.isEmpty(fileIdList)) {
|
||||
return new ArrayList<>(0);
|
||||
}
|
||||
LogUtil.info(JSONObject.toJSONString(fileIdList) + " 获取文件开始");
|
||||
|
||||
FileMetadataExample example = new FileMetadataExample();
|
||||
example.createCriteria().andIdIn(new ArrayList<>(fileIdList));
|
||||
List<FileMetadataWithBLOBs> fileMetadataWithBLOBs = fileMetadataMapper.selectByExampleWithBLOBs(example);
|
||||
|
||||
List<FileRequest> requestList = new ArrayList<>();
|
||||
fileMetadataWithBLOBs.forEach(fileMetadata -> {
|
||||
FileRequest request = new FileRequest(fileMetadata.getProjectId(), fileMetadata.getName(), fileMetadata.getType());
|
||||
request.setResourceId(fileMetadata.getId());
|
||||
request.setResourceType(fileMetadata.getResourceType());
|
||||
request.setPath(fileMetadata.getPath());
|
||||
request.setStorage(fileMetadata.getStorage());
|
||||
if (StringUtils.equals(fileMetadata.getStorage(), StorageConstants.GIT.name())) {
|
||||
try {
|
||||
GitFileAttachInfo gitFileInfo = JSONObject.parseObject(fileMetadata.getAttachInfo(), GitFileAttachInfo.class);
|
||||
request.setFileAttachInfo(gitFileInfo);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("解析Git附加信息【" + fileMetadata.getAttachInfo() + "】失败!", e);
|
||||
}
|
||||
}
|
||||
requestList.add(request);
|
||||
});
|
||||
|
||||
List<FileInfoDTO> repositoryFileDTOList = fileManagerService.downloadFileBatch(requestList);
|
||||
LogUtil.info(JSONObject.toJSONString(fileIdList) + " 获取文件结束。");
|
||||
return repositoryFileDTOList;
|
||||
}
|
||||
|
||||
public FileMetadata pullFromRepository(FileMetadata request) {
|
||||
FileMetadata returnModel = null;
|
||||
FileMetadataWithBLOBs baseMetadata = fileMetadataMapper.selectByPrimaryKey(request.getId());
|
||||
if (StringUtils.equals(baseMetadata.getStorage(), StorageConstants.GIT.name()) && StringUtils.isNotEmpty(baseMetadata.getAttachInfo())) {
|
||||
GitFileAttachInfo baseAttachInfo = JSONObject.parseObject(baseMetadata.getAttachInfo(), GitFileAttachInfo.class);
|
||||
FileModule fileModule = fileModuleService.get(baseMetadata.getModuleId());
|
||||
if (fileModule != null) {
|
||||
GitRepositoryUtils repositoryUtils = new GitRepositoryUtils(fileModule.getRepositoryPath(), fileModule.getRepositoryUserName(), fileModule.getRepositoryToken());
|
||||
GitFileAttachInfo gitFileAttachInfo = repositoryUtils.selectLastCommitIdByBranch(baseAttachInfo.getBranch(), baseAttachInfo.getFilePath());
|
||||
if (gitFileAttachInfo != null &&
|
||||
!StringUtils.equals(gitFileAttachInfo.getCommitId(), baseAttachInfo.getCommitId())) {
|
||||
//有新的commitId,更新filemetadata的版本
|
||||
long thistime = System.currentTimeMillis();
|
||||
FileMetadataWithBLOBs newMetadata = this.genOtherVersionFileMetadata(baseMetadata, thistime, gitFileAttachInfo);
|
||||
fileMetadataMapper.insert(newMetadata);
|
||||
|
||||
baseMetadata.setUpdateTime(thistime);
|
||||
baseMetadata.setLatest(false);
|
||||
baseMetadata.setUpdateUser(SessionUtils.getUserId());
|
||||
fileMetadataMapper.updateByPrimaryKeySelective(baseMetadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnModel;
|
||||
}
|
||||
|
||||
private FileMetadataWithBLOBs genOtherVersionFileMetadata(FileMetadataWithBLOBs baseMetadata, long operationTime, GitFileAttachInfo gitFileAttachInfo) {
|
||||
FileMetadataWithBLOBs newMetadata = new FileMetadataWithBLOBs();
|
||||
newMetadata.setDescription(baseMetadata.getDescription());
|
||||
newMetadata.setId(UUID.randomUUID().toString());
|
||||
newMetadata.setAttachInfo(JSONObject.toJSONString(gitFileAttachInfo));
|
||||
newMetadata.setName(baseMetadata.getName());
|
||||
newMetadata.setType(baseMetadata.getType());
|
||||
newMetadata.setSize(baseMetadata.getSize());
|
||||
newMetadata.setCreateTime(operationTime);
|
||||
newMetadata.setUpdateTime(operationTime);
|
||||
newMetadata.setStorage(baseMetadata.getStorage());
|
||||
newMetadata.setCreateUser(SessionUtils.getUserId());
|
||||
newMetadata.setProjectId(baseMetadata.getProjectId());
|
||||
newMetadata.setUpdateUser(SessionUtils.getUserId());
|
||||
newMetadata.setTags(baseMetadata.getTags());
|
||||
newMetadata.setLoadJar(baseMetadata.getLoadJar());
|
||||
newMetadata.setModuleId(baseMetadata.getModuleId());
|
||||
newMetadata.setPath(baseMetadata.getPath());
|
||||
newMetadata.setResourceType(baseMetadata.getResourceType());
|
||||
newMetadata.setRefId(baseMetadata.getRefId());
|
||||
newMetadata.setLatest(true);
|
||||
return newMetadata;
|
||||
}
|
||||
|
||||
public List<FileVersionDTO> selectFileVersion(String refId) {
|
||||
List<FileVersionDTO> returnList = new ArrayList<>();
|
||||
if (StringUtils.isNotBlank(refId)) {
|
||||
FileMetadataExample example = new FileMetadataExample();
|
||||
example.createCriteria().andRefIdEqualTo(refId);
|
||||
List<FileMetadataWithBLOBs> fileMetadataList = this.fileMetadataMapper.selectByExampleWithBLOBs(example);
|
||||
fileMetadataList.sort(Comparator.comparing(FileMetadataWithBLOBs::getCreateTime).reversed());
|
||||
for (FileMetadataWithBLOBs fileMetadata : fileMetadataList) {
|
||||
try {
|
||||
if (StringUtils.isNotBlank(fileMetadata.getAttachInfo())) {
|
||||
GitFileAttachInfo gitFileAttachInfo = JSONObject.parseObject(fileMetadata.getAttachInfo(), GitFileAttachInfo.class);
|
||||
User user = userService.selectById(fileMetadata.getCreateUser());
|
||||
FileVersionDTO dto = new FileVersionDTO(fileMetadata.getId(), gitFileAttachInfo.getCommitId(), gitFileAttachInfo.getCommitMessage(),
|
||||
user == null ? fileMetadata.getCreateUser() : user.getName(), fileMetadata.getCreateTime());
|
||||
returnList.add(dto);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("解析多版本下fileMetadata的attachInfo出错!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public Pager<List<FileRelevanceCaseDTO>> getFileRelevanceCase(String refId, int goPage, int pageSize) {
|
||||
List<FileRelevanceCaseDTO> list = new ArrayList<>();
|
||||
Page<Object> page = null;
|
||||
if (StringUtils.isNotBlank(refId)) {
|
||||
FileMetadataExample fileMetadataExample = new FileMetadataExample();
|
||||
fileMetadataExample.createCriteria().andRefIdEqualTo(refId);
|
||||
List<FileMetadataWithBLOBs> fileMetadataWithBLOBsList = fileMetadataMapper.selectByExampleWithBLOBs(fileMetadataExample);
|
||||
if (CollectionUtils.isNotEmpty(fileMetadataWithBLOBsList)) {
|
||||
Map<String, String> fileCommitIdMap = new HashMap<>();
|
||||
fileMetadataWithBLOBsList.forEach(item -> {
|
||||
if (StringUtils.isNotBlank(item.getAttachInfo()) && StringUtils.equals(item.getStorage(), StorageConstants.GIT.name())) {
|
||||
try {
|
||||
GitFileAttachInfo info = JSONObject.parseObject(item.getAttachInfo(), GitFileAttachInfo.class);
|
||||
fileCommitIdMap.put(item.getId(), info.getCommitId());
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("解析Git attachInfo失败!", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
page = PageHelper.startPage(goPage, pageSize, true);
|
||||
FileAssociationExample associationExample = new FileAssociationExample();
|
||||
associationExample.createCriteria().andFileMetadataIdIn(new ArrayList<>(fileCommitIdMap.keySet())).andTypeIn(new ArrayList<>() {{
|
||||
this.add(FileAssociationType.API.name());
|
||||
this.add(FileAssociationType.CASE.name());
|
||||
this.add(FileAssociationType.SCENARIO.name());
|
||||
this.add("TEST_CASE");
|
||||
}});
|
||||
List<FileAssociation> fileAssociationList = fileAssociationMapper.selectByExample(associationExample);
|
||||
for (FileAssociation fileAssociation : fileAssociationList) {
|
||||
String caseId = null;
|
||||
String caseName = null;
|
||||
if (StringUtils.equals(fileAssociation.getType(), FileAssociationType.API.name())) {
|
||||
ApiDefinition apiDefinition = apiDefinitionMapper.selectByPrimaryKey(fileAssociation.getSourceId());
|
||||
if (apiDefinition != null) {
|
||||
caseId = apiDefinition.getNum() == null ? "" : apiDefinition.getNum().toString();
|
||||
caseName = apiDefinition.getName();
|
||||
}
|
||||
} else if (StringUtils.equals(fileAssociation.getType(), FileAssociationType.CASE.name())) {
|
||||
ApiTestCase testCase = apiTestCaseMapper.selectByPrimaryKey(fileAssociation.getSourceId());
|
||||
if (testCase != null) {
|
||||
caseId = testCase.getNum() == null ? "" : testCase.getNum().toString();
|
||||
caseName = testCase.getName();
|
||||
}
|
||||
} else if (StringUtils.equals(fileAssociation.getType(), FileAssociationType.SCENARIO.name())) {
|
||||
ApiScenario testCase = apiScenarioMapper.selectByPrimaryKey(fileAssociation.getSourceId());
|
||||
if (testCase != null) {
|
||||
caseId = testCase.getNum() == null ? "" : testCase.getNum().toString();
|
||||
caseName = testCase.getName();
|
||||
}
|
||||
} else if (StringUtils.equals(fileAssociation.getType(), "TEST_CASE")) {
|
||||
TestCase testCase = testCaseMapper.selectByPrimaryKey(fileAssociation.getSourceId());
|
||||
if (testCase != null) {
|
||||
caseId = testCase.getNum() == null ? "" : testCase.getNum().toString();
|
||||
caseName = testCase.getName();
|
||||
}
|
||||
}
|
||||
|
||||
if (!StringUtils.isAllBlank(caseId, caseName)) {
|
||||
FileRelevanceCaseDTO dto = new FileRelevanceCaseDTO(fileAssociation.getId(), caseId, caseName, fileAssociation.getType(), fileCommitIdMap.get(fileAssociation.getFileMetadataId()));
|
||||
list.add(dto);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (page == null) {
|
||||
page = new Page<>(goPage, pageSize);
|
||||
}
|
||||
|
||||
//排序一下
|
||||
list.sort(Comparator.comparing(FileRelevanceCaseDTO::getCaseName));
|
||||
return PageUtils.setPageInfo(page, list);
|
||||
}
|
||||
|
||||
public String updateCaseVersion(String refId, QueryProjectFileRequest request) {
|
||||
String returnString = "";
|
||||
if (CollectionUtils.isNotEmpty(request.getIds())) {
|
||||
FileMetadataExample example = new FileMetadataExample();
|
||||
example.createCriteria().andRefIdEqualTo(refId).andLatestEqualTo(true);
|
||||
List<FileMetadata> fileMetadataList = fileMetadataMapper.selectByExample(example);
|
||||
if (CollectionUtils.isNotEmpty(fileMetadataList)) {
|
||||
String latestId = fileMetadataList.get(0).getId();
|
||||
|
||||
FileAssociationExample associationExample = new FileAssociationExample();
|
||||
associationExample.createCriteria().andIdIn(request.getIds());
|
||||
|
||||
FileAssociation fileAssociation = new FileAssociation();
|
||||
fileAssociation.setFileMetadataId(latestId);
|
||||
|
||||
int updateCount = fileAssociationMapper.updateByExampleSelective(fileAssociation, associationExample);
|
||||
returnString = String.valueOf(updateCount);
|
||||
}
|
||||
}
|
||||
return returnString;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import io.metersphere.base.mapper.FileModuleMapper;
|
|||
import io.metersphere.base.mapper.ext.ExtFileMetadataMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtFileModuleMapper;
|
||||
import io.metersphere.commons.constants.ApiTestConstants;
|
||||
import io.metersphere.commons.constants.FileModuleTypeConstants;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
|
@ -198,6 +199,13 @@ public class FileModuleService extends NodeTreeService<FileModuleVo> {
|
|||
if (fileModuleMapper.selectByExample(example).size() > 0) {
|
||||
MSException.throwException(Translator.get("test_case_module_already_exists") + ": " + node.getName());
|
||||
}
|
||||
if (StringUtils.equalsIgnoreCase(node.getModuleType(), FileModuleTypeConstants.REPOSITORY.getValue())) {
|
||||
example.clear();
|
||||
criteria.andNameEqualTo(node.getName()).andProjectIdEqualTo(node.getProjectId()).andModuleTypeEqualTo(FileModuleTypeConstants.REPOSITORY.getValue());
|
||||
if (fileModuleMapper.selectByExample(example).size() > 0) {
|
||||
MSException.throwException(Translator.get("repository_module_already_exists") + ": " + node.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -226,11 +234,19 @@ public class FileModuleService extends NodeTreeService<FileModuleVo> {
|
|||
|
||||
public int deleteNode(List<String> nodeIds) {
|
||||
if (CollectionUtils.isNotEmpty(nodeIds)) {
|
||||
List<String> refIdList = extFileMetadataMapper.selectRefIdsByIds(nodeIds);
|
||||
//删除文件
|
||||
FileMetadataExample example = new FileMetadataExample();
|
||||
example.createCriteria().andModuleIdIn(nodeIds);
|
||||
fileMetadataMapper.deleteByExample(example);
|
||||
|
||||
if (CollectionUtils.isNotEmpty(refIdList)) {
|
||||
//删除其余版本的文件
|
||||
example.clear();
|
||||
example.createCriteria().andRefIdIn(refIdList);
|
||||
fileMetadataMapper.deleteByExample(example);
|
||||
}
|
||||
|
||||
FileModuleExample apiDefinitionNodeExample = new FileModuleExample();
|
||||
apiDefinitionNodeExample.createCriteria().andIdIn(nodeIds);
|
||||
return fileModuleMapper.deleteByExample(apiDefinitionNodeExample);
|
||||
|
@ -387,5 +403,4 @@ public class FileModuleService extends NodeTreeService<FileModuleVo> {
|
|||
public String getModuleNameById(String moduleId) {
|
||||
return extFileModuleMapper.getNameById(moduleId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,197 @@
|
|||
package io.metersphere.metadata.utils;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.metadata.vo.repository.GitFileAttachInfo;
|
||||
import io.metersphere.metadata.vo.repository.RepositoryRequest;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
|
||||
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.ObjectLoader;
|
||||
import org.eclipse.jgit.lib.Ref;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.revwalk.RevTree;
|
||||
import org.eclipse.jgit.revwalk.RevWalk;
|
||||
import org.eclipse.jgit.transport.CredentialsProvider;
|
||||
import org.eclipse.jgit.transport.RefSpec;
|
||||
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
|
||||
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||
import org.eclipse.jgit.treewalk.filter.PathFilter;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class GitRepositoryUtils {
|
||||
private final String REF_SPACE = "+refs/heads/*:refs/heads/*";
|
||||
private final String DEFAULT_GIT_USERNAME = "PRIVATE-TOKEN";
|
||||
|
||||
private String repositoryUrl;
|
||||
private String userName;
|
||||
private String token;
|
||||
|
||||
private Git git;
|
||||
|
||||
public GitRepositoryUtils(String repositoryUrl, String userName, String token) {
|
||||
this.repositoryUrl = StringUtils.trim(repositoryUrl);
|
||||
if (StringUtils.isNotBlank(userName)) {
|
||||
this.userName = StringUtils.trim(userName);
|
||||
} else {
|
||||
this.userName = this.DEFAULT_GIT_USERNAME;
|
||||
}
|
||||
this.token = StringUtils.trim(token);
|
||||
LogUtil.info("初始化文件库完成. repositoryUrl:" + repositoryUrl + "; userName:" + userName + "; token:" + token);
|
||||
}
|
||||
|
||||
public byte[] getSingleFile(String filePath, String commitId) throws Exception {
|
||||
LogUtil.info("准备获取文件. repositoryUrl:" + repositoryUrl + "; filePath:" + filePath + "; commitId:" + commitId);
|
||||
InMemoryRepository repo = this.getGitRepositoryInMemory(repositoryUrl, userName, token);
|
||||
ObjectId fileCommitObjectId = repo.resolve(commitId);
|
||||
RevWalk revWalk = new RevWalk(repo);
|
||||
RevCommit commit = revWalk.parseCommit(fileCommitObjectId);
|
||||
RevTree tree = commit.getTree();
|
||||
TreeWalk treeWalk = new TreeWalk(repo);
|
||||
treeWalk.addTree(tree);
|
||||
treeWalk.setRecursive(true);
|
||||
treeWalk.setFilter(PathFilter.create(filePath));
|
||||
if (!treeWalk.next()) {
|
||||
LogUtil.info("未获取到文件!. repositoryUrl:" + repositoryUrl + "; filePath:" + filePath + "; commitId:" + commitId);
|
||||
return null;
|
||||
}
|
||||
ObjectId objectId = treeWalk.getObjectId(0);
|
||||
ObjectLoader loader = repo.open(objectId);
|
||||
byte[] returnBytes = loader.getBytes();
|
||||
this.closeConnection(repo);
|
||||
return returnBytes;
|
||||
}
|
||||
|
||||
public Map<String, byte[]> getFiles(List<RepositoryRequest> repositoryRequestList) throws Exception {
|
||||
Map<String, byte[]> returnMap = new HashMap<>();
|
||||
if (CollectionUtils.isEmpty(repositoryRequestList)) {
|
||||
return returnMap;
|
||||
}
|
||||
Map<String, List<RepositoryRequest>> commitIdFilePathMap = repositoryRequestList.stream().collect(Collectors.groupingBy(RepositoryRequest::getCommitId));
|
||||
LogUtil.info("准备批量获取文件. repositoryUrl:" + repositoryUrl + "; commitIdFilePathMap:" + JSONObject.toJSONString(repositoryRequestList));
|
||||
InMemoryRepository repo = this.getGitRepositoryInMemory(repositoryUrl, userName, token);
|
||||
ObjectId fileCommitObjectId = null;
|
||||
for (Map.Entry<String, List<RepositoryRequest>> commitFilePathEntry : commitIdFilePathMap.entrySet()) {
|
||||
String commitId = commitFilePathEntry.getKey();
|
||||
List<RepositoryRequest> itemRequestList = commitFilePathEntry.getValue();
|
||||
for (RepositoryRequest repositoryRequest : itemRequestList) {
|
||||
String filePath = repositoryRequest.getFilePath();
|
||||
fileCommitObjectId = repo.resolve(commitId);
|
||||
RevWalk revWalk = new RevWalk(repo);
|
||||
RevCommit commit = revWalk.parseCommit(fileCommitObjectId);
|
||||
RevTree tree = commit.getTree();
|
||||
TreeWalk treeWalk = new TreeWalk(repo);
|
||||
treeWalk.addTree(tree);
|
||||
treeWalk.setRecursive(true);
|
||||
treeWalk.setFilter(PathFilter.create(filePath));
|
||||
if (!treeWalk.next()) {
|
||||
LogUtil.info("未获取到文件!. repositoryUrl:" + repositoryUrl + "; filePath:" + filePath + "; commitId:" + commitId);
|
||||
continue;
|
||||
}
|
||||
ObjectId objectId = treeWalk.getObjectId(0);
|
||||
ObjectLoader loader = repo.open(objectId);
|
||||
returnMap.put(repositoryRequest.getFileMetadataId(), loader.getBytes());
|
||||
}
|
||||
this.closeConnection(repo);
|
||||
}
|
||||
LogUtil.info("准备批量获取文件结束. repositoryUrl:" + repositoryUrl);
|
||||
return returnMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件的commitId
|
||||
*
|
||||
* @param branch
|
||||
* @return 文件存在,返回对应的commitid
|
||||
* @throws Exception 文件不存在的时候报错
|
||||
*/
|
||||
public GitFileAttachInfo selectLastCommitIdByBranch(String branch, String filePath) {
|
||||
GitFileAttachInfo attachInfo = null;
|
||||
this.validateParams(repositoryUrl, branch, userName, token);
|
||||
InMemoryRepository repo = null;
|
||||
try {
|
||||
repo = this.getGitRepositoryInMemory(repositoryUrl, userName, token);
|
||||
ObjectId fileCommitId = repo.resolve("refs/heads/" + branch);
|
||||
RevCommit commit = this.getRevTreeByRepositoryAndCommitId(repo, fileCommitId);
|
||||
RevTree tree = commit.getTree();
|
||||
TreeWalk treeWalk = new TreeWalk(repo);
|
||||
treeWalk.addTree(tree);
|
||||
treeWalk.setRecursive(true);
|
||||
treeWalk.setFilter(PathFilter.create(filePath));
|
||||
if (!treeWalk.next()) {
|
||||
return null;
|
||||
} else {
|
||||
attachInfo = new GitFileAttachInfo(repositoryUrl, userName, token, branch, fileCommitId.getName(), filePath, commit.getFullMessage());
|
||||
return attachInfo;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("获取文件库文件报错!", e);
|
||||
} finally {
|
||||
this.closeConnection(repo);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void validateParams(String... params) {
|
||||
for (String param : params) {
|
||||
if (StringUtils.isBlank(param)) {
|
||||
MSException.throwException("Has none params!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private RevCommit getRevTreeByRepositoryAndCommitId(InMemoryRepository repo, ObjectId fileCommitId) throws Exception {
|
||||
RevWalk revWalk = new RevWalk(repo);
|
||||
RevCommit commit = revWalk.parseCommit(fileCommitId);
|
||||
return commit;
|
||||
}
|
||||
|
||||
private InMemoryRepository getGitRepositoryInMemory(String repositoryUrl, String userName, String token) throws Exception {
|
||||
DfsRepositoryDescription repoDesc = new DfsRepositoryDescription();
|
||||
InMemoryRepository repo = new InMemoryRepository(repoDesc);
|
||||
CredentialsProvider credentialsProvider = new UsernamePasswordCredentialsProvider(userName, token);
|
||||
git = new Git(repo);
|
||||
git.fetch().setRemote(repositoryUrl).setRefSpecs(new RefSpec(REF_SPACE)).setCredentialsProvider(credentialsProvider).call();
|
||||
repo.getObjectDatabase();
|
||||
return repo;
|
||||
}
|
||||
|
||||
private void closeConnection(Repository repo) {
|
||||
if (git != null) {
|
||||
git.close();
|
||||
}
|
||||
if (repo != null) {
|
||||
repo.close();
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getBranches() {
|
||||
List<String> returnList = new ArrayList<>();
|
||||
this.validateParams(repositoryUrl, userName, token);
|
||||
InMemoryRepository repo = null;
|
||||
try {
|
||||
Collection<Ref> refList;
|
||||
UsernamePasswordCredentialsProvider pro = new UsernamePasswordCredentialsProvider(userName, token);
|
||||
refList = Git.lsRemoteRepository().setRemote(repositoryUrl).setCredentialsProvider(pro).call();
|
||||
refList.forEach(item -> {
|
||||
returnList.add(item.getName());
|
||||
});
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("获取文件库文件报错!", e);
|
||||
} finally {
|
||||
this.closeConnection(repo);
|
||||
}
|
||||
if (CollectionUtils.isEmpty(returnList)) {
|
||||
MSException.throwException("Repository connect error!");
|
||||
}
|
||||
return returnList;
|
||||
|
||||
}
|
||||
}
|
|
@ -12,6 +12,15 @@ public class MetadataUtils {
|
|||
return "";
|
||||
}
|
||||
|
||||
public static String getFileNameByRemotePath(String filePath) {
|
||||
if (StringUtils.isBlank(filePath)) {
|
||||
return "";
|
||||
} else {
|
||||
String[] stringArr = StringUtils.split(filePath, "/");
|
||||
return stringArr[stringArr.length - 1];
|
||||
}
|
||||
}
|
||||
|
||||
public static String getFileName(String name, String type) {
|
||||
type = StringUtils.isNotEmpty(type) ? type.toLowerCase() : null;
|
||||
if (type != null && !name.endsWith(type)) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package io.metersphere.metadata.vo;
|
||||
|
||||
import io.metersphere.base.domain.FileMetadata;
|
||||
import io.metersphere.base.domain.FileMetadataWithBLOBs;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -8,5 +8,5 @@ import java.util.List;
|
|||
@Data
|
||||
public class DownloadRequest {
|
||||
private String projectId;
|
||||
private List<FileMetadata> requests;
|
||||
private List<FileMetadataWithBLOBs> requests;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
package io.metersphere.metadata.vo;
|
||||
|
||||
import io.metersphere.base.domain.FileMetadataWithBLOBs;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FileMetadataCreateRequest extends FileMetadataWithBLOBs {
|
||||
private String repositoryBranch;
|
||||
private String repositoryPath;
|
||||
}
|
|
@ -8,4 +8,10 @@ import lombok.Setter;
|
|||
@Setter
|
||||
public class FileModuleVo extends TreeNodeDTO<FileModuleVo> {
|
||||
private String path;
|
||||
private String moduleType;
|
||||
private String repositoryName;
|
||||
private String repositoryPath;
|
||||
private String repositoryUserName;
|
||||
private String repositoryToken;
|
||||
private String repositoryDesc;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package io.metersphere.metadata.vo;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.commons.constants.StorageConstants;
|
||||
import io.metersphere.metadata.vo.repository.FileAttachInfo;
|
||||
import io.metersphere.metadata.vo.repository.GitFileAttachInfo;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
|
@ -17,6 +20,9 @@ public class FileRequest {
|
|||
private String resourceType;
|
||||
private String path;
|
||||
|
||||
//文件附属信息
|
||||
private FileAttachInfo fileAttachInfo;
|
||||
|
||||
public FileRequest() {
|
||||
|
||||
}
|
||||
|
@ -30,4 +36,12 @@ public class FileRequest {
|
|||
this.fileName = StringUtils.join(name, ".", this.type);
|
||||
}
|
||||
}
|
||||
|
||||
public void setFileAttachInfoByString(String attachInfoByString) {
|
||||
if (StringUtils.isNotEmpty(attachInfoByString)) {
|
||||
if (StringUtils.equals(this.storage, StorageConstants.GIT.name())) {
|
||||
this.setFileAttachInfo(JSONObject.parseObject(attachInfoByString, GitFileAttachInfo.class));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package io.metersphere.metadata.vo.repository;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FileAttachInfo {
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package io.metersphere.metadata.vo.repository;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class FileInfoDTO {
|
||||
private String id;
|
||||
private String fileName;
|
||||
private String storage;
|
||||
private byte[] fileByte;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package io.metersphere.metadata.vo.repository;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class FileRelevanceCaseDTO {
|
||||
public String id;
|
||||
public String caseId;
|
||||
public String caseName;
|
||||
public String caseType;
|
||||
public String commitId;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package io.metersphere.metadata.vo.repository;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class FileVersionDTO {
|
||||
public String id;
|
||||
public String commitId;
|
||||
public String commitMessage;
|
||||
public String operator;
|
||||
public long operatorTime;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package io.metersphere.metadata.vo.repository;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class GitFileAttachInfo extends FileAttachInfo {
|
||||
private String repositoryPath;
|
||||
private String userName;
|
||||
private String token;
|
||||
private String branch;
|
||||
private String commitId;
|
||||
private String filePath;
|
||||
private String commitMessage;
|
||||
|
||||
public String getRepositoryInfo() {
|
||||
return repositoryPath + "-" + userName + "-" + token;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package io.metersphere.metadata.vo.repository;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class RepositoryRequest {
|
||||
private String fileMetadataId;
|
||||
private String filePath;
|
||||
private String commitId;
|
||||
}
|
|
@ -3,6 +3,7 @@ package io.metersphere.performance.controller;
|
|||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import io.metersphere.base.domain.FileMetadata;
|
||||
import io.metersphere.base.domain.FileMetadataWithBLOBs;
|
||||
import io.metersphere.base.domain.LoadTest;
|
||||
import io.metersphere.base.domain.Schedule;
|
||||
import io.metersphere.commons.constants.NoticeConstants;
|
||||
|
@ -203,7 +204,7 @@ public class PerformanceTestController {
|
|||
}
|
||||
|
||||
@PostMapping("/file/{projectId}/getMetadataByName")
|
||||
public List<FileMetadata> getProjectMetadataByName(@PathVariable String projectId, @RequestBody QueryProjectFileRequest request) {
|
||||
public List<FileMetadataWithBLOBs> getProjectMetadataByName(@PathVariable String projectId, @RequestBody QueryProjectFileRequest request) {
|
||||
return fileMetadataService.getProjectFiles(projectId, request);
|
||||
}
|
||||
|
||||
|
@ -212,7 +213,7 @@ public class PerformanceTestController {
|
|||
byte[] bytes = fileMetadataService.loadFileAsBytes(fileOperationRequest.getId());
|
||||
return ResponseEntity.ok()
|
||||
.contentType(MediaType.parseMediaType("application/octet-stream"))
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileOperationRequest.getId()+".jmx" + "\"")
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileOperationRequest.getId() + ".jmx" + "\"")
|
||||
.body(bytes);
|
||||
}
|
||||
|
||||
|
@ -280,7 +281,7 @@ public class PerformanceTestController {
|
|||
|
||||
@GetMapping("get/{version}/{refId}")
|
||||
public LoadTestDTO getLoadTestByVersion(@PathVariable String version, @PathVariable String refId) {
|
||||
return performanceTestService.getLoadTestByVersion(version,refId);
|
||||
return performanceTestService.getLoadTestByVersion(version, refId);
|
||||
}
|
||||
|
||||
@GetMapping("delete/{version}/{refId}")
|
||||
|
|
|
@ -2,15 +2,16 @@ package io.metersphere.service;
|
|||
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.*;
|
||||
import io.metersphere.base.mapper.ext.ExtFileMetadataMapper;
|
||||
import io.metersphere.commons.constants.FileType;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.performance.request.QueryProjectFileRequest;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.SerializationUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
@ -34,6 +35,8 @@ public class FileService {
|
|||
private TestCaseFileMapper testCaseFileMapper;
|
||||
@Resource
|
||||
private IssueFileMapper issueFileMapper;
|
||||
@Resource
|
||||
private ExtFileMetadataMapper extFileMetadataMapper;
|
||||
|
||||
public byte[] loadFileAsBytes(String id) {
|
||||
FileContent fileContent = fileContentMapper.selectByPrimaryKey(id);
|
||||
|
@ -66,6 +69,14 @@ public class FileService {
|
|||
example.createCriteria().andIdIn(ids);
|
||||
fileMetadataMapper.deleteByExample(example);
|
||||
|
||||
List<String> refIdList = extFileMetadataMapper.selectRefIdsByIds(ids);
|
||||
if (CollectionUtils.isNotEmpty(refIdList)) {
|
||||
//删除其余版本的文件
|
||||
example.clear();
|
||||
example.createCriteria().andRefIdIn(refIdList);
|
||||
fileMetadataMapper.deleteByExample(example);
|
||||
}
|
||||
|
||||
FileContentExample example2 = new FileContentExample();
|
||||
example2.createCriteria().andFileIdIn(ids);
|
||||
fileContentMapper.deleteByExample(example2);
|
||||
|
@ -93,7 +104,7 @@ public class FileService {
|
|||
}
|
||||
|
||||
public FileMetadata saveFile(MultipartFile file, String projectId, String fileId) {
|
||||
final FileMetadata fileMetadata = new FileMetadata();
|
||||
final FileMetadataWithBLOBs fileMetadata = new FileMetadataWithBLOBs();
|
||||
if (StringUtils.isEmpty(fileId)) {
|
||||
fileMetadata.setId(UUID.randomUUID().toString());
|
||||
} else {
|
||||
|
@ -106,6 +117,8 @@ public class FileService {
|
|||
fileMetadata.setUpdateTime(System.currentTimeMillis());
|
||||
FileType fileType = getFileType(fileMetadata.getName());
|
||||
fileMetadata.setType(fileType.name());
|
||||
fileMetadata.setLatest(true);
|
||||
fileMetadata.setRefId(fileMetadata.getId());
|
||||
fileMetadataMapper.insert(fileMetadata);
|
||||
|
||||
FileContent fileContent = new FileContent();
|
||||
|
@ -142,7 +155,7 @@ public class FileService {
|
|||
if (!parentFile.exists()) {
|
||||
parentFile.mkdirs();
|
||||
}
|
||||
try (OutputStream os = new FileOutputStream(uploadPath + "/" + attachmentName)){
|
||||
try (OutputStream os = new FileOutputStream(uploadPath + "/" + attachmentName)) {
|
||||
InputStream in = new ByteArrayInputStream(bytes);
|
||||
int len = 0;
|
||||
byte[] buf = new byte[1024];
|
||||
|
@ -189,7 +202,7 @@ public class FileService {
|
|||
}
|
||||
|
||||
public FileMetadata saveFile(File file, byte[] fileByte) {
|
||||
final FileMetadata fileMetadata = new FileMetadata();
|
||||
final FileMetadataWithBLOBs fileMetadata = new FileMetadataWithBLOBs();
|
||||
fileMetadata.setId(UUID.randomUUID().toString());
|
||||
fileMetadata.setName(file.getName());
|
||||
fileMetadata.setSize(file.length());
|
||||
|
@ -197,6 +210,8 @@ public class FileService {
|
|||
fileMetadata.setUpdateTime(System.currentTimeMillis());
|
||||
FileType fileType = getFileType(fileMetadata.getName());
|
||||
fileMetadata.setType(fileType.name());
|
||||
fileMetadata.setLatest(true);
|
||||
fileMetadata.setRefId(fileMetadata.getId());
|
||||
fileMetadataMapper.insert(fileMetadata);
|
||||
|
||||
FileContent fileContent = new FileContent();
|
||||
|
@ -213,9 +228,9 @@ public class FileService {
|
|||
} else {
|
||||
FileMetadataExample example = new FileMetadataExample();
|
||||
example.createCriteria().andProjectIdEqualTo(projectId).andNameEqualTo(file.getName());
|
||||
List<FileMetadata> fileMetadatasInDataBase = fileMetadataMapper.selectByExample(example);
|
||||
List<FileMetadataWithBLOBs> fileMetadatasInDataBase = fileMetadataMapper.selectByExampleWithBLOBs(example);
|
||||
if (CollectionUtils.isEmpty(fileMetadatasInDataBase)) {
|
||||
final FileMetadata fileMetadata = new FileMetadata();
|
||||
final FileMetadataWithBLOBs fileMetadata = new FileMetadataWithBLOBs();
|
||||
fileMetadata.setId(UUID.randomUUID().toString());
|
||||
fileMetadata.setName(file.getName());
|
||||
fileMetadata.setSize(file.length());
|
||||
|
@ -224,6 +239,8 @@ public class FileService {
|
|||
fileMetadata.setUpdateTime(System.currentTimeMillis());
|
||||
FileType fileType = getFileType(fileMetadata.getName());
|
||||
fileMetadata.setType(fileType.name());
|
||||
fileMetadata.setLatest(true);
|
||||
fileMetadata.setRefId(fileMetadata.getId());
|
||||
fileMetadataMapper.insert(fileMetadata);
|
||||
|
||||
FileContent fileContent = new FileContent();
|
||||
|
@ -232,7 +249,7 @@ public class FileService {
|
|||
fileContentMapper.insert(fileContent);
|
||||
return fileMetadata;
|
||||
} else {
|
||||
FileMetadata fileMetadata = fileMetadatasInDataBase.get(0);
|
||||
FileMetadataWithBLOBs fileMetadata = fileMetadatasInDataBase.get(0);
|
||||
fileMetadata.setName(file.getName());
|
||||
fileMetadata.setSize(file.length());
|
||||
fileMetadata.setProjectId(projectId);
|
||||
|
@ -253,7 +270,7 @@ public class FileService {
|
|||
}
|
||||
|
||||
public FileMetadata saveFile(File file, byte[] fileByte, String projectId) {
|
||||
final FileMetadata fileMetadata = new FileMetadata();
|
||||
final FileMetadataWithBLOBs fileMetadata = new FileMetadataWithBLOBs();
|
||||
fileMetadata.setId(UUID.randomUUID().toString());
|
||||
fileMetadata.setName(file.getName());
|
||||
fileMetadata.setSize(file.length());
|
||||
|
@ -262,6 +279,8 @@ public class FileService {
|
|||
fileMetadata.setUpdateTime(System.currentTimeMillis());
|
||||
FileType fileType = getFileType(fileMetadata.getName());
|
||||
fileMetadata.setType(fileType.name());
|
||||
fileMetadata.setLatest(true);
|
||||
fileMetadata.setRefId(fileMetadata.getId());
|
||||
fileMetadataMapper.insert(fileMetadata);
|
||||
|
||||
FileContent fileContent = new FileContent();
|
||||
|
@ -273,7 +292,7 @@ public class FileService {
|
|||
}
|
||||
|
||||
public FileMetadata saveFile(byte[] fileByte, String fileName, Long fileSize) {
|
||||
final FileMetadata fileMetadata = new FileMetadata();
|
||||
final FileMetadataWithBLOBs fileMetadata = new FileMetadataWithBLOBs();
|
||||
fileMetadata.setId(UUID.randomUUID().toString());
|
||||
fileMetadata.setName(fileName);
|
||||
fileMetadata.setSize(fileSize);
|
||||
|
@ -281,6 +300,8 @@ public class FileService {
|
|||
fileMetadata.setUpdateTime(System.currentTimeMillis());
|
||||
FileType fileType = getFileType(fileMetadata.getName());
|
||||
fileMetadata.setType(fileType.name());
|
||||
fileMetadata.setLatest(true);
|
||||
fileMetadata.setRefId(fileMetadata.getId());
|
||||
fileMetadataMapper.insert(fileMetadata);
|
||||
|
||||
FileContent fileContent = new FileContent();
|
||||
|
@ -292,12 +313,14 @@ public class FileService {
|
|||
}
|
||||
|
||||
public FileMetadata copyFile(String fileId) {
|
||||
FileMetadata fileMetadata = fileMetadataMapper.selectByPrimaryKey(fileId);
|
||||
FileMetadataWithBLOBs fileMetadata = fileMetadataMapper.selectByPrimaryKey(fileId);
|
||||
FileContent fileContent = getFileContent(fileId);
|
||||
if (fileMetadata != null && fileContent != null) {
|
||||
fileMetadata.setId(UUID.randomUUID().toString());
|
||||
fileMetadata.setCreateTime(System.currentTimeMillis());
|
||||
fileMetadata.setUpdateTime(System.currentTimeMillis());
|
||||
fileMetadata.setLatest(true);
|
||||
fileMetadata.setRefId(fileMetadata.getId());
|
||||
fileMetadataMapper.insert(fileMetadata);
|
||||
|
||||
fileContent.setFileId(fileMetadata.getId());
|
||||
|
@ -307,7 +330,6 @@ public class FileService {
|
|||
}
|
||||
|
||||
|
||||
|
||||
public FileAttachmentMetadata copyAttachment(String fileId, String attachmentType, String belongId) {
|
||||
String copyPath = FileUtils.ATTACHMENT_DIR + "/" + attachmentType + "/" + belongId;
|
||||
FileAttachmentMetadata fileAttachmentMetadata = fileAttachmentMetadataMapper.selectByPrimaryKey(fileId);
|
||||
|
@ -398,7 +420,7 @@ public class FileService {
|
|||
return fileMetadataMapper.selectByPrimaryKey(fileId);
|
||||
}
|
||||
|
||||
public void updateFileMetadata(FileMetadata fileMetadata) {
|
||||
public void updateFileMetadata(FileMetadataWithBLOBs fileMetadata) {
|
||||
fileMetadataMapper.updateByPrimaryKeySelective(fileMetadata);
|
||||
}
|
||||
|
||||
|
@ -439,13 +461,15 @@ public class FileService {
|
|||
try {
|
||||
RsaKey rsaKey = RsaUtil.getRsaKey();
|
||||
byte[] bytes = SerializationUtils.serialize(rsaKey);
|
||||
final FileMetadata fileMetadata = new FileMetadata();
|
||||
final FileMetadataWithBLOBs fileMetadata = new FileMetadataWithBLOBs();
|
||||
fileMetadata.setId(key);
|
||||
fileMetadata.setName(key);
|
||||
fileMetadata.setSize((long) bytes.length);
|
||||
fileMetadata.setCreateTime(System.currentTimeMillis());
|
||||
fileMetadata.setUpdateTime(System.currentTimeMillis());
|
||||
fileMetadata.setType("RSA_KEY");
|
||||
fileMetadata.setLatest(true);
|
||||
fileMetadata.setRefId(fileMetadata.getId());
|
||||
fileMetadataMapper.insert(fileMetadata);
|
||||
|
||||
FileContent fileContent = new FileContent();
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
</javaClientGenerator>
|
||||
|
||||
<!--要生成的数据库表 -->
|
||||
<table tableName="api_sync_rule_relation"/>
|
||||
<table tableName="file_metadata"/>
|
||||
|
||||
<!-- 要忽略的字段-->
|
||||
<!-- <table tableName="test_case">
|
||||
|
|
|
@ -430,4 +430,6 @@ create_api_case=New interface use case
|
|||
api_case_create_notice=Interface use case new notification
|
||||
update_api_case=Updated interface use case
|
||||
api_case_update_notice=Interface use case update notification
|
||||
error_xml_struct=Data is not xml
|
||||
error_xml_struct=Data is not xml
|
||||
repository_module_already_exists=The repository name already exists at the same project
|
||||
can_not_move_to_repository_node=Can not move to repository node
|
|
@ -430,3 +430,5 @@ api_case_create_notice=接口用例新建通知
|
|||
update_api_case=更新了接口用例
|
||||
api_case_update_notice=接口用例更新通知
|
||||
error_xml_struct=错误的xml数据
|
||||
repository_module_already_exists=同项目下该文件库名称已存在
|
||||
can_not_move_to_repository_node=禁止移动到文件库目录
|
|
@ -429,3 +429,5 @@ api_case_create_notice=接口用例新建通知
|
|||
update_api_case=更新了接口用例
|
||||
api_case_update_notice=接口用例更新通知
|
||||
error_xml_struct=錯誤的xml數據
|
||||
repository_module_already_exists=同項目下該文件庫名稱已存在
|
||||
can_not_move_to_repository_node=禁止移動到文件庫目錄
|
||||
|
|
|
@ -303,7 +303,7 @@ export default {
|
|||
break;
|
||||
case "scenario":
|
||||
this.$router.push({
|
||||
name: 'ApiAutomation',
|
||||
name: 'ApiAutomationSingle',
|
||||
params: {paramObj: redirectObj}
|
||||
});
|
||||
break;
|
||||
|
|
|
@ -47,6 +47,11 @@ export default {
|
|||
name: "ApiAutomation",
|
||||
component: () => import('@/business/components/api/automation/ApiAutomation'),
|
||||
},
|
||||
{
|
||||
path: "automation",
|
||||
name: "ApiAutomationSingle",
|
||||
component: () => import('@/business/components/api/automation/ApiAutomation'),
|
||||
},
|
||||
{
|
||||
path: 'monitor/view',
|
||||
name: 'ApiMonitor',
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
<ms-file-module @nodeSelectEvent="change" @myFile="myFile" @setNodeTree="setNodeTree" ref="module"/>
|
||||
</ms-aside-container>
|
||||
<ms-main-container>
|
||||
<resource-manage ref="resourceManage" :moduleId="moduleId" :nodeTree="nodeTree" @refreshModule="refreshModule"/>
|
||||
<resource-manage ref="resourceManage" :moduleId="moduleId" :module-type="moduleType" :nodeTree="nodeTree"
|
||||
@refreshModule="refreshModule"/>
|
||||
</ms-main-container>
|
||||
</ms-container>
|
||||
</template>
|
||||
|
@ -31,12 +32,14 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
moduleId: "",
|
||||
moduleType: "module",
|
||||
nodeTree: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
change(node, nodeIds, pNodes) {
|
||||
this.moduleId = node.data.id;
|
||||
this.moduleType = node.data.moduleType;
|
||||
this.$refs.resourceManage.moduleChange(nodeIds);
|
||||
},
|
||||
myFile() {
|
||||
|
@ -45,7 +48,7 @@ export default {
|
|||
setNodeTree(data) {
|
||||
this.nodeTree = data;
|
||||
},
|
||||
refreshModule(){
|
||||
refreshModule() {
|
||||
this.$refs.module.refresh();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
<template>
|
||||
<el-dialog :title="dialogTitle"
|
||||
:visible.sync="dialogFormVisible"
|
||||
:before-close="close"
|
||||
width="600px">
|
||||
<el-form :model="metadataForm" :rules="metadataRule" ref="form" label-width="80px" @submit.native.prevent>
|
||||
<el-form-item
|
||||
:label="$t('project.project_file.file.branch')"
|
||||
prop="repositoryBranch">
|
||||
<el-input v-model="metadataForm.repositoryBranch"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('project.project_file.file.path')"
|
||||
prop="repositoryPath">
|
||||
<el-input v-model="metadataForm.repositoryPath"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template v-slot:footer>
|
||||
<el-button @click="close">{{ $t('commons.cancel') }}</el-button>
|
||||
<el-button v-xpack v-prevent-re-click type="primary" :loading="isSaveBtnLoading" @click="saveFileMetadata"
|
||||
@keydown.enter.native.prevent>{{ $t('commons.confirm') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getCurrentProjectID, getCurrentUserId, getUUID, listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
||||
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
|
||||
|
||||
export default {
|
||||
name: "FileMetadataDialog",
|
||||
components: {
|
||||
MsDialogFooter,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialogFormVisible: false,
|
||||
dialogTitle: '',
|
||||
operationType: '',
|
||||
isSaveBtnLoading: false,
|
||||
projectId: getCurrentProjectID(),
|
||||
metadataForm: {
|
||||
repositoryBranch: '',
|
||||
repositoryPath: '',
|
||||
},
|
||||
metadataRule: {
|
||||
repositoryBranch: [
|
||||
{required: true, message: this.$t('project.project_file.validation.input_file_branch'), trigger: 'blur'},
|
||||
],
|
||||
repositoryPath: [
|
||||
{required: true, message: this.$t('project.project_file.validation.input_file_path'), trigger: 'blur'},
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
watch: {},
|
||||
props: {
|
||||
moduleId: String,
|
||||
},
|
||||
computed: {},
|
||||
methods: {
|
||||
saveFileMetadata() {
|
||||
this.$refs.form.validate(valid => {
|
||||
if (valid) {
|
||||
let url = '';
|
||||
let param = JSON.parse(JSON.stringify(this.metadataForm));
|
||||
param.storage = 'GIT';
|
||||
if (param.id) {
|
||||
url = "/file/metadata/edit";
|
||||
} else {
|
||||
url = "/file/metadata/create";
|
||||
param.id = getUUID();
|
||||
param.createUser = getCurrentUserId();
|
||||
param.updateUser = getCurrentUserId();
|
||||
param.projectId = this.projectId;
|
||||
param.moduleId = this.moduleId;
|
||||
}
|
||||
let formData = new FormData();
|
||||
formData.append("request", new Blob([JSON.stringify(param)], {type: "application/json"}));
|
||||
let options = {
|
||||
method: 'POST',
|
||||
url: url,
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': undefined
|
||||
}
|
||||
};
|
||||
this.isSaveBtnLoading = true;
|
||||
this.result = this.$request(options, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.$emit('refresh');
|
||||
this.isSaveBtnLoading = false;
|
||||
this.close();
|
||||
}, (error) => {
|
||||
this.$emit('refresh');
|
||||
this.isSaveBtnLoading = false;
|
||||
});
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
open(operationType, param) {
|
||||
this.isSaveBtnLoading = false;
|
||||
listenGoBack(this.close);
|
||||
this.initDialog(operationType);
|
||||
if (param) {
|
||||
this.metadataForm = JSON.parse(JSON.stringify(param));
|
||||
} else {
|
||||
this.metadataForm = {
|
||||
repositoryBranch: '',
|
||||
repositoryPath: '',
|
||||
};
|
||||
}
|
||||
this.dialogFormVisible = true;
|
||||
},
|
||||
close() {
|
||||
this.isSaveBtnLoading = false;
|
||||
removeGoBackListener(this.close);
|
||||
this.$refs.form.resetFields();
|
||||
this.dialogFormVisible = false;
|
||||
},
|
||||
initDialog(operationType) {
|
||||
this.operationType = operationType;
|
||||
//初始化弹窗数据-title
|
||||
if (operationType === 'create') {
|
||||
this.dialogTitle = this.$t('commons.create');
|
||||
} else if (operationType === 'edit') {
|
||||
this.dialogTitle = this.$t('commons.edit');
|
||||
} else {
|
||||
this.dialogTitle = '';
|
||||
}
|
||||
},
|
||||
clearForm() {
|
||||
this.metadataForm = {
|
||||
repositoryBranch: '',
|
||||
repositoryPath: '',
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,235 @@
|
|||
<template>
|
||||
|
||||
<el-dialog :title="dialogTitle"
|
||||
:visible.sync="dialogFormVisible"
|
||||
:before-close="close"
|
||||
width="600px">
|
||||
<el-row v-show="operationType==='create'" type="flex" justify="center" style="margin-bottom: 10px;">
|
||||
<el-radio-group v-model="moduleForm.moduleType">
|
||||
<el-radio label="module">{{ $t("project.project_file.file_module_type.module") }}</el-radio>
|
||||
<el-radio v-xpack label="repository">{{ $t("project.project_file.file_module_type.repository") }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-row>
|
||||
<el-form :model="moduleForm" :rules="moduleRule" ref="form" label-width="100px" @submit.native.prevent>
|
||||
<el-form-item v-show="moduleForm.moduleType === 'module'"
|
||||
:label="$t('test_track.module.name')"
|
||||
prop="name">
|
||||
<el-input v-model="moduleForm.name"></el-input>
|
||||
</el-form-item>
|
||||
<div v-show="moduleForm.moduleType === 'repository'">
|
||||
<el-form-item
|
||||
:label="$t('project.project_file.repository.name')"
|
||||
prop="name">
|
||||
<el-input v-model="moduleForm.name"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('project.project_file.repository.path')"
|
||||
prop="repositoryPath">
|
||||
<el-input v-model="moduleForm.repositoryPath"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
:label="$t('api_test.request.tcp.username')"
|
||||
prop="repositoryUserName">
|
||||
<el-input v-model="moduleForm.repositoryUserName">
|
||||
<template slot="append">
|
||||
<el-tooltip class="item" effect="dark"
|
||||
:content="$t('project.project_file.validation.input_gitee_user_please')" placement="top">
|
||||
<i class="el-icon-info"/>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
:label="$t('project.project_file.repository.token')"
|
||||
prop="repositoryToken">
|
||||
<el-input v-model="moduleForm.repositoryToken"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
type="textarea"
|
||||
:label="$t('project.project_file.repository.desc')"
|
||||
prop="repositoryDesc">
|
||||
<el-input v-model="moduleForm.repositoryDesc"></el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
|
||||
<template v-slot:footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="close">{{ $t('commons.cancel') }}</el-button>
|
||||
<el-button v-prevent-re-click :loading="isConnBtnLoading" type="primary" @click="testConnect"
|
||||
v-show="moduleForm.moduleType === 'repository'"
|
||||
@keydown.enter.native.prevent>
|
||||
{{ $t('system_parameter_setting.test_connection') }}
|
||||
</el-button>
|
||||
<el-button v-prevent-re-click :loading="isSaveBtnLoading" type="primary" @click="saveFileModule"
|
||||
@keydown.enter.native.prevent>
|
||||
{{ $t('commons.confirm') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getCurrentProjectID, listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
||||
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
|
||||
|
||||
export default {
|
||||
name: "FileModuleDialog",
|
||||
components: {
|
||||
MsDialogFooter,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialogFormVisible: false,
|
||||
dialogTitle: '',
|
||||
operationType: '',
|
||||
projectId: getCurrentProjectID(),
|
||||
isConnBtnLoading: false,
|
||||
isSaveBtnLoading: false,
|
||||
moduleForm: {
|
||||
name: '',
|
||||
moduleType: 'module',
|
||||
repositoryUserName: '',
|
||||
repositoryPath: '',
|
||||
repositoryToken: '',
|
||||
repositoryDesc: '',
|
||||
},
|
||||
moduleRule: {
|
||||
name: [
|
||||
{required: true, message: this.$t('test_track.case.input_name'), trigger: 'blur'},
|
||||
{max: 60, message: this.$t('test_track.length_less_than') + '60', trigger: 'blur'}
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'moduleForm.moduleType'() {
|
||||
if (this.moduleForm.moduleType === 'module') {
|
||||
this.moduleRule = {
|
||||
name: [
|
||||
{required: true, message: this.$t('test_track.case.input_name'), trigger: 'blur'},
|
||||
{max: 60, message: this.$t('test_track.length_less_than') + '60', trigger: 'blur'}
|
||||
],
|
||||
};
|
||||
} else if (this.moduleForm.moduleType === 'repository') {
|
||||
this.moduleRule = {
|
||||
name: [
|
||||
{required: true, message: this.$t('test_track.case.input_name'), trigger: 'blur'},
|
||||
{max: 60, message: this.$t('test_track.length_less_than') + '60', trigger: 'blur'}
|
||||
],
|
||||
repositoryPath: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('project.project_file.validation.input_repository_path'),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{max: 255, message: this.$t('test_track.length_less_than') + '255', trigger: 'blur'},
|
||||
{
|
||||
pattern: '(.*)\.git$',
|
||||
message: this.$t('project.project_file.validation.input_repository_path'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
repositoryToken: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('project.project_file.validation.input_repository_token'),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{max: 255, message: this.$t('test_track.length_less_than') + '255', trigger: 'blur'}
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
props: {},
|
||||
computed: {},
|
||||
methods: {
|
||||
testConnect() {
|
||||
let param = this.moduleForm;
|
||||
let url = "/file/module/connect";
|
||||
this.isConnBtnLoading = true;
|
||||
this.$post(url, param, () => {
|
||||
this.$success(this.$t('commons.connection_successful'));
|
||||
this.isConnBtnLoading = false;
|
||||
}, (error) => {
|
||||
this.$emit('refresh');
|
||||
this.isConnBtnLoading = false;
|
||||
});
|
||||
},
|
||||
saveFileModule() {
|
||||
this.$refs.form.validate(valid => {
|
||||
if (valid) {
|
||||
let url = '';
|
||||
if (this.operationType === 'create') {
|
||||
url = "/file/module/add";
|
||||
} else if (this.operationType === 'edit') {
|
||||
url = "/file/module/edit";
|
||||
}
|
||||
let param = this.moduleForm;
|
||||
param.projectId = this.projectId;
|
||||
|
||||
this.isSaveBtnLoading = true;
|
||||
this.$post(url, param, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.$emit('refresh');
|
||||
this.isSaveBtnLoading = false;
|
||||
this.close();
|
||||
}, (error) => {
|
||||
this.isSaveBtnLoading = false;
|
||||
this.$emit('refresh');
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
open(operationType, param) {
|
||||
this.isSaveBtnLoading = false;
|
||||
this.isConnBtnLoading = false;
|
||||
listenGoBack(this.close);
|
||||
this.initDialog(operationType);
|
||||
if (operationType === 'create') {
|
||||
param.moduleType = 'module';
|
||||
}
|
||||
this.moduleForm = JSON.parse(JSON.stringify(param));
|
||||
this.dialogFormVisible = true;
|
||||
},
|
||||
close() {
|
||||
this.isSaveBtnLoading = false;
|
||||
this.isConnBtnLoading = false;
|
||||
removeGoBackListener(this.close);
|
||||
this.$refs.form.resetFields();
|
||||
this.dialogFormVisible = false;
|
||||
},
|
||||
initDialog(operationType) {
|
||||
this.operationType = operationType;
|
||||
//初始化弹窗数据-title
|
||||
if (operationType === 'create') {
|
||||
this.dialogTitle = this.$t('commons.create');
|
||||
} else if (operationType === 'edit') {
|
||||
this.dialogTitle = this.$t('commons.edit');
|
||||
} else {
|
||||
this.dialogTitle = '';
|
||||
}
|
||||
},
|
||||
clearForm() {
|
||||
this.moduleForm = {
|
||||
name: '',
|
||||
moduleType: 'module',
|
||||
repositoryPath: '',
|
||||
repositoryToken: '',
|
||||
repositoryUserName: '',
|
||||
repositoryDesc: '',
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -5,106 +5,132 @@
|
|||
<span>{{ data.name }}</span>
|
||||
<i class="el-icon-download ms-header-menu" @click="download" v-permission="['PROJECT_FILE:READ+DOWNLOAD+JAR']"/>
|
||||
<i class="el-icon-delete ms-header-menu" @click="deleteData" v-permission="['PROJECT_FILE:READ+DELETE+JAR']"/>
|
||||
<el-button v-if="isRepositoryFile()" :loading="isPullBtnLoading" class="ms-header-menu" size="mini"
|
||||
@click="filePull"
|
||||
style="padding: 2px;font-size: 12px">pull</el-button>
|
||||
</span>
|
||||
<el-row align="center" v-loading="loading">
|
||||
<el-col style="margin: 10px" :span="10">
|
||||
<el-row :gutter="20" style="background: #F5F6F8;height: 480px">
|
||||
<el-col :span="2" class="ms-left-col">
|
||||
<i class="el-icon-arrow-left ms-icon-arrow" @click="beforeData"/>
|
||||
|
||||
<el-tabs v-if="visible" tab-position="right" v-model="showPanel"
|
||||
:class=" isRepositoryFile()?'':'file-metadata-tab'">
|
||||
<el-tab-pane name="baseInfo" :label=" isRepositoryFile()?$t('test_track.plan_view.base_info'):''">
|
||||
<el-row align="center" v-loading="loading">
|
||||
<el-col style="margin: 10px" :span="10">
|
||||
<el-row :gutter="20" style="background: #F5F6F8;height: 480px">
|
||||
<el-col :span="2" class="ms-left-col">
|
||||
<i class="el-icon-arrow-left ms-icon-arrow" @click="beforeData"/>
|
||||
</el-col>
|
||||
<el-col :span="18" style="padding-top: 80px">
|
||||
<el-card :body-style="{ padding: '0px' }" v-if="isImage(data.type) && !isRepositoryFile()">
|
||||
<img :src="'/file/metadata/info/' + data.id" class="ms-edit-image"/>
|
||||
</el-card>
|
||||
<el-card :body-style="{ padding: '0px' }" v-else>
|
||||
<div class="ms-edit-image">
|
||||
<div class="ms-file-item">
|
||||
<div class="icon-title">{{ getType(data.type) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="2" class="ms-right-col">
|
||||
<i class="el-icon-arrow-right ms-icon-arrow" @click="nextData"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :span="18" style="padding-top: 80px">
|
||||
<el-card :body-style="{ padding: '0px' }" v-if="isImage(data.type)">
|
||||
<img :src="'/file/metadata/info/' + data.id" class="ms-edit-image"/>
|
||||
</el-card>
|
||||
<el-card :body-style="{ padding: '0px' }" v-else>
|
||||
<div class="ms-edit-image">
|
||||
<div class="ms-file-item">
|
||||
<div class="icon-title">{{ getType(data.type) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="2" class="ms-right-col">
|
||||
<i class="el-icon-arrow-right ms-icon-arrow" @click="nextData"/>
|
||||
<el-col :span="13">
|
||||
<el-container>
|
||||
<el-main>
|
||||
<el-form :model="data" :rules="rules" label-position="right" label-width="80px" size="small" ref="form">
|
||||
<!-- 基础信息 -->
|
||||
<el-form-item :label="$t('commons.description')" prop="description">
|
||||
<el-input class="ms-http-textarea"
|
||||
v-model="data.description"
|
||||
type="textarea"
|
||||
:rows="2" size="small" @blur="save"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('load_test.file_name')" prop="name">
|
||||
<el-input
|
||||
class="ms-file-item-input"
|
||||
size="small"
|
||||
v-model="data.name"
|
||||
:disabled="isRepositoryFile()"
|
||||
show-word-limit @blur="save"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('load_test.file_type')" prop="type">
|
||||
<span>{{ data.type }}</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="!isRepositoryFile()" :label="$t('load_test.file_size')" prop="size">
|
||||
<span>{{ formatFileSize(data.size) }}</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('api_test.automation.tag')" prop="tags">
|
||||
<ms-input-tag :currentScenario="data" ref="tag" @onblur="save"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('test_track.case.module')" prop="moduleId">
|
||||
<ms-select-tree :disabled="isRepositoryFile()" size="small" :data="moduleOptions"
|
||||
:defaultKey="data.moduleId"
|
||||
@getValue="setModule" :obj="moduleObj" clearable checkStrictly/>
|
||||
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('project.creator')" prop="createUser">
|
||||
<span>{{ data.createUser }}</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('commons.create_time')" prop="createTime">
|
||||
<span>{{ data.createTime | timestampFormatDate }}</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="'加载Jar包'" prop="loadJar" v-if="data.type === 'JAR'">
|
||||
<el-switch v-model="data.loadJar" :active-text="$t('project.file_jar_message')" @change="save"/>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="isRepositoryFile()" :label="$t('commons.version')">
|
||||
{{ getCommitId() }}
|
||||
</el-form-item>
|
||||
<el-form-item v-else :label="$t('project.upload_file_again')" prop="files">
|
||||
<el-upload
|
||||
style="width: 38px; float: left;"
|
||||
action="#"
|
||||
:before-upload="beforeUploadFile"
|
||||
:http-request="handleUpload"
|
||||
:show-file-list="false"
|
||||
v-permission="['PROJECT_FILE:READ+UPLOAD+JAR']">
|
||||
<el-button icon="el-icon-plus" size="mini"/>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="13">
|
||||
<el-form :model="data" :rules="rules" label-position="right" label-width="80px" size="small" ref="form">
|
||||
<!-- 基础信息 -->
|
||||
<el-form-item :label="$t('commons.description')" prop="description">
|
||||
<el-input class="ms-http-textarea"
|
||||
v-model="data.description"
|
||||
type="textarea"
|
||||
:rows="2" size="small" @blur="save"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('load_test.file_name')" prop="name">
|
||||
<el-input
|
||||
class="ms-file-item-input"
|
||||
size="small"
|
||||
v-model="data.name"
|
||||
show-word-limit @blur="save"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('load_test.file_type')" prop="type">
|
||||
<span>{{ data.type }}</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('load_test.file_size')" prop="size">
|
||||
<span>{{ formatFileSize(data.size) }}</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('api_test.automation.tag')" prop="tags">
|
||||
<ms-input-tag :currentScenario="data" ref="tag" @onblur="save"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('test_track.case.module')" prop="moduleId">
|
||||
<ms-select-tree size="small" :data="moduleOptions" :defaultKey="data.moduleId"
|
||||
@getValue="setModule" :obj="moduleObj" clearable checkStrictly/>
|
||||
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('project.creator')" prop="createUser">
|
||||
<span>{{ data.createUser }}</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('commons.create_time')" prop="createTime">
|
||||
<span>{{ data.createTime | timestampFormatDate }}</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="'加载Jar包'" prop="loadJar" v-if="data.type === 'JAR'">
|
||||
<el-switch v-model="data.loadJar" :active-text="$t('project.file_jar_message')" @change="save"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('project.upload_file_again')" prop="files">
|
||||
<el-upload
|
||||
style="width: 38px; float: left;"
|
||||
action="#"
|
||||
:before-upload="beforeUploadFile"
|
||||
:http-request="handleUpload"
|
||||
:show-file-list="false"
|
||||
v-permission="['PROJECT_FILE:READ+UPLOAD+JAR']">
|
||||
<el-button icon="el-icon-plus" size="mini"/>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="relevanceCase" v-if="isRepositoryFile()"
|
||||
:label=" $t('test_track.review_view.relevance_case')">
|
||||
<file-case-relevance-list :file-metadata-ref-id="data.refId"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="versionHistory" v-if="isRepositoryFile()"
|
||||
:label=" $t('project.project_file.repository.version_history')">
|
||||
<file-version-list :file-metadata-ref-id="data.refId"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getCurrentProjectID, operationConfirm} from "@/common/js/utils";
|
||||
import {hasPermission} from "../../../../../../common/js/utils";
|
||||
import FileCaseRelevanceList from "@/business/components/project/menu/file/list/FileCaseRelevanceList";
|
||||
import FileVersionList from "@/business/components/project/menu/file/list/FileVersionList";
|
||||
|
||||
export default {
|
||||
name: "MsEditFileMetadata",
|
||||
components: {
|
||||
MsSelectTree: () => import("../../../../common/select-tree/SelectTree"),
|
||||
MsInputTag: () => import("../../../../api/automation/scenario/MsInputTag"),
|
||||
FileCaseRelevanceList,
|
||||
FileVersionList,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -112,6 +138,8 @@ export default {
|
|||
visible: false,
|
||||
isFirst: false,
|
||||
isLast: false,
|
||||
isPullBtnLoading: false,
|
||||
showPanel: "baseInfo",
|
||||
results: [],
|
||||
moduleObj: {
|
||||
id: 'id',
|
||||
|
@ -148,6 +176,36 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
getCommitId() {
|
||||
if (this.data && this.data.attachInfo) {
|
||||
return JSON.parse(this.data.attachInfo).commitId;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
filePull() {
|
||||
this.isPullBtnLoading = true;
|
||||
|
||||
let formData = new FormData();
|
||||
formData.append("request", new Blob([JSON.stringify({id: this.data.id})], {type: "application/json"}));
|
||||
|
||||
let options = {
|
||||
method: 'POST',
|
||||
url: '/file/metadata/git/pull',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': undefined
|
||||
}
|
||||
};
|
||||
this.result = this.$request(options, () => {
|
||||
this.$success(this.$t('commons.update') + this.$t('api_test.automation.request_success'));
|
||||
this.isPullBtnLoading = false;
|
||||
this.$emit("reload");
|
||||
this.close();
|
||||
}, (error) => {
|
||||
this.isPullBtnLoading = false;
|
||||
});
|
||||
},
|
||||
beforeUploadFile(file) {
|
||||
if (!this.fileValidator(file)) {
|
||||
return false;
|
||||
|
@ -169,13 +227,16 @@ export default {
|
|||
}
|
||||
},
|
||||
close() {
|
||||
this.showPanel = "baseInfo";
|
||||
this.visible = false;
|
||||
},
|
||||
saveAndClose() {
|
||||
this.showPanel = "baseInfo";
|
||||
this.visible = false;
|
||||
this.$emit("setCurrentPage", this.currentPage);
|
||||
},
|
||||
open(data, size, page, t) {
|
||||
this.showPanel = "baseInfo";
|
||||
this.pageSize = size;
|
||||
this.currentPage = page;
|
||||
this.total = t;
|
||||
|
@ -183,6 +244,9 @@ export default {
|
|||
this.results = this.metadataArray;
|
||||
this.visible = true;
|
||||
},
|
||||
isRepositoryFile() {
|
||||
return this.data.storage === 'GIT';
|
||||
},
|
||||
save() {
|
||||
this.$refs['form'].validate((valid) => {
|
||||
if (valid) {
|
||||
|
@ -200,7 +264,11 @@ export default {
|
|||
});
|
||||
},
|
||||
getType(type) {
|
||||
return type || "";
|
||||
if (this.isRepositoryFile()) {
|
||||
return "Repository " + type || "";
|
||||
} else {
|
||||
return type || "";
|
||||
}
|
||||
},
|
||||
isImage(type) {
|
||||
return (type && this.images.indexOf(type.toLowerCase()) !== -1);
|
||||
|
@ -261,6 +329,7 @@ export default {
|
|||
});
|
||||
},
|
||||
beforeData() {
|
||||
this.showPanel = "baseInfo";
|
||||
const index = this.results.findIndex(e => e.id === this.data.id);
|
||||
this.isFirst = index <= 0;
|
||||
if (!this.isFirst) {
|
||||
|
@ -292,6 +361,7 @@ export default {
|
|||
return val + " " + list[num];
|
||||
},
|
||||
nextData() {
|
||||
this.showPanel = "baseInfo";
|
||||
const index = this.results.findIndex(e => e.id === this.data.id);
|
||||
this.isLast = (this.results.length - 1) === index;
|
||||
if (!this.isLast) {
|
||||
|
@ -369,4 +439,8 @@ export default {
|
|||
cursor: pointer;
|
||||
color: var(--color);
|
||||
}
|
||||
|
||||
.file-metadata-tab >>> .el-tabs__active-bar {
|
||||
background-color: white;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
<template>
|
||||
<div>
|
||||
<ms-table
|
||||
class="basic-config"
|
||||
:batch-operators="buttons"
|
||||
:data="tableData"
|
||||
:condition="condition"
|
||||
:hidePopover="true"
|
||||
|
||||
:total="total"
|
||||
enableSelection
|
||||
showSelectAll
|
||||
|
||||
@refresh="selectData" ref="table">
|
||||
<ms-table-column
|
||||
label="ID"
|
||||
:min-width="120"
|
||||
prop="caseId">
|
||||
</ms-table-column>
|
||||
|
||||
<ms-table-column
|
||||
:label="$t('api_test.home_page.failed_case_list.table_coloum.case_name')"
|
||||
:min-width="120"
|
||||
prop="caseName">
|
||||
</ms-table-column>
|
||||
|
||||
<ms-table-column
|
||||
:label="$t('project.project_file.repository.file_version')"
|
||||
:min-width="120"
|
||||
prop="caseType">
|
||||
<template v-slot="scope">
|
||||
<span v-if="scope.row.caseType === 'API'">
|
||||
{{ $t('api_test.home_page.api_details_card.title') }}
|
||||
</span>
|
||||
<span v-else-if="scope.row.caseType === 'CASE'">
|
||||
{{ $t('commons.api_case') }}
|
||||
</span>
|
||||
<span v-else-if="scope.row.caseType === 'SCENARIO'">
|
||||
{{ $t('commons.scenario_case') }}
|
||||
</span>
|
||||
<span v-else-if="scope.row.caseType === 'TEST_CASE'">
|
||||
{{ $t('commons.test_case') }}
|
||||
</span>
|
||||
|
||||
</template>
|
||||
</ms-table-column>
|
||||
|
||||
|
||||
<ms-table-column
|
||||
:label="$t('project.project_file.repository.file_version')"
|
||||
:min-width="120"
|
||||
prop="commitId">
|
||||
</ms-table-column>
|
||||
|
||||
<el-table-column :label="$t('commons.operating')" fixed="right" :width="130">
|
||||
<template v-slot:default="scope">
|
||||
<el-button size="mini" @click="updateFileVersion(scope.row)" style="padding: 4px;font-size: 12px">PULL
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ms-table>
|
||||
<table-pagination
|
||||
:change="selectData"
|
||||
:current-page.sync="currentPage"
|
||||
:page-size.sync="pageSize"
|
||||
:total="total"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import MsTable from "@/business/components/common/components/table/MsTable";
|
||||
import MsTableColumn from "@/business/components/common/components/table/MsTableColumn";
|
||||
import MsTableOperatorButton from "@/business/components/common/components/MsTableOperatorButton";
|
||||
import TablePagination from "@/business/components/common/pagination/TablePagination";
|
||||
import MsTableHeaderSelectPopover from "@/business/components/common/components/table/MsTableHeaderSelectPopover";
|
||||
|
||||
export default {
|
||||
name: "FileCaseRelevanceList",
|
||||
components: {
|
||||
MsTable, MsTableColumn, MsTableOperatorButton, TablePagination, MsTableHeaderSelectPopover
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableData: [],
|
||||
selectNodeIds: [],
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
metadataArr: [],
|
||||
fileNumLimit: 10,
|
||||
condition: {},
|
||||
buttons: [
|
||||
{
|
||||
name: 'PULL',
|
||||
handleClick: this.batchUpdateFileVersion
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
props: {
|
||||
fileMetadataRefId: String,
|
||||
},
|
||||
watch: {
|
||||
fileMetadataRefId() {
|
||||
this.selectData();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.selectData();
|
||||
},
|
||||
methods: {
|
||||
selectData() {
|
||||
this.$post('/file/metadata/file/relevance/case/' + this.fileMetadataRefId + "/" + this.currentPage + "/" + this.pageSize, this.condition, res => {
|
||||
let returnData = res.data;
|
||||
this.total = returnData.itemCount;
|
||||
this.tableData = returnData.listObject;
|
||||
});
|
||||
},
|
||||
updateFileVersion(row) {
|
||||
this.condition.ids = [row.id];
|
||||
this.$post('/file/metadata/case/version/update/' + this.fileMetadataRefId, this.condition, res => {
|
||||
this.$success('Pull ' + this.$t('variables.end'));
|
||||
this.selectData();
|
||||
});
|
||||
},
|
||||
batchUpdateFileVersion() {
|
||||
let selectIds = this.$refs.table.selectIds;
|
||||
this.condition.ids = selectIds;
|
||||
this.$post('/file/metadata/case/version/update/' + this.fileMetadataRefId, this.condition, res => {
|
||||
this.$success('Pull ' + this.$t('variables.end'));
|
||||
this.selectData();
|
||||
});
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -7,6 +7,7 @@
|
|||
@search="getProjectFiles" title="">
|
||||
<template v-slot:button>
|
||||
<el-upload
|
||||
v-if="moduleType==='module'"
|
||||
action=""
|
||||
:limit="fileNumLimit"
|
||||
multiple
|
||||
|
@ -15,9 +16,13 @@
|
|||
:http-request="handleUpload"
|
||||
:on-exceed="handleExceed">
|
||||
<ms-table-button icon="el-icon-upload2"
|
||||
:content="$t('load_test.upload_file')"
|
||||
:content="$t('variables.add_file')"
|
||||
v-permission="['PROJECT_FILE:READ+UPLOAD+JAR']"/>
|
||||
</el-upload>
|
||||
<ms-table-button icon="el-icon-upload2" v-else-if="moduleType==='repository'"
|
||||
:content="$t('variables.add_file')"
|
||||
@click="addRepositoryFile"
|
||||
v-permission="['PROJECT_FILE:READ+UPLOAD+JAR']"/>
|
||||
</template>
|
||||
</ms-table-header>
|
||||
</template>
|
||||
|
@ -162,6 +167,7 @@
|
|||
@download="handleDownload"
|
||||
@setCurrentPage="setCurrentPage"
|
||||
@delete="handleDelete" ref="editFileMetadata"/>
|
||||
<file-metadata-dialog :module-id="moduleId" @refresh="refreshModuleAndList" ref="repositoryFileDialog"/>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
|
@ -169,7 +175,7 @@
|
|||
import MsTablePagination from "@/business/components/common/pagination/TablePagination";
|
||||
import MsTableButton from "@/business/components/common/components/MsTableButton";
|
||||
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
|
||||
import {getCurrentProjectID, operationConfirm, getCurrentUserId} from "@/common/js/utils";
|
||||
import {getCurrentProjectID, getCurrentUserId, operationConfirm} from "@/common/js/utils";
|
||||
import MsTableOperatorButton from "@/business/components/common/components/MsTableOperatorButton";
|
||||
import MsTableHeader from "../header/FileHeader";
|
||||
import MsTableSearchBar from "@/business/components/common/components/MsTableSearchBar";
|
||||
|
@ -181,6 +187,7 @@ import MsFileBatchMove from "../module/FileBatchMove";
|
|||
import MsFileThumbnail from "./FileThumbnail";
|
||||
import MsEditFileMetadata from "../edit/EditFileMetadata";
|
||||
import MsTag from "@/business/components/common/components/MsTag";
|
||||
import FileMetadataDialog from "@/business/components/project/menu/file/dialog/FileMetadataDialog";
|
||||
|
||||
export default {
|
||||
name: "MsFileMetadataList",
|
||||
|
@ -198,10 +205,15 @@ export default {
|
|||
MsFileBatchMove,
|
||||
MsFileThumbnail,
|
||||
MsEditFileMetadata,
|
||||
MsTag
|
||||
MsTag,
|
||||
FileMetadataDialog,
|
||||
},
|
||||
props: {
|
||||
moduleId: String,
|
||||
moduleType: {
|
||||
type: String,
|
||||
default: 'module',
|
||||
},
|
||||
nodeTree: Array,
|
||||
},
|
||||
data() {
|
||||
|
@ -287,6 +299,10 @@ export default {
|
|||
});
|
||||
});
|
||||
},
|
||||
refreshModuleAndList() {
|
||||
this.getProjectFiles();
|
||||
this.refreshModule();
|
||||
},
|
||||
fileValidator(file) {
|
||||
/// todo: 是否需要对文件内容和大小做限制
|
||||
return file.size > 0;
|
||||
|
@ -306,7 +322,12 @@ export default {
|
|||
let file = uploadResources.file;
|
||||
let formData = new FormData();
|
||||
let url = '/file/metadata/create';
|
||||
let request = {createUser: getCurrentUserId(), updateUser: getCurrentUserId(), projectId: this.projectId, moduleId: this.moduleId};
|
||||
let request = {
|
||||
createUser: getCurrentUserId(),
|
||||
updateUser: getCurrentUserId(),
|
||||
projectId: this.projectId,
|
||||
moduleId: this.moduleId,
|
||||
};
|
||||
formData.append("request", new Blob([JSON.stringify(request)], {type: "application/json"}));
|
||||
formData.append("file", file);
|
||||
let options = {
|
||||
|
@ -414,6 +435,9 @@ export default {
|
|||
},
|
||||
moveSave(param) {
|
||||
this.buildBatchParam(param);
|
||||
},
|
||||
addRepositoryFile() {
|
||||
this.$refs.repositoryFileDialog.open("create");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-table :data="data" class="test-content document-table" style="width: 100%" ref="table">
|
||||
<el-table-column prop="commitId"
|
||||
:label="$t('project.project_file.repository.file_version')"
|
||||
min-width="120px"
|
||||
show-overflow-tooltip/>
|
||||
<el-table-column prop="commitMessage"
|
||||
:label="$t('project.project_file.repository.update_log')"
|
||||
min-width="200"
|
||||
show-overflow-tooltip/>
|
||||
<el-table-column prop="operator"
|
||||
:label="$t('operating_log.user')"
|
||||
min-width="120"
|
||||
show-overflow-tooltip/>
|
||||
<el-table-column prop="operatorTime" min-width="160" :label="$t('operating_log.time')" sortable>
|
||||
<template v-slot:default="scope">
|
||||
<span>{{ scope.row.operatorTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "FileVersionList",
|
||||
data() {
|
||||
return {
|
||||
data: [],
|
||||
};
|
||||
},
|
||||
props: {
|
||||
fileMetadataRefId: String,
|
||||
},
|
||||
watch: {
|
||||
fileMetadataRefId() {
|
||||
this.selectData();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.selectData();
|
||||
},
|
||||
methods: {
|
||||
selectData() {
|
||||
if (this.fileMetadataRefId) {
|
||||
this.$get('file/metadata/fileVersion/' + this.fileMetadataRefId, response => {
|
||||
if (response.data) {
|
||||
this.data = response.data;
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.$refs.table.doLayout();
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -5,6 +5,11 @@
|
|||
:destroy-on-close="true" width="600px"
|
||||
v-loading="loading" append-to-body class="batch-move">
|
||||
<div>
|
||||
<div v-xpack style="margin-bottom: 5px">
|
||||
<i class="el-icon-info"/>
|
||||
<span>{{ $t('project.project_file.validation.can_not_move_repository_file') }}</span>
|
||||
</div>
|
||||
|
||||
<el-input :placeholder="$t('test_track.module.search')" v-model="filterText" size="small"/>
|
||||
<el-tree
|
||||
class="filter-tree node-tree"
|
||||
|
@ -90,7 +95,7 @@ export default {
|
|||
});
|
||||
},
|
||||
save() {
|
||||
if (!this.currentKey || this.currentKey ==='') {
|
||||
if (!this.currentKey || this.currentKey === '') {
|
||||
this.$warning(this.$t('test_track.case.input_module'));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -11,13 +11,16 @@
|
|||
:update-permission="['PROJECT_API_SCENARIO:READ+EDIT']"
|
||||
:default-label="$t('commons.module_title')"
|
||||
:show-case-num="showCaseNum"
|
||||
@add="add"
|
||||
operation_type_add="external"
|
||||
operation_type_edit="external"
|
||||
@edit="edit"
|
||||
@drag="drag"
|
||||
@remove="remove"
|
||||
@refresh="list"
|
||||
@filter="filter"
|
||||
@nodeSelectEvent="nodeChange"
|
||||
@addOperation="fileTreeModuleAdd"
|
||||
@editOperation="fileTreeModuleEdit"
|
||||
ref="nodeTree">
|
||||
|
||||
<template v-slot:header>
|
||||
|
@ -26,8 +29,8 @@
|
|||
:condition="condition"/>
|
||||
<ms-my-file :condition="condition" :exe="myFile" :total='total' v-if="loading"/>
|
||||
</template>
|
||||
|
||||
</ms-node-tree>
|
||||
<file-module-dialog @refresh="list" ref="fileModuleDialog"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -37,6 +40,7 @@ import {buildTree} from "@/business/components/api/definition/model/NodeTree";
|
|||
import MsMyFile from "./MyFile";
|
||||
import MsSearchBar from "@/business/components/common/components/search/MsSearchBar";
|
||||
import {getCurrentProjectID, getCurrentUserId} from "@/common/js/utils";
|
||||
import FileModuleDialog from "@/business/components/project/menu/file/dialog/FileModuleDialog";
|
||||
|
||||
export default {
|
||||
name: 'MsFileModule',
|
||||
|
@ -44,6 +48,7 @@ export default {
|
|||
MsSearchBar,
|
||||
MsMyFile,
|
||||
MsNodeTree,
|
||||
FileModuleDialog,
|
||||
},
|
||||
props: {
|
||||
isReadOnly: {
|
||||
|
@ -95,6 +100,12 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
fileTreeModuleAdd(param) {
|
||||
this.$refs.fileModuleDialog.open('create', param);
|
||||
},
|
||||
fileTreeModuleEdit(data) {
|
||||
this.$refs.fileModuleDialog.open('edit', data);
|
||||
},
|
||||
reload() {
|
||||
this.loading = false
|
||||
this.$nextTick(() => {
|
||||
|
@ -138,16 +149,6 @@ export default {
|
|||
this.list();
|
||||
});
|
||||
},
|
||||
add(param) {
|
||||
param.projectId = this.projectId;
|
||||
param.protocol = this.condition.protocol;
|
||||
this.$post("/file/module/add", param, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.list();
|
||||
}, (error) => {
|
||||
this.list();
|
||||
});
|
||||
},
|
||||
remove(nodeIds) {
|
||||
this.$post("/file/module/delete", nodeIds, () => {
|
||||
this.list();
|
||||
|
|
|
@ -117,6 +117,16 @@ export default {
|
|||
type: String,
|
||||
default: "view"
|
||||
},
|
||||
//添加操作的操作类型
|
||||
operation_type_add: {
|
||||
type: String,
|
||||
default: "simple"
|
||||
},
|
||||
//修改操作的操作类型
|
||||
operation_type_edit: {
|
||||
type: String,
|
||||
default: "simple"
|
||||
},
|
||||
treeNodes: {
|
||||
type: Array
|
||||
},
|
||||
|
@ -254,20 +264,23 @@ export default {
|
|||
}
|
||||
},
|
||||
edit(node, data, isAppend) {
|
||||
this.$set(data, 'isEdit', true);
|
||||
this.$nextTick(() => {
|
||||
this.$refs.nameInput.focus();
|
||||
|
||||
// 不知为何,执行this.$set(data, 'isEdit', true);进入编辑状态之后过滤会失效,重新执行下过滤
|
||||
if (!isAppend) {
|
||||
this.$nextTick(() => {
|
||||
this.filter(this.filterText);
|
||||
});
|
||||
this.$nextTick(() => {
|
||||
this.$emit('filter');
|
||||
});
|
||||
}
|
||||
});
|
||||
if (this.operation_type_edit === 'simple') {
|
||||
this.$set(data, 'isEdit', true);
|
||||
this.$nextTick(() => {
|
||||
this.$refs.nameInput.focus();
|
||||
// 不知为何,执行this.$set(data, 'isEdit', true);进入编辑状态之后过滤会失效,重新执行下过滤
|
||||
if (!isAppend) {
|
||||
this.$nextTick(() => {
|
||||
this.filter(this.filterText);
|
||||
});
|
||||
this.$nextTick(() => {
|
||||
this.$emit('filter');
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (this.operation_type_edit === 'external') {
|
||||
this.$emit("editOperation", data);
|
||||
}
|
||||
},
|
||||
increase(id) {
|
||||
this.traverse(id, node => {
|
||||
|
@ -317,21 +330,33 @@ export default {
|
|||
}
|
||||
},
|
||||
append(node, data) {
|
||||
const newChild = {
|
||||
id: undefined,
|
||||
isEdit: false,
|
||||
name: "",
|
||||
children: []
|
||||
};
|
||||
if (!data.children) {
|
||||
this.$set(data, 'children', [])
|
||||
if (this.operation_type_add === 'simple') {
|
||||
const newChild = {
|
||||
id: undefined,
|
||||
isEdit: false,
|
||||
name: "",
|
||||
children: []
|
||||
};
|
||||
if (!data.children) {
|
||||
this.$set(data, 'children', [])
|
||||
}
|
||||
data.children.push(newChild);
|
||||
this.edit(node, newChild, true);
|
||||
node.expanded = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.nameInput.focus();
|
||||
});
|
||||
} else if (this.operation_type_add === 'external') {
|
||||
let param = {};
|
||||
param.parentId = node.id;
|
||||
param.level = 1;
|
||||
if (data.id != 'root') {
|
||||
// 非根节点
|
||||
param.parentId = data.id;
|
||||
param.level = data.level + 1;
|
||||
}
|
||||
this.$emit("addOperation", param);
|
||||
}
|
||||
data.children.push(newChild);
|
||||
this.edit(node, newChild, true);
|
||||
node.expanded = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.nameInput.focus();
|
||||
});
|
||||
},
|
||||
save(node, data) {
|
||||
if (data.name.trim() === '') {
|
||||
|
|
|
@ -870,6 +870,34 @@ export default {
|
|||
compare: 'Compare',
|
||||
change_latest_tip: 'This operation will modify the default display of the interface, scene, test case and other list pages, which may take some time. Please wait! '
|
||||
},
|
||||
project_file: {
|
||||
file_module_type: {
|
||||
module: 'Module',
|
||||
repository: 'Repository'
|
||||
},
|
||||
file: {
|
||||
branch: 'File branck',
|
||||
path: 'File path',
|
||||
},
|
||||
repository: {
|
||||
name: 'Repository name',
|
||||
path: 'Path',
|
||||
token: 'Token',
|
||||
desc: 'Description',
|
||||
version_history: 'History',
|
||||
file_version: 'Version',
|
||||
update_log: 'Commit log',
|
||||
},
|
||||
validation: {
|
||||
input_repository_name: 'Input repository name',
|
||||
input_repository_path: 'Input repository path',
|
||||
input_repository_token: 'Input repository token',
|
||||
input_file_branch: 'Input file branch',
|
||||
input_file_path: 'Input file path',
|
||||
input_gitee_user_please: 'Gitee uses need input user name',
|
||||
can_not_move_repository_file: 'Repository file can not move',
|
||||
},
|
||||
},
|
||||
timing_clean_plan_report: "Regularly clean up test report",
|
||||
timing_clean_api_report: "Regularly clean up api report",
|
||||
timing_clean_load_report: "Regularly clean up performance report",
|
||||
|
|
|
@ -879,6 +879,34 @@ export default {
|
|||
compare: '对比',
|
||||
change_latest_tip: '此操作会修改接口,场景,测试用例等列表页面的默认展示,可能会消耗一些时间。请耐心等待!'
|
||||
},
|
||||
project_file: {
|
||||
file_module_type: {
|
||||
module: '模块',
|
||||
repository: '存储库'
|
||||
},
|
||||
file: {
|
||||
branch: '文件分支',
|
||||
path: '文件路径',
|
||||
},
|
||||
repository: {
|
||||
name: '存储库名称',
|
||||
path: '存储库地址',
|
||||
token: 'Token',
|
||||
desc: '描述',
|
||||
version_history: '版本历史',
|
||||
file_version: '文件版本',
|
||||
update_log: '更新记录',
|
||||
},
|
||||
validation: {
|
||||
input_repository_name: '请输入存储库名称',
|
||||
input_repository_path: '请输入存储库地址',
|
||||
input_repository_token: '请输入存储库Token',
|
||||
input_file_branch: '请输入文件分支',
|
||||
input_file_path: '请输入文件路径',
|
||||
input_gitee_user_please: 'Gitee用户需要输入用户名',
|
||||
can_not_move_repository_file: '文件库文件无法移动',
|
||||
},
|
||||
},
|
||||
timing_clean_plan_report: "定时清理测试计划报告",
|
||||
timing_clean_api_report: "定时清理接口测试报告",
|
||||
timing_clean_load_report: "定时清理性能测试报告",
|
||||
|
|
|
@ -875,6 +875,34 @@ export default {
|
|||
compare: '對比',
|
||||
change_latest_tip: '此操作會修改接口,場景,測試用例等列表頁面的默認展示,可能會消耗一些時間。請耐心等待! '
|
||||
},
|
||||
project_file: {
|
||||
file_module_type: {
|
||||
module: '模塊',
|
||||
repository: '存儲庫'
|
||||
},
|
||||
repository: {
|
||||
name: '存儲庫名稱',
|
||||
path: '存儲庫地址',
|
||||
token: 'Token',
|
||||
desc: '描述',
|
||||
version_history: '版本歷史',
|
||||
file_version: '文件版本',
|
||||
update_log: '更新記錄',
|
||||
},
|
||||
file: {
|
||||
branch: '文件分支',
|
||||
path: '文件路徑',
|
||||
},
|
||||
validation: {
|
||||
input_repository_name: '請輸入存儲庫名稱',
|
||||
input_repository_path: '請輸入存儲庫地址',
|
||||
input_repository_token: '請輸入存儲庫Token',
|
||||
input_file_branch: '请输入文件分支',
|
||||
input_file_path: '请输入文件路徑',
|
||||
input_gitee_user_please: 'Gitee用戶需要輸入用戶名',
|
||||
can_not_move_repository_file: '文件庫文件無法移動',
|
||||
},
|
||||
},
|
||||
timing_clean_plan_report: "定時清理測試計劃報告",
|
||||
timing_clean_api_report: "定時清理接口測試報告",
|
||||
timing_clean_load_report: "定時清理性能測試報告",
|
||||
|
|
Loading…
Reference in New Issue