From c4bcc25c5a586a616e02c35762304f9a247cd022 Mon Sep 17 00:00:00 2001 From: song-cc-rock Date: Thu, 28 Mar 2024 17:12:40 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E7=B3=BB=E7=BB=9F=E8=AE=BE=E7=BD=AE):=20?= =?UTF-8?q?=E8=A1=A5=E5=85=85=E6=A8=A1=E6=9D=BF=E7=AE=A1=E7=90=86=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/domain/CustomFieldOption.java | 17 +++-- .../domain/CustomFieldOptionExample.java | 60 +++++++++++++++++ .../system/mapper/CustomFieldOptionMapper.xml | 32 ++++++++-- .../3.0.0/ddl/V3.0.0_11__system_setting.sql | 1 + .../migration/3.0.0/dml/V3.0.0_11_1__data.sql | 32 +++++----- .../src/main/resources/i18n/system.properties | 2 + .../resources/i18n/system_en_US.properties | 2 + .../resources/i18n/system_zh_CN.properties | 2 + .../resources/i18n/system_zh_TW.properties | 2 + .../ProjectCustomFieldControllerTests.java | 8 ++- .../dto/request/DefaultBugCustomField.java | 11 ++-- .../request/DefaultFunctionalCustomField.java | 11 ++-- .../sdk/request/CustomFieldOptionRequest.java | 5 ++ .../service/BaseCustomFieldOptionService.java | 15 ++++- .../main/resources/systemGeneratorConfig.xml | 4 +- .../base/BaseCustomFieldTestService.java | 3 +- ...rganizationCustomFieldControllerTests.java | 13 ++-- .../SystemProjectControllerTests.java | 2 + frontend/src/models/setting/template.ts | 1 + .../components/addFieldToTemplateDrawer.vue | 2 +- .../template/components/addTemplate.vue | 64 +++++++++++++++---- .../caseTemplateRightSystemField.vue | 32 ++++++++++ .../defectTemplateRightSystemField.vue | 43 +++++++++++++ .../template/components/editFieldDrawer.vue | 8 ++- .../template/components/fieldSetting.vue | 8 +-- .../template/components/viewTemplate.vue | 26 +++++++- .../organization/template/locale/en-US.ts | 4 ++ .../organization/template/locale/zh-CN.ts | 4 ++ 28 files changed, 341 insertions(+), 73 deletions(-) create mode 100644 frontend/src/views/setting/organization/template/components/caseTemplateRightSystemField.vue create mode 100644 frontend/src/views/setting/organization/template/components/defectTemplateRightSystemField.vue diff --git a/backend/framework/domain/src/main/java/io/metersphere/system/domain/CustomFieldOption.java b/backend/framework/domain/src/main/java/io/metersphere/system/domain/CustomFieldOption.java index 4ffa2cd48c..843277b45b 100644 --- a/backend/framework/domain/src/main/java/io/metersphere/system/domain/CustomFieldOption.java +++ b/backend/framework/domain/src/main/java/io/metersphere/system/domain/CustomFieldOption.java @@ -1,12 +1,16 @@ 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 jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.Data; + import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; -import lombok.Data; @Data public class CustomFieldOption implements Serializable { @@ -29,13 +33,18 @@ public class CustomFieldOption implements Serializable { @NotNull(message = "{custom_field_option.internal.not_blank}", groups = {Created.class}) private Boolean internal; + @Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "{custom_field_option.pos.not_blank}", groups = {Created.class}) + private Long pos; + private static final long serialVersionUID = 1L; public enum Column { fieldId("field_id", "fieldId", "VARCHAR", false), value("value", "value", "VARCHAR", true), text("text", "text", "VARCHAR", true), - internal("internal", "internal", "BIT", false); + internal("internal", "internal", "BIT", false), + pos("pos", "pos", "BIGINT", false); private static final String BEGINNING_DELIMITER = "`"; diff --git a/backend/framework/domain/src/main/java/io/metersphere/system/domain/CustomFieldOptionExample.java b/backend/framework/domain/src/main/java/io/metersphere/system/domain/CustomFieldOptionExample.java index edec159e3a..8bda91df5e 100644 --- a/backend/framework/domain/src/main/java/io/metersphere/system/domain/CustomFieldOptionExample.java +++ b/backend/framework/domain/src/main/java/io/metersphere/system/domain/CustomFieldOptionExample.java @@ -373,6 +373,66 @@ public class CustomFieldOptionExample { addCriterion("internal not between", value1, value2, "internal"); return (Criteria) this; } + + public Criteria andPosIsNull() { + addCriterion("pos is null"); + return (Criteria) this; + } + + public Criteria andPosIsNotNull() { + addCriterion("pos is not null"); + return (Criteria) this; + } + + public Criteria andPosEqualTo(Long value) { + addCriterion("pos =", value, "pos"); + return (Criteria) this; + } + + public Criteria andPosNotEqualTo(Long value) { + addCriterion("pos <>", value, "pos"); + return (Criteria) this; + } + + public Criteria andPosGreaterThan(Long value) { + addCriterion("pos >", value, "pos"); + return (Criteria) this; + } + + public Criteria andPosGreaterThanOrEqualTo(Long value) { + addCriterion("pos >=", value, "pos"); + return (Criteria) this; + } + + public Criteria andPosLessThan(Long value) { + addCriterion("pos <", value, "pos"); + return (Criteria) this; + } + + public Criteria andPosLessThanOrEqualTo(Long value) { + addCriterion("pos <=", value, "pos"); + return (Criteria) this; + } + + public Criteria andPosIn(List values) { + addCriterion("pos in", values, "pos"); + return (Criteria) this; + } + + public Criteria andPosNotIn(List values) { + addCriterion("pos not in", values, "pos"); + return (Criteria) this; + } + + public Criteria andPosBetween(Long value1, Long value2) { + addCriterion("pos between", value1, value2, "pos"); + return (Criteria) this; + } + + public Criteria andPosNotBetween(Long value1, Long value2) { + addCriterion("pos not between", value1, value2, "pos"); + return (Criteria) this; + } } public static class Criteria extends GeneratedCriteria { diff --git a/backend/framework/domain/src/main/java/io/metersphere/system/mapper/CustomFieldOptionMapper.xml b/backend/framework/domain/src/main/java/io/metersphere/system/mapper/CustomFieldOptionMapper.xml index df6b24d4de..440f626712 100644 --- a/backend/framework/domain/src/main/java/io/metersphere/system/mapper/CustomFieldOptionMapper.xml +++ b/backend/framework/domain/src/main/java/io/metersphere/system/mapper/CustomFieldOptionMapper.xml @@ -6,6 +6,7 @@ + @@ -66,7 +67,7 @@ - field_id, `value`, `text`, internal + field_id, `value`, `text`, internal, pos @@ -158,6 +165,9 @@ internal = #{record.internal,jdbcType=BIT}, + + pos = #{record.pos,jdbcType=BIGINT}, + @@ -168,7 +178,8 @@ set field_id = #{record.fieldId,jdbcType=VARCHAR}, `value` = #{record.value,jdbcType=VARCHAR}, `text` = #{record.text,jdbcType=VARCHAR}, - internal = #{record.internal,jdbcType=BIT} + internal = #{record.internal,jdbcType=BIT}, + pos = #{record.pos,jdbcType=BIGINT} @@ -182,6 +193,9 @@ internal = #{internal,jdbcType=BIT}, + + pos = #{pos,jdbcType=BIGINT}, + where field_id = #{fieldId,jdbcType=VARCHAR} and `value` = #{value,jdbcType=VARCHAR} @@ -189,17 +203,18 @@ update custom_field_option set `text` = #{text,jdbcType=VARCHAR}, - internal = #{internal,jdbcType=BIT} + internal = #{internal,jdbcType=BIT}, + pos = #{pos,jdbcType=BIGINT} where field_id = #{fieldId,jdbcType=VARCHAR} and `value` = #{value,jdbcType=VARCHAR} insert into custom_field_option - (field_id, `value`, `text`, internal) + (field_id, `value`, `text`, internal, pos) values (#{item.fieldId,jdbcType=VARCHAR}, #{item.value,jdbcType=VARCHAR}, #{item.text,jdbcType=VARCHAR}, - #{item.internal,jdbcType=BIT}) + #{item.internal,jdbcType=BIT}, #{item.pos,jdbcType=BIGINT}) @@ -224,6 +239,9 @@ #{item.internal,jdbcType=BIT} + + #{item.pos,jdbcType=BIGINT} + ) diff --git a/backend/framework/domain/src/main/resources/migration/3.0.0/ddl/V3.0.0_11__system_setting.sql b/backend/framework/domain/src/main/resources/migration/3.0.0/ddl/V3.0.0_11__system_setting.sql index 664213e06f..71ccec21ad 100644 --- a/backend/framework/domain/src/main/resources/migration/3.0.0/ddl/V3.0.0_11__system_setting.sql +++ b/backend/framework/domain/src/main/resources/migration/3.0.0/ddl/V3.0.0_11__system_setting.sql @@ -373,6 +373,7 @@ CREATE TABLE IF NOT EXISTS custom_field_option( `value` VARCHAR(50) NOT NULL COMMENT '选项值' , `text` VARCHAR(255) NOT NULL COMMENT '选项值名称' , `internal` BIT NOT NULL DEFAULT 0 COMMENT '是否内置' , + `pos` BIGINT NOT NULL COMMENT '自定义排序,间隔5000' , PRIMARY KEY (field_id,value) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 diff --git a/backend/framework/domain/src/main/resources/migration/3.0.0/dml/V3.0.0_11_1__data.sql b/backend/framework/domain/src/main/resources/migration/3.0.0/dml/V3.0.0_11_1__data.sql index 3ebc73c73d..287c9a658b 100644 --- a/backend/framework/domain/src/main/resources/migration/3.0.0/dml/V3.0.0_11_1__data.sql +++ b/backend/framework/domain/src/main/resources/migration/3.0.0/dml/V3.0.0_11_1__data.sql @@ -274,17 +274,17 @@ INSERT INTO test_resource_pool_blob (id, configuration) VALUES ((select id from INSERT INTO project_test_resource_pool (project_id, test_resource_pool_id) VALUES ('100001100001', (SELECT id FROM test_resource_pool WHERE name = '默认资源池')); -- 初始化组织功能用例字段 INSERT INTO custom_field(id, name, scene, `type`, remark, internal, scope_type, create_time, update_time, create_user, scope_id) VALUES(UUID_SHORT(), 'functional_priority', 'FUNCTIONAL', 'SELECT', '', 1, 'ORGANIZATION', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', '100001'); -INSERT INTO custom_field_option (field_id,value,`text`,internal) VALUES ((select id from custom_field where name = 'functional_priority'), 'P0', 'P0', 1); -INSERT INTO custom_field_option (field_id,value,`text`,internal) VALUES ((select id from custom_field where name = 'functional_priority'), 'P1', 'P1', 1); -INSERT INTO custom_field_option (field_id,value,`text`,internal) VALUES ((select id from custom_field where name = 'functional_priority'), 'P2', 'P2', 1); -INSERT INTO custom_field_option (field_id,value,`text`,internal) VALUES ((select id from custom_field where name = 'functional_priority'), 'P3', 'P3', 1); +INSERT INTO custom_field_option (field_id,value,`text`,internal, pos) VALUES ((select id from custom_field where name = 'functional_priority'), 'P0', 'P0', 1, 5000); +INSERT INTO custom_field_option (field_id,value,`text`,internal, pos) VALUES ((select id from custom_field where name = 'functional_priority'), 'P1', 'P1', 1, 10000); +INSERT INTO custom_field_option (field_id,value,`text`,internal, pos) VALUES ((select id from custom_field where name = 'functional_priority'), 'P2', 'P2', 1, 15000); +INSERT INTO custom_field_option (field_id,value,`text`,internal, pos) VALUES ((select id from custom_field where name = 'functional_priority'), 'P3', 'P3', 1, 20000); -- 初始化组织缺陷严重程度 INSERT INTO custom_field(id, name, scene, `type`, remark, internal, scope_type, create_time, update_time, create_user, scope_id) VALUES(UUID_SHORT(), 'bug_degree', 'BUG', 'SELECT', '', 1, 'ORGANIZATION', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', '100001'); -INSERT INTO custom_field_option (field_id,value,`text`,internal) VALUES ((select id from custom_field where name = 'bug_degree'), UUID_SHORT(), '提示', 1); -INSERT INTO custom_field_option (field_id,value,`text`,internal) VALUES ((select id from custom_field where name = 'bug_degree'), UUID_SHORT(), '一般', 1); -INSERT INTO custom_field_option (field_id,value,`text`,internal) VALUES ((select id from custom_field where name = 'bug_degree'), UUID_SHORT(), '严重', 1); -INSERT INTO custom_field_option (field_id,value,`text`,internal) VALUES ((select id from custom_field where name = 'bug_degree'), UUID_SHORT(), '致命', 1); +INSERT INTO custom_field_option (field_id,value,`text`,internal, pos) VALUES ((select id from custom_field where name = 'bug_degree'), UUID_SHORT(), '提示', 1, 5000); +INSERT INTO custom_field_option (field_id,value,`text`,internal, pos) VALUES ((select id from custom_field where name = 'bug_degree'), UUID_SHORT(), '一般', 1, 10000); +INSERT INTO custom_field_option (field_id,value,`text`,internal, pos) VALUES ((select id from custom_field where name = 'bug_degree'), UUID_SHORT(), '严重', 1, 15000); +INSERT INTO custom_field_option (field_id,value,`text`,internal, pos) VALUES ((select id from custom_field where name = 'bug_degree'), UUID_SHORT(), '致命', 1, 20000); -- 初始化组织功能用例默认模板, 缺陷默认模板 INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part, scene) VALUES (UUID_SHORT(), 'functional_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'ORGANIZATION', '100001', 0, 'FUNCTIONAL'); @@ -299,17 +299,17 @@ INSERT INTO project_version (id, project_id, name, description, status, latest, -- 初始化项目功能用例字段 INSERT INTO custom_field(id, name, scene, `type`, remark, internal, scope_type, create_time, update_time, create_user, scope_id, ref_id) VALUES(UUID_SHORT(), 'functional_priority', 'FUNCTIONAL', 'SELECT', '', 1, 'PROJECT', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', '100001100001', (SELECT id FROM (SELECT * FROM custom_field) t where name = 'functional_priority')); -INSERT INTO custom_field_option (field_id,value,`text`,internal) VALUES ((select id from custom_field where name = 'functional_priority' and scope_id = '100001100001'), 'P0', 'P0', 1); -INSERT INTO custom_field_option (field_id,value,`text`,internal) VALUES ((select id from custom_field where name = 'functional_priority' and scope_id = '100001100001'), 'P1', 'P1', 1); -INSERT INTO custom_field_option (field_id,value,`text`,internal) VALUES ((select id from custom_field where name = 'functional_priority' and scope_id = '100001100001'), 'P2', 'P2', 1); -INSERT INTO custom_field_option (field_id,value,`text`,internal) VALUES ((select id from custom_field where name = 'functional_priority' and scope_id = '100001100001'), 'P3', 'P3', 1); +INSERT INTO custom_field_option (field_id,value,`text`,internal, pos) VALUES ((select id from custom_field where name = 'functional_priority' and scope_id = '100001100001'), 'P0', 'P0', 1, 5000); +INSERT INTO custom_field_option (field_id,value,`text`,internal, pos) VALUES ((select id from custom_field where name = 'functional_priority' and scope_id = '100001100001'), 'P1', 'P1', 1, 10000); +INSERT INTO custom_field_option (field_id,value,`text`,internal, pos) VALUES ((select id from custom_field where name = 'functional_priority' and scope_id = '100001100001'), 'P2', 'P2', 1, 15000); +INSERT INTO custom_field_option (field_id,value,`text`,internal, pos) VALUES ((select id from custom_field where name = 'functional_priority' and scope_id = '100001100001'), 'P3', 'P3', 1, 20000); -- 初始化项目缺陷严重程度 INSERT INTO custom_field(id, name, scene, `type`, remark, internal, scope_type, create_time, update_time, create_user, scope_id, ref_id) VALUES(UUID_SHORT(), 'bug_degree', 'BUG', 'SELECT', '', 1, 'PROJECT', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', '100001100001', (SELECT id FROM (SELECT * FROM custom_field) t where name = 'bug_degree')); -INSERT INTO custom_field_option (field_id,value,`text`,internal) VALUES ((select id from custom_field where name = 'bug_degree' and scope_id = '100001100001'), UUID_SHORT(), '提示', 1); -INSERT INTO custom_field_option (field_id,value,`text`,internal) VALUES ((select id from custom_field where name = 'bug_degree' and scope_id = '100001100001'), UUID_SHORT(), '一般', 1); -INSERT INTO custom_field_option (field_id,value,`text`,internal) VALUES ((select id from custom_field where name = 'bug_degree' and scope_id = '100001100001'), UUID_SHORT(), '严重', 1); -INSERT INTO custom_field_option (field_id,value,`text`,internal) VALUES ((select id from custom_field where name = 'bug_degree' and scope_id = '100001100001'), UUID_SHORT(), '致命', 1); +INSERT INTO custom_field_option (field_id,value,`text`,internal, pos) VALUES ((select id from custom_field where name = 'bug_degree' and scope_id = '100001100001'), UUID_SHORT(), '提示', 1, 5000); +INSERT INTO custom_field_option (field_id,value,`text`,internal, pos) VALUES ((select id from custom_field where name = 'bug_degree' and scope_id = '100001100001'), UUID_SHORT(), '一般', 1, 10000); +INSERT INTO custom_field_option (field_id,value,`text`,internal, pos) VALUES ((select id from custom_field where name = 'bug_degree' and scope_id = '100001100001'), UUID_SHORT(), '严重', 1, 15000); +INSERT INTO custom_field_option (field_id,value,`text`,internal, pos) VALUES ((select id from custom_field where name = 'bug_degree' and scope_id = '100001100001'), UUID_SHORT(), '致命', 1, 20000); -- 初始化项目功能用例默认模板, 缺陷默认模板 INSERT INTO template (id,name,remark,internal,update_time,create_time,create_user,scope_type,scope_id,enable_third_part, scene, ref_id) VALUES (UUID_SHORT(), 'functional_default', '', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'PROJECT', '100001100001', 0, 'FUNCTIONAL', (SELECT id FROM (SELECT * FROM template) t where name = 'functional_default')); diff --git a/backend/framework/sdk/src/main/resources/i18n/system.properties b/backend/framework/sdk/src/main/resources/i18n/system.properties index 7518448eff..dffd202b41 100644 --- a/backend/framework/sdk/src/main/resources/i18n/system.properties +++ b/backend/framework/sdk/src/main/resources/i18n/system.properties @@ -227,6 +227,8 @@ custom_field_option.value.not_blank=选项值不能为空 custom_field_option.value.length_range=选项值长度必须在{min}和{max}之间 custom_field_option.text.not_blank=选项值名称不能为空 custom_field_option.text.length_range=选项值名称长度必须在{min}和{max}之间 +custom_field_option.internal.not_blank=选项值是否内置不能为空 +custom_field_option.pos.not_blank=选项值顺序不能为空 # permission permission.system_plugin.name=插件 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 8c28dd1cc2..a948d83710 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 @@ -229,6 +229,8 @@ custom_field_option.value.not_blank=value cannot be empty custom_field_option.value.length_range=value length must be between {min} and {max} custom_field_option.text.not_blank=text cannot be empty custom_field_option.text.length_range=text length must be between {min} and {max} +custom_field_option.internal.not_blank=option_value_internal_cannot_be_null +custom_field_option.pos.not_blank=option_value_pos_cannot_be_empty # permission permission.system_plugin.name=Plugin permission.system_organization_project.name=Organization Project 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 d2e87938e0..9fae99787a 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 @@ -229,6 +229,8 @@ custom_field_option.value.not_blank=选项值不能为空 custom_field_option.value.length_range=选项值长度必须在{min}和{max}之间 custom_field_option.text.not_blank=选项值名称不能为空 custom_field_option.text.length_range=选项值名称长度必须在{min}和{max}之间 +custom_field_option.internal.not_blank=选项值是否内置不能为空 +custom_field_option.pos.not_blank=选项值顺序不能为空 # permission permission.system_plugin.name=插件 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 1ebb091f1c..2d22eafac5 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 @@ -228,6 +228,8 @@ custom_field_option.value.not_blank=選項值不能為空 custom_field_option.value.length_range=選項值長度必須在{min}和{max}之間 custom_field_option.text.not_blank=選項值名稱不能為空 custom_field_option.text.length_range=選項值名稱長度必須在{min}和{max}之間 +custom_field_option.internal.not_blank=選項值是否內置不能爲空 +custom_field_option.pos.not_blank=選項值順序不能爲空 # permission permission.system_plugin.name=插件 diff --git a/backend/services/project-management/src/test/java/io/metersphere/project/controller/ProjectCustomFieldControllerTests.java b/backend/services/project-management/src/test/java/io/metersphere/project/controller/ProjectCustomFieldControllerTests.java index 7b439a2d22..724c8a4dce 100644 --- a/backend/services/project-management/src/test/java/io/metersphere/project/controller/ProjectCustomFieldControllerTests.java +++ b/backend/services/project-management/src/test/java/io/metersphere/project/controller/ProjectCustomFieldControllerTests.java @@ -2,13 +2,13 @@ package io.metersphere.project.controller; import io.metersphere.project.service.ProjectCustomFieldLogService; import io.metersphere.sdk.constants.*; +import io.metersphere.sdk.util.BeanUtils; +import io.metersphere.system.base.BaseTest; +import io.metersphere.system.controller.param.CustomFieldUpdateRequestDefinition; import io.metersphere.system.domain.*; import io.metersphere.system.dto.sdk.CustomFieldDTO; import io.metersphere.system.dto.sdk.request.CustomFieldOptionRequest; import io.metersphere.system.dto.sdk.request.CustomFieldUpdateRequest; -import io.metersphere.sdk.util.BeanUtils; -import io.metersphere.system.base.BaseTest; -import io.metersphere.system.controller.param.CustomFieldUpdateRequestDefinition; import io.metersphere.system.log.constants.OperationLogModule; import io.metersphere.system.log.constants.OperationLogType; import io.metersphere.system.mapper.CustomFieldMapper; @@ -92,6 +92,7 @@ public class ProjectCustomFieldControllerTests extends BaseTest { CustomFieldOptionRequest customFieldOptionRequest = new CustomFieldOptionRequest(); customFieldOptionRequest.setValue("1111"); customFieldOptionRequest.setText("test"); + customFieldOptionRequest.setPos(5000L); request.setEnableOptionKey(true); List optionRequests = Arrays.asList(customFieldOptionRequest); request.setOptions(optionRequests); @@ -165,6 +166,7 @@ public class ProjectCustomFieldControllerTests extends BaseTest { CustomFieldOptionRequest customFieldOptionRequest = new CustomFieldOptionRequest(); customFieldOptionRequest.setValue("11112"); customFieldOptionRequest.setText("test1"); + customFieldOptionRequest.setPos(5000L); List optionRequests = Arrays.asList(customFieldOptionRequest); request.setOptions(optionRequests); this.requestPostWithOk(DEFAULT_UPDATE, request); diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/dto/request/DefaultBugCustomField.java b/backend/services/system-setting/src/main/java/io/metersphere/system/dto/request/DefaultBugCustomField.java index 5a3c8ca7bf..fdb7376c6d 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/dto/request/DefaultBugCustomField.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/dto/request/DefaultBugCustomField.java @@ -18,10 +18,10 @@ public enum DefaultBugCustomField { */ DEGREE("bug_degree", CustomFieldType.SELECT, Arrays.asList( - getNewOption(IDGenerator.nextStr(), "提示"), - getNewOption(IDGenerator.nextStr(), "一般"), - getNewOption(IDGenerator.nextStr(), "严重"), - getNewOption(IDGenerator.nextStr(), "致命") + getNewOption(IDGenerator.nextStr(), "提示", 5000L), + getNewOption(IDGenerator.nextStr(), "一般", 10000L), + getNewOption(IDGenerator.nextStr(), "严重", 15000L), + getNewOption(IDGenerator.nextStr(), "致命", 20000L) ) ); @@ -47,10 +47,11 @@ public enum DefaultBugCustomField { return options; } - private static CustomFieldOption getNewOption(String value, String text) { + private static CustomFieldOption getNewOption(String value, String text, Long pos) { CustomFieldOption customFieldOption = new CustomFieldOption(); customFieldOption.setValue(value); customFieldOption.setText(text); + customFieldOption.setPos(pos); customFieldOption.setInternal(true); return customFieldOption; } diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/dto/request/DefaultFunctionalCustomField.java b/backend/services/system-setting/src/main/java/io/metersphere/system/dto/request/DefaultFunctionalCustomField.java index 8b7eff1341..c8ef9ad200 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/dto/request/DefaultFunctionalCustomField.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/dto/request/DefaultFunctionalCustomField.java @@ -14,10 +14,10 @@ public enum DefaultFunctionalCustomField { PRIORITY("functional_priority", CustomFieldType.SELECT, Arrays.asList( - getNewOption("P0", "P0"), - getNewOption("P1", "P1"), - getNewOption("P2", "P2"), - getNewOption("P3", "P3") + getNewOption("P0", "P0", 5000L), + getNewOption("P1", "P1", 10000L), + getNewOption("P2", "P2", 15000L), + getNewOption("P3", "P3", 20000L) ) ); @@ -43,10 +43,11 @@ public enum DefaultFunctionalCustomField { return options; } - private static CustomFieldOption getNewOption(String value, String text) { + private static CustomFieldOption getNewOption(String value, String text, Long pos) { CustomFieldOption customFieldOption = new CustomFieldOption(); customFieldOption.setValue(value); customFieldOption.setText(text); + customFieldOption.setPos(pos); customFieldOption.setInternal(true); return customFieldOption; } diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/dto/sdk/request/CustomFieldOptionRequest.java b/backend/services/system-setting/src/main/java/io/metersphere/system/dto/sdk/request/CustomFieldOptionRequest.java index e0d907f02c..d94b0e7f5b 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/dto/sdk/request/CustomFieldOptionRequest.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/dto/sdk/request/CustomFieldOptionRequest.java @@ -4,6 +4,7 @@ import io.metersphere.validation.groups.Created; import io.metersphere.validation.groups.Updated; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import lombok.Data; @@ -18,4 +19,8 @@ public class CustomFieldOptionRequest { @NotBlank(message = "{custom_field_option.text.not_blank}", groups = {Created.class, Updated.class}) @Size(min = 1, max = 255, message = "{custom_field_option.text.length_range}", groups = {Created.class, Updated.class}) private String text; + + @Schema(title = "选项值顺序", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "{custom_field_option.pos.not_blank}", groups = {Created.class}) + private Long pos; } diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/service/BaseCustomFieldOptionService.java b/backend/services/system-setting/src/main/java/io/metersphere/system/service/BaseCustomFieldOptionService.java index 98a1e180d3..bb02895370 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/service/BaseCustomFieldOptionService.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/service/BaseCustomFieldOptionService.java @@ -1,9 +1,9 @@ package io.metersphere.system.service; -import io.metersphere.system.dto.sdk.request.CustomFieldOptionRequest; import io.metersphere.sdk.util.BeanUtils; import io.metersphere.system.domain.CustomFieldOption; import io.metersphere.system.domain.CustomFieldOptionExample; +import io.metersphere.system.dto.sdk.request.CustomFieldOptionRequest; import io.metersphere.system.mapper.CustomFieldOptionMapper; import jakarta.annotation.Resource; import org.apache.commons.collections.CollectionUtils; @@ -12,6 +12,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -44,7 +45,11 @@ public class BaseCustomFieldOptionService { public List getByFieldId(String fieldId) { CustomFieldOptionExample example = new CustomFieldOptionExample(); example.createCriteria().andFieldIdEqualTo(fieldId); - return customFieldOptionMapper.selectByExample(example); + List options = customFieldOptionMapper.selectByExample(example); + if (CollectionUtils.isNotEmpty(options)) { + options.sort(Comparator.comparing(CustomFieldOption::getPos)); + } + return options; } public void addByFieldId(String fieldId, List customFieldOptions) { @@ -90,6 +95,10 @@ public class BaseCustomFieldOptionService { } CustomFieldOptionExample example = new CustomFieldOptionExample(); example.createCriteria().andFieldIdIn(fieldIds); - return customFieldOptionMapper.selectByExample(example); + List options = customFieldOptionMapper.selectByExample(example); + if (CollectionUtils.isNotEmpty(options)) { + options.sort(Comparator.comparing(CustomFieldOption::getPos)); + } + return options; } } diff --git a/backend/services/system-setting/src/main/resources/systemGeneratorConfig.xml b/backend/services/system-setting/src/main/resources/systemGeneratorConfig.xml index e9e0b06876..f656f19aec 100644 --- a/backend/services/system-setting/src/main/resources/systemGeneratorConfig.xml +++ b/backend/services/system-setting/src/main/resources/systemGeneratorConfig.xml @@ -95,14 +95,14 @@ - + -
+ + + +
{{ t('system.orgTemplate.required') }} - {{ - t('system.orgTemplate.required') - }}
@@ -94,7 +94,11 @@ @click="moveField(formItem as DefinedFieldItem, 'bottom')" /> - + - + + + +
+ + + + + +
+ +
@@ -27,9 +41,15 @@ import type { FormItem, FormRuleItem } from '@/components/pure/ms-form-create/types'; import CaseTemplateLeftContent from './caseTemplateLeftContent.vue'; import DefectTemplateLeftContent from './defectTemplateLeftContent.vue'; + import CaseTemplateRightSystemField from '@/views/setting/organization/template/components/caseTemplateRightSystemField.vue'; + import DefectTemplateRightSystemField from '@/views/setting/organization/template/components/defectTemplateRightSystemField.vue'; + + import { useI18n } from '@/hooks/useI18n'; import type { DefinedFieldItem, SeneType } from '@/models/setting/template'; + const { t } = useI18n(); + const props = defineProps<{ templateType: SeneType; // 模板场景 selectField: DefinedFieldItem[]; // 选择模板字段 @@ -42,6 +62,10 @@ const fApi = ref(null); const formCreateRef = ref(); + const viewForm = ref>({ + tags: '', + }); + // 处理表单格式 const getFormRules = () => { formRuleField.value = []; diff --git a/frontend/src/views/setting/organization/template/locale/en-US.ts b/frontend/src/views/setting/organization/template/locale/en-US.ts index 5214a1ba82..f775aab581 100644 --- a/frontend/src/views/setting/organization/template/locale/en-US.ts +++ b/frontend/src/views/setting/organization/template/locale/en-US.ts @@ -90,6 +90,7 @@ export default { 'system.orgTemplate.caseName': 'Use case name', 'system.orgTemplate.caseNamePlaceholder': 'Please enter a use case name', 'system.orgTemplate.defectNamePlaceholder': 'Please enter a use defect name', + 'system.orgTemplate.noDefaultPlaceholder': 'Default value are not supported', 'system.orgTemplate.precondition': 'precondition', 'system.orgTemplate.stepDescription': 'Step description', 'system.orgTemplate.changeType': 'Change type', @@ -164,6 +165,9 @@ export default { 'system.orgTemplate.custom': 'custom', 'system.orgTemplate.defectName': 'Defect Name', 'system.orgTemplate.defectContent': 'Defect Content', + 'system.orgTemplate.defectHandleUser': 'AssignUser', + 'system.orgTemplate.defectStatus': 'Status', + 'system.orgTemplate.caseModule': 'Module', 'system.orgTemplate.defectNameTip': 'You can set a default value for the defect name, which is used uniformly when creating it', 'system.orgTemplate.defectContentTip': diff --git a/frontend/src/views/setting/organization/template/locale/zh-CN.ts b/frontend/src/views/setting/organization/template/locale/zh-CN.ts index 3e5bc01e5c..96a6300fd2 100644 --- a/frontend/src/views/setting/organization/template/locale/zh-CN.ts +++ b/frontend/src/views/setting/organization/template/locale/zh-CN.ts @@ -90,6 +90,7 @@ export default { 'system.orgTemplate.caseName': '用例名称', 'system.orgTemplate.caseNamePlaceholder': '请输入用例名称', 'system.orgTemplate.defectNamePlaceholder': '请输入缺陷名称', + 'system.orgTemplate.noDefaultPlaceholder': '暂不支持默认值', 'system.orgTemplate.precondition': '前置条件', 'system.orgTemplate.stepDescription': '步骤描述', 'system.orgTemplate.changeType': '更改类型', @@ -156,6 +157,9 @@ export default { 'system.orgTemplate.custom': '自定义', 'system.orgTemplate.defectName': '缺陷名称', 'system.orgTemplate.defectContent': '缺陷内容', + 'system.orgTemplate.defectHandleUser': '处理人', + 'system.orgTemplate.caseModule': '所属模块', + 'system.orgTemplate.defectStatus': '状态', 'system.orgTemplate.defectNameTip': '可为缺陷名称设置默认值,创建时统一使用', 'system.orgTemplate.defectContentTip': '可为缺陷内容设置默认值,创建时统一使用', 'system.orgTemplate.templateNameRules': '请输入模板名称',