Compare commits

..

19 Commits

Author SHA1 Message Date
zengweizhang 49bdd12ff3 Merge pull request '修复test_tracking错误' (#905) from zengweizhang/microservices:master into dev_testCase_export 2025-05-30 11:00:55 +08:00
zwz b079d42fcd 修复test_tracking错误 2025-05-30 11:00:17 +08:00
zengweizhang 1ab2d600de Merge pull request '修复test_tracking错误' (#904) from zengweizhang/microservices:master into dev_testCase_export 2025-05-30 10:46:45 +08:00
zwz 4ca5dd0c51 修复test_tracking错误 2025-05-30 10:45:54 +08:00
zengweizhang 1f55b9878e Merge pull request '修复test_tracking错误' (#903) from zengweizhang/microservices:master into dev_testCase_export 2025-05-30 10:28:48 +08:00
zwz 34867e4580 修复test_tracking错误 2025-05-30 10:27:03 +08:00
zengweizhang 06825e82c1 Merge pull request '修复映射问题' (#902) from zengweizhang/microservices:master into dev_testCase_export 2025-05-30 09:42:38 +08:00
zwz 2f06bf137d 修复test_tracking错误 2025-05-30 09:40:26 +08:00
zengweizhang d887c6cf1b Merge pull request '获取测试用例管理详细信息 错误修复' (#901) from zengweizhang/microservices:master into dev_testCase_export 2025-05-29 19:50:20 +08:00
zwz 51fe5866e3 获取测试用例管理详细信息,用户未找到问题修复 2025-05-29 19:35:30 +08:00
wanjia9506 03abc0cf28 Merge pull request '获取测试用例管理详细信息 错误修复' (#898) from zengweizhang/microservices:master into dev_testCase_export 2025-05-29 17:21:49 +08:00
zwz 2218278c58 获取测试用例管理详细信息 错误修复 2025-05-29 16:59:06 +08:00
otto bd9382cf1c Merge pull request '新增测试用例 "测试追踪"、"是否导入" 字段,修复导入测试用例后列表刷新问题' (#895) from zengweizhang/microservices:master into dev_testCase_export 2025-05-29 15:18:08 +08:00
zwz 618b62d22d 新增测试用例 "测试追踪"、"是否导入" 字段,修复导入测试用例后列表刷新问题 2025-05-29 14:53:32 +08:00
zwz e8a6db6ac8 新增测试用例 "测试追踪"、"是否导入" 字段,修复导入测试用例后列表刷新问题 2025-05-29 14:48:42 +08:00
wanjia9506 a41c0192f2 Merge pull request '新增测试用例导入、导出功能,优化部分代码' (#887) from zengweizhang/microservices:master into dev_testCase_export 2025-05-27 16:54:12 +08:00
zwz bfa4e01372 Merge branch 'master' of https://gitlink.org.cn/Gitlink/microservices 2025-05-27 16:16:09 +08:00
zwz 72cb98c592 新增测试用例导入、导出功能,优化部分代码 2025-05-27 16:00:22 +08:00
zwz 7b1c5fe622 增加测试用例批量导出功能 2025-05-23 15:54:52 +08:00
53 changed files with 1397 additions and 915 deletions

View File

@ -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>

View File

@ -32,7 +32,6 @@ import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -173,12 +172,6 @@ public class PmsDashboardController extends BaseController {
}
todoProjectIssuesSearchVo.setPmProjectIds(StringUtils.join(projectList.stream().map(PmsProject::getId).toArray(), ","));
JSONObject result = pmsProjectIssuesService.selectMyTodoPmsProjectIssuesList(todoProjectIssuesSearchVo);
// 判断projectList中是否存在projectAssigneeId和当前用户id相等
Long currentUserId = SecurityUtils.getGitlinkUserId();
boolean isProjectAssigner = projectList.stream()
.anyMatch(project -> currentUserId != null && currentUserId.equals(project.getProjectAssigneeId()));
result.put("isProjectAssigner", isProjectAssigner);
return success(result);
}

View File

@ -20,7 +20,7 @@ import java.util.List;
/**
* 项目管理-文档库Controller
*
*
* @author wanjia
* @date 2024-01-08
*/
@ -30,7 +30,8 @@ import java.util.List;
@ApiImplicitParams({
@ApiImplicitParam(name = "enterpriseIdentifier", value = "企业标识", paramType = "path", dataType = "String")
})
public class PmsDocumentController extends BaseController {
public class PmsDocumentController extends BaseController
{
@Autowired
private IPmsDocumentService pmsDocumentService;
@ -45,7 +46,8 @@ public class PmsDocumentController extends BaseController {
@ApiImplicitParam(name = "orderByColumn", value = "排序列更新时间updateTime创建时间createTime", paramType = "query", dataType = "String"),
@ApiImplicitParam(name = "isAsc", value = "排序的方向desc或者asc,默认asc", paramType = "query", dataType = "String")
})
public GenericsTableDataInfo<PmsDocumentVo> list(@Validated PmsDocumentSearchVo pmsDocumentSearchVo) {
public GenericsTableDataInfo<PmsDocumentVo> list( @Validated PmsDocumentSearchVo pmsDocumentSearchVo)
{
return pmsDocumentService.selectPmsDocumentVoList(pmsDocumentSearchVo);
}
@ -56,7 +58,8 @@ public class PmsDocumentController extends BaseController {
@Log(title = "项目管理-文档库", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ApiOperation(value = "导出项目管理-文档库列表", hidden = true)
public void export(HttpServletResponse response, PmsDocument pmsDocument) {
public void export(HttpServletResponse response, PmsDocument pmsDocument)
{
List<PmsDocument> list = pmsDocumentService.selectPmsDocumentList(pmsDocument);
ExcelUtil<PmsDocument> util = new ExcelUtil<PmsDocument>(PmsDocument.class);
util.exportExcel(response, list, "项目管理-文档库数据");
@ -68,7 +71,8 @@ public class PmsDocumentController extends BaseController {
// @RequiresPermissions("pms:document:query")
@GetMapping(value = "/{id}")
@ApiOperation(value = "获取项目管理-文档库详细信息")
public AjaxResult getInfo(@PathVariable("id") Long id, @ApiParam("企业id") @RequestParam(name = "enterpriseId") Long enterpriseId) {
public AjaxResult getInfo(@PathVariable("id") Long id, @ApiParam("企业id") @RequestParam(name = "enterpriseId") Long enterpriseId)
{
return success(pmsDocumentService.selectPmsDocumentDetailVoByIdAndEnterpriseId(id, enterpriseId));
}
@ -79,7 +83,8 @@ public class PmsDocumentController extends BaseController {
@Log(title = "项目管理-文档库", businessType = BusinessType.INSERT)
@PostMapping
@ApiOperation(value = "新增项目管理-文档库")
public AjaxResult add(@RequestBody @Validated PmsDocumentInputVo pmsDocumentInputVo) {
public AjaxResult add(@RequestBody @Validated PmsDocumentInputVo pmsDocumentInputVo)
{
return toAjax(pmsDocumentService.insertPmsDocument(pmsDocumentInputVo.toPmsDocument()));
}
@ -90,7 +95,8 @@ public class PmsDocumentController extends BaseController {
@Log(title = "新增附件类型文档", businessType = BusinessType.INSERT)
@PostMapping("/fileType")
@ApiOperation(value = "新增附件类型文档")
public AjaxResult addFileTypeDoc(@RequestBody @Validated PmsFileTypeDocumentInputVo pmsFileTypeDocumentInputVo) {
public AjaxResult addFileTypeDoc(@RequestBody @Validated PmsFileTypeDocumentInputVo pmsFileTypeDocumentInputVo)
{
return toAjax(pmsDocumentService.insertPmsFileTypeDocument(pmsFileTypeDocumentInputVo));
}
@ -101,7 +107,8 @@ public class PmsDocumentController extends BaseController {
@Log(title = "项目管理-文档库", businessType = BusinessType.UPDATE)
@PutMapping
@ApiOperation(value = "修改项目管理-文档库")
public AjaxResult edit(@RequestBody PmsDocumentUpdateVo pmsDocumentUpdateVo) {
public AjaxResult edit(@RequestBody PmsDocumentUpdateVo pmsDocumentUpdateVo)
{
return toAjax(pmsDocumentService.updatePmsDocument(pmsDocumentUpdateVo.toPmsDocument()));
}
@ -110,11 +117,12 @@ public class PmsDocumentController extends BaseController {
*/
// @RequiresPermissions("pms:document:remove")
@Log(title = "项目管理-文档库", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
@DeleteMapping("/{ids}")
@ApiOperation(value = "删除项目管理-文档库")
public AjaxResult remove(@PathVariable Long[] ids,
@ApiParam("企业id") @RequestParam(name = "enterpriseId") Long enterpriseId,
@ApiParam("项目id") @RequestParam(name = "pmsProjectId", defaultValue = "0") Long pmsProjectId) {
@ApiParam("项目id") @RequestParam(name = "pmsProjectId", defaultValue = "0") Long pmsProjectId)
{
return toAjax(pmsDocumentService.deletePmsDocumentByIds(ids, enterpriseId, pmsProjectId));
}
@ -123,16 +131,8 @@ public class PmsDocumentController extends BaseController {
*/
@GetMapping(value = "/optionalWikiRepoList")
@ApiOperation(value = "导入wiki时可选的仓库列表")
public AjaxResult getOptionalWikiRepoList(@Validated OptionalWikiReposSearchVo optionalWikiReposSearchVo) {
public AjaxResult getOptionalWikiRepoList(@Validated OptionalWikiReposSearchVo optionalWikiReposSearchVo)
{
return success(pmsDocumentService.getOptionalWikiRepoList(optionalWikiReposSearchVo));
}
/**
* 下载文档类型文件
*/
@GetMapping(value = "/downloadDoc/{docId}")
@ApiOperation(value = "下载文档类型文件")
public void downloadDoc(@PathVariable String enterpriseIdentifier, @PathVariable Long docId, HttpServletResponse response) {
pmsDocumentService.downloadDoc(response, enterpriseIdentifier, docId);
}
}

View File

@ -5,7 +5,6 @@ import com.microservices.common.core.web.page.GenericsTableDataInfo;
import com.microservices.pms.document.domain.PmsDocument;
import com.microservices.pms.document.domain.vo.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
@ -94,6 +93,4 @@ public interface IPmsDocumentService
* @return
*/
JSONObject getOptionalWikiRepoList(OptionalWikiReposSearchVo optionalWikiReposSearchVo);
void downloadDoc(HttpServletResponse response, String enterpriseIdentifier, Long docId);
}

View File

@ -5,7 +5,6 @@ import com.microservices.common.core.constant.HttpStatus;
import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.utils.DateUtils;
import com.microservices.common.core.utils.StringUtils;
import com.microservices.common.core.utils.file.FileUtils;
import com.microservices.common.core.web.page.Breadcrumb;
import com.microservices.common.core.web.page.GenericsTableDataInfo;
import com.microservices.common.httpClient.util.GitLinkRequestHelper;
@ -22,7 +21,6 @@ import com.microservices.pms.enums.PmsDocumentType;
import com.microservices.pms.project.mapper.PmsProjectRepositoryMapper;
import com.microservices.pms.project.service.IPmsProjectService;
import com.microservices.pms.utils.PmsGitLinkRequestUrl;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
@ -30,12 +28,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.stream.Collectors;
@ -45,13 +38,13 @@ import static com.microservices.common.httpClient.constant.GitLinkConstants.DATA
/**
* 项目管理-文档库Service业务层处理
*
*
* @author wanjia
* @date 2024-01-08
*/
@Slf4j
@Service
public class PmsDocumentServiceImpl implements IPmsDocumentService {
public class PmsDocumentServiceImpl implements IPmsDocumentService
{
private static final Logger logger = LoggerFactory.getLogger(PmsDocumentServiceImpl.class);
@Resource
private PmsDocumentMapper pmsDocumentMapper;
@ -76,12 +69,13 @@ public class PmsDocumentServiceImpl implements IPmsDocumentService {
/**
* 查询项目管理-文档库
*
*
* @param id 项目管理-文档库主键
* @return 项目管理-文档库
*/
@Override
public PmsDocument selectPmsDocumentByIdAndEnterpriseId(Long id, Long enterpriseId) {
public PmsDocument selectPmsDocumentByIdAndEnterpriseId(Long id, Long enterpriseId)
{
boolean isEnterpriseAdmin = pmsCommonService.hasDocsManageRole(enterpriseId);
return pmsDocumentMapper.selectPmsDocumentByIdAndEnterpriseId(id, enterpriseId, isEnterpriseAdmin, SecurityUtils.getUsername());
}
@ -103,12 +97,13 @@ public class PmsDocumentServiceImpl implements IPmsDocumentService {
/**
* 查询项目管理-文档库列表
*
*
* @param pmsDocument 项目管理-文档库
* @return 项目管理-文档库
*/
@Override
public List<PmsDocument> selectPmsDocumentList(PmsDocument pmsDocument) {
public List<PmsDocument> selectPmsDocumentList(PmsDocument pmsDocument)
{
checkAuthAndReturnAdminStatus(pmsDocument.getPmsEnterpriseId());
return pmsDocumentMapper.selectPmsDocumentList(pmsDocument);
}
@ -121,7 +116,7 @@ public class PmsDocumentServiceImpl implements IPmsDocumentService {
pmsDocumentSearchVo.setCurrentUserName(currentUserName);
startPage();
List<PmsDocument> pmsDocumentList = pmsDocumentMapper.selectPmsDocumentListBySearchInput(pmsDocumentSearchVo);
GenericsTableDataInfo<PmsDocumentVo> page = toPage(pmsDocumentList, this::buildPmsDocumentVo);
GenericsTableDataInfo<PmsDocumentVo> page = toPage(pmsDocumentList,this::buildPmsDocumentVo);
//构建面包屑列表
if (pmsDocumentSearchVo.getParentId() != 0) {
List<Breadcrumb> breadcrumbs = buildBreadcrumbs(pmsDocumentSearchVo.getParentId());
@ -137,53 +132,21 @@ public class PmsDocumentServiceImpl implements IPmsDocumentService {
PmsEnterprise pmsEnterprise = pmsEnterpriseService.selectPmsEnterpriseById(enterpriseId);
Map<String, String> queryParams = buildRepoListQueryParams(optionalWikiReposSearchVo);
try {
return gitLinkRequestHelper.doGet(PmsGitLinkRequestUrl.GET_ORGANIZATION_REPO_LIST(pmsEnterprise.getEnterpriseIdentifier(), queryParams));
return gitLinkRequestHelper.doGet(PmsGitLinkRequestUrl.GET_ORGANIZATION_REPO_LIST(pmsEnterprise.getEnterpriseIdentifier(), queryParams));
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
@Override
public void downloadDoc(HttpServletResponse response, String enterpriseIdentifier, Long docId) {
PmsEnterprise enterprise = pmsEnterpriseService.selectPmsEnterpriseByIdentifier(enterpriseIdentifier);
PmsDocument pmsDocument = selectPmsDocumentByIdAndEnterpriseId(docId, enterprise.getId());
if (!pmsDocument.getDocType().equals(PmsDocumentType.DOCUMENT.getKey())) {
throw new ServiceException("当前接口仅允许下载文档类型");
}
Path tempFilePath = null;
try {
String docFileName = pmsDocument.getName() + ".md";
FileUtils.setAttachmentResponseHeader(response, docFileName);
// 创建临时文件
tempFilePath = Files.createTempFile(pmsDocument.getName(), ".md");
String content = "";
if (pmsDocument.getContent() != null) {
content = pmsDocument.getContent();
}
Files.write(tempFilePath, content.getBytes(StandardCharsets.UTF_8));
FileUtils.writeBytes(tempFilePath.toString(), response.getOutputStream());
} catch (IOException e) {
log.error("文档下载失败:{}", e.getMessage());
throw new ServiceException("文档下载失败");
} finally {
if (tempFilePath != null) {
try {
Files.deleteIfExists(tempFilePath);
} catch (IOException e) {
log.error("删除临时文件失败:{}", e.getMessage());
}
}
}
}
/**
* 新增项目管理-文档库
*
*
* @param pmsDocument 项目管理-文档库
* @return 结果
*/
@Override
public int insertPmsDocument(PmsDocument pmsDocument) {
public int insertPmsDocument(PmsDocument pmsDocument)
{
checkPmsProjectById(pmsDocument.getPmsProjectId());
checkAuthAndReturnAdminStatus(pmsDocument.getPmsEnterpriseId());
String currentUserName = SecurityUtils.getUsername();
@ -206,12 +169,13 @@ public class PmsDocumentServiceImpl implements IPmsDocumentService {
/**
* 修改项目管理-文档库
*
*
* @param pmsDocument 项目管理-文档库
* @return 结果
*/
@Override
public int updatePmsDocument(PmsDocument pmsDocument) {
public int updatePmsDocument(PmsDocument pmsDocument)
{
checkPmsProjectById(pmsDocument.getPmsProjectId());
String currentUserName = SecurityUtils.getUsername();
boolean isEnterpriseAdmin = checkAuthAndReturnAdminStatus(pmsDocument.getPmsEnterpriseId());
@ -231,7 +195,8 @@ public class PmsDocumentServiceImpl implements IPmsDocumentService {
* @return 结果
*/
@Override
public int deletePmsDocumentByIds(Long[] ids, Long enterpriseId, Long projectId) {
public int deletePmsDocumentByIds(Long[] ids, Long enterpriseId, Long projectId)
{
checkPmsProjectById(projectId);
String currentUserName = SecurityUtils.getUsername();
boolean isEnterpriseAdmin = checkAuthAndReturnAdminStatus(enterpriseId);
@ -242,12 +207,13 @@ public class PmsDocumentServiceImpl implements IPmsDocumentService {
/**
* 删除项目管理-文档库信息
*
*
* @param id 项目管理-文档库主键
* @return 结果
*/
@Override
public int deletePmsDocumentById(Long id, Long enterpriseId, Long projectId) {
public int deletePmsDocumentById(Long id, Long enterpriseId, Long projectId)
{
checkPmsProjectById(projectId);
String currentUserName = SecurityUtils.getUsername();
boolean isEnterpriseAdmin = checkAuthAndReturnAdminStatus(enterpriseId);
@ -340,7 +306,7 @@ public class PmsDocumentServiceImpl implements IPmsDocumentService {
throw new ServiceException("文件类型的文档名称个数与文件标识个数不匹配");
}
List<PmsDocument> pmsDocumentList = new ArrayList<>();
for (int i = 0; i < names.length; i++) {
for (int i=0; i < names.length; i++) {
PmsDocument pmsDocument = new PmsDocument();
BeanUtils.copyProperties(pmsFileTypeDocumentInputVo, pmsDocument);
pmsDocument.setName(names[i]);
@ -410,7 +376,7 @@ public class PmsDocumentServiceImpl implements IPmsDocumentService {
queryParams.put("pm_project_repository_ids", unlinkedRepoIdsString);
}
queryParams.put("search", optionalWikiReposSearchVo.getSearch());
queryParams.put("page", String.valueOf(optionalWikiReposSearchVo.getPage()));
queryParams.put("page" , String.valueOf(optionalWikiReposSearchVo.getPage()));
queryParams.put("limit", String.valueOf(optionalWikiReposSearchVo.getLimit()));
queryParams.put("sort_by", optionalWikiReposSearchVo.getSortBy());
queryParams.put("sort_direction", "desc");

View File

@ -118,8 +118,7 @@ public class ProductReqSpecsController extends BaseController {
@Log(title = "需求", businessType = BusinessType.UPDATE)
@PutMapping("/activePlan")
@ApiOperation(value = "需求纳入计划")
public AjaxResult activePlan(@PathVariable String enterpriseIdentifier, @RequestBody @Validated ProductReqSpecsActivePlanVo productReqSpecsActivePlanVo) {
productReqSpecsActivePlanVo.setEnterpriseIdentifier(enterpriseIdentifier);
public AjaxResult activePlan(@RequestBody @Validated ProductReqSpecsActivePlanVo productReqSpecsActivePlanVo) {
return toAjax(pmsProductRequirementService.activePlan(productReqSpecsActivePlanVo));
}

View File

@ -31,12 +31,8 @@ public class ProductReqSpecsActivePlanVo {
@NotNull
private Long projectId;
@ApiModelProperty(value = "企业标识", hidden = true)
private String enterpriseIdentifier;
public PmsProjectIssuesInputVo toPmsProjectIssuesInputVo(PmsProductRequirement reqSpecs, List<String> forgeFileIdentifierList) {
PmsProjectIssuesInputVo issue = new PmsProjectIssuesInputVo();
issue.setEnterpriseIdentifier(enterpriseIdentifier);
issue.setSubject(reqSpecs.getTitle());
issue.setPmProjectId(projectId);
issue.setStatusId(ProjectIssueStatus.RESOLVING.getId());

View File

@ -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

View File

@ -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<>();

View File

@ -32,7 +32,7 @@ import java.util.List;
* @date 2024-06-20
*/
@Service
public class PmsProductLibraryRepositoriesServiceImpl extends ProductLibraryCommonService implements IPmsProductLibraryRepositoriesService {
public class PmsProductLibraryRepositoriesServiceImpl implements IPmsProductLibraryRepositoriesService {
@Autowired
private PmsProductLibraryRepositoriesMapper pmsProductLibraryRepositoriesMapper;
@Autowired
@ -328,15 +328,7 @@ public class PmsProductLibraryRepositoriesServiceImpl extends ProductLibraryComm
pmsProductLibraryRepositoriesSearch.setPmsEnterpriseIdentifier(enterpriseIdentifier);
return PageUtils.toPage(
pmsProductLibraryRepositoriesMapper.selectPmsProductLibraryRepositoriesList(pmsProductLibraryRepositoriesSearch),
this::toPmsProductLibraryRepositoriesSimpleVo);
}
private PmsProductLibraryRepositoriesSimpleVo toPmsProductLibraryRepositoriesSimpleVo(PmsProductLibraryRepositories productLibraryRepositories) {
PmsProductLibraryRepositoriesSimpleVo target = productLibraryRepositories.toPmsProductLibraryRepositoriesSimpleVo();
if (StringUtils.isNotEmpty(externalUrl)) {
target.setUrl(target.getUrl().replace(nexusUrl, externalUrl));
}
return target;
PmsProductLibraryRepositories::toPmsProductLibraryRepositoriesSimpleVo);
}
@Override

View File

@ -43,7 +43,6 @@ import com.microservices.system.api.utils.FeignUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@ -61,7 +60,7 @@ import java.util.stream.Collectors;
* @author OTTO
*/
@Service
public class PmsProductLibraryServiceImpl extends ProductLibraryCommonService implements IPmsProductLibraryService {
public class PmsProductLibraryServiceImpl implements IPmsProductLibraryService {
private static final Logger log = LoggerFactory.getLogger(PmsProductLibraryServiceImpl.class);
@Autowired
@ -159,9 +158,6 @@ public class PmsProductLibraryServiceImpl extends ProductLibraryCommonService im
)
);
}
if (StringUtils.isNotEmpty(externalUrl)) {
pmsProductLibrarySimpleVo.setUrl(pmsProductLibrarySimpleVo.getUrl().replace(nexusUrl, externalUrl));
}
return pmsProductLibrarySimpleVo;
}

View File

@ -1,11 +0,0 @@
package com.microservices.pms.productLibrary.service.impl;
import org.springframework.beans.factory.annotation.Value;
public abstract class ProductLibraryCommonService {
@Value("${nexus.proxy.externalUrl:}")
public String externalUrl;
@Value("${nexus.proxy.targetAddr:}")
public String nexusUrl;
}

View File

@ -44,8 +44,7 @@ public class PmsProjectIssuesController extends BaseController {
@RequiresPermissions(value = {"pms:pmsProject:show", "pms:pmsProject:showMe", "pms:pmsProjectTestsheet:edit"}, logical = Logical.OR)
@GetMapping("/list")
@ApiOperation(value = "项目工作项列表")
public AjaxResult list(@PathVariable String enterpriseIdentifier, PmsProjectIssuesSearchVo pmsProjectIssuesSearchVo) {
pmsProjectIssuesSearchVo.setEnterpriseIdentifier(enterpriseIdentifier);
public AjaxResult list(PmsProjectIssuesSearchVo pmsProjectIssuesSearchVo) {
JSONObject result = pmsProjectIssuesService.selectPmsProjectIssuesList(pmsProjectIssuesSearchVo);
return success(result);
}
@ -385,15 +384,4 @@ public class PmsProjectIssuesController extends BaseController {
public void exportIssues(HttpServletResponse response, @ApiParam("项目Id") @RequestParam(name = "pmProjectId") Long pmProjectId) {
pmsProjectIssuesService.exportIssues(response, pmProjectId);
}
/**
* 同步更新issue企业标识
* 说明旧issues数据直接通过pmProjectId与pms建立关联新需求要与企业建立关联故需要同步更新issue企业标识
*/
@PutMapping("/updateIssueEnterpriseIdentifier")
@ApiOperation(value = "同步更新issue企业标识")
public AjaxResult updateIssueEnterpriseIdentifier() {
boolean result = pmsProjectIssuesService.updateIssueEnterpriseIdentifier();
return success(result);
}
}

View File

@ -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 文件");
}
}
}

View File

@ -2,8 +2,6 @@ package com.microservices.pms.project.controller;
import com.alibaba.fastjson2.JSONObject;
import com.microservices.common.core.web.domain.AjaxResult;
import com.microservices.pms.project.domain.vo.PmsPersonalWeeklyIssuesSearchVo;
import com.microservices.pms.project.domain.vo.PmsPersonalWeeklyReportSearchVo;
import com.microservices.pms.project.domain.vo.PmsProjectIssuesInputVo;
import com.microservices.pms.project.domain.vo.PmsProjectIssuesSearchVo;
import com.microservices.pms.project.service.PmsProjectIssuesService;
@ -37,62 +35,20 @@ public class PmsProjectWeeklyReportController {
*/
@GetMapping("/list")
@ApiOperation(value = "项目周报列表")
public AjaxResult list(@PathVariable String enterpriseIdentifier, PmsProjectIssuesSearchVo pmsProjectIssuesSearchVo)
public AjaxResult list(PmsProjectIssuesSearchVo pmsProjectIssuesSearchVo)
{
pmsProjectIssuesSearchVo.setEnterpriseIdentifier(enterpriseIdentifier);
JSONObject result = pmsProjectIssuesService.selectPmsProjectIssuesList(pmsProjectIssuesSearchVo);
return success(result);
}
/**
* 查询周报-个人工作项统计
*/
@GetMapping("/personal")
@ApiOperation(value = "周报-个人工作项统计")
public AjaxResult getPersonalWeeklyReport(@PathVariable String enterpriseIdentifier, PmsPersonalWeeklyReportSearchVo pmsPersonalWeeklyReportSearchVo)
{
JSONObject result = pmsProjectIssuesService.getPersonalIssuesStatistics(enterpriseIdentifier, pmsPersonalWeeklyReportSearchVo);
return success(result);
}
@GetMapping("/personalIssueList")
@ApiOperation(value = "周报-个人工作项列表")
public AjaxResult getPersonalIssueList(@PathVariable String enterpriseIdentifier, PmsPersonalWeeklyIssuesSearchVo pmsPersonalWeeklyIssuesSearchVo)
{
pmsPersonalWeeklyIssuesSearchVo.setEnterpriseIdentifier(enterpriseIdentifier);
JSONObject result = pmsProjectIssuesService.getPersonalIssueList(pmsPersonalWeeklyIssuesSearchVo);
return success(result);
}
/**
* 查询周报-项目组工作项统计
*/
@GetMapping("/projectTeam")
@ApiOperation(value = "周报-项目组工作项统计")
public AjaxResult getProjectTeamWeeklyReport(@PathVariable String enterpriseIdentifier)
{
JSONObject result = pmsProjectIssuesService.getProjectTeamIssuesStatistics(enterpriseIdentifier);
return success(result);
}
@GetMapping("/projectIssueList")
@ApiOperation(value = "周报-项目组工作项列表")
public AjaxResult getProjectIssueList(@PathVariable String enterpriseIdentifier, PmsProjectIssuesSearchVo pmsProjectIssuesSearchVo)
{
pmsProjectIssuesSearchVo.setEnterpriseIdentifier(enterpriseIdentifier);
JSONObject result = pmsProjectIssuesService.getProjectIssueList(pmsProjectIssuesSearchVo);
return success(result);
}
/**
* 新增项目项目周报
*/
@PostMapping("/add")
@ApiOperation(value = "新增项目周报")
public AjaxResult add(@PathVariable String enterpriseIdentifier, @RequestBody PmsProjectIssuesInputVo pmsProjectIssuesInputVo)
public AjaxResult add(@RequestBody PmsProjectIssuesInputVo pmsProjectIssuesInputVo)
{
pmsProjectIssuesInputVo.setEnterpriseIdentifier(enterpriseIdentifier);
JSONObject result = pmsProjectIssuesService.insertPmsProjectWeeklyReportIssues(pmsProjectIssuesInputVo);
JSONObject result = pmsProjectIssuesService.insertPmsProjectIssues(pmsProjectIssuesInputVo);
return success(result);
}
@ -103,18 +59,18 @@ public class PmsProjectWeeklyReportController {
@ApiOperation(value = "编辑项目周报")
public AjaxResult edit(@PathVariable("id") Long id, @RequestBody PmsProjectIssuesInputVo pmsProjectIssuesInputVo)
{
JSONObject result = pmsProjectIssuesService.updatePmsProjectWeeklyReportIssues(id, pmsProjectIssuesInputVo);
JSONObject result = pmsProjectIssuesService.updatePmsProjectIssues(id, pmsProjectIssuesInputVo);
return success(result);
}
/**
* 删除项目周报
*/
@DeleteMapping("/{id}")
public AjaxResult remove(@ApiParam( "周报id")@PathVariable Long id)
@DeleteMapping("/{ids}")
public AjaxResult remove(@ApiParam( "周报id数组,为-1时删除全部")@PathVariable Long[] ids, @ApiParam( "项目Id")@RequestParam(name = "pmProjectId") Long pmProjectId)
{
JSONObject result = pmsProjectIssuesService.deletePmsProjectWeeklyReportIssueByIds(id);
JSONObject result = pmsProjectIssuesService.deletePmsProjectIssueByIds(ids, pmProjectId);
return success(result);
}
@ -122,10 +78,10 @@ public class PmsProjectWeeklyReportController {
* 查看项目周报
*/
@GetMapping("/{id}")
public AjaxResult query(@PathVariable String enterpriseIdentifier, @PathVariable("id") Long id)
public AjaxResult query(@PathVariable("id") Long id, @ApiParam( "项目Id")@RequestParam(name = "pmProjectId") Long pmProjectId)
{
JSONObject result = pmsProjectIssuesService.selectPmsProjectIssueByIdAndEnterPrise(id, enterpriseIdentifier);
JSONObject result = pmsProjectIssuesService.selectPmsProjectIssueById(id, pmProjectId);
return success(result);
}
}

View File

@ -1,88 +0,0 @@
package com.microservices.pms.project.domain;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class ForgeIssues {
private Integer id;
private Integer trackerId;
private Integer projectId;
private String subject;
private Date dueDate;
private Integer categoryId;
private Integer statusId;
private Integer assignedToId;
private Integer priorityId;
private Integer fixedVersionId;
private Integer authorId;
private Date createdOn;
private Date updatedOn;
private Date startDate;
private Integer doneRatio;
private Float estimatedHours;
private Integer parentId;
private Integer rootId;
private Integer lft;
private Integer rgt;
private Boolean isPrivate;
private Date closedOn;
private Integer projectIssuesIndex;
private String issueType;
private Integer token;
private String issueTagsValue;
private Boolean isLock;
private String issueClassify;
private String refName;
private String branchName;
private String description;
private Integer blockchainTokenNum;
private Long pmProjectId;
private Long pmSprintId;
private Integer pmIssueType;
private BigDecimal timeScale;
private Integer childCount;
private Long changerId;
private Integer fakeId;
private String enterpriseIdentifier;
}

View File

@ -126,29 +126,35 @@ 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;
@ApiModelProperty(value = "测试追踪")
private String testTracking;
@ApiModelProperty(value = "产品需求id")
private Long productReqSpecsId;
@ApiModelProperty(value = "是否导入")
private Long isImport;
public PmsProjectTestcaseDataVo toPmsProjectTestcaseDataVo() {
PmsProjectTestcaseDataVo target = new PmsProjectTestcaseDataVo();
BeanUtils.copyProperties(this, target);

View File

@ -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);
}
}

View File

@ -1,46 +0,0 @@
package com.microservices.pms.project.domain.vo;
import com.microservices.common.core.utils.ServletUtils;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@ApiModel("个人周报工作项搜索对象")
public class PmsPersonalWeeklyIssuesSearchVo {
@ApiModelProperty(value = "用户gitlink用户id")
private Long userId;
@ApiModelProperty(value = "企业标识", hidden = true)
private String enterpriseIdentifier;
@ApiModelProperty(value = "工作项名称搜索关键词")
private String keyword;
@ApiModelProperty(value = "状态值,可多个状态逗号隔开")
private String statusIds;
@ApiModelProperty(value = "排序方式: issues.updated_on 更新时间 issues.created_on 创建时间 issue_priorities.position 优先级")
private String sortBy;
@ApiModelProperty(value = "排序方向:asc 正序 desc 倒序")
private String sortDirection;
@ApiModelProperty(value = "本周工作项页码")
private String thisWeekPage;
@ApiModelProperty(value = "分页数")
private String thisWeekLimit;
@ApiModelProperty(value = "本周工作项页码")
private String nextWeekPage;
@ApiModelProperty(value = "分页数")
private String nextWeekLimit;
public void setKeyword(String keyword) {
this.keyword = ServletUtils.urlDecode(keyword);
}
}

View File

@ -1,17 +0,0 @@
package com.microservices.pms.project.domain.vo;
import com.microservices.common.core.utils.ServletUtils;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel("个人周报工作项统计对象")
public class PmsPersonalWeeklyReportSearchVo {
@ApiModelProperty(value = "用户gitlink用户id", hidden = true)
private Long userId;
@ApiModelProperty(value = "企业标识", hidden = true)
private String enterpriseIdentifier;
}

View File

@ -9,10 +9,7 @@ import lombok.Data;
@ApiModel("项目工作项搜索对象")
public class PmsProjectIssuesSearchVo {
@ApiModelProperty(value = "企业标识", hidden = true)
private String enterpriseIdentifier;
@ApiModelProperty(value = "项目id")
@ApiModelProperty(value = "项目id", required = true)
private String pmProjectId;
@ApiModelProperty(value = "项目迭代id")

View File

@ -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;
/**
* 测试步骤列表
*/

View File

@ -84,6 +84,35 @@ 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;
@ApiModelProperty(value = "测试用例标识")
@Size(max = 255, message = "长度需要小于500")
private String identifier;
@ApiModelProperty(value = "测试追踪")
@Size(max = 255, message = "长度需要小于500")
private String testTracking;
/**
* 测试步骤列表
*/

View File

@ -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;
}

View File

@ -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;
/**
* 测试步骤列表
*/

View File

@ -0,0 +1,40 @@
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;
private String testTracking;
}

View File

@ -1,21 +0,0 @@
package com.microservices.pms.project.mapper;
import com.microservices.common.datasource.annotation.Slave;
import com.microservices.pms.project.domain.ForgeIssues;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 用户表 数据层
*
* @author microservices
*/
@Slave
@Mapper
public interface ForgeIssuesMapper {
List<ForgeIssues> getBriefIssues();
int updateForIssues(ForgeIssues forgeIssues);
}

View File

@ -89,8 +89,4 @@ public interface PmsProjectMapper
void updatePmsProjectNoProduct(@Param("projectIdList") List<Long> projectIdList);
PmsProject selectPmsProjectById(Long id);
List<Long> selectProjectIdsByAssigneeUserId(@Param("enterpriseIdentifier") String enterpriseIdentifier, @Param("gitlinkUserId") Long gitlinkUserId);
String selectEnterpriseIdentifierByProjectId(@Param("pmProjectId") Long pmProjectId);
}

View File

@ -80,8 +80,4 @@ public interface PmsProjectSprintMapper
Integer selectOpeningSprintLastWeekIterationCount(@Param("pmProjectId") Long pmProjectId);
PmsProjectSprintStatisticsVo selectPmsProjectSprintStatisticsByProjectId(@Param("pmProjectId") Long pmProjectId);
int selectNewSprintCurrentNaturalWeekCount(@Param("projectId") Long projectId);
int selectCompleteSprintCurrentNaturalWeekCount(@Param("projectId") Long projectId);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -68,8 +68,4 @@ public interface PmsProjectTestsheetMapper
int deletePmsProjectTestsheetByProjectId(@Param("projectId") Long projectId);
Integer selectCountBySprintId(@Param("sprintId") Long sprintId);
int selectNewTestSheetCurrentNaturalWeekCount(@Param("projectId") Long projectId);
int selectCompleteTestSheetCurrentNaturalWeekCount(@Param("projectId") Long projectId);
}

View File

@ -5,6 +5,7 @@ import com.microservices.common.core.web.page.GenericsTableDataInfo;
import com.microservices.pms.project.domain.PmsProject;
import com.microservices.pms.project.domain.vo.*;
import com.microservices.system.api.domain.SimpleSysUser;
import com.microservices.system.api.domain.SysNotice;
import java.util.List;
@ -99,6 +100,4 @@ public interface IPmsProjectService
JSONObject getMyRepositoriesStatistics(Long repositoryId);
PmsProject selectPmsProjectByIdNoCheckRole(Long pmsProjectId);
List<Long> selectProjectIdsByAssigneeUserId(String enterpriseIdentifier, Long gitlinkUserId);
}

View File

@ -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;
}

View File

@ -4,7 +4,6 @@ import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.utils.DateUtils;
import com.microservices.common.core.utils.StringUtils;
import com.microservices.common.httpClient.util.GitLinkRequestHelper;
import com.microservices.common.security.utils.SecurityUtils;
import com.microservices.pms.common.service.IPmsCommonService;
@ -15,14 +14,9 @@ import com.microservices.pms.enterprise.service.IPmsEnterpriseService;
import com.microservices.pms.enums.ProjectIssueStatus;
import com.microservices.pms.product.domain.enums.ProductReqStatus;
import com.microservices.pms.product.service.IPmsProductRequirementService;
import com.microservices.pms.project.domain.ForgeIssues;
import com.microservices.pms.project.domain.PmsProject;
import com.microservices.pms.project.domain.SimpleRepository;
import com.microservices.pms.project.domain.vo.*;
import com.microservices.pms.project.mapper.ForgeIssuesMapper;
import com.microservices.pms.project.mapper.PmsProjectMapper;
import com.microservices.pms.project.mapper.PmsProjectSprintMapper;
import com.microservices.pms.project.mapper.PmsProjectTestsheetMapper;
import com.microservices.pms.utils.PmsConstants;
import com.microservices.pms.utils.PmsGitLinkRequestUrl;
import com.microservices.pms.utils.PmsUtils;
@ -37,7 +31,6 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.net.URISyntaxException;
import java.util.*;
@ -79,14 +72,6 @@ public class PmsProjectIssuesService {
@Autowired
private IPmsCommonService pmsCommonService;
@Resource
private PmsProjectSprintMapper pmsProjectSprintMapper;
@Resource
private PmsProjectTestsheetMapper pmsProjectTestsheetMapper;
@Resource
private PmsProjectMapper pmsProjectMapper;
@Resource
private ForgeIssuesMapper forgeIssuesMapper;
public JSONObject selectPmsProjectIssuesList(PmsProjectIssuesSearchVo pmsProjectIssuesSearchVo) {
@ -107,7 +92,6 @@ public class PmsProjectIssuesService {
for (int i = 0; i < issues.size(); i++) {
JSONObject issue = issues.getJSONObject(i);
setIssueAssignersState(issue, gitlinkUserNickNameMap);
setIssuePmsProjectName(issue);
issues.set(i, issue);
}
issueListResult.put("issues", issues);
@ -115,60 +99,6 @@ public class PmsProjectIssuesService {
return issueListResult;
}
public JSONObject enrichProjectIssueList(JSONObject issueListResult) {
HashMap<Long, String> gitlinkUserNickNameMap = new HashMap<>();
if (issueListResult.containsKey("this_week_all_issues")) {
JSONArray issues = issueListResult.getJSONArray("this_week_all_issues");
if (issues != null) {
for (int i = 0; i < issues.size(); i++) {
JSONObject issue = issues.getJSONObject(i);
setIssueAssignersState(issue, gitlinkUserNickNameMap);
setIssuePmsProjectName(issue);
issues.set(i, issue);
}
issueListResult.put("this_week_all_issues", issues);
}
}
if (issueListResult.containsKey("next_week_all_issues")) {
JSONArray issues = issueListResult.getJSONArray("next_week_all_issues");
if (issues != null) {
for (int i = 0; i < issues.size(); i++) {
JSONObject issue = issues.getJSONObject(i);
setIssueAssignersState(issue, gitlinkUserNickNameMap);
setIssuePmsProjectName(issue);
issues.set(i, issue);
}
issueListResult.put("next_week_all_issues", issues);
}
}
if (issueListResult.containsKey("close_task_issues")) {
JSONArray issues = issueListResult.getJSONArray("close_task_issues");
if (issues != null) {
for (int i = 0; i < issues.size(); i++) {
JSONObject issue = issues.getJSONObject(i);
setIssueAssignersState(issue, gitlinkUserNickNameMap);
setIssuePmsProjectName(issue);
issues.set(i, issue);
}
issueListResult.put("close_task_issues", issues);
}
}
return issueListResult;
}
private void setIssuePmsProjectName(JSONObject issue) {
if (issue.containsKey("pm_project_id")) {
Long pmProjectId = issue.getLong("pm_project_id");
if (pmProjectId == null) {
return;
}
PmsProject pmsProject = pmsProjectMapper.selectPmsProjectById(pmProjectId);
if (pmsProject != null) {
issue.put("pm_project_name", pmsProject.getProjectName());
}
}
}
public JSONObject insertPmsProjectIssuesRestricted(PmsProjectIssuesInputVo pmsProjectIssuesInputVo) {
PmsProject pmsProject = pmsProjectService.selectAndCheckPmsProjectById(pmsProjectIssuesInputVo.getPmProjectId());
if (pmsProject.getPmsProductId() != null
@ -185,11 +115,6 @@ public class PmsProjectIssuesService {
return gitLinkRequestHelper.doPost(PmsGitLinkRequestUrl.CREATE_ISSUE(), issueInput);
}
public JSONObject insertPmsProjectWeeklyReportIssues(PmsProjectIssuesInputVo pmsProjectIssuesInputVo) {
JSONObject issueInput = convertPmsProjectIssuesInputVoToIssueInputJSON(pmsProjectIssuesInputVo);
return gitLinkRequestHelper.doPost(PmsGitLinkRequestUrl.CREATE_ISSUE(), issueInput);
}
@Transactional(rollbackFor = Exception.class)
public JSONObject updatePmsProjectIssues(Long id, PmsProjectIssuesInputVo pmsProjectIssuesInputVo) {
PmsProject pmsProject = pmsProjectService.selectAndCheckPmsProjectById(pmsProjectIssuesInputVo.getPmProjectId());
@ -227,7 +152,7 @@ public class PmsProjectIssuesService {
}
}
}
if (PmsConstants.PROJECT_ISSUE_TYPE_PERSONAL_WEEKLY_REPORT.equals(updatedIssue.getString("pm_issue_type"))
if (PmsConstants.PROJECT_ISSUE_TYPE_WEEKLY_REPORT.equals(updatedIssue.getString("pm_issue_type"))
&& updatedIssue.getString("root_id") != null
&& !updatedIssue.getJSONObject("author").getLong("id").equals(SecurityUtils.getGitlinkUserId())) {
throw new ServiceException("非本人周报,不可编辑");
@ -236,27 +161,6 @@ public class PmsProjectIssuesService {
return gitLinkRequestHelper.doPut(PmsGitLinkRequestUrl.UPDATE_ISSUE(id), issueInput);
}
public JSONObject updatePmsProjectWeeklyReportIssues(Long id, PmsProjectIssuesInputVo pmsProjectIssuesInputVo) {
JSONObject updatedIssue;
try {
updatedIssue = gitLinkRequestHelper.doGet(PmsGitLinkRequestUrl.GET_ISSUE(id, null));
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
isIssueCreatedByCurrentUser(updatedIssue);
JSONObject issueInput = convertPmsProjectIssuesInputVoToIssueInputJSON(pmsProjectIssuesInputVo);
return gitLinkRequestHelper.doPut(PmsGitLinkRequestUrl.UPDATE_ISSUE(id), issueInput);
}
private static void isIssueCreatedByCurrentUser(JSONObject updatedIssue) {
if ((PmsConstants.PROJECT_ISSUE_TYPE_PERSONAL_WEEKLY_REPORT.equals(updatedIssue.getString("pm_issue_type"))
|| PmsConstants.PROJECT_ISSUE_TYPE_GROUP_WEEKLY_REPORT.equals(updatedIssue.getString("pm_issue_type")))
&& updatedIssue.getString("root_id") != null
&& !updatedIssue.getJSONObject("author").getLong("id").equals(SecurityUtils.getGitlinkUserId())) {
throw new ServiceException("非本人周报,不可编辑");
}
}
public JSONObject batchUpdatePmsProjectIssues(Long pmProjectId, PmsProjectIssuesBatchUpdateVo pmsProjectIssuesUpdateVo) {
pmsProjectService.selectAndCheckPmsProjectById(pmProjectId);
//转换为issue入参
@ -276,17 +180,6 @@ public class PmsProjectIssuesService {
}
}
public JSONObject selectPmsProjectIssueByIdAndEnterPrise(Long id, String enterpriseIdentifier) {
PmsEnterprise pmsEnterprise = pmsEnterpriseService.selectPmsEnterpriseByIdentifier(enterpriseIdentifier);
try {
JSONObject result = setProjectIssueUserState(gitLinkRequestHelper.doGet(PmsGitLinkRequestUrl.GET_ISSUE(id, null)));
result.put("pm_enterprise_name", pmsEnterprise.getEnterpriseName());
return result;
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
public JSONObject selectPmsProjectIssueByIdNoCheckRole(Long id, Long pmProjectId) {
PmsProject pmsProject = pmsProjectService.selectPmsProjectByIdNoCheckRole(pmProjectId);
try {
@ -416,17 +309,6 @@ public class PmsProjectIssuesService {
return gitLinkRequestHelper.doDelete(PmsGitLinkRequestUrl.DELETE_ISSUES_BATCH(pmProjectId), jsonObject);
}
public JSONObject deletePmsProjectWeeklyReportIssueByIds(Long id) {
JSONObject updatedIssue;
try {
updatedIssue = gitLinkRequestHelper.doGet(PmsGitLinkRequestUrl.GET_ISSUE(id, null));
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
isIssueCreatedByCurrentUser(updatedIssue);
return gitLinkRequestHelper.doDelete(PmsGitLinkRequestUrl.DELETE_WEEKLY_REPORT_ISSUE(id));
}
public JSONObject selectPmsProjectIssueStatus() {
return gitLinkRequestHelper.doGet(PmsGitLinkRequestUrl.GET_REPO_ISSUE_DEFAULT_STATUS());
}
@ -692,108 +574,4 @@ public class PmsProjectIssuesService {
throw new RuntimeException(e);
}
}
public JSONObject getPersonalIssuesStatistics(String enterpriseIdentifier, PmsPersonalWeeklyReportSearchVo pmsPersonalWeeklyReportSearchVo) {
Long gitlinkUserId = SecurityUtils.getGitlinkUserId();
pmsPersonalWeeklyReportSearchVo.setUserId(gitlinkUserId);
pmsPersonalWeeklyReportSearchVo.setEnterpriseIdentifier(enterpriseIdentifier);
JSONObject issueSearch = new JSONObject();
convertObjectToJSONObject(pmsPersonalWeeklyReportSearchVo, issueSearch, null);
try {
return enrichProjectIssueList(gitLinkRequestHelper.doGet(PmsGitLinkRequestUrl.GET_WEEKLY_ISSUES_PERSONAL(issueSearch)));
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
public JSONObject getProjectTeamIssuesStatistics(String enterpriseIdentifier) {
List<Long> pmProjectIds = pmsProjectService.selectProjectIdsByAssigneeUserId(enterpriseIdentifier, SecurityUtils.getGitlinkUserId());
String pmProjectIdsStr = StringUtils.join(pmProjectIds, ",");
JSONObject result = gitLinkRequestHelper.doGet(PmsGitLinkRequestUrl.GET_WEEKLY_ISSUES_GROUP(enterpriseIdentifier, pmProjectIdsStr));
enrichProjectInfo(result);
return result;
}
public void enrichProjectInfo(JSONObject inputJson) {
if (inputJson == null) {
return;
}
// 遍历最外层 key
for (String projectIdStr : inputJson.keySet()) {
Long projectId;
try {
projectId = Long.valueOf(projectIdStr); // 转换为 Long
} catch (NumberFormatException e) {
// 非数字字符串跳过处理
continue;
}
// 查询项目信息
PmsProject project = pmsProjectMapper.selectPmsProjectById(projectId);
JSONObject innerData = inputJson.getJSONObject(projectIdStr);
if (project != null) {
// 将项目信息转换为 JSONObject
JSONObject projectInfo = new JSONObject();
projectInfo.put("projectId", project.getId());
projectInfo.put("projectName", project.getProjectName());
projectInfo.put("enterpriseId", project.getPmsEnterpriseId());
projectInfo.put("createdTime", project.getCreateTime());
// projectInfo 插入到原 JSON 的对应层级中
innerData.put("project_info", projectInfo);
}
// 统计新建迭代数
innerData.put("this_week_new_sprint_count", pmsProjectSprintMapper.selectNewSprintCurrentNaturalWeekCount(projectId));
// 统计完成迭代数
innerData.put("this_week_complete_sprint_count", pmsProjectSprintMapper.selectCompleteSprintCurrentNaturalWeekCount(projectId));
// 统计新建测试单数
innerData.put("this_week_new_test_sheet_count", pmsProjectTestsheetMapper.selectNewTestSheetCurrentNaturalWeekCount(projectId));
// 统计完成测试单数
innerData.put("this_week_complete_test_sheet_count", pmsProjectTestsheetMapper.selectCompleteTestSheetCurrentNaturalWeekCount(projectId));
}
}
public JSONObject getProjectIssueList(PmsProjectIssuesSearchVo pmsProjectIssuesSearchVo) {
List<Long> pmProjectIds = pmsProjectService.selectProjectIdsByAssigneeUserId(
pmsProjectIssuesSearchVo.getEnterpriseIdentifier(),
StringUtils.isEmpty(pmsProjectIssuesSearchVo.getAssignerId()) ? SecurityUtils.getGitlinkUserId() : Long.valueOf(pmsProjectIssuesSearchVo.getAssignerId()));
String pmProjectIdsStr = StringUtils.join(pmProjectIds, ",");
pmsProjectIssuesSearchVo.setPmProjectIds(pmProjectIdsStr);
JSONObject issueSearch = new JSONObject();
convertObjectToJSONObject(pmsProjectIssuesSearchVo, issueSearch, null);
try {
return setProjectIssueListUserState(gitLinkRequestHelper.doGet(PmsGitLinkRequestUrl.GET_GROUP_ISSUE_LIST(issueSearch)));
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
public JSONObject getPersonalIssueList(PmsPersonalWeeklyIssuesSearchVo pmsPersonalWeeklyIssuesSearchVo) {
pmsPersonalWeeklyIssuesSearchVo.setUserId(pmsPersonalWeeklyIssuesSearchVo.getUserId() == null ? SecurityUtils.getGitlinkUserId() : pmsPersonalWeeklyIssuesSearchVo.getUserId());
JSONObject issueSearch = new JSONObject();
convertObjectToJSONObject(pmsPersonalWeeklyIssuesSearchVo, issueSearch, null);
try {
return enrichProjectIssueList(gitLinkRequestHelper.doGet(PmsGitLinkRequestUrl.GET_PERSONAL_ISSUE_LIST(issueSearch)));
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
public boolean updateIssueEnterpriseIdentifier() {
Long currentUserId = SecurityUtils.getGitlinkUserId();
if (currentUserId == null || currentUserId != 831) {
return false;
}
List<ForgeIssues> forgeIssuesList = forgeIssuesMapper.getBriefIssues();
for (ForgeIssues forgeIssues : forgeIssuesList) {
String enterpriseIdentifier = pmsProjectMapper.selectEnterpriseIdentifierByProjectId(forgeIssues.getPmProjectId());
if (enterpriseIdentifier != null) {
forgeIssues.setEnterpriseIdentifier(enterpriseIdentifier);
forgeIssuesMapper.updateForIssues(forgeIssues);
}
}
return true;
}
}

View File

@ -127,6 +127,7 @@ public class PmsProjectRepositoryServiceImpl implements IPmsProjectRepositorySer
*/
@Override
public int insertPmsProjectRepository(PmsProjectRepository pmsProjectRepository) {
pmsProjectService.selectAndCheckPmsProjectById(pmsProjectRepository.getPmsProjectId());
//仓库已被关联返回错误提示
if (pmsProjectRepositoryMapper.countPmsProjectRepositoryByProjectRepositoryId(pmsProjectRepository.getProjectRepositoryId()) > 0) {
throw new ServiceException("代码库id:[%s]已被关联", pmsProjectRepository.getProjectRepositoryId());

View File

@ -396,11 +396,6 @@ public class PmsProjectServiceImpl implements IPmsProjectService {
return pmsProject;
}
@Override
public List<Long> selectProjectIdsByAssigneeUserId(String enterpriseIdentifier, Long gitlinkUserId) {
return pmsProjectMapper.selectProjectIdsByAssigneeUserId(enterpriseIdentifier, gitlinkUserId);
}
@Override
public PmsProject selectAndCheckPmsProjectById(String idStr) {
if (StringUtils.isEmpty(idStr)) {

View File

@ -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;
/**
* 查询测试用例管理
@ -83,7 +96,9 @@ public class PmsProjectTestcaseServiceImpl implements IPmsProjectTestcaseService
if (pmsProjectTestcase == null) {
throw new ServiceException("该测试用例不存在(测试用例ID[%s])", id);
}
pmsProjectService.selectPmsProjectById(pmsProjectTestcase.getPmsProjectId());
if(pmsProjectTestcase.getIsImport() == null){
pmsProjectService.selectPmsProjectById(pmsProjectTestcase.getPmsProjectId());
}
return pmsProjectTestcase;
}
@ -136,20 +151,22 @@ public class PmsProjectTestcaseServiceImpl implements IPmsProjectTestcaseService
, x -> pmsProductModuleService.selectPmsProductModuleById(x, false)
, pmsProjectTestcase.getPmsModuleId()));
}
// 设置需求创建人
pmsProjectTestcaseDataVo.setCreateBy(
PmsUtils.getSelectObjectInCache(
hashMap
, pmsCommonService::getNickNameByUsername
, pmsProjectTestcase.getCreateBy())
);
// 设置需求更新人
pmsProjectTestcaseDataVo.setUpdateBy(
PmsUtils.getSelectObjectInCache(
hashMap
, pmsCommonService::getNickNameByUsername
, pmsProjectTestcase.getUpdateBy())
);
if (pmsProjectTestcase.getIsImport() != null) {
// 设置需求创建人
pmsProjectTestcaseDataVo.setCreateBy(
PmsUtils.getSelectObjectInCache(
hashMap
, pmsCommonService::getNickNameByUsername
, pmsProjectTestcase.getCreateBy())
);
// 设置需求更新人
pmsProjectTestcaseDataVo.setUpdateBy(
PmsUtils.getSelectObjectInCache(
hashMap
, pmsCommonService::getNickNameByUsername
, pmsProjectTestcase.getUpdateBy())
);
}
// 设置产品需求
if (pmsProjectTestcase.getProductReqSpecsId() != null) {
pmsProjectTestcaseDataVo.setProductReqSpecs(
@ -168,6 +185,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());
@ -175,7 +195,9 @@ public class PmsProjectTestcaseServiceImpl implements IPmsProjectTestcaseService
// 设置附件列表
pmsProjectTestcaseDetailVo.setFileList(pmsCommonService.getAllFileByFileIdentifiers(pmsProjectTestcase.getFileIdentifiers()));
pmsCommonService.setBaseEntityVo(pmsProjectTestcaseDetailVo, pmsProjectTestcase);
if(pmsProjectTestcase.getIsImport() == null) {
pmsCommonService.setBaseEntityVo(pmsProjectTestcaseDetailVo, pmsProjectTestcase);
}
return pmsProjectTestcaseDetailVo;
}
@ -493,4 +515,847 @@ 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();
// 获取或创建 CTNumberingPOI 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.setIsImport(1L);
testcase.setTestcaseStepList(testcaseSteps);
if (testcase.getAssigneeGitlinkId() == null) {
// 未设置维护用户时默认为当前操作用户
testcase.setAssigneeGitlinkId(SecurityUtils.getGitlinkUserId());
}
if (testcase.getTypeId() == null) {
// 设置类型为默认值
PmsProjectTestcaseType defaultType = pmsProjectTestcaseTypeService.selectDefaultPmsProjectTestcaseType();
testcase.setTypeId(defaultType.getId());
}
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;
}
}

View File

@ -122,14 +122,9 @@ public class PmsConstants {
public final static String PROJECT_ISSUE_TYPE_BUG = "3";
/**
* 项目工作项个人周报类型
* 项目工作项周报类型
*/
public final static String PROJECT_ISSUE_TYPE_PERSONAL_WEEKLY_REPORT = "4";
/**
* 项目工作项项目组周报类型
*/
public final static String PROJECT_ISSUE_TYPE_GROUP_WEEKLY_REPORT = "5";
public final static String PROJECT_ISSUE_TYPE_WEEKLY_REPORT = "4";
/**
* 疑修筛选类型-全部

View File

@ -146,9 +146,7 @@ public class PmsGitLinkRequestUrl extends GitLinkRequestUrl {
public static GitLinkRequestUrl GET_ISSUE(Long id, Long pmProjectId) throws URISyntaxException {
Map<String, String> params = new HashMap<>();
if (pmProjectId != null) {
params.put("pm_project_id", String.valueOf(pmProjectId));
}
params.put("pm_project_id", String.valueOf(pmProjectId));
return getGitLinkRequestUrl(buildUri(String.format(
"/api/pm/issues/%s", id), params
));
@ -166,12 +164,6 @@ public class PmsGitLinkRequestUrl extends GitLinkRequestUrl {
));
}
public static GitLinkRequestUrl DELETE_WEEKLY_REPORT_ISSUE(Long id) {
return getGitLinkRequestUrl(String.format(
"/api/pm/issues/%s", id
));
}
public static GitLinkRequestUrl DELETE_ISSUES_BATCH(Long pmProjectId) {
String path = String.format("/api/pm/issues/batch_destroy?pm_project_id=%s", pmProjectId);
return getGitLinkRequestUrl(path);
@ -447,25 +439,4 @@ public class PmsGitLinkRequestUrl extends GitLinkRequestUrl {
public static GitLinkRequestUrl GET_ACTION_RUN_DATA(String owner, String workflows) {
return getGitLinkRequestUrl(String.format("/api/pm/action_runs?owner_id=%s&workflows=%s", owner, workflows), "data");
}
public static GitLinkRequestUrl GET_WEEKLY_ISSUES_PERSONAL(JSONObject issueSearch) throws URISyntaxException {
return getGitLinkRequestUrl(
buildUri("/api/pm/weekly_issues/personal.json", issueSearch));
}
public static GitLinkRequestUrl GET_WEEKLY_ISSUES_GROUP(String enterpriseIdentifier, String pmProjectIds){
return getGitLinkRequestUrl(
String.format("/api/pm/weekly_issues/group.json?enterprise_identifier=%s&pm_project_ids=%s", enterpriseIdentifier, pmProjectIds));
}
public static GitLinkRequestUrl GET_GROUP_ISSUE_LIST(JSONObject params) throws URISyntaxException {
return getGitLinkRequestUrl(
buildUri("/api/pm/weekly_issues/group_issues.json", params));
}
public static GitLinkRequestUrl GET_PERSONAL_ISSUE_LIST(JSONObject issueSearch) throws URISyntaxException {
return getGitLinkRequestUrl(
buildUri("/api/pm/weekly_issues/personal_issues.json", issueSearch));
}
}

View File

@ -1,61 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.microservices.pms.project.mapper.ForgeIssuesMapper">
<resultMap id="BaseResultMap" type="com.microservices.pms.project.domain.ForgeIssues">
<id column="id" property="id" jdbcType="INTEGER" />
<result column="tracker_id" property="trackerId" jdbcType="INTEGER" />
<result column="project_id" property="projectId" jdbcType="INTEGER" />
<result column="subject" property="subject" jdbcType="VARCHAR" />
<result column="due_date" property="dueDate" jdbcType="DATE" />
<result column="category_id" property="categoryId" jdbcType="INTEGER" />
<result column="status_id" property="statusId" jdbcType="INTEGER" />
<result column="assigned_to_id" property="assignedToId" jdbcType="INTEGER" />
<result column="priority_id" property="priorityId" jdbcType="INTEGER" />
<result column="fixed_version_id" property="fixedVersionId" jdbcType="INTEGER" />
<result column="author_id" property="authorId" jdbcType="INTEGER" />
<result column="created_on" property="createdOn" jdbcType="TIMESTAMP" />
<result column="updated_on" property="updatedOn" jdbcType="TIMESTAMP" />
<result column="start_date" property="startDate" jdbcType="DATE" />
<result column="done_ratio" property="doneRatio" jdbcType="INTEGER" />
<result column="estimated_hours" property="estimatedHours" jdbcType="REAL" />
<result column="parent_id" property="parentId" jdbcType="INTEGER" />
<result column="root_id" property="rootId" jdbcType="INTEGER" />
<result column="lft" property="lft" jdbcType="INTEGER" />
<result column="rgt" property="rgt" jdbcType="INTEGER" />
<result column="is_private" property="isPrivate" jdbcType="BIT" />
<result column="closed_on" property="closedOn" jdbcType="TIMESTAMP" />
<result column="project_issues_index" property="projectIssuesIndex" jdbcType="INTEGER" />
<result column="issue_type" property="issueType" jdbcType="VARCHAR" />
<result column="token" property="token" jdbcType="INTEGER" />
<result column="issue_tags_value" property="issueTagsValue" jdbcType="VARCHAR" />
<result column="is_lock" property="isLock" jdbcType="BIT" />
<result column="issue_classify" property="issueClassify" jdbcType="VARCHAR" />
<result column="ref_name" property="refName" jdbcType="VARCHAR" />
<result column="branch_name" property="branchName" jdbcType="VARCHAR" />
<result column="description" property="description" jdbcType="VARCHAR" />
<result column="blockchain_token_num" property="blockchainTokenNum" jdbcType="INTEGER" />
<result column="pm_project_id" property="pmProjectId" jdbcType="BIGINT" />
<result column="pm_sprint_id" property="pmSprintId" jdbcType="BIGINT" />
<result column="pm_issue_type" property="pmIssueType" jdbcType="INTEGER" />
<result column="time_scale" property="timeScale" jdbcType="DECIMAL" />
<result column="child_count" property="childCount" jdbcType="INTEGER" />
<result column="changer_id" property="changerId" jdbcType="BIGINT" />
<result column="fake_id" property="fakeId" jdbcType="INTEGER" />
<result column="enterprise_identifier" property="enterpriseIdentifier" jdbcType="VARCHAR" />
</resultMap>
<update id="updateForIssues">
UPDATE issues
set enterprise_identifier = #{enterpriseIdentifier}
where id = #{id}
</update>
<select id="getBriefIssues" resultMap="BaseResultMap">
SELECT
id, pm_project_id, enterprise_identifier
FROM
issues
WHERE pm_project_id IS NOT NULL AND (enterprise_identifier IS NULL OR enterprise_identifier = '');
</select>
</mapper>

View File

@ -173,19 +173,6 @@
from pms_project
<include refid="selectWhereBySearchVo"/>
</select>
<select id="selectProjectIdsByAssigneeUserId" resultType="java.lang.Long">
select pp.id
from pms_project pp
left join pms_enterprise pe on pe.id = pp.pms_enterprise_id
where pp.project_assignee_id = #{gitlinkUserId}
and pe.enterprise_identifier = #{enterpriseIdentifier}
</select>
<select id="selectEnterpriseIdentifierByProjectId" resultType="java.lang.String">
select pe.enterprise_identifier
from pms_project pp
left join pms_enterprise pe on pe.id = pp.pms_enterprise_id
where pp.id = #{pmProjectId}
</select>
<insert id="insertPmsProject" parameterType="PmsProject" useGeneratedKeys="true" keyProperty="id">
insert into pms_project

View File

@ -221,19 +221,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
WHERE pms_project_id = #{pmProjectId} AND status = 2
) AS `closed_sprint_count`
</select>
<select id="selectNewSprintCurrentNaturalWeekCount" resultType="java.lang.Integer">
select count(*)
from pms_project_sprint
where pms_project_id = #{projectId}
AND create_time <![CDATA[ >= ]]> STR_TO_DATE(DATE_FORMAT(NOW(), '%Y-%V-1'), '%Y-%U-%w')
AND create_time <![CDATA[ <= ]]> STR_TO_DATE(DATE_FORMAT(NOW(), '%Y-%V-1'), '%Y-%U-%w') + INTERVAL 6 DAY
</select>
<select id="selectCompleteSprintCurrentNaturalWeekCount" resultType="java.lang.Integer">
select count(*)
from pms_project_sprint
where pms_project_id = #{projectId}
AND status = 2
AND update_time <![CDATA[ >= ]]> STR_TO_DATE(DATE_FORMAT(NOW(), '%Y-%V-1'), '%Y-%U-%w')
AND update_time <![CDATA[ <= ]]> STR_TO_DATE(DATE_FORMAT(NOW(), '%Y-%V-1'), '%Y-%U-%w') + INTERVAL 6 DAY
</select>
</mapper>

View File

@ -21,11 +21,13 @@
<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="testTracking" column="test_track"/>
<result property="productReqSpecsId" column="product_req_specs_id"/>
<result property="isImport" column="is_import"/>
</resultMap>
<sql id="selectPmsProjectTestcaseVo">
@ -45,9 +47,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,11 +129,13 @@
<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="testTracking != null">test_tracking,</if>
<if test="productReqSpecsId != null">product_req_specs_id,</if>
<if test="isImport != null">is_import,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="title != null and title != ''">#{title},</if>
@ -149,11 +153,13 @@
<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="testTracking != null">#{testTracking},</if>
<if test="productReqSpecsId != null">#{productReqSpecsId},</if>
<if test="isImport != null">#{isImport},</if>
</trim>
</insert>
@ -175,11 +181,13 @@
<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>
<if test="testTracking != null">#{testTracking},</if>
<if test="productReqSpecsId != null">#{productReqSpecsId},</if>
<if test="isImport != null">#{isImport},</if>
</trim>
where id = #{id}
</update>
@ -296,4 +304,28 @@
#{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"/>
<result property="testTracking" column="test_tracking"/>
</resultMap>
<select id="getTestcase" resultMap="PmsProjectTestcaseVo">
SELECT * FROM pms_project_testcase WHERE pms_project_id = #{project_id}
</select>
</mapper>

View File

@ -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">

View File

@ -53,21 +53,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="selectCountBySprintId" resultType="java.lang.Integer">
select count(*) from pms_project_testsheet where project_sprint_id = #{sprintId}
</select>
<select id="selectNewTestSheetCurrentNaturalWeekCount" resultType="java.lang.Integer">
select count(*)
from pms_project_testsheet
where pms_project_id = #{projectId}
AND create_time <![CDATA[ >= ]]> STR_TO_DATE(DATE_FORMAT(NOW(), '%Y-%V-1'), '%Y-%U-%w')
AND create_time <![CDATA[ <= ]]> STR_TO_DATE(DATE_FORMAT(NOW(), '%Y-%V-1'), '%Y-%U-%w') + INTERVAL 6 DAY
</select>
<select id="selectCompleteTestSheetCurrentNaturalWeekCount" resultType="java.lang.Integer">
select count(*)
from pms_project_testsheet
where pms_project_id = #{projectId}
AND status = 2
AND update_time <![CDATA[ >= ]]> STR_TO_DATE(DATE_FORMAT(NOW(), '%Y-%V-1'), '%Y-%U-%w')
AND update_time <![CDATA[ <= ]]> STR_TO_DATE(DATE_FORMAT(NOW(), '%Y-%V-1'), '%Y-%U-%w') + INTERVAL 6 DAY
</select>
<insert id="insertPmsProjectTestsheet" parameterType="PmsProjectTestsheet" useGeneratedKeys="true" keyProperty="id">
insert into pms_project_testsheet

View File

@ -1,4 +1,4 @@
package com.microservices.wiki.controller.sys;
package com.microservices.wiki.contoller.sys;
import com.microservices.common.core.web.domain.AjaxResult;

View File

@ -1,11 +1,13 @@
package com.microservices.wiki.controller.wiki;
package com.microservices.wiki.contoller.wiki;
import com.microservices.common.core.constant.HttpStatus;
import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.web.domain.AjaxResult;
import com.microservices.wiki.domain.sys.User;
import com.microservices.wiki.domain.wiki.Wiki;
import com.microservices.wiki.domain.wiki.vo.*;
import com.microservices.wiki.domain.wiki.vo.WikiAllVo;
import com.microservices.wiki.domain.wiki.vo.WikiContent;
import com.microservices.wiki.domain.wiki.vo.WikiDeleteVo;
import com.microservices.wiki.domain.wiki.vo.WikiPageVo;
import com.microservices.wiki.refactoring.response.HttpClientResult;
import com.microservices.wiki.refactoring.utils.BeanCopyUtils;
import com.microservices.wiki.refactoring.utils.FastJsonUtils;
@ -34,9 +36,6 @@ public class WikiController {
@Value("${gitea-wiki-api-base-url}")
private String giteaApiBaseUrl;
@Value("${gitea-hat-wiki-api-base-url}")
private String giteaHatApiBaseUrl;
@Value("${gitea-wiki-token}")
private String token;
@ -139,44 +138,6 @@ public class WikiController {
return new AjaxResult(httpClientResult.getCode(), "", httpClientResult.getContent());
}
@ApiOperation("getWikiRevisions")
@GetMapping("/getWikiRevisions")
public AjaxResult getWikiRevisions(
HttpServletRequest request,
@ApiParam(value = "owner of the repo", required = true) @RequestParam(defaultValue = "") String owner,
@ApiParam(value = "name of the repo", required = true) @RequestParam(defaultValue = "") String repo,
@ApiParam(value = "name of the wikipage", required = true) @RequestParam(defaultValue = "") String pageName,
@ApiParam(value = "id of the project", required = true) @RequestParam(defaultValue = "") Integer projectId) throws Exception {
String giteaToken = wikiService.getGiteaToken(request, projectId);
//未获取有效giteaToken时赋值内置giteaToken
giteaToken = giteaToken == null ? token : giteaToken;
WikiRevisionsVo wikiRevisionsVo = wikiService.getWikiRevisions(owner, repo, pageName, giteaApiDomain+giteaApiBaseUrl, giteaToken);
return new AjaxResult(HttpStatus.SUCCESS,"操作成功", wikiRevisionsVo);
}
@ApiOperation("getPreviousWiki")
@GetMapping("/getPreviousWiki")
public AjaxResult getPreviousWiki(
HttpServletRequest request,
@ApiParam(value = "owner of the repo", required = true) @RequestParam(defaultValue = "") String owner,
@ApiParam(value = "name of the repo", required = true) @RequestParam(defaultValue = "") String repo,
@ApiParam(value = "name of the wikipage", required = true) @RequestParam(defaultValue = "") String pageName,
@ApiParam(value = "id of the project", required = true) @RequestParam(defaultValue = "") Integer projectId,
@ApiParam(value = "sha of the project", required = true) @RequestParam(defaultValue = "") String sha) throws Exception {
String giteaToken = wikiService.getGiteaToken(request, projectId);
//未获取有效giteaToken时赋值内置giteaToken
giteaToken = giteaToken == null ? token : giteaToken;
HttpClientResult httpClientResult = wikiService.getPreviousWiki(owner, repo, pageName, sha, giteaApiDomain+giteaHatApiBaseUrl, giteaToken);
if (httpClientResult == null) {
throw new ServiceException("获取wiki历史版本数据异常");
}
if (httpClientResult.getCode() != 200) {
return new AjaxResult(httpClientResult.getCode(),"操作失败", httpClientResult.getContent());
}
WikiContent wikiContent = getWikiContent(httpClientResult);
return new AjaxResult(httpClientResult.getCode(), "操作成功", wikiContent);
}
@ -189,10 +150,7 @@ public class WikiController {
WikiContent wikiContent = FastJsonUtils.toBean(httpClientResult.getContent(), WikiContent.class);
if (wikiContent != null && wikiContent.getLast_commit() != null
&& wikiContent.getLast_commit().getAuthor() != null) {
String image_url = userService.getRemoteUserLogoByUserLogin(wikiContent.getLast_commit().getCommiter().getName());
wikiContent.setImage_url(image_url);
wikiContent.getLast_commit().getCommiter().setImage_url(image_url);
wikiContent.getLast_commit().getAuthor().setImage_url(image_url);
wikiContent.setImage_url(userService.getRemoteUserLogoByUserLogin(wikiContent.getLast_commit().getAuthor().getName()));
User commitUser = userService.getUserByLogin(wikiContent.getLast_commit().getAuthor().getName());
if(commitUser != null){
wikiContent.setUserName(StringUtils.isEmpty(commitUser.getNickname()) ? commitUser.getLogin() : commitUser.getNickname());

View File

@ -1,4 +1,4 @@
package com.microservices.wiki.controller.wiki;
package com.microservices.wiki.contoller.wiki;
import com.microservices.common.core.exception.ServiceException;

View File

@ -12,6 +12,4 @@ public class AuthorMessage {
private Date date;
private String email;
private String image_url;
}

View File

@ -9,6 +9,4 @@ public class CommitMessage {
private String message;
private AuthorMessage author;
private AuthorMessage commiter;
}

View File

@ -1,12 +0,0 @@
package com.microservices.wiki.domain.wiki.vo;
import lombok.Data;
import java.util.List;
@Data
public class WikiRevisionsVo {
private List<CommitMessage> commits;
private Integer count;
}

View File

@ -1,22 +1,18 @@
package com.microservices.wiki.service.wiki;
import cn.hutool.core.util.ZipUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.github.jhonnymertz.wkhtmltopdf.wrapper.Pdf;
import com.github.jhonnymertz.wkhtmltopdf.wrapper.configurations.WrapperConfig;
import com.github.jhonnymertz.wkhtmltopdf.wrapper.params.Param;
import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.web.domain.AjaxResult;
import com.microservices.wiki.domain.projects.Projects;
import com.microservices.wiki.domain.sys.User;
import com.microservices.wiki.domain.sys.UserVo;
import com.microservices.wiki.domain.wiki.Wiki;
import com.microservices.wiki.domain.wiki.WikiContentSimple;
import com.microservices.wiki.domain.wiki.WikiPage;
import com.microservices.wiki.domain.wiki.vo.WikiCloneLinkVo;
import com.microservices.wiki.domain.wiki.vo.WikiPageVo;
import com.microservices.wiki.domain.wiki.vo.WikiRevisionsVo;
import com.microservices.wiki.domain.wiki.vo.WikiVo;
import com.microservices.wiki.mapper.members.MembersMapper;
import com.microservices.wiki.mapper.projects.ProjectsMapper;
@ -24,7 +20,6 @@ import com.microservices.wiki.mapper.team_projects.TeamProjectsMapper;
import com.microservices.wiki.refactoring.response.HttpClientResult;
import com.microservices.wiki.refactoring.utils.*;
import com.microservices.wiki.service.sys.UserService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -87,9 +82,9 @@ public class WikiService {
urlFormat += "?access_token=" + giteaToken;
}
String completeUrl = giteaApiDomain + urlFormat;
logger.info("getWikiPages completeUrl:{}", completeUrl);
logger.info("completeUrl:" + completeUrl);
HttpClientResult httpClientResult = HttpClientUtils.doGet(completeUrl, null);
logger.info("httpClientResultCode:{}", httpClientResult.getCode());
logger.info("httpClientResultCode:" + httpClientResult.getCode());
return httpClientResult;
}
@ -111,7 +106,7 @@ public class WikiService {
urlFormat += "?access_token=" + giteaToken;
}
String completeUrl = URL + urlFormat;
logger.info("getWiki completeUrl: {}", completeUrl);
logger.info("completeUrl: " + completeUrl);
return HttpClientUtils.doGet(completeUrl, null, null);
}
@ -122,7 +117,7 @@ public class WikiService {
Map<String, String> params;
WikiVo wikiVo = BeanCopyUtils.beanPropertiesCopy(wiki, WikiVo.class);
params = ConvertBean.convertToStringMap(wikiVo);
logger.info("completeUrl: {}{}", URL, urlFormat);
logger.info("completeUrl: " + URL + urlFormat);
String completeUrl = URL + urlFormat;
return HttpClientUtils.doPost(completeUrl, null, params);
}
@ -134,7 +129,7 @@ public class WikiService {
String pageName = wiki.getTitle();
String urlFormat = String.format("/repos/%s/%s/wiki/page/%s?access_token=%s", owner, repo, pageName, giteaToken);
String completeUrl = URL + urlFormat;
logger.info("delete completeUrl {}", completeUrl);
logger.info("delete completeUrl " + completeUrl);
return HttpClientUtils.doDelete(completeUrl);
}
@ -145,52 +140,10 @@ public class WikiService {
String urlFormat = String.format("/repos/%s/%s/wiki/page/%s?access_token=%s", owner, repo, pageName, giteaToken);
WikiVo wikiVo = BeanCopyUtils.beanPropertiesCopy(wiki, WikiVo.class);
String completeUrl = URL + urlFormat;
logger.info("completeUrl: {}", completeUrl);
logger.info("completeUrl: " + completeUrl);
return HttpClientUtils.doPatch(completeUrl, ConvertBean.convertToStringMap(wikiVo));
}
public WikiRevisionsVo getWikiRevisions(String owner, String repo, String pageName, String URL, String giteaToken) throws Exception {
String urlFormat = String.format("/repos/%s/%s/wiki/revisions/%s", owner, repo, pageName);
if (giteaToken != null) {
urlFormat += "?access_token=" + giteaToken;
}
String completeUrl = URL + urlFormat;
logger.info("getWikiRevisions completeUrl: {}", completeUrl);
HttpClientResult httpClientResult = HttpClientUtils.doGet(completeUrl, null, null);
if (httpClientResult == null) {
throw new ServiceException("获取wiki历史版本列表数据异常");
}
if (httpClientResult.getCode() != 200) {
throw new ServiceException(httpClientResult.getCode(),"操作失败", httpClientResult.getContent());
}
WikiRevisionsVo wikiRevisionsVo = JSON.parseObject(httpClientResult.getContent(), WikiRevisionsVo.class);
wikiRevisionsVo.getCommits().forEach(commit -> {
commit.getCommiter().setImage_url(userService.getRemoteUserLogoByUserLogin(commit.getCommiter().getName()));
User commitUser = userService.getUserByLogin(commit.getCommiter().getName());
if(commitUser != null){
commit.getCommiter().setName(StringUtils.isEmpty(commitUser.getNickname()) ? commitUser.getLogin() : commitUser.getNickname());
}
commit.getAuthor().setImage_url(userService.getRemoteUserLogoByUserLogin(commit.getAuthor().getName()));
User authorUser = userService.getUserByLogin(commit.getAuthor().getName());
if(authorUser != null){
commit.getAuthor().setName(StringUtils.isEmpty(authorUser.getNickname()) ? authorUser.getLogin() : authorUser.getNickname());
}
});
return wikiRevisionsVo;
}
public HttpClientResult getPreviousWiki(String owner, String repo, String pageName, String sha, String URL, String giteaToken) throws Exception {
String urlFormat = String.format("/repos/%s/%s/wiki/revisions/%s/%s", owner, repo, pageName, sha);
if (giteaToken != null) {
urlFormat += "?access_token=" + giteaToken;
}
String completeUrl = URL + urlFormat;
logger.info("getPreviousWiki completeUrl: {}", completeUrl);
return HttpClientUtils.doGet(completeUrl, null, null);
}
public String StringToURLEncode(String s) throws UnsupportedEncodingException {
s = java.net.URLEncoder.encode(s, "UTF-8").replaceAll("\\+", "-").replaceAll("\\*", "%2A");
@ -271,7 +224,7 @@ public class WikiService {
if (httpClientResult1.getCode() == 200) {
WikiContentSimple wikiContentSimple = FastJsonUtils.toBean(httpClientResult1.getContent(), WikiContentSimple.class);
fileUtils.writeStringToFile(wikiContentSimple.getContent_base64(), wikiContentSimple.getTitle() + ".md", dirPath);
logger.info("wikiContent:{}", wikiContentSimple.getSimple_content());
logger.info("wikiContent" + wikiContentSimple.getSimple_content());
}
}
downLoadZip(response, repoName, dirPath);
@ -356,7 +309,7 @@ public class WikiService {
org.apache.commons.io.FileUtils.forceDelete(new File(completeDestPath));
org.apache.commons.io.FileUtils.forceDelete(new File(dirPath));
} catch (IOException e) {
logger.warn("delete scratch zip file fail: {}", completeDestPath);
logger.warn("delete scratch zip file fail: " + completeDestPath);
}
}
@ -379,7 +332,7 @@ public class WikiService {
try {
org.apache.commons.io.FileUtils.forceDelete(new File(filePath));
} catch (IOException e) {
logger.warn("delete scratch file fail: {}", filePath);
logger.warn("delete scratch file fail: " + filePath);
}
}
}