diff --git a/backend/framework/sdk/src/main/resources/i18n/commons.properties b/backend/framework/sdk/src/main/resources/i18n/commons.properties index 1f673ab77c..bb93cd98d9 100644 --- a/backend/framework/sdk/src/main/resources/i18n/commons.properties +++ b/backend/framework/sdk/src/main/resources/i18n/commons.properties @@ -556,4 +556,6 @@ test_plan=测试计划 ID internal_user_view_permission_error=系统视图无法删除! user_view.all_data=全部数据 user_view.my_follow=我关注的 -user_view.my_create=我创建的 \ No newline at end of file +user_view.my_create=我创建的 +user_view.my_review=我评审的 +user_view_exist=视图已存在 \ No newline at end of file diff --git a/backend/framework/sdk/src/main/resources/i18n/commons_en_US.properties b/backend/framework/sdk/src/main/resources/i18n/commons_en_US.properties index b4cece61bb..afcda0260d 100644 --- a/backend/framework/sdk/src/main/resources/i18n/commons_en_US.properties +++ b/backend/framework/sdk/src/main/resources/i18n/commons_en_US.properties @@ -594,4 +594,6 @@ test_plan=Test Plan ID internal_user_view_permission_error=System views cannot be deleted! user_view.all_data=All data user_view.my_follow=I followed -user_view.my_create=I created \ No newline at end of file +user_view.my_create=I created +user_view.my_review=I review +user_view_exist=The view already exists \ No newline at end of file diff --git a/backend/framework/sdk/src/main/resources/i18n/commons_zh_CN.properties b/backend/framework/sdk/src/main/resources/i18n/commons_zh_CN.properties index 3d8a85536c..d7b2e6d252 100644 --- a/backend/framework/sdk/src/main/resources/i18n/commons_zh_CN.properties +++ b/backend/framework/sdk/src/main/resources/i18n/commons_zh_CN.properties @@ -589,4 +589,6 @@ test_plan=测试计划 ID internal_user_view_permission_error=系统视图无法删除! user_view.all_data=全部数据 user_view.my_follow=我关注的 -user_view.my_create=我创建的 \ No newline at end of file +user_view.my_create=我创建的 +user_view.my_review=我评审的 +user_view_exist=视图已存在 \ No newline at end of file diff --git a/backend/framework/sdk/src/main/resources/i18n/commons_zh_TW.properties b/backend/framework/sdk/src/main/resources/i18n/commons_zh_TW.properties index 685fbb4a4b..acb6d472c7 100644 --- a/backend/framework/sdk/src/main/resources/i18n/commons_zh_TW.properties +++ b/backend/framework/sdk/src/main/resources/i18n/commons_zh_TW.properties @@ -589,4 +589,6 @@ test_plan=測試計劃 ID internal_user_view_permission_error=系統視圖無法刪除! user_view.all_data=全部數據 user_view.my_follow=我關注的 -user_view.my_create=我創建的 \ No newline at end of file +user_view.my_create=我創建的 +user_view.my_review=我評審的 +user_view_exist=視圖已存在 \ No newline at end of file diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/constants/InternalUserView.java b/backend/services/system-setting/src/main/java/io/metersphere/system/constants/InternalUserView.java index 7d01cd9b81..306cef410d 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/constants/InternalUserView.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/constants/InternalUserView.java @@ -22,7 +22,7 @@ public enum InternalUserView { CombineCondition condition = new CombineCondition(); condition.setName("follower"); condition.setValue(getCurrentUserValue()); - condition.setOperator(CombineCondition.CombineConditionOperator.EQUALS.name()); + condition.setOperator(CombineCondition.CombineConditionOperator.IN.name()); userViewDTO.setConditions(List.of(condition)); return userViewDTO; }), @@ -31,7 +31,16 @@ public enum InternalUserView { CombineCondition condition = new CombineCondition(); condition.setName("create_user"); condition.setValue(getCurrentUserValue()); - condition.setOperator(CombineCondition.CombineConditionOperator.EQUALS.name()); + condition.setOperator(CombineCondition.CombineConditionOperator.IN.name()); + userViewDTO.setConditions(List.of(condition)); + return userViewDTO; + }), + MY_REVIEW(() -> { + UserViewDTO userViewDTO = getUserViewDTO("my_review"); + CombineCondition condition = new CombineCondition(); + condition.setName("review_user"); + condition.setValue(getCurrentUserValue()); + condition.setOperator(CombineCondition.CombineConditionOperator.IN.name()); userViewDTO.setConditions(List.of(condition)); return userViewDTO; }); diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/constants/UserViewType.java b/backend/services/system-setting/src/main/java/io/metersphere/system/constants/UserViewType.java index ac0b8744b8..1f2a4358af 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/constants/UserViewType.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/constants/UserViewType.java @@ -8,11 +8,19 @@ import java.util.List; /** * @Author: jianxing * @CreateTime: 2024-09-02 10:47 + * + * 视图的类型 + * 例如:功能用例视图 + * */ public enum UserViewType implements ValueEnum { FUNCTIONAL_CASE("functional-case", List.of(InternalUserView.ALL_DATA, InternalUserView.MY_FOLLOW, InternalUserView.MY_CREATE)), + REVIEW_FUNCTIONAL_CASE("review-functional-case", + List.of(InternalUserView.ALL_DATA, InternalUserView.MY_REVIEW, InternalUserView.MY_CREATE)), + API_DEFINITION("api-definition", + List.of(InternalUserView.ALL_DATA, InternalUserView.MY_FOLLOW, InternalUserView.MY_CREATE)), ; private String value; diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/controller/result/SystemResultCode.java b/backend/services/system-setting/src/main/java/io/metersphere/system/controller/result/SystemResultCode.java index 28908860c7..88f86d956b 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/controller/result/SystemResultCode.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/controller/result/SystemResultCode.java @@ -32,7 +32,8 @@ public enum SystemResultCode implements IResultCode { PLUGIN_SCRIPT_FORMAT(101011, "plugin.script.format"), NO_PROJECT_USER_ROLE_PERMISSION(101012, "project_user_role_permission_error"), NO_GLOBAL_USER_ROLE_PERMISSION(101013, "no_global_user_role_permission_error"), - PLUGIN_PARSE_ERROR(101014, "plugin.parse.error"); + PLUGIN_PARSE_ERROR(101014, "plugin.parse.error"), + USER_VIEW_EXIST(101015, "user_view_exist"),; private final int code; private final String message; diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/service/UserViewService.java b/backend/services/system-setting/src/main/java/io/metersphere/system/service/UserViewService.java index b43604b63f..903325af72 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/service/UserViewService.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/service/UserViewService.java @@ -23,6 +23,7 @@ import io.metersphere.system.mapper.UserViewConditionMapper; import io.metersphere.system.mapper.UserViewMapper; import io.metersphere.system.uid.IDGenerator; import jakarta.annotation.Resource; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -31,6 +32,8 @@ import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; +import static io.metersphere.system.controller.result.SystemResultCode.USER_VIEW_EXIST; + /** * @Author: jianxing * @CreateTime: 2024-08-30 14:30 @@ -90,6 +93,7 @@ public class UserViewService { } public UserViewDTO add(UserViewAddRequest request, String viewType, String userId) { + checkAddExist(request, viewType, userId); Long nextPos = getNextPos(request.getScopeId(), userId, viewType); UserView userView = BeanUtils.copyBean(new UserView(), request); userView.setCreateTime(System.currentTimeMillis()); @@ -113,6 +117,33 @@ public class UserViewService { return userViewDTO; } + private void checkAddExist(UserViewAddRequest request, String viewType, String userId) { + UserViewExample example = new UserViewExample(); + example.createCriteria() + .andUserIdEqualTo(userId) + .andScopeIdEqualTo(request.getScopeId()) + .andViewTypeEqualTo(viewType) + .andNameEqualTo(request.getName()); + if (userViewMapper.countByExample(example) > 0) { + throw new MSException(USER_VIEW_EXIST); + } + } + + private void checkUpdateExist(String name, String scopeId, String viewType, String userId) { + if (StringUtils.isBlank(name)) { + return; + } + UserViewExample example = new UserViewExample(); + example.createCriteria() + .andUserIdEqualTo(userId) + .andScopeIdEqualTo(scopeId) + .andViewTypeEqualTo(viewType) + .andNameEqualTo(name); + if (userViewMapper.countByExample(example) > 0) { + throw new MSException(USER_VIEW_EXIST); + } + } + public Long getNextPos(String scopeId, String userId, String viewType) { Long pos = extUserViewMapper.getLastPos(scopeId, userId, viewType, null); return (pos == null ? 0 : pos) + POS_STEP; @@ -133,6 +164,9 @@ public class UserViewService { } private void addUserViewConditions(List conditions, UserView userView) { + if (CollectionUtils.isEmpty(conditions)) { + return; + } List insertConditions = conditions.stream().map(condition -> { UserViewCondition userViewCondition = BeanUtils.copyBean(new UserViewCondition(), condition); userViewCondition.setId(IDGenerator.nextStr()); @@ -187,16 +221,19 @@ public class UserViewService { UserView originUserView = userViewMapper.selectByPrimaryKey(request.getId()); // 校验权限,只能修改自己的视图 checkOwner(userId, originUserView); + checkUpdateExist(request.getName(), originUserView.getScopeId(), viewType, userId); UserView userView = BeanUtils.copyBean(new UserView(), request); userView.setViewType(viewType); userView.setUpdateTime(System.currentTimeMillis()); userViewMapper.updateByPrimaryKeySelective(userView); - // 先删除 - deleteConditionsByViewId(originUserView.getId()); - // 再新增 - addUserViewConditions(request.getConditions(), userView); + if (request.getConditions() != null) { + // 先删除 + deleteConditionsByViewId(originUserView.getId()); + // 再新增 + addUserViewConditions(request.getConditions(), userView); + } UserViewDTO userViewDTO = BeanUtils.copyBean(new UserViewDTO(), request); userViewDTO.setId(originUserView.getId()); diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/UserViewControllerTests.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/UserViewControllerTests.java index f6a2ad855a..ccb37261c8 100644 --- a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/UserViewControllerTests.java +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/UserViewControllerTests.java @@ -23,6 +23,8 @@ import org.springframework.test.web.servlet.MvcResult; import java.util.List; import java.util.UUID; +import static io.metersphere.system.controller.result.SystemResultCode.USER_VIEW_EXIST; + @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @AutoConfigureMockMvc @TestMethodOrder(MethodOrderer.OrderAnnotation.class) @@ -33,6 +35,7 @@ public class UserViewControllerTests extends BaseTest { private final String GROUPED_LIST = "grouped/list?scopeId={0}"; private static UserViewDTO addUserViewDTO; + private static UserViewDTO anotherAddUserViewDTO; @Resource private UserViewService userViewService; @@ -117,6 +120,14 @@ public class UserViewControllerTests extends BaseTest { UserViewDTO userViewDTO = userViewService.get(addUserViewDTO.getId(), UserViewType.FUNCTIONAL_CASE, InternalUser.ADMIN.getValue()); Assertions.assertEquals(request, BeanUtils.copyBean(new UserViewAddRequest(), userViewDTO)); Assertions.assertEquals(request.getConditions(), userViewDTO.getConditions()); + + // @@重名校验异常 + assertErrorCode(this.requestPost(DEFAULT_ADD, request), USER_VIEW_EXIST); + + request.setName(UUID.randomUUID().toString()); + request.setConditions(null); + mvcResult = this.requestPostWithOkAndReturn(DEFAULT_ADD, request); + anotherAddUserViewDTO = getResultData(mvcResult, UserViewDTO.class); } @Test @@ -134,6 +145,13 @@ public class UserViewControllerTests extends BaseTest { UserViewDTO userViewDTO = userViewService.get(addUserViewDTO.getId(), UserViewType.FUNCTIONAL_CASE, InternalUser.ADMIN.getValue()); Assertions.assertEquals(request, BeanUtils.copyBean(new UserViewUpdateRequest(), userViewDTO)); Assertions.assertEquals(request.getConditions(), userViewDTO.getConditions()); + + // @@ Conditions 为 null + request.setId(anotherAddUserViewDTO.getId()); + assertErrorCode(this.requestPost(DEFAULT_UPDATE, request), USER_VIEW_EXIST); + request.setName(UUID.randomUUID().toString()); + request.setConditions(null); + this.requestPostWithOkAndReturn(DEFAULT_UPDATE, request); } @Test @@ -160,7 +178,7 @@ public class UserViewControllerTests extends BaseTest { MvcResult mvcResult = this.requestGetWithOkAndReturn(GROUPED_LIST, DEFAULT_PROJECT_ID); UserViewListGroupedDTO result = getResultData(mvcResult, UserViewListGroupedDTO.class); Assertions.assertEquals(result.getInternalViews().size(), 3); - Assertions.assertEquals(result.getCustomViews().size(), 1); + Assertions.assertEquals(result.getCustomViews().size(), 2); Assertions.assertEquals(result.getCustomViews().get(0), BeanUtils.copyBean(new UserViewListDTO(), addUserViewDTO)); }