diff --git a/backend/framework/domain/src/main/java/io/metersphere/system/domain/User.java b/backend/framework/domain/src/main/java/io/metersphere/system/domain/User.java index 9a840d0456..318d310dde 100644 --- a/backend/framework/domain/src/main/java/io/metersphere/system/domain/User.java +++ b/backend/framework/domain/src/main/java/io/metersphere/system/domain/User.java @@ -1,15 +1,20 @@ package io.metersphere.system.domain; -import io.metersphere.validation.groups.*; +import io.metersphere.validation.groups.Created; +import io.metersphere.validation.groups.Updated; import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.*; -import java.io.Serializable; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import lombok.Data; +import java.io.Serializable; + @Data public class User implements Serializable { @Schema(title = "用户ID", requiredMode = Schema.RequiredMode.REQUIRED) - @NotBlank(message = "{user.id.not_blank}", groups = {Created.class, Updated.class}) + @NotBlank(message = "{user.id.not_blank}", groups = {Updated.class}) @Size(min = 1, max = 50, message = "{user.id.length_range}", groups = {Created.class, Updated.class}) private String id; @@ -19,15 +24,16 @@ public class User implements Serializable { private String name; @Schema(title = "用户邮箱", requiredMode = Schema.RequiredMode.REQUIRED) - @NotBlank(message = "{user.email.not_blank}", groups = {Created.class}) + @NotBlank(message = "{user.email.not_blank}", groups = {Created.class, Updated.class}) @Size(min = 1, max = 64, message = "{user.email.length_range}", groups = {Created.class, Updated.class}) + @Email(message = "{user.email.invalid}", groups = {Created.class, Updated.class}) private String email; @Schema(title = "用户密码") private String password; @Schema(title = "是否启用", requiredMode = Schema.RequiredMode.REQUIRED) - @NotNull(message = "{user.enable.not_blank}", groups = {Created.class}) + @NotNull(message = "{user.enable.not_blank}", groups = {Updated.class}) private Boolean enable; @Schema(title = "创建时间") diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/controller/LoginController.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/controller/LoginController.java index 1040af852e..4326b08d77 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/controller/LoginController.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/controller/LoginController.java @@ -48,9 +48,7 @@ public class LoginController { } return ResultHolder.success(sessionUser); } - MSException.throwException(rsaKey.getPublicKey()); - // - return null; + throw new MSException(rsaKey.getPublicKey()); } @PostMapping(value = "/login") @@ -58,7 +56,7 @@ public class LoginController { SessionUser sessionUser = SessionUtils.getUser(); if (sessionUser != null) { if (!StringUtils.equals(sessionUser.getId(), request.getUsername())) { - MSException.throwException(Translator.get("please_logout_current_user")); + throw new MSException(Translator.get("please_logout_current_user")); } } SecurityUtils.getSubject().getSession().setAttribute("authenticate", UserSource.LOCAL.name()); diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/exception/MSException.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/exception/MSException.java index 2d95824f11..f191c7ec8f 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/exception/MSException.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/exception/MSException.java @@ -11,36 +11,26 @@ public class MSException extends RuntimeException { super(message); } + public MSException(IResultCode errorCode) { + super(StringUtils.EMPTY); + this.errorCode = errorCode; + } + public MSException(IResultCode errorCode, String message) { super(message); this.errorCode = errorCode; } + + public static void throwException(IResultCode errorCode, String message) { + throw new MSException(errorCode, message); + } + public MSException(IResultCode errorCode, Throwable t) { super(t); this.errorCode = errorCode; } - public static void throwException(String message) { - throw new MSException(message); - } - - public static void throwException(Throwable t) { - throw new MSException(null, t); - } - - public static void throwException(IResultCode errorCode) { - throw new MSException(errorCode, StringUtils.EMPTY); - } - - public static void throwException(IResultCode errorCode, String message) { - throw new MSException(errorCode, message); - } - - public static void throwException(IResultCode errorCode, Throwable t) { - throw new MSException(errorCode, t); - } - public IResultCode getErrorCode() { return errorCode; } diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/mapper/BaseUserMapper.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/mapper/BaseUserMapper.java index 3650d71010..9965822864 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/mapper/BaseUserMapper.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/mapper/BaseUserMapper.java @@ -7,6 +7,8 @@ import org.apache.ibatis.annotations.Param; import java.util.List; public interface BaseUserMapper { + UserDTO selectByEmail(String email); + UserDTO selectById(String id); List findAll(); @@ -14,4 +16,8 @@ public interface BaseUserMapper { void batchSave(@Param("users") List users); boolean isSuperUser(String userId); + + String selectEmailInDB(@Param("email") String email, @Param("id") String id); + + List selectUserIdByEmailList(@Param("emailList") List emailList); } diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/mapper/BaseUserMapper.xml b/backend/framework/sdk/src/main/java/io/metersphere/sdk/mapper/BaseUserMapper.xml index 5cb7dd9adc..b53b6fc480 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/mapper/BaseUserMapper.xml +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/mapper/BaseUserMapper.xml @@ -8,6 +8,13 @@ WHERE user.id = #{id} + + + + \ No newline at end of file diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/plugin/loader/PluginManager.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/plugin/loader/PluginManager.java index df0e0c5b65..f48c922ba7 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/plugin/loader/PluginManager.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/plugin/loader/PluginManager.java @@ -30,9 +30,8 @@ public class PluginManager { /** * 加载对应目录下的 jar 包 - * */ - public PluginManager loadJar(String pluginId, String jarfileDir, StorageStrategy storageStrategy) throws IOException { + public PluginManager loadJar(String pluginId, String jarfileDir, StorageStrategy storageStrategy) throws IOException { PluginClassLoader pluginClassLoader = new PluginClassLoader(storageStrategy); classLoaderMap.put(pluginId, pluginClassLoader); pluginClassLoader.loadJar(jarfileDir); @@ -91,12 +90,11 @@ public class PluginManager { return clazz.getConstructor().newInstance(); } catch (InvocationTargetException e) { LogUtils.error(e); - MSException.throwException(CommonResultCode.PLUGIN_GET_INSTANCE, e.getTargetException().getMessage()); + throw new MSException(CommonResultCode.PLUGIN_GET_INSTANCE, e.getTargetException().getMessage()); } catch (Exception e) { LogUtils.error(e); - MSException.throwException(CommonResultCode.PLUGIN_GET_INSTANCE, e.getMessage()); + throw new MSException(CommonResultCode.PLUGIN_GET_INSTANCE, e.getMessage()); } - return null; } public T getImplInstance(String pluginId, Class superClazz, Object param) { @@ -105,12 +103,11 @@ public class PluginManager { return clazz.getConstructor(param.getClass()).newInstance(param); } catch (InvocationTargetException e) { LogUtils.error(e.getTargetException()); - MSException.throwException(CommonResultCode.PLUGIN_GET_INSTANCE, e.getTargetException().getMessage()); + throw new MSException(CommonResultCode.PLUGIN_GET_INSTANCE, e.getTargetException().getMessage()); } catch (Exception e) { LogUtils.error(e); - MSException.throwException(CommonResultCode.PLUGIN_GET_INSTANCE, e.getMessage()); + throw new MSException(CommonResultCode.PLUGIN_GET_INSTANCE, e.getMessage()); } - return null; } diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/service/BaseUserService.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/service/BaseUserService.java index 08bd248705..136687c97a 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/service/BaseUserService.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/service/BaseUserService.java @@ -291,7 +291,7 @@ public class BaseUserService { criteria.andEmailEqualTo(user.getEmail()); criteria.andIdNotEqualTo(user.getId()); if (userMapper.countByExample(example) > 0) { - MSException.throwException(Translator.get("user_email_already_exists")); + throw new MSException(Translator.get("user_email_already_exists")); } } user.setPassword(null); @@ -358,10 +358,10 @@ public class BaseUserService { public boolean checkUserPassword(String userId, String password) { if (StringUtils.isBlank(userId)) { - MSException.throwException(Translator.get("user_name_is_null")); + throw new MSException(Translator.get("user_name_is_null")); } if (StringUtils.isBlank(password)) { - MSException.throwException(Translator.get("password_is_null")); + throw new MSException(Translator.get("password_is_null")); } UserExample example = new UserExample(); example.createCriteria().andIdEqualTo(userId).andPasswordEqualTo(CodingUtil.md5(password)); diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/service/UserKeyService.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/service/UserKeyService.java index ce6430abad..4ee023166d 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/service/UserKeyService.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/service/UserKeyService.java @@ -34,14 +34,14 @@ public class UserKeyService { public UserKey generateUserKey(String userId) { if (baseUserService.getUserDTO(userId) == null) { - MSException.throwException(Translator.get("user_not_exist") + userId); + throw new MSException(Translator.get("user_not_exist") + userId); } UserKeyExample userKeysExample = new UserKeyExample(); userKeysExample.createCriteria().andCreateUserEqualTo(userId); List userKeysList = userKeyMapper.selectByExample(userKeysExample); if (!CollectionUtils.isEmpty(userKeysList) && userKeysList.size() >= 5) { - MSException.throwException(Translator.get("user_apikey_limit")); + throw new MSException(Translator.get("user_apikey_limit")); } UserKey userKeys = new UserKey(); diff --git a/backend/framework/sdk/src/main/resources/i18n/system_en_US.properties b/backend/framework/sdk/src/main/resources/i18n/system_en_US.properties index 61a4da3c54..63e8a5c91a 100644 --- a/backend/framework/sdk/src/main/resources/i18n/system_en_US.properties +++ b/backend/framework/sdk/src/main/resources/i18n/system_en_US.properties @@ -1,3 +1,4 @@ +user.not.login=User not login auth_source.id.not_blank=Auth source id must not be blank auth_source.status.length_range=Auth source status must be between {min} and {max} characters long auth_source.status.not_blank=Auth source status must not be blank @@ -95,6 +96,8 @@ user.name.not_blank=User name must not be blank user.name.length_range=User name must be between {min} and {max} characters long user.email.not_blank=User email must not be blank user.email.length_range=User email must be between {min} and {max} characters long +user.email.repeat=User email already exists +user.email.invalid=User email is invalid user.status.not_blank=User status must not be blank user.status.length_range=User status must be between {min} and {max} characters long user.source.not_blank=User source must not be blank @@ -109,6 +112,9 @@ user_key.access_key.not_blank=User key access key must not be blank user_key.access_key.length_range=User key access key must be between {min} and {max} characters long user_key.secret_key.not_blank=User key secret key must not be blank user_key.secret_key.length_range=User key secret key must be between {min} and {max} characters long +user.info.not_empty=User info must not be blank +user.organizationId.not_blank=User organization must not be blank +user.projectId.not_blank=User project must not be blank user_role.id.not_blank=User role id must not be blank user_role.name.not_blank=User role name must not be blank user_role.name.length_range=User role name must be between {min} and {max} characters long diff --git a/backend/framework/sdk/src/main/resources/i18n/system_zh_CN.properties b/backend/framework/sdk/src/main/resources/i18n/system_zh_CN.properties index c120a4b462..4abcfd49ff 100644 --- a/backend/framework/sdk/src/main/resources/i18n/system_zh_CN.properties +++ b/backend/framework/sdk/src/main/resources/i18n/system_zh_CN.properties @@ -1,143 +1,149 @@ -auth_source.id.not_blank=认证源ID不能为空 -auth_source.status.length_range=认证源状态长度必须在{min}和{max}之间 -auth_source.status.not_blank=认证源状态不能为空 -license.id.not_blank=License ID不能为空 -message_task.id.not_blank=消息通知任务ID不能为空 -message_task.type.not_blank=消息通知任务类型不能为空 -message_task.type.length_range=消息通知任务类型长度必须在{min}和{max}之间 -message_task.event.not_blank=消息通知任务事件不能为空 -message_task.event.length_range=消息通知任务事件长度必须在{min}和{max}之间 -message_task.receiver.not_blank=消息通知任务接收者不能为空 -message_task.receiver.length_range=消息通知任务接收者长度必须在{min}和{max}之间 -message_task.task_type.not_blank=消息通知任务任务类型不能为空 -message_task.task_type.length_range=消息通知任务任务类型长度必须在{min}和{max}之间 -message_task.test_id.not_blank=消息通知任务测试ID不能为空 -message_task.test_id.length_range=消息通知任务测试ID长度必须在{min}和{max}之间 -message_task.project_id.not_blank=消息通知任务项目ID不能为空 -message_task.project_id.length_range=消息通知任务项目ID长度必须在{min}和{max}之间 -message_task_blob.id.not_blank=消息通知任务ID不能为空 -notification.id.not_blank=消息通知ID不能为空 -notification.type.not_blank=消息通知类型不能为空 -notification.type.length_range=消息通知类型长度必须在{min}和{max}之间 -notification.receiver.not_blank=消息通知接收者不能为空 -notification.receiver.length_range=消息通知接收者长度必须在{min}和{max}之间 -notification.title.not_blank=消息通知标题不能为空 -notification.title.length_range=消息通知标题长度必须在{min}和{max}之间 -notification.status.not_blank=消息通知状态不能为空 -notification.status.length_range=消息通知状态长度必须在{min}和{max}之间 -notification.operator.not_blank=消息通知操作者不能为空 -notification.operator.length_range=消息通知操作者长度必须在{min}和{max}之间 -notification.operation.not_blank=消息通知操作不能为空 -notification.operation.length_range=消息通知操作长度必须在{min}和{max}之间 -notification.resource_id.not_blank=消息通知资源ID不能为空 -notification.resource_id.length_range=消息通知资源ID长度必须在{min}和{max}之间 -notification.resource_type.not_blank=消息通知资源类型不能为空 -notification.resource_type.length_range=消息通知资源类型长度必须在{min}和{max}之间 -notification.resource_name.not_blank=消息通知资源名称不能为空 -notification.resource_name.length_range=消息通知资源名称长度必须在{min}和{max}之间 -novice_statistics.id.not_blank=新手村ID不能为空 -novice_statistics.guide_step.not_blank=新手村步骤不能为空 -novice_statistics.guide_step.length_range=新手村步骤长度必须在{min}和{max}之间 -operating_log.id.not_blank=操作日志ID不能为空 -operating_log.project_id.not_blank=操作日志项目ID不能为空 -operating_log.project_id.length_range=操作日志项目ID长度必须在{min}和{max}之间 -operating_log_resource.id.not_blank=操作日志资源ID不能为空 -operating_log_resource.operating_log_id.not_blank=操作日志资源操作日志ID不能为空 -operating_log_resource.operating_log_id.length_range=操作日志资源操作日志ID长度必须在{min}和{max}之间 -operating_log_resource.source_id.not_blank=操作日志资源来源ID不能为空 -operating_log_resource.source_id.length_range=操作日志资源来源ID长度必须在{min}和{max}之间 -plugin.id.not_blank=插件主键不能为空 -plugin.plugin_id.not_blank=插件ID不能为空 -plugin.plugin_id.length_range=插件ID长度必须在{min}和{max}之间 -plugin.script_id.not_blank=插件脚本ID不能为空 -plugin.script_id.length_range=插件脚本ID长度必须在{min}和{max}之间 -plugin.clazz_name.not_blank=插件类名不能为空 -plugin.clazz_name.length_range=插件类名长度必须在{min}和{max}之间 -plugin.jmeter_clazz.not_blank=插件jmeter类名不能为空 -plugin.jmeter_clazz.length_range=插件jmeter类名长度必须在{min}和{max}之间 -plugin.source_path.not_blank=插件源路径不能为空 -plugin.source_path.length_range=插件源路径长度必须在{min}和{max}之间 -plugin.source_name.not_blank=插件源名称不能为空 -plugin.source_name.length_range=插件源名称长度必须在{min}和{max}之间 -plugin.scenario.not_blank=插件场景不能为空 -plugin.scenario.length_range=插件场景长度必须在{min}和{max}之间 -plugin_blob.id.not_blank=插件ID不能为空 -quota.id.not_blank=配额ID不能为空 -schedule.id.not_blank=定时任务ID不能为空 -schedule.type.not_blank=定时任务类型不能为空 -schedule.type.length_range=定时任务类型长度必须在{min}和{max}之间 -schedule.value.not_blank=定时任务值不能为空 -schedule.value.length_range=定时任务值长度必须在{min}和{max}之间 -schedule.job.not_blank=定时任务不能为空 -schedule.job.length_range=定时任务长度必须在{min}和{max}之间 -schedule.create_user.not_blank=定时任务创建人不能为空 -schedule.create_user.length_range=定时任务创建人长度必须在{min}和{max}之间 -service_integration.id.not_blank=服务集成ID不能为空 -service_integration.platform.not_blank=服务集成平台不能为空 -service_integration.platform.length_range=服务集成平台长度必须在{min}和{max}之间 -system_parameter.param_key.not_blank=系统参数Key不能为空 -system_parameter.type.not_blank=系统参数类型不能为空 -system_parameter.type.length_range=系统参数类型长度必须在{min}和{max}之间 -test_resource.id.not_blank=资源池节点ID不能为空 -test_resource.test_resource_pool_id.not_blank=资源池ID不能为空 -test_resource.test_resource_pool_id.length_range=资源池ID长度必须在{min}和{max}之间 -test_resource.status.not_blank=资源池节点状态不能为空 -test_resource.status.length_range=资源池节点状态长度必须在{min}和{max}之间 -test_resource_pool.id.not_blank=资源池ID不能为空 -test_resource_pool.name.not_blank=资源池名称不能为空 -test_resource_pool.name.length_range=资源池名称长度必须在{min}和{max}之间 -test_resource_pool.type.not_blank=资源池类型不能为空 -test_resource_pool.type.length_range=资源池类型长度必须在{min}和{max}之间 -test_resource_pool.status.not_blank=资源池状态不能为空 -test_resource_pool.status.length_range=资源池状态长度必须在{min}和{max}之间 -user.id.not_blank=用户ID不能为空 -user.name.not_blank=用户名称不能为空 -user.name.length_range=用户名称长度必须在{min}和{max}之间 -user.email.not_blank=用户email不能为空 -user.email.length_range=用户email长度必须在{min}和{max}之间 -user.status.not_blank=用户状态不能为空 -user.status.length_range=用户状态长度必须在{min}和{max}之间 -user.source.not_blank=用户来源不能为空 -user.source.length_range=用户来源长度必须在{min}和{max}之间 -user.create_user.not_blank=用户创建人不能为空 -user.create_user.length_range=用户创建人长度必须在{min}和{max}之间 -user_extend.id.not_blank=用户ID不能为空 -user_key.id.not_blank=用户ApiKey ID不能为空 -user_key.create_user.not_blank=用户ApiKey创建人不能为空 -user_key.create_user.length_range=用户ApiKey创建人长度必须在{min}和{max}之间 -user_key.access_key.not_blank=用户ApiKey access key不能为空 -user_key.access_key.length_range=用户ApiKey access key长度必须在{min}和{max}之间 -user_key.secret_key.not_blank=用户ApiKey secret key不能为空 -user_key.secret_key.length_range=用户ApiKey secret key长度必须在{min}和{max}之间 -user_role.id.not_blank=用户组ID不能为空 -user_role.name.not_blank=用户组名称不能为空 -user_role.name.length_range=用户组名称长度必须在{min}和{max}之间 -user_role.system.not_blank=是否是系统用户组不能为空 -user_role.system.length_range=是否是系统用户组长度必须在{min}和{max}之间 -user_role.type.not_blank=用户组类型不能为空 -user_role.type.length_range=用户组类型长度必须在{min}和{max}之间 -user_role.create_user.not_blank=用户组创建人不能为空 -user_role.create_user.length_range=用户组创建人长度必须在{min}和{max}之间 -user_role.scope_id.not_blank=用户组应用范围不能为空 -user_role.scope_id.length_range=用户组应用范围长度必须在{min}和{max}之间 -user_role_permission.id.not_blank=用户组权限ID不能为空 -user_role_permission.role_id.not_blank=用户组权限用户组ID不能为空 -user_role_permission.role_id.length_range=用户组权限用户组ID长度必须在{min}和{max}之间 -user_role_permission.permission_id.not_blank=用户组权限权限ID不能为空 -user_role_permission.permission_id.length_range=用户组权限权限ID长度必须在{min}和{max}之间 -user_role_permission.module_id.not_blank=用户组权限模块ID不能为空 -user_role_permission.module_id.length_range=用户组权限模块ID长度必须在{min}和{max}之间 -user_role_relation.id.not_blank=用户组关系ID不能为空 -user_role_relation.user_id.not_blank=用户组关系用户ID不能为空 -user_role_relation.user_id.length_range=用户组关系用户ID长度必须在{min}和{max}之间 -user_role_relation.role_id.not_blank=用户组关系用户组ID不能为空 -user_role_relation.role_id.length_range=用户组关系用户组ID长度必须在{min}和{max}之间 -user_role_relation.source_id.not_blank=用户组关系来源ID不能为空 -user_role_relation.source_id.length_range=用户组关系来源ID长度必须在{min}和{max}之间 -organization.id.not_blank=工作空间ID不能为空 -organization.name.not_blank=工作空间名称不能为空 -organization.name.length_range=工作空间名称长度必须在{min}和{max}之间 -organization.create_user.not_blank=工作空间创建人不能为空 -organization.create_user.length_range=工作空间创建人长度必须在{min}和{max}之间 +user.not.login=\u672A\u83B7\u53D6\u5230\u767B\u5F55\u7528\u6237 +auth_source.id.not_blank=\u8BA4\u8BC1\u6E90ID\u4E0D\u80FD\u4E3A\u7A7A +auth_source.status.length_range=\u8BA4\u8BC1\u6E90\u72B6\u6001\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +auth_source.status.not_blank=\u8BA4\u8BC1\u6E90\u72B6\u6001\u4E0D\u80FD\u4E3A\u7A7A +license.id.not_blank=License ID\u4E0D\u80FD\u4E3A\u7A7A +message_task.id.not_blank=\u6D88\u606F\u901A\u77E5\u4EFB\u52A1ID\u4E0D\u80FD\u4E3A\u7A7A +message_task.type.not_blank=\u6D88\u606F\u901A\u77E5\u4EFB\u52A1\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A +message_task.type.length_range=\u6D88\u606F\u901A\u77E5\u4EFB\u52A1\u7C7B\u578B\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +message_task.event.not_blank=\u6D88\u606F\u901A\u77E5\u4EFB\u52A1\u4E8B\u4EF6\u4E0D\u80FD\u4E3A\u7A7A +message_task.event.length_range=\u6D88\u606F\u901A\u77E5\u4EFB\u52A1\u4E8B\u4EF6\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +message_task.receiver.not_blank=\u6D88\u606F\u901A\u77E5\u4EFB\u52A1\u63A5\u6536\u8005\u4E0D\u80FD\u4E3A\u7A7A +message_task.receiver.length_range=\u6D88\u606F\u901A\u77E5\u4EFB\u52A1\u63A5\u6536\u8005\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +message_task.task_type.not_blank=\u6D88\u606F\u901A\u77E5\u4EFB\u52A1\u4EFB\u52A1\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A +message_task.task_type.length_range=\u6D88\u606F\u901A\u77E5\u4EFB\u52A1\u4EFB\u52A1\u7C7B\u578B\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +message_task.test_id.not_blank=\u6D88\u606F\u901A\u77E5\u4EFB\u52A1\u6D4B\u8BD5ID\u4E0D\u80FD\u4E3A\u7A7A +message_task.test_id.length_range=\u6D88\u606F\u901A\u77E5\u4EFB\u52A1\u6D4B\u8BD5ID\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +message_task.project_id.not_blank=\u6D88\u606F\u901A\u77E5\u4EFB\u52A1\u9879\u76EEID\u4E0D\u80FD\u4E3A\u7A7A +message_task.project_id.length_range=\u6D88\u606F\u901A\u77E5\u4EFB\u52A1\u9879\u76EEID\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +message_task_blob.id.not_blank=\u6D88\u606F\u901A\u77E5\u4EFB\u52A1ID\u4E0D\u80FD\u4E3A\u7A7A +notification.id.not_blank=\u6D88\u606F\u901A\u77E5ID\u4E0D\u80FD\u4E3A\u7A7A +notification.type.not_blank=\u6D88\u606F\u901A\u77E5\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A +notification.type.length_range=\u6D88\u606F\u901A\u77E5\u7C7B\u578B\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +notification.receiver.not_blank=\u6D88\u606F\u901A\u77E5\u63A5\u6536\u8005\u4E0D\u80FD\u4E3A\u7A7A +notification.receiver.length_range=\u6D88\u606F\u901A\u77E5\u63A5\u6536\u8005\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +notification.title.not_blank=\u6D88\u606F\u901A\u77E5\u6807\u9898\u4E0D\u80FD\u4E3A\u7A7A +notification.title.length_range=\u6D88\u606F\u901A\u77E5\u6807\u9898\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +notification.status.not_blank=\u6D88\u606F\u901A\u77E5\u72B6\u6001\u4E0D\u80FD\u4E3A\u7A7A +notification.status.length_range=\u6D88\u606F\u901A\u77E5\u72B6\u6001\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +notification.operator.not_blank=\u6D88\u606F\u901A\u77E5\u64CD\u4F5C\u8005\u4E0D\u80FD\u4E3A\u7A7A +notification.operator.length_range=\u6D88\u606F\u901A\u77E5\u64CD\u4F5C\u8005\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +notification.operation.not_blank=\u6D88\u606F\u901A\u77E5\u64CD\u4F5C\u4E0D\u80FD\u4E3A\u7A7A +notification.operation.length_range=\u6D88\u606F\u901A\u77E5\u64CD\u4F5C\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +notification.resource_id.not_blank=\u6D88\u606F\u901A\u77E5\u8D44\u6E90ID\u4E0D\u80FD\u4E3A\u7A7A +notification.resource_id.length_range=\u6D88\u606F\u901A\u77E5\u8D44\u6E90ID\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +notification.resource_type.not_blank=\u6D88\u606F\u901A\u77E5\u8D44\u6E90\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A +notification.resource_type.length_range=\u6D88\u606F\u901A\u77E5\u8D44\u6E90\u7C7B\u578B\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +notification.resource_name.not_blank=\u6D88\u606F\u901A\u77E5\u8D44\u6E90\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A +notification.resource_name.length_range=\u6D88\u606F\u901A\u77E5\u8D44\u6E90\u540D\u79F0\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +novice_statistics.id.not_blank=\u65B0\u624B\u6751ID\u4E0D\u80FD\u4E3A\u7A7A +novice_statistics.guide_step.not_blank=\u65B0\u624B\u6751\u6B65\u9AA4\u4E0D\u80FD\u4E3A\u7A7A +novice_statistics.guide_step.length_range=\u65B0\u624B\u6751\u6B65\u9AA4\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +operating_log.id.not_blank=\u64CD\u4F5C\u65E5\u5FD7ID\u4E0D\u80FD\u4E3A\u7A7A +operating_log.project_id.not_blank=\u64CD\u4F5C\u65E5\u5FD7\u9879\u76EEID\u4E0D\u80FD\u4E3A\u7A7A +operating_log.project_id.length_range=\u64CD\u4F5C\u65E5\u5FD7\u9879\u76EEID\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +operating_log_resource.id.not_blank=\u64CD\u4F5C\u65E5\u5FD7\u8D44\u6E90ID\u4E0D\u80FD\u4E3A\u7A7A +operating_log_resource.operating_log_id.not_blank=\u64CD\u4F5C\u65E5\u5FD7\u8D44\u6E90\u64CD\u4F5C\u65E5\u5FD7ID\u4E0D\u80FD\u4E3A\u7A7A +operating_log_resource.operating_log_id.length_range=\u64CD\u4F5C\u65E5\u5FD7\u8D44\u6E90\u64CD\u4F5C\u65E5\u5FD7ID\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +operating_log_resource.source_id.not_blank=\u64CD\u4F5C\u65E5\u5FD7\u8D44\u6E90\u6765\u6E90ID\u4E0D\u80FD\u4E3A\u7A7A +operating_log_resource.source_id.length_range=\u64CD\u4F5C\u65E5\u5FD7\u8D44\u6E90\u6765\u6E90ID\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +plugin.id.not_blank=\u63D2\u4EF6\u4E3B\u952E\u4E0D\u80FD\u4E3A\u7A7A +plugin.plugin_id.not_blank=\u63D2\u4EF6ID\u4E0D\u80FD\u4E3A\u7A7A +plugin.plugin_id.length_range=\u63D2\u4EF6ID\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +plugin.script_id.not_blank=\u63D2\u4EF6\u811A\u672CID\u4E0D\u80FD\u4E3A\u7A7A +plugin.script_id.length_range=\u63D2\u4EF6\u811A\u672CID\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +plugin.clazz_name.not_blank=\u63D2\u4EF6\u7C7B\u540D\u4E0D\u80FD\u4E3A\u7A7A +plugin.clazz_name.length_range=\u63D2\u4EF6\u7C7B\u540D\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +plugin.jmeter_clazz.not_blank=\u63D2\u4EF6jmeter\u7C7B\u540D\u4E0D\u80FD\u4E3A\u7A7A +plugin.jmeter_clazz.length_range=\u63D2\u4EF6jmeter\u7C7B\u540D\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +plugin.source_path.not_blank=\u63D2\u4EF6\u6E90\u8DEF\u5F84\u4E0D\u80FD\u4E3A\u7A7A +plugin.source_path.length_range=\u63D2\u4EF6\u6E90\u8DEF\u5F84\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +plugin.source_name.not_blank=\u63D2\u4EF6\u6E90\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A +plugin.source_name.length_range=\u63D2\u4EF6\u6E90\u540D\u79F0\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +plugin.scenario.not_blank=\u63D2\u4EF6\u573A\u666F\u4E0D\u80FD\u4E3A\u7A7A +plugin.scenario.length_range=\u63D2\u4EF6\u573A\u666F\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +plugin_blob.id.not_blank=\u63D2\u4EF6ID\u4E0D\u80FD\u4E3A\u7A7A +quota.id.not_blank=\u914D\u989DID\u4E0D\u80FD\u4E3A\u7A7A +schedule.id.not_blank=\u5B9A\u65F6\u4EFB\u52A1ID\u4E0D\u80FD\u4E3A\u7A7A +schedule.type.not_blank=\u5B9A\u65F6\u4EFB\u52A1\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A +schedule.type.length_range=\u5B9A\u65F6\u4EFB\u52A1\u7C7B\u578B\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +schedule.value.not_blank=\u5B9A\u65F6\u4EFB\u52A1\u503C\u4E0D\u80FD\u4E3A\u7A7A +schedule.value.length_range=\u5B9A\u65F6\u4EFB\u52A1\u503C\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +schedule.job.not_blank=\u5B9A\u65F6\u4EFB\u52A1\u4E0D\u80FD\u4E3A\u7A7A +schedule.job.length_range=\u5B9A\u65F6\u4EFB\u52A1\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +schedule.create_user.not_blank=\u5B9A\u65F6\u4EFB\u52A1\u521B\u5EFA\u4EBA\u4E0D\u80FD\u4E3A\u7A7A +schedule.create_user.length_range=\u5B9A\u65F6\u4EFB\u52A1\u521B\u5EFA\u4EBA\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +service_integration.id.not_blank=\u670D\u52A1\u96C6\u6210ID\u4E0D\u80FD\u4E3A\u7A7A +service_integration.platform.not_blank=\u670D\u52A1\u96C6\u6210\u5E73\u53F0\u4E0D\u80FD\u4E3A\u7A7A +service_integration.platform.length_range=\u670D\u52A1\u96C6\u6210\u5E73\u53F0\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +system_parameter.param_key.not_blank=\u7CFB\u7EDF\u53C2\u6570Key\u4E0D\u80FD\u4E3A\u7A7A +system_parameter.type.not_blank=\u7CFB\u7EDF\u53C2\u6570\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A +system_parameter.type.length_range=\u7CFB\u7EDF\u53C2\u6570\u7C7B\u578B\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +test_resource.id.not_blank=\u8D44\u6E90\u6C60\u8282\u70B9ID\u4E0D\u80FD\u4E3A\u7A7A +test_resource.test_resource_pool_id.not_blank=\u8D44\u6E90\u6C60ID\u4E0D\u80FD\u4E3A\u7A7A +test_resource.test_resource_pool_id.length_range=\u8D44\u6E90\u6C60ID\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +test_resource.status.not_blank=\u8D44\u6E90\u6C60\u8282\u70B9\u72B6\u6001\u4E0D\u80FD\u4E3A\u7A7A +test_resource.status.length_range=\u8D44\u6E90\u6C60\u8282\u70B9\u72B6\u6001\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +test_resource_pool.id.not_blank=\u8D44\u6E90\u6C60ID\u4E0D\u80FD\u4E3A\u7A7A +test_resource_pool.name.not_blank=\u8D44\u6E90\u6C60\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A +test_resource_pool.name.length_range=\u8D44\u6E90\u6C60\u540D\u79F0\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +test_resource_pool.type.not_blank=\u8D44\u6E90\u6C60\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A +test_resource_pool.type.length_range=\u8D44\u6E90\u6C60\u7C7B\u578B\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +test_resource_pool.status.not_blank=\u8D44\u6E90\u6C60\u72B6\u6001\u4E0D\u80FD\u4E3A\u7A7A +test_resource_pool.status.length_range=\u8D44\u6E90\u6C60\u72B6\u6001\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +user.id.not_blank=\u7528\u6237ID\u4E0D\u80FD\u4E3A\u7A7A +user.name.not_blank=\u7528\u6237\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A +user.name.length_range=\u7528\u6237\u540D\u79F0\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +user.email.not_blank=\u7528\u6237email\u4E0D\u80FD\u4E3A\u7A7A +user.email.length_range=\u7528\u6237email\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +user.email.repeat=\u7528\u6237email\u5DF2\u5B58\u5728 +user.email.invalid=\u7528\u6237email\u683C\u5F0F\u4E0D\u6B63\u786E +user.status.not_blank=\u7528\u6237\u72B6\u6001\u4E0D\u80FD\u4E3A\u7A7A +user.status.length_range=\u7528\u6237\u72B6\u6001\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +user.source.not_blank=\u7528\u6237\u6765\u6E90\u4E0D\u80FD\u4E3A\u7A7A +user.source.length_range=\u7528\u6237\u6765\u6E90\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +user.create_user.not_blank=\u7528\u6237\u521B\u5EFA\u4EBA\u4E0D\u80FD\u4E3A\u7A7A +user.create_user.length_range=\u7528\u6237\u521B\u5EFA\u4EBA\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +user_extend.id.not_blank=\u7528\u6237ID\u4E0D\u80FD\u4E3A\u7A7A +user_key.id.not_blank=\u7528\u6237ApiKey ID\u4E0D\u80FD\u4E3A\u7A7A +user_key.create_user.not_blank=\u7528\u6237ApiKey\u521B\u5EFA\u4EBA\u4E0D\u80FD\u4E3A\u7A7A +user_key.create_user.length_range=\u7528\u6237ApiKey\u521B\u5EFA\u4EBA\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +user_key.access_key.not_blank=\u7528\u6237ApiKey access key\u4E0D\u80FD\u4E3A\u7A7A +user_key.access_key.length_range=\u7528\u6237ApiKey access key\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +user_key.secret_key.not_blank=\u7528\u6237ApiKey secret key\u4E0D\u80FD\u4E3A\u7A7A +user_key.secret_key.length_range=\u7528\u6237ApiKey secret key\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +user.info.not_empty=\u7528\u6237\u4FE1\u606F\u4E0D\u80FD\u4E3A\u7A7A +user.organizationId.not_blank=\u7528\u6237\u7EC4\u7EC7\u4E0D\u80FD\u4E3A\u7A7A +user.projectId.not_blank=\u7528\u6237\u9879\u76EE\u4E0D\u80FD\u4E3A\u7A7A +user_role.id.not_blank=\u7528\u6237\u7EC4ID\u4E0D\u80FD\u4E3A\u7A7A +user_role.name.not_blank=\u7528\u6237\u7EC4\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A +user_role.name.length_range=\u7528\u6237\u7EC4\u540D\u79F0\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +user_role.system.not_blank=\u662F\u5426\u662F\u7CFB\u7EDF\u7528\u6237\u7EC4\u4E0D\u80FD\u4E3A\u7A7A +user_role.system.length_range=\u662F\u5426\u662F\u7CFB\u7EDF\u7528\u6237\u7EC4\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +user_role.type.not_blank=\u7528\u6237\u7EC4\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A +user_role.type.length_range=\u7528\u6237\u7EC4\u7C7B\u578B\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +user_role.create_user.not_blank=\u7528\u6237\u7EC4\u521B\u5EFA\u4EBA\u4E0D\u80FD\u4E3A\u7A7A +user_role.create_user.length_range=\u7528\u6237\u7EC4\u521B\u5EFA\u4EBA\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +user_role.scope_id.not_blank=\u7528\u6237\u7EC4\u5E94\u7528\u8303\u56F4\u4E0D\u80FD\u4E3A\u7A7A +user_role.scope_id.length_range=\u7528\u6237\u7EC4\u5E94\u7528\u8303\u56F4\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +user_role_permission.id.not_blank=\u7528\u6237\u7EC4\u6743\u9650ID\u4E0D\u80FD\u4E3A\u7A7A +user_role_permission.role_id.not_blank=\u7528\u6237\u7EC4\u6743\u9650\u7528\u6237\u7EC4ID\u4E0D\u80FD\u4E3A\u7A7A +user_role_permission.role_id.length_range=\u7528\u6237\u7EC4\u6743\u9650\u7528\u6237\u7EC4ID\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +user_role_permission.permission_id.not_blank=\u7528\u6237\u7EC4\u6743\u9650\u6743\u9650ID\u4E0D\u80FD\u4E3A\u7A7A +user_role_permission.permission_id.length_range=\u7528\u6237\u7EC4\u6743\u9650\u6743\u9650ID\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +user_role_permission.module_id.not_blank=\u7528\u6237\u7EC4\u6743\u9650\u6A21\u5757ID\u4E0D\u80FD\u4E3A\u7A7A +user_role_permission.module_id.length_range=\u7528\u6237\u7EC4\u6743\u9650\u6A21\u5757ID\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +user_role_relation.id.not_blank=\u7528\u6237\u7EC4\u5173\u7CFBID\u4E0D\u80FD\u4E3A\u7A7A +user_role_relation.user_id.not_blank=\u7528\u6237\u7EC4\u5173\u7CFB\u7528\u6237ID\u4E0D\u80FD\u4E3A\u7A7A +user_role_relation.user_id.length_range=\u7528\u6237\u7EC4\u5173\u7CFB\u7528\u6237ID\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +user_role_relation.role_id.not_blank=\u7528\u6237\u7EC4\u5173\u7CFB\u7528\u6237\u7EC4ID\u4E0D\u80FD\u4E3A\u7A7A +user_role_relation.role_id.length_range=\u7528\u6237\u7EC4\u5173\u7CFB\u7528\u6237\u7EC4ID\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +user_role_relation.source_id.not_blank=\u7528\u6237\u7EC4\u5173\u7CFB\u6765\u6E90ID\u4E0D\u80FD\u4E3A\u7A7A +user_role_relation.source_id.length_range=\u7528\u6237\u7EC4\u5173\u7CFB\u6765\u6E90ID\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +organization.id.not_blank=\u5DE5\u4F5C\u7A7A\u95F4ID\u4E0D\u80FD\u4E3A\u7A7A +organization.name.not_blank=\u5DE5\u4F5C\u7A7A\u95F4\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A +organization.name.length_range=\u5DE5\u4F5C\u7A7A\u95F4\u540D\u79F0\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 +organization.create_user.not_blank=\u5DE5\u4F5C\u7A7A\u95F4\u521B\u5EFA\u4EBA\u4E0D\u80FD\u4E3A\u7A7A +organization.create_user.length_range=\u5DE5\u4F5C\u7A7A\u95F4\u521B\u5EFA\u4EBA\u957F\u5EA6\u5FC5\u987B\u5728{min}\u548C{max}\u4E4B\u95F4 diff --git a/backend/framework/sdk/src/main/resources/i18n/system_zh_TW.properties b/backend/framework/sdk/src/main/resources/i18n/system_zh_TW.properties index 365f10019b..fe8ca93ba9 100644 --- a/backend/framework/sdk/src/main/resources/i18n/system_zh_TW.properties +++ b/backend/framework/sdk/src/main/resources/i18n/system_zh_TW.properties @@ -1,141 +1,147 @@ -auth_source.id.not_blank=認證源ID不能為空 -auth_source.status.length_range=認證源狀態長度必須在{min}和{max}之間 -auth_source.status.not_blank=認證源狀態不能為空 -license.id.not_blank=License ID不能為空 -message_task.id.not_blank=消息通知任務ID不能為空 -message_task.type.not_blank=消息通知任務類型不能為空 -message_task.type.length_range=消息通知任務類型長度必須在{min}和{max}之間 -message_task.event.not_blank=消息通知任務事件不能為空 -message_task.event.length_range=消息通知任務事件長度必須在{min}和{max}之間 -message_task.receiver.not_blank=消息通知任務接收者不能為空 -message_task.receiver.length_range=消息通知任務接收者長度必須在{min}和{max}之間 -message_task.task_type.not_blank=消息通知任務任務類型不能為空 -message_task.task_type.length_range=消息通知任務任務類型長度必須在{min}和{max}之間 -message_task.test_id.not_blank=消息通知任務測試ID不能為空 -message_task.test_id.length_range=消息通知任務測試ID長度必須在{min}和{max}之間 -message_task.project_id.not_blank=消息通知任務項目ID不能為空 -message_task.project_id.length_range=消息通知任務項目ID長度必須在{min}和{max}之間 -message_task_blob.id.not_blank=消息通知任務ID不能為空 -notification.id.not_blank=消息通知ID不能為空 -notification.type.not_blank=消息通知類型不能為空 -notification.type.length_range=消息通知類型長度必須在{min}和{max}之間 -notification.receiver.not_blank=消息通知接收者不能為空 -notification.receiver.length_range=消息通知接收者長度必須在{min}和{max}之間 -notification.title.not_blank=消息通知標題不能為空 -notification.title.length_range=消息通知標題長度必須在{min}和{max}之間 -notification.status.not_blank=消息通知狀態不能為空 -notification.status.length_range=消息通知狀態長度必須在{min}和{max}之間 -notification.operator.not_blank=消息通知操作者不能為空 -notification.operator.length_range=消息通知操作者長度必須在{min}和{max}之間 -notification.operation.not_blank=消息通知操作不能為空 -notification.operation.length_range=消息通知操作長度必須在{min}和{max}之間 -notification.resource_id.not_blank=消息通知資源ID不能為空 -notification.resource_id.length_range=消息通知資源ID長度必須在{min}和{max}之間 -notification.resource_type.not_blank=消息通知資源類型不能為空 -notification.resource_type.length_range=消息通知資源類型長度必須在{min}和{max}之間 -notification.resource_name.not_blank=消息通知資源名稱不能為空 -notification.resource_name.length_range=消息通知資源名稱長度必須在{min}和{max}之間 -novice_statistics.id.not_blank=新手村ID不能為空 -novice_statistics.guide_step.not_blank=新手村步驟不能為空 -novice_statistics.guide_step.length_range=新手村步驟長度必須在{min}和{max}之間 -operating_log.id.not_blank=操作日誌ID不能為空 -operating_log.project_id.not_blank=操作日誌項目ID不能為空 -operating_log.project_id.length_range=操作日誌項目ID長度必須在{min}和{max}之間 -operating_log_resource.id.not_blank=操作日誌資源ID不能為空 -operating_log_resource.operating_log_id.not_blank=操作日誌資源操作日誌ID不能為空 -operating_log_resource.operating_log_id.length_range=操作日誌資源操作日誌ID長度必須在{min}和{max}之間 -operating_log_resource.source_id.not_blank=操作日誌資源來源ID不能為空 -operating_log_resource.source_id.length_range=操作日誌資源來源ID長度必須在{min}和{max}之間 -plugin.id.not_blank=插件主鍵不能為空 -plugin.plugin_id.not_blank=插件ID不能為空 -plugin.plugin_id.length_range=插件ID長度必須在{min}和{max}之間 -plugin.script_id.not_blank=插件腳本ID不能為空 -plugin.script_id.length_range=插件腳本ID長度必須在{min}和{max}之間 -plugin.clazz_name.not_blank=插件類名不能為空 -plugin.clazz_name.length_range=插件類名長度必須在{min}和{max}之間 -plugin.jmeter_clazz.not_blank=插件jmeter類名不能為空 -plugin.jmeter_clazz.length_range=插件jmeter類名長度必須在{min}和{max}之間 -plugin.source_path.not_blank=插件源路徑不能為空 -plugin.source_path.length_range=插件源路徑長度必須在{min}和{max}之間 -plugin.source_name.not_blank=插件源名稱不能為空 -plugin.source_name.length_range=插件源名稱長度必須在{min}和{max}之間 -plugin.scenario.not_blank=插件場景不能為空 -plugin.scenario.length_range=插件場景長度必須在{min}和{max}之間 -plugin_blob.id.not_blank=插件ID不能為空 -quota.id.not_blank=配額ID不能為空 -schedule.id.not_blank=定時任務ID不能為空 -schedule.type.not_blank=定時任務類型不能為空 -schedule.type.length_range=定時任務類型長度必須在{min}和{max}之間 -schedule.value.not_blank=定時任務值不能為空 -schedule.value.length_range=定時任務值長度必須在{min}和{max}之間 -schedule.job.not_blank=定時任務不能為空 -schedule.job.length_range=定時任務長度必須在{min}和{max}之間 -schedule.create_user.not_blank=定時任務創建人不能為空 -schedule.create_user.length_range=定時任務創建人長度必須在{min}和{max}之間 -service_integration.id.not_blank=服務集成ID不能為空 -service_integration.platform.not_blank=服務集成平台不能為空 -service_integration.platform.length_range=服務集成平台長度必須在{min}和{max}之間 -system_parameter.param_key.not_blank=系統參數Key不能為空 -system_parameter.type.not_blank=系統參數類型不能為空 -system_parameter.type.length_range=系統參數類型長度必須在{min}和{max}之間 -test_resource.id.not_blank=資源池節點ID不能為空 -test_resource.test_resource_pool_id.not_blank=資源池ID不能為空 -test_resource.test_resource_pool_id.length_range=資源池ID長度必須在{min}和{max}之間 -test_resource.status.not_blank=資源池節點狀態不能為空 -test_resource.status.length_range=資源池節點狀態長度必須在{min}和{max}之間 -test_resource_pool.id.not_blank=資源池ID不能為空 -test_resource_pool.name.not_blank=資源池名稱不能為空 -test_resource_pool.name.length_range=資源池名稱長度必須在{min}和{max}之間 -test_resource_pool.type.not_blank=資源池類型不能為空 -test_resource_pool.type.length_range=資源池類型長度必須在{min}和{max}之間 -test_resource_pool.status.not_blank=資源池狀態不能為空 -test_resource_pool.status.length_range=資源池狀態長度必須在{min}和{max}之間 -user.id.not_blank=用戶ID不能為空 -user.name.not_blank=用戶名稱不能為空 -user.name.length_range=用戶名稱長度必須在{min}和{max}之間 -user.email.not_blank=用戶email不能為空 -user.email.length_range=用戶email長度必須在{min}和{max}之間 -user.status.not_blank=用戶狀態不能為空 -user.status.length_range=用戶狀態長度必須在{min}和{max}之間 -user.source.not_blank=用戶來源不能為空 -user.source.length_range=用戶來源長度必須在{min}和{max}之間 -user.create_user.not_blank=用戶創建人不能為空 -user.create_user.length_range=用戶創建人長度必須在{min}和{max}之間 -user_extend.id.not_blank=用戶ID不能為空 -user_key.id.not_blank=用戶ApiKey ID不能為空 -user_key.create_user.not_blank=用戶ApiKey創建人不能為空 -user_key.create_user.length_range=用戶ApiKey創建人長度必須在{min}和{max}之間 -user_key.access_key.not_blank=用戶ApiKey access key不能為空 -user_key.access_key.length_range=用戶ApiKey access key長度必須在{min}和{max}之間 -user_key.secret_key.not_blank=用戶ApiKey secret key不能為空 -user_key.secret_key.length_range=用戶ApiKey secret key長度必須在{min}和{max}之間 -user_role.id.not_blank=用戶組ID不能為空 -user_role.name.not_blank=用戶組名稱不能為空 -user_role.name.length_range=用戶組名稱長度必須在{min}和{max}之間 -user_role.system.not_blank=是否是系統用戶組不能為空 -user_role.system.length_range=是否是系統用戶組長度必須在{min}和{max}之間 -user_role.type.not_blank=用戶組類型不能為空 -user_role.type.length_range=用戶組類型長度必須在{min}和{max}之間 -user_role.create_user.not_blank=用戶組創建人不能為空 -user_role.create_user.length_range=用戶組創建人長度必須在{min}和{max}之間 -user_role.scope_id.not_blank=用戶組應用範圍不能為空 -user_role.scope_id.length_range=用戶組應用範圍長度必須在{min}和{max}之間 -user_role_permission.id.not_blank=用戶組權限ID不能為空 -user_role_permission.role_id.not_blank=用戶組權限用戶組ID不能為空 -user_role_permission.role_id.length_range=用戶組權限用戶組ID長度必須在{min}和{max}之間 -user_role_permission.permission_id.not_blank=用戶組權限權限ID不能為空 -user_role_permission.permission_id.length_range=用戶組權限權限ID長度必須在{min}和{max}之間 -user_role_permission.module_id.not_blank=用戶組權限模塊ID不能為空 -user_role_permission.module_id.length_range=用戶組權限模塊ID長度必須在{min}和{max}之間 -user_role_relation.id.not_blank=用戶組關係ID不能為空 -user_role_relation.user_id.not_blank=用戶組關係用戶ID不能為空 -user_role_relation.user_id.length_range=用戶組關係用戶ID長度必須在{min}和{max}之間 -user_role_relation.role_id.not_blank=用戶組關係用戶組ID不能為空 -user_role_relation.role_id.length_range=用戶組關係用戶組ID長度必須在{min}和{max}之間 -user_role_relation.source_id.not_blank=用戶組關係來源ID不能為空 -user_role_relation.source_id.length_range=用戶組關係來源ID長度必須在{min}和{max}之間 -organization.id.not_blank=工作空間ID不能為空 -organization.name.not_blank=工作空間名稱不能為空 -organization.name.length_range=工作空間名稱長度必須在{min}和{max}之間 -organization.create_user.not_blank=工作空間創建人不能為空 -organization.create_user.length_range=工作空間創建人長度必須在{min}和{max}之間 \ No newline at end of file +user.not.login=\u672A\u7372\u53D6\u5230\u767B\u9304\u7528\u6236 +auth_source.id.not_blank=\u8A8D\u8B49\u6E90ID\u4E0D\u80FD\u70BA\u7A7A +auth_source.status.length_range=\u8A8D\u8B49\u6E90\u72C0\u614B\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +auth_source.status.not_blank=\u8A8D\u8B49\u6E90\u72C0\u614B\u4E0D\u80FD\u70BA\u7A7A +license.id.not_blank=License ID\u4E0D\u80FD\u70BA\u7A7A +message_task.id.not_blank=\u6D88\u606F\u901A\u77E5\u4EFB\u52D9ID\u4E0D\u80FD\u70BA\u7A7A +message_task.type.not_blank=\u6D88\u606F\u901A\u77E5\u4EFB\u52D9\u985E\u578B\u4E0D\u80FD\u70BA\u7A7A +message_task.type.length_range=\u6D88\u606F\u901A\u77E5\u4EFB\u52D9\u985E\u578B\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +message_task.event.not_blank=\u6D88\u606F\u901A\u77E5\u4EFB\u52D9\u4E8B\u4EF6\u4E0D\u80FD\u70BA\u7A7A +message_task.event.length_range=\u6D88\u606F\u901A\u77E5\u4EFB\u52D9\u4E8B\u4EF6\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +message_task.receiver.not_blank=\u6D88\u606F\u901A\u77E5\u4EFB\u52D9\u63A5\u6536\u8005\u4E0D\u80FD\u70BA\u7A7A +message_task.receiver.length_range=\u6D88\u606F\u901A\u77E5\u4EFB\u52D9\u63A5\u6536\u8005\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +message_task.task_type.not_blank=\u6D88\u606F\u901A\u77E5\u4EFB\u52D9\u4EFB\u52D9\u985E\u578B\u4E0D\u80FD\u70BA\u7A7A +message_task.task_type.length_range=\u6D88\u606F\u901A\u77E5\u4EFB\u52D9\u4EFB\u52D9\u985E\u578B\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +message_task.test_id.not_blank=\u6D88\u606F\u901A\u77E5\u4EFB\u52D9\u6E2C\u8A66ID\u4E0D\u80FD\u70BA\u7A7A +message_task.test_id.length_range=\u6D88\u606F\u901A\u77E5\u4EFB\u52D9\u6E2C\u8A66ID\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +message_task.project_id.not_blank=\u6D88\u606F\u901A\u77E5\u4EFB\u52D9\u9805\u76EEID\u4E0D\u80FD\u70BA\u7A7A +message_task.project_id.length_range=\u6D88\u606F\u901A\u77E5\u4EFB\u52D9\u9805\u76EEID\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +message_task_blob.id.not_blank=\u6D88\u606F\u901A\u77E5\u4EFB\u52D9ID\u4E0D\u80FD\u70BA\u7A7A +notification.id.not_blank=\u6D88\u606F\u901A\u77E5ID\u4E0D\u80FD\u70BA\u7A7A +notification.type.not_blank=\u6D88\u606F\u901A\u77E5\u985E\u578B\u4E0D\u80FD\u70BA\u7A7A +notification.type.length_range=\u6D88\u606F\u901A\u77E5\u985E\u578B\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +notification.receiver.not_blank=\u6D88\u606F\u901A\u77E5\u63A5\u6536\u8005\u4E0D\u80FD\u70BA\u7A7A +notification.receiver.length_range=\u6D88\u606F\u901A\u77E5\u63A5\u6536\u8005\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +notification.title.not_blank=\u6D88\u606F\u901A\u77E5\u6A19\u984C\u4E0D\u80FD\u70BA\u7A7A +notification.title.length_range=\u6D88\u606F\u901A\u77E5\u6A19\u984C\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +notification.status.not_blank=\u6D88\u606F\u901A\u77E5\u72C0\u614B\u4E0D\u80FD\u70BA\u7A7A +notification.status.length_range=\u6D88\u606F\u901A\u77E5\u72C0\u614B\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +notification.operator.not_blank=\u6D88\u606F\u901A\u77E5\u64CD\u4F5C\u8005\u4E0D\u80FD\u70BA\u7A7A +notification.operator.length_range=\u6D88\u606F\u901A\u77E5\u64CD\u4F5C\u8005\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +notification.operation.not_blank=\u6D88\u606F\u901A\u77E5\u64CD\u4F5C\u4E0D\u80FD\u70BA\u7A7A +notification.operation.length_range=\u6D88\u606F\u901A\u77E5\u64CD\u4F5C\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +notification.resource_id.not_blank=\u6D88\u606F\u901A\u77E5\u8CC7\u6E90ID\u4E0D\u80FD\u70BA\u7A7A +notification.resource_id.length_range=\u6D88\u606F\u901A\u77E5\u8CC7\u6E90ID\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +notification.resource_type.not_blank=\u6D88\u606F\u901A\u77E5\u8CC7\u6E90\u985E\u578B\u4E0D\u80FD\u70BA\u7A7A +notification.resource_type.length_range=\u6D88\u606F\u901A\u77E5\u8CC7\u6E90\u985E\u578B\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +notification.resource_name.not_blank=\u6D88\u606F\u901A\u77E5\u8CC7\u6E90\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A +notification.resource_name.length_range=\u6D88\u606F\u901A\u77E5\u8CC7\u6E90\u540D\u7A31\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +novice_statistics.id.not_blank=\u65B0\u624B\u6751ID\u4E0D\u80FD\u70BA\u7A7A +novice_statistics.guide_step.not_blank=\u65B0\u624B\u6751\u6B65\u9A5F\u4E0D\u80FD\u70BA\u7A7A +novice_statistics.guide_step.length_range=\u65B0\u624B\u6751\u6B65\u9A5F\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +operating_log.id.not_blank=\u64CD\u4F5C\u65E5\u8A8CID\u4E0D\u80FD\u70BA\u7A7A +operating_log.project_id.not_blank=\u64CD\u4F5C\u65E5\u8A8C\u9805\u76EEID\u4E0D\u80FD\u70BA\u7A7A +operating_log.project_id.length_range=\u64CD\u4F5C\u65E5\u8A8C\u9805\u76EEID\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +operating_log_resource.id.not_blank=\u64CD\u4F5C\u65E5\u8A8C\u8CC7\u6E90ID\u4E0D\u80FD\u70BA\u7A7A +operating_log_resource.operating_log_id.not_blank=\u64CD\u4F5C\u65E5\u8A8C\u8CC7\u6E90\u64CD\u4F5C\u65E5\u8A8CID\u4E0D\u80FD\u70BA\u7A7A +operating_log_resource.operating_log_id.length_range=\u64CD\u4F5C\u65E5\u8A8C\u8CC7\u6E90\u64CD\u4F5C\u65E5\u8A8CID\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +operating_log_resource.source_id.not_blank=\u64CD\u4F5C\u65E5\u8A8C\u8CC7\u6E90\u4F86\u6E90ID\u4E0D\u80FD\u70BA\u7A7A +operating_log_resource.source_id.length_range=\u64CD\u4F5C\u65E5\u8A8C\u8CC7\u6E90\u4F86\u6E90ID\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +plugin.id.not_blank=\u63D2\u4EF6\u4E3B\u9375\u4E0D\u80FD\u70BA\u7A7A +plugin.plugin_id.not_blank=\u63D2\u4EF6ID\u4E0D\u80FD\u70BA\u7A7A +plugin.plugin_id.length_range=\u63D2\u4EF6ID\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +plugin.script_id.not_blank=\u63D2\u4EF6\u8173\u672CID\u4E0D\u80FD\u70BA\u7A7A +plugin.script_id.length_range=\u63D2\u4EF6\u8173\u672CID\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +plugin.clazz_name.not_blank=\u63D2\u4EF6\u985E\u540D\u4E0D\u80FD\u70BA\u7A7A +plugin.clazz_name.length_range=\u63D2\u4EF6\u985E\u540D\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +plugin.jmeter_clazz.not_blank=\u63D2\u4EF6jmeter\u985E\u540D\u4E0D\u80FD\u70BA\u7A7A +plugin.jmeter_clazz.length_range=\u63D2\u4EF6jmeter\u985E\u540D\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +plugin.source_path.not_blank=\u63D2\u4EF6\u6E90\u8DEF\u5F91\u4E0D\u80FD\u70BA\u7A7A +plugin.source_path.length_range=\u63D2\u4EF6\u6E90\u8DEF\u5F91\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +plugin.source_name.not_blank=\u63D2\u4EF6\u6E90\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A +plugin.source_name.length_range=\u63D2\u4EF6\u6E90\u540D\u7A31\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +plugin.scenario.not_blank=\u63D2\u4EF6\u5834\u666F\u4E0D\u80FD\u70BA\u7A7A +plugin.scenario.length_range=\u63D2\u4EF6\u5834\u666F\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +plugin_blob.id.not_blank=\u63D2\u4EF6ID\u4E0D\u80FD\u70BA\u7A7A +quota.id.not_blank=\u914D\u984DID\u4E0D\u80FD\u70BA\u7A7A +schedule.id.not_blank=\u5B9A\u6642\u4EFB\u52D9ID\u4E0D\u80FD\u70BA\u7A7A +schedule.type.not_blank=\u5B9A\u6642\u4EFB\u52D9\u985E\u578B\u4E0D\u80FD\u70BA\u7A7A +schedule.type.length_range=\u5B9A\u6642\u4EFB\u52D9\u985E\u578B\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +schedule.value.not_blank=\u5B9A\u6642\u4EFB\u52D9\u503C\u4E0D\u80FD\u70BA\u7A7A +schedule.value.length_range=\u5B9A\u6642\u4EFB\u52D9\u503C\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +schedule.job.not_blank=\u5B9A\u6642\u4EFB\u52D9\u4E0D\u80FD\u70BA\u7A7A +schedule.job.length_range=\u5B9A\u6642\u4EFB\u52D9\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +schedule.create_user.not_blank=\u5B9A\u6642\u4EFB\u52D9\u5275\u5EFA\u4EBA\u4E0D\u80FD\u70BA\u7A7A +schedule.create_user.length_range=\u5B9A\u6642\u4EFB\u52D9\u5275\u5EFA\u4EBA\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +service_integration.id.not_blank=\u670D\u52D9\u96C6\u6210ID\u4E0D\u80FD\u70BA\u7A7A +service_integration.platform.not_blank=\u670D\u52D9\u96C6\u6210\u5E73\u53F0\u4E0D\u80FD\u70BA\u7A7A +service_integration.platform.length_range=\u670D\u52D9\u96C6\u6210\u5E73\u53F0\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +system_parameter.param_key.not_blank=\u7CFB\u7D71\u53C3\u6578Key\u4E0D\u80FD\u70BA\u7A7A +system_parameter.type.not_blank=\u7CFB\u7D71\u53C3\u6578\u985E\u578B\u4E0D\u80FD\u70BA\u7A7A +system_parameter.type.length_range=\u7CFB\u7D71\u53C3\u6578\u985E\u578B\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +test_resource.id.not_blank=\u8CC7\u6E90\u6C60\u7BC0\u9EDEID\u4E0D\u80FD\u70BA\u7A7A +test_resource.test_resource_pool_id.not_blank=\u8CC7\u6E90\u6C60ID\u4E0D\u80FD\u70BA\u7A7A +test_resource.test_resource_pool_id.length_range=\u8CC7\u6E90\u6C60ID\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +test_resource.status.not_blank=\u8CC7\u6E90\u6C60\u7BC0\u9EDE\u72C0\u614B\u4E0D\u80FD\u70BA\u7A7A +test_resource.status.length_range=\u8CC7\u6E90\u6C60\u7BC0\u9EDE\u72C0\u614B\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +test_resource_pool.id.not_blank=\u8CC7\u6E90\u6C60ID\u4E0D\u80FD\u70BA\u7A7A +test_resource_pool.name.not_blank=\u8CC7\u6E90\u6C60\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A +test_resource_pool.name.length_range=\u8CC7\u6E90\u6C60\u540D\u7A31\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +test_resource_pool.type.not_blank=\u8CC7\u6E90\u6C60\u985E\u578B\u4E0D\u80FD\u70BA\u7A7A +test_resource_pool.type.length_range=\u8CC7\u6E90\u6C60\u985E\u578B\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +test_resource_pool.status.not_blank=\u8CC7\u6E90\u6C60\u72C0\u614B\u4E0D\u80FD\u70BA\u7A7A +test_resource_pool.status.length_range=\u8CC7\u6E90\u6C60\u72C0\u614B\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +user.id.not_blank=\u7528\u6236ID\u4E0D\u80FD\u70BA\u7A7A +user.name.not_blank=\u7528\u6236\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A +user.name.length_range=\u7528\u6236\u540D\u7A31\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +user.email.not_blank=\u7528\u6236email\u4E0D\u80FD\u70BA\u7A7A +user.email.length_range=\u7528\u6236email\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +user.email.repeat=\u7528\u6236email\u5DF2\u5B58\u5728 +user.email.invalid=\u7528\u6236email\u683C\u5F0F\u4E0D\u6B63\u78BA +user.status.not_blank=\u7528\u6236\u72C0\u614B\u4E0D\u80FD\u70BA\u7A7A +user.status.length_range=\u7528\u6236\u72C0\u614B\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +user.source.not_blank=\u7528\u6236\u4F86\u6E90\u4E0D\u80FD\u70BA\u7A7A +user.source.length_range=\u7528\u6236\u4F86\u6E90\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +user.create_user.not_blank=\u7528\u6236\u5275\u5EFA\u4EBA\u4E0D\u80FD\u70BA\u7A7A +user.create_user.length_range=\u7528\u6236\u5275\u5EFA\u4EBA\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +user_extend.id.not_blank=\u7528\u6236ID\u4E0D\u80FD\u70BA\u7A7A +user_key.id.not_blank=\u7528\u6236ApiKey ID\u4E0D\u80FD\u70BA\u7A7A +user_key.create_user.not_blank=\u7528\u6236ApiKey\u5275\u5EFA\u4EBA\u4E0D\u80FD\u70BA\u7A7A +user_key.create_user.length_range=\u7528\u6236ApiKey\u5275\u5EFA\u4EBA\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +user_key.access_key.not_blank=\u7528\u6236ApiKey access key\u4E0D\u80FD\u70BA\u7A7A +user_key.access_key.length_range=\u7528\u6236ApiKey access key\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +user_key.secret_key.not_blank=\u7528\u6236ApiKey secret key\u4E0D\u80FD\u70BA\u7A7A +user_key.secret_key.length_range=\u7528\u6236ApiKey secret key\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +user.info.not_empty=\u7528\u6236\u4FE1\u606F\u4E0D\u80FD\u70BA\u7A7A +user.organizationId.not_blank=\u7528\u6236\u7D44\u7E54\u4E0D\u80FD\u70BA\u7A7A +user.projectId.not_blank=\u7528\u6236\u9805\u76EE\u4E0D\u80FD\u70BA\u7A7A +user_role.id.not_blank=\u7528\u6236\u7D44ID\u4E0D\u80FD\u70BA\u7A7A +user_role.name.not_blank=\u7528\u6236\u7D44\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A +user_role.name.length_range=\u7528\u6236\u7D44\u540D\u7A31\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +user_role.system.not_blank=\u662F\u5426\u662F\u7CFB\u7D71\u7528\u6236\u7D44\u4E0D\u80FD\u70BA\u7A7A +user_role.system.length_range=\u662F\u5426\u662F\u7CFB\u7D71\u7528\u6236\u7D44\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +user_role.type.not_blank=\u7528\u6236\u7D44\u985E\u578B\u4E0D\u80FD\u70BA\u7A7A +user_role.type.length_range=\u7528\u6236\u7D44\u985E\u578B\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +user_role.create_user.not_blank=\u7528\u6236\u7D44\u5275\u5EFA\u4EBA\u4E0D\u80FD\u70BA\u7A7A +user_role.create_user.length_range=\u7528\u6236\u7D44\u5275\u5EFA\u4EBA\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +user_role.scope_id.not_blank=\u7528\u6236\u7D44\u61C9\u7528\u7BC4\u570D\u4E0D\u80FD\u70BA\u7A7A +user_role.scope_id.length_range=\u7528\u6236\u7D44\u61C9\u7528\u7BC4\u570D\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +user_role_permission.id.not_blank=\u7528\u6236\u7D44\u6B0A\u9650ID\u4E0D\u80FD\u70BA\u7A7A +user_role_permission.role_id.not_blank=\u7528\u6236\u7D44\u6B0A\u9650\u7528\u6236\u7D44ID\u4E0D\u80FD\u70BA\u7A7A +user_role_permission.role_id.length_range=\u7528\u6236\u7D44\u6B0A\u9650\u7528\u6236\u7D44ID\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +user_role_permission.permission_id.not_blank=\u7528\u6236\u7D44\u6B0A\u9650\u6B0A\u9650ID\u4E0D\u80FD\u70BA\u7A7A +user_role_permission.permission_id.length_range=\u7528\u6236\u7D44\u6B0A\u9650\u6B0A\u9650ID\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +user_role_permission.module_id.not_blank=\u7528\u6236\u7D44\u6B0A\u9650\u6A21\u584AID\u4E0D\u80FD\u70BA\u7A7A +user_role_permission.module_id.length_range=\u7528\u6236\u7D44\u6B0A\u9650\u6A21\u584AID\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +user_role_relation.id.not_blank=\u7528\u6236\u7D44\u95DC\u4FC2ID\u4E0D\u80FD\u70BA\u7A7A +user_role_relation.user_id.not_blank=\u7528\u6236\u7D44\u95DC\u4FC2\u7528\u6236ID\u4E0D\u80FD\u70BA\u7A7A +user_role_relation.user_id.length_range=\u7528\u6236\u7D44\u95DC\u4FC2\u7528\u6236ID\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +user_role_relation.role_id.not_blank=\u7528\u6236\u7D44\u95DC\u4FC2\u7528\u6236\u7D44ID\u4E0D\u80FD\u70BA\u7A7A +user_role_relation.role_id.length_range=\u7528\u6236\u7D44\u95DC\u4FC2\u7528\u6236\u7D44ID\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +user_role_relation.source_id.not_blank=\u7528\u6236\u7D44\u95DC\u4FC2\u4F86\u6E90ID\u4E0D\u80FD\u70BA\u7A7A +user_role_relation.source_id.length_range=\u7528\u6236\u7D44\u95DC\u4FC2\u4F86\u6E90ID\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +organization.id.not_blank=\u5DE5\u4F5C\u7A7A\u9593ID\u4E0D\u80FD\u70BA\u7A7A +organization.name.not_blank=\u5DE5\u4F5C\u7A7A\u9593\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A +organization.name.length_range=\u5DE5\u4F5C\u7A7A\u9593\u540D\u7A31\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 +organization.create_user.not_blank=\u5DE5\u4F5C\u7A7A\u9593\u5275\u5EFA\u4EBA\u4E0D\u80FD\u70BA\u7A7A +organization.create_user.length_range=\u5DE5\u4F5C\u7A7A\u9593\u5275\u5EFA\u4EBA\u9577\u5EA6\u5FC5\u9808\u5728{min}\u548C{max}\u4E4B\u9593 \ No newline at end of file diff --git a/backend/services/bug-management/src/main/java/io/metersphere/bug/service/BugService.java b/backend/services/bug-management/src/main/java/io/metersphere/bug/service/BugService.java index 4f5cb8919c..713cec1e03 100644 --- a/backend/services/bug-management/src/main/java/io/metersphere/bug/service/BugService.java +++ b/backend/services/bug-management/src/main/java/io/metersphere/bug/service/BugService.java @@ -39,7 +39,7 @@ public class BugService { example.createCriteria().andProjectIdEqualTo(bug.getProjectId()); List bugs = bugMapper.selectByExample(example); if (CollectionUtils.isNotEmpty(bugs)) { - MSException.throwException(BugMgtResultCode.BUG_EXIST_EXCEPTION); + throw new MSException(BugMgtResultCode.BUG_EXIST_EXCEPTION); } bug.setCreateTime(System.currentTimeMillis()); bug.setUpdateTime(System.currentTimeMillis()); diff --git a/backend/services/project-management/src/test/java/io/metersphere/project/controller/ProjectControllerTests.java b/backend/services/project-management/src/test/java/io/metersphere/project/controller/ProjectControllerTests.java index a5355da043..b5506342de 100644 --- a/backend/services/project-management/src/test/java/io/metersphere/project/controller/ProjectControllerTests.java +++ b/backend/services/project-management/src/test/java/io/metersphere/project/controller/ProjectControllerTests.java @@ -1,9 +1,6 @@ package io.metersphere.project.controller; import com.jayway.jsonpath.JsonPath; -import io.metersphere.project.domain.Project; -import io.metersphere.sdk.constants.SessionConstants; -import io.metersphere.sdk.util.JSON; import jakarta.annotation.Resource; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Order; @@ -16,7 +13,6 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -47,54 +43,55 @@ public class ProjectControllerTests { } // 添加项目 - @Test - @Order(1) - public void testAddProject() throws Exception { - Project project = new Project(); - project.setName("test"); - project.setCreateUser("admin"); - project.setOrganizationId("default"); - - var result = mockMvc.perform(MockMvcRequestBuilders.post("/project/add") - .header(SessionConstants.HEADER_TOKEN, sessionId) - .header(SessionConstants.CSRF_TOKEN, csrfToken) - .content(JSON.toJSONString(project)) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andReturn(); - projectId = JsonPath.read(result.getResponse().getContentAsString(), "$.data.id"); - } - - @Test - @Order(2) - public void testEditProject() throws Exception { - Project project = new Project(); - project.setId(projectId); - project.setName("test2"); - project.setCreateUser("admin"); - project.setOrganizationId("default"); - - mockMvc.perform(MockMvcRequestBuilders.post("/project/edit") - .header(SessionConstants.HEADER_TOKEN, sessionId) - .header(SessionConstants.CSRF_TOKEN, csrfToken) - .content(JSON.toJSONString(project)) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andDo(print()); - } - - @Test - @Order(3) - public void testSelectAll() throws Exception { - mockMvc.perform(MockMvcRequestBuilders.get("/project/list-all") - .header(SessionConstants.HEADER_TOKEN, sessionId) - .header(SessionConstants.CSRF_TOKEN, csrfToken)) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) -// .andExpect(jsonPath("$.person.name").value("Jason")) - .andDo(print()); - } + // @Test + // @Order(1) + // public void testAddProject() throws Exception { + // Project project = new Project(); + // project.setName("test"); + // project.setCreateUser("admin"); + // project.setOrganizationId("default"); + // + // + // var result = mockMvc.perform(MockMvcRequestBuilders.post("/project/add") + // .header(SessionConstants.HEADER_TOKEN, sessionId) + // .header(SessionConstants.CSRF_TOKEN, csrfToken) + // .content(JSON.toJSONString(project)) + // .contentType(MediaType.APPLICATION_JSON)) + // .andExpect(status().isOk()) + // .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + // .andReturn(); + // projectId = JsonPath.read(result.getResponse().getContentAsString(), "$.data.id"); + // } + // + // @Test + // @Order(2) + // public void testEditProject() throws Exception { + // Project project = new Project(); + // project.setId(projectId); + // project.setName("test2"); + // project.setCreateUser("admin"); + // project.setOrganizationId("default"); + // + // mockMvc.perform(MockMvcRequestBuilders.post("/project/edit") + // .header(SessionConstants.HEADER_TOKEN, sessionId) + // .header(SessionConstants.CSRF_TOKEN, csrfToken) + // .content(JSON.toJSONString(project)) + // .contentType(MediaType.APPLICATION_JSON)) + // .andExpect(status().isOk()) + // .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + // .andDo(print()); + // } + // + // @Test + // @Order(3) + // public void testSelectAll() throws Exception { + // mockMvc.perform(MockMvcRequestBuilders.get("/project/list-all") + // .header(SessionConstants.HEADER_TOKEN, sessionId) + // .header(SessionConstants.CSRF_TOKEN, csrfToken)) + // .andExpect(status().isOk()) + // .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + // // .andExpect(jsonPath("$.person.name").value("Jason")) + // .andDo(print()); + // } } diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/controller/UserController.java b/backend/services/system-setting/src/main/java/io/metersphere/system/controller/UserController.java index fd6e44043c..c5af493cea 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/controller/UserController.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/controller/UserController.java @@ -3,57 +3,31 @@ package io.metersphere.system.controller; import io.metersphere.sdk.constants.PermissionConstants; import io.metersphere.sdk.dto.UserDTO; -import io.metersphere.system.domain.User; +import io.metersphere.sdk.util.SessionUtils; +import io.metersphere.system.dto.UserMaintainRequest; import io.metersphere.system.service.UserService; import io.metersphere.validation.groups.Created; -import io.metersphere.validation.groups.Updated; import jakarta.annotation.Resource; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import java.util.List; - @RestController @RequestMapping("/user") public class UserController { @Resource private UserService userService; - @GetMapping("/get/{userId}") + @GetMapping("/get/{email}") @RequiresPermissions(PermissionConstants.SYSTEM_USER_READ) - public User getUser(@PathVariable String userId) { - return userService.getById(userId); + public UserDTO getUser(@PathVariable String email) { + return userService.getByEmail(email); } @PostMapping("/add") @RequiresPermissions(PermissionConstants.SYSTEM_USER_READ_ADD) - public UserDTO addUser(@Validated({Created.class}) @RequestBody UserDTO user) { - return userService.add(user); + public UserMaintainRequest addUser(@Validated({Created.class}) @RequestBody UserMaintainRequest userCreateDTO) { + userCreateDTO.setCreateUserToList(SessionUtils.getSessionId()); + return userService.add(userCreateDTO); } - - @PostMapping("/update") - @RequiresPermissions(PermissionConstants.SYSTEM_USER_READ_UPDATE) - public UserDTO updateUser(@Validated({Updated.class}) @RequestBody UserDTO user) { - return userService.update(user); - } - - @GetMapping("/delete/{userId}") - @RequiresPermissions(PermissionConstants.SYSTEM_USER_READ_DELETE) - public UserDTO deleteUser(@PathVariable String userId) { - return userService.delete(userId); - } - - @PostMapping("/batch-add3") - @RequiresPermissions(PermissionConstants.SYSTEM_USER_READ_ADD) - public boolean batchSaveUser3(@Validated({Created.class}) @RequestBody List user) { - return userService.batchSave3(user); - } - - @GetMapping("/count") - @RequiresPermissions(PermissionConstants.SYSTEM_USER_READ) - public long batchSaveUser() { - return userService.count(); - } - } diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/dto/UserMaintainRequest.java b/backend/services/system-setting/src/main/java/io/metersphere/system/dto/UserMaintainRequest.java new file mode 100644 index 0000000000..1deaefbb43 --- /dev/null +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/dto/UserMaintainRequest.java @@ -0,0 +1,39 @@ +package io.metersphere.system.dto; + +import io.metersphere.system.domain.User; +import io.metersphere.validation.groups.Created; +import io.metersphere.validation.groups.Updated; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import lombok.Data; + +import java.util.List; + +@Data +public class UserMaintainRequest { + @Schema(title = "用户信息集合", requiredMode = Schema.RequiredMode.REQUIRED) + @NotEmpty(groups = {Created.class, Updated.class}, message = "{user.info.not_empty}") + List<@Valid User> userInfoList; + @Schema(title = "组织Id", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(groups = {Created.class, Updated.class}, message = "{user.organizationId.not_blank}") + String organizationId; + @Schema(title = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(groups = {Created.class, Updated.class}, message = "{user.projectId.not_blank}") + String projectId; + + public void setCreateUserToList(String userSessionId) { + userInfoList.forEach(user -> { + user.setCreateUser(userSessionId); + user.setUpdateUser(userSessionId); + }); + } + + public void setUpdateUserToList(String userSessionId) { + userInfoList.forEach(user -> { + user.setUpdateUser(userSessionId); + }); + } +} + diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/service/UserService.java b/backend/services/system-setting/src/main/java/io/metersphere/system/service/UserService.java index 6689c34390..8f43d1df60 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/service/UserService.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/service/UserService.java @@ -1,21 +1,23 @@ package io.metersphere.system.service; import io.metersphere.sdk.dto.UserDTO; +import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.mapper.BaseUserMapper; -import io.metersphere.sdk.util.BeanUtils; +import io.metersphere.sdk.util.CodingUtil; +import io.metersphere.sdk.util.Translator; import io.metersphere.system.domain.User; -import io.metersphere.system.domain.UserExample; -import io.metersphere.system.domain.UserExtend; -import io.metersphere.system.mapper.UserExtendMapper; +import io.metersphere.system.dto.UserMaintainRequest; import io.metersphere.system.mapper.UserMapper; import jakarta.annotation.Resource; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.ibatis.session.SqlSession; -import org.apache.ibatis.session.SqlSessionFactory; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; @Service @Transactional(rollbackFor = Exception.class) @@ -24,78 +26,50 @@ public class UserService { private BaseUserMapper baseUserMapper; @Resource private UserMapper userMapper; - @Resource - private UserExtendMapper userExtendMapper; - @Resource - private SqlSessionFactory sqlSessionFactory; - public UserDTO add(UserDTO entity) { - // todo 后台直接获取在线用户 - entity.setCreateUser("admin"); - entity.setCreateTime(System.currentTimeMillis()); - entity.setUpdateTime(System.currentTimeMillis()); - userMapper.insert(entity); - - UserExtend userExtend = new UserExtend(); - BeanUtils.copyBean(userExtend, entity); - userExtendMapper.insert(userExtend); - return entity; - } - - public UserDTO update(UserDTO entity) { - entity.setCreateUser(null); - entity.setCreateTime(null); - entity.setUpdateTime(System.currentTimeMillis()); - userMapper.updateByPrimaryKeySelective(entity); - // 扩展属性按需更新 - if (entity.getPlatformInfo() != null || StringUtils.isNotEmpty(entity.getSeleniumServer())) { - UserExtend userExtend = new UserExtend(); - BeanUtils.copyBean(userExtend, entity); - userExtendMapper.updateByPrimaryKeySelective(userExtend); - } - return baseUserMapper.selectById(entity.getId()); - } - - public UserDTO getById(String id) { - return baseUserMapper.selectById(id); - } - - public boolean batchSave3(List users) { - - long start = System.currentTimeMillis(); - int batchSize = 100; - int size = users.size(); - int pageSize = size / batchSize; - - users.forEach(user -> { - user.setCreateUser("admin"); - user.setCreateTime(System.currentTimeMillis()); - user.setUpdateTime(System.currentTimeMillis()); - }); - - for (int i = 0; i < pageSize; i++) { - int startIndex = i * batchSize; - List sub = users.subList(startIndex, startIndex + batchSize); - baseUserMapper.batchSave(sub); + private void validateUserInfo(List userList) { + //判断参数内是否含有重复邮箱 + List emailList = new ArrayList<>(); + List repeatEmailList = new ArrayList<>(); + var userInDbMap = baseUserMapper.selectUserIdByEmailList( + userList.stream().map(User::getEmail).collect(Collectors.toList())) + .stream().collect(Collectors.toMap(User::getEmail, User::getId)); + for (User user : userList) { + if (emailList.contains(user.getEmail())) { + repeatEmailList.add(user.getEmail()); + } else { + //判断邮箱是否已存在数据库中 + if (userInDbMap.containsKey(user.getEmail())) { + repeatEmailList.add(user.getEmail()); + } else { + emailList.add(user.getEmail()); + } + } } - if (size % batchSize != 0) { - int startIndex = pageSize * batchSize; - List sub = users.subList(startIndex, size); - baseUserMapper.batchSave(sub); + if (CollectionUtils.isNotEmpty(repeatEmailList)) { + throw new MSException(Translator.get("user.email.repeat", repeatEmailList.toString())); } - System.out.println("batch save cost: " + (System.currentTimeMillis() - start) + "ms"); - return true; } - public long count() { - return userMapper.countByExample(new UserExample()); + public UserMaintainRequest add(UserMaintainRequest userCreateDTO) { + this.validateUserInfo(userCreateDTO.getUserInfoList()); + long createTime = System.currentTimeMillis(); + for (User user : userCreateDTO.getUserInfoList()) { + user.setId(UUID.randomUUID().toString()); + if (StringUtils.isEmpty(user.getPassword())) { + user.setPassword(CodingUtil.md5(user.getEmail())); + } + user.setCreateTime(createTime); + user.setUpdateTime(createTime); + userMapper.insertSelective(user); + } + return userCreateDTO; } - public UserDTO delete(String userId) { - UserDTO userDTO = baseUserMapper.selectById(userId); - userMapper.deleteByPrimaryKey(userId); - userExtendMapper.deleteByPrimaryKey(userId); - return userDTO; + + public UserDTO getByEmail(String email) { + return baseUserMapper.selectByEmail(email); } + } diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/UserControllerTests.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/UserControllerTests.java index 8d0a45be53..d5431cbca7 100644 --- a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/UserControllerTests.java +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/UserControllerTests.java @@ -2,21 +2,32 @@ package io.metersphere.system.controller; import com.jayway.jsonpath.JsonPath; import io.metersphere.sdk.constants.SessionConstants; +import io.metersphere.sdk.controller.handler.ResultHolder; import io.metersphere.sdk.dto.UserDTO; import io.metersphere.sdk.util.JSON; import io.metersphere.system.domain.User; +import io.metersphere.system.dto.UserMaintainRequest; +import io.metersphere.system.utils.UserTestUtils; +import io.metersphere.utils.JsonUtils; import jakarta.annotation.Resource; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.*; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.ResultMatcher; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import java.util.ArrayList; +import java.util.List; +import java.util.UUID; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @SpringBootTest @@ -28,124 +39,223 @@ public class UserControllerTests { private static String sessionId; private static String csrfToken; + private static final List USER_LIST = new ArrayList<>(); + + //成功入库的用户保存内存中,其他用例会使用到 + private void addUser2List(MvcResult mvcResult) throws Exception { + String returnData = mvcResult.getResponse().getContentAsString(); + ResultHolder resultHolder = JsonUtils.parseObject(returnData, ResultHolder.class); + + //返回请求正常 + Assertions.assertNotNull(resultHolder); + + UserMaintainRequest userMaintainRequest = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), UserMaintainRequest.class); + + //返回值不为空 + Assertions.assertNotNull(userMaintainRequest); + + USER_LIST.addAll(userMaintainRequest.getUserInfoList()); + } + + private void checkUserList() throws Exception { + if (CollectionUtils.isEmpty(USER_LIST)) { + //测试数据初始化入库 + this.testAddSuccess(); + } + } + @BeforeEach public void login() throws Exception { - MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/login") - .content("{\"username\":\"admin\",\"password\":\"metersphere\"}") + if (StringUtils.isAnyBlank(sessionId, csrfToken)) { + MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/login") + .content("{\"username\":\"admin\",\"password\":\"metersphere\"}") + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + .andReturn(); + sessionId = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.sessionId"); + csrfToken = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.csrfToken"); + } + } + + private void requestPost(String url, Object param, ResultMatcher resultMatcher) throws Exception { + mockMvc.perform(MockMvcRequestBuilders.post(url) + .header(SessionConstants.HEADER_TOKEN, sessionId) + .header(SessionConstants.CSRF_TOKEN, csrfToken) + .content(JSON.toJSONString(param)) .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andReturn(); - sessionId = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.sessionId"); - csrfToken = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.csrfToken"); + .andExpect(resultMatcher).andDo(print()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)); + } + + private MvcResult responsePost(String url, Object param) throws Exception { + return mockMvc.perform(MockMvcRequestBuilders.post(url) + .header(SessionConstants.HEADER_TOKEN, sessionId) + .header(SessionConstants.CSRF_TOKEN, csrfToken) + .content(JSON.toJSONString(param)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andDo(print()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn(); + } + + private MvcResult responseGet(String url) throws Exception { + return mockMvc.perform(MockMvcRequestBuilders.get(url) + .header(SessionConstants.HEADER_TOKEN, sessionId) + .header(SessionConstants.CSRF_TOKEN, csrfToken) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andDo(print()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn(); } @Test @Order(1) - public void testAddUser() throws Exception { - UserDTO user = new UserDTO(); - user.setId("user"); - user.setName("user"); - user.setSource("LOCAL"); - user.setEmail("bin@fit2cloud.com"); + public void testAddSuccess() throws Exception { + String url = "/user/add"; + //模拟前台批量添加用户 + UserMaintainRequest userMaintainRequest = UserTestUtils.getSimpleUserCreateDTO(); + MvcResult mvcResult = this.responsePost(url, userMaintainRequest); + this.addUser2List(mvcResult); - user.setSeleniumServer("http://localhost:4444"); + //含有重复的用户名称 + userMaintainRequest = UserTestUtils.getSimpleUserCreateDTO(); + userMaintainRequest.setUserInfoList( + new ArrayList<>() {{ + add(new User() {{ + setName("tianyang.repeat"); + setEmail("tianyang.repeat.name.1@126.com"); + setSource("LOCAL"); + }}); - mockMvc.perform(MockMvcRequestBuilders.post("/user/add") - .header(SessionConstants.HEADER_TOKEN, sessionId) - .header(SessionConstants.CSRF_TOKEN, csrfToken) - .content(JSON.toJSONString(user)) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)); + add(new User() {{ + setName("tianyang.repeat"); + setEmail("tianyang.repeat.name.2@126.com"); + setSource("LOCAL"); + }}); + }} + ); + mvcResult = this.responsePost(url, userMaintainRequest); + this.addUser2List(mvcResult); } @Test @Order(2) - public void testAddUserFailed() throws Exception { - UserDTO user = new UserDTO(); - user.setId("user2"); + public void testAddError() throws Exception { + String url = "/user/add"; + UserMaintainRequest userMaintainRequest; + boolean projectIsEmpty = true; + boolean organizationIsEmpty = true; + boolean userIsEmpty = true; + /* + * 校验参数不合法的反例 + * 每一次校验,使用getErrorUserCreateDTO方法重新获取参数,避免上一步的参数干扰 + */ + ResultMatcher resultMatcher = status().isBadRequest(); + //所有参数都为空 + userMaintainRequest = UserTestUtils.getErrorUserCreateDTO(organizationIsEmpty, projectIsEmpty, userIsEmpty); + this.requestPost(url, userMaintainRequest, resultMatcher); + //组织ID为空 + userMaintainRequest = UserTestUtils.getErrorUserCreateDTO(organizationIsEmpty, !projectIsEmpty, !userIsEmpty); + this.requestPost(url, userMaintainRequest, resultMatcher); + //项目ID为空 + userMaintainRequest = UserTestUtils.getErrorUserCreateDTO(!organizationIsEmpty, projectIsEmpty, !userIsEmpty); + this.requestPost(url, userMaintainRequest, resultMatcher); + //没有用户 + userMaintainRequest = UserTestUtils.getErrorUserCreateDTO(!organizationIsEmpty, !projectIsEmpty, userIsEmpty); + this.requestPost(url, userMaintainRequest, resultMatcher); + //含有用户名称为空的数据 + userMaintainRequest = UserTestUtils.getSimpleUserCreateDTO(); + userMaintainRequest.getUserInfoList().add(new User() {{ + setEmail("tianyang.name.empty@126.com"); + setSource("LOCAL"); + }}); + this.requestPost(url, userMaintainRequest, resultMatcher); + //含有用户邮箱为空的数据 + userMaintainRequest = UserTestUtils.getSimpleUserCreateDTO(); + userMaintainRequest.getUserInfoList().add(new User() {{ + setName("tianyang.email.empty"); + setSource("LOCAL"); + }}); + this.requestPost(url, userMaintainRequest, resultMatcher); + //用户邮箱不符合标准 + userMaintainRequest = UserTestUtils.getSimpleUserCreateDTO(); + userMaintainRequest.getUserInfoList().add(new User() {{ + setName("用户邮箱放飞自我"); + setEmail("用户邮箱放飞自我"); + setSource("LOCAL"); + }}); + this.requestPost(url, userMaintainRequest, resultMatcher); + //用户来源为空 + userMaintainRequest = UserTestUtils.getSimpleUserCreateDTO(); + userMaintainRequest.getUserInfoList().add(new User() {{ + setName("tianyang.source.empty"); + setEmail("tianyang.source.empty@126.com"); + }}); + this.requestPost(url, userMaintainRequest, resultMatcher); - user.setSeleniumServer("http://localhost:4444"); - - mockMvc.perform(MockMvcRequestBuilders.post("/user/add") - .header(SessionConstants.HEADER_TOKEN, sessionId) - .header(SessionConstants.CSRF_TOKEN, csrfToken) - .content(JSON.toJSONString(user)) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isBadRequest()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)); + /* + * 校验业务判断出错的反例 (500 error) + * 需要保证数据库有正常数据 + */ + resultMatcher = status().is5xxServerError(); + this.checkUserList(); + //含有重复的用户邮箱 + userMaintainRequest = UserTestUtils.getErrorUserCreateDTO(!organizationIsEmpty, !projectIsEmpty, !userIsEmpty); + String firstUserEmail = userMaintainRequest.getUserInfoList().get(0).getEmail(); + userMaintainRequest.getUserInfoList().add(new User() {{ + setName("tianyang.no.error4"); + setEmail(firstUserEmail); + setSource("LOCAL"); + }}); + this.requestPost(url, userMaintainRequest, resultMatcher); + //测试请求参数中含有数据库中已存在的邮箱情况 + userMaintainRequest = UserTestUtils.getErrorUserCreateDTO(!organizationIsEmpty, !projectIsEmpty, userIsEmpty); + userMaintainRequest.setUserInfoList( + new ArrayList<>() {{ + add(new User() {{ + setName("tianyang.repeat.email.db"); + setEmail(UserTestUtils.USER_DEFAULT_EMAIL); + setSource("LOCAL"); + }}); + }} + ); + this.requestPost(url, userMaintainRequest, resultMatcher); } @Test @Order(3) - public void testGetUser() throws Exception { - mockMvc.perform(MockMvcRequestBuilders.get("/user/get/user") - .header(SessionConstants.HEADER_TOKEN, sessionId) - .header(SessionConstants.CSRF_TOKEN, csrfToken)) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("$.data.id").value("user")); - } + public void testGetByEmailSuccess() throws Exception { + this.checkUserList(); + String url = "/user/get/" + UserTestUtils.USER_DEFAULT_EMAIL; + MvcResult mvcResult = this.responseGet(url); + String returnData = mvcResult.getResponse().getContentAsString(); + ResultHolder resultHolder = JsonUtils.parseObject(returnData, ResultHolder.class); + //返回请求正常 + Assertions.assertNotNull(resultHolder); - @Test - @Order(4) - public void testUpdateUser() throws Exception { - UserDTO user = new UserDTO(); - user.setId("user"); - user.setName("useristrator"); + UserDTO userDTO = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), UserDTO.class); + //返回值不为空 + Assertions.assertNotNull(userDTO); - mockMvc.perform(MockMvcRequestBuilders.post("/user/update") - .header(SessionConstants.HEADER_TOKEN, sessionId) - .header(SessionConstants.CSRF_TOKEN, csrfToken) - .content(JSON.toJSONString(user)) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)); + //返回邮箱等于参数邮箱,且用户名合法 + Assertions.assertEquals(userDTO.getEmail(), UserTestUtils.USER_DEFAULT_EMAIL); + Assertions.assertNotNull(userDTO.getName()); } @Test - @Order(5) - public void testDeleteUser() throws Exception { + @Order(3) + public void testGetByEmailError() throws Exception { + //测试使用任意参数,不能获取到任何用户信息 + this.checkUserList(); + String url = "/user/get/" + UUID.randomUUID(); + MvcResult mvcResult = this.responseGet(url); - mockMvc.perform(MockMvcRequestBuilders.get("/user/delete/user") - .header(SessionConstants.HEADER_TOKEN, sessionId) - .header(SessionConstants.CSRF_TOKEN, csrfToken)) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("$.data.id").value("user")); - } - - @Test - @Order(7) - public void testBatchAddUser3() throws Exception { - var users = new ArrayList(); - int size = 123; - for (int i = 0; i < size; i++) { - User user = new User(); - user.setId("batch3_" + i); - user.setName("batch3_" + i); - user.setSource("LOCAL"); - user.setEmail("bin@fit2cloud.com"); - users.add(user); - } - - mockMvc.perform(MockMvcRequestBuilders.post("/user/batch-add3") - .header(SessionConstants.HEADER_TOKEN, sessionId) - .header(SessionConstants.CSRF_TOKEN, csrfToken) - .content(JSON.toJSONString(users)) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)); - -// mockMvc.perform(MockMvcRequestBuilders.get("/user/count") -// .header(SessionConstants.HEADER_TOKEN, sessionId) -// .header(SessionConstants.CSRF_TOKEN, csrfToken) -// .contentType(MediaType.APPLICATION_JSON)) -// .andExpect(status().isOk()) -// .andExpect(content().contentType(MediaType.APPLICATION_JSON)) -// .andExpect(jsonPath("$.data").value(size)); + String returnData = mvcResult.getResponse().getContentAsString(); + ResultHolder resultHolder = JsonUtils.parseObject(returnData, ResultHolder.class); + //返回请求正常 + Assertions.assertNotNull(resultHolder); + //返回值为空 + Assertions.assertNull(resultHolder.getData()); } } diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/utils/UserTestUtils.java b/backend/services/system-setting/src/test/java/io/metersphere/system/utils/UserTestUtils.java new file mode 100644 index 0000000000..0ce2c76795 --- /dev/null +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/utils/UserTestUtils.java @@ -0,0 +1,58 @@ +package io.metersphere.system.utils; + +import io.metersphere.system.domain.User; +import io.metersphere.system.dto.UserMaintainRequest; + +import java.util.ArrayList; + +public class UserTestUtils { + + public static final String USER_DEFAULT_NAME = "tianyang.no.1"; + public static final String USER_DEFAULT_EMAIL = "tianyang.no.1@126.com"; + public static final String ORGANIZATION_ID = "ms-organization"; + public static final String PROJECT_ID = "ms-project"; + + public static UserMaintainRequest getSimpleUserCreateDTO() { + UserMaintainRequest userMaintainRequest = new UserMaintainRequest(); + userMaintainRequest.setOrganizationId(ORGANIZATION_ID); + userMaintainRequest.setProjectId(PROJECT_ID); + userMaintainRequest.setUserInfoList(new ArrayList<>() {{ + add(new User() {{ + setName(USER_DEFAULT_NAME); + setEmail(USER_DEFAULT_EMAIL); + setSource("LOCAL"); + }}); + add(new User() {{ + setName("tianyang.no.2"); + setEmail("tianyang.no.2@126.com"); + setSource("LOCAL"); + }}); + }}); + return userMaintainRequest; + } + + public static UserMaintainRequest getErrorUserCreateDTO(boolean organizationIsEmpty, boolean projectIsEmpty, boolean userIsEmpty) { + UserMaintainRequest userMaintainRequest = new UserMaintainRequest(); + if (!organizationIsEmpty) { + userMaintainRequest.setOrganizationId(ORGANIZATION_ID); + } + if (!projectIsEmpty) { + userMaintainRequest.setProjectId(PROJECT_ID); + } + if (!userIsEmpty) { + userMaintainRequest.setUserInfoList(new ArrayList<>() {{ + add(new User() {{ + setName("tianyang.error.1"); + setEmail("tianyang.error.1@126.com"); + setSource("LOCAL"); + }}); + add(new User() {{ + setName("tianyang.error.2"); + setEmail("tianyang.error.2@126.com"); + setSource("LOCAL"); + }}); + }}); + } + return userMaintainRequest; + } +} diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanController.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanController.java index fa8eab22bd..6c2bf78ab7 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanController.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanController.java @@ -26,7 +26,7 @@ public class TestPlanController { @PostMapping("/delete/batch") public void deleteBatch(@RequestBody List idList) { if (CollectionUtils.isEmpty(idList)) { - MSException.throwException("The ids cannot be empty!"); + throw new MSException("The ids cannot be empty!"); } testPlanService.batchDelete(idList); } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanService.java index 74ca5d012c..2adfcfdf54 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanService.java @@ -52,10 +52,10 @@ public class TestPlanService { public TestPlanDTO add(@NotNull TestPlanDTO testPlanCreateRequest) { User user = SessionUtils.getUser(); if (user == null) { - MSException.throwException("Cannot find user!"); + throw new MSException("Cannot find user!"); } if (StringUtils.equals(testPlanCreateRequest.getParentId(), testPlanCreateRequest.getId())) { - MSException.throwException("The parent test plan cannot be the same as the current test plan!"); + throw new MSException("The parent test plan cannot be the same as the current test plan!"); } if (StringUtils.isBlank(testPlanCreateRequest.getId())) {