diff --git a/backend/framework/plugin/plugin-platform-sdk/src/main/java/io/metersphere/plugin/platform/dto/reponse/PlatformCustomFieldItemDTO.java b/backend/framework/plugin/plugin-platform-sdk/src/main/java/io/metersphere/plugin/platform/dto/reponse/PlatformCustomFieldItemDTO.java index f076bba392..8e6ed1a435 100644 --- a/backend/framework/plugin/plugin-platform-sdk/src/main/java/io/metersphere/plugin/platform/dto/reponse/PlatformCustomFieldItemDTO.java +++ b/backend/framework/plugin/plugin-platform-sdk/src/main/java/io/metersphere/plugin/platform/dto/reponse/PlatformCustomFieldItemDTO.java @@ -13,4 +13,6 @@ public class PlatformCustomFieldItemDTO extends PlatformCustomFieldDTO { private String defaultValue; private Boolean supportSearch; private String searchMethod; + private String placeHolder; + private Boolean systemField; } diff --git a/backend/framework/plugin/plugin-platform-sdk/src/main/java/io/metersphere/plugin/platform/enums/PlatformCustomFieldType.java b/backend/framework/plugin/plugin-platform-sdk/src/main/java/io/metersphere/plugin/platform/enums/PlatformCustomFieldType.java index b34b123fd5..d2f08bafaa 100644 --- a/backend/framework/plugin/plugin-platform-sdk/src/main/java/io/metersphere/plugin/platform/enums/PlatformCustomFieldType.java +++ b/backend/framework/plugin/plugin-platform-sdk/src/main/java/io/metersphere/plugin/platform/enums/PlatformCustomFieldType.java @@ -8,70 +8,69 @@ public enum PlatformCustomFieldType { /** * 输入框 */ - INPUT(false, "input"), + INPUT(false), /** * 文本框 */ - TEXTAREA(false, "textarea"), + TEXTAREA(false), /** * 单选下拉框框 */ - SELECT(true, "select"), + SELECT(true), /** * 多选下拉框框 */ - MULTIPLE_SELECT(true, "multipleSelect"), + MULTIPLE_SELECT(true), /** * 单选框 */ - RADIO(true, "radio"), + RADIO(true), /** * 复选框 */ - CHECKBOX(true, "checkbox"), + CHECKBOX(true), /** * 单选成员 */ - MEMBER(true, "member"), + MEMBER(true), /** * 多选成员 */ - MULTIPLE_MEMBER(true, "multipleMember"), + MULTIPLE_MEMBER(true), /** * 日期 */ - DATE(false, "date"), + DATE(false), /** * 日期时间 */ - DATETIME(false, "datetime"), + DATETIME(false), /** * 整型 */ - INT(false, "int"), + INT(false), /** * 浮点型 */ - FLOAT(false, "float"), + FLOAT(false), /** * 多值输入框(标签输入框) */ - MULTIPLE_INPUT(false, "multipleInput"), + MULTIPLE_INPUT(false), + + // (第三方平台单独的自定义类型) /** * 级联选择 */ - CASCADE_SELECT(true, "cascadingSelect"), + CASCADER(true), /** * 富文本 */ - RICH_TEXT(false, "richText"); + RICH_TEXT(false); private final Boolean hasOption; - private final String type; - - PlatformCustomFieldType(Boolean hasOption, String type) { + PlatformCustomFieldType(Boolean hasOption) { this.hasOption = hasOption; - this.type = type; } } diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/CustomFieldType.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/CustomFieldType.java index cd590ae5ce..369d0cb8f9 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/CustomFieldType.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/CustomFieldType.java @@ -8,73 +8,65 @@ public enum CustomFieldType { /** * 输入框 */ - INPUT(false, "input"), + INPUT(false), /** * 文本框 */ - TEXTAREA(false, "textarea"), + TEXTAREA(false), /** * 单选下拉框框 */ - SELECT(true, "select"), + SELECT(true), /** * 多选下拉框框 */ - MULTIPLE_SELECT(true, "multipleSelect"), + MULTIPLE_SELECT(true), /** * 单选框 */ - RADIO(true, "radio"), + RADIO(true), /** * 复选框 */ - CHECKBOX(true, "checkbox"), + CHECKBOX(true), /** * 单选成员 */ - MEMBER(true, "member"), + MEMBER(true), /** * 多选成员 */ - MULTIPLE_MEMBER(true, "multipleMember"), + MULTIPLE_MEMBER(true), /** * 日期 */ - DATE(false, "date"), + DATE(false), /** * 日期时间 */ - DATETIME(false, "datetime"), + DATETIME(false), /** * 整型 */ - INT(false, "int"), + INT(false), /** * 浮点型 */ - FLOAT(false, "float"), + FLOAT(false), /** * 多值输入框(标签输入框) */ - MULTIPLE_INPUT(false, "multipleInput"); + MULTIPLE_INPUT(false); private final Boolean hasOption; - - private final String type; - - CustomFieldType(Boolean hasOption, String type) { + CustomFieldType(Boolean hasOption) { this.hasOption = hasOption; - this.type = type; } public Boolean getHasOption() { return this.hasOption; } - public String getType() { - return this.type; - } - public static Set getHasOptionValueSet() { return Arrays.stream(CustomFieldType.values()) .filter(CustomFieldType::getHasOption) diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDefinitionMapper.xml b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDefinitionMapper.xml index 242b115b7b..6e0595040a 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDefinitionMapper.xml +++ b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDefinitionMapper.xml @@ -413,16 +413,16 @@ select api_id from api_definition_custom_field where field_id = #{custom.id} - + and `value` - + and ${custom.value} - + and left(replace(unix_timestamp(trim(both '"' from `value`)), '.', ''), 13) diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDefinitionModuleMapper.xml b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDefinitionModuleMapper.xml index 7c08ce38d4..a590debff1 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDefinitionModuleMapper.xml +++ b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiDefinitionModuleMapper.xml @@ -266,16 +266,16 @@ select api_id from api_definition_custom_field where field_id = #{custom.id} - + and `value` - + and ${custom.value} - + and left(replace(unix_timestamp(trim(both '"' from `value`)), '.', ''), 13) diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiScenarioMapper.xml b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiScenarioMapper.xml index 3769f82666..c93cea8846 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiScenarioMapper.xml +++ b/backend/services/api-test/src/main/java/io/metersphere/api/mapper/ExtApiScenarioMapper.xml @@ -314,16 +314,16 @@ select api_id from api_definition_custom_field where field_id = #{custom.id} - + and `value` - + and ${custom.value} - + and left(replace(unix_timestamp(trim(both '"' from `value`)), '.', ''), 13) diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionControllerTests.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionControllerTests.java index ccb71762e4..1dbd7fc5ac 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionControllerTests.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiDefinitionControllerTests.java @@ -944,13 +944,13 @@ public class ApiDefinitionControllerTests extends BaseTest { Map custom = new HashMap<>(); custom.put("id", "test_field"); custom.put("operator", "in"); - custom.put("type", "multipleSelect"); + custom.put("type", "MULTIPLE_SELECT"); custom.put("value", JSON.toJSONString(List.of("test", "default"))); customs.add(custom); Map currentUserCustom = new HashMap<>(); currentUserCustom.put("id", "test_field"); currentUserCustom.put("operator", "current user"); - currentUserCustom.put("type", "multipleMember"); + currentUserCustom.put("type", "MULTIPLE_MEMBER"); currentUserCustom.put("value", "current user"); customs.add(currentUserCustom); map.put("customs", customs); 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 9f48e79e6d..f715dc9c33 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 @@ -259,9 +259,9 @@ public class BugService { detail.setPlatformDefault(template.getPlatformDefault()); detail.setStatus(bug.getStatus()); detail.setPlatformBugId(bug.getPlatformBugId()); + detail.setTitle(bug.getTitle()); if (!detail.getPlatformDefault()) { - // 非平台默认模板 {标题, 内容, 标签, 自定义字段: 处理人, 状态} - detail.setTitle(bug.getTitle()); + // 非平台默认模板 {内容, 标签, 自定义字段: 处理人, 状态} BugContent bugContent = bugContentMapper.selectByPrimaryKey(id); detail.setDescription(bugContent.getDescription()); detail.setTags(bug.getTags()); @@ -286,7 +286,7 @@ public class BugService { } }); } else { - // 平台默认模板 + // 平台默认模板 {自定义字段} allCustomFields.forEach(field -> template.getCustomFields().stream().filter(templateField -> StringUtils.equals(templateField.getFieldId(), field.getId())).findFirst().ifPresent(templateField -> { field.setName(templateField.getFieldName()); field.setType(templateField.getType()); @@ -697,7 +697,7 @@ public class BugService { handleUserField.setFieldId(BugTemplateCustomField.HANDLE_USER.getId()); handleUserField.setFieldName(BugTemplateCustomField.HANDLE_USER.getName()); handleUserField.setFieldKey(BugTemplateCustomField.HANDLE_USER.getId()); - handleUserField.setType(CustomFieldType.SELECT.getType()); + handleUserField.setType(CustomFieldType.SELECT.name()); List localHandlerOption = bugCommonService.getLocalHandlerOption(projectId); handleUserOption = localHandlerOption.stream().map(user -> { CustomFieldOption option = new CustomFieldOption(); @@ -713,7 +713,7 @@ public class BugService { // 成员类型的自定义字段, 选项值与处理人选项保持一致 final List memberOption = handleUserOption; templateDTO.getCustomFields().forEach(field -> { - if (StringUtils.equalsAny(field.getType(), CustomFieldType.MEMBER.getType(), CustomFieldType.MULTIPLE_MEMBER.getType())) { + if (StringUtils.equalsAny(field.getType(), CustomFieldType.MEMBER.name(), CustomFieldType.MULTIPLE_MEMBER.name())) { field.setPlatformOptionJson(JSON.toJSONString(memberOption)); } }); @@ -737,7 +737,7 @@ public class BugService { statusField.setFieldId(BugTemplateCustomField.STATUS.getId()); statusField.setFieldName(BugTemplateCustomField.STATUS.getName()); statusField.setFieldKey(BugTemplateCustomField.STATUS.getId()); - statusField.setType(CustomFieldType.SELECT.getType()); + statusField.setType(CustomFieldType.SELECT.name()); List statusOption = bugStatusService.getToStatusItemOption(projectId, fromStatusId, platformBugKey); List statusCustomOption = statusOption.stream().map(option -> { CustomFieldOption customFieldOption = new CustomFieldOption(); @@ -1252,6 +1252,8 @@ public class BugService { customField.setFieldId(platformCustomField.getId()); customField.setFieldName(platformCustomField.getName()); customField.setPlatformOptionJson(platformCustomField.getOptions()); + customField.setPlatformPlaceHolder(platformCustomField.getPlaceHolder()); + customField.setPlatformSystemField(platformCustomField.getSystemField()); return customField; }).collect(Collectors.toList()); template.setCustomFields(customFields); diff --git a/backend/services/bug-management/src/test/java/io/metersphere/bug/controller/BugControllerTests.java b/backend/services/bug-management/src/test/java/io/metersphere/bug/controller/BugControllerTests.java index c42eaf5400..ca2a319b3e 100644 --- a/backend/services/bug-management/src/test/java/io/metersphere/bug/controller/BugControllerTests.java +++ b/backend/services/bug-management/src/test/java/io/metersphere/bug/controller/BugControllerTests.java @@ -588,7 +588,7 @@ public class BugControllerTests extends BaseTest { BugCustomFieldDTO summary = new BugCustomFieldDTO(); summary.setId("summary"); summary.setName("摘要"); - summary.setType("input"); + summary.setType("INPUT"); summary.setValue("这是一个系统Jira模板创建的缺陷"); addRequest.getCustomFields().add(summary); MultiValueMap addParam3 = getMultiPartParam(addRequest, null); @@ -667,7 +667,7 @@ public class BugControllerTests extends BaseTest { field.setId("test_field"); field.setName("test"); field.setValue("test"); - field.setType("multipleSelect"); + field.setType("MULTIPLE_SELECT"); bugService.transferCustomToPlatformField(null, List.of(field), true); // 添加没有配置自定义映射字段的Jira缺陷 removeApiFieldTmp(); @@ -694,8 +694,6 @@ public class BugControllerTests extends BaseTest { this.requestMultipart(BUG_ADD, addParam).andExpect(status().is5xxServerError()); // 获取禅道模板(删除默认项目模板) bugService.attachTemplateStatusField(null, null, null, null); - // 获取处理人选项 - this.requestGetWithOk(BUG_HEADER_COLUMNS_OPTION + "/default-project-for-bug"); // 批量删除 BugBatchRequest request = new BugBatchRequest(); request.setProjectId("default-project-for-bug"); diff --git a/backend/services/bug-management/src/test/resources/dml/init_bug.sql b/backend/services/bug-management/src/test/resources/dml/init_bug.sql index e49c817d5b..13c08e9e22 100644 --- a/backend/services/bug-management/src/test/resources/dml/init_bug.sql +++ b/backend/services/bug-management/src/test/resources/dml/init_bug.sql @@ -66,7 +66,7 @@ INSERT INTO project_application (project_id, type, type_value) VALUES INSERT INTO service_integration(`id`, `plugin_id`, `enable`, `configuration`, `organization_id`) VALUES ('621103810617344', 'jira', true, 0x504B0304140008080800BC517657000000000000000000000000030000007A6970258DC10EC2201044FF65CF06D2C498D89347B5574FBD6D8158222CD85D6268E3BF4BE3F5CDBC990DD0DAC531430FB348E65EEBE06B41AAA9289480CC1E4991130D07C022F3A366D7DA13B2373B32261592469AF1572FCF883E289362CB735BF8A4C5EE073474C3CB8E59A6F85EEFF12AE676EC4E67F8FE00504B0708384DA4307800000087000000504B01021400140008080800BC517657384DA43078000000870000000300000000000000000000000000000000007A6970504B0506000000000100010031000000A90000000000, '100001'), - ('652096294625281', 'zentao', true, 0x504B03041400080808003B939C57000000000000000000000000030000007A6970AB564A4C49294A2D2E56B252CA282929B0D2D7373437D23334D33334D03333D3AF4ACD2B49CCD757D2514A4C4ECE2FCD2B01AA4B4CC9CDCC038A1424161797E717A500859C1373F2F3D21D8C0C0C4D811245A985A5A9C525219505A940B900C7108F784F3F377FA55A00504B07081BBBB5766A0000006E000000504B010214001400080808003B939C571BBBB5766A0000006E0000000300000000000000000000000000000000007A6970504B05060000000001000100310000009B0000000000, '100001'); + ('652096294625281', 'zentao', true, 0x504B030414000808080093756458000000000000000000000000030000007A6970AB564A4C49294A2D2E56B252CA282929B0D2D7373437D23334D3333230D033B3B4B230B0B050D2514A4C4ECE2FCD2B01AA4A4CC9CDCC038A1424161797E717A500859C1373F2F3D21D8C0C0C4D811245A985A5A9C525219505A940B900C7108F784F3F377FA55A00504B07088A813510680000006C000000504B01021400140008080800937564588A813510680000006C0000000300000000000000000000000000000000007A6970504B0506000000000100010031000000990000000000, '100001'); diff --git a/backend/services/bug-management/src/test/resources/file/metersphere-jira-test.jar b/backend/services/bug-management/src/test/resources/file/metersphere-jira-test.jar index 4fdd8d3978..fd55952f78 100644 Binary files a/backend/services/bug-management/src/test/resources/file/metersphere-jira-test.jar and b/backend/services/bug-management/src/test/resources/file/metersphere-jira-test.jar differ diff --git a/backend/services/bug-management/src/test/resources/file/metersphere-zentao-test.jar b/backend/services/bug-management/src/test/resources/file/metersphere-zentao-test.jar index 18be15bba3..81e4d4b6d6 100644 Binary files a/backend/services/bug-management/src/test/resources/file/metersphere-zentao-test.jar and b/backend/services/bug-management/src/test/resources/file/metersphere-zentao-test.jar differ diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/dto/sdk/TemplateCustomFieldDTO.java b/backend/services/system-setting/src/main/java/io/metersphere/system/dto/sdk/TemplateCustomFieldDTO.java index e36b465550..306b35ed27 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/dto/sdk/TemplateCustomFieldDTO.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/dto/sdk/TemplateCustomFieldDTO.java @@ -33,9 +33,6 @@ public class TemplateCustomFieldDTO { @Schema(title = "选项值") private List options; - @Schema(title = "平台选项值") - private String platformOptionJson; - @Schema(title = "是否支持搜索") private Boolean supportSearch; @@ -44,4 +41,16 @@ public class TemplateCustomFieldDTO { @Schema(description = "是否内置字段") private Boolean internal; + + /** + * 平台字段相关属性 -- start + */ + @Schema(title = "平台选项值") + private String platformOptionJson; + + @Schema(description = "平台字段占位提示") + private String platformPlaceHolder; + + @Schema(description = "是否平台系统字段") + private Boolean platformSystemField; } diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/utils/CustomFieldUtils.java b/backend/services/system-setting/src/main/java/io/metersphere/system/utils/CustomFieldUtils.java index 4be307e24d..40f8cd9948 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/utils/CustomFieldUtils.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/utils/CustomFieldUtils.java @@ -69,8 +69,8 @@ public class CustomFieldUtils { String fieldType = custom.get(COMBINE_CUSTOM_FIELD_TYPE).toString(); String fieldValue = custom.get(COMBINE_CUSTOM_FIELD_VALUE).toString(); - if (StringUtils.equalsAny(fieldType, CustomFieldType.MULTIPLE_MEMBER.getType(), - CustomFieldType.CHECKBOX.getType(), CustomFieldType.MULTIPLE_SELECT.getType()) && StringUtils.isNotEmpty(fieldValue)) { + if (StringUtils.equalsAny(fieldType, CustomFieldType.MULTIPLE_MEMBER.name(), + CustomFieldType.CHECKBOX.name(), CustomFieldType.MULTIPLE_SELECT.name()) && StringUtils.isNotEmpty(fieldValue)) { List customValues = JSON.parseArray(fieldValue, String.class); List jsonValues = customValues.stream().map(item -> "JSON_CONTAINS(`value`, '[\"".concat(item).concat("\"]')")).toList(); custom.put(COMBINE_CUSTOM_FIELD_VALUE, "(".concat(StringUtils.join(jsonValues, " OR ")).concat(")")); diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/CustomFieldTests.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/CustomFieldTests.java index 4f5e97fb0c..251f171981 100644 --- a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/CustomFieldTests.java +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/CustomFieldTests.java @@ -38,13 +38,13 @@ class CustomFieldTests extends BaseTest { Map custom = new HashMap<>(); custom.put("id", "test_field"); custom.put("operator", "in"); - custom.put("type", "multipleSelect"); + custom.put("type", "MULTIPLE_SELECT"); custom.put("value", JSON.toJSONString(List.of("test", "default"))); customs.add(custom); Map currentUserCustom = new HashMap<>(); currentUserCustom.put("id", "test_field"); currentUserCustom.put("operator", "current user"); - currentUserCustom.put("type", "multipleMember"); + currentUserCustom.put("type", "MULTIPLE_MEMBER"); currentUserCustom.put("value", "current user"); customs.add(currentUserCustom); currentUserCustom.put("value", ""); diff --git a/frontend/src/components/pure/ms-form-create/form-create.ts b/frontend/src/components/pure/ms-form-create/form-create.ts index c75f8dc987..7c7096cbcc 100644 --- a/frontend/src/components/pure/ms-form-create/form-create.ts +++ b/frontend/src/components/pure/ms-form-create/form-create.ts @@ -180,6 +180,16 @@ export const PASSWORD = { }, }; +export const CASCADER = { + type: 'cascader', + field: 'fieldName', + title: '', + value: [], + props: { + 'allow-clear': true, + }, +}; + export const FieldTypeFormRules: Record = { INPUT, SELECT, @@ -196,4 +206,5 @@ export const FieldTypeFormRules: Record = { TEXTAREA, JIRAKEY, PASSWORD, + CASCADER, }; diff --git a/frontend/src/components/pure/ms-form-create/ms-form-create.vue b/frontend/src/components/pure/ms-form-create/ms-form-create.vue index b971f32fec..5f4f8c5217 100644 --- a/frontend/src/components/pure/ms-form-create/ms-form-create.vue +++ b/frontend/src/components/pure/ms-form-create/ms-form-create.vue @@ -16,9 +16,8 @@ import { useI18n } from '@/hooks/useI18n'; - import type { FormItem } from './types'; - import { FormRuleItem } from './types'; - import formCreate, { Rule } from '@form-create/arco-design'; + import { FormItem, FormRuleItem } from './types'; + import formCreate from '@form-create/arco-design'; defineOptions({ name: 'MsFormCreate' }); @@ -147,6 +146,20 @@ formItems.value = formItems.value.filter((item: FormItem) => !item.displayConditions?.field); } + function mapOption(options: any[]) { + return options.map((optionsItem) => { + const mappedItem: any = { + label: optionsItem.text, + value: optionsItem.value, + }; + + if (optionsItem.children) { + mappedItem.children = mapOption(optionsItem.children); + } + return mappedItem; + }); + } + function convertItem(item: FormItem) { // 当前类型 let fieldType; @@ -162,12 +175,7 @@ fieldType = FieldTypeFormRules[currentTypeForm].type; } const options = item?.options; - const currentOptions = options?.map((optionsItem: any) => { - return { - label: optionsItem.text, - value: optionsItem.value, - }; - }); + const currentOptions = mapOption(options || []); const ruleItem: any = { type: fieldType, // 表单类型 field: item.name, // 字段 @@ -206,6 +214,10 @@ tooltip: item.tooltip, }, }; + // 如果存在placeholder, 替换掉默认的placeholder + if (item.platformPlaceHolder) { + ruleItem.props.placeholder = item.platformPlaceHolder; + } // 如果不存在关联name删除link关联属性 if (!ruleItem.link.filter((ink: string) => ink).length) { delete ruleItem.link; diff --git a/frontend/src/components/pure/ms-form-create/types.ts b/frontend/src/components/pure/ms-form-create/types.ts index 4685fc1e4d..c4ce10f2a3 100644 --- a/frontend/src/components/pure/ms-form-create/types.ts +++ b/frontend/src/components/pure/ms-form-create/types.ts @@ -18,6 +18,7 @@ export type FormItemType = | 'FLOAT' | 'NUMBER' | 'PassWord' + | 'CASCADER' | undefined; // 表单选项 @@ -64,6 +65,7 @@ export interface FormItem { inputSearch?: boolean; // 是否支持远程搜索 tooltip?: string; // 表单后边的提示info instructionsIcon?: ''; // 是否有图片在表单后边展示 + platformPlaceHolder?: string; // 平台表单项占位符 optionMethod?: string; // 请求检索的方法 两个参数 表单项的所有值 options?: FormItemDefaultOptions[]; required: boolean; diff --git a/frontend/src/models/bug-management.ts b/frontend/src/models/bug-management.ts index fba2902413..42fb880970 100644 --- a/frontend/src/models/bug-management.ts +++ b/frontend/src/models/bug-management.ts @@ -1,6 +1,6 @@ -import {FormItemType} from '@/components/pure/ms-form-create/types'; +import { FormItemType } from '@/components/pure/ms-form-create/types'; -import {BatchApiParams} from './common'; +import { BatchApiParams } from './common'; export interface BugListItem { id: string; // 缺陷id @@ -47,6 +47,8 @@ export interface BugEditCustomField { required: boolean; isMutiple?: boolean; options?: any[]; + defaultValue: string; + platformSystemField: boolean; } export interface BugEditFormObject { [key: string]: any; @@ -54,7 +56,7 @@ export interface BugEditFormObject { export interface BugEditCustomFieldItem { id: string; name: string; - type: string; + type: string | undefined; value: string; } export type BugBatchUpdateFiledType = 'single_select' | 'multiple_select' | 'tags' | 'input' | 'user_selector' | 'date'; @@ -104,6 +106,6 @@ export interface OperationFile { } export interface BugTemplateRequest { - fromStatusId: string; // 缺陷当前状态 - platformBugKey: string; // 缺陷第三方平台Key + fromStatusId: string; // 缺陷当前状态 + platformBugKey: string; // 缺陷第三方平台Key } diff --git a/frontend/src/utils/recursion.ts b/frontend/src/utils/recursion.ts new file mode 100644 index 0000000000..5734e51079 --- /dev/null +++ b/frontend/src/utils/recursion.ts @@ -0,0 +1,29 @@ +export interface Option { + label: string; + value: string; + children?: Option[]; +} + +// 递归函数,获取所有父级元素 +export function findParents(data: Option[], targetId: string, parents: string[] = []) { + for (let i = 0; i < data.length; i++) { + const current = data[i]; + if (current.value === targetId) { + // 第一层级, 直接返回 + parents.push(current.value); + return parents; + } + if (current.children && current.children.length > 0) { + // 多层级, 递归查找 + parents.push(current.value); + const result = findParents(current.children, targetId, parents); + if (result) { + // 子元素中有匹配的, 返回结果 + return result; + } + // 子元素中没有匹配的, 队尾元素删除, 继续查找相邻元素 + parents.pop(); + } + } + return null; +} diff --git a/frontend/src/views/bug-management/components/bug-detail-drawer.vue b/frontend/src/views/bug-management/components/bug-detail-drawer.vue index 957fa182b5..8732d0e7dd 100644 --- a/frontend/src/views/bug-management/components/bug-detail-drawer.vue +++ b/frontend/src/views/bug-management/components/bug-detail-drawer.vue @@ -100,6 +100,8 @@ :form-item="formItem" :allow-edit="true" :detail-info="detailInfo" + :is-platform-default-template="isPlatformDefaultTemplate" + :platform-system-fields="platformSystemFields" @update-success="updateSuccess" /> @@ -118,7 +120,11 @@ @@ -226,17 +234,19 @@ const currentProjectId = computed(() => appStore.currentProjectId); const showDrawerVisible = defineModel('visible', { default: false }); const bugDetailTabRef = ref(); + const isPlatformDefaultTemplate = ref(false); const activeTab = ref('detail'); const detailInfo = ref>({ match: [] }); // 存储当前详情信息,通过loadBug 获取 const tags = ref([]); + const platformSystemFields = ref([]); // 平台系统字段 // 处理表单格式 const getFormRules = (arr: BugEditCustomField[], valueObj: BugEditFormObject) => { formRules.value = []; if (Array.isArray(arr) && arr.length) { - formRules.value = arr.map((item) => { + formRules.value = arr.map((item: any) => { return { type: item.type, name: item.fieldId, @@ -244,6 +254,7 @@ value: valueObj[item.fieldId], options: item.platformOptionJson ? JSON.parse(item.platformOptionJson) : item.options, required: item.required as boolean, + platformPlaceHolder: item.platformPlaceHolder, props: { modelValue: valueObj[item.fieldId], options: item.platformOptionJson ? JSON.parse(item.platformOptionJson) : item.options, @@ -262,7 +273,14 @@ fromStatusId: request.fromStatusId, platformBugKey: request.platformBugKey, }); - getFormRules(res.customFields, valueObj); + platformSystemFields.value = res.customFields.filter((field) => field.platformSystemField); + platformSystemFields.value.forEach((item) => { + item.defaultValue = valueObj[item.fieldId]; + }); + getFormRules( + res.customFields.filter((field) => !field.platformSystemField), + valueObj + ); } catch (error) { // eslint-disable-next-line no-console console.log(error); @@ -272,16 +290,24 @@ async function loadedBug(detail: BugEditFormObject) { detailInfo.value = { ...detail }; const { templateId } = detail; - // tag 赋值 + + // 是否平台默认模板 + isPlatformDefaultTemplate.value = detail.platformDefault; + // TAG 赋值 tags.value = detail.tags || []; caseCount.value = detail.linkCaseCount; - const tmpObj = {}; + const tmpObj = { status: detail.status }; if (detail.customFields && Array.isArray(detail.customFields)) { detail.customFields.forEach((item) => { - if (item.type === 'MULTIPLE_SELECT') { + if (item.type === 'MULTIPLE_SELECT' || item.type === 'MULTIPLE_INPUT' || item.type === 'CHECKBOX') { tmpObj[item.id] = JSON.parse(item.value); } else if (item.type === 'INT') { tmpObj[item.id] = Number(item.value); + } else if (item.type === 'CASCADER') { + const arr = JSON.parse(item.value); + if (arr && arr instanceof Array && arr.length > 0) { + tmpObj[item.id] = arr[arr.length - 1]; + } } else { tmpObj[item.id] = item.value; } diff --git a/frontend/src/views/bug-management/components/bugDetailTab.vue b/frontend/src/views/bug-management/components/bugDetailTab.vue index 63f41564f9..ffc4cd232e 100644 --- a/frontend/src/views/bug-management/components/bugDetailTab.vue +++ b/frontend/src/views/bug-management/components/bugDetailTab.vue @@ -1,7 +1,6 @@