refactor(工作台): 优化待办缺陷列表

This commit is contained in:
song-cc-rock 2024-11-13 11:07:47 +08:00 committed by Craftsman
parent 9205f028fd
commit ab426e9853
8 changed files with 184 additions and 22 deletions

View File

@ -69,7 +69,7 @@ public interface Platform extends ExtensionPoint {
List<SelectOption> getFormOptions(GetOptionRequest optionsRequest); List<SelectOption> getFormOptions(GetOptionRequest optionsRequest);
/** /**
* 获取第三方平台缺陷状态选项 * 获取第三方平台缺陷状态选项
* @param projectConfig 项目配置信息 * @param projectConfig 项目配置信息
* @param issueKey 缺陷ID * @param issueKey 缺陷ID
* @param previousStatus 当前状态 * @param previousStatus 当前状态
@ -78,6 +78,14 @@ public interface Platform extends ExtensionPoint {
*/ */
List<SelectOption> getStatusTransitions(String projectConfig, String issueKey, String previousStatus) throws Exception; List<SelectOption> getStatusTransitions(String projectConfig, String issueKey, String previousStatus) throws Exception;
/**
* 获取第三方平台缺陷状态流结束状态选项 (用于工作台过滤展示, 不实现则默认都展示第三方平台所有状态)
* @param projectConfig 项目配置信息(暂定, 可能其他平台后续需提供服务集成配置信息)
* @return 平台结束状态流选项
* @throws Exception 获取平台结束状态异常
*/
List<SelectOption> getStatusTransitionsLastSteps(String projectConfig) throws Exception;
/** /**
* 获取第三方平台关联需求列表 * 获取第三方平台关联需求列表
* @param request 需求分页查询参数 * @param request 需求分页查询参数

View File

@ -17,12 +17,9 @@ public class BugPageRequest extends BasePageRequest {
@NotBlank(message = "{bug.project_id.not_blank}") @NotBlank(message = "{bug.project_id.not_blank}")
private String projectId; private String projectId;
@Schema(description = "是否回收站") @Schema(description = "是否回收站, 后台默认设置")
private boolean useTrash; private boolean useTrash;
@Schema(description = "是否我的待办, 默认查询全部") @Schema(description = "待办参数, 后台默认设置")
private boolean myTodo = false; private BugTodoRequest todoParam;
@Schema(description = "我的待办用户ID, 组合使用: myTodo=true, myTodoUserId=xxx")
private String myTodoUserId;
} }

View File

@ -0,0 +1,31 @@
package io.metersphere.bug.dto.request;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Data;
import java.util.List;
/**
* @author song-cc-rock
* 缺陷待办参数
*/
@Data
@Builder
public class BugTodoRequest {
@Schema(description = "当前用户ID")
private String msUserId;
@Schema(description = "Local状态结束标识集合")
private List<String> msLastStepStatus;
@Schema(description = "当前对接平台; 非Local时需要")
private String currentPlatform;
@Schema(description = "当前对接平台用户ID")
private String platformUser;
@Schema(description = "对接平台状态结束标识集合")
private List<String> platformLastStatus;
}

View File

@ -28,6 +28,13 @@ public interface ExtBugMapper {
@BaseConditionFilter @BaseConditionFilter
List<BugDTO> list(@Param("request") BugPageRequest request, @Param("sort") String sort); List<BugDTO> list(@Param("request") BugPageRequest request, @Param("sort") String sort);
/**
* 获取项目状态流结束标识
* @param projectId 项目ID
* @return 结束标识集合
*/
List<String> getLocalLastStepStatusIds(@Param("projectId") String projectId);
/** /**
* 缺陷列表查询 * 缺陷列表查询
* *

View File

@ -23,6 +23,11 @@
</if> </if>
</select> </select>
<select id="getLocalLastStepStatusIds" resultType="java.lang.String">
select id from status_item si left join status_definition sd on si.id = sd.status_id
where scope_type = 'PROJECT' and scope_id = #{projectId} and sd.definition_id = 'END'
</select>
<select id="getIdsByPageRequest" resultType="java.lang.String"> <select id="getIdsByPageRequest" resultType="java.lang.String">
select b.id from bug b left join bug_content bc on b.id = bc.bug_id select b.id from bug b left join bug_content bc on b.id = bc.bug_id
<include refid="queryWhereCondition"/> <include refid="queryWhereCondition"/>
@ -157,13 +162,37 @@
or b.tags like concat('%', #{request.keyword},'%') or b.tags like concat('%', #{request.keyword},'%')
) )
</if> </if>
<!-- 我的待办: Local平台&&非结束状态&&处理人为我; --> <!-- 我的待办 -->
<if test="request.myTodo"> <if test="request.todoParam != null">
and b.platform = 'Local' and b.status in ( and (
select id from status_item si left join status_definition sd on si.id = sd.status_id <!-- Local平台: 非结束状态&&处理人为当前登录用户 -->
where scope_type = 'PROJECT' and scope_id = #{request.projectId} (
and (sd.definition_id != 'END' || sd.definition_id is null) b.platform = 'Local'
) and b.handle_user = #{request.myTodoUserId} <if test="request.todoParam.msLastStepStatus != null and request.todoParam.msLastStepStatus.size() > 0">
and b.status not in
<foreach collection="request.todoParam.msLastStepStatus" item="lastStatus" separator="," open="(" close=")">
#{lastStatus}
</foreach>
</if>
and b.handle_user = #{request.todoParam.msUserId}
)
<if test="request.todoParam.currentPlatform != null and request.todoParam.currentPlatform != 'Local'">
<!-- 插件平台: 非平台结束状态&&处理人为个人中心账号配置 -->
or
(
b.platform = #{request.todoParam.currentPlatform}
<if test="request.todoParam.platformLastStatus != null and request.todoParam.platformLastStatus.size() > 0">
and b.status not in
<foreach collection="request.todoParam.platformLastStatus" item="lastStatus" separator="," open="(" close=")">
#{lastStatus}
</foreach>
</if>
<if test="request.todoParam.platformUser != null">
and b.handle_user = #{request.todoParam.platformUser}
</if>
)
</if>
)
</if> </if>
<include refid="filter"/> <include refid="filter"/>
<include refid="combine"> <include refid="combine">

View File

@ -43,6 +43,8 @@ public class BugCommonService {
@Resource @Resource
private FileService fileService; private FileService fileService;
@Resource @Resource
private ExtBugMapper extBugMapper;
@Resource
private BugStatusService bugStatusService; private BugStatusService bugStatusService;
@Resource @Resource
private BugCommentMapper bugCommentMapper; private BugCommentMapper bugCommentMapper;
@ -189,4 +191,24 @@ public class BugCommonService {
List<SelectOption> allStatusOption = ListUtils.union(headerOptions, localOptions).stream().distinct().toList(); List<SelectOption> allStatusOption = ListUtils.union(headerOptions, localOptions).stream().distinct().toList();
return allStatusOption.stream().collect(Collectors.toMap(SelectOption::getValue, SelectOption::getText)); return allStatusOption.stream().collect(Collectors.toMap(SelectOption::getValue, SelectOption::getText));
} }
/**
* 获取Local状态流结束标识
* @param projectId 项目ID
* @return 状态流结束标识集合
*/
public List<String> getLocalLastStepStatus(String projectId) {
return extBugMapper.getLocalLastStepStatusIds(projectId);
}
/**
* 获取平台状态流结束标识
* @param projectId 项目ID
* @return 状态流结束标识集合
*/
public List<String> getPlatformLastStepStatus(String projectId) throws Exception {
Platform platform = projectApplicationService.getPlatform(projectId, true);
List<SelectOption> platformLastSteps = platform.getStatusTransitionsLastSteps(projectApplicationService.getProjectBugThirdPartConfig(projectId));
return platformLastSteps.stream().map(SelectOption::getValue).toList();
}
} }

