提交 99c46579 编写于 作者: F fit2-zhao
......@@ -98,7 +98,7 @@ public class APITestService {
checkQuota();
request.setBodyUploadIds(null);
ApiTest test = createTest(request);
saveFile(test.getId(), file);
saveFile(test, file);
return test;
}
......@@ -112,7 +112,7 @@ public class APITestService {
request.setBodyUploadIds(null);
ApiTest test = updateTest(request);
createBodyFiles(test, bodyUploadIds, bodyFiles);
saveFile(test.getId(), file);
saveFile(test, file);
}
private void createBodyFiles(ApiTest test, List<String> bodyUploadIds, List<MultipartFile> bodyFiles) {
......@@ -292,10 +292,10 @@ public class APITestService {
return test;
}
private void saveFile(String testId, MultipartFile file) {
final FileMetadata fileMetadata = fileService.saveFile(file);
private void saveFile(ApiTest apiTest, MultipartFile file) {
final FileMetadata fileMetadata = fileService.saveFile(file, apiTest.getProjectId());
ApiTestFile apiTestFile = new ApiTestFile();
apiTestFile.setTestId(testId);
apiTestFile.setTestId(apiTest.getId());
apiTestFile.setFileId(fileMetadata.getId());
apiTestFileMapper.insert(apiTestFile);
}
......@@ -532,12 +532,12 @@ public class APITestService {
//处理附件
Map<String, String> attachmentFiles = new HashMap<>();
int fileIndex = 0;
for (String filePath: attachmentFilePathList) {
File file = new File(filePath);
if(file.exists() && file.isFile()){
try{
FileMetadata fileMetadata = fileService.saveFile(file,FileUtil.readAsByteArray(file),fileIndex++);
FileMetadata fileMetadata = fileService.saveFile(file,FileUtil.readAsByteArray(file));
attachmentFiles.put(fileMetadata.getId(),fileMetadata.getName());
}catch (Exception e){
e.printStackTrace();
......
package io.metersphere.base.domain;
import lombok.Data;
import java.io.Serializable;
import lombok.Data;
@Data
public class FileMetadata implements Serializable {
......@@ -18,7 +17,7 @@ public class FileMetadata implements Serializable {
private Long size;
private Integer sort;
private String projectId;
private static final long serialVersionUID = 1L;
}
\ No newline at end of file
......@@ -494,63 +494,73 @@ public class FileMetadataExample {
return (Criteria) this;
}
public Criteria andSortIsNull() {
addCriterion("sort is null");
public Criteria andProjectIdIsNull() {
addCriterion("project_id is null");
return (Criteria) this;
}
public Criteria andSortIsNotNull() {
addCriterion("sort is not null");
public Criteria andProjectIdIsNotNull() {
addCriterion("project_id is not null");
return (Criteria) this;
}
public Criteria andSortEqualTo(Integer value) {
addCriterion("sort =", value, "sort");
public Criteria andProjectIdEqualTo(String value) {
addCriterion("project_id =", value, "projectId");
return (Criteria) this;
}
public Criteria andSortNotEqualTo(Integer value) {
addCriterion("sort <>", value, "sort");
public Criteria andProjectIdNotEqualTo(String value) {
addCriterion("project_id <>", value, "projectId");
return (Criteria) this;
}
public Criteria andSortGreaterThan(Integer value) {
addCriterion("sort >", value, "sort");
public Criteria andProjectIdGreaterThan(String value) {
addCriterion("project_id >", value, "projectId");
return (Criteria) this;
}
public Criteria andSortGreaterThanOrEqualTo(Integer value) {
addCriterion("sort >=", value, "sort");
public Criteria andProjectIdGreaterThanOrEqualTo(String value) {
addCriterion("project_id >=", value, "projectId");
return (Criteria) this;
}
public Criteria andSortLessThan(Integer value) {
addCriterion("sort <", value, "sort");
public Criteria andProjectIdLessThan(String value) {
addCriterion("project_id <", value, "projectId");
return (Criteria) this;
}
public Criteria andSortLessThanOrEqualTo(Integer value) {
addCriterion("sort <=", value, "sort");
public Criteria andProjectIdLessThanOrEqualTo(String value) {
addCriterion("project_id <=", value, "projectId");
return (Criteria) this;
}
public Criteria andSortIn(List<Integer> values) {
addCriterion("sort in", values, "sort");
public Criteria andProjectIdLike(String value) {
addCriterion("project_id like", value, "projectId");
return (Criteria) this;
}
public Criteria andSortNotIn(List<Integer> values) {
addCriterion("sort not in", values, "sort");
public Criteria andProjectIdNotLike(String value) {
addCriterion("project_id not like", value, "projectId");
return (Criteria) this;
}
public Criteria andSortBetween(Integer value1, Integer value2) {
addCriterion("sort between", value1, value2, "sort");
public Criteria andProjectIdIn(List<String> values) {
addCriterion("project_id in", values, "projectId");
return (Criteria) this;
}
public Criteria andSortNotBetween(Integer value1, Integer value2) {
addCriterion("sort not between", value1, value2, "sort");
public Criteria andProjectIdNotIn(List<String> values) {
addCriterion("project_id not in", values, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdBetween(String value1, String value2) {
addCriterion("project_id between", value1, value2, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdNotBetween(String value1, String value2) {
addCriterion("project_id not between", value1, value2, "projectId");
return (Criteria) this;
}
}
......
package io.metersphere.base.domain;
import lombok.Data;
import java.io.Serializable;
import lombok.Data;
@Data
public class LoadTestFile implements Serializable {
......@@ -10,5 +9,7 @@ public class LoadTestFile implements Serializable {
private String fileId;
private Integer sort;
private static final long serialVersionUID = 1L;
}
\ No newline at end of file
......@@ -243,6 +243,66 @@ public class LoadTestFileExample {
addCriterion("file_id not between", value1, value2, "fileId");
return (Criteria) this;
}
public Criteria andSortIsNull() {
addCriterion("sort is null");
return (Criteria) this;
}
public Criteria andSortIsNotNull() {
addCriterion("sort is not null");
return (Criteria) this;
}
public Criteria andSortEqualTo(Integer value) {
addCriterion("sort =", value, "sort");
return (Criteria) this;
}
public Criteria andSortNotEqualTo(Integer value) {
addCriterion("sort <>", value, "sort");
return (Criteria) this;
}
public Criteria andSortGreaterThan(Integer value) {
addCriterion("sort >", value, "sort");
return (Criteria) this;
}
public Criteria andSortGreaterThanOrEqualTo(Integer value) {
addCriterion("sort >=", value, "sort");
return (Criteria) this;
}
public Criteria andSortLessThan(Integer value) {
addCriterion("sort <", value, "sort");
return (Criteria) this;
}
public Criteria andSortLessThanOrEqualTo(Integer value) {
addCriterion("sort <=", value, "sort");
return (Criteria) this;
}
public Criteria andSortIn(List<Integer> values) {
addCriterion("sort in", values, "sort");
return (Criteria) this;
}
public Criteria andSortNotIn(List<Integer> values) {
addCriterion("sort not in", values, "sort");
return (Criteria) this;
}
public Criteria andSortBetween(Integer value1, Integer value2) {
addCriterion("sort between", value1, value2, "sort");
return (Criteria) this;
}
public Criteria andSortNotBetween(Integer value1, Integer value2) {
addCriterion("sort not between", value1, value2, "sort");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {
......
......@@ -8,7 +8,7 @@
<result column="create_time" jdbcType="BIGINT" property="createTime" />
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
<result column="size" jdbcType="BIGINT" property="size" />
<result column="sort" jdbcType="INTEGER" property="sort" />
<result column="project_id" jdbcType="VARCHAR" property="projectId" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
......@@ -69,7 +69,7 @@
</where>
</sql>
<sql id="Base_Column_List">
id, `name`, `type`, create_time, update_time, `size`, sort
id, `name`, `type`, create_time, update_time, `size`, project_id
</sql>
<select id="selectByExample" parameterType="io.metersphere.base.domain.FileMetadataExample" resultMap="BaseResultMap">
select
......@@ -104,10 +104,10 @@
<insert id="insert" parameterType="io.metersphere.base.domain.FileMetadata">
insert into file_metadata (id, `name`, `type`,
create_time, update_time, `size`,
sort)
project_id)
values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR},
#{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}, #{size,jdbcType=BIGINT},
#{sort,jdbcType=INTEGER})
#{projectId,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.FileMetadata">
insert into file_metadata
......@@ -130,8 +130,8 @@
<if test="size != null">
`size`,
</if>
<if test="sort != null">
sort,
<if test="projectId != null">
project_id,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
......@@ -153,8 +153,8 @@
<if test="size != null">
#{size,jdbcType=BIGINT},
</if>
<if test="sort != null">
#{sort,jdbcType=INTEGER},
<if test="projectId != null">
#{projectId,jdbcType=VARCHAR},
</if>
</trim>
</insert>
......@@ -185,8 +185,8 @@
<if test="record.size != null">
`size` = #{record.size,jdbcType=BIGINT},
</if>
<if test="record.sort != null">
sort = #{record.sort,jdbcType=INTEGER},
<if test="record.projectId != null">
project_id = #{record.projectId,jdbcType=VARCHAR},
</if>
</set>
<if test="_parameter != null">
......@@ -201,7 +201,7 @@
create_time = #{record.createTime,jdbcType=BIGINT},
update_time = #{record.updateTime,jdbcType=BIGINT},
`size` = #{record.size,jdbcType=BIGINT},
sort = #{record.sort,jdbcType=INTEGER}
project_id = #{record.projectId,jdbcType=VARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
......@@ -224,8 +224,8 @@
<if test="size != null">
`size` = #{size,jdbcType=BIGINT},
</if>
<if test="sort != null">
sort = #{sort,jdbcType=INTEGER},
<if test="projectId != null">
project_id = #{projectId,jdbcType=VARCHAR},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
......@@ -237,7 +237,7 @@
create_time = #{createTime,jdbcType=BIGINT},
update_time = #{updateTime,jdbcType=BIGINT},
`size` = #{size,jdbcType=BIGINT},
sort = #{sort,jdbcType=INTEGER}
project_id = #{projectId,jdbcType=VARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
</mapper>
\ No newline at end of file
......@@ -4,6 +4,7 @@
<resultMap id="BaseResultMap" type="io.metersphere.base.domain.LoadTestFile">
<result column="test_id" jdbcType="VARCHAR" property="testId" />
<result column="file_id" jdbcType="VARCHAR" property="fileId" />
<result column="sort" jdbcType="INTEGER" property="sort" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
......@@ -64,7 +65,7 @@
</where>
</sql>
<sql id="Base_Column_List">
test_id, file_id
test_id, file_id, sort
</sql>
<select id="selectByExample" parameterType="io.metersphere.base.domain.LoadTestFileExample" resultMap="BaseResultMap">
select
......@@ -87,8 +88,10 @@
</if>
</delete>
<insert id="insert" parameterType="io.metersphere.base.domain.LoadTestFile">
insert into load_test_file (test_id, file_id)
values (#{testId,jdbcType=VARCHAR}, #{fileId,jdbcType=VARCHAR})
insert into load_test_file (test_id, file_id, sort
)
values (#{testId,jdbcType=VARCHAR}, #{fileId,jdbcType=VARCHAR}, #{sort,jdbcType=INTEGER}
)
</insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.LoadTestFile">
insert into load_test_file
......@@ -99,6 +102,9 @@
<if test="fileId != null">
file_id,
</if>
<if test="sort != null">
sort,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="testId != null">
......@@ -107,6 +113,9 @@
<if test="fileId != null">
#{fileId,jdbcType=VARCHAR},
</if>
<if test="sort != null">
#{sort,jdbcType=INTEGER},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="io.metersphere.base.domain.LoadTestFileExample" resultType="java.lang.Long">
......@@ -124,6 +133,9 @@
<if test="record.fileId != null">
file_id = #{record.fileId,jdbcType=VARCHAR},
</if>
<if test="record.sort != null">
sort = #{record.sort,jdbcType=INTEGER},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
......@@ -132,7 +144,8 @@
<update id="updateByExample" parameterType="map">
update load_test_file
set test_id = #{record.testId,jdbcType=VARCHAR},
file_id = #{record.fileId,jdbcType=VARCHAR}
file_id = #{record.fileId,jdbcType=VARCHAR},
sort = #{record.sort,jdbcType=INTEGER}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
......
package io.metersphere.base.mapper.ext;
import io.metersphere.base.domain.FileMetadata;
import io.metersphere.base.domain.LoadTest;
import io.metersphere.dto.LoadTestDTO;
import io.metersphere.performance.dto.LoadTestFileDTO;
import io.metersphere.performance.request.QueryTestPlanRequest;
import org.apache.ibatis.annotations.Param;
......@@ -18,6 +18,6 @@ public interface ExtLoadTestMapper {
LoadTest getNextNum(@Param("projectId") String projectId);
List<LoadTestFileDTO> getProjectFiles(@Param("projectId") String projectId, @Param("loadTypes") List<String> loadType);
List<FileMetadata> getProjectFiles(@Param("projectId") String projectId, @Param("loadTypes") List<String> loadType);
}
......@@ -132,11 +132,9 @@
select * from load_test lt where lt.project_id = #{projectId} ORDER BY num DESC LIMIT 1;
</select>
<select id="getProjectFiles" resultType="io.metersphere.performance.dto.LoadTestFileDTO">
SELECT file_metadata.*, load_test.id as testId, load_test.name as testName
FROM load_test
JOIN load_test_file ON load_test.id = load_test_file.test_id
JOIN file_metadata ON load_test_file.file_id = file_metadata.id
<select id="getProjectFiles" resultType="io.metersphere.base.domain.FileMetadata">
SELECT file_metadata.*
FROM file_metadata
WHERE file_metadata.type IN
<foreach collection="loadTypes" item="id" separator="," open="(" close=")">
#{id}
......
......@@ -14,6 +14,7 @@ import io.metersphere.service.ProjectService;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.util.List;
......@@ -84,4 +85,13 @@ public class ProjectController {
projectService.updateProject(Project);
}
@PostMapping(value = "upload/files/{projectId}", consumes = {"multipart/form-data"})
public void uploadFiles(@PathVariable String projectId, @RequestPart(value = "file") List<MultipartFile> files) {
projectService.uploadFiles(projectId, files);
}
@GetMapping(value = "delete/file/{fileId}")
public void deleteFile(@PathVariable String fileId) {
projectService.deleteFile(fileId);
}
}
......@@ -15,7 +15,6 @@ import io.metersphere.dto.DashboardTestDTO;
import io.metersphere.dto.LoadTestDTO;
import io.metersphere.dto.ScheduleDao;
import io.metersphere.performance.dto.LoadTestExportJmx;
import io.metersphere.performance.dto.LoadTestFileDTO;
import io.metersphere.performance.request.*;
import io.metersphere.performance.service.PerformanceTestService;
import io.metersphere.service.CheckPermissionService;
......@@ -122,7 +121,7 @@ public class PerformanceTestController {
}
@GetMapping("/project/{loadType}/{projectId}/{goPage}/{pageSize}")
public Pager<List<LoadTestFileDTO>> getProjectFiles(@PathVariable String projectId, @PathVariable String loadType,
public Pager<List<FileMetadata>> getProjectFiles(@PathVariable String projectId, @PathVariable String loadType,
@PathVariable int goPage, @PathVariable int pageSize) {
checkPermissionService.checkProjectOwner(projectId);
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
......@@ -148,7 +147,7 @@ public class PerformanceTestController {
@GetMapping("/file/metadata/{testId}")
public List<FileMetadata> getFileMetadata(@PathVariable String testId) {
checkPermissionService.checkPerformanceTestOwner(testId);
return fileService.getFileMetadataByTestId(testId);
return performanceTestService.getFileMetadataByTestId(testId);
}
@GetMapping("/file/getMetadataById/{metadataId}")
......@@ -156,6 +155,11 @@ public class PerformanceTestController {
return fileService.getFileMetadataById(metadataId);
}
@PostMapping("/file/{projectId}/getMetadataByName")
public List<FileMetadata> getProjectMetadataByName(@PathVariable String projectId, @RequestBody QueryProjectFileRequest request) {
return fileService.getProjectFiles(projectId, request);
}
@PostMapping("/file/download")
public ResponseEntity<byte[]> downloadJmx(@RequestBody FileOperationRequest fileOperationRequest) {
byte[] bytes = fileService.loadFileAsBytes(fileOperationRequest.getId());
......
package io.metersphere.performance.dto;
import io.metersphere.base.domain.FileMetadata;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class LoadTestFileDTO extends FileMetadata {
private String testId;
private String testName;
}
......@@ -15,6 +15,7 @@ import io.metersphere.i18n.Translator;
import io.metersphere.performance.engine.docker.DockerTestEngine;
import io.metersphere.performance.parse.EngineSourceParser;
import io.metersphere.performance.parse.EngineSourceParserFactory;
import io.metersphere.performance.service.PerformanceTestService;
import io.metersphere.service.FileService;
import io.metersphere.service.KubernetesTestEngine;
import io.metersphere.service.TestResourcePoolService;
......@@ -46,6 +47,7 @@ import java.util.stream.Collectors;
@Service
public class EngineFactory {
private static FileService fileService;
private static PerformanceTestService performanceTestService;
private static TestResourcePoolService testResourcePoolService;
private static Class<? extends KubernetesTestEngine> kubernetesTestEngineClass;
......@@ -87,7 +89,7 @@ public class EngineFactory {
}
public static EngineContext createContext(LoadTestWithBLOBs loadTest, String resourceId, double ratio, long startTime, String reportId, int resourceIndex) {
final List<FileMetadata> fileMetadataList = fileService.getFileMetadataByTestId(loadTest.getId());
final List<FileMetadata> fileMetadataList = performanceTestService.getFileMetadataByTestId(loadTest.getId());
if (org.springframework.util.CollectionUtils.isEmpty(fileMetadataList)) {
MSException.throwException(Translator.get("run_load_test_file_not_found") + loadTest.getId());
}
......@@ -235,4 +237,9 @@ public class EngineFactory {
public void setTestResourcePoolService(TestResourcePoolService testResourcePoolService) {
EngineFactory.testResourcePoolService = testResourcePoolService;
}
@Resource
public void setPerformanceTestService(PerformanceTestService performanceTestService) {
EngineFactory.performanceTestService = performanceTestService;
}
}
package io.metersphere.performance.request;
import lombok.Data;
@Data
public class QueryProjectFileRequest {
private String filename;
}
......@@ -21,7 +21,6 @@ import io.metersphere.dto.ScheduleDao;
import io.metersphere.i18n.Translator;
import io.metersphere.job.sechedule.PerformanceTestJob;
import io.metersphere.performance.dto.LoadTestExportJmx;
import io.metersphere.performance.dto.LoadTestFileDTO;
import io.metersphere.performance.engine.Engine;
import io.metersphere.performance.engine.EngineFactory;
import io.metersphere.performance.engine.producer.LoadTestProducer;
......@@ -124,8 +123,10 @@ public class PerformanceTestService {
loadTestFileMapper.deleteByExample(loadTestFileExample);
if (!CollectionUtils.isEmpty(loadTestFiles)) {
final List<String> fileIds = loadTestFiles.stream().map(LoadTestFile::getFileId).collect(Collectors.toList());
fileService.deleteFileByIds(fileIds);
List<String> fileIds = loadTestFiles.stream().map(LoadTestFile::getFileId).collect(Collectors.toList());
LoadTestFileExample example3 = new LoadTestFileExample();
example3.createCriteria().andFileIdIn(fileIds);
loadTestFileMapper.deleteByExample(example3);
}
}
......@@ -138,15 +139,15 @@ public class PerformanceTestService {
// 导入项目里其他的文件
this.importFiles(importFileIds, loadTest.getId(), request.getFileSorts());
// 保存上传的文件
this.saveUploadFiles(files, loadTest.getId(), request.getFileSorts());
this.saveUploadFiles(files, loadTest, request.getFileSorts());
//关联转化的文件
this.conversionFiles(loadTest.getId(),request.getConversionFileIdList());
this.conversionFiles(loadTest.getId(), request.getConversionFileIdList());
return loadTest.getId();
}
private void conversionFiles(String id, List<String> conversionFileIdList) {
for (String metaFileId : conversionFileIdList) {
if(!this.loadTestFileExsits(id,metaFileId)){
if (!this.loadTestFileExsits(id, metaFileId)) {
LoadTestFile loadTestFile = new LoadTestFile();
loadTestFile.setTestId(id);
loadTestFile.setFileId(metaFileId);
......@@ -161,21 +162,22 @@ public class PerformanceTestService {
example.createCriteria().andTestIdEqualTo(testId).andFileIdEqualTo(metaFileId);
long loadTestFiles = loadTestFileMapper.countByExample(example);
if(!fileExsits && loadTestFiles>0){
if (!fileExsits && loadTestFiles > 0) {
return false;
}else {
return true;
} else {
return true;
}
}
private void saveUploadFiles(List<MultipartFile> files, String testId, Map<String, Integer> fileSorts) {
private void saveUploadFiles(List<MultipartFile> files, LoadTest loadTest, Map<String, Integer> fileSorts) {
if (files != null) {
for (int i = 0; i < files.size(); i++) {
MultipartFile file = files.get(i);
final FileMetadata fileMetadata = fileService.saveFile(file, fileSorts.getOrDefault(file.getOriginalFilename(), i));
FileMetadata fileMetadata = fileService.saveFile(file, loadTest.getProjectId());
LoadTestFile loadTestFile = new LoadTestFile();
loadTestFile.setTestId(testId);
loadTestFile.setTestId(loadTest.getId());
loadTestFile.setFileId(fileMetadata.getId());
loadTestFile.setSort(fileSorts.getOrDefault(file.getOriginalFilename(), i));
loadTestFileMapper.insert(loadTestFile);
}
}
......@@ -184,12 +186,11 @@ public class PerformanceTestService {
private void importFiles(List<String> importFileIds, String testId, Map<String, Integer> fileSorts) {
for (int i = 0; i < importFileIds.size(); i++) {
String fileId = importFileIds.get(i);
FileMetadata fileMetadata = fileService.copyFile(fileId);
fileMetadata.setSort(fileSorts.getOrDefault(fileMetadata.getName(), i));
fileService.updateFileMetadata(fileMetadata);
FileMetadata fileMetadata = fileService.getFileMetadataById(fileId);
LoadTestFile loadTestFile = new LoadTestFile();
loadTestFile.setTestId(testId);
loadTestFile.setFileId(fileMetadata.getId());
loadTestFile.setFileId(fileId);
loadTestFile.setSort(fileSorts.getOrDefault(fileMetadata.getName(), i));
loadTestFileMapper.insert(loadTestFile);
}
}
......@@ -230,16 +231,23 @@ public class PerformanceTestService {
}
// 新选择了一个文件,删除原来的文件
List<FileMetadata> updatedFiles = request.getUpdatedFileList();
List<FileMetadata> originFiles = fileService.getFileMetadataByTestId(request.getId());
List<FileMetadata> originFiles = getFileMetadataByTestId(request.getId());
List<String> updatedFileIds = updatedFiles.stream().map(FileMetadata::getId).collect(Collectors.toList());
List<String> originFileIds = originFiles.stream().map(FileMetadata::getId).collect(Collectors.toList());
// 相减
List<String> deleteFileIds = ListUtils.subtract(originFileIds, updatedFileIds);
fileService.deleteFileByIds(deleteFileIds);
// 删除已经不相关的文件
LoadTestFileExample example3 = new LoadTestFileExample();
example3.createCriteria().andFileIdIn(deleteFileIds);
loadTestFileMapper.deleteByExample(example3);
// 导入项目里其他的文件
List<String> addFileIds = ListUtils.subtract(updatedFileIds, originFileIds);
this.importFiles(addFileIds, request.getId(), request.getFileSorts());
this.saveUploadFiles(files, request.getId(), request.getFileSorts());
// 处理新上传的文件
this.saveUploadFiles(files, loadTest, request.getFileSorts());
loadTest.setName(request.getName());
loadTest.setProjectId(request.getProjectId());
......@@ -400,7 +408,7 @@ public class PerformanceTestService {
}
public List<LoadTestExportJmx> getJmxContent(String testId) {
List<FileMetadata> fileMetadataList = fileService.getFileMetadataByTestId(testId);
List<FileMetadata> fileMetadataList = getFileMetadataByTestId(testId);
List<LoadTestExportJmx> results = new ArrayList<>();
for (FileMetadata metadata : fileMetadataList) {
if (FileType.JMX.name().equals(metadata.getType())) {
......@@ -449,13 +457,7 @@ public class PerformanceTestService {
List<LoadTestFile> loadTestFiles = loadTestFileMapper.selectByExample(loadTestFileExample);
if (!CollectionUtils.isEmpty(loadTestFiles)) {
loadTestFiles.forEach(loadTestFile -> {
FileMetadata fileMetadata = fileService.copyFile(loadTestFile.getFileId());
if (fileMetadata == null) {
// 如果性能测试出现文件变更,这里会有 null
return;
}
loadTestFile.setTestId(copy.getId());
loadTestFile.setFileId(fileMetadata.getId());
loadTestFileMapper.insert(loadTestFile);
});
}
......@@ -557,13 +559,18 @@ public class PerformanceTestService {
}
}
public List<LoadTestFileDTO> getProjectFiles(String projectId, String loadType) {
public List<FileMetadata> getProjectFiles(String projectId, String loadType) {
List<String> loadTypes = new ArrayList<>();
loadTypes.add(StringUtils.upperCase(loadType));
if (StringUtils.equalsIgnoreCase(loadType, "resource")) {
loadTypes.add(FileType.CSV.name());
loadTypes.add(FileType.JAR.name());
}
if (StringUtils.equalsIgnoreCase(loadType, "all")) {
loadTypes.add(FileType.CSV.name());
loadTypes.add(FileType.JAR.name());
loadTypes.add(FileType.JMX.name());
}
return extLoadTestMapper.getProjectFiles(projectId, loadTypes);
}
......@@ -580,4 +587,16 @@ public class PerformanceTestService {
return results;
}
public List<FileMetadata> getFileMetadataByTestId(String testId) {
LoadTestFileExample loadTestFileExample = new LoadTestFileExample();
loadTestFileExample.createCriteria().andTestIdEqualTo(testId);
loadTestFileExample.setOrderByClause("sort asc");
List<LoadTestFile> loadTestFiles = loadTestFileMapper.selectByExample(loadTestFileExample);
List<String> fileIds = loadTestFiles.stream().map(LoadTestFile::getFileId).collect(Collectors.toList());
FileMetadataExample example = new FileMetadataExample();
example.createCriteria().andIdIn(fileIds);
return fileService.getFileMetadataByIds(fileIds);
}
}
......@@ -7,8 +7,10 @@ import io.metersphere.base.mapper.LoadTestFileMapper;
import io.metersphere.base.mapper.TestCaseFileMapper;
import io.metersphere.commons.constants.FileType;
import io.metersphere.commons.exception.MSException;
import io.metersphere.performance.request.QueryProjectFileRequest;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
......@@ -37,21 +39,6 @@ public class FileService {
return fileContent.getFile();
}
public List<FileMetadata> getFileMetadataByTestId(String testId) {
LoadTestFileExample loadTestFileExample = new LoadTestFileExample();
loadTestFileExample.createCriteria().andTestIdEqualTo(testId);
final List<LoadTestFile> loadTestFiles = loadTestFileMapper.selectByExample(loadTestFileExample);
if (CollectionUtils.isEmpty(loadTestFiles)) {
return new ArrayList<>();
}
List<String> fileIds = loadTestFiles.stream().map(LoadTestFile::getFileId).collect(Collectors.toList());
FileMetadataExample example = new FileMetadataExample();
example.createCriteria().andIdIn(fileIds);
example.setOrderByClause("sort asc"); // 安装顺序排序
return fileMetadataMapper.selectByExample(example);
}
public FileContent getFileContent(String fileId) {
return fileContentMapper.selectByPrimaryKey(fileId);
}
......@@ -86,20 +73,16 @@ public class FileService {
fileContentMapper.deleteByExample(example2);
}
public FileMetadata saveFile(MultipartFile file) {
return saveFile(file, 0);
}
public FileMetadata saveFile(MultipartFile file, Integer sort) {
public FileMetadata saveFile(MultipartFile file, String projectId) {
final FileMetadata fileMetadata = new FileMetadata();
fileMetadata.setId(UUID.randomUUID().toString());
fileMetadata.setName(file.getOriginalFilename());
fileMetadata.setSize(file.getSize());
fileMetadata.setProjectId(projectId);
fileMetadata.setCreateTime(System.currentTimeMillis());
fileMetadata.setUpdateTime(System.currentTimeMillis());
FileType fileType = getFileType(fileMetadata.getName());
fileMetadata.setType(fileType.name());
fileMetadata.setSort(sort);
fileMetadataMapper.insert(fileMetadata);
FileContent fileContent = new FileContent();
......@@ -114,7 +97,11 @@ public class FileService {
return fileMetadata;
}
public FileMetadata saveFile(File file, byte[] fileByte, Integer sort) {
public FileMetadata saveFile(MultipartFile file) {
return saveFile(file, null);
}
public FileMetadata saveFile(File file, byte[] fileByte) {
final FileMetadata fileMetadata = new FileMetadata();
fileMetadata.setId(UUID.randomUUID().toString());
fileMetadata.setName(file.getName());
......@@ -123,7 +110,6 @@ public class FileService {
fileMetadata.setUpdateTime(System.currentTimeMillis());
FileType fileType = getFileType(fileMetadata.getName());
fileMetadata.setType(fileType.name());
fileMetadata.setSort(sort);
fileMetadataMapper.insert(fileMetadata);
FileContent fileContent = new FileContent();
......@@ -197,12 +183,6 @@ public class FileService {
return fileMetadataMapper.selectByPrimaryKey(fileId);
}
public List<FileMetadata> getProjectJMXs(String projectId) {
FileMetadataExample example = new FileMetadataExample();
fileMetadataMapper.selectByExample(example);
return null;
}
public void updateFileMetadata(FileMetadata fileMetadata) {
fileMetadataMapper.updateByPrimaryKeySelective(fileMetadata);
}
......@@ -211,10 +191,29 @@ public class FileService {
FileMetadataExample example = new FileMetadataExample();
example.createCriteria().andIdEqualTo(fileId);
long fileCount = fileMetadataMapper.countByExample(example);
if(fileCount>0){
return true;
}else {
return false;
if (fileCount > 0) {
return true;
} else {
return false;
}
}
public List<FileMetadata> getProjectFiles(String projectId, QueryProjectFileRequest request) {
FileMetadataExample example = new FileMetadataExample();
FileMetadataExample.Criteria criteria = example.createCriteria();
criteria.andProjectIdEqualTo(projectId);
if (!StringUtils.isEmpty(request.getFilename())) {
criteria.andNameEqualTo(request.getFilename());
}
return fileMetadataMapper.selectByExample(example);
}
public List<FileMetadata> getFileMetadataByIds(List<String> fileIds) {
if (CollectionUtils.isEmpty(fileIds)) {
return new ArrayList<>();
}
FileMetadataExample example = new FileMetadataExample();
example.createCriteria().andIdIn(fileIds);
return fileMetadataMapper.selectByExample(example);
}
}
\ No newline at end of file
......@@ -3,13 +3,12 @@ package io.metersphere.service;
import io.metersphere.api.dto.DeleteAPITestRequest;
import io.metersphere.api.dto.QueryAPITestRequest;
import io.metersphere.api.service.APITestService;
import io.metersphere.base.domain.LoadTest;
import io.metersphere.base.domain.LoadTestExample;
import io.metersphere.base.domain.Project;
import io.metersphere.base.domain.ProjectExample;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.ApiTestFileMapper;
import io.metersphere.base.mapper.LoadTestFileMapper;
import io.metersphere.base.mapper.LoadTestMapper;
import io.metersphere.base.mapper.ProjectMapper;
import io.metersphere.base.mapper.ext.*;
import io.metersphere.base.mapper.ext.ExtProjectMapper;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.ServiceUtils;
import io.metersphere.commons.utils.SessionUtils;
......@@ -17,6 +16,7 @@ import io.metersphere.controller.request.ProjectRequest;
import io.metersphere.dto.ProjectDTO;
import io.metersphere.i18n.Translator;
import io.metersphere.performance.request.DeleteTestPlanRequest;
import io.metersphere.performance.request.QueryProjectFileRequest;
import io.metersphere.performance.service.PerformanceTestService;
import io.metersphere.track.service.TestCaseService;
import io.metersphere.track.service.TestPlanProjectService;
......@@ -25,6 +25,7 @@ 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;
import java.util.List;
......@@ -43,14 +44,6 @@ public class ProjectService {
@Resource
private LoadTestMapper loadTestMapper;
@Resource
private ExtTestCaseMapper extTestCaseMapper;
@Resource
private ExtTestPlanMapper extTestPlanMapper;
@Resource
private ExtLoadTestMapper extLoadTestMapperMapper;
@Resource
private ExtApiTestMapper extApiTestMapper;
@Resource
private TestPlanService testPlanService;
@Resource
private TestCaseService testCaseService;
......@@ -58,6 +51,12 @@ public class ProjectService {
private APITestService apiTestService;
@Resource
private TestPlanProjectService testPlanProjectService;
@Resource
private FileService fileService;
@Resource
private LoadTestFileMapper loadTestFileMapper;
@Resource
private ApiTestFileMapper apiTestFileMapper;
public Project addProject(Project project) {
if (StringUtils.isBlank(project.getName())) {
......@@ -169,4 +168,49 @@ public class ProjectService {
public Project getProjectById(String id) {
return projectMapper.selectByPrimaryKey(id);
}
public void uploadFiles(String projectId, List<MultipartFile> files) {
if (files != null) {
for (MultipartFile file : files) {
QueryProjectFileRequest request = new QueryProjectFileRequest();
request.setFilename(file.getOriginalFilename());
if (CollectionUtils.isEmpty(fileService.getProjectFiles(projectId, request))) {
fileService.saveFile(file, projectId);
} else {
MSException.throwException(Translator.get("project_file_already_exists"));
}
}
}
}
public void deleteFile(String fileId) {
LoadTestFileExample example1 = new LoadTestFileExample();
example1.createCriteria().andFileIdEqualTo(fileId);
List<LoadTestFile> loadTestFiles = loadTestFileMapper.selectByExample(example1);
String errorMessage = "";
if (loadTestFiles.size() > 0) {
List<String> testIds = loadTestFiles.stream().map(LoadTestFile::getTestId).distinct().collect(Collectors.toList());
LoadTestExample example = new LoadTestExample();
example.createCriteria().andIdIn(testIds);
List<LoadTest> loadTests = loadTestMapper.selectByExample(example);
errorMessage += Translator.get("load_test") + ": " + StringUtils.join(loadTests.stream().map(LoadTest::getName).toArray(), ",");
errorMessage += "\n";
}
ApiTestFileExample example2 = new ApiTestFileExample();
example2.createCriteria().andFileIdEqualTo(fileId);
List<ApiTestFile> apiTestFiles = apiTestFileMapper.selectByExample(example2);
if (apiTestFiles.size() > 0) {
List<String> testIds = apiTestFiles.stream().map(ApiTestFile::getTestId).distinct().collect(Collectors.toList());
LoadTestExample example = new LoadTestExample();
example.createCriteria().andIdIn(testIds);
QueryAPITestRequest request = new QueryAPITestRequest();
request.setIds(testIds);
List<ApiTest> apiTests = apiTestService.listByIds(request);
errorMessage += Translator.get("api_test") + ": " + StringUtils.join(apiTests.stream().map(ApiTest::getName).toArray(), ",");
}
if (StringUtils.isNotBlank(errorMessage)) {
MSException.throwException(errorMessage + Translator.get("project_file_in_use"));
}
fileService.deleteFileById(fileId);
}
}
......@@ -662,7 +662,7 @@ public class TestCaseService {
}
files.forEach(file -> {
final FileMetadata fileMetadata = fileService.saveFile(file);
final FileMetadata fileMetadata = fileService.saveFile(file, testCaseWithBLOBs.getProjectId());
TestCaseFile testCaseFile = new TestCaseFile();
testCaseFile.setCaseId(testCaseWithBLOBs.getId());
testCaseFile.setFileId(fileMetadata.getId());
......@@ -695,7 +695,7 @@ public class TestCaseService {
if (files != null) {
files.forEach(file -> {
final FileMetadata fileMetadata = fileService.saveFile(file);
final FileMetadata fileMetadata = fileService.saveFile(file,testCaseWithBLOBs.getProjectId());
TestCaseFile testCaseFile = new TestCaseFile();
testCaseFile.setFileId(fileMetadata.getId());
testCaseFile.setCaseId(request.getId());
......
......@@ -90,10 +90,6 @@ ALTER TABLE test_case_review
alter table test_plan_api_scenario
change environment_id environment longtext null comment 'Relevance environment';
-- file add sort column
alter table file_metadata
add sort int default 0;
-- add Original state
alter table api_definition add original_state varchar(64);
alter table api_scenario add original_state varchar(64);
......@@ -147,3 +143,16 @@ update schedule sch inner join swagger_url_project sup on
set sch.name = LEFT(SUBSTRING_INDEX(sup.swagger_url, '/', 3), 100);
-- delete an unused colum
alter table schedule drop column custom_data;
-- add sort column
alter table load_test_file add sort int default 0;
UPDATE file_metadata JOIN (SELECT file_id, project_id
FROM load_test_file
JOIN load_test ON test_id = load_test.id) temp ON file_id = file_metadata.id
SET file_metadata.project_id = temp.project_id;
UPDATE file_metadata JOIN (SELECT file_id, project_id
FROM api_test_file
JOIN api_test ON test_id = api_test.id) temp ON file_id = file_metadata.id
SET file_metadata.project_id = temp.project_id;
\ No newline at end of file
......@@ -66,6 +66,8 @@ only_one_k8s=Only one K8S can be added
#project
project_name_is_null=Project name cannot be null
project_name_already_exists=The project name already exists
project_file_already_exists=The file already exists
project_file_in_use=use this file and cannot be deleted.
#organization
organization_name_is_null=organization name cannot be null
organization_name_already_exists=The organization name already exists
......@@ -75,6 +77,7 @@ organization_id_is_null=Organization ID cannot be null
api_load_script_error=Load script error
api_report_is_null="Report is null, can't update"
api_test_environment_already_exists="Api test environment already exists"
api_test=API Test
#test case
test_case_node_level=level
test_case_node_level_tip=The node tree maximum depth is
......
......@@ -66,6 +66,8 @@ only_one_k8s=只能添加一个 K8S
#project
project_name_is_null=项目名称不能为空
project_name_already_exists=项目名称已存在
project_file_already_exists=项目下该文件已经存在
project_file_in_use=占用文件,无法删除。
#organization
organization_name_is_null=组织名不能为空
organization_name_already_exists=组织名已存在
......@@ -75,6 +77,7 @@ organization_id_is_null=组织 ID 不能为空
api_load_script_error=读取脚本失败
api_report_is_null="测试报告是未生成,无法更新"
api_test_environment_already_exists="已存在该名称的环境配置"
api_test=接口测试
#test case
test_case_node_level=
test_case_node_level_tip=模块树最大深度为
......
......@@ -66,6 +66,8 @@ only_one_k8s=只能添加一個 K8S
#project
project_name_is_null=項目名稱不能為空
project_name_already_exists=項目名稱已存在
project_file_already_exists=項目下文件已存在
project_file_in_use=佔用文件,無法刪除。
#organization
organization_name_is_null=組織名不能為空
organization_name_already_exists=組織名已存在
......@@ -75,6 +77,7 @@ organization_id_is_null=組織 ID 不能為空
api_load_script_error=讀取腳本失敗
api_report_is_null="測試報告是未生成,無法更新"
api_test_environment_already_exists="已存在該名稱的環境配置"
api_test=接口測試
#test case
test_case_node_level=
test_case_node_level_tip=模塊樹最大深度為
......
......@@ -3,6 +3,41 @@
:destroy-on-close="true"
:title="$t('load_test.exist_jmx')" width="70%"
:visible.sync="loadFileVisible">
<el-row>
<el-upload
v-if="loadType === 'jmx'"
style="padding-right: 10px;"
accept=".jmx"
action=""
multiple
:limit="fileNumLimit"
:show-file-list="false"
:before-upload="beforeUploadFile"
:http-request="handleUpload"
:on-exceed="handleExceed"
:disabled="isReadOnly"
:file-list="fileList">
<ms-table-button :is-tester-permission="true" icon="el-icon-upload2"
:content="$t('load_test.upload_jmx')"/>
</el-upload>
<el-upload
v-else
style="padding-right: 10px;"
accept=".jar,.csv,.json,.pdf,.jpg,.png,.jpeg,.doc,.docx,.xlsx"
action=""
:limit="fileNumLimit"
multiple
:show-file-list="false"
:before-upload="beforeUploadFile"
:http-request="handleUpload"
:on-exceed="handleExceed"
:disabled="isReadOnly"
:file-list="fileList">
<ms-table-button :is-tester-permission="true" icon="el-icon-upload2"
:content="$t('load_test.upload_file')"/>
</el-upload>
</el-row>
<el-table v-loading="projectLoadingResult.loading"
class="basic-config"
......@@ -11,10 +46,6 @@
@select="handleSelectionChange">
<el-table-column type="selection"/>
<el-table-column
prop="testName"
:label="$t('load_test.test')">
</el-table-column>
<el-table-column
prop="name"
:label="$t('load_test.file_name')">
......@@ -45,15 +76,18 @@ import MsDialogFooter from "@/business/components/common/components/MsDialogFoot
import MsTablePagination from "@/business/components/common/pagination/TablePagination";
import {getCurrentProjectID} from "@/common/js/utils";
import {findThreadGroup} from "@/business/components/performance/test/model/ThreadGroup";
import MsTableButton from "@/business/components/common/components/MsTableButton";
import axios from "axios";
export default {
name: "ExistFiles",
components: {MsTablePagination, MsDialogFooter},
components: {MsTableButton, MsTablePagination, MsDialogFooter},
props: {
fileList: Array,
tableData: Array,
uploadList: Array,
scenarios: Array
scenarios: Array,
isReadOnly: Boolean,
},
data() {
return {
......@@ -65,6 +99,7 @@ export default {
loadType: 'jmx',
existFiles: [],
selectIds: new Set,
fileNumLimit: 10,
}
},
methods: {
......@@ -106,6 +141,7 @@ export default {
},
handleImport() {
if (this.selectIds.size === 0) {
this.loadFileVisible = false;
return;
}
......@@ -163,6 +199,68 @@ export default {
});
},
beforeUploadFile(file) {
if (!this.fileValidator(file)) {
/// todo: 显示错误信息
return false;
}
if (this.tableData.filter(f => f.name === file.name).length > 0) {
this.$error(this.$t('load_test.delete_file'));
return false;
}
let valid = false;
// 检查数据库是否存在同名文件
async function f() {
return await axios.post('/performance/file/' + getCurrentProjectID() + '/getMetadataByName', {filename: file.name})
}
f().then(res => {
let response = res.data;
if (response.data.length === 0) {
let type = file.name.substring(file.name.lastIndexOf(".") + 1);
this.tableData.push({
name: file.name,
size: (file.size / 1024).toFixed(2) + ' KB',
type: type.toUpperCase(),
updateTime: file.lastModified,
});
valid = true;
} else {
this.$error(this.$t('load_test.project_file_exist'));
}
});
return valid;
},
handleUpload(uploadResources) {
let self = this;
let file = uploadResources.file;
self.uploadList.push(file);
let type = file.name.substring(file.name.lastIndexOf(".") + 1);
if (type.toLowerCase() !== 'jmx') {
return;
}
let jmxReader = new FileReader();
jmxReader.onload = (event) => {
let threadGroups = findThreadGroup(event.target.result, file.name);
threadGroups.forEach(tg => {
tg.options = {};
this.scenarios.push(tg);
});
self.$emit('fileChange', self.scenarios);
};
jmxReader.readAsText(file);
},
handleExceed() {
this.$error(this.$t('load_test.file_size_limit'));
},
fileValidator(file) {
/// todo: 是否需要对文件内容和大小做限制
return file.size > 0;
},
}
}
</script>
......
......@@ -4,21 +4,6 @@
<h4>{{ $t('load_test.scenario_list') }}</h4>
</el-row>
<el-row type="flex" justify="start" align="middle">
<el-upload
style="padding-right: 10px;"
accept=".jmx"
action=""
multiple
:limit="fileNumLimit"
:show-file-list="false"
:before-upload="beforeUploadJmx"
:http-request="handleUpload"
:on-exceed="handleExceed"
:disabled="isReadOnly"
:file-list="fileList">
<ms-table-button :is-tester-permission="true" icon="el-icon-upload2"
:content="$t('load_test.upload_jmx')"/>
</el-upload>
<ms-table-button :is-tester-permission="true" icon="el-icon-circle-plus-outline"
:content="$t('load_test.load_exist_jmx')" @click="loadJMX()"/>
<ms-table-button :is-tester-permission="true" icon="el-icon-share"
......@@ -68,21 +53,6 @@
<h4>{{ $t('load_test.other_resource') }}</h4>
</el-row>
<el-row type="flex" justify="start" align="middle">
<el-upload
style="padding-right: 10px;"
accept=".jar,.csv,.json,.pdf,.jpg,.png,.jpeg,.doc,.docx,.xlsx"
action=""
:limit="fileNumLimit"
multiple
:show-file-list="false"
:before-upload="beforeUploadFile"
:http-request="handleUpload"
:on-exceed="handleExceed"
:disabled="isReadOnly"
:file-list="fileList">
<ms-table-button :is-tester-permission="true" icon="el-icon-upload2"
:content="$t('load_test.upload_file')"/>
</el-upload>
<ms-table-button :is-tester-permission="true" icon="el-icon-circle-plus-outline"
:content="$t('load_test.load_exist_file')" @click="loadFile()"/>
......@@ -125,6 +95,7 @@
:file-list="fileList"
:table-data="tableData"
:upload-list="uploadList"
:is-read-only="isReadOnly"
:scenarios="threadGroups"/>
<exist-scenarios ref="existScenarios"
......@@ -139,7 +110,6 @@
<script>
import {Message} from "element-ui";
import {findThreadGroup} from "@/business/components/performance/test/model/ThreadGroup";
import MsTableButton from "@/business/components/common/components/MsTableButton";
import MsTablePagination from "@/business/components/common/pagination/TablePagination";
import MsTableOperatorButton from "@/business/components/common/components/MsTableOperatorButton";
......@@ -229,64 +199,6 @@ export default {
});
})
},
beforeUploadJmx(file) {
if (!this.fileValidator(file)) {
/// todo: 显示错误信息
return false;
}
if (this.tableData.filter(f => f.name === file.name).length > 0) {
this.$error(this.$t('load_test.delete_file'));
return false;
}
let type = file.name.substring(file.name.lastIndexOf(".") + 1);
this.tableData.push({
name: file.name,
size: (file.size / 1024).toFixed(2) + ' KB',
type: type.toUpperCase(),
updateTime: file.lastModified,
});
return true;
},
beforeUploadFile(file) {
if (!this.fileValidator(file)) {
/// todo: 显示错误信息
return false;
}
if (this.tableData.filter(f => f.name === file.name).length > 0) {
this.$error(this.$t('load_test.delete_file'));
return false;
}
let type = file.name.substring(file.name.lastIndexOf(".") + 1);
this.tableData.push({
name: file.name,
size: (file.size / 1024).toFixed(2) + ' KB',
type: type.toUpperCase(),
updateTime: file.lastModified,
});
return true;
},
handleUpload(uploadResources) {
let self = this;
let file = uploadResources.file;
self.uploadList.push(file);
let type = file.name.substring(file.name.lastIndexOf(".") + 1);
if (type.toLowerCase() !== 'jmx') {
return;
}
let jmxReader = new FileReader();
jmxReader.onload = (event) => {
self.threadGroups = self.threadGroups.concat(findThreadGroup(event.target.result, file.name));
self.$emit('fileChange', self.threadGroups);
};
jmxReader.readAsText(file);
},
selectAttachFileById(metadataIdArr) {
this.metadataIdList = metadataIdArr;
for (let i = 0; i < metadataIdArr.length; i++) {
......@@ -380,13 +292,6 @@ export default {
tgTypeChange(row) {
this.$emit("tgTypeChange", row);
},
handleExceed() {
this.$error(this.$t('load_test.file_size_limit'));
},
fileValidator(file) {
/// todo: 是否需要对文件内容和大小做限制
return file.size > 0;
},
updatedFileList() {
return this.fileList;// 表示修改了已经上传的文件列表
},
......@@ -414,7 +319,7 @@ export default {
},
validConfig() {
if (this.uploadList.length + this.fileList.length > this.fileNumLimit) {
this.handleExceed();
this.$refs.existFiles.handleExceed();
return false;
}
......
<template>
<el-dialog :close-on-click-modal="false"
:destroy-on-close="true"
:title="$t('load_test.exist_jmx')" width="70%"
:visible.sync="loadFileVisible">
<el-row>
<el-upload
style="padding-right: 10px;"
accept=".jmx,.jar,.csv,.json,.pdf,.jpg,.png,.jpeg,.doc,.docx,.xlsx"
action=""
:limit="fileNumLimit"
multiple
:show-file-list="false"
:before-upload="beforeUploadFile"
:http-request="handleUpload"
:on-exceed="handleExceed"
:file-list="fileList">
<ms-table-button :is-tester-permission="true" icon="el-icon-upload2"
:content="$t('load_test.upload_file')"/>
</el-upload>
</el-row>
<el-table v-loading="projectLoadingResult.loading"
class="basic-config"
:data="existFiles">
<el-table-column type="selection"/>
<el-table-column
prop="name"
:label="$t('load_test.file_name')">
</el-table-column>
<el-table-column
prop="type"
:label="$t('load_test.file_type')">
</el-table-column>
<el-table-column
:label="$t('load_test.last_modify_time')">
<template v-slot:default="scope">
<i class="el-icon-time"/>
<span class="last-modified">{{ scope.row.updateTime | timestampFormatDate }}</span>
</template>
</el-table-column>
<el-table-column :label="$t('commons.operating')">
<template v-slot:default="scope">
<ms-table-operator-button :is-tester-permission="true"
icon="el-icon-delete"
type="danger"
:tip="$t('commons.delete')"
@exec="handleDelete(scope.row)">
</ms-table-operator-button>
</template>
</el-table-column>
</el-table>
<ms-table-pagination :change="getProjectFiles" :current-page.sync="currentPage" :page-size.sync="pageSize"
:total="total"/>
</el-dialog>
</template>
<script>
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} from "@/common/js/utils";
import MsTableOperatorButton from "@/business/components/common/components/MsTableOperatorButton";
import {Message} from "element-ui";
export default {
name: "MsResourceFiles",
components: {MsTableOperatorButton, MsDialogFooter, MsTableButton, MsTablePagination},
data() {
return {
loadFileVisible: false,
projectLoadingResult: {},
currentPage: 1,
pageSize: 5,
total: 0,
existFiles: [],
fileList: [],
uploadList: [],
fileNumLimit: 10,
}
},
methods: {
open() {
this.loadFileVisible = true;
this.getProjectFiles();
},
close() {
this.loadFileVisible = false;
this.selectIds.clear();
},
getProjectFiles() {
this.projectLoadingResult = this.$get('/performance/project/all/' + getCurrentProjectID() + "/" + this.currentPage + "/" + this.pageSize, res => {
let data = res.data;
this.total = data.itemCount;
this.existFiles = data.listObject;
})
},
fileValidator(file) {
/// todo: 是否需要对文件内容和大小做限制
return file.size > 0;
},
beforeUploadFile(file) {
if (!this.fileValidator(file)) {
/// todo: 显示错误信息
return false;
}
return true;
},
handleUpload(uploadResources) {
let file = uploadResources.file;
let formData = new FormData();
let url = '/project/upload/files/' + getCurrentProjectID()
formData.append("file", file);
let options = {
method: 'POST',
url: url,
data: formData,
headers: {
'Content-Type': undefined
}
}
this.$request(options, (response) => {
this.$success(this.$t('commons.save_success'));
this.getProjectFiles();
});
},
handleExceed() {
this.$error(this.$t('load_test.file_size_limit'));
},
handleDelete(row) {
console.log(row);
this.$confirm(this.$t('project.file_delete_tip', [row.name]), '', {
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
type: 'warning'
}).then(() => {
this.$get('/project/delete/file/' + row.id, response => {
Message.success(this.$t('commons.delete_success'));
this.getProjectFiles();
});
}).catch(() => {
});
}
}
}
</script>
<style scoped>
</style>
......@@ -7,6 +7,8 @@
<template v-slot:button>
<ms-table-button :is-tester-permission="true" icon="el-icon-box"
:content="$t('api_test.jar_config.title')" @click="openJarConfig"/>
<ms-table-button :is-tester-permission="true" icon="el-icon-files"
:content="$t('load_test.other_resource')" @click="openFiles"/>
</template>
</ms-table-header>
</template>
......@@ -88,6 +90,7 @@
<ms-jar-config ref="jarConfig"/>
<ms-resource-files ref="resourceFiles"/>
</div>
</template>
......@@ -109,10 +112,12 @@ import {PROJECT_ID} from "@/common/js/constants";
import MsJarConfig from "../../api/test/components/jar/JarConfig";
import MsTableButton from "../../common/components/MsTableButton";
import {_sort} from "@/common/js/tableUtils";
import MsResourceFiles from "@/business/components/performance/test/components/ResourceFiles";
export default {
name: "MsProject",
components: {
MsResourceFiles,
MsTableButton,
MsJarConfig,
TemplateComponent,
......@@ -121,170 +126,173 @@ export default {
MsDeleteConfirm,
MsMainContainer,
MsContainer, MsTableOperator, MsCreateBox, MsTablePagination, MsTableHeader, MsDialogFooter
},
data() {
return {
createVisible: false,
result: {},
btnTips: this.$t('project.create'),
title: this.$t('project.create'),
condition: {},
items: [],
tapd: false,
jira: false,
zentao: false,
form: {},
currentPage: 1,
pageSize: 10,
total: 0,
rules: {
name: [
{required: true, message: this.$t('project.input_name'), trigger: 'blur'},
{min: 2, max: 50, message: this.$t('commons.input_limit', [2, 50]), trigger: 'blur'}
],
description: [
{max: 250, message: this.$t('commons.input_limit', [0, 250]), trigger: 'blur'}
],
},
},
data() {
return {
createVisible: false,
result: {},
btnTips: this.$t('project.create'),
title: this.$t('project.create'),
condition: {},
items: [],
tapd: false,
jira: false,
zentao: false,
form: {},
currentPage: 1,
pageSize: 10,
total: 0,
rules: {
name: [
{required: true, message: this.$t('project.input_name'), trigger: 'blur'},
{min: 2, max: 50, message: this.$t('commons.input_limit', [2, 50]), trigger: 'blur'}
],
description: [
{max: 250, message: this.$t('commons.input_limit', [0, 250]), trigger: 'blur'}
],
},
}
},
props: {
baseUrl: {
type: String
}
},
mounted() {
if (this.$route.path.split('/')[2] === 'project' &&
this.$route.path.split('/')[3] === 'create') {
this.create();
this.$router.replace('/setting/project/all');
}
this.list();
},
activated() {
this.list();
},
computed: {
currentUser: () => {
return getCurrentUser();
}
},
destroyed() {
this.createVisible = false;
},
methods: {
create() {
let workspaceId = this.currentUser.lastWorkspaceId;
if (!workspaceId) {
this.$warning(this.$t('project.please_choose_workspace'));
return false;
}
this.title = this.$t('project.create');
// listenGoBack(this.handleClose);
this.createVisible = true;
this.form = {};
},
props: {
baseUrl: {
type: String
}
edit(row) {
this.title = this.$t('project.edit');
this.createVisible = true;
listenGoBack(this.handleClose);
this.form = Object.assign({}, row);
this.$get("/service/integration/all/" + getCurrentUser().lastOrganizationId, response => {
let data = response.data;
let platforms = data.map(d => d.platform);
if (platforms.indexOf("Tapd") !== -1) {
this.tapd = true;
}
if (platforms.indexOf("Jira") !== -1) {
this.jira = true;
}
if (platforms.indexOf("Zentao") !== -1) {
this.zentao = true;
}
});
},
mounted() {
if (this.$route.path.split('/')[2] === 'project' &&
this.$route.path.split('/')[3] === 'create') {
this.create();
this.$router.replace('/setting/project/all');
}
this.list();
submit(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
let saveType = "add";
if (this.form.id) {
saveType = "update"
}
this.result = this.$post("/project/" + saveType, this.form, () => {
this.createVisible = false;
this.list();
Message.success(this.$t('commons.save_success'));
});
} else {
return false;
}
});
},
activated() {
this.list();
openJarConfig() {
this.$refs.jarConfig.open();
},
computed: {
currentUser: () => {
return getCurrentUser();
}
openFiles() {
this.$refs.resourceFiles.open();
},
destroyed() {
this.createVisible = false;
handleDelete(project) {
this.$refs.deleteConfirm.open(project);
},
methods: {
create() {
let workspaceId = this.currentUser.lastWorkspaceId;
if (!workspaceId) {
this.$warning(this.$t('project.please_choose_workspace'));
return false;
}
this.title = this.$t('project.create');
// listenGoBack(this.handleClose);
this.createVisible = true;
this.form = {};
},
edit(row) {
this.title = this.$t('project.edit');
this.createVisible = true;
listenGoBack(this.handleClose);
this.form = Object.assign({}, row);
this.$get("/service/integration/all/" + getCurrentUser().lastOrganizationId, response => {
let data = response.data;
let platforms = data.map(d => d.platform);
if (platforms.indexOf("Tapd") !== -1) {
this.tapd = true;
}
if (platforms.indexOf("Jira") !== -1) {
this.jira = true;
}
if (platforms.indexOf("Zentao") !== -1) {
this.zentao = true;
_handleDelete(project) {
this.$confirm(this.$t('project.delete_tip'), '', {
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
type: 'warning'
}).then(() => {
this.$get('/project/delete/' + project.id, () => {
if (project.id === getCurrentProjectID()) {
localStorage.removeItem(PROJECT_ID);
this.$post("/user/update/current", {id: getCurrentUser().id, lastProjectId: ''});
}
Message.success(this.$t('commons.delete_success'));
this.list();
});
},
submit(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
let saveType = "add";
if (this.form.id) {
saveType = "update"
}
this.result = this.$post("/project/" + saveType, this.form, () => {
this.createVisible = false;
this.list();
Message.success(this.$t('commons.save_success'));
});
} else {
return false;
}
});
},
openJarConfig() {
this.$refs.jarConfig.open();
},
handleDelete(project) {
this.$refs.deleteConfirm.open(project);
},
_handleDelete(project) {
this.$confirm(this.$t('project.delete_tip'), '', {
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
type: 'warning'
}).then(() => {
this.$get('/project/delete/' + project.id, () => {
if (project.id === getCurrentProjectID()) {
localStorage.removeItem(PROJECT_ID);
this.$post("/user/update/current", {id: getCurrentUser().id, lastProjectId: ''});
}
Message.success(this.$t('commons.delete_success'));
this.list();
});
}).catch(() => {
this.$message({
type: 'info',
message: this.$t('commons.delete_cancelled')
});
}).catch(() => {
this.$message({
type: 'info',
message: this.$t('commons.delete_cancelled')
});
},
handleClose() {
removeGoBackListener(this.handleClose);
this.createVisible = false;
this.tapd = false;
this.jira = false;
this.zentao = false;
},
search() {
this.list();
},
list() {
let url = "/project/list/" + this.currentPage + '/' + this.pageSize;
this.result = this.$post(url, this.condition, (response) => {
let data = response.data;
this.items = data.listObject;
this.total = data.itemCount;
})
},
sort(column) {
_sort(column, this.condition);
this.list();
},
openEnvironmentConfig(project) {
this.$refs.environmentConfig.open(project.id);
},
});
},
created() {
document.addEventListener('keydown', this.handleEvent)
handleClose() {
removeGoBackListener(this.handleClose);
this.createVisible = false;
this.tapd = false;
this.jira = false;
this.zentao = false;
},
beforeDestroy() {
document.removeEventListener('keydown', this.handleEvent);
}
search() {
this.list();
},
list() {
let url = "/project/list/" + this.currentPage + '/' + this.pageSize;
this.result = this.$post(url, this.condition, (response) => {
let data = response.data;
this.items = data.listObject;
this.total = data.itemCount;
})
},
sort(column) {
_sort(column, this.condition);
this.list();
},
openEnvironmentConfig(project) {
this.$refs.environmentConfig.open(project.id);
},
},
created() {
document.addEventListener('keydown', this.handleEvent)
},
beforeDestroy() {
document.removeEventListener('keydown', this.handleEvent);
}
}
</script>
<style scoped>
pre {
margin: 0 0;
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", Arial, sans-serif;
}
pre {
margin: 0 0;
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", Arial, sans-serif;
}
</style>
......@@ -338,6 +338,7 @@ export default {
delete: 'Delete project',
delete_confirm: 'Deleting this project will delete all test resources under this project. Are you sure you want to delete?',
delete_tip: 'Deleting this project will delete all test resources under this project. Are you sure you want to delete?',
file_delete_tip: 'Deleting this project file: {0}?',
search_by_name: 'Search by name',
search_by_name_jar: 'Search by name/jar',
input_name: 'Please enter a workspace name',
......@@ -530,6 +531,7 @@ export default {
load_exist_jmx: 'Load Project JMX',
threadgroup_at_least_one: 'At least one ThreadGroup is enabled',
load_api_automation_jmx: 'Import API automation scenario',
project_file_exist: "The file already exists in the project, please import it directly"
},
api_test: {
creator: "Creator",
......
......@@ -335,6 +335,7 @@ export default {
delete: '删除项目',
delete_confirm: '确定要删除这个项目吗?',
delete_tip: '删除该项目,会删除该项目下所有测试资源,确定要删除吗?',
file_delete_tip: '删除该项目的文件: {0}?',
search_by_name: '根据名称搜索',
search_by_name_jar: '根据 名称 / jar包 搜索',
input_name: '请输入项目名称',
......@@ -525,10 +526,11 @@ export default {
exist_jmx: '已存在的文件',
other_resource: '资源文件',
upload_file: '上传新文件',
load_exist_file: '加载已有文件',
load_exist_jmx: '加载已有 JMX 文件',
load_exist_file: '加载文件',
load_exist_jmx: '加载 JMX 文件',
threadgroup_at_least_one: '至少启用一个线程组',
load_api_automation_jmx: '引用接口自动化场景',
project_file_exist: "项目中已存在该文件,请直接引用"
},
api_test: {
creator: "创建人",
......
......@@ -335,6 +335,7 @@ export default {
delete: '刪除項目',
delete_confirm: '確定要刪除這個項目嗎?',
delete_tip: '刪除該項目,會刪除該項目下所有測試資源,確定要刪除嗎?',
file_delete_tip: '刪除該項目的文件: {0}?',
search_by_name: '根據名稱搜索',
search_by_name_jar: '根據名稱/jar包搜索',
input_name: '請輸入項目名稱',
......@@ -525,10 +526,11 @@ export default {
exist_jmx: '已存在的文件',
other_resource: '資源文件',
upload_file: '上傳新文件',
load_exist_file: '加載已有文件',
load_exist_jmx: '加載已有 JMX 文件',
load_exist_file: '加載文件',
load_exist_jmx: '加載 JMX 文件',
threadgroup_at_least_one: '至少啟用一個線程組',
load_api_automation_jmx: '引用接口自動化場景',
project_file_exist: "項目中已存在該文件,請直接引用"
},
api_test: {
creator: "創建人",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册