fix(缺陷管理): 修复缺陷操作相关的通知问题
--bug=1036449 --user=宋昌昌 【项目管理】消息通知-批量编辑缺陷-未发送通知 https://www.tapd.cn/55049933/s/1467801
This commit is contained in:
parent
8265d5f21b
commit
ceafebe073
|
@ -125,8 +125,8 @@ public class BugController {
|
||||||
@GetMapping("/delete/{id}")
|
@GetMapping("/delete/{id}")
|
||||||
@Operation(summary = "缺陷管理-列表-删除缺陷")
|
@Operation(summary = "缺陷管理-列表-删除缺陷")
|
||||||
@RequiresPermissions(PermissionConstants.PROJECT_BUG_DELETE)
|
@RequiresPermissions(PermissionConstants.PROJECT_BUG_DELETE)
|
||||||
@Log(type = OperationLogType.DELETE, expression = "#msClass.deleteLog(#id)", msClass = BugLogService.class)
|
|
||||||
@SendNotice(taskType = NoticeConstants.TaskType.BUG_TASK, event = NoticeConstants.Event.DELETE, target = "#targetClass.getNoticeById(#id)", targetClass = BugNoticeService.class)
|
@SendNotice(taskType = NoticeConstants.TaskType.BUG_TASK, event = NoticeConstants.Event.DELETE, target = "#targetClass.getNoticeById(#id)", targetClass = BugNoticeService.class)
|
||||||
|
@Log(type = OperationLogType.DELETE, expression = "#msClass.deleteLog(#id)", msClass = BugLogService.class)
|
||||||
public void delete(@PathVariable String id) {
|
public void delete(@PathVariable String id) {
|
||||||
bugService.delete(id, SessionUtils.getUserId());
|
bugService.delete(id, SessionUtils.getUserId());
|
||||||
}
|
}
|
||||||
|
@ -176,6 +176,7 @@ public class BugController {
|
||||||
@Operation(summary = "缺陷管理-列表-批量删除缺陷")
|
@Operation(summary = "缺陷管理-列表-批量删除缺陷")
|
||||||
@RequiresPermissions(PermissionConstants.PROJECT_BUG_DELETE)
|
@RequiresPermissions(PermissionConstants.PROJECT_BUG_DELETE)
|
||||||
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
||||||
|
@SendNotice(taskType = NoticeConstants.TaskType.BUG_TASK, event = NoticeConstants.Event.DELETE, target = "#targetClass.getBatchNoticeByRequest(#request)", targetClass = BugNoticeService.class)
|
||||||
public void batchDelete(@Validated @RequestBody BugBatchRequest request) {
|
public void batchDelete(@Validated @RequestBody BugBatchRequest request) {
|
||||||
request.setUseTrash(false);
|
request.setUseTrash(false);
|
||||||
bugService.batchDelete(request, SessionUtils.getUserId());
|
bugService.batchDelete(request, SessionUtils.getUserId());
|
||||||
|
@ -185,6 +186,7 @@ public class BugController {
|
||||||
@Operation(summary = "缺陷管理-列表-批量编辑缺陷")
|
@Operation(summary = "缺陷管理-列表-批量编辑缺陷")
|
||||||
@RequiresPermissions(PermissionConstants.PROJECT_BUG_UPDATE)
|
@RequiresPermissions(PermissionConstants.PROJECT_BUG_UPDATE)
|
||||||
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
||||||
|
@SendNotice(taskType = NoticeConstants.TaskType.BUG_TASK, event = NoticeConstants.Event.UPDATE, target = "#targetClass.getBatchNoticeByRequest(#request)", targetClass = BugNoticeService.class)
|
||||||
public void batchUpdate(@Validated @RequestBody BugBatchUpdateRequest request) {
|
public void batchUpdate(@Validated @RequestBody BugBatchUpdateRequest request) {
|
||||||
request.setUseTrash(false);
|
request.setUseTrash(false);
|
||||||
bugService.batchUpdate(request, SessionUtils.getUserId());
|
bugService.batchUpdate(request, SessionUtils.getUserId());
|
||||||
|
|
|
@ -106,7 +106,7 @@ public class BugLogService {
|
||||||
* @param id 缺陷ID
|
* @param id 缺陷ID
|
||||||
* @return 缺陷DTO
|
* @return 缺陷DTO
|
||||||
*/
|
*/
|
||||||
private BugDTO getOriginalValue(String id) {
|
public BugDTO getOriginalValue(String id) {
|
||||||
// 缺陷基础信息
|
// 缺陷基础信息
|
||||||
BugDTO originalBug = new BugDTO();
|
BugDTO originalBug = new BugDTO();
|
||||||
Bug bug = bugMapper.selectByPrimaryKey(id);
|
Bug bug = bugMapper.selectByPrimaryKey(id);
|
||||||
|
|
|
@ -1,27 +1,19 @@
|
||||||
package io.metersphere.bug.service;
|
package io.metersphere.bug.service;
|
||||||
|
|
||||||
import io.metersphere.bug.domain.Bug;
|
import io.metersphere.bug.dto.request.BugBatchRequest;
|
||||||
import io.metersphere.bug.dto.request.BugEditRequest;
|
import io.metersphere.bug.dto.request.BugEditRequest;
|
||||||
import io.metersphere.bug.dto.response.BugCustomFieldDTO;
|
import io.metersphere.bug.dto.response.BugDTO;
|
||||||
import io.metersphere.bug.mapper.ExtBugCustomFieldMapper;
|
|
||||||
import io.metersphere.plugin.platform.dto.SelectOption;
|
import io.metersphere.plugin.platform.dto.SelectOption;
|
||||||
import io.metersphere.system.domain.User;
|
import io.metersphere.sdk.util.BeanUtils;
|
||||||
import io.metersphere.system.dto.BugNoticeDTO;
|
import io.metersphere.system.dto.BugNoticeDTO;
|
||||||
import io.metersphere.system.dto.sdk.OptionDTO;
|
import io.metersphere.system.dto.sdk.OptionDTO;
|
||||||
import io.metersphere.system.mapper.UserMapper;
|
|
||||||
import io.metersphere.system.notice.NoticeModel;
|
|
||||||
import io.metersphere.system.notice.constants.NoticeConstants;
|
|
||||||
import io.metersphere.system.notice.utils.MessageTemplateUtils;
|
|
||||||
import io.metersphere.system.service.NoticeSendService;
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.apache.commons.beanutils.BeanMap;
|
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -35,15 +27,13 @@ public class BugNoticeService {
|
||||||
public static final String CUSTOM_HANDLE_USER = "处理人";
|
public static final String CUSTOM_HANDLE_USER = "处理人";
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private UserMapper userMapper;
|
private BugService bugService;
|
||||||
|
@Resource
|
||||||
|
private BugLogService bugLogService;
|
||||||
@Resource
|
@Resource
|
||||||
private BugCommonService bugCommonService;
|
private BugCommonService bugCommonService;
|
||||||
@Resource
|
@Resource
|
||||||
private BugStatusService bugStatusService;
|
private BugStatusService bugStatusService;
|
||||||
@Resource
|
|
||||||
private NoticeSendService noticeSendService;
|
|
||||||
@Resource
|
|
||||||
private ExtBugCustomFieldMapper extBugCustomFieldMapper;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取缺陷通知
|
* 获取缺陷通知
|
||||||
|
@ -84,43 +74,46 @@ public class BugNoticeService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送删除缺陷通知
|
* 获取缺陷通知
|
||||||
* @param bug 缺陷
|
* @param id 缺陷ID
|
||||||
* @param currentUser 当前用户
|
|
||||||
*/
|
*/
|
||||||
public void sendDeleteNotice(Bug bug, String currentUser) {
|
public BugNoticeDTO getNoticeById(String id) {
|
||||||
Map<String, String> statusMap = getStatusMap(bug.getProjectId());
|
// 缺陷基础信息
|
||||||
Map<String, String> handlerMap = getHandleMap(bug.getProjectId());
|
BugDTO bugDTO = bugLogService.getOriginalValue(id);
|
||||||
// 缺陷相关内容
|
// 构建通知对象
|
||||||
BugNoticeDTO notice = new BugNoticeDTO();
|
BugNoticeDTO notice = new BugNoticeDTO();
|
||||||
notice.setTitle(bug.getTitle());
|
BeanUtils.copyBean(notice, bugDTO);
|
||||||
notice.setStatus(statusMap.get(bug.getStatus()));
|
// 自定义字段解析{name: value}
|
||||||
notice.setHandleUser(handlerMap.get(bug.getHandleUser()));
|
if (CollectionUtils.isNotEmpty(bugDTO.getCustomFields())) {
|
||||||
List<BugCustomFieldDTO> customFields = extBugCustomFieldMapper.getBugAllCustomFields(List.of(bug.getId()), bug.getProjectId());
|
List<OptionDTO> fields = new ArrayList<>();
|
||||||
List<OptionDTO> fields = customFields.stream().map(field -> {
|
bugDTO.getCustomFields().forEach(field -> {
|
||||||
OptionDTO fieldDTO = new OptionDTO();
|
// 其他自定义字段
|
||||||
fieldDTO.setId(field.getName());
|
OptionDTO fieldDTO = new OptionDTO();
|
||||||
fieldDTO.setName(field.getValue());
|
fieldDTO.setId(field.getName());
|
||||||
return fieldDTO;
|
fieldDTO.setName(field.getValue());
|
||||||
}).toList();
|
fields.add(fieldDTO);
|
||||||
notice.setCustomFields(fields);
|
});
|
||||||
BeanMap beanMap = new BeanMap(notice);
|
notice.setCustomFields(fields);
|
||||||
User user = userMapper.selectByPrimaryKey(currentUser);
|
}
|
||||||
Map paramMap = new HashMap<>(beanMap);
|
return notice;
|
||||||
paramMap.put(NoticeConstants.RelatedUser.OPERATOR, user.getName());
|
}
|
||||||
Map<String, String> defaultTemplateMap = MessageTemplateUtils.getDefaultTemplateMap();
|
|
||||||
String template = defaultTemplateMap.get(NoticeConstants.TemplateText.BUG_TASK_DELETE);
|
/**
|
||||||
Map<String, String> defaultSubjectMap = MessageTemplateUtils.getDefaultTemplateSubjectMap();
|
* 获取批量操作的缺陷通知
|
||||||
String subject = defaultSubjectMap.get(NoticeConstants.TemplateText.BUG_TASK_DELETE);
|
* @param request 批量请求参数
|
||||||
NoticeModel noticeModel = NoticeModel.builder().operator(currentUser)
|
* @return 缺陷通知集合
|
||||||
.context(template).subject(subject).paramMap(paramMap).event(NoticeConstants.Event.DELETE).build();
|
*/
|
||||||
noticeSendService.send(NoticeConstants.TaskType.BUG_TASK, noticeModel);
|
public List<BugNoticeDTO> getBatchNoticeByRequest(BugBatchRequest request) {
|
||||||
|
List<BugNoticeDTO> notices = new ArrayList<>();
|
||||||
|
List<String> batchIds = bugService.getBatchIdsByRequest(request);
|
||||||
|
batchIds.forEach(id -> notices.add(getNoticeById(id)));
|
||||||
|
return notices;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取状态集合
|
* 获取状态集合
|
||||||
* @param projectId 项目ID
|
* @param projectId 项目ID
|
||||||
* @return
|
* @return 状态集合
|
||||||
*/
|
*/
|
||||||
private Map<String, String> getStatusMap(String projectId) {
|
private Map<String, String> getStatusMap(String projectId) {
|
||||||
List<SelectOption> statusOption = bugStatusService.getHeaderStatusOption(projectId);
|
List<SelectOption> statusOption = bugStatusService.getHeaderStatusOption(projectId);
|
||||||
|
|
|
@ -91,8 +91,6 @@ import static io.metersphere.bug.enums.result.BugResultCode.NOT_LOCAL_BUG_ERROR;
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public class BugService {
|
public class BugService {
|
||||||
|
|
||||||
private static int MAX_TAG_SIZE = 10;
|
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private BugMapper bugMapper;
|
private BugMapper bugMapper;
|
||||||
@Resource
|
@Resource
|
||||||
|
@ -118,8 +116,6 @@ public class BugService {
|
||||||
@Resource
|
@Resource
|
||||||
private BaseTemplateCustomFieldService baseTemplateCustomFieldService;
|
private BaseTemplateCustomFieldService baseTemplateCustomFieldService;
|
||||||
@Resource
|
@Resource
|
||||||
private BugNoticeService bugNoticeService;
|
|
||||||
@Resource
|
|
||||||
private BugCommonService bugCommonService;
|
private BugCommonService bugCommonService;
|
||||||
@Resource
|
@Resource
|
||||||
private BugCustomFieldMapper bugCustomFieldMapper;
|
private BugCustomFieldMapper bugCustomFieldMapper;
|
||||||
|
@ -162,6 +158,8 @@ public class BugService {
|
||||||
|
|
||||||
public static final Long INTERVAL_POS = 5000L;
|
public static final Long INTERVAL_POS = 5000L;
|
||||||
|
|
||||||
|
private static final int MAX_TAG_SIZE = 10;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 缺陷列表查询
|
* 缺陷列表查询
|
||||||
*
|
*
|
||||||
|
@ -178,12 +176,6 @@ public class BugService {
|
||||||
return buildExtraInfo(bugList);
|
return buildExtraInfo(bugList);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkTagLength(List<String> tags) {
|
|
||||||
if (CollectionUtils.isNotEmpty(tags) && tags.size() > MAX_TAG_SIZE) {
|
|
||||||
throw new MSException(Translator.getWithArgs("bug_tags_size_large_than", String.valueOf(MAX_TAG_SIZE)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建或编辑缺陷
|
* 创建或编辑缺陷
|
||||||
*
|
*
|
||||||
|
@ -332,8 +324,6 @@ public class BugService {
|
||||||
clearAssociate(id, bug.getProjectId());
|
clearAssociate(id, bug.getProjectId());
|
||||||
bugMapper.deleteByPrimaryKey(id);
|
bugMapper.deleteByPrimaryKey(id);
|
||||||
}
|
}
|
||||||
// 发送通知
|
|
||||||
bugNoticeService.sendDeleteNotice(bug, currentUser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1511,4 +1501,14 @@ public class BugService {
|
||||||
Set<Object> keySet = ConcurrentHashMap.newKeySet();
|
Set<Object> keySet = ConcurrentHashMap.newKeySet();
|
||||||
return t -> keySet.add(function.apply(t));
|
return t -> keySet.add(function.apply(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验TAG长度
|
||||||
|
* @param tags 标签集合
|
||||||
|
*/
|
||||||
|
private void checkTagLength(List<String> tags) {
|
||||||
|
if (CollectionUtils.isNotEmpty(tags) && tags.size() > MAX_TAG_SIZE) {
|
||||||
|
throw new MSException(Translator.getWithArgs("bug_tags_size_large_than", String.valueOf(MAX_TAG_SIZE)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -123,53 +123,48 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" async setup>
|
<script lang="ts" async setup>
|
||||||
import { useRoute } from 'vue-router';
|
import {useRoute} from 'vue-router';
|
||||||
import { useIntervalFn } from '@vueuse/core';
|
import {useIntervalFn} from '@vueuse/core';
|
||||||
import { Message, TableData } from '@arco-design/web-vue';
|
import {Message, TableData} from '@arco-design/web-vue';
|
||||||
|
|
||||||
import { MsAdvanceFilter, timeSelectOptions } from '@/components/pure/ms-advance-filter';
|
import {MsAdvanceFilter, timeSelectOptions} from '@/components/pure/ms-advance-filter';
|
||||||
import { BackEndEnum, FilterFormItem, FilterResult, FilterType } from '@/components/pure/ms-advance-filter/type';
|
import {BackEndEnum, FilterFormItem, FilterResult, FilterType} from '@/components/pure/ms-advance-filter/type';
|
||||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||||
import MsCard from '@/components/pure/ms-card/index.vue';
|
import MsCard from '@/components/pure/ms-card/index.vue';
|
||||||
import MsExportDrawer from '@/components/pure/ms-export-drawer/index.vue';
|
import MsExportDrawer from '@/components/pure/ms-export-drawer/index.vue';
|
||||||
import { MsExportDrawerMap, MsExportDrawerOption } from '@/components/pure/ms-export-drawer/types';
|
import {MsExportDrawerMap, MsExportDrawerOption} from '@/components/pure/ms-export-drawer/types';
|
||||||
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||||
import { BatchActionParams, BatchActionQueryParams, MsTableColumn } from '@/components/pure/ms-table/type';
|
import {BatchActionParams, BatchActionQueryParams, MsTableColumn} from '@/components/pure/ms-table/type';
|
||||||
import useTable from '@/components/pure/ms-table/useTable';
|
import useTable from '@/components/pure/ms-table/useTable';
|
||||||
import MsTableMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
import MsTableMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
||||||
import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
import {ActionsItem} from '@/components/pure/ms-table-more-action/types';
|
||||||
import BatchEditModal from './components/batchEditModal.vue';
|
import BatchEditModal from './components/batchEditModal.vue';
|
||||||
import BugDetailDrawer from './components/bug-detail-drawer.vue';
|
import BugDetailDrawer from './components/bug-detail-drawer.vue';
|
||||||
import DeleteModal from './components/deleteModal.vue';
|
import DeleteModal from './components/deleteModal.vue';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
deleteBatchBug,
|
deleteBatchBug,
|
||||||
deleteSingleBug,
|
deleteSingleBug,
|
||||||
exportBug,
|
exportBug,
|
||||||
getBugList,
|
getBugList,
|
||||||
getCustomFieldHeader,
|
getCustomFieldHeader,
|
||||||
getExportConfig,
|
getExportConfig,
|
||||||
getSyncStatus,
|
getSyncStatus,
|
||||||
syncBugEnterprise,
|
syncBugEnterprise,
|
||||||
syncBugOpenSource,
|
syncBugOpenSource,
|
||||||
} from '@/api/modules/bug-management';
|
} from '@/api/modules/bug-management';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import {useI18n} from '@/hooks/useI18n';
|
||||||
import useModal from '@/hooks/useModal';
|
import useModal from '@/hooks/useModal';
|
||||||
import router from '@/router';
|
import router from '@/router';
|
||||||
import { useAppStore, useTableStore } from '@/store';
|
import {useAppStore, useTableStore} from '@/store';
|
||||||
import useLicenseStore from '@/store/modules/setting/license';
|
import useLicenseStore from '@/store/modules/setting/license';
|
||||||
import {
|
import {customFieldDataToTableData, customFieldToColumns, downloadByteFile, tableParamsToRequestParams,} from '@/utils';
|
||||||
customFieldDataToTableData,
|
|
||||||
customFieldToColumns,
|
|
||||||
downloadByteFile,
|
|
||||||
tableParamsToRequestParams,
|
|
||||||
} from '@/utils';
|
|
||||||
|
|
||||||
import { BugEditCustomField, BugListItem } from '@/models/bug-management';
|
import {BugEditCustomField, BugListItem} from '@/models/bug-management';
|
||||||
import { RouteEnum } from '@/enums/routeEnum';
|
import {RouteEnum} from '@/enums/routeEnum';
|
||||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
import {TableKeyEnum} from '@/enums/tableEnum';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const tableStore = useTableStore();
|
const tableStore = useTableStore();
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
|
@ -291,19 +286,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'bugManagement.creator',
|
title: 'bugManagement.creator',
|
||||||
slotName: 'createUserName',
|
dataIndex: 'createUser',
|
||||||
dataIndex: 'createUserName',
|
|
||||||
width: 112,
|
|
||||||
showTooltip: true,
|
|
||||||
showDrag: true,
|
|
||||||
sortable: {
|
|
||||||
sortDirections: ['ascend', 'descend'],
|
|
||||||
sorter: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'bugManagement.updateUser',
|
|
||||||
dataIndex: 'updateUserName',
|
|
||||||
width: 112,
|
width: 112,
|
||||||
showTooltip: true,
|
showTooltip: true,
|
||||||
showDrag: true,
|
showDrag: true,
|
||||||
|
@ -324,7 +307,6 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'bugManagement.updateUser',
|
title: 'bugManagement.updateUser',
|
||||||
slotName: 'updateUserName',
|
|
||||||
dataIndex: 'updateUser',
|
dataIndex: 'updateUser',
|
||||||
width: 112,
|
width: 112,
|
||||||
showTooltip: true,
|
showTooltip: true,
|
||||||
|
|
Loading…
Reference in New Issue