refactor(项目设置): 重构更新状态定义和状态流接口

This commit is contained in:
AgAngle 2023-11-02 10:28:50 +08:00 committed by jianxing
parent 03109b9bff
commit b2924b1a58
20 changed files with 492 additions and 427 deletions

View File

@ -1,24 +1,36 @@
package io.metersphere.sdk.constants; package io.metersphere.sdk.constants;
import io.metersphere.sdk.util.Translator; import lombok.Getter;
import java.util.Arrays;
@Getter
public enum BugStatusDefinitionType { public enum BugStatusDefinitionType {
/** /**
* 起始状态 * 起始状态
*/ */
START("status_definition.type.start"), START("status_definition.type.start", true),
/** /**
* 结束状态 * 结束状态
*/ */
END("status_definition.type.end"); END("status_definition.type.end", false);
BugStatusDefinitionType(String name) { BugStatusDefinitionType(String name, Boolean isSingleChoice) {
this.name = name; this.name = name;
this.isSingleChoice = isSingleChoice;
} }
/**
* 状态名
*/
private String name; private String name;
/**
* 是否是单选
*/
private Boolean isSingleChoice;
public String getName() { public static BugStatusDefinitionType getStatusDefinitionType(String type) {
return Translator.get(name); return Arrays.stream(BugStatusDefinitionType.values()).filter(item -> item.name().equals(type))
.findFirst().orElse(null);
} }
} }

View File

@ -407,6 +407,7 @@ internal_custom_field_permission_error=系统字段或模板无法删除!
internal_template_permission_error=系统模板无法删除! internal_template_permission_error=系统模板无法删除!
default_template_permission_error=默认模板无法删除! default_template_permission_error=默认模板无法删除!
field_validate_error={0}字段参数值不合法 field_validate_error={0}字段参数值不合法
status_definition_required_error=该状态无法取消
#result message #result message
http_result_success=操作成功 http_result_success=操作成功

View File

@ -410,6 +410,7 @@ internal_custom_field_permission_error=System fields cannot be deleted
internal_template_permission_error=System template cannot be deleted internal_template_permission_error=System template cannot be deleted
default_template_permission_error=Default templates cannot be deleted default_template_permission_error=Default templates cannot be deleted
field_validate_error=The field {0} value is invalid field_validate_error=The field {0} value is invalid
status_definition_required_error=This status cannot be canceled
#result message #result message
http_result_success=operate success http_result_success=operate success

View File

@ -407,6 +407,7 @@ internal_custom_field_permission_error=系统字段或模板无法删除!
internal_template_permission_error=系统模板无法删除! internal_template_permission_error=系统模板无法删除!
default_template_permission_error=默认模板无法删除! default_template_permission_error=默认模板无法删除!
field_validate_error={0}字段参数值不合法 field_validate_error={0}字段参数值不合法
status_definition_required_error=该状态无法取消
#result message #result message
http_result_success=操作成功 http_result_success=操作成功

View File

@ -406,6 +406,7 @@ internal_custom_field_permission_error=系統字段或模板無法刪除!
internal_template_permission_error=系統模板無法刪除! internal_template_permission_error=系統模板無法刪除!
default_template_permission_error=默认模板无法删除! default_template_permission_error=默认模板无法删除!
field_validate_error={0}字段參數值不合法 field_validate_error={0}字段參數值不合法
status_definition_required_error=該狀態無法取消
#result message #result message
http_result_success=操作成功 http_result_success=操作成功

View File