View File

@ -3,19 +3,31 @@ package io.metersphere.dashboard.controller;
import com.github.pagehelper.Page; import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import io.metersphere.bug.dto.request.BugPageRequest; import io.metersphere.bug.dto.request.BugPageRequest;
import io.metersphere.bug.dto.request.BugTodoRequest;
import io.metersphere.bug.dto.response.BugDTO; import io.metersphere.bug.dto.response.BugDTO;
import io.metersphere.bug.enums.BugPlatform;
import io.metersphere.bug.service.BugCommonService;
import io.metersphere.bug.service.BugService; import io.metersphere.bug.service.BugService;
import io.metersphere.functional.dto.CaseReviewDTO; import io.metersphere.functional.dto.CaseReviewDTO;
import io.metersphere.functional.request.CaseReviewPageRequest; import io.metersphere.functional.request.CaseReviewPageRequest;
import io.metersphere.functional.service.CaseReviewService; import io.metersphere.functional.service.CaseReviewService;
import io.metersphere.plan.dto.request.TestPlanTableRequest; import io.metersphere.plan.dto.request.TestPlanTableRequest;
import io.metersphere.plan.dto.response.TestPlanResponse; import io.metersphere.plan.dto.response.TestPlanResponse;
import io.metersphere.plan.dto.response.TestPlanStatisticsResponse;
import io.metersphere.plan.service.TestPlanManagementService; import io.metersphere.plan.service.TestPlanManagementService;
import io.metersphere.plan.service.TestPlanStatisticsService;
import io.metersphere.plugin.platform.dto.SelectOption;
import io.metersphere.project.service.ProjectApplicationService;
import io.metersphere.sdk.util.LogUtils;
import io.metersphere.system.domain.ServiceIntegration;
import io.metersphere.system.security.CheckOwner; import io.metersphere.system.security.CheckOwner;
import io.metersphere.system.service.UserPlatformAccountService;
import io.metersphere.system.utils.PageUtils; import io.metersphere.system.utils.PageUtils;
import io.metersphere.system.utils.Pager; import io.metersphere.system.utils.Pager;
import io.metersphere.system.utils.SessionUtils; import io.metersphere.system.utils.SessionUtils;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -36,12 +48,20 @@ import java.util.List;
@RequestMapping("/dashboard/todo") @RequestMapping("/dashboard/todo")
public class ToDoController { public class ToDoController {
@Resource
private CaseReviewService caseReviewService;
@Resource @Resource
private BugService bugService; private BugService bugService;
@Resource @Resource
private BugCommonService bugCommonService;
@Resource
private CaseReviewService caseReviewService;
@Resource
private TestPlanManagementService testPlanManagementService; private TestPlanManagementService testPlanManagementService;
@Resource
private ProjectApplicationService projectApplicationService;
@Resource
private UserPlatformAccountService userPlatformAccountService;
@Resource
private TestPlanStatisticsService testPlanStatisticsService;
@PostMapping("/plan/page") @PostMapping("/plan/page")
@Operation(summary = "我的待办-测试计划-列表分页查询") @Operation(summary = "我的待办-测试计划-列表分页查询")
@ -52,14 +72,21 @@ public class ToDoController {
return testPlanManagementService.page(request); return testPlanManagementService.page(request);
} }
@PostMapping("/plan/statistics")
@Operation(summary = "我的待办-测试计划-获取列表详情统计 {通过率, 执行进度}")
@Parameter(name = "ids", description = "计划ID集合", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED))
public List<TestPlanStatisticsResponse> selectTestPlanMetricById(@RequestBody List<String> ids) {
return testPlanStatisticsService.calculateRate(ids);
}
@PostMapping("/review/page") @PostMapping("/review/page")
@Operation(summary = "我的待办-用例评审-列表分页查询") @Operation(summary = "我的待办-用例评审-列表分页查询")
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project") @CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
public Pager<List<CaseReviewDTO>> reviewPage(@Validated @RequestBody CaseReviewPageRequest request) { public Pager<List<CaseReviewDTO>> reviewPage(@Validated @RequestBody CaseReviewPageRequest request) {
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "pos desc");
request.setMyTodo(true); request.setMyTodo(true);
request.setMyTodoUserId(SessionUtils.getUserId()); request.setMyTodoUserId(SessionUtils.getUserId());
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "pos desc");
return PageUtils.setPageInfo(page, caseReviewService.getCaseReviewPage(request)); return PageUtils.setPageInfo(page, caseReviewService.getCaseReviewPage(request));
} }
@ -67,11 +94,44 @@ public class ToDoController {
@Operation(summary = "我的待办-缺陷-列表分页查询") @Operation(summary = "我的待办-缺陷-列表分页查询")
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project") @CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
public Pager<List<BugDTO>> bugPage(@Validated @RequestBody BugPageRequest request) { public Pager<List<BugDTO>> bugPage(@Validated @RequestBody BugPageRequest request) {
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "pos desc");
request.setUseTrash(false); request.setUseTrash(false);
request.setMyTodo(true); request.setTodoParam(buildBugToDoParam(request, SessionUtils.getUserId(), SessionUtils.getCurrentOrganizationId()));
request.setMyTodoUserId(SessionUtils.getUserId()); Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "b.pos desc");
return PageUtils.setPageInfo(page, bugService.list(request)); return PageUtils.setPageInfo(page, bugService.list(request));
} }
/**
* 设置缺陷待办参数
* @param request 请求参数
* @param currentUserId 当前用户ID
* @param currentOrgId 当前组织ID
* @return 待办参数
*/
private BugTodoRequest buildBugToDoParam(BugPageRequest request, String currentUserId, String currentOrgId) {
List<String> msLastStepStatusIds = bugCommonService.getLocalLastStepStatus(request.getProjectId());
BugTodoRequest todoParam = BugTodoRequest.builder().msUserId(currentUserId).msLastStepStatus(msLastStepStatusIds).build();
try {
// 设置待办的平台参数
String platformName = projectApplicationService.getPlatformName(request.getProjectId());
if (StringUtils.equals(platformName, BugPlatform.LOCAL.getName())) {
return todoParam;
}
todoParam.setCurrentPlatform(platformName);
List<String> platformLastStepStatus = bugCommonService.getPlatformLastStepStatus(request.getProjectId());
todoParam.setPlatformLastStatus(platformLastStepStatus);
ServiceIntegration serviceIntegration = projectApplicationService.getPlatformServiceIntegrationWithSyncOrDemand(request.getProjectId(), true);
String platformUserName = userPlatformAccountService.getPlatformUserName(currentUserId, currentOrgId, serviceIntegration.getPluginId());
List<SelectOption> headerHandlerOption = bugCommonService.getHeaderHandlerOption(request.getProjectId());
if (StringUtils.isNotBlank(platformUserName)) {
headerHandlerOption.stream().filter(option -> StringUtils.containsAnyIgnoreCase(option.getText(), platformUserName))
.findFirst().ifPresent(option -> todoParam.setPlatformUser(option.getValue()));
}
} catch (Exception e) {
// 设置平台参数异常时, 无法正常过滤平台非结束的缺陷
LogUtils.error(e.getMessage());
return todoParam;
}
return todoParam;
}
} }

View File

@ -132,4 +132,12 @@ public class UserPlatformAccountService {
// noinspection unchecked // noinspection unchecked
return (Map<String, Object>) userPlatformInfo.get(pluginId); return (Map<String, Object>) userPlatformInfo.get(pluginId);
} }
public String getPlatformUserName(String uerId, String orgId, String pluginId) {
Map<String, Object> pluginUserPlatformConfig = getPluginUserPlatformConfig(pluginId, orgId, uerId);
if (pluginUserPlatformConfig == null) {
return null;
}
return (String) pluginUserPlatformConfig.get("nickName");
}
} }