Merge pull request '新增测试用例导入、导出功能,优化部分代码' (#887) from zengweizhang/microservices:master into dev_testCase_export
This commit is contained in:
commit
a41c0192f2
|
@ -121,6 +121,12 @@
|
|||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.14</version>
|
||||
</dependency>
|
||||
<!-- Apache POI for Word processing -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.apache.poi</groupId>-->
|
||||
<!-- <artifactId>poi-ooxml</artifactId>-->
|
||||
<!-- <version>5.4.0</version>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- 自然语言处理,用于自动提取文章概要 -->
|
||||
<dependency>
|
||||
<groupId>com.hankcs</groupId>
|
||||
|
@ -139,6 +145,12 @@
|
|||
<version>0.4.8</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- 文件导入、导出库 -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.github.ben-manes.caffeine</groupId>-->
|
||||
<!-- <artifactId>Java2Word</artifactId>-->
|
||||
<!-- <version>1.0.0</version>-->
|
||||
<!-- </dependency>-->
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -67,6 +67,15 @@ public interface IPmsProductModuleService
|
|||
*/
|
||||
List<TreeSelect> selectPmsProductModuleTreeList(PmsProductModule pmsProductModule, int type);
|
||||
|
||||
/**
|
||||
* 构建模块的树状结构
|
||||
*
|
||||
* @param projectid 模块搜索条件
|
||||
* @param type 模块类型(1产品模块 2测试用例模块, 3测试单,实际取测试用例模块)
|
||||
* @return 模块树状结构
|
||||
*/
|
||||
List<TreeSelect> getPmsProductModuleTreeList(Long projectid, int type);
|
||||
|
||||
/**
|
||||
* 查询模块及模块子级ID列表
|
||||
* @param parentModuleId 父级模块ID
|
||||
|
|
|
@ -351,6 +351,63 @@ public class PmsProductModuleServiceImpl implements IPmsProductModuleService
|
|||
return buildModuleTreeSelect(moduleList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TreeSelect> getPmsProductModuleTreeList(Long projectId, int type) {
|
||||
List<PmsProductModule> moduleList;
|
||||
PmsProductModule pmsProductModule = new PmsProductModule();
|
||||
pmsProductModule.setPmsProjectId(projectId);
|
||||
//模块类型(1产品模块 2测试用例模块, 3测试单,实际取测试用例模块)
|
||||
if (PmsConstants.TESTSHEET_TAG_AND_MODULE_TYPE.equals(type)) {
|
||||
pmsProductModule.setType(PmsConstants.TESTCASE_TAG_AND_MODULE_TYPE);
|
||||
moduleList = pmsProductModuleMapper.selectPmsProductModuleForTestsheetList(pmsProductModule);
|
||||
} else {
|
||||
pmsProductModule.setType(type);
|
||||
moduleList = pmsProductModuleMapper.selectPmsProductModuleList(pmsProductModule);
|
||||
}
|
||||
|
||||
Integer allNodeDataCount;
|
||||
Integer noModuleNodeDataCount;
|
||||
String allNodeName = "全部模块";
|
||||
if (type == PmsConstants.PRODUCT_TAG_AND_MODULE_TYPE) {
|
||||
// 设置各节点数量为需求数量
|
||||
moduleList.forEach(x -> x.setNodeDataCount(x.getRequirementCount()));
|
||||
|
||||
|
||||
} else if (type == PmsConstants.TESTSHEET_TAG_AND_MODULE_TYPE) {
|
||||
// 设置各节点数量为测试单执行用例数量
|
||||
moduleList.forEach(x -> x.setNodeDataCount(x.getTestsheetCasesCount()));
|
||||
// 排除0测试单执行用例数据
|
||||
moduleList = moduleList.stream().filter(e -> e.getTestsheetCasesCount() > 0).collect(Collectors.toList());
|
||||
} else {
|
||||
// 设置各节点数量为测试用例数量
|
||||
moduleList.forEach(x -> x.setNodeDataCount(x.getTestCaseCount()));
|
||||
}
|
||||
// 父级需求数需包含子级需求数
|
||||
aggregateCounts(moduleList, 0L);
|
||||
|
||||
// 构建顶级模块(全部需求)
|
||||
PmsProductModule allPmsProductModule=new PmsProductModule();
|
||||
allPmsProductModule.setPmsProductIdentifier(pmsProductModule.getPmsProductIdentifier());
|
||||
allPmsProductModule.setId(0L);
|
||||
allPmsProductModule.setModuleName(allNodeName);
|
||||
allPmsProductModule.setIsFixedModule(true);
|
||||
moduleList.add(allPmsProductModule);
|
||||
// 模块根据id排序
|
||||
moduleList = moduleList.stream()
|
||||
.sorted(Comparator.comparing(PmsProductModule::getId))
|
||||
.sorted(Comparator.comparing(PmsProductModule::getIsFixedModule))
|
||||
.collect(Collectors.toList());
|
||||
// 构建无所属模块
|
||||
PmsProductModule noPmsProductModule = new PmsProductModule();
|
||||
noPmsProductModule.setPmsProductIdentifier(pmsProductModule.getPmsProductIdentifier());
|
||||
noPmsProductModule.setId(-1L);
|
||||
noPmsProductModule.setModuleName(NO_MODULE(type));
|
||||
noPmsProductModule.setParentId(0L);
|
||||
noPmsProductModule.setIsFixedModule(true);
|
||||
moduleList.add(noPmsProductModule);
|
||||
return buildModuleTreeSelect(moduleList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> selectChildrenPmsProductModuleIdList(Long parentModuleId) {
|
||||
List<PmsProductModule> pmsProductModuleList=new ArrayList<>();
|
||||
|
|
|
@ -9,15 +9,20 @@ import com.microservices.common.log.annotation.Log;
|
|||
import com.microservices.common.log.enums.BusinessType;
|
||||
import com.microservices.common.security.annotation.Logical;
|
||||
import com.microservices.common.security.annotation.RequiresPermissions;
|
||||
import com.microservices.pms.product.domain.vo.TreeSelect;
|
||||
import com.microservices.pms.product.service.IPmsProductModuleService;
|
||||
import com.microservices.pms.project.domain.PmsProjectTestcase;
|
||||
import com.microservices.pms.project.domain.vo.*;
|
||||
import com.microservices.pms.project.service.IPmsProjectTestcaseService;
|
||||
import com.microservices.pms.utils.PmsConstants;
|
||||
import io.swagger.annotations.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -132,4 +137,40 @@ public class PmsProjectTestcaseController extends BaseController {
|
|||
@RequestBody JSONObject batchUpdateVo) {
|
||||
return toAjax(pmsProjectTestcaseService.batchUpdatePmsProjectTestcase(batchUpdateVo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量下载测试用例
|
||||
*/
|
||||
@ApiOperation(value = "批量下载测试用例")
|
||||
@GetMapping("/{projectId}/download")
|
||||
public void download(@PathVariable("projectId") Long projectId, HttpServletResponse response)throws IOException {
|
||||
PmsProjectTestcaseModuleSearchVo pmsProjectTestcaseModuleSearchVo = new PmsProjectTestcaseModuleSearchVo();
|
||||
pmsProjectTestcaseModuleSearchVo.setPmsProjectId(projectId);
|
||||
List<TreeSelect> treeSelects = pmsProductModuleService.getPmsProductModuleTreeList(projectId, PmsConstants.TESTCASE_TAG_AND_MODULE_TYPE);
|
||||
pmsProjectTestcaseService.generateWord(treeSelects, projectId, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量导入测试用例
|
||||
*/
|
||||
@ApiOperation(value = "批量导入测试用例")
|
||||
@PostMapping("/{projectId}/upload")
|
||||
public AjaxResult upload(@RequestPart("file") MultipartFile file, @PathVariable("projectId") Long projectId) throws IOException {
|
||||
if (file.isEmpty()) {
|
||||
return error("上传的文件为空,请选择有效的文件");
|
||||
}
|
||||
|
||||
String fileName = file.getOriginalFilename();
|
||||
if (fileName == null) {
|
||||
return error("无法获取文件名,请检查上传的文件");
|
||||
}
|
||||
|
||||
if (fileName.endsWith(".docx")) {
|
||||
pmsProjectTestcaseService.testcaseImport(projectId, file);
|
||||
return success("上传的文件是 docx 格式");
|
||||
} else {
|
||||
return error("上传的文件不是 docx 格式,请上传 docx 文件");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -126,22 +126,22 @@ public class PmsProjectTestcase extends BaseEntity {
|
|||
private List<PmsProjectTestcaseStep> testcaseStepList;
|
||||
|
||||
/**
|
||||
* 预留字段1
|
||||
* 测试用例描述
|
||||
*/
|
||||
@JsonIgnore
|
||||
private String reservedField1;
|
||||
@ApiModelProperty(value = "测试用例描述")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 预留字段2
|
||||
* 测试方法
|
||||
*/
|
||||
@JsonIgnore
|
||||
private String reservedField2;
|
||||
@ApiModelProperty(value = "测试方法")
|
||||
private String testMethod;
|
||||
|
||||
/**
|
||||
* 预留字段3
|
||||
* 测试终止条件
|
||||
*/
|
||||
@JsonIgnore
|
||||
private String reservedField3;
|
||||
@ApiModelProperty(value = "测试终止条件")
|
||||
private String terminationConditions;
|
||||
|
||||
@ApiModelProperty(value = "测试用例标识")
|
||||
private String identifier;
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
package com.microservices.pms.project.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class PendingOutputDataVo {
|
||||
private Long id;
|
||||
|
||||
private Long pms_projiect_id;
|
||||
|
||||
private String title;
|
||||
|
||||
private Long type_id;
|
||||
|
||||
private String tag_ids;
|
||||
|
||||
private List<String> content_list;
|
||||
|
||||
private List<String> expected_result;
|
||||
|
||||
private String update_by;
|
||||
|
||||
private LocalDate update_time;
|
||||
|
||||
private String create_by;
|
||||
|
||||
private LocalDate create_time;
|
||||
|
||||
private String test_type;
|
||||
|
||||
private String description;
|
||||
|
||||
private String test_method;
|
||||
|
||||
private String termination_conditions;
|
||||
|
||||
private String identifier;
|
||||
|
||||
private String preconditions;
|
||||
|
||||
|
||||
|
||||
public PendingOutputDataVo() {
|
||||
content_list = new ArrayList<>();
|
||||
expected_result = new ArrayList<>();
|
||||
}
|
||||
|
||||
// 添加元素的方法
|
||||
public void addToContent(String item) {
|
||||
content_list.add(item);
|
||||
}
|
||||
|
||||
public void addToExpected(String item) {
|
||||
expected_result.add(item);
|
||||
}
|
||||
|
||||
public void addContent(String item) {
|
||||
this.content_list.add(item);
|
||||
}
|
||||
|
||||
public void addExpected(String item) {
|
||||
this.expected_result.add(item);
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModel;
|
|||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -35,6 +36,27 @@ public class PmsProjectTestcaseDetailVo extends PmsProjectTestcaseDataVo {
|
|||
@ApiModelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 测试用例描述
|
||||
*/
|
||||
@ApiModelProperty(value = "测试用例描述")
|
||||
@Size(max = 500, message = "长度需要小于500")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 测试方法
|
||||
*/
|
||||
@ApiModelProperty(value = "测试方法")
|
||||
@Size(max = 255, message = "长度需要小于255")
|
||||
private String testMethod;
|
||||
|
||||
/**
|
||||
* 测试终止条件
|
||||
*/
|
||||
@ApiModelProperty(value = "测试终止条件")
|
||||
@Size(max = 500, message = "长度需要小于500")
|
||||
private String terminationConditions;
|
||||
|
||||
/**
|
||||
* 测试步骤列表
|
||||
*/
|
||||
|
|
|
@ -84,6 +84,27 @@ public class PmsProjectTestcaseInputVo {
|
|||
@Size(max = 500, message = "长度需要小于500")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 测试用例描述
|
||||
*/
|
||||
@ApiModelProperty(value = "测试用例描述")
|
||||
@Size(max = 500, message = "长度需要小于500")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 测试方法
|
||||
*/
|
||||
@ApiModelProperty(value = "测试方法")
|
||||
@Size(max = 255, message = "长度需要小于255")
|
||||
private String testMethod;
|
||||
|
||||
/**
|
||||
* 测试终止条件
|
||||
*/
|
||||
@ApiModelProperty(value = "测试终止条件")
|
||||
@Size(max = 500, message = "长度需要小于500")
|
||||
private String terminationConditions;
|
||||
|
||||
/**
|
||||
* 测试步骤列表
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package com.microservices.pms.project.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class PmsProjectTestcaseStepVo {
|
||||
private Long index;
|
||||
|
||||
private String content;
|
||||
|
||||
private String expectedResult;
|
||||
|
||||
private String updateBy;
|
||||
|
||||
private String createBy;
|
||||
|
||||
}
|
|
@ -80,6 +80,27 @@ public class PmsProjectTestcaseUpdateVo {
|
|||
@Size(max = 500, message = "长度需要小于500")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 测试用例描述
|
||||
*/
|
||||
@ApiModelProperty(value = "测试用例描述")
|
||||
@Size(max = 500, message = "长度需要小于500")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 测试方法
|
||||
*/
|
||||
@ApiModelProperty(value = "测试方法")
|
||||
@Size(max = 255, message = "长度需要小于255")
|
||||
private String testMethod;
|
||||
|
||||
/**
|
||||
* 测试终止条件
|
||||
*/
|
||||
@ApiModelProperty(value = "测试终止条件")
|
||||
@Size(max = 500, message = "长度需要小于500")
|
||||
private String terminationConditions;
|
||||
|
||||
/**
|
||||
* 测试步骤列表
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package com.microservices.pms.project.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
@Data
|
||||
public class PmsProjectTestcaseVo {
|
||||
private Long id;
|
||||
|
||||
private Long pmsProjiectId;
|
||||
|
||||
private String title;
|
||||
|
||||
private Long typeId;
|
||||
|
||||
private String tagIds;
|
||||
|
||||
private Long pmsModuleId;
|
||||
|
||||
private LocalDate updateTime;
|
||||
|
||||
private String updateBy;
|
||||
|
||||
private LocalDate createTime;
|
||||
|
||||
private String createBy;
|
||||
|
||||
private String preconditions;
|
||||
|
||||
private String description;
|
||||
|
||||
private String testMethod;
|
||||
|
||||
private String terminationConditions;
|
||||
|
||||
private String identifier;
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.microservices.pms.project.mapper;
|
|||
|
||||
import com.microservices.pms.project.domain.PmsProjectTestcase;
|
||||
import com.microservices.pms.project.domain.vo.PmsProjectTestcaseBatchUpdateVo;
|
||||
import com.microservices.pms.project.domain.vo.PmsProjectTestcaseVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
|
@ -112,4 +113,12 @@ public interface PmsProjectTestcaseMapper {
|
|||
List<Long> selectProjectIdListInTestcaseIdList(@Param("idList") List<Long> idList);
|
||||
|
||||
int deletePmsProjectTestcaseByProjectId(@Param("projectId") Long projectId);
|
||||
|
||||
/**
|
||||
* 获取testcasevo中部分字段
|
||||
*
|
||||
* @param pms_project_id 关联的项目号
|
||||
*/
|
||||
public List<PmsProjectTestcaseVo> getTestcase(Long pms_project_id);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.microservices.pms.project.mapper;
|
||||
|
||||
import com.microservices.pms.project.domain.PmsProjectTestcaseStep;
|
||||
import com.microservices.pms.project.domain.vo.PmsProjectTestcaseStepVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
|
@ -77,4 +78,11 @@ public interface PmsProjectTestcaseStepMapper {
|
|||
* @return 操作步骤
|
||||
*/
|
||||
PmsProjectTestcaseStep selectPmsProjectTestcaseStepByIndexAndTestcaseId(@Param("index") Long index, @Param("testcaseId") Long testcaseId);
|
||||
|
||||
/**
|
||||
* 获取testCaseStepvo中部分字段
|
||||
*
|
||||
* @param PmsProjectTestcase_id 关联的测试用例号
|
||||
*/
|
||||
public List<PmsProjectTestcaseStepVo> getTestcaseStep(Long PmsProjectTestcase_id);
|
||||
}
|
||||
|
|
|
@ -3,10 +3,14 @@ package com.microservices.pms.project.service;
|
|||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.microservices.common.core.web.page.GenericsTableDataInfo;
|
||||
import com.microservices.pms.product.domain.vo.ProductReqSpecsAssociatedTestcaseDataVo;
|
||||
import com.microservices.pms.product.domain.vo.TreeSelect;
|
||||
import com.microservices.pms.project.domain.PmsProjectTestcase;
|
||||
import com.microservices.pms.project.domain.vo.PmsProjectTestcaseDataVo;
|
||||
import com.microservices.pms.project.domain.vo.PmsProjectTestcaseDetailVo;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -118,4 +122,21 @@ public interface IPmsProjectTestcaseService {
|
|||
List<ProductReqSpecsAssociatedTestcaseDataVo> selectReqSpecsAssociatedTestcaseList(Long reqSpecsId);
|
||||
|
||||
PmsProjectTestcase copyPmsProjectTestcase(Long testcaseId);
|
||||
|
||||
/**
|
||||
* 获取测试用例列表
|
||||
*
|
||||
* @param treeSelects 模块树结构
|
||||
* @param projectId 项目id
|
||||
* @param response
|
||||
* @return 导出word数据流
|
||||
*/
|
||||
void generateWord(List<TreeSelect> treeSelects, Long projectId, HttpServletResponse response)throws IOException;
|
||||
|
||||
/**
|
||||
* 处理docx文件将测试用例导入到数据库
|
||||
* @param projectId 项目id
|
||||
* @param file 导入的docx文件
|
||||
*/
|
||||
void testcaseImport(Long projectId, MultipartFile file) throws IOException;
|
||||
}
|
||||
|
|
|
@ -15,15 +15,14 @@ import com.microservices.pms.product.domain.PmsProductModule;
|
|||
import com.microservices.pms.product.domain.PmsProductRequirement;
|
||||
import com.microservices.pms.product.domain.enums.ProductReqStatus;
|
||||
import com.microservices.pms.product.domain.vo.ProductReqSpecsAssociatedTestcaseDataVo;
|
||||
import com.microservices.pms.product.domain.vo.TreeSelect;
|
||||
import com.microservices.pms.product.service.IPmsProductModuleService;
|
||||
import com.microservices.pms.product.service.IPmsProductRequirementService;
|
||||
import com.microservices.pms.product.service.IPmsProductRequirementTagService;
|
||||
import com.microservices.pms.project.domain.*;
|
||||
import com.microservices.pms.project.domain.vo.PmsProjectTestcaseBatchUpdateVo;
|
||||
import com.microservices.pms.project.domain.vo.PmsProjectTestcaseDataVo;
|
||||
import com.microservices.pms.project.domain.vo.PmsProjectTestcaseDetailVo;
|
||||
import com.microservices.pms.project.domain.vo.PmsProjectTestcaseStepDataVo;
|
||||
import com.microservices.pms.project.domain.vo.*;
|
||||
import com.microservices.pms.project.mapper.PmsProjectTestcaseMapper;
|
||||
import com.microservices.pms.project.mapper.PmsProjectTestcaseStepMapper;
|
||||
import com.microservices.pms.project.mapper.PmsProjectTestsheetCasesMapper;
|
||||
import com.microservices.pms.project.service.IPmsProjectService;
|
||||
import com.microservices.pms.project.service.IPmsProjectTestcaseService;
|
||||
|
@ -32,12 +31,24 @@ import com.microservices.pms.project.service.IPmsProjectTestcaseTypeService;
|
|||
import com.microservices.pms.utils.PmsConstants;
|
||||
import com.microservices.pms.utils.PmsUtils;
|
||||
import com.microservices.system.api.domain.SysUser;
|
||||
import org.apache.poi.xwpf.usermodel.*;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.math.BigInteger;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.microservices.common.core.utils.PageUtils.startPage;
|
||||
|
@ -70,6 +81,8 @@ public class PmsProjectTestcaseServiceImpl implements IPmsProjectTestcaseService
|
|||
private PmsProjectTestsheetCasesMapper pmsProjectTestsheetCasesMapper;
|
||||
@Autowired
|
||||
private IPmsProductRequirementService pmsProductRequirementService;
|
||||
@Autowired
|
||||
private PmsProjectTestcaseStepMapper pmsProjectTestcaseStepMapper;
|
||||
|
||||
/**
|
||||
* 查询测试用例管理
|
||||
|
@ -168,6 +181,9 @@ public class PmsProjectTestcaseServiceImpl implements IPmsProjectTestcaseService
|
|||
PmsProjectTestcaseDetailVo pmsProjectTestcaseDetailVo = pmsProjectTestcaseDataVo.toPmsProjectTestcaseDetailVo();
|
||||
pmsProjectTestcaseDetailVo.setPreconditions(pmsProjectTestcase.getPreconditions());
|
||||
pmsProjectTestcaseDetailVo.setRemark(pmsProjectTestcase.getRemark());
|
||||
pmsProjectTestcaseDetailVo.setDescription(pmsProjectTestcase.getDescription());
|
||||
pmsProjectTestcaseDetailVo.setTestMethod(pmsProjectTestcase.getTestMethod());
|
||||
pmsProjectTestcaseDetailVo.setTerminationConditions(pmsProjectTestcase.getTerminationConditions());
|
||||
// 设置测试步骤列表
|
||||
PmsProjectTestcaseStep pmsProjectTestcaseStepSearch = new PmsProjectTestcaseStep();
|
||||
pmsProjectTestcaseStepSearch.setPmsTestcaseId(pmsProjectTestcase.getId());
|
||||
|
@ -493,4 +509,837 @@ public class PmsProjectTestcaseServiceImpl implements IPmsProjectTestcaseService
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
//测试用例导出相关
|
||||
/**
|
||||
* 从数据库osredem-microservices,表pms_project_testcase中获取测试用例信息存到集合中
|
||||
*
|
||||
* @param item 项目id
|
||||
**/
|
||||
public List<PmsProjectTestcaseVo> getTestcase(Long item) {
|
||||
return pmsProjectTestcaseMapper.getTestcase(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从数据库osredem-microservices,表pms_project_testcase_step中获取测试步骤信息存到集合中
|
||||
*
|
||||
* @param item 表pms_project_testcase中index
|
||||
**/
|
||||
public List<PmsProjectTestcaseStepVo> getTestcaseStep(Long item) {
|
||||
return pmsProjectTestcaseStepMapper.getTestcaseStep(item);
|
||||
}
|
||||
|
||||
private String typeIdtoSting(Long typeId) {
|
||||
switch (Math.toIntExact(typeId)) {
|
||||
case 1:
|
||||
return "功能测试";
|
||||
case 2:
|
||||
return "性能测试";
|
||||
case 3:
|
||||
return "接口测试";
|
||||
case 4:
|
||||
return "安装部署";
|
||||
case 5:
|
||||
return "安全相关";
|
||||
case 6:
|
||||
return "配置相关";
|
||||
default:
|
||||
return "其他";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 将项目id下所有测试用例信息存到集合中
|
||||
*
|
||||
* @param item 项目id
|
||||
**/
|
||||
public List<PendingOutputDataVo> GetPendingOutputData(Long item, Long moduleId) {
|
||||
List<PendingOutputDataVo> outputDatas = new ArrayList<PendingOutputDataVo>();
|
||||
// 数据库中信息类存到testcases集合中
|
||||
List<PmsProjectTestcaseVo> testcases = getTestcase(item);
|
||||
|
||||
for (PmsProjectTestcaseVo testcase : testcases) {
|
||||
if (testcase.getPmsModuleId() == moduleId) {
|
||||
List<PmsProjectTestcaseStepVo> steps = getTestcaseStep(testcase.getId());
|
||||
PendingOutputDataVo pendingOutputData = new PendingOutputDataVo();
|
||||
pendingOutputData.setId(testcase.getId());
|
||||
pendingOutputData.setTitle(testcase.getTitle());
|
||||
pendingOutputData.setTag_ids(testcase.getTagIds());
|
||||
pendingOutputData.setTest_type(typeIdtoSting(testcase.getTypeId()));
|
||||
pendingOutputData.setTitle(testcase.getTitle());
|
||||
pendingOutputData.setPreconditions(testcase.getPreconditions());
|
||||
pendingOutputData.setUpdate_by(testcase.getUpdateBy());
|
||||
pendingOutputData.setUpdate_time(testcase.getUpdateTime());
|
||||
pendingOutputData.setCreate_by(testcase.getCreateBy());
|
||||
pendingOutputData.setCreate_time(testcase.getCreateTime());
|
||||
pendingOutputData.setDescription(testcase.getDescription());
|
||||
pendingOutputData.setTest_method(testcase.getTestMethod());
|
||||
pendingOutputData.setTermination_conditions(testcase.getTerminationConditions());
|
||||
pendingOutputData.setIdentifier(testcase.getIdentifier());
|
||||
if (steps != null) {
|
||||
for (PmsProjectTestcaseStepVo step : steps) {
|
||||
pendingOutputData.addContent(step.getContent());
|
||||
pendingOutputData.addExpected(step.getExpectedResult());
|
||||
}
|
||||
}
|
||||
outputDatas.add(pendingOutputData);
|
||||
}
|
||||
}
|
||||
return outputDatas;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 水平合并单元格(跨列合并)
|
||||
*
|
||||
* @param wordExtractor 表格对象
|
||||
* @param indentation 缩进值 1cm = 567
|
||||
* @param text 写入单元格字符串
|
||||
* @param isCenter 表格中段落是否居中
|
||||
* @param isBold 表格中段落是否加租
|
||||
*/
|
||||
private void autoWrap(XWPFTableCell wordExtractor, Integer indentation, String text, boolean isCenter, boolean isBold) {
|
||||
XWPFParagraph paragraph = wordExtractor.getParagraphs().get(0);
|
||||
// 设置单元格文本垂直居中
|
||||
CTTcPr tcPr = wordExtractor.getCTTc().addNewTcPr();
|
||||
CTVerticalJc va = tcPr.addNewVAlign();
|
||||
va.setVal(STVerticalJc.CENTER);
|
||||
// 设置段前段后间距
|
||||
CTP ctp = paragraph.getCTP();
|
||||
CTPPr pPr = ctp.isSetPPr() ? ctp.getPPr() : ctp.addNewPPr();
|
||||
CTSpacing spacing = pPr.isSetSpacing() ? pPr.getSpacing() : pPr.addNewSpacing();
|
||||
spacing.setBefore(BigInteger.valueOf(0)); // 段前间距
|
||||
spacing.setAfter(BigInteger.valueOf(0));
|
||||
//设置居中
|
||||
if (isCenter) {
|
||||
paragraph.setAlignment(ParagraphAlignment.CENTER);
|
||||
}
|
||||
// 设置缩进
|
||||
CTInd ind = pPr.isSetInd() ? pPr.getInd() : pPr.addNewInd();
|
||||
ind.setLeft(BigInteger.valueOf(indentation)); // 1cm = 567
|
||||
// 设置自动换行
|
||||
CTPPr pPr2 = paragraph.getCTP().addNewPPr();
|
||||
CTSpacing spacing2 = pPr2.addNewSpacing();
|
||||
spacing2.setLineRule(STLineSpacingRule.AUTO);
|
||||
// 设置字体样式
|
||||
XWPFRun run = paragraph.createRun();
|
||||
run.setText(text);//填写单元格内容
|
||||
//设置字体为五号 10.5*2
|
||||
CTRPr rPr = run.getCTR().isSetRPr() ? run.getCTR().getRPr() : run.getCTR().addNewRPr();
|
||||
rPr.addNewSz().setVal(BigInteger.valueOf(21));
|
||||
rPr.addNewSzCs().setVal(BigInteger.valueOf(21));
|
||||
// 字体样式
|
||||
run.setFontFamily("Times New Roman");
|
||||
run.setFontFamily("宋体", XWPFRun.FontCharRange.eastAsia);
|
||||
run.setBold(isBold); // 是否加粗
|
||||
}
|
||||
|
||||
/**
|
||||
* 水平合并单元格(跨列合并)
|
||||
*
|
||||
* @param table 表格对象
|
||||
* @param row 行索引
|
||||
* @param startCol 起始列索引
|
||||
* @param endCol 结束列索引
|
||||
*/
|
||||
private static void mergeCellsHorizontally(XWPFTable table, int row, int startCol, int endCol) {
|
||||
for (int cellIndex = startCol; cellIndex <= endCol; cellIndex++) {
|
||||
XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
|
||||
if (cellIndex == startCol) {
|
||||
// 第一个单元格设置合并范围
|
||||
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
|
||||
} else {
|
||||
// 后续单元格标记为继续合并
|
||||
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏表格的最后一行
|
||||
*
|
||||
* @param xwpfTabletable 表格对象
|
||||
*/
|
||||
private void hideTableRow(XWPFTable xwpfTabletable) {
|
||||
XWPFTableRow templateRow = xwpfTabletable.getRow(xwpfTabletable.getNumberOfRows()-1); // 使用最后一行作为模板
|
||||
CTTrPr trPr = templateRow.getCtRow().isSetTrPr() ? templateRow.getCtRow().getTrPr() : templateRow.getCtRow().addNewTrPr();
|
||||
trPr.addNewHidden();//.setVal("on"); // 隐藏模板行
|
||||
|
||||
//隐藏行中段落
|
||||
for (XWPFTableCell cell : templateRow.getTableCells()) {
|
||||
for (XWPFParagraph paragraph : cell.getParagraphs()) {
|
||||
CTPPr pPr = paragraph.getCTP().isSetPPr() ?
|
||||
paragraph.getCTP().getPPr() :
|
||||
paragraph.getCTP().addNewPPr();
|
||||
pPr.addNewRPr().addNewVanish();//.setVal("on");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置表格边框格式
|
||||
*
|
||||
* @param xwpfTabletable 表格对象
|
||||
*/
|
||||
private void setTableBorders(XWPFTable xwpfTabletable) {
|
||||
CTTblPr tblPr = xwpfTabletable.getCTTbl().getTblPr();
|
||||
CTTblBorders borders = tblPr.isSetTblBorders() ? tblPr.getTblBorders() : tblPr.addNewTblBorders();
|
||||
|
||||
// 设置上边框
|
||||
CTBorder top = borders.isSetTop() ? borders.getTop() : borders.addNewTop();
|
||||
top.setVal(STBorder.SINGLE); // 边框类型:单线
|
||||
top.setSz(BigInteger.valueOf(12)); // 边框大小:8 = 1pt
|
||||
top.setColor("000000"); // 边框颜色:黑色
|
||||
|
||||
// 设置下边框
|
||||
CTBorder bottom = borders.isSetBottom() ? borders.getBottom() : borders.addNewBottom();
|
||||
bottom.setVal(STBorder.SINGLE);
|
||||
bottom.setSz(BigInteger.valueOf(6));
|
||||
bottom.setColor("000000");
|
||||
|
||||
// 设置左边框
|
||||
CTBorder left = borders.isSetLeft() ? borders.getLeft() : borders.addNewLeft();
|
||||
left.setVal(STBorder.SINGLE);
|
||||
left.setSz(BigInteger.valueOf(12));
|
||||
left.setColor("000000");
|
||||
|
||||
// 设置右边框
|
||||
CTBorder right = borders.isSetRight() ? borders.getRight() : borders.addNewRight();
|
||||
right.setVal(STBorder.SINGLE);
|
||||
right.setSz(BigInteger.valueOf(12));
|
||||
right.setColor("000000");
|
||||
|
||||
// 设置内部水平边框
|
||||
CTBorder insideH = borders.isSetInsideH() ? borders.getInsideH() : borders.addNewInsideH();
|
||||
insideH.setVal(STBorder.SINGLE);
|
||||
insideH.setSz(BigInteger.valueOf(6)); // 比外边框细一些
|
||||
insideH.setColor("000000");
|
||||
|
||||
// 设置内部垂直边框
|
||||
CTBorder insideV = borders.isSetInsideV() ? borders.getInsideV() : borders.addNewInsideV();
|
||||
insideV.setVal(STBorder.SINGLE);
|
||||
insideV.setSz(BigInteger.valueOf(6));
|
||||
insideV.setColor("000000");
|
||||
}
|
||||
|
||||
private void fillTbale(XWPFTable xwpfTable, PendingOutputDataVo pendingOutputData) {
|
||||
for (XWPFTableRow row : xwpfTable.getRows()) {
|
||||
// 遍历行中的每个单元格
|
||||
for (XWPFTableCell cell : row.getTableCells()) {
|
||||
XWPFParagraph paragraph = cell.getParagraphs().get(0);
|
||||
// 设置单元格文本垂直居中
|
||||
CTTcPr tcPr = cell.getCTTc().addNewTcPr();
|
||||
CTVerticalJc va = tcPr.addNewVAlign();
|
||||
va.setVal(STVerticalJc.CENTER);
|
||||
// 设置段前段后间距
|
||||
CTP ctp = paragraph.getCTP();
|
||||
CTPPr pPr = ctp.isSetPPr() ? ctp.getPPr() : ctp.addNewPPr();
|
||||
CTSpacing spacing = pPr.isSetSpacing() ? pPr.getSpacing() : pPr.addNewSpacing();
|
||||
spacing.setBefore(BigInteger.valueOf(0)); // 段前间距
|
||||
spacing.setAfter(BigInteger.valueOf(0));
|
||||
}
|
||||
}
|
||||
//固定文本部分
|
||||
autoWrap(xwpfTable.getRow(0).getCell(0), 125,"测试用例名称",false,true);
|
||||
autoWrap(xwpfTable.getRow(1).getCell(0), 125,"测试用例标识",false,true);
|
||||
autoWrap(xwpfTable.getRow(1).getCell(5), 125,"测试追踪",false,true);
|
||||
autoWrap(xwpfTable.getRow(2).getCell(0), 125,"测试用例描述",false,true);
|
||||
autoWrap(xwpfTable.getRow(3).getCell(0), 125,"测试方法",false,true);
|
||||
autoWrap(xwpfTable.getRow(4).getCell(0), 125,"测试类型",false,true);
|
||||
autoWrap(xwpfTable.getRow(5).getCell(0), 62,"前提和约束(包括初始化要求)",false,true);
|
||||
autoWrap(xwpfTable.getRow(6).getCell(0), 125,"测试终止条件",false,true);
|
||||
autoWrap(xwpfTable.getRow(7).getCell(0), 125,"测试过程",true,true);
|
||||
autoWrap(xwpfTable.getRow(8).getCell(0), 125,"序号",false,true);
|
||||
autoWrap(xwpfTable.getRow(8).getCell(1), 125,"输入及操作步骤",true,true);
|
||||
autoWrap(xwpfTable.getRow(8).getCell(4), 125,"期望测试结果",true,true);
|
||||
autoWrap(xwpfTable.getRow(8).getCell(6), 125,"评估准则",true,true);
|
||||
autoWrap(xwpfTable.getRow(8).getCell(8), 125,"实际测试结果",true,true);
|
||||
autoWrap(xwpfTable.getRow(xwpfTable.getNumberOfRows() - 4).getCell(0), 62,"设计人员",false,true);
|
||||
autoWrap(xwpfTable.getRow(xwpfTable.getNumberOfRows() - 4).getCell(4), 62,"设计日期",false,true);
|
||||
autoWrap(xwpfTable.getRow(xwpfTable.getNumberOfRows() - 3).getCell(0), 62,"测试人员",false,true);
|
||||
autoWrap(xwpfTable.getRow(xwpfTable.getNumberOfRows() - 3).getCell(4), 62,"测试执行时间",false,true);
|
||||
autoWrap(xwpfTable.getRow(xwpfTable.getNumberOfRows() - 2).getCell(0), 62,"执行结果",false,true);
|
||||
|
||||
//需要通过调取数据库中信息填入部分
|
||||
autoWrap(xwpfTable.getRow(0).getCell(3), 62,pendingOutputData.getTitle(),false,false);
|
||||
autoWrap(xwpfTable.getRow(1).getCell(3), 62,pendingOutputData.getIdentifier(),false,false);
|
||||
autoWrap(xwpfTable.getRow(2).getCell(3), 62,pendingOutputData.getDescription(),false,false);
|
||||
autoWrap(xwpfTable.getRow(3).getCell(3), 62,pendingOutputData.getTest_method(),false,false);
|
||||
autoWrap(xwpfTable.getRow(4).getCell(3), 62,pendingOutputData.getTest_type(),false,false);
|
||||
autoWrap(xwpfTable.getRow(5).getCell(3), 62,pendingOutputData.getPreconditions(),false,false);
|
||||
autoWrap(xwpfTable.getRow(6).getCell(3), 62,pendingOutputData.getTermination_conditions(),false,false);
|
||||
List<String> content = pendingOutputData.getContent_list();
|
||||
List<String> expected = pendingOutputData.getExpected_result();
|
||||
int i;
|
||||
for(i = 0;i<content.size();i++){
|
||||
autoWrap(xwpfTable.getRow(i + 9).getCell(0), 186,String.valueOf(i + 1),false,false);
|
||||
autoWrap(xwpfTable.getRow(i + 9).getCell(1), 62,content.get(i),false,false);
|
||||
autoWrap(xwpfTable.getRow(i + 9).getCell(4), 62,expected.get(i),false,false);
|
||||
}
|
||||
if(pendingOutputData.getUpdate_time()!=null ){
|
||||
autoWrap(xwpfTable.getRow(i + 9).getCell(2),62, pendingOutputData.getUpdate_by(), false,false);
|
||||
autoWrap(xwpfTable.getRow(i + 9).getCell(6),62, String.format("%1$tY-%1$tm-%1$td",pendingOutputData.getUpdate_time()), false,false);
|
||||
} else{
|
||||
if(pendingOutputData.getCreate_time()!=null ){
|
||||
autoWrap(xwpfTable.getRow(i + 9).getCell(2),62, pendingOutputData.getCreate_by(), false,false);
|
||||
autoWrap(xwpfTable.getRow(i + 9).getCell(6),62, String.format("%1$tY-%1$tm-%1$td",pendingOutputData.getCreate_time()), false,false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void creatTableTemplate(XWPFDocument xwpfDocument,PendingOutputDataVo pendingOutputData) {
|
||||
//获取此用例步骤数
|
||||
int stepNumber = pendingOutputData.getContent_list().size();
|
||||
// 创建表格 - 宽度设置为所有列宽度之和
|
||||
XWPFTable table = xwpfDocument.createTable(stepNumber + 13, 9);
|
||||
|
||||
// 不显示表格最后行
|
||||
hideTableRow(table);
|
||||
|
||||
// 设置表格边框
|
||||
setTableBorders(table);
|
||||
|
||||
// 设置表格宽度为页面宽度的100%
|
||||
table.setWidth("100%");
|
||||
|
||||
// 设置表格布局为固定列宽
|
||||
CTTbl ctTable = table.getCTTbl();
|
||||
CTTblPr tblPr = ctTable.getTblPr() == null ? ctTable.addNewTblPr() : ctTable.getTblPr();
|
||||
CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW();
|
||||
tblPr.addNewTblLayout().setType(STTblLayoutType.FIXED);
|
||||
|
||||
// 初始化表格行的宽度
|
||||
List<String> columnWidths = new ArrayList<>();
|
||||
columnWidths.add("7.6%");
|
||||
columnWidths.add("11%");
|
||||
columnWidths.add("4.8%");
|
||||
columnWidths.add("11.1%");
|
||||
columnWidths.add("19.8%");
|
||||
columnWidths.add("7.3%");
|
||||
columnWidths.add("9%");
|
||||
columnWidths.add("9.1%");
|
||||
columnWidths.add("20.1%");
|
||||
|
||||
XWPFTableRow firstRow = table.getRow(0);
|
||||
for (int rowIndex = 0; rowIndex < table.getNumberOfRows(); rowIndex++) {
|
||||
XWPFTableRow row = table.getRow(rowIndex);
|
||||
for (int colIndex = 0; colIndex < columnWidths.size(); colIndex++) {
|
||||
row.getCell(colIndex).setWidth(columnWidths.get(colIndex));
|
||||
}
|
||||
}
|
||||
|
||||
// 生成模板第1行(通过合并方式)
|
||||
mergeCellsHorizontally(table, 0, 0, 2);
|
||||
mergeCellsHorizontally(table, 0, 3, 8);
|
||||
// 生成模板第2行(通过合并方式)
|
||||
mergeCellsHorizontally(table, 1, 0, 2);
|
||||
mergeCellsHorizontally(table, 1, 3, 4);
|
||||
mergeCellsHorizontally(table, 1, 5, 6);
|
||||
mergeCellsHorizontally(table, 1, 7, 8);
|
||||
// 生成模板第3行(通过合并方式)
|
||||
mergeCellsHorizontally(table, 2, 0, 2);
|
||||
mergeCellsHorizontally(table, 2, 3, 8);
|
||||
// 生成模板第4行(通过合并方式)
|
||||
mergeCellsHorizontally(table, 3, 0, 2);
|
||||
mergeCellsHorizontally(table, 3, 3, 8);
|
||||
// 生成模板第5行(通过合并方式)
|
||||
mergeCellsHorizontally(table, 4, 0, 2);
|
||||
mergeCellsHorizontally(table, 4, 3, 8);
|
||||
// 生成模板第6行(通过合并方式)
|
||||
mergeCellsHorizontally(table, 5, 0, 2);
|
||||
mergeCellsHorizontally(table, 5, 3, 8);
|
||||
// 生成模板第7行(通过合并方式)
|
||||
mergeCellsHorizontally(table, 6, 0, 2);
|
||||
mergeCellsHorizontally(table, 6, 3, 8);
|
||||
// 生成模板第8行(通过合并方式)
|
||||
mergeCellsHorizontally(table, 7, 0, 8);
|
||||
// 生成模板第9行(通过合并方式)
|
||||
mergeCellsHorizontally(table, 8, 1, 3);
|
||||
mergeCellsHorizontally(table, 8, 4, 5);
|
||||
mergeCellsHorizontally(table, 8, 6, 7);
|
||||
// 生成模板操作步骤
|
||||
for (int stepRowIndex = 0; stepRowIndex < stepNumber; stepRowIndex++) {
|
||||
mergeCellsHorizontally(table, stepRowIndex + 9, 1, 3);
|
||||
mergeCellsHorizontally(table, stepRowIndex + 9, 4, 5);
|
||||
mergeCellsHorizontally(table, stepRowIndex + 9, 6, 7);
|
||||
}
|
||||
//生成模版倒数第三行
|
||||
mergeCellsHorizontally(table, table.getNumberOfRows() - 4, 0, 1);
|
||||
mergeCellsHorizontally(table, table.getNumberOfRows() - 4, 2, 3);
|
||||
mergeCellsHorizontally(table, table.getNumberOfRows() - 4, 4, 5);
|
||||
mergeCellsHorizontally(table, table.getNumberOfRows() - 4, 6, 8);
|
||||
//生成模版倒数第二行
|
||||
mergeCellsHorizontally(table, table.getNumberOfRows() - 3, 0, 1);
|
||||
mergeCellsHorizontally(table, table.getNumberOfRows() - 3, 2, 3);
|
||||
mergeCellsHorizontally(table, table.getNumberOfRows() - 3, 4, 5);
|
||||
mergeCellsHorizontally(table, table.getNumberOfRows() - 3, 6, 8);
|
||||
//生成模版倒数第一行
|
||||
mergeCellsHorizontally(table, table.getNumberOfRows() - 2, 0, 1);
|
||||
mergeCellsHorizontally(table, table.getNumberOfRows() - 2, 2, 8);
|
||||
|
||||
// 在表格中填值
|
||||
fillTbale(table, pendingOutputData);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 添加表格标题(应该是<章节号>-<表格序号>)
|
||||
private static void addNumberedTableTitle(XWPFDocument doc, String titleText, int chapter, int tableCount) {
|
||||
XWPFParagraph titleParagraph = doc.createParagraph();
|
||||
titleParagraph.setAlignment(ParagraphAlignment.CENTER);
|
||||
XWPFRun run = titleParagraph.createRun();
|
||||
run.setText("表");
|
||||
//run.setText("表 " + chapter + "-" + tableNumber);
|
||||
// run.setText("表 " + titleText);
|
||||
// // 设置标题样式
|
||||
run.setFontFamily("Times New Roman");
|
||||
run.setFontFamily("宋体", XWPFRun.FontCharRange.eastAsia);
|
||||
run.setFontSize(12);
|
||||
|
||||
// 创建域开始字符
|
||||
XWPFRun startRun = titleParagraph.createRun();
|
||||
CTFldChar startFldChar = startRun.getCTR().addNewFldChar();
|
||||
startFldChar.setFldCharType(STFldCharType.BEGIN);
|
||||
|
||||
// 创建域代码
|
||||
XWPFRun codeRun = titleParagraph.createRun();
|
||||
String domainCode = " SEQ Table \\* ARABIC \\s " + chapter;
|
||||
codeRun.setText(domainCode);
|
||||
codeRun.setFontSize(12); // 设置字体大小,可根据需要调整
|
||||
codeRun.setFontFamily("Times New Roman");
|
||||
codeRun.setFontFamily("宋体", XWPFRun.FontCharRange.eastAsia);
|
||||
|
||||
// 创建域分隔字符
|
||||
XWPFRun sepRun = titleParagraph.createRun();
|
||||
CTFldChar sepFldChar = sepRun.getCTR().addNewFldChar();
|
||||
sepFldChar.setFldCharType(STFldCharType.SEPARATE);
|
||||
|
||||
// 创建域结果
|
||||
XWPFRun resultRun = titleParagraph.createRun();
|
||||
resultRun.setText(chapter + " - " + tableCount);
|
||||
resultRun.setFontSize(12); // 设置字体大小,可根据需要调整
|
||||
resultRun.setFontFamily("Times New Roman");
|
||||
resultRun.setFontFamily("宋体", XWPFRun.FontCharRange.eastAsia);
|
||||
|
||||
// 创建域结束字符
|
||||
XWPFRun endRun = titleParagraph.createRun();
|
||||
CTFldChar endFldChar = endRun.getCTR().addNewFldChar();
|
||||
endFldChar.setFldCharType(STFldCharType.END);
|
||||
|
||||
XWPFRun titlerun = titleParagraph.createRun();
|
||||
titlerun.setText(titleText);
|
||||
titlerun.setFontSize(12); // 设置字体大小,可根据需要调整
|
||||
titlerun.setFontFamily("Times New Roman");
|
||||
titlerun.setFontFamily("宋体", XWPFRun.FontCharRange.eastAsia);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建标题样式
|
||||
* @param document 文档
|
||||
* @param styleId 样式 ID
|
||||
* @param styleName 样式名称
|
||||
* @param fontSize 字体大小
|
||||
*/
|
||||
private static void createTitleStyle(XWPFDocument document, String styleId, String styleName, int fontSize, int level, BigInteger numId) {
|
||||
// 获取文档的样式管理器
|
||||
XWPFStyles styles = document.createStyles();
|
||||
// 创建新的样式
|
||||
CTStyle ctStyle = CTStyle.Factory.newInstance();
|
||||
ctStyle.setStyleId(styleId);
|
||||
|
||||
CTString styleNameCT = CTString.Factory.newInstance();
|
||||
styleNameCT.setVal(styleName);
|
||||
ctStyle.setName(styleNameCT);
|
||||
|
||||
// 设置样式类型为段落样式
|
||||
CTDecimalNumber indentNumber = CTDecimalNumber.Factory.newInstance();
|
||||
indentNumber.setVal(BigInteger.valueOf(1));
|
||||
ctStyle.setType(STStyleType.PARAGRAPH);
|
||||
|
||||
// 设置字体和字号
|
||||
CTPPr ppr = ctStyle.addNewPPr();
|
||||
CTSpacing spacing = ppr.addNewSpacing();
|
||||
spacing.setAfter(BigInteger.valueOf(0));
|
||||
spacing.setLineRule(STLineSpacingRule.AUTO);
|
||||
|
||||
CTDecimalNumber outlineLvl = ppr.addNewOutlineLvl();
|
||||
// 根据样式 ID 确定大纲级别
|
||||
if ("Heading1".equals(styleId)) {
|
||||
outlineLvl.setVal(BigInteger.valueOf(0));
|
||||
} else if ("Heading2".equals(styleId)) {
|
||||
outlineLvl.setVal(BigInteger.valueOf(1));
|
||||
} else if ("Heading3".equals(styleId)) {
|
||||
outlineLvl.setVal(BigInteger.valueOf(2));
|
||||
} else if ("Heading4".equals(styleId)) {
|
||||
outlineLvl.setVal(BigInteger.valueOf(3));
|
||||
} else if ("Heading5".equals(styleId)) {
|
||||
outlineLvl.setVal(BigInteger.valueOf(4));
|
||||
}
|
||||
|
||||
// 关联编号
|
||||
CTNumPr numPr = ppr.addNewNumPr();
|
||||
numPr.addNewNumId().setVal(numId);
|
||||
numPr.addNewIlvl().setVal(BigInteger.valueOf(level - 1));
|
||||
|
||||
// 设置字体样式
|
||||
CTRPr rpr = ctStyle.addNewRPr();
|
||||
CTFonts fonts = rpr.addNewRFonts();
|
||||
fonts.setEastAsia("宋体");
|
||||
fonts.setAscii("Times New Roman");
|
||||
fonts.setHAnsi("Times New Roman");
|
||||
if(styles.getNumberOfStyles() < 4){
|
||||
rpr.addNewSz().setVal(BigInteger.valueOf(fontSize * 2));
|
||||
}else{
|
||||
rpr.addNewSz().setVal(BigInteger.valueOf(24));
|
||||
}
|
||||
|
||||
// 将样式添加到样式管理器中
|
||||
styles.addStyle(new XWPFStyle(ctStyle));
|
||||
}
|
||||
|
||||
// 创建多级列表编号模板
|
||||
private static BigInteger createMultiLevelNumbering(XWPFDocument doc) {
|
||||
XWPFNumbering numbering = doc.createNumbering();
|
||||
// 获取或创建 CTNumbering(POI 4.1.2 兼容方式)
|
||||
CTNumbering ctNumbering;
|
||||
try {
|
||||
Field f = XWPFNumbering.class.getDeclaredField("ctNumbering");
|
||||
f.setAccessible(true);
|
||||
ctNumbering = (CTNumbering) f.get(numbering);
|
||||
if (ctNumbering == null) {
|
||||
ctNumbering = CTNumbering.Factory.newInstance();
|
||||
f.set(numbering, ctNumbering);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("无法初始化编号系统", e);
|
||||
}
|
||||
|
||||
CTAbstractNum abstractNum = CTAbstractNum.Factory.newInstance();
|
||||
abstractNum.setAbstractNumId(BigInteger.ZERO);
|
||||
|
||||
// 级别1样式:1.
|
||||
CTLvl lvl1 = abstractNum.addNewLvl();
|
||||
lvl1.setIlvl(BigInteger.ZERO);
|
||||
lvl1.addNewNumFmt().setVal(STNumberFormat.DECIMAL);
|
||||
lvl1.addNewLvlText().setVal("%1.");
|
||||
lvl1.addNewLvlJc().setVal(STJc.LEFT);
|
||||
lvl1.addNewStart().setVal(BigInteger.ONE);
|
||||
|
||||
// 级别2样式:1.1
|
||||
CTLvl lvl2 = abstractNum.addNewLvl();
|
||||
lvl2.setIlvl(BigInteger.ONE);
|
||||
lvl2.addNewNumFmt().setVal(STNumberFormat.DECIMAL);
|
||||
lvl2.addNewLvlText().setVal("%1.%2.");
|
||||
lvl2.addNewLvlJc().setVal(STJc.LEFT);
|
||||
lvl2.addNewStart().setVal(BigInteger.ONE);
|
||||
|
||||
// 级别3样式:1.1.1
|
||||
CTLvl lvl3 = abstractNum.addNewLvl();
|
||||
lvl3.setIlvl(BigInteger.valueOf(2));
|
||||
lvl3.addNewNumFmt().setVal(STNumberFormat.DECIMAL);
|
||||
lvl3.addNewLvlText().setVal("%1.%2.%3.");
|
||||
lvl3.addNewLvlJc().setVal(STJc.LEFT);
|
||||
lvl3.addNewStart().setVal(BigInteger.ONE);
|
||||
|
||||
// 级别4样式:1.1.1.1
|
||||
CTLvl lvl4 = abstractNum.addNewLvl();
|
||||
lvl4.setIlvl(BigInteger.valueOf(3));
|
||||
lvl4.addNewNumFmt().setVal(STNumberFormat.DECIMAL);
|
||||
lvl4.addNewLvlText().setVal("%1.%2.%3.%4.");
|
||||
lvl4.addNewLvlJc().setVal(STJc.LEFT);
|
||||
lvl4.addNewStart().setVal(BigInteger.ONE);
|
||||
|
||||
// 级别5样式:1.1.1.1.1
|
||||
CTLvl lvl5 = abstractNum.addNewLvl();
|
||||
lvl5.setIlvl(BigInteger.valueOf(4));
|
||||
lvl5.addNewNumFmt().setVal(STNumberFormat.DECIMAL);
|
||||
lvl5.addNewLvlText().setVal("%1.%2.%3.%4.%5.");
|
||||
lvl5.addNewLvlJc().setVal(STJc.LEFT);
|
||||
lvl5.addNewStart().setVal(BigInteger.ONE);
|
||||
|
||||
// 注册到文档
|
||||
ctNumbering.addNewAbstractNum().set(abstractNum);
|
||||
|
||||
CTNum num = ctNumbering.addNewNum();
|
||||
num.setNumId(BigInteger.ONE);
|
||||
num.addNewAbstractNumId().setVal(BigInteger.ZERO);
|
||||
|
||||
return BigInteger.ONE;
|
||||
}
|
||||
|
||||
private static void addNumberedHeading(XWPFDocument doc, String text, int level) {
|
||||
XWPFParagraph para = doc.createParagraph();
|
||||
para.setStyle("Heading" + level);
|
||||
XWPFRun run = para.createRun();
|
||||
run.setText(text);
|
||||
}
|
||||
|
||||
// 插入分页符(另起一页),生成最后一个表格后不用插入
|
||||
private void insertTable(XWPFDocument doc,List<PendingOutputDataVo> pendingOutputDatas, int chapter) {
|
||||
for (int i = 0; i < pendingOutputDatas.size(); i++) {
|
||||
PendingOutputDataVo pendingOutputData = pendingOutputDatas.get(i);
|
||||
//addNumberedTableTitle(doc, pendingOutputData.getTitle());
|
||||
addNumberedTableTitle(doc, pendingOutputData.getTitle(), chapter,i + 1);
|
||||
creatTableTemplate(doc,pendingOutputData);
|
||||
|
||||
if (i < pendingOutputDatas.size() - 1){
|
||||
XWPFParagraph pageBreak = doc.createParagraph();
|
||||
XWPFRun pageBreakRun = pageBreak.createRun();
|
||||
pageBreakRun.addBreak(BreakType.PAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void iterateTraversl(Long projectId, List<TreeSelect> treeSelects, XWPFDocument document){
|
||||
// 获取文档的样式管理器
|
||||
//XWPFStyles styles = document.createStyles();
|
||||
// 使用栈进行迭代遍历
|
||||
Stack<TreeSelect> stack = new Stack<>();
|
||||
// 先将所有根节点压入栈
|
||||
if (treeSelects != null) {
|
||||
for (int i = treeSelects.size() - 1; i >= 0; i--) {
|
||||
stack.push(treeSelects.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
int chapter = 1;
|
||||
while (!stack.isEmpty()) {
|
||||
TreeSelect current = stack.pop();
|
||||
|
||||
// 处理当前节点,这里简单打印节点信息,你可以根据需求修改
|
||||
//System.out.println("ID: " + current.getId() + ", 名称: " + current.getLabel() + ", 层级:" + current.getLevel() + ", 父ID: " + current.getParentId() + ", 是否叶子节点: " + current.getIsLeaf() );
|
||||
if (current.getIsLeaf()) {
|
||||
if(current.getId() > 0){
|
||||
addNumberedHeading(document, current.getLabel(), current.getLevel());
|
||||
List<PendingOutputDataVo> pendingOutputDatas = GetPendingOutputData(projectId, current.getId());
|
||||
insertTable(document, pendingOutputDatas, chapter);
|
||||
chapter = chapter + 1;
|
||||
} else {
|
||||
addNumberedHeading(document, current.getLabel(), current.getLevel());
|
||||
List<PendingOutputDataVo> pendingOutputDatas = GetPendingOutputData(projectId, null);
|
||||
insertTable(document, pendingOutputDatas, chapter);
|
||||
chapter = chapter + 1;
|
||||
}
|
||||
} else{
|
||||
if(current.getId() > 0){
|
||||
addNumberedHeading(document, current.getLabel(), current.getLevel());
|
||||
}
|
||||
}
|
||||
//处理当前节点结束
|
||||
|
||||
// 将子节点压入栈
|
||||
List<TreeSelect> children = current.getChildren();
|
||||
if (children != null) {
|
||||
for (int i = children.size() - 1; i >= 0; i--) {
|
||||
stack.push(children.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void generateWord(List<TreeSelect> treeSelects, Long projectId, HttpServletResponse response) throws IOException {
|
||||
// 创建一个新的 Word 文档
|
||||
XWPFDocument document = new XWPFDocument();
|
||||
|
||||
// 创建多级编号样式
|
||||
BigInteger numId = createMultiLevelNumbering(document);
|
||||
// 创建关联编号的标题样式
|
||||
createTitleStyle(document, "Heading1", "标题1", 18, 1, numId);
|
||||
createTitleStyle(document, "Heading2", "标题2", 16, 2, numId);
|
||||
createTitleStyle(document, "Heading3", "标题3", 14, 3, numId);
|
||||
createTitleStyle(document, "Heading4", "标题4", 12, 4, numId);
|
||||
createTitleStyle(document, "Heading5", "标题5", 12, 5, numId);
|
||||
// 写入标题"测试用例"
|
||||
XWPFParagraph title = document.createParagraph();
|
||||
title.setAlignment(ParagraphAlignment.CENTER); // 居中
|
||||
XWPFRun titleRun = title.createRun();
|
||||
titleRun.setText("测试用例");
|
||||
titleRun.setFontSize(22); // 字体大小
|
||||
titleRun.setFontFamily("宋体"); // 字体样式
|
||||
// 添加带自动编号的内容
|
||||
iterateTraversl(projectId, treeSelects, document);
|
||||
|
||||
// 设置响应头
|
||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||
response.setHeader("Content-Disposition", "attachment; filename=testCase_" + projectId + ".docx");
|
||||
|
||||
// 将文档写入响应输出流
|
||||
OutputStream outputStream = response.getOutputStream();
|
||||
document.write(outputStream);
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
document.close();
|
||||
}
|
||||
|
||||
// 导入测试用例相关
|
||||
/**
|
||||
* 处理docx文件将测试用例导入到数据库
|
||||
* @param projectId 项目id
|
||||
* @param file 导入的docx文件
|
||||
*/
|
||||
public void testcaseImport(Long projectId, MultipartFile file) throws IOException {
|
||||
List<Map<String, List<List<String>>>> allTables = extractTableDates(file);
|
||||
insertTestcaseValue(allTables, projectId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取word中所有表格中的行列数据,并存储到集合中
|
||||
* @param file 导入的docx文件
|
||||
* @return List<Map<String, List<List<String>>>> 存储表格内行列数据的集合
|
||||
*/
|
||||
private List<Map<String, List<List<String>>>> extractTableDates(MultipartFile file) throws IOException {
|
||||
InputStream inputStream = file.getInputStream();
|
||||
XWPFDocument document = new XWPFDocument(inputStream);
|
||||
|
||||
List<Map<String, List<List<String>>>> allTables = new ArrayList<>();
|
||||
// 获取文档中的所有表格
|
||||
List<XWPFTable> tables = document.getTables();
|
||||
|
||||
for (int i = 0; i < tables.size(); i++) {
|
||||
XWPFTable table = tables.get(i);
|
||||
Map<String, List<List<String>>> tableData = new HashMap<>();
|
||||
List<List<String>> rows = new ArrayList<>();
|
||||
|
||||
// 遍历表格中的每一行
|
||||
for (XWPFTableRow row : table.getRows()) {
|
||||
List<String> rowData = new ArrayList<>();
|
||||
// 遍历行中的每一列
|
||||
for (XWPFTableCell cell : row.getTableCells()) {
|
||||
// 获取单元格文本
|
||||
StringBuilder cellText = new StringBuilder();
|
||||
for (XWPFParagraph paragraph : cell.getParagraphs()) {
|
||||
for (XWPFRun run : paragraph.getRuns()) {
|
||||
cellText.append(run.getText(0));
|
||||
}
|
||||
}
|
||||
rowData.add(cellText.toString().trim());
|
||||
}
|
||||
rows.add(rowData);
|
||||
}
|
||||
|
||||
tableData.put("table_" + (i + 1), rows);
|
||||
if(tableData.get("table_" + (i + 1)).get(0).size() == 2 && tableData.get("table_" + (i + 1)).get(1).size() == 4 && tableData.get("table_" + (i + 1)).get(2).size() == 2){}
|
||||
allTables.add(tableData);
|
||||
}
|
||||
return allTables;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将集合中表格行列数据写入数据库中
|
||||
* @param tableRows 单个表格的行列数据
|
||||
* @return boolean 返回是否时测试用例表格数据
|
||||
*/
|
||||
private boolean testcaseTableValidation(List<List<String>> tableRows) {
|
||||
if (tableRows.size()>12) {
|
||||
return tableRows.get(0).size() == 2 && tableRows.get(1).size() == 4 && tableRows.get(8).size() == 5;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将集合中表格行列数据写入数据库中
|
||||
* @param allTables 所有表格的行列数据
|
||||
* @param projectId 当前项目ID
|
||||
*/
|
||||
private void insertTestcaseValue(List<Map<String, List<List<String>>>> allTables, Long projectId) throws IOException {
|
||||
// 遍历所有表格
|
||||
for (int tableIndex = 0; tableIndex < allTables.size(); tableIndex++) {
|
||||
Map<String, List<List<String>>> tableMap = allTables.get(tableIndex);
|
||||
// 假设每个 map 只有一个键值对
|
||||
String tableName = tableMap.keySet().iterator().next();
|
||||
List<List<String>> tableRows = tableMap.get(tableName);
|
||||
System.out.println("Table " + tableName + " rows: " + tableRows.size());
|
||||
if(testcaseTableValidation(tableRows)){
|
||||
PmsProjectTestcase testcase = new PmsProjectTestcase();
|
||||
List<PmsProjectTestcaseStep> testcaseSteps = new ArrayList<>();
|
||||
testcase.setPmsProjectId(projectId);
|
||||
testcase.setTitle(getTableCellValue(tableRows,0,1));
|
||||
testcase.setIdentifier(getTableCellValue(tableRows,1,1));
|
||||
testcase.setDescription(getTableCellValue(tableRows,2,1));
|
||||
testcase.setTestMethod(getTableCellValue(tableRows,3,1));
|
||||
String testType = getTableCellValue(tableRows,4,1);
|
||||
testcase.setTypeId(TypeToId(testType));
|
||||
testcase.setPreconditions(getTableCellValue(tableRows,5,1));
|
||||
testcase.setTerminationConditions(getTableCellValue(tableRows,6,1));
|
||||
for(int i = 9; i < tableRows.size(); i++){
|
||||
if (tableRows.get(i).size() > 4 && getTableCellValue(tableRows, i, 1) != null){
|
||||
PmsProjectTestcaseStep testcaseStep = new PmsProjectTestcaseStep();
|
||||
testcaseStep.setIndex(i - 8L);
|
||||
testcaseStep.setContent(getTableCellValue(tableRows, i, 1));
|
||||
testcaseStep.setExpectedResult(getTableCellValue(tableRows, i, 2));
|
||||
testcaseSteps.add(testcaseStep);
|
||||
} else {
|
||||
testcase.setCreateBy(getTableCellValue(tableRows, i, 1));
|
||||
Date date = stringToDateUsingDateTimeFormatter(getTableCellValue(tableRows, i , 3), "yyyy-MM-dd");
|
||||
testcase.setCreateTime(date);
|
||||
break;
|
||||
}
|
||||
}
|
||||
testcase.setTestcaseStepList(testcaseSteps);
|
||||
|
||||
testcase.setAssigneeGitlinkId(1L);
|
||||
// 获取当前项目下测试用例的最大索引值
|
||||
Long maxIndex = pmsProjectTestcaseMapper.selectPmsProjectTestcaseMaxIndexByProjectId(testcase.getPmsProjectId());
|
||||
if (maxIndex == null) {
|
||||
maxIndex = 1L;
|
||||
}
|
||||
testcase.setIndex(++maxIndex);
|
||||
pmsProjectTestcaseMapper.insertPmsProjectTestcase(testcase);
|
||||
// 批量新增测试步骤
|
||||
pmsProjectTestcaseStepService.batchInsertPmsProjectTestcaseStep(testcase.getId(), testcase.getTestcaseStepList());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用 DateTimeFormatter 和 LocalDate 将 String 转换为 Date
|
||||
* @param dateStr 日期字符串
|
||||
* @param pattern 日期格式模式
|
||||
* @return 转换后的 Date 对象
|
||||
*/
|
||||
public static Date stringToDateUsingDateTimeFormatter(String dateStr, String pattern) {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
|
||||
LocalDate localDate = LocalDate.parse(dateStr, formatter);
|
||||
Instant instant = localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
|
||||
return Date.from(instant);
|
||||
}
|
||||
|
||||
|
||||
private Long TypeToId(String type){
|
||||
switch (type) {
|
||||
case "功能测试":
|
||||
return 1L;
|
||||
case "性能测试":
|
||||
return 2L;
|
||||
case "接口测试":
|
||||
return 3L;
|
||||
case "安装部署":
|
||||
return 4L;
|
||||
case "安全相关":
|
||||
return 5L;
|
||||
case "配置相关":
|
||||
return 6L;
|
||||
default:
|
||||
// 其它类型
|
||||
return 7L;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用 DateTimeFormatter 和 LocalDate 将 String 转换为 Date
|
||||
* @param rows 单个表格所有行列数据
|
||||
* @param targetRowIndex 定位单元格的行索引
|
||||
* @param targetColIndex 定位单元格的列索引
|
||||
* @return cell获取的表格中字符串
|
||||
*/
|
||||
private String getTableCellValue(List<List<String>> rows, int targetRowIndex, int targetColIndex) {
|
||||
String cell = null;
|
||||
if (targetRowIndex < rows.size() && targetColIndex < rows.get(targetRowIndex).size()) {
|
||||
cell = rows.get(targetRowIndex).get(targetColIndex);
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
<result property="createBy" column="create_by"/>
|
||||
<result property="delFlag" column="del_flag"/>
|
||||
<result property="index" column="index"/>
|
||||
<result property="reservedField1" column="reserved_field_1"/>
|
||||
<result property="reservedField2" column="reserved_field_2"/>
|
||||
<result property="reservedField3" column="reserved_field_3"/>
|
||||
<result property="description" column="description"/>
|
||||
<result property="testMethod" column="test_method"/>
|
||||
<result property="terminationConditions" column="termination_conditions"/>
|
||||
<result property="identifier" column="identifier"/>
|
||||
<result property="productReqSpecsId" column="product_req_specs_id"/>
|
||||
</resultMap>
|
||||
|
@ -45,9 +45,9 @@
|
|||
create_by,
|
||||
del_flag,
|
||||
`index`,
|
||||
reserved_field_1,
|
||||
reserved_field_2,
|
||||
reserved_field_3,
|
||||
description,
|
||||
test_method,
|
||||
termination_conditions,
|
||||
identifier,
|
||||
product_req_specs_id
|
||||
from pms_project_testcase
|
||||
|
@ -127,9 +127,9 @@
|
|||
<if test="createBy != null">create_by,</if>
|
||||
<if test="delFlag != null">del_flag,</if>
|
||||
<if test="index != null">`index`,</if>
|
||||
<if test="reservedField1 != null">reserved_field_1,</if>
|
||||
<if test="reservedField2 != null">reserved_field_2,</if>
|
||||
<if test="reservedField3 != null">reserved_field_3,</if>
|
||||
<if test="description != null">description,</if>
|
||||
<if test="testMethod != null">test_method,</if>
|
||||
<if test="terminationConditions != null">termination_conditions,</if>
|
||||
<if test="identifier != null">identifier,</if>
|
||||
<if test="productReqSpecsId != null">product_req_specs_id,</if>
|
||||
</trim>
|
||||
|
@ -149,9 +149,9 @@
|
|||
<if test="createBy != null">#{createBy},</if>
|
||||
<if test="delFlag != null">#{delFlag},</if>
|
||||
<if test="index != null">#{index},</if>
|
||||
<if test="reservedField1 != null">#{reservedField1},</if>
|
||||
<if test="reservedField2 != null">#{reservedField2},</if>
|
||||
<if test="reservedField3 != null">#{reservedField3},</if>
|
||||
<if test="description != null">#{description},</if>
|
||||
<if test="testMethod != null">#{testMethod},</if>
|
||||
<if test="terminationConditions != null">#{terminationConditions},</if>
|
||||
<if test="identifier != null">#{identifier},</if>
|
||||
<if test="productReqSpecsId != null">#{productReqSpecsId},</if>
|
||||
</trim>
|
||||
|
@ -175,9 +175,9 @@
|
|||
<if test="createBy != null">create_by = #{createBy},</if>
|
||||
<if test="delFlag != null">del_flag = #{delFlag},</if>
|
||||
<if test="index != null">`index` = #{index},</if>
|
||||
<if test="reservedField1 != null">reserved_field_1 = #{reservedField1},</if>
|
||||
<if test="reservedField2 != null">reserved_field_2 = #{reservedField2},</if>
|
||||
<if test="reservedField3 != null">reserved_field_3 = #{reservedField3},</if>
|
||||
<if test="description != null">description = #{description},</if>
|
||||
<if test="testMethod != null">test_method = #{testMethod},</if>
|
||||
<if test="terminationConditions != null">termination_conditions = #{terminationConditions},</if>
|
||||
<if test="identifier != null">identifier = #{identifier},</if>
|
||||
<if test="productReqSpecsId != null">product_req_specs_id = #{productReqSpecsId},</if>
|
||||
</trim>
|
||||
|
@ -296,4 +296,27 @@
|
|||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
|
||||
<resultMap type="com.microservices.pms.project.domain.vo.PmsProjectTestcaseVo" id="PmsProjectTestcaseVo">
|
||||
<result property="id" column="id" />
|
||||
<result property="pmsProjiectId" column="pms_project_id" />
|
||||
<result property="title" column="title" />
|
||||
<result property="typeId" column="type_id" />
|
||||
<result property="tagIds" column="tag_ids"/>
|
||||
<result property="pmsModuleId" column="pms_module_id"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="preconditions" column="preconditions"/>
|
||||
<result property="description" column="description"/>
|
||||
<result property="testMethod" column="test_Method"/>
|
||||
<result property="terminationConditions" column="termination_conditions"/>
|
||||
<result property="identifier" column="identifier"/>
|
||||
</resultMap>
|
||||
<select id="getTestcase" resultMap="PmsProjectTestcaseVo">
|
||||
SELECT * FROM pms_project_testcase WHERE pms_project_id = #{project_id}
|
||||
</select>
|
||||
|
||||
</mapper>
|
|
@ -58,6 +58,16 @@
|
|||
where `index` = #{index}
|
||||
and pms_testcase_id=#{testcaseId}
|
||||
</select>
|
||||
<resultMap type="com.microservices.pms.project.domain.vo.PmsProjectTestcaseStepVo" id="PmsProjectTestcaseStepVo">
|
||||
<result property="index" column="index"/>
|
||||
<result property="content" column="content"/>
|
||||
<result property="expectedResult" column="expected_result"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
</resultMap>
|
||||
<select id="getTestcaseStep" resultMap="PmsProjectTestcaseStepVo">
|
||||
SELECT * FROM pms_project_testcase_step WHERE pms_testcase_id = #{pms_project_testcase_id}
|
||||
</select>
|
||||
|
||||
<insert id="insertPmsProjectTestcaseStep" parameterType="PmsProjectTestcaseStep" useGeneratedKeys="true"
|
||||
keyProperty="id">
|
||||
|
|
Loading…
Reference in New Issue