refactor(缺陷管理): 优化部分接口
This commit is contained in:
parent
1b04ae1aad
commit
0c49a5d4c1
|
@ -94,7 +94,7 @@ bug_comment_not_exist=缺陷评论不存在
|
|||
bug_comment_not_owner=非当前评论创建人, 无法操作!
|
||||
bug_relate_case_not_found=未查询到关联的用例
|
||||
bug_relate_case_type_unknown=关联的用例类型未知, 无法查看
|
||||
bug_relate_case_permission_error=无权限查看, 请联系管理员
|
||||
bug_relate_case_permission_error=无用例查看权限, 请联系管理员
|
||||
bug_status_can_not_be_empty=缺陷状态不能为空
|
||||
handle_user_can_not_be_empty=缺陷处理人不能为空
|
||||
bug.title=缺项名称
|
||||
|
|
|
@ -80,7 +80,7 @@ bug_relation_case.create_user.length_range=createUser length must be between 1-5
|
|||
bug_not_exist=Bug does not exist
|
||||
bug_tags_size_large_than=Bug size large than {0}
|
||||
not_local_bug_error=Not local bug, error
|
||||
third_party_not_config=The sync config of project application is not enabled, or the service integration configuration is empty, or not enabled;
|
||||
third_party_not_config=Please correctly configure the service integration or project application settings and enable them;
|
||||
bug_attachment_upload_error=Bug attachment upload error
|
||||
bug_attachment_link_error=Bug attachment link error
|
||||
bug_attachment_delete_error=Bug attachment delete error
|
||||
|
|
|
@ -80,7 +80,7 @@ bug_relation_case.create_user.length_range=创建人长度必须在1-50之间
|
|||
bug_not_exist=缺陷不存在
|
||||
not_local_bug_error=非本地缺陷,无法操作
|
||||
bug_tags_size_large_than=缺陷标签数量超过{0}个
|
||||
third_party_not_config=项目应用设置的同步配置未启用, 或服务集成配置为空及未启用;
|
||||
third_party_not_config=请正确配置服务集成或项目应用设置的同步缺陷参数, 并启用;
|
||||
bug_attachment_upload_error=缺陷附件上传失败
|
||||
bug_attachment_link_error=缺陷附件关联失败
|
||||
bug_attachment_delete_error=缺陷附件删除失败
|
||||
|
|
|
@ -79,7 +79,7 @@ bug_relation_case.create_user.length_range=创建人長度必須在1-50之間
|
|||
# error
|
||||
bug_not_exist=缺陷不存在
|
||||
not_local_bug_error=非本地缺陷,無法操作
|
||||
third_party_not_config=項目應用管理的同步配置未啟用, 或服務集成配置為空及未啟用;
|
||||
third_party_not_config=請正確配置服務集成或項目應用設置的同步缺陷參數, 並啟用;
|
||||
bug_tags_size_large_than=缺陷标签数量超过{0}个
|
||||
bug_attachment_upload_error=缺陷附件上傳失敗
|
||||
bug_attachment_link_error=缺陷附件關聯失敗
|
||||
|
|
|
@ -11,6 +11,7 @@ import io.metersphere.bug.dto.response.BugDTO;
|
|||
import io.metersphere.bug.dto.response.BugDetailDTO;
|
||||
import io.metersphere.bug.service.*;
|
||||
import io.metersphere.project.dto.ProjectTemplateOptionDTO;
|
||||
import io.metersphere.project.service.ProjectApplicationService;
|
||||
import io.metersphere.project.service.ProjectTemplateService;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.sdk.constants.TemplateScene;
|
||||
|
@ -50,13 +51,21 @@ public class BugController {
|
|||
@Resource
|
||||
private BugService bugService;
|
||||
@Resource
|
||||
private BugCommonService bugCommonService;
|
||||
@Resource
|
||||
private BugSyncService bugSyncService;
|
||||
@Resource
|
||||
private BugStatusService bugStatusService;
|
||||
@Resource
|
||||
private ProjectTemplateService projectTemplateService;
|
||||
@Resource
|
||||
private ProjectApplicationService projectApplicationService;
|
||||
|
||||
@GetMapping("/current-platform/{projectId}")
|
||||
@Operation(summary = "缺陷管理-列表-获取当前项目所属平台")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_BUG_READ)
|
||||
@CheckOwner(resourceId = "#projectId", resourceType = "project")
|
||||
public String getCurrentPlatform(@PathVariable String projectId) {
|
||||
return projectApplicationService.getPlatformName(projectId);
|
||||
}
|
||||
|
||||
@GetMapping("/header/custom-field/{projectId}")
|
||||
@Operation(summary = "缺陷管理-列表-获取表头自定义字段集合")
|
||||
|
@ -149,7 +158,7 @@ public class BugController {
|
|||
|
||||
@GetMapping("/export/columns/{projectId}")
|
||||
@Operation(summary = "缺陷管理-列表-获取导出字段配置")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_BUG_EXPORT)
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_BUG_READ)
|
||||
@CheckOwner(resourceId = "#projectId", resourceType = "project")
|
||||
public BugExportColumns getExportColumns(@PathVariable String projectId) {
|
||||
return bugService.getExportColumns(projectId);
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.metersphere.bug.controller;
|
|||
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import io.metersphere.bug.dto.BugCaseCheckResult;
|
||||
import io.metersphere.bug.dto.request.BugRelatedCasePageRequest;
|
||||
import io.metersphere.bug.dto.response.BugRelateCaseDTO;
|
||||
import io.metersphere.bug.service.BugRelateCaseCommonService;
|
||||
|
@ -90,7 +91,7 @@ public class BugRelateCaseController {
|
|||
|
||||
@GetMapping("/check-permission/{projectId}/{caseType}")
|
||||
@Operation(description = "缺陷管理-关联用例-查看用例权限校验")
|
||||
public void checkPermission(@PathVariable String projectId, @PathVariable String caseType) {
|
||||
bugRelateCaseCommonService.checkPermission(projectId, SessionUtils.getUserId(), caseType);
|
||||
public BugCaseCheckResult checkPermission(@PathVariable String projectId, @PathVariable String caseType) {
|
||||
return bugRelateCaseCommonService.checkPermission(projectId, SessionUtils.getUserId(), caseType);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package io.metersphere.bug.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class BugCaseCheckResult implements Serializable {
|
||||
|
||||
@Schema(description = "校验是否通过")
|
||||
private Boolean pass;
|
||||
|
||||
@Schema(description = "未通过信息")
|
||||
private String msg;
|
||||
}
|
|
@ -2,6 +2,7 @@ package io.metersphere.bug.service;
|
|||
|
||||
import io.metersphere.bug.domain.BugRelationCase;
|
||||
import io.metersphere.bug.domain.BugRelationCaseExample;
|
||||
import io.metersphere.bug.dto.BugCaseCheckResult;
|
||||
import io.metersphere.bug.dto.request.BugRelatedCasePageRequest;
|
||||
import io.metersphere.bug.dto.response.BugRelateCaseDTO;
|
||||
import io.metersphere.bug.mapper.BugRelationCaseMapper;
|
||||
|
@ -179,17 +180,18 @@ public class BugRelateCaseCommonService extends ModuleTreeService {
|
|||
* @param currentUser 当前用户
|
||||
* @param caseType 用例类型
|
||||
*/
|
||||
public void checkPermission(String projectId, String currentUser, String caseType) {
|
||||
public BugCaseCheckResult checkPermission(String projectId, String currentUser, String caseType) {
|
||||
// 校验关联用例的查看权限, 目前只支持功能用例的查看权限, 后续支持除功能用例外的其他类型用例
|
||||
if (!CaseType.FUNCTIONAL_CASE.getKey().equals(caseType)) {
|
||||
// 关联的用例类型未知
|
||||
throw new MSException(Translator.get("bug_relate_case_type_unknown"));
|
||||
return BugCaseCheckResult.builder().pass(false).msg(Translator.get("bug_relate_case_type_unknown")).build();
|
||||
}
|
||||
boolean hasPermission = permissionCheckService.userHasProjectPermission(currentUser, projectId, PermissionConstants.FUNCTIONAL_CASE_READ);
|
||||
if (!hasPermission) {
|
||||
// 没有该用例的访问权限
|
||||
throw new MSException(Translator.get("bug_relate_case_permission_error"));
|
||||
return BugCaseCheckResult.builder().pass(false).msg(Translator.get("bug_relate_case_permission_error")).build();
|
||||
}
|
||||
return BugCaseCheckResult.builder().pass(true).build();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -311,10 +311,16 @@ public class BugService {
|
|||
record.setDeleteTime(System.currentTimeMillis());
|
||||
bugMapper.updateByPrimaryKeySelective(record);
|
||||
} else {
|
||||
// 需同步删除平台缺陷
|
||||
// 获取配置平台, 插入平台缺陷
|
||||
Platform platform = projectApplicationService.getPlatform(bug.getProjectId(), true);
|
||||
platform.deleteBug(bug.getPlatformBugId());
|
||||
/*
|
||||
* 和当前项目所属平台不一致, 只删除MS缺陷, 不同步删除平台缺陷
|
||||
* 一致需同步删除平台缺陷
|
||||
*/
|
||||
String platformName = projectApplicationService.getPlatformName(bug.getProjectId());
|
||||
if (StringUtils.equals(platformName, bug.getPlatform())) {
|
||||
// 需同步删除平台缺陷
|
||||
Platform platform = projectApplicationService.getPlatform(bug.getProjectId(), true);
|
||||
platform.deleteBug(bug.getPlatformBugId());
|
||||
}
|
||||
// 删除缺陷后, 前置操作: 删除关联用例, 删除关联附件
|
||||
clearAssociate(id, bug.getProjectId());
|
||||
bugMapper.deleteByPrimaryKey(id);
|
||||
|
@ -651,7 +657,6 @@ public class BugService {
|
|||
// 状态字段
|
||||
attachTemplateStatusField(templateDTO, projectId, fromStatusId, platformBugKey);
|
||||
|
||||
List<CustomFieldOption> handleUserOption = new ArrayList<>();
|
||||
// 内置字段(处理人字段)
|
||||
if (!StringUtils.equals(platformName, BugPlatform.LOCAL.getName())) {
|
||||
// 获取插件中自定义的注入字段(处理人)
|
||||
|
@ -671,13 +676,12 @@ public class BugService {
|
|||
request.setProjectConfig(projectApplicationService.getProjectBugThirdPartConfig(projectId));
|
||||
if (StringUtils.equals(injectField.getKey(), BugTemplateCustomField.HANDLE_USER.getId())) {
|
||||
List<SelectOption> formOptions = platform.getFormOptions(request);
|
||||
handleUserOption = formOptions.stream().map(user -> {
|
||||
templateCustomFieldDTO.setOptions(formOptions.stream().map(user -> {
|
||||
CustomFieldOption option = new CustomFieldOption();
|
||||
option.setText(user.getText());
|
||||
option.setValue(user.getValue());
|
||||
return option;
|
||||
}).toList();
|
||||
templateCustomFieldDTO.setOptions(handleUserOption);
|
||||
}).toList());
|
||||
} else {
|
||||
templateCustomFieldDTO.setPlatformOptionJson(JSON.toJSONString(platform.getFormOptions(request)));
|
||||
}
|
||||
|
@ -690,23 +694,15 @@ public class BugService {
|
|||
handleUserField.setFieldName(BugTemplateCustomField.HANDLE_USER.getName());
|
||||
handleUserField.setFieldKey(BugTemplateCustomField.HANDLE_USER.getId());
|
||||
handleUserField.setType(CustomFieldType.SELECT.name());
|
||||
List<SelectOption> localHandlerOption = bugCommonService.getLocalHandlerOption(projectId);
|
||||
handleUserOption = localHandlerOption.stream().map(user -> {
|
||||
CustomFieldOption option = new CustomFieldOption();
|
||||
option.setText(user.getText());
|
||||
option.setValue(user.getValue());
|
||||
return option;
|
||||
}).toList();
|
||||
handleUserField.setOptions(handleUserOption);
|
||||
handleUserField.setOptions(getMemberOption(projectId));
|
||||
handleUserField.setRequired(true);
|
||||
templateDTO.getCustomFields().addFirst(handleUserField);
|
||||
}
|
||||
|
||||
// 成员类型的自定义字段, 选项值与处理人选项保持一致
|
||||
final List<CustomFieldOption> memberOption = handleUserOption;
|
||||
// 成员类型的自定义字段, 选项值为项目下成员用户
|
||||
templateDTO.getCustomFields().forEach(field -> {
|
||||
if (StringUtils.equalsAny(field.getType(), CustomFieldType.MEMBER.name(), CustomFieldType.MULTIPLE_MEMBER.name())) {
|
||||
field.setPlatformOptionJson(JSON.toJSONString(memberOption));
|
||||
field.setOptions(getMemberOption(projectId));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1582,4 +1578,19 @@ public class BugService {
|
|||
bugAttachment.setCreateUser(currentUser);
|
||||
return bugAttachment;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前项目下成员选项
|
||||
* @param projectId 项目ID
|
||||
* @return 选项集合
|
||||
*/
|
||||
private List<CustomFieldOption> getMemberOption(String projectId) {
|
||||
List<SelectOption> localHandlerOption = bugCommonService.getLocalHandlerOption(projectId);
|
||||
return localHandlerOption.stream().map(user -> {
|
||||
CustomFieldOption option = new CustomFieldOption();
|
||||
option.setText(user.getText());
|
||||
option.setValue(user.getValue());
|
||||
return option;
|
||||
}).toList();
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@ import io.metersphere.bug.domain.BugExample;
|
|||
import io.metersphere.bug.dto.response.BugColumnsOptionResponse;
|
||||
import io.metersphere.bug.enums.BugPlatform;
|
||||
import io.metersphere.bug.mapper.BugMapper;
|
||||
import io.metersphere.bug.mapper.ExtBugMapper;
|
||||
import io.metersphere.plugin.platform.dto.SelectOption;
|
||||
import io.metersphere.plugin.platform.spi.Platform;
|
||||
import io.metersphere.project.service.ProjectApplicationService;
|
||||
|
@ -24,14 +23,12 @@ import java.util.List;
|
|||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class BugStatusService {
|
||||
@Resource
|
||||
private BugMapper bugMapper;
|
||||
@Resource
|
||||
private ExtBugMapper extBugMapper;
|
||||
@Resource
|
||||
private ProjectApplicationService projectApplicationService;
|
||||
@Resource
|
||||
private BaseStatusFlowSettingService baseStatusFlowSettingService;
|
||||
private BugMapper bugMapper;
|
||||
@Resource
|
||||
private ProjectApplicationService projectApplicationService;
|
||||
@Resource
|
||||
private BaseStatusFlowSettingService baseStatusFlowSettingService;
|
||||
@Resource
|
||||
private BugCommonService bugCommonService;
|
||||
|
||||
|
@ -118,6 +115,11 @@ public class BugStatusService {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取
|
||||
* @param projectId
|
||||
* @return
|
||||
*/
|
||||
public BugColumnsOptionResponse getColumnsOption(String projectId) {
|
||||
return new BugColumnsOptionResponse(
|
||||
bugCommonService.getLocalHandlerOption(projectId),
|
||||
|
|
|
@ -90,6 +90,7 @@ public class BugControllerTests extends BaseTest {
|
|||
public static final String BUG_SYNC_CHECK = "/bug/sync/check";
|
||||
public static final String BUG_EXPORT_COLUMNS = "/bug/export/columns/%s";
|
||||
public static final String BUG_EXPORT = "/bug/export";
|
||||
public static final String BUG_CURRENT_PLATFORM = "/bug/current-platform/%s";
|
||||
|
||||
@Resource
|
||||
private PluginService pluginService;
|
||||
|
@ -409,7 +410,7 @@ public class BugControllerTests extends BaseTest {
|
|||
void testExportColumns() throws Exception {
|
||||
this.requestGetWithOkAndReturn(String.format(BUG_EXPORT_COLUMNS, "default-project-for-bug"));
|
||||
//校验权限
|
||||
this.requestGetPermissionTest(PermissionConstants.PROJECT_BUG_EXPORT, String.format(BUG_EXPORT_COLUMNS, DEFAULT_PROJECT_ID));
|
||||
this.requestGetPermissionTest(PermissionConstants.PROJECT_BUG_READ, String.format(BUG_EXPORT_COLUMNS, DEFAULT_PROJECT_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -467,6 +468,12 @@ public class BugControllerTests extends BaseTest {
|
|||
this.requestPostPermissionTest(PermissionConstants.PROJECT_BUG_EXPORT, BUG_EXPORT, request);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(15)
|
||||
void testCurrentPlatform() throws Exception {
|
||||
this.requestGetWithOk(String.format(BUG_CURRENT_PLATFORM, "default-project-for-bug"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(90)
|
||||
void testDeleteBugSuccess() throws Exception {
|
||||
|
@ -508,7 +515,7 @@ public class BugControllerTests extends BaseTest {
|
|||
// 全选, 删除所有
|
||||
request.setSelectAll(true);
|
||||
request.setSelectIds(List.of("test"));
|
||||
request.setExcludeIds(List.of("default-bug-id-jira-delete"));
|
||||
request.setExcludeIds(List.of("default-bug-id-jira-delete", "default-bug-id-jira-sync", "default-bug-id-jira-sync-1"));
|
||||
this.requestPost(BUG_BATCH_DELETE, request, status().is5xxServerError());
|
||||
}
|
||||
|
||||
|
@ -851,22 +858,6 @@ public class BugControllerTests extends BaseTest {
|
|||
pluginService.add(request, mockMultipartFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加禅道插件,供测试使用
|
||||
* @throws Exception 异常
|
||||
*/
|
||||
public void addZentaoPlugin() throws Exception {
|
||||
PluginUpdateRequest request = new PluginUpdateRequest();
|
||||
File jiraTestFile = new File(Objects.requireNonNull(this.getClass().getClassLoader().getResource("file/metersphere-zentao-test.jar")).getPath());
|
||||
FileInputStream inputStream = new FileInputStream(jiraTestFile);
|
||||
MockMultipartFile mockMultipartFile = new MockMultipartFile(jiraTestFile.getName(), jiraTestFile.getName(), "jar", inputStream);
|
||||
request.setName("测试插件-ZENTAO");
|
||||
request.setGlobal(true);
|
||||
request.setEnable(true);
|
||||
request.setCreateUser(ADMIN.name());
|
||||
pluginService.add(request, mockMultipartFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取添加的Jira缺陷
|
||||
* @return 缺陷
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package io.metersphere.bug.controller;
|
||||
|
||||
import io.metersphere.bug.dto.BugCaseCheckResult;
|
||||
import io.metersphere.bug.dto.request.BugRelatedCasePageRequest;
|
||||
import io.metersphere.bug.dto.response.BugRelateCaseDTO;
|
||||
import io.metersphere.bug.service.BugRelateCaseCommonService;
|
||||
|
@ -8,6 +9,7 @@ import io.metersphere.request.AssociateOtherCaseRequest;
|
|||
import io.metersphere.request.TestCasePageProviderRequest;
|
||||
import io.metersphere.sdk.constants.UserRoleType;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.base.BaseTest;
|
||||
import io.metersphere.system.controller.handler.ResultHolder;
|
||||
import io.metersphere.system.utils.Pager;
|
||||
|
@ -171,16 +173,24 @@ public class BugRelateCaseControllerTests extends BaseTest {
|
|||
@Order(8)
|
||||
void testBugRelateCheckPermissionError() throws Exception {
|
||||
// 非功能用例类型参数
|
||||
this.requestGet(BUG_CASE_CHECK + "/100001100001/API", status().is5xxServerError());
|
||||
MvcResult mvcResult = this.requestGetAndReturn(BUG_CASE_CHECK + "/100001100001/API");
|
||||
BugCaseCheckResult resultData = getResultData(mvcResult, BugCaseCheckResult.class);
|
||||
Assertions.assertFalse(resultData.getPass());
|
||||
Assertions.assertEquals(resultData.getMsg(), Translator.get("bug_relate_case_type_unknown"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(9)
|
||||
void testBugRelateCheckPermissionSuccess() throws Exception {
|
||||
// 默认项目ID且登录用户为admin
|
||||
this.requestGet(BUG_CASE_CHECK + "/100001100001/FUNCTIONAL", status().isOk()).andReturn();
|
||||
MvcResult mvcResult = this.requestGetAndReturn(BUG_CASE_CHECK + "/100001100001/FUNCTIONAL");
|
||||
BugCaseCheckResult resultData = getResultData(mvcResult, BugCaseCheckResult.class);
|
||||
Assertions.assertTrue(resultData.getPass());
|
||||
// 切换登录用户为PROJECT, 权限校验失败
|
||||
this.requestGetWithNoAdmin(BUG_CASE_CHECK + "/default-project-for-bug/FUNCTIONAL", UserRoleType.PROJECT.name(), status().is5xxServerError()).andReturn();
|
||||
MvcResult errResult = this.requestGetWithNoAdmin(BUG_CASE_CHECK + "/default-project-for-bug/FUNCTIONAL", UserRoleType.PROJECT.name()).andReturn();
|
||||
BugCaseCheckResult errData = getResultData(errResult, BugCaseCheckResult.class);
|
||||
Assertions.assertFalse(errData.getPass());
|
||||
Assertions.assertEquals(errData.getMsg(), Translator.get("bug_relate_case_permission_error"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -25,7 +25,9 @@ INSERT INTO bug_custom_field (bug_id, field_id, value) VALUE ('default-bug-id-ji
|
|||
INSERT INTO custom_field (id, name, scene, type, remark, internal, scope_type, create_time, update_time, create_user, scope_id) VALUE
|
||||
('test_field', '测试字段', 'BUG', 'MULTIPLE_SELECT', '', 0, 'PROJECT', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'default-project-for-bug'),
|
||||
('custom-field-1', '测试字段1', 'BUG', 'SELECT', '', 0, 'PROJECT', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'default-project-for-bug'),
|
||||
('custom-field-2', '测试字段2', 'BUG', 'SELECT', '', 0, 'PROJECT', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'default-project-for-bug');
|
||||
('custom-field-2', '测试字段2', 'BUG', 'SELECT', '', 0, 'PROJECT', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'default-project-for-bug'),
|
||||
('custom-field-3', '测试字段3', 'BUG', 'MEMBER', '', 0, 'PROJECT', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'default-project-for-bug'),
|
||||
('custom-field-4', '测试字段4', 'BUG', 'MULTIPLE_MEMBER', '', 0, 'PROJECT', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'default-project-for-bug');
|
||||
|
||||
INSERT INTO template (id, name, remark, internal, update_time, create_time, create_user, scope_type, scope_id, enable_third_part, scene) VALUES
|
||||
('bug-template-id', 'bug-template', '', 0, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'PROJECT', 'default-project-for-bug', 0, 'BUG'),
|
||||
|
@ -33,7 +35,9 @@ INSERT INTO template (id, name, remark, internal, update_time, create_time, crea
|
|||
('no-status-template', 'no-status-template', '', 0, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'PROJECT', 'no-status-project', 0, 'BUG');
|
||||
INSERT INTO template_custom_field(`id`, `field_id`, `template_id`, `required`, `system_field`, `pos`, `api_field_id`, `default_value`) VALUES
|
||||
('100581234408685570', 'custom-field-1', 'default-bug-template-id', false, false, 0, 'customfield_10097', NULL),
|
||||
('100581234408685571', 'custom-field-2', 'default-bug-template-id', false, false, 0, 'customfield_10098', NULL);
|
||||
('100581234408685571', 'custom-field-2', 'default-bug-template-id', false, false, 0, 'customfield_10098', NULL),
|
||||
('100581234408685572', 'custom-field-3', 'default-bug-template-id', false, false, 0, '', NULL),
|
||||
('100581234408685573', 'custom-field-4', 'default-bug-template-id', false, false, 0, '', NULL);
|
||||
|
||||
INSERT INTO bug_relation_case (id, case_id, bug_id, case_type, test_plan_id, test_plan_case_id, create_user, create_time, update_time) VALUE
|
||||
(UUID_SHORT(), UUID_SHORT(), 'default-bug-id', 'functional', null, null, 'admin', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000);
|
||||
|
|
|
@ -43,7 +43,7 @@ public class TemplateCustomFieldDTO {
|
|||
private Boolean internal;
|
||||
|
||||
/**
|
||||
* 平台字段相关属性 -- start
|
||||
* 平台字段相关属性 @start
|
||||
*/
|
||||
@Schema(title = "平台选项值")
|
||||
private String platformOptionJson;
|
||||
|
|
|
@ -2,7 +2,6 @@ import { CommentParams } from '@/components/business/ms-comment/types';
|
|||
|
||||
import MSR from '@/api/http/index';
|
||||
import * as bugURL from '@/api/requrls/bug-management';
|
||||
import { getCustomOptionHeaderUrl } from '@/api/requrls/bug-management';
|
||||
|
||||
import { BugEditFormObject, BugListItem, BugOptionListItem } from '@/models/bug-management';
|
||||
import { AssociatedList, DemandItem, OperationFile } from '@/models/caseManagement/featureCase';
|
||||
|
@ -79,6 +78,11 @@ export function getTemplateDetailInfo(data: { id: string; projectId: string }) {
|
|||
return MSR.post({ url: `${bugURL.getTemplateDetailUrl}`, data });
|
||||
}
|
||||
|
||||
// 获取当前项目所属平台
|
||||
export function getPlatform(projectId: string) {
|
||||
return MSR.get({ url: `${bugURL.getPlatform}${projectId}` });
|
||||
}
|
||||
|
||||
// 同步缺陷开源
|
||||
export function syncBugOpenSource(projectId: string) {
|
||||
return MSR.get({ url: bugURL.getSyncBugOpenSourceUrl + projectId });
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
export const getPlatform = '/bug/current-platform/';
|
||||
export const postTableListUrl = '/bug/page';
|
||||
export const postUpdateBugUrl = '/bug/update';
|
||||
export const postBatchUpdateBugUrl = '/bug/batch-update';
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<a-button v-permission="['PROJECT_BUG:READ+ADD']" type="primary" @click="handleCreate"
|
||||
>{{ t('bugManagement.createBug') }}
|
||||
</a-button>
|
||||
<a-button :loading="!isComplete" type="outline" @click="handleSync"
|
||||
<a-button v-if="currentPlatform !== 'Local'" :loading="!isComplete" type="outline" @click="handleSync"
|
||||
>{{ t('bugManagement.syncBug') }}
|
||||
</a-button>
|
||||
</div>
|
||||
|
@ -30,16 +30,26 @@
|
|||
>
|
||||
<!-- ID -->
|
||||
<template #num="{ record, rowIndex }">
|
||||
<a-button type="text" class="px-0" @click="handleShowDetail(record.id, rowIndex)">{{ record.num }}</a-button>
|
||||
<a-button
|
||||
type="text"
|
||||
class="px-0"
|
||||
:disabled="currentPlatform !== record.platform"
|
||||
@click="handleShowDetail(record.id, rowIndex)"
|
||||
>{{ record.num }}</a-button
|
||||
>
|
||||
</template>
|
||||
<template #operation="{ record }">
|
||||
<div class="flex flex-nowrap items-center">
|
||||
<span v-permission="['PROJECT_BUG:READ+ADD']" class="flex flex-row items-center">
|
||||
<MsButton class="!mr-0" @click="handleCopy(record)">{{ t('common.copy') }}</MsButton>
|
||||
<MsButton class="!mr-0" :disabled="currentPlatform !== record.platform" @click="handleCopy(record)">{{
|
||||
t('common.copy')
|
||||
}}</MsButton>
|
||||
<a-divider class="!mx-2 h-[12px]" direction="vertical" />
|
||||
</span>
|
||||
<span v-permission="['PROJECT_BUG:READ+UPDATE']" class="flex flex-row items-center">
|
||||
<MsButton class="!mr-0" @click="handleEdit(record)">{{ t('common.edit') }}</MsButton>
|
||||
<MsButton class="!mr-0" :disabled="currentPlatform !== record.platform" @click="handleEdit(record)">{{
|
||||
t('common.edit')
|
||||
}}</MsButton>
|
||||
<a-divider class="!mx-2 h-[12px]" direction="vertical" />
|
||||
</span>
|
||||
<MsTableMoreAction
|
||||
|
@ -228,6 +238,7 @@
|
|||
getCustomFieldHeader,
|
||||
getCustomOptionHeader,
|
||||
getExportConfig,
|
||||
getPlatform,
|
||||
getSyncStatus,
|
||||
syncBugEnterprise,
|
||||
syncBugOpenSource,
|
||||
|
@ -249,8 +260,6 @@
|
|||
import { RouteEnum } from '@/enums/routeEnum';
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
|
||||
import { log } from 'console';
|
||||
|
||||
const { t } = useI18n();
|
||||
const MsExportDrawer = defineAsyncComponent(() => import('@/components/pure/ms-export-drawer/index.vue'));
|
||||
const DeleteModal = defineAsyncComponent(() => import('./components/deleteModal.vue'));
|
||||
|
@ -264,6 +273,7 @@
|
|||
const syncVisible = ref(false);
|
||||
const exportVisible = ref(false);
|
||||
const exportOptionData = ref<MsExportDrawerMap>({});
|
||||
const currentPlatform = ref('Local');
|
||||
const detailVisible = ref(false);
|
||||
const activeDetailId = ref<string>('');
|
||||
const activeCaseIndex = ref<number>(0);
|
||||
|
@ -358,7 +368,7 @@
|
|||
title: 'bugManagement.ID',
|
||||
dataIndex: 'num',
|
||||
slotName: 'num',
|
||||
width: 200,
|
||||
width: 100,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
|
@ -369,7 +379,7 @@
|
|||
{
|
||||
title: 'bugManagement.bugName',
|
||||
dataIndex: 'title',
|
||||
width: 300,
|
||||
width: 250,
|
||||
showTooltip: true,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
|
@ -715,6 +725,12 @@
|
|||
exportOptionData.value = res;
|
||||
};
|
||||
|
||||
const setCurrentPlatform = async () => {
|
||||
const res = await getPlatform(projectId.value);
|
||||
currentPlatform.value = res;
|
||||
console.log(currentPlatform.value);
|
||||
};
|
||||
|
||||
const moreActionList: ActionsItem[] = [
|
||||
{
|
||||
label: t('common.delete'),
|
||||
|
@ -793,6 +809,7 @@
|
|||
|
||||
onMounted(() => {
|
||||
setLoadListParams({ projectId: projectId.value });
|
||||
setCurrentPlatform();
|
||||
setExportOptionData();
|
||||
initFilterOptions();
|
||||
fetchData();
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<template #deleteTimeColumn="{ record }">
|
||||
{{ dayjs(record.deleteTime).format('YYYY-MM-DD HH:mm:ss') || '-' }}
|
||||
</template>
|
||||
|
||||
<template #createUserFilter="{ columnConfig }">
|
||||
<TableFilter
|
||||
v-model:visible="createUserFilterVisible"
|
||||
|
@ -127,6 +131,7 @@
|
|||
<script lang="ts" async setup>
|
||||
import { ref } from 'vue';
|
||||
import { Message, TableData } from '@arco-design/web-vue';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import { MsAdvanceFilter } from '@/components/pure/ms-advance-filter';
|
||||
import { BackEndEnum, FilterFormItem, FilterType } from '@/components/pure/ms-advance-filter/type';
|
||||
|
@ -217,6 +222,7 @@
|
|||
dataIndex: 'deleteTime',
|
||||
showDrag: true,
|
||||
width: 199,
|
||||
slotName: 'deleteTimeColumn',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
|
@ -226,7 +232,7 @@
|
|||
{
|
||||
title: 'bugManagement.recycle.deleteMan',
|
||||
dataIndex: 'deleteUserName',
|
||||
width: 112,
|
||||
width: 125,
|
||||
showDrag: true,
|
||||
slotName: 'deleteUser',
|
||||
showTooltip: true,
|
||||
|
@ -236,7 +242,7 @@
|
|||
{
|
||||
title: 'bugManagement.ID',
|
||||
dataIndex: 'num',
|
||||
width: 80,
|
||||
width: 100,
|
||||
showTooltip: true,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
|
@ -248,7 +254,7 @@
|
|||
{
|
||||
title: 'bugManagement.bugName',
|
||||
dataIndex: 'title',
|
||||
width: 200,
|
||||
width: 250,
|
||||
showTooltip: true,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
|
@ -263,15 +269,31 @@
|
|||
slotName: 'handleUser',
|
||||
showTooltip: true,
|
||||
titleSlotName: 'handleUserFilter',
|
||||
width: 112,
|
||||
width: 125,
|
||||
showDrag: true,
|
||||
showInTable: true,
|
||||
},
|
||||
{
|
||||
title: 'bugManagement.status',
|
||||
dataIndex: 'statusName',
|
||||
width: 100,
|
||||
slotName: 'status',
|
||||
titleSlotName: 'statusFilter',
|
||||
showDrag: true,
|
||||
showInTable: true,
|
||||
},
|
||||
{
|
||||
title: 'bugManagement.tag',
|
||||
showDrag: true,
|
||||
width: 200,
|
||||
isStringTag: true,
|
||||
dataIndex: 'tags',
|
||||
},
|
||||
{
|
||||
title: 'bugManagement.creator',
|
||||
dataIndex: 'createUser',
|
||||
slotName: 'createUser',
|
||||
width: 112,
|
||||
width: 125,
|
||||
showTooltip: true,
|
||||
showDrag: true,
|
||||
titleSlotName: 'createUserFilter',
|
||||
|
@ -295,7 +317,7 @@
|
|||
{
|
||||
title: 'bugManagement.updateUser',
|
||||
dataIndex: 'updateUser',
|
||||
width: 112,
|
||||
width: 125,
|
||||
showTooltip: true,
|
||||
showDrag: true,
|
||||
titleSlotName: 'updateUserFilter',
|
||||
|
@ -316,28 +338,6 @@
|
|||
},
|
||||
showInTable: true,
|
||||
},
|
||||
{
|
||||
title: 'bugManagement.status',
|
||||
dataIndex: 'statusName',
|
||||
width: 84,
|
||||
slotName: 'status',
|
||||
titleSlotName: 'statusFilter',
|
||||
showDrag: true,
|
||||
showInTable: true,
|
||||
},
|
||||
{
|
||||
title: 'bugManagement.handleMan',
|
||||
dataIndex: 'handleUserName',
|
||||
showTooltip: true,
|
||||
showDrag: true,
|
||||
},
|
||||
{
|
||||
title: 'bugManagement.tag',
|
||||
showDrag: true,
|
||||
width: 456,
|
||||
isStringTag: true,
|
||||
dataIndex: 'tags',
|
||||
},
|
||||
{
|
||||
title: 'common.operation',
|
||||
slotName: 'operation',
|
||||
|
|
Loading…
Reference in New Issue