@ -34,7 +34,8 @@ public class ProjectStatusFlowSettingLogService {
public LogDTO updateStatusDefinitionLog(StatusDefinitionUpdateRequest request) { public LogDTO updateStatusDefinitionLog(StatusDefinitionUpdateRequest request) {
return updateStatusFlowSettingLog(request.getScopeId(), request.getScene()); StatusItem statusItem = statusItemMapper.selectByPrimaryKey(request.getStatusId());
return updateStatusFlowSettingLog(statusItem.getScopeId(), statusItem.getScene());
} }
public LogDTO addStatusItemLog(StatusItemAddRequest request) { public LogDTO addStatusItemLog(StatusItemAddRequest request) {
@ -52,7 +53,8 @@ public class ProjectStatusFlowSettingLogService {
} }
public LogDTO updateStatusFlowLog(StatusFlowUpdateRequest request) { public LogDTO updateStatusFlowLog(StatusFlowUpdateRequest request) {
return updateStatusFlowSettingLog(request.getScopeId(), request.getScene()); StatusItem statusItem = statusItemMapper.selectByPrimaryKey(request.getFromId());
return updateStatusFlowSettingLog(statusItem.getScopeId(), statusItem.getScene());
} }
public LogDTO updateStatusFlowSettingLog(String scopeId, String scene) { public LogDTO updateStatusFlowSettingLog(String scopeId, String scene) {

View File

@ -43,11 +43,11 @@ public class ProjectStatusFlowSettingService extends BaseStatusFlowSettingServic
* 比如设置成项目 * 比如设置成项目
* @param request * @param request
*/ */
@Override
public void updateStatusDefinition(StatusDefinitionUpdateRequest request) { public void updateStatusDefinition(StatusDefinitionUpdateRequest request) {
ProjectService.checkResourceExist(request.getScopeId()); StatusItem statusItem = baseStatusItemService.getWithCheck(request.getStatusId());
projectTemplateService.checkProjectTemplateEnable(request.getScopeId(), request.getScene()); ProjectService.checkResourceExist(statusItem.getScopeId());
super.updateStatusDefinition(request); projectTemplateService.checkProjectTemplateEnable(statusItem.getScopeId(), statusItem.getScene());
super.updateStatusDefinition(statusItem, request);
} }
/** /**
@ -105,8 +105,11 @@ public class ProjectStatusFlowSettingService extends BaseStatusFlowSettingServic
* @param request * @param request
*/ */
public void updateStatusFlow(StatusFlowUpdateRequest request) { public void updateStatusFlow(StatusFlowUpdateRequest request) {
ProjectService.checkResourceExist(request.getScopeId()); StatusItem fromStatusItem = baseStatusItemService.getWithCheck(request.getFromId());
projectTemplateService.checkProjectTemplateEnable(request.getScopeId(), request.getScene()); StatusItem toStatusItem = baseStatusItemService.getWithCheck(request.getToId());
ProjectService.checkResourceExist(fromStatusItem.getScopeId());
ProjectService.checkResourceExist(toStatusItem.getScopeId());
projectTemplateService.checkProjectTemplateEnable(fromStatusItem.getScopeId(), fromStatusItem.getScene());
super.updateStatusFlow(request); super.updateStatusFlow(request);
} }

View File

@ -34,8 +34,7 @@ import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static io.metersphere.project.enums.result.ProjectResultCode.PROJECT_TEMPLATE_PERMISSION; import static io.metersphere.project.enums.result.ProjectResultCode.PROJECT_TEMPLATE_PERMISSION;
import static io.metersphere.system.controller.handler.result.CommonResultCode.STATUS_ITEM_EXIST; import static io.metersphere.system.controller.handler.result.CommonResultCode.*;
import static io.metersphere.system.controller.handler.result.CommonResultCode.STATUS_ITEM_NOT_EXIST;
import static io.metersphere.system.controller.handler.result.MsHttpResultCode.NOT_FOUND; import static io.metersphere.system.controller.handler.result.MsHttpResultCode.NOT_FOUND;
import static io.metersphere.system.controller.result.SystemResultCode.ORGANIZATION_TEMPLATE_PERMISSION; import static io.metersphere.system.controller.result.SystemResultCode.ORGANIZATION_TEMPLATE_PERMISSION;
@ -58,6 +57,7 @@ public class ProjectStatusFlowSettingControllerTest extends BaseTest {
private static final String STATUS_FLOW_UPDATE = "status/flow/update"; private static final String STATUS_FLOW_UPDATE = "status/flow/update";
private static StatusItem addStatusItem; private static StatusItem addStatusItem;
private static StatusItem anotherAddStatusItem;
@Resource @Resource
private StatusItemMapper statusItemMapper; private StatusItemMapper statusItemMapper;
@ -124,7 +124,8 @@ public class ProjectStatusFlowSettingControllerTest extends BaseTest {
request.setName("test3"); request.setName("test3");
request.setAllTransferTo(true); request.setAllTransferTo(true);
mvcResult = this.requestPostWithOkAndReturn(STATUS_ADD, request); mvcResult = this.requestPostWithOkAndReturn(STATUS_ADD, request);
statusItemId = getResultData(mvcResult, StatusItem.class).getId(); anotherAddStatusItem = getResultData(mvcResult, StatusItem.class);
statusItemId = anotherAddStatusItem.getId();
OrganizationStatusFlowSettingControllerTest.assertAllTransferTo(statusItemId, request.getScopeId()); OrganizationStatusFlowSettingControllerTest.assertAllTransferTo(statusItemId, request.getScopeId());
// @@校验组织是否存在 // @@校验组织是否存在
@ -178,21 +179,41 @@ public class ProjectStatusFlowSettingControllerTest extends BaseTest {
requestPostPermissionTest(PermissionConstants.PROJECT_TEMPLATE_UPDATE, STATUS_UPDATE, request); requestPostPermissionTest(PermissionConstants.PROJECT_TEMPLATE_UPDATE, STATUS_UPDATE, request);
} }
@Test @Test
@Order(3) @Order(3)
public void updateStatusDefinition() throws Exception { public void updateStatusDefinition() throws Exception {
StatusDefinitionUpdateRequest request = new StatusDefinitionUpdateRequest(); StatusDefinitionUpdateRequest request = new StatusDefinitionUpdateRequest();
request.setScene(TemplateScene.BUG.name()); request.setStatusId(addStatusItem.getId());
request.setScopeId(DEFAULT_PROJECT_ID); request.setDefinitionId(BugStatusDefinitionType.END.name());
StatusDefinitionUpdateRequest.StatusDefinitionRequest statusDefinition = new StatusDefinitionUpdateRequest.StatusDefinitionRequest(); request.setEnable(true);
statusDefinition.setStatusId(addStatusItem.getId());
statusDefinition.setDefinitionId(BugStatusDefinitionType.END.name());
request.setStatusDefinitions(List.of(statusDefinition));
// @@校验请求成功 // @@校验请求成功
this.requestPostWithOkAndReturn(STATUS_DEFINITION_UPDATE, request); this.requestPostWithOkAndReturn(STATUS_DEFINITION_UPDATE, request);
assertUpdateStatusDefinition(DEFAULT_PROJECT_ID); OrganizationStatusFlowSettingControllerTest.assertUpdateStatusDefinition(request);
// 校验项目是否同步修改
OrganizationStatusFlowSettingControllerTest.assertRefUpdateStatusDefinition(request);
// 取消关联
request.setEnable(false);
this.requestPostWithOkAndReturn(STATUS_DEFINITION_UPDATE, request);
OrganizationStatusFlowSettingControllerTest.assertUpdateStatusDefinition(request);
// @测试单选
request.setStatusId(addStatusItem.getId());
request.setDefinitionId(BugStatusDefinitionType.START.name());
request.setEnable(true);
this.requestPostWithOkAndReturn(STATUS_DEFINITION_UPDATE, request);
OrganizationStatusFlowSettingControllerTest.assertUpdateStatusDefinition(request);
// 校验单选
OrganizationStatusFlowSettingControllerTest.assertSingleChoiceUpdateStatusDefinition(request);
// 校验单选禁止取消
request.setEnable(false);
assertErrorCode(this.requestPost(STATUS_DEFINITION_UPDATE, request), STATUS_DEFINITION_REQUIRED_ERROR);
// 设置回来避免其他地方校验出错
StatusItem newStatusItem = OrganizationStatusFlowSettingControllerTest.getNewStatusItem(addStatusItem.getScopeId());
request.setStatusId(newStatusItem.getId());
request.setEnable(true);
this.requestPostWithOkAndReturn(STATUS_DEFINITION_UPDATE, request);
// @校验是否开启组织模板 // @校验是否开启组织模板
changeOrgTemplateEnable(true); changeOrgTemplateEnable(true);
@ -200,11 +221,7 @@ public class ProjectStatusFlowSettingControllerTest extends BaseTest {
changeOrgTemplateEnable(false); changeOrgTemplateEnable(false);
// @@状态不存在 // @@状态不存在
request.getStatusDefinitions().get(0).setStatusId("1111"); request.setStatusId("1111");
assertErrorCode(this.requestPost(STATUS_DEFINITION_UPDATE, request), STATUS_ITEM_NOT_EXIST);
// @@校验组织是否存在
request.setScopeId("1111");
assertErrorCode(this.requestPost(STATUS_DEFINITION_UPDATE, request), NOT_FOUND); assertErrorCode(this.requestPost(STATUS_DEFINITION_UPDATE, request), NOT_FOUND);
// @@校验日志 // @@校验日志
@ -215,34 +232,27 @@ public class ProjectStatusFlowSettingControllerTest extends BaseTest {
requestPostPermissionTest(PermissionConstants.PROJECT_TEMPLATE_UPDATE, STATUS_DEFINITION_UPDATE, request); requestPostPermissionTest(PermissionConstants.PROJECT_TEMPLATE_UPDATE, STATUS_DEFINITION_UPDATE, request);
} }
private void assertUpdateStatusDefinition(String scopeId) {
List<String> statusIds = baseStatusItemService.getByScopeIdAndScene(scopeId, TemplateScene.BUG.name()).stream().map(StatusItem::getId).toList();
List<StatusDefinition> statusDefinitions = baseStatusDefinitionService.getStatusDefinitions(statusIds);
Assertions.assertEquals(statusDefinitions.size(), 1);
Assertions.assertEquals(statusDefinitions.get(0).getDefinitionId(), BugStatusDefinitionType.END.name());
}
@Test @Test
@Order(4) @Order(4)
public void updateStatusFlow() throws Exception { public void updateStatusFlow() throws Exception {
StatusFlowUpdateRequest request = new StatusFlowUpdateRequest(); StatusFlowUpdateRequest request = new StatusFlowUpdateRequest();
request.setScopeId(DEFAULT_PROJECT_ID); request.setFromId(anotherAddStatusItem.getId());
request.setScene(TemplateScene.BUG.name()); request.setToId(addStatusItem.getId());
StatusFlowUpdateRequest.StatusFlowRequest statusFlow = new StatusFlowUpdateRequest.StatusFlowRequest(); request.setEnable(true);
statusFlow.setFromId(addStatusItem.getId());
StatusItemExample example = new StatusItemExample();
example.createCriteria().andScopeIdEqualTo(DEFAULT_PROJECT_ID).andSceneEqualTo(TemplateScene.BUG.name());
StatusItem targetStatusItem = statusItemMapper.selectByExample(example).stream()
.filter(item -> !StringUtils.equals(addStatusItem.getId(), item.getId()))
.findFirst()
.get();
statusFlow.setToId(targetStatusItem.getId());
request.setStatusFlows(List.of(statusFlow));
// @@校验请求成功 // @@校验请求成功
this.requestPostWithOkAndReturn(STATUS_FLOW_UPDATE, request); this.requestPostWithOkAndReturn(STATUS_FLOW_UPDATE, request);
assertUpdateStatusFlow(DEFAULT_PROJECT_ID, statusFlow); OrganizationStatusFlowSettingControllerTest.assertUpdateStatusFlow(request);
// 校验项目是否同步修改
OrganizationStatusFlowSettingControllerTest.assertRefUpdateStatusFlow(request);
// @@校验取消
request.setEnable(false);
this.requestPostWithOkAndReturn(STATUS_FLOW_UPDATE, request);
OrganizationStatusFlowSettingControllerTest.assertUpdateStatusFlow(request);
// 校验项目是否同步修改
OrganizationStatusFlowSettingControllerTest.assertRefUpdateStatusFlow(request);
// @校验是否开启组织模板 // @校验是否开启组织模板
changeOrgTemplateEnable(true); changeOrgTemplateEnable(true);
@ -250,11 +260,7 @@ public class ProjectStatusFlowSettingControllerTest extends BaseTest {
changeOrgTemplateEnable(false); changeOrgTemplateEnable(false);
// @@状态不存在 // @@状态不存在
request.getStatusFlows().get(0).setToId("1111"); request.setToId("1111");
assertErrorCode(this.requestPost(STATUS_FLOW_UPDATE, request), STATUS_ITEM_NOT_EXIST);
// @@校验组织是否存在
request.setScopeId("1111");
assertErrorCode(this.requestPost(STATUS_FLOW_UPDATE, request), NOT_FOUND); assertErrorCode(this.requestPost(STATUS_FLOW_UPDATE, request), NOT_FOUND);
// @@校验日志 // @@校验日志
@ -265,15 +271,6 @@ public class ProjectStatusFlowSettingControllerTest extends BaseTest {
requestPostPermissionTest(PermissionConstants.PROJECT_TEMPLATE_UPDATE, STATUS_FLOW_UPDATE, request); requestPostPermissionTest(PermissionConstants.PROJECT_TEMPLATE_UPDATE, STATUS_FLOW_UPDATE, request);
} }
private void assertUpdateStatusFlow(String scopeId, StatusFlowUpdateRequest.StatusFlowRequest statusFlow) {
List<String> statusIds = baseStatusItemService.getByScopeIdAndScene(scopeId, TemplateScene.BUG.name()).stream()
.map(StatusItem::getId).toList();
List<StatusFlow> statusFlows = baseStatusFlowService.getStatusFlows(statusIds);
Assertions.assertEquals(statusFlows.size(), 1);
Assertions.assertEquals(statusFlows.get(0).getFromId(), statusFlow.getFromId());
Assertions.assertEquals(statusFlows.get(0).getToId(), statusFlow.getToId());
}
@Test @Test
@Order(5) @Order(5)
public void deleteStatusItem() throws Exception { public void deleteStatusItem() throws Exception {

View File

@ -27,7 +27,8 @@ public enum CommonResultCode implements IResultCode {
DEFAULT_TEMPLATE_PERMISSION(100014, "default_template_permission_error"), DEFAULT_TEMPLATE_PERMISSION(100014, "default_template_permission_error"),
STATUS_ITEM_NOT_EXIST(100015, "status_item.not.exist"), STATUS_ITEM_NOT_EXIST(100015, "status_item.not.exist"),
STATUS_ITEM_EXIST(100016, "status_item.exist"), STATUS_ITEM_EXIST(100016, "status_item.exist"),
FIELD_VALIDATE_ERROR(100017, "field_validate_error"); FIELD_VALIDATE_ERROR(100017, "field_validate_error"),
STATUS_DEFINITION_REQUIRED_ERROR(100018, "status_definition_required_error");;
private int code; private int code;

View File

@ -1,38 +1,17 @@
package io.metersphere.system.dto.sdk.request; package io.metersphere.system.dto.sdk.request;
import io.metersphere.sdk.constants.TemplateScene;
import io.metersphere.system.valid.EnumValue;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
@Data @Data
public class StatusDefinitionUpdateRequest implements Serializable { public class StatusDefinitionUpdateRequest implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Schema(description = "组织ID或项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank
@Size(min = 1, max = 50)
private String scopeId;
@Schema(description = "使用场景", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{status_item.scene.not_blank}")
@EnumValue(enumClass = TemplateScene.class)
private String scene;
@NotBlank
@Valid
private List<StatusDefinitionRequest> statusDefinitions;
@Data
public static class StatusDefinitionRequest implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "状态ID", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "状态ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{status_definition.status_id.not_blank}") @NotBlank(message = "{status_definition.status_id.not_blank}")
@Size(min = 1, max = 50, message = "{status_definition.status_id.length_range}") @Size(min = 1, max = 50, message = "{status_definition.status_id.length_range}")
@ -42,5 +21,8 @@ public class StatusDefinitionUpdateRequest implements Serializable {
@NotBlank(message = "{status_definition.definition_id.not_blank}") @NotBlank(message = "{status_definition.definition_id.not_blank}")
@Size(min = 1, max = 100, message = "{status_definition.definition_id.length_range}") @Size(min = 1, max = 100, message = "{status_definition.definition_id.length_range}")
private String definitionId; private String definitionId;
}
@Schema(description = "启用或者禁用", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull
private Boolean enable;
} }

View File

@ -1,38 +1,17 @@
package io.metersphere.system.dto.sdk.request; package io.metersphere.system.dto.sdk.request;
import io.metersphere.sdk.constants.TemplateScene;
import io.metersphere.system.valid.EnumValue;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
@Data @Data
public class StatusFlowUpdateRequest implements Serializable { public class StatusFlowUpdateRequest implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Schema(description = "组织ID或项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank
@Size(min = 1, max = 50)
private String scopeId;
@Schema(description = "使用场景", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{status_item.scene.not_blank}")
@EnumValue(enumClass = TemplateScene.class)
private String scene;
@NotBlank
@Valid
private List<StatusFlowRequest> statusFlows;
@Data
public static class StatusFlowRequest implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "起始状态ID", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "起始状态ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{status_flow.from_id.not_blank}") @NotBlank(message = "{status_flow.from_id.not_blank}")
@Size(min = 1, max = 50, message = "{status_flow.from_id.length_range}") @Size(min = 1, max = 50, message = "{status_flow.from_id.length_range}")
@ -42,5 +21,8 @@ public class StatusFlowUpdateRequest implements Serializable {
@NotBlank(message = "{status_flow.to_id.not_blank}") @NotBlank(message = "{status_flow.to_id.not_blank}")
@Size(min = 1, max = 50, message = "{status_flow.to_id.length_range}") @Size(min = 1, max = 50, message = "{status_flow.to_id.length_range}")
private String toId; private String toId;
}
@Schema(description = "启用或者禁用", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull
private Boolean enable;
} }

View File

@ -38,6 +38,18 @@ public class BaseStatusDefinitionService {
statusDefinitionMapper.deleteByExample(example); statusDefinitionMapper.deleteByExample(example);
} }
public void delete(String statusId, String definitionId) {
statusDefinitionMapper.deleteByPrimaryKey(statusId, definitionId);
}
public void add(StatusDefinition statusDefinition) {
StatusDefinitionExample example = new StatusDefinitionExample();
example.createCriteria()
.andStatusIdEqualTo(statusDefinition.getStatusId())
.andDefinitionIdEqualTo(statusDefinition.getDefinitionId());
statusDefinitionMapper.insert(statusDefinition);
}
public void deleteByStatusIds(List<String> statusItemIds) { public void deleteByStatusIds(List<String> statusItemIds) {
if (CollectionUtils.isEmpty(statusItemIds)) { if (CollectionUtils.isEmpty(statusItemIds)) {
return; return;
@ -54,4 +66,12 @@ public class BaseStatusDefinitionService {
} }
statusDefinitionMapper.batchInsert(statusDefinitions); statusDefinitionMapper.batchInsert(statusDefinitions);
} }
public void deleteByStatusIdsAndDefinitionId(List<String> statusIds, String definitionId) {
StatusDefinitionExample example = new StatusDefinitionExample();
example.createCriteria()
.andStatusIdIn(statusIds)
.andDefinitionIdEqualTo(definitionId);
statusDefinitionMapper.deleteByExample(example);
}
} }

View File

@ -1,7 +1,5 @@
package io.metersphere.system.service; package io.metersphere.system.service;
import io.metersphere.system.dto.sdk.request.StatusFlowUpdateRequest;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.system.domain.StatusFlow; import io.metersphere.system.domain.StatusFlow;
import io.metersphere.system.domain.StatusFlowExample; import io.metersphere.system.domain.StatusFlowExample;
import io.metersphere.system.mapper.StatusFlowMapper; import io.metersphere.system.mapper.StatusFlowMapper;
@ -11,10 +9,7 @@ import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/** /**
* @author jianxing * @author jianxing
@ -40,34 +35,6 @@ public class BaseStatusFlowService {
return statusFlowMapper.selectByExample(example); return statusFlowMapper.selectByExample(example);
} }
public void updateStatusFlow(List<String> deleteStatusItemIds, List<StatusFlowUpdateRequest.StatusFlowRequest> statusFlowRequests) {
// 先删除
StatusFlowExample example = new StatusFlowExample();
example.createCriteria().andFromIdIn(deleteStatusItemIds);
statusFlowMapper.deleteByExample(example);
example.clear();
example.createCriteria().andToIdIn(deleteStatusItemIds);
statusFlowMapper.deleteByExample(example);
// 再添加
List<StatusFlow> statusFlows = statusFlowRequests.stream().map(request -> {
StatusFlow statusFlow = new StatusFlow();
BeanUtils.copyBean(statusFlow, request);
statusFlow.setId(IDGenerator.nextStr());
return statusFlow;
}).toList();
statusFlowMapper.batchInsert(statusFlows);
}
public static List<String> getStatusIds(List<StatusFlowUpdateRequest.StatusFlowRequest> statusFlows) {
Set<String> statusIds = new HashSet<>();
statusFlows.forEach(statusFlow -> {
statusIds.add(statusFlow.getFromId());
statusIds.add(statusFlow.getToId());
});
return statusIds.stream().collect(Collectors.toList());
}
public void deleteByStatusId(String statusId) { public void deleteByStatusId(String statusId) {
StatusFlowExample example = new StatusFlowExample(); StatusFlowExample example = new StatusFlowExample();
example.createCriteria() example.createCriteria()
@ -100,4 +67,28 @@ public class BaseStatusFlowService {
}); });
statusFlowMapper.batchInsert(statusFlows); statusFlowMapper.batchInsert(statusFlows);
} }
public void add(StatusFlow statusFlow) {
statusFlow.setId(IDGenerator.nextStr());
statusFlowMapper.insert(statusFlow);
}
public void delete(String fromId, String toId) {
StatusFlowExample example = new StatusFlowExample();
example.createCriteria()
.andFromIdEqualTo(fromId)
.andToIdEqualTo(toId);
statusFlowMapper.deleteByExample(example);
}
public void deleteByFromIdsAndToIds(List<String> subProjectFromIds, List<String> subProjectToIds) {
if (CollectionUtils.isEmpty(subProjectFromIds) || CollectionUtils.isEmpty(subProjectToIds)) {
return;
}
StatusFlowExample example = new StatusFlowExample();
example.createCriteria()
.andFromIdIn(subProjectFromIds)
.andToIdIn(subProjectToIds);
statusFlowMapper.deleteByExample(example);
}
} }

View File

@ -1,22 +1,23 @@
package io.metersphere.system.service; package io.metersphere.system.service;
import io.metersphere.sdk.constants.DefaultBugStatusItem;
import io.metersphere.sdk.constants.BugStatusDefinitionType; import io.metersphere.sdk.constants.BugStatusDefinitionType;
import io.metersphere.sdk.constants.DefaultBugStatusItem;
import io.metersphere.sdk.constants.TemplateScene; import io.metersphere.sdk.constants.TemplateScene;
import io.metersphere.sdk.constants.TemplateScopeType; import io.metersphere.sdk.constants.TemplateScopeType;
import io.metersphere.system.dto.sdk.request.StatusDefinitionUpdateRequest; import io.metersphere.sdk.exception.MSException;
import io.metersphere.system.dto.sdk.request.StatusFlowUpdateRequest;
import io.metersphere.system.dto.sdk.request.StatusItemAddRequest;
import io.metersphere.sdk.util.BeanUtils; import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.system.controller.handler.result.CommonResultCode;
import io.metersphere.system.domain.StatusDefinition; import io.metersphere.system.domain.StatusDefinition;
import io.metersphere.system.domain.StatusDefinitionExample; import io.metersphere.system.domain.StatusDefinitionExample;
import io.metersphere.system.domain.StatusFlow; import io.metersphere.system.domain.StatusFlow;
import io.metersphere.system.domain.StatusItem; import io.metersphere.system.domain.StatusItem;
import io.metersphere.system.dto.StatusItemDTO; import io.metersphere.system.dto.StatusItemDTO;
import io.metersphere.system.dto.sdk.request.StatusDefinitionUpdateRequest;
import io.metersphere.system.dto.sdk.request.StatusFlowUpdateRequest;
import io.metersphere.system.dto.sdk.request.StatusItemAddRequest;
import io.metersphere.system.mapper.StatusDefinitionMapper; import io.metersphere.system.mapper.StatusDefinitionMapper;
import io.metersphere.system.uid.IDGenerator; import io.metersphere.system.uid.IDGenerator;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -95,46 +96,42 @@ public class BaseStatusFlowSettingService {
* *
* @param request * @param request
*/ */
public void updateStatusDefinition(StatusDefinitionUpdateRequest request) { protected void updateStatusDefinition(StatusItem statusItem, StatusDefinitionUpdateRequest request) {
List<StatusDefinitionUpdateRequest.StatusDefinitionRequest> statusDefinitionsRequests = request.getStatusDefinitions(); handleSingleChoice(statusItem, request);
List<StatusDefinition> statusDefinitions = statusDefinitionsRequests.stream() if (request.getEnable()) {
.map(statusFlowRequest -> BeanUtils.copyBean(new StatusDefinition(), statusFlowRequest)) baseStatusDefinitionService.add(BeanUtils.copyBean(new StatusDefinition(), request));
.toList(); } else {
List<String> statusIds = getStatusIds(statusDefinitionsRequests); baseStatusDefinitionService.delete(request.getStatusId(), request.getDefinitionId());
// 校验状态项是否存在 }
baseStatusItemService.checkStatusScope(request.getScopeId(), statusIds);
// 查询项目下所有的状态项
List<String> scopeStatusItemIds = baseStatusItemService.getByScopeIdAndScene(request.getScopeId(), request.getScene())
.stream()
.map(StatusItem::getId)
.toList();
updateStatusDefinition(scopeStatusItemIds, statusDefinitions);
} }
/** /**
* 设置状态定义 * 处理单选的状态定义
* 比如设置成项目 * @param statusItem
* * @param request
* @param scopeStatusItemIds
* @param statusDefinitions
*/ */
public void updateStatusDefinition(List<String> scopeStatusItemIds, List<StatusDefinition> statusDefinitions) { private void handleSingleChoice(StatusItem statusItem, StatusDefinitionUpdateRequest request) {
if (CollectionUtils.isEmpty(statusDefinitions)) { if (StringUtils.equals(statusItem.getScene(), TemplateScene.BUG.name())) {
BugStatusDefinitionType statusDefinitionType = BugStatusDefinitionType.getStatusDefinitionType(request.getDefinitionId());
if (!statusDefinitionType.getIsSingleChoice()) {
return; return;
} }
// 先删除组织或项目下的所有定义 // 如果是单选需要将其他状态取消勾选
StatusDefinitionExample example = new StatusDefinitionExample(); if (request.getEnable()) {
example.createCriteria().andStatusIdIn(scopeStatusItemIds); List<String> statusIds = baseStatusItemService.getByScopeIdAndScene(statusItem.getScopeId(), statusItem.getScene())
statusDefinitionMapper.deleteByExample(example); .stream()
// 再添加 .map(StatusItem::getId)
statusDefinitionMapper.batchInsert(statusDefinitions);
}
private List<String> getStatusIds(List<StatusDefinitionUpdateRequest.StatusDefinitionRequest> statusDefinitions) {
List<String> statusIds = statusDefinitions.stream()
.map(StatusDefinitionUpdateRequest.StatusDefinitionRequest::getStatusId)
.toList(); .toList();
return statusIds; StatusDefinitionExample example = new StatusDefinitionExample();
example.createCriteria()
.andStatusIdIn(statusIds)
.andDefinitionIdEqualTo(request.getDefinitionId());
statusDefinitionMapper.deleteByExample(example);
} else {
// 单选默认必选不能取消
throw new MSException(CommonResultCode.STATUS_DEFINITION_REQUIRED_ERROR);
}
}
} }
/** /**
@ -143,13 +140,11 @@ public class BaseStatusFlowSettingService {
* @param request * @param request
*/ */
protected void updateStatusFlow(StatusFlowUpdateRequest request) { protected void updateStatusFlow(StatusFlowUpdateRequest request) {
List<StatusFlowUpdateRequest.StatusFlowRequest> statusFlows = request.getStatusFlows(); if (request.getEnable()) {
List<String> statusIds = baseStatusFlowService.getStatusIds(statusFlows); baseStatusFlowService.add(BeanUtils.copyBean(new StatusFlow(), request));
baseStatusItemService.checkStatusScope(request.getScopeId(), statusIds); } else {
List<String> statusItemIds = baseStatusItemService.getByScopeIdAndScene(request.getScopeId(), request.getScene()) baseStatusFlowService.delete(request.getFromId(), request.getToId());
.stream() }
.map(StatusItem::getId).toList();
baseStatusFlowService.updateStatusFlow(statusItemIds, request.getStatusFlows());
} }
protected void deleteStatusItem(String id) { protected void deleteStatusItem(String id) {
@ -232,20 +227,17 @@ public class BaseStatusFlowSettingService {
protected void handleAllTransferTo(StatusItemAddRequest request, String addStatusItemId) { protected void handleAllTransferTo(StatusItemAddRequest request, String addStatusItemId) {
if (BooleanUtils.isTrue(request.getAllTransferTo())) { if (BooleanUtils.isTrue(request.getAllTransferTo())) {
List<StatusItem> statusItems = baseStatusItemService.getByScopeIdAndScene(request.getScopeId(), request.getScene()); List<StatusItem> statusItems = baseStatusItemService.getByScopeIdAndScene(request.getScopeId(), request.getScene());
List<StatusFlowUpdateRequest.StatusFlowRequest> statusFlows = statusItems.stream() List<StatusFlowUpdateRequest> statusFlowUpdateRequests = statusItems.stream()
// 过滤自己 // 过滤自己
.filter(item -> !StringUtils.equals(item.getId(), addStatusItemId)) .filter(item -> !StringUtils.equals(item.getId(), addStatusItemId))
.map(item -> { .map(item -> {
StatusFlowUpdateRequest.StatusFlowRequest statusFlow = new StatusFlowUpdateRequest.StatusFlowRequest(); StatusFlowUpdateRequest statusFlowRequest = new StatusFlowUpdateRequest();
statusFlow.setFromId(item.getId()); statusFlowRequest.setFromId(item.getId());
statusFlow.setToId(addStatusItemId); statusFlowRequest.setToId(addStatusItemId);
return statusFlow; statusFlowRequest.setEnable(true);
return statusFlowRequest;
}).toList(); }).toList();
StatusFlowUpdateRequest statusFlowUpdateRequest = new StatusFlowUpdateRequest(); statusFlowUpdateRequests.forEach(this::updateStatusFlow);
statusFlowUpdateRequest.setScopeId(request.getScopeId());
statusFlowUpdateRequest.setScene(request.getScene());
statusFlowUpdateRequest.setStatusFlows(statusFlows);
updateStatusFlow(statusFlowUpdateRequest);
} }
} }

View File

@ -85,10 +85,8 @@ public class BaseStatusItemService {
public StatusItem add(StatusItem statusItem) { public StatusItem add(StatusItem statusItem) {
checkAddExist(statusItem); checkAddExist(statusItem);
statusItem.setInternal(false); statusItem.setInternal(false);
if (statusItem.getPos() == null) { // 放到最后
// 如果没有指定排序就放到最后
statusItem.setPos(getByScopeIdAndScene(statusItem.getScopeId(), statusItem.getScene()).size() + 1); statusItem.setPos(getByScopeIdAndScene(statusItem.getScopeId(), statusItem.getScene()).size() + 1);
}
return baseAdd(statusItem); return baseAdd(statusItem);
} }
@ -152,6 +150,9 @@ public class BaseStatusItemService {
} }
public List<StatusItem> getByScopeIdsAndScene(List<String> scopeIds, String scene) { public List<StatusItem> getByScopeIdsAndScene(List<String> scopeIds, String scene) {
if (CollectionUtils.isEmpty(scopeIds)) {
return List.of();
}
StatusItemExample example = new StatusItemExample(); StatusItemExample example = new StatusItemExample();
example.createCriteria().andScopeIdIn(scopeIds).andSceneEqualTo(scene); example.createCriteria().andScopeIdIn(scopeIds).andSceneEqualTo(scene);
return statusItemMapper.selectByExample(example); return statusItemMapper.selectByExample(example);

View File

@ -34,7 +34,8 @@ public class OrganizationStatusFlowSettingLogService {
public LogDTO updateStatusDefinitionLog(StatusDefinitionUpdateRequest request) { public LogDTO updateStatusDefinitionLog(StatusDefinitionUpdateRequest request) {
return updateStatusFlowSettingLog(request.getScopeId(), request.getScene()); StatusItem statusItem = statusItemMapper.selectByPrimaryKey(request.getStatusId());
return updateStatusFlowSettingLog(statusItem.getScopeId(), statusItem.getScene());
} }
public LogDTO addStatusItemLog(StatusItemAddRequest request) { public LogDTO addStatusItemLog(StatusItemAddRequest request) {
@ -52,7 +53,8 @@ public class OrganizationStatusFlowSettingLogService {
} }
public LogDTO updateStatusFlowLog(StatusFlowUpdateRequest request) { public LogDTO updateStatusFlowLog(StatusFlowUpdateRequest request) {
return updateStatusFlowSettingLog(request.getScopeId(), request.getScene()); StatusItem statusItem = statusItemMapper.selectByPrimaryKey(request.getFromId());
return updateStatusFlowSettingLog(statusItem.getScopeId(), statusItem.getScene());
} }
public LogDTO updateStatusFlowSettingLog(String scopeId, String scene) { public LogDTO updateStatusFlowSettingLog(String scopeId, String scene) {

View File

@ -1,17 +1,21 @@
package io.metersphere.system.service; package io.metersphere.system.service;
import io.metersphere.sdk.constants.BugStatusDefinitionType;
import io.metersphere.sdk.constants.TemplateScene;
import io.metersphere.sdk.constants.TemplateScopeType; import io.metersphere.sdk.constants.TemplateScopeType;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.SubListUtils;
import io.metersphere.system.domain.StatusDefinition;
import io.metersphere.system.domain.StatusDefinitionExample;
import io.metersphere.system.domain.StatusFlow;
import io.metersphere.system.domain.StatusItem;
import io.metersphere.system.dto.StatusItemDTO;
import io.metersphere.system.dto.sdk.request.StatusDefinitionUpdateRequest; import io.metersphere.system.dto.sdk.request.StatusDefinitionUpdateRequest;
import io.metersphere.system.dto.sdk.request.StatusFlowUpdateRequest; import io.metersphere.system.dto.sdk.request.StatusFlowUpdateRequest;
import io.metersphere.system.dto.sdk.request.StatusItemAddRequest; import io.metersphere.system.dto.sdk.request.StatusItemAddRequest;
import io.metersphere.system.dto.sdk.request.StatusItemUpdateRequest; import io.metersphere.system.dto.sdk.request.StatusItemUpdateRequest;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.SubListUtils;
import io.metersphere.system.domain.StatusDefinition;
import io.metersphere.system.domain.StatusFlow;
import io.metersphere.system.domain.StatusItem;
import io.metersphere.system.dto.StatusItemDTO;
import io.metersphere.system.mapper.BaseProjectMapper; import io.metersphere.system.mapper.BaseProjectMapper;
import io.metersphere.system.uid.IDGenerator;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -20,6 +24,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -54,12 +59,13 @@ public class OrganizationStatusFlowSettingService extends BaseStatusFlowSettingS
* *
* @param request * @param request
*/ */
@Override
public void updateStatusDefinition(StatusDefinitionUpdateRequest request) { public void updateStatusDefinition(StatusDefinitionUpdateRequest request) {
OrganizationService.checkResourceExist(request.getScopeId()); StatusItem statusItem = baseStatusItemService.getWithCheck(request.getStatusId());
organizationTemplateService.checkOrganizationTemplateEnable(request.getScopeId(), request.getScene()); OrganizationService.checkResourceExist(statusItem.getScopeId());
super.updateStatusDefinition(request); organizationTemplateService.checkOrganizationTemplateEnable(statusItem.getScopeId(), statusItem.getScene());
updateRefProjectStatusDefinition(request); super.updateStatusDefinition(statusItem, request);
// 同步更新项目级别状态定义
updateRefProjectStatusDefinition(statusItem, request);
} }
/** /**
@ -68,48 +74,54 @@ public class OrganizationStatusFlowSettingService extends BaseStatusFlowSettingS
* @param request * @param request
* @return * @return
*/ */
public void updateRefProjectStatusDefinition(StatusDefinitionUpdateRequest request) { public void updateRefProjectStatusDefinition(StatusItem orgStatusItem, StatusDefinitionUpdateRequest request) {
String orgId = request.getScopeId(); handleRefSingleChoice(orgStatusItem, request);
List<StatusDefinitionUpdateRequest.StatusDefinitionRequest> orgStatusDefinitions = request.getStatusDefinitions(); List<StatusItem> statusItems = baseStatusItemService.getByRefId(request.getStatusId());
if (orgStatusDefinitions == null) { SubListUtils.dealForSubList(statusItems, 200, (subStatusItems) -> {
// 每次处理200条
if (request.getEnable()) {
List<StatusDefinition> projectStatusDefinitions = subStatusItems.stream().map(statusItem -> {
StatusDefinition statusDefinition = new StatusDefinition();
statusDefinition.setStatusId(((StatusItem) statusItem).getId());
statusDefinition.setDefinitionId(request.getDefinitionId());
return statusDefinition;
}).toList();
baseStatusDefinitionService.batchAdd(projectStatusDefinitions);
} else {
List<String> projectStatusIds = subStatusItems.stream()
.map(statusItem -> ((StatusItem) statusItem).getId())
.toList();
baseStatusDefinitionService.deleteByStatusIdsAndDefinitionId(projectStatusIds, request.getDefinitionId());
}
});
}
/**
* 处理单选的状态定义
*
* @param request
*/
private void handleRefSingleChoice(StatusItem orgStatusItem, StatusDefinitionUpdateRequest request) {
if (StringUtils.equals(orgStatusItem.getScene(), TemplateScene.BUG.name())) {
BugStatusDefinitionType statusDefinitionType = BugStatusDefinitionType.getStatusDefinitionType(request.getDefinitionId());
if (!statusDefinitionType.getIsSingleChoice()) {
return; return;
} }
List<String> projectIds = baseProjectMapper.getProjectIdByOrgId(orgStatusItem.getScopeId());
List<String> projectIds = baseProjectMapper.getProjectIdByOrgId(orgId);
SubListUtils.dealForSubList(projectIds, 200, (subProjectIds) -> { SubListUtils.dealForSubList(projectIds, 200, (subProjectIds) -> {
// 每次处理200条
List<StatusDefinition> statusDefinitions = new ArrayList<>();
// 查询组织下所有项目的状态项 // 查询组织下所有项目的状态项
List<StatusItem> statusItems = baseStatusItemService.getByScopeIdsAndScene(subProjectIds, request.getScene()); List<StatusItem> statusItems = baseStatusItemService.getByScopeIdsAndScene(subProjectIds, orgStatusItem.getScene());
Map<String, List<StatusItem>> projectStatusItemMap = statusItems List<String> statusItemIds = statusItems.stream().map(StatusItem::getId).toList();
.stream() StatusDefinitionExample example = new StatusDefinitionExample();
.collect(Collectors.groupingBy(StatusItem::getScopeId)); example.createCriteria()
.andStatusIdIn(statusItemIds)
for (String projectId : projectStatusItemMap.keySet()) { .andDefinitionIdEqualTo(request.getDefinitionId());
List<StatusItem> projectStatusItems = projectStatusItemMap.get(projectId); // 如果是单选需要将其他状态取消勾选
// 构建map键为组织状态ID值为项目字状态ID statusDefinitionMapper.deleteByExample(example);
Map<String, String> refFieldMap = projectStatusItems
.stream()
.collect(Collectors.toMap(StatusItem::getRefId, StatusItem::getId));
// 根据组织状态ID替换为项目状态ID
List<StatusDefinition> projectStatusDefinitions = orgStatusDefinitions.stream()
.map(item -> {
StatusDefinition statusDefinition = BeanUtils.copyBean(new StatusDefinition(), item);
statusDefinition.setStatusId(refFieldMap.get(item.getStatusId()));
return statusDefinition;
})
.filter(item -> StringUtils.isNotBlank(item.getStatusId()))
.toList();
statusDefinitions.addAll(projectStatusDefinitions);
}
// 删除项目下的状态项
List<String> scopeStatusItemIds = statusItems
.stream()
.map(StatusItem::getId)
.toList();
updateStatusDefinition(scopeStatusItemIds, statusDefinitions);
}); });
} }
}
/** /**
* 添加状态选项 * 添加状态选项
@ -207,14 +219,14 @@ public class OrganizationStatusFlowSettingService extends BaseStatusFlowSettingS
*/ */
public void deleteRefStatusItem(String orgStatusItemId) { public void deleteRefStatusItem(String orgStatusItemId) {
// 删除关联的项目状态项 // 删除关联的项目状态项
baseStatusItemService.deleteByRefId(orgStatusItemId);
List<String> statusItemIds = baseStatusItemService.getStatusItemIdByRefId(orgStatusItemId); List<String> statusItemIds = baseStatusItemService.getStatusItemIdByRefId(orgStatusItemId);
SubListUtils.dealForSubList(statusItemIds, 100, (subProjectIds) -> { SubListUtils.dealForSubList(statusItemIds, 100, (subStatusItemIds) -> {
// 删除相关的状态定义 // 删除相关的状态定义
baseStatusDefinitionService.deleteByStatusIds(statusItemIds); baseStatusDefinitionService.deleteByStatusIds(subStatusItemIds);
// 删除相关的状态流 // 删除相关的状态流
baseStatusFlowService.deleteByStatusIds(statusItemIds); baseStatusFlowService.deleteByStatusIds(subStatusItemIds);
}); });
baseStatusItemService.deleteByRefId(orgStatusItemId);
} }
/** /**
@ -223,10 +235,13 @@ public class OrganizationStatusFlowSettingService extends BaseStatusFlowSettingS
* @param request * @param request
*/ */
public void updateStatusFlow(StatusFlowUpdateRequest request) { public void updateStatusFlow(StatusFlowUpdateRequest request) {
OrganizationService.checkResourceExist(request.getScopeId()); StatusItem fromStatusItem = baseStatusItemService.getWithCheck(request.getFromId());
organizationTemplateService.checkOrganizationTemplateEnable(request.getScopeId(), request.getScene()); StatusItem toStatusItem = baseStatusItemService.getWithCheck(request.getToId());
// 同步添加项目级别状态流 OrganizationService.checkResourceExist(fromStatusItem.getScopeId());
OrganizationService.checkResourceExist(toStatusItem.getScopeId());
organizationTemplateService.checkOrganizationTemplateEnable(fromStatusItem.getScopeId(), fromStatusItem.getScene());
super.updateStatusFlow(request); super.updateStatusFlow(request);
// 同步添加项目级别状态流
updateRefProjectStatusFlow(request); updateRefProjectStatusFlow(request);
} }
@ -237,45 +252,50 @@ public class OrganizationStatusFlowSettingService extends BaseStatusFlowSettingS
* @return * @return
*/ */
public void updateRefProjectStatusFlow(StatusFlowUpdateRequest request) { public void updateRefProjectStatusFlow(StatusFlowUpdateRequest request) {
String orgId = request.getScopeId();
List<StatusFlowUpdateRequest.StatusFlowRequest> statusFlowRequests = request.getStatusFlows();
if (statusFlowRequests == null) {
return;
}
List<String> projectIds = baseProjectMapper.getProjectIdByOrgId(orgId); // 获取from和to状态项
SubListUtils.dealForSubList(projectIds, 100, (subProjectIds) -> { List<StatusItem> fromStatusItems = baseStatusItemService.getByRefId(request.getFromId());
Map<String, StatusItem> fromStatusItemMap = fromStatusItems.stream()
.collect(Collectors.toMap(StatusItem::getScopeId, Function.identity()));
List<StatusItem> toStatusItems = baseStatusItemService.getByRefId(request.getToId());
Map<String, StatusItem> toStatusItemMap = toStatusItems.stream()
.collect(Collectors.toMap(StatusItem::getScopeId, Function.identity()));
if (request.getEnable()) {
// 同步添加项目级别状态流
List<StatusFlow> statusFlows = new ArrayList<>(); List<StatusFlow> statusFlows = new ArrayList<>();
for (String projectId : fromStatusItemMap.keySet()) {
// 查询组织下所有项目的状态项 String fromId = fromStatusItemMap.get(projectId).getId();
List<StatusItem> statusItems = baseStatusItemService.getByScopeIdsAndScene(subProjectIds, request.getScene()); String toId = toStatusItemMap.get(projectId).getId();
Map<String, List<StatusItem>> projectStatusItemMap = statusItems if (StringUtils.isNotBlank(fromId) && StringUtils.isNotBlank(toId)) {
.stream()
.collect(Collectors.groupingBy(StatusItem::getScopeId));
List<String> statusItemIds = statusItems.stream().map(StatusItem::getId).toList();
for (String projectId : projectStatusItemMap.keySet()) {
// 构建map键为组织状态ID值为项目字状态ID
Map<String, String> refStatusItemMap = projectStatusItemMap.get(projectId)
.stream()
.collect(Collectors.toMap(StatusItem::getRefId, StatusItem::getId));
// 根据组织状态ID替换为项目状态ID
List<StatusFlow> projectStatusFlows = statusFlowRequests.stream()
.map(item -> {
StatusFlow statusFlow = new StatusFlow(); StatusFlow statusFlow = new StatusFlow();
statusFlow.setToId(refStatusItemMap.get(item.getToId())); statusFlow.setFromId(fromId);
statusFlow.setFromId(refStatusItemMap.get(item.getFromId())); statusFlow.setToId(toId);
return statusFlow; statusFlow.setId(IDGenerator.nextStr());
}) statusFlows.add(statusFlow);
.filter(item -> item.getToId() != null && item.getFromId() != null) }
.toList(); }
statusFlows.addAll(projectStatusFlows); SubListUtils.dealForSubList(statusFlows, 200, baseStatusFlowService::batchAdd);
} else {
// 同步删除项目级别状态流
List<String> subProjectFromIds = new ArrayList<>();
List<String> subProjectToIds = new ArrayList<>();
for (String projectId : fromStatusItemMap.keySet()) {
String fromId = fromStatusItemMap.get(projectId).getId();
String toId = toStatusItemMap.get(projectId).getId();
if (StringUtils.isNotBlank(fromId) && StringUtils.isNotBlank(toId)) {
subProjectFromIds.add(fromId);
subProjectToIds.add(toId);
if (subProjectFromIds.size() > 100) {
// 分批删除
baseStatusFlowService.deleteByFromIdsAndToIds(subProjectFromIds, subProjectToIds);
subProjectFromIds.clear();
subProjectToIds.clear();
}
}
}
baseStatusFlowService.deleteByFromIdsAndToIds(subProjectFromIds, subProjectToIds);
} }
// 先删除
baseStatusFlowService.deleteByStatusIds(statusItemIds);
// 在添加
baseStatusFlowService.batchAdd(statusFlows);
});
} }
@Override @Override

View File

@ -17,6 +17,8 @@ import io.metersphere.system.domain.*;
import io.metersphere.system.dto.StatusItemDTO; import io.metersphere.system.dto.StatusItemDTO;
import io.metersphere.system.log.constants.OperationLogType; import io.metersphere.system.log.constants.OperationLogType;
import io.metersphere.system.mapper.OrganizationParameterMapper; import io.metersphere.system.mapper.OrganizationParameterMapper;
import io.metersphere.system.mapper.StatusDefinitionMapper;
import io.metersphere.system.mapper.StatusFlowMapper;
import io.metersphere.system.mapper.StatusItemMapper; import io.metersphere.system.mapper.StatusItemMapper;
import io.metersphere.system.service.BaseStatusDefinitionService; import io.metersphere.system.service.BaseStatusDefinitionService;
import io.metersphere.system.service.BaseStatusFlowService; import io.metersphere.system.service.BaseStatusFlowService;
@ -33,10 +35,10 @@ import org.springframework.test.web.servlet.MvcResult;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static io.metersphere.system.controller.handler.result.CommonResultCode.STATUS_ITEM_EXIST; import static io.metersphere.system.controller.handler.result.CommonResultCode.*;
import static io.metersphere.system.controller.handler.result.CommonResultCode.STATUS_ITEM_NOT_EXIST;
import static io.metersphere.system.controller.handler.result.MsHttpResultCode.NOT_FOUND; import static io.metersphere.system.controller.handler.result.MsHttpResultCode.NOT_FOUND;
import static io.metersphere.system.controller.result.SystemResultCode.ORGANIZATION_TEMPLATE_PERMISSION; import static io.metersphere.system.controller.result.SystemResultCode.ORGANIZATION_TEMPLATE_PERMISSION;
@ -59,6 +61,7 @@ public class OrganizationStatusFlowSettingControllerTest extends BaseTest {
private static final String STATUS_FLOW_UPDATE = "status/flow/update"; private static final String STATUS_FLOW_UPDATE = "status/flow/update";
private static StatusItem addStatusItem; private static StatusItem addStatusItem;
private static StatusItem anotherAddStatusItem;
@Resource @Resource
private StatusItemMapper statusItemMapper; private StatusItemMapper statusItemMapper;
@ -155,7 +158,8 @@ public class OrganizationStatusFlowSettingControllerTest extends BaseTest {
request.setName("test2"); request.setName("test2");
request.setAllTransferTo(true); request.setAllTransferTo(true);
mvcResult = this.requestPostWithOkAndReturn(STATUS_ADD, request); mvcResult = this.requestPostWithOkAndReturn(STATUS_ADD, request);
statusItemId = getResultData(mvcResult, StatusItem.class).getId(); anotherAddStatusItem = getResultData(mvcResult, StatusItem.class);
statusItemId = anotherAddStatusItem.getId();
assertAllTransferTo(statusItemId, request.getScopeId()); assertAllTransferTo(statusItemId, request.getScopeId());
assertRefAllTransferTo(statusItemId); assertRefAllTransferTo(statusItemId);
@ -185,6 +189,7 @@ public class OrganizationStatusFlowSettingControllerTest extends BaseTest {
/** /**
* 校验 allTransferTo * 校验 allTransferTo
*
* @param statusItemId * @param statusItemId
*/ */
public static void assertAllTransferTo(String statusItemId, String scopeId) { public static void assertAllTransferTo(String statusItemId, String scopeId) {
@ -239,6 +244,11 @@ public class OrganizationStatusFlowSettingControllerTest extends BaseTest {
Assertions.assertEquals(statusItem.getRemark(), request.getRemark()); Assertions.assertEquals(statusItem.getRemark(), request.getRemark());
assertRefStatusItem(statusItem); assertRefStatusItem(statusItem);
// 提升覆盖率
request.setName(null);
this.requestPostWithOkAndReturn(STATUS_UPDATE, request);
baseStatusItemService.getByScopeIdsAndScene(null, TemplateScene.BUG.name());
// @校验是否开启组织模板 // @校验是否开启组织模板
changeOrgTemplateEnable(false); changeOrgTemplateEnable(false);
assertErrorCode(this.requestPost(STATUS_UPDATE, request), ORGANIZATION_TEMPLATE_PERMISSION); assertErrorCode(this.requestPost(STATUS_UPDATE, request), ORGANIZATION_TEMPLATE_PERMISSION);
@ -260,23 +270,45 @@ public class OrganizationStatusFlowSettingControllerTest extends BaseTest {
requestPostPermissionTest(PermissionConstants.ORGANIZATION_TEMPLATE_UPDATE, STATUS_UPDATE, request); requestPostPermissionTest(PermissionConstants.ORGANIZATION_TEMPLATE_UPDATE, STATUS_UPDATE, request);
} }
@Test @Test
@Order(3) @Order(3)
public void updateStatusDefinition() throws Exception { public void updateStatusDefinition() throws Exception {
StatusDefinitionUpdateRequest request = new StatusDefinitionUpdateRequest(); StatusDefinitionUpdateRequest request = new StatusDefinitionUpdateRequest();
request.setScene(TemplateScene.BUG.name()); request.setStatusId(addStatusItem.getId());
request.setScopeId(DEFAULT_ORGANIZATION_ID); request.setDefinitionId(BugStatusDefinitionType.END.name());
StatusDefinitionUpdateRequest.StatusDefinitionRequest statusDefinition = new StatusDefinitionUpdateRequest.StatusDefinitionRequest(); request.setEnable(true);
statusDefinition.setStatusId(addStatusItem.getId());
statusDefinition.setDefinitionId(BugStatusDefinitionType.END.name());
request.setStatusDefinitions(List.of(statusDefinition));
// @@校验请求成功 // @@校验请求成功
this.requestPostWithOkAndReturn(STATUS_DEFINITION_UPDATE, request); this.requestPostWithOkAndReturn(STATUS_DEFINITION_UPDATE, request);
assertUpdateStatusDefinition(DEFAULT_ORGANIZATION_ID); assertUpdateStatusDefinition(request);
// 校验项目是否同步修改 // 校验项目是否同步修改
assertUpdateStatusDefinition(DEFAULT_PROJECT_ID); assertRefUpdateStatusDefinition(request);
// 取消关联
request.setEnable(false);
this.requestPostWithOkAndReturn(STATUS_DEFINITION_UPDATE, request);
assertUpdateStatusDefinition(request);
// 校验项目是否同步修改
assertRefUpdateStatusDefinition(request);
// @测试单选
request.setStatusId(addStatusItem.getId());
request.setDefinitionId(BugStatusDefinitionType.START.name());
request.setEnable(true);
this.requestPostWithOkAndReturn(STATUS_DEFINITION_UPDATE, request);
assertUpdateStatusDefinition(request);
// 校验项目是否同步修改
assertRefUpdateStatusDefinition(request);
// 校验单选
assertSingleChoiceUpdateStatusDefinition(request);
// 校验单选禁止取消
request.setEnable(false);
assertErrorCode(this.requestPost(STATUS_DEFINITION_UPDATE, request), STATUS_DEFINITION_REQUIRED_ERROR);
// 设置回来避免其他地方校验出错
StatusItem newStatusItem = getNewStatusItem(addStatusItem.getScopeId());
request.setStatusId(newStatusItem.getId());
request.setEnable(true);
this.requestPostWithOkAndReturn(STATUS_DEFINITION_UPDATE, request);
// @校验是否开启组织模板 // @校验是否开启组织模板
changeOrgTemplateEnable(false); changeOrgTemplateEnable(false);
@ -284,11 +316,7 @@ public class OrganizationStatusFlowSettingControllerTest extends BaseTest {
changeOrgTemplateEnable(true); changeOrgTemplateEnable(true);
// @@状态不存在 // @@状态不存在
request.getStatusDefinitions().get(0).setStatusId("1111"); request.setStatusId("1111");
assertErrorCode(this.requestPost(STATUS_DEFINITION_UPDATE, request), STATUS_ITEM_NOT_EXIST);
// @@校验组织是否存在
request.setScopeId("1111");
assertErrorCode(this.requestPost(STATUS_DEFINITION_UPDATE, request), NOT_FOUND); assertErrorCode(this.requestPost(STATUS_DEFINITION_UPDATE, request), NOT_FOUND);
// @@校验日志 // @@校验日志
@ -299,39 +327,82 @@ public class OrganizationStatusFlowSettingControllerTest extends BaseTest {
requestPostPermissionTest(PermissionConstants.ORGANIZATION_TEMPLATE_UPDATE, STATUS_DEFINITION_UPDATE, request); requestPostPermissionTest(PermissionConstants.ORGANIZATION_TEMPLATE_UPDATE, STATUS_DEFINITION_UPDATE, request);
} }
private void assertUpdateStatusDefinition(String scopeId) { public static StatusItem getNewStatusItem(String scopeId) {
List<String> statusIds = baseStatusItemService.getByScopeIdAndScene(scopeId, TemplateScene.BUG.name()).stream().map(StatusItem::getId).toList(); StatusItemExample example = new StatusItemExample();
List<StatusDefinition> statusDefinitions = baseStatusDefinitionService.getStatusDefinitions(statusIds); example.createCriteria()
Assertions.assertEquals(statusDefinitions.size(), 1); .andNameEqualTo(DefaultBugStatusItemName.NEW)
Assertions.assertEquals(statusDefinitions.get(0).getDefinitionId(), BugStatusDefinitionType.END.name()); .andScopeIdEqualTo(scopeId);
StatusItemMapper statusItemMapper = CommonBeanFactory.getBean(StatusItemMapper.class);
return statusItemMapper.selectByExample(example).get(0);
}
public static void assertUpdateStatusDefinition(StatusDefinitionUpdateRequest request) {
StatusDefinitionExample example = new StatusDefinitionExample();
example.createCriteria()
.andStatusIdEqualTo(request.getStatusId())
.andDefinitionIdEqualTo(request.getDefinitionId());
StatusDefinitionMapper statusDefinitionMapper = CommonBeanFactory.getBean(StatusDefinitionMapper.class);
List<StatusDefinition> statusDefinitions = statusDefinitionMapper.selectByExample(example);
if (request.getEnable()) {
Assertions.assertTrue(statusDefinitions.size() == 1);
} else {
Assertions.assertTrue(statusDefinitions.size() == 0);
}
}
public static void assertSingleChoiceUpdateStatusDefinition(StatusDefinitionUpdateRequest request) {
// 查询当前组织或项目下的状态项
BaseStatusItemService baseStatusItemService = CommonBeanFactory.getBean(BaseStatusItemService.class);
StatusItem statusItem = baseStatusItemService.getWithCheck(request.getStatusId());
List<String> scopeStatusItemIds = baseStatusItemService.getByScopeIdAndScene(statusItem.getScopeId(), TemplateScene.BUG.name())
.stream().map(StatusItem::getId).toList();
// 查询当前组织或项目下的该状态定义
StatusDefinitionExample example = new StatusDefinitionExample();
example.createCriteria()
.andStatusIdIn(scopeStatusItemIds)
.andDefinitionIdEqualTo(request.getDefinitionId());
StatusDefinitionMapper statusDefinitionMapper = CommonBeanFactory.getBean(StatusDefinitionMapper.class);
List<StatusDefinition> statusDefinitions = statusDefinitionMapper.selectByExample(example);
if (request.getEnable()) {
Assertions.assertTrue(statusDefinitions.size() == 1);
}
}
public static void assertRefUpdateStatusDefinition(StatusDefinitionUpdateRequest request) {
BaseStatusItemService baseStatusItemService = CommonBeanFactory.getBean(BaseStatusItemService.class);
List<StatusItem> projectStatusItem = baseStatusItemService.getByRefId(request.getStatusId());
StatusDefinitionUpdateRequest projectRequest = BeanUtils.copyBean(new StatusDefinitionUpdateRequest(), request);
projectStatusItem.forEach(statusItem -> {
projectRequest.setStatusId(statusItem.getId());
assertUpdateStatusDefinition(projectRequest);
});
} }
@Test @Test
@Order(4) @Order(4)
public void updateStatusFlow() throws Exception { public void updateStatusFlow() throws Exception {
StatusFlowUpdateRequest request = new StatusFlowUpdateRequest(); StatusFlowUpdateRequest request = new StatusFlowUpdateRequest();
request.setScopeId(DEFAULT_ORGANIZATION_ID); request.setFromId(anotherAddStatusItem.getId());
request.setScene(TemplateScene.BUG.name()); request.setToId(addStatusItem.getId());
request.setEnable(true);
StatusFlowUpdateRequest.StatusFlowRequest statusFlow = new StatusFlowUpdateRequest.StatusFlowRequest();
statusFlow.setFromId(addStatusItem.getId());
StatusItemExample example = new StatusItemExample();
example.createCriteria().andScopeIdEqualTo(DEFAULT_ORGANIZATION_ID).andSceneEqualTo(TemplateScene.BUG.name());
StatusItem targetStatusItem = statusItemMapper.selectByExample(example).stream()
.filter(item -> !StringUtils.equals(addStatusItem.getId(), item.getId()))
.findFirst()
.get();
statusFlow.setToId(targetStatusItem.getId());
request.setStatusFlows(List.of(statusFlow));
// @@校验请求成功 // @@校验请求成功
this.requestPostWithOkAndReturn(STATUS_FLOW_UPDATE, request); this.requestPostWithOkAndReturn(STATUS_FLOW_UPDATE, request);
assertUpdateStatusFlow(DEFAULT_ORGANIZATION_ID, statusFlow); assertUpdateStatusFlow(request);
// 校验项目是否同步修改 // 校验项目是否同步修改
StatusFlowUpdateRequest.StatusFlowRequest projectStatusFlow = new StatusFlowUpdateRequest.StatusFlowRequest(); assertRefUpdateStatusFlow(request);
projectStatusFlow.setFromId(baseStatusItemService.getByRefId(statusFlow.getFromId()).get(0).getId());
projectStatusFlow.setToId(baseStatusItemService.getByRefId(statusFlow.getToId()).get(0).getId()); // @@校验取消
assertUpdateStatusFlow(DEFAULT_PROJECT_ID, projectStatusFlow); request.setEnable(false);
this.requestPostWithOkAndReturn(STATUS_FLOW_UPDATE, request);
assertUpdateStatusFlow(request);
// 校验项目是否同步修改
assertRefUpdateStatusFlow(request);
// 增加覆盖率
baseStatusFlowService.deleteByFromIdsAndToIds(null, null);
// @校验是否开启组织模板 // @校验是否开启组织模板
changeOrgTemplateEnable(false); changeOrgTemplateEnable(false);
@ -339,11 +410,7 @@ public class OrganizationStatusFlowSettingControllerTest extends BaseTest {
changeOrgTemplateEnable(true); changeOrgTemplateEnable(true);
// @@状态不存在 // @@状态不存在
request.getStatusFlows().get(0).setToId("1111"); request.setToId("1111");
assertErrorCode(this.requestPost(STATUS_FLOW_UPDATE, request), STATUS_ITEM_NOT_EXIST);
// @@校验组织是否存在
request.setScopeId("1111");
assertErrorCode(this.requestPost(STATUS_FLOW_UPDATE, request), NOT_FOUND); assertErrorCode(this.requestPost(STATUS_FLOW_UPDATE, request), NOT_FOUND);
// @@校验日志 // @@校验日志
@ -354,13 +421,35 @@ public class OrganizationStatusFlowSettingControllerTest extends BaseTest {
requestPostPermissionTest(PermissionConstants.ORGANIZATION_TEMPLATE_UPDATE, STATUS_FLOW_UPDATE, request); requestPostPermissionTest(PermissionConstants.ORGANIZATION_TEMPLATE_UPDATE, STATUS_FLOW_UPDATE, request);
} }
private void assertUpdateStatusFlow(String scopeId, StatusFlowUpdateRequest.StatusFlowRequest statusFlow) { public static void assertUpdateStatusFlow(StatusFlowUpdateRequest request) {
List<String> statusIds = baseStatusItemService.getByScopeIdAndScene(scopeId, TemplateScene.BUG.name()).stream() StatusFlowExample example = new StatusFlowExample();
.map(StatusItem::getId).toList(); example.createCriteria()
List<StatusFlow> statusFlows = baseStatusFlowService.getStatusFlows(statusIds); .andFromIdEqualTo(request.getFromId())
Assertions.assertEquals(statusFlows.size(), 1); .andToIdEqualTo(request.getToId());
Assertions.assertEquals(statusFlows.get(0).getFromId(), statusFlow.getFromId()); StatusFlowMapper statusFlowMapper = CommonBeanFactory.getBean(StatusFlowMapper.class);
Assertions.assertEquals(statusFlows.get(0).getToId(), statusFlow.getToId()); List<StatusFlow> statusFlows = statusFlowMapper.selectByExample(example);
if (request.getEnable()) {
Assertions.assertTrue(statusFlows.size() == 1);
} else {
Assertions.assertTrue(statusFlows.size() == 0);
}
}
public static void assertRefUpdateStatusFlow(StatusFlowUpdateRequest request) {
BaseStatusItemService baseStatusItemService = CommonBeanFactory.getBean(BaseStatusItemService.class);
List<StatusItem> fromStatusItems = baseStatusItemService.getByRefId(request.getFromId());
Map<String, StatusItem> fromStatusItemMap = fromStatusItems.stream()
.collect(Collectors.toMap(StatusItem::getScopeId, Function.identity()));
List<StatusItem> toStatusItems = baseStatusItemService.getByRefId(request.getToId());
Map<String, StatusItem> toStatusItemMap = toStatusItems.stream()
.collect(Collectors.toMap(StatusItem::getScopeId, Function.identity()));
StatusFlowUpdateRequest projectRequest = BeanUtils.copyBean(new StatusFlowUpdateRequest(), request);
for (String projectId : fromStatusItemMap.keySet()) {
projectRequest.setFromId(fromStatusItemMap.get(projectId).getId());
projectRequest.setToId(toStatusItemMap.get(projectId).getId());
assertUpdateStatusFlow(projectRequest);
}
} }
@Test @Test
@ -372,11 +461,14 @@ public class OrganizationStatusFlowSettingControllerTest extends BaseTest {
changeOrgTemplateEnable(true); changeOrgTemplateEnable(true);
// @@请求成功 // @@请求成功
List<String> projectStatusItemIds = baseStatusItemService.getStatusItemIdByRefId(addStatusItem.getId());
this.requestGetWithOk(STATUS_DELETE, addStatusItem.getId()); this.requestGetWithOk(STATUS_DELETE, addStatusItem.getId());
Assertions.assertNull(statusItemMapper.selectByPrimaryKey(addStatusItem.getId())); Assertions.assertNull(statusItemMapper.selectByPrimaryKey(addStatusItem.getId()));
Assertions.assertTrue(CollectionUtils.isEmpty(baseStatusItemService.getStatusItemIdByRefId(addStatusItem.getId()))); Assertions.assertTrue(CollectionUtils.isEmpty(baseStatusItemService.getStatusItemIdByRefId(addStatusItem.getId())));
Assertions.assertTrue(CollectionUtils.isEmpty(baseStatusDefinitionService.getStatusDefinitions(List.of(addStatusItem.getId())))); Assertions.assertTrue(CollectionUtils.isEmpty(baseStatusDefinitionService.getStatusDefinitions(List.of(addStatusItem.getId()))));
Assertions.assertTrue(CollectionUtils.isEmpty(baseStatusFlowService.getStatusFlows(List.of(addStatusItem.getId())))); Assertions.assertTrue(CollectionUtils.isEmpty(baseStatusFlowService.getStatusFlows(List.of(addStatusItem.getId()))));
Assertions.assertTrue(CollectionUtils.isEmpty(baseStatusDefinitionService.getStatusDefinitions(projectStatusItemIds)));
Assertions.assertTrue(CollectionUtils.isEmpty(baseStatusFlowService.getStatusFlows(projectStatusItemIds)));
// @@校验 NOT_FOUND 异常 // @@校验 NOT_FOUND 异常
assertErrorCode(this.requestGet(STATUS_DELETE, "1111"), NOT_FOUND); assertErrorCode(this.requestGet(STATUS_DELETE, "1111"), NOT_FOUND);
@ -430,7 +522,7 @@ public class OrganizationStatusFlowSettingControllerTest extends BaseTest {
public static void assertSortStatusItem(String scopeId, List<String> statusIds) { public static void assertSortStatusItem(String scopeId, List<String> statusIds) {
BaseStatusItemService baseStatusItemService = CommonBeanFactory.getBean(BaseStatusItemService.class); BaseStatusItemService baseStatusItemService = CommonBeanFactory.getBean(BaseStatusItemService.class);
List<StatusItem> statusItems = baseStatusItemService.getByScopeId(scopeId); List<StatusItem> statusItems = baseStatusItemService.getByScopeIdAndScene(scopeId, TemplateScene.BUG.name());
for (int i = 0; i < statusIds.size(); i++) { for (int i = 0; i < statusIds.size(); i++) {
String statusId = statusIds.get(i); String statusId = statusIds.get(i);
// 根据statusId 查询 // 根据statusId 查询

View File

@ -1,37 +1,16 @@
package io.metersphere.system.controller.param; package io.metersphere.system.controller.param;
import io.metersphere.sdk.constants.TemplateScene;
import io.metersphere.system.valid.EnumValue;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
@Data @Data
public class StatusDefinitionUpdateRequestDefinition implements Serializable { public class StatusDefinitionUpdateRequestDefinition implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Schema(description = "组织ID或项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank
@Size(min = 1, max = 50)
private String scopeId;
@Schema(description = "使用场景", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank
@EnumValue(enumClass = TemplateScene.class)
private String scene;
@NotBlank
@Valid
private List<StatusDefinitionRequestStatusDefinition> statusDefinitions;
@Data
public static class StatusDefinitionRequestStatusDefinition implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "状态ID", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "状态ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{status_definition.status_id.not_blank}") @NotBlank(message = "{status_definition.status_id.not_blank}")
@Size(min = 1, max = 50, message = "{status_definition.status_id.length_range}") @Size(min = 1, max = 50, message = "{status_definition.status_id.length_range}")
@ -41,5 +20,8 @@ public class StatusDefinitionUpdateRequestDefinition implements Serializable {
@NotBlank(message = "{status_definition.definition_id.not_blank}") @NotBlank(message = "{status_definition.definition_id.not_blank}")
@Size(min = 1, max = 100, message = "{status_definition.definition_id.length_range}") @Size(min = 1, max = 100, message = "{status_definition.definition_id.length_range}")
private String definitionId; private String definitionId;
}
@Schema(description = "启用或者禁用", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull
private Boolean enable;
} }

View File

@ -1,38 +1,17 @@
package io.metersphere.system.controller.param; package io.metersphere.system.controller.param;
import io.metersphere.sdk.constants.TemplateScene;
import io.metersphere.system.valid.EnumValue;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
@Data @Data
public class StatusFlowUpdateRequestDefinition implements Serializable { public class StatusFlowUpdateRequestDefinition implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Schema(description = "组织ID或项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank
@Size(min = 1, max = 50)
private String scopeId;
@Schema(description = "使用场景", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{status_item.scene.not_blank}")
@EnumValue(enumClass = TemplateScene.class)
private String scene;
@NotBlank
@Valid
private List<StatusFlowRequestDefinition> statusFlows;
@Data
public static class StatusFlowRequestDefinition implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "起始状态ID", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "起始状态ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{status_flow.from_id.not_blank}") @NotBlank(message = "{status_flow.from_id.not_blank}")
@Size(min = 1, max = 50, message = "{status_flow.from_id.length_range}") @Size(min = 1, max = 50, message = "{status_flow.from_id.length_range}")
@ -42,5 +21,8 @@ public class StatusFlowUpdateRequestDefinition implements Serializable {
@NotBlank(message = "{status_flow.to_id.not_blank}") @NotBlank(message = "{status_flow.to_id.not_blank}")
@Size(min = 1, max = 50, message = "{status_flow.to_id.length_range}") @Size(min = 1, max = 50, message = "{status_flow.to_id.length_range}")
private String toId; private String toId;
}
@Schema(description = "启用或者禁用", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull
private Boolean enable;
} }