fix(缺陷管理): 缺陷管理详情页增加关联用例的角标

--bug=1036510 --user=宋天阳 【缺陷管理】缺陷详情-用例tab页签未展示数量统计 https://www.tapd.cn/55049933/s/1471524
This commit is contained in:
song-tianyang 2024-03-07 17:19:08 +08:00 committed by 建国
parent e94af49d6f
commit 04f93984e1
6 changed files with 82 additions and 42 deletions

View File

@ -58,4 +58,7 @@ public class BugDetailDTO {
@Schema(description = "缺陷状态") @Schema(description = "缺陷状态")
private String status; private String status;
@Schema(description = "缺陷关联的用例数")
private long linkCaseCount;
} }

View File

@ -65,4 +65,6 @@ public interface ExtBugRelateCaseMapper {
* @return 缺陷集合 * @return 缺陷集合
*/ */
List<BugProviderDTO> getAssociateBugs(@Param("request") AssociateBugPageRequest request, @Param("sort") String sort); List<BugProviderDTO> getAssociateBugs(@Param("request") AssociateBugPageRequest request, @Param("sort") String sort);
long countByCaseId(String caseId);
} }

View File

@ -88,6 +88,11 @@
brc.create_time desc brc.create_time desc
</if> </if>
</select> </select>
<select id="countByCaseId" resultType="java.lang.Long">
SELECT count(id)
FROM bug_relation_case brc
where brc.bug_id = #{caseId}
</select>
<sql id="queryWhereConditionByProvider"> <sql id="queryWhereConditionByProvider">
<if test="request.caseId != null and request.caseId != ''"> <if test="request.caseId != null and request.caseId != ''">

View File

@ -300,6 +300,7 @@ public class BugService {
BugFollowerExample example = new BugFollowerExample(); BugFollowerExample example = new BugFollowerExample();
example.createCriteria().andBugIdEqualTo(id).andUserIdEqualTo(currentUser); example.createCriteria().andBugIdEqualTo(id).andUserIdEqualTo(currentUser);
detail.setFollowFlag(bugFollowerMapper.countByExample(example) > 0); detail.setFollowFlag(bugFollowerMapper.countByExample(example) > 0);
detail.setLinkCaseCount(extBugRelateCaseMapper.countByCaseId(id));
return detail; return detail;
} }

View File

@ -86,38 +86,32 @@
<template #first> <template #first>
<div class="leftWrapper h-full"> <div class="leftWrapper h-full">
<div class="header h-[50px]"> <div class="header h-[50px]">
<a-tabs v-model:active-key="activeTab" lazy-load> <MsTab
<a-tab-pane key="detail"> v-model:active-key="activeTab"
<template #title> :content-tab-list="contentTabList"
{{ t('bugManagement.detail.detail') }} :get-text-func="getTabBadge"
</template> class="no-content relative mb-[8px] border-b border-[var(--color-text-n8)]"
<BugDetailTab />
ref="bugDetailTabRef" <div class="tab-pane-container">
:form-item="formItem" <BugDetailTab
:allow-edit="true" v-if="activeTab === 'detail'"
:detail-info="detailInfo" ref="bugDetailTabRef"
@update-success="updateSuccess" :form-item="formItem"
/> :allow-edit="true"
</a-tab-pane> :detail-info="detailInfo"
<a-tab-pane key="case"> @update-success="updateSuccess"
<template #title> />
{{ t('bugManagement.detail.case') }}
</template> <BugCaseTab
<BugCaseTab :bug-id="detailInfo.id" /> v-else-if="activeTab === 'case'"
</a-tab-pane> :bug-id="detailInfo.id"
<a-tab-pane key="comment"> @updateCaseSuccess="updateSuccess"
<template #title> />
{{ t('bugManagement.detail.comment') }}
</template> <CommentTab v-else-if="activeTab === 'comment'" ref="commentRef" :bug-id="detailInfo.id" />
<CommentTab ref="commentRef" :bug-id="detailInfo.id" />
</a-tab-pane> <BugHistoryTab v-else-if="activeTab === 'history'" :bug-id="detailInfo.id" />
<a-tab-pane key="history"> </div>
<template #title>
{{ t('bugManagement.detail.changeHistory') }}
</template>
<BugHistoryTab :bug-id="detailInfo.id" />
</a-tab-pane>
</a-tabs>
</div> </div>
</div> </div>
</template> </template>
@ -142,15 +136,6 @@
<MsTag v-for="item of tags" :key="item"> {{ item }} </MsTag> <MsTag v-for="item of tags" :key="item"> {{ item }} </MsTag>
</span> </span>
</div> </div>
<!-- 创建人 创建时间需求说先去掉 -->
<!-- <div class="baseItem">
<span class="label"> {{ t('bugManagement.detail.creator') }}</span>
<span>{{ detailInfo?.createUserName }}</span>
</div>
<div class="baseItem">
<span class="label"> {{ t('bugManagement.detail.createTime') }}</span>
<span>{{ dayjs(detailInfo?.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
</div> -->
</div> </div>
</template> </template>
</MsSplitBox> </MsSplitBox>
@ -178,6 +163,7 @@
import type { FormItem, FormRuleItem } from '@/components/pure/ms-form-create/types'; import type { FormItem, FormRuleItem } from '@/components/pure/ms-form-create/types';
import MsIcon from '@/components/pure/ms-icon-font/index.vue'; import MsIcon from '@/components/pure/ms-icon-font/index.vue';
import MsSplitBox from '@/components/pure/ms-split-box/index.vue'; import MsSplitBox from '@/components/pure/ms-split-box/index.vue';
import MsTab from '@/components/pure/ms-tab/index.vue';
import type { MsPaginationI } from '@/components/pure/ms-table/type'; import type { MsPaginationI } from '@/components/pure/ms-table/type';
import MsTag from '@/components/pure/ms-tag/ms-tag.vue'; import MsTag from '@/components/pure/ms-tag/ms-tag.vue';
import { CommentInput } from '@/components/business/ms-comment'; import { CommentInput } from '@/components/business/ms-comment';
@ -221,6 +207,7 @@
pageChange: (page: number) => Promise<void>; // pageChange: (page: number) => Promise<void>; //
}>(); }>();
const caseCount = ref(0);
const appStore = useAppStore(); const appStore = useAppStore();
const commentContent = ref(''); const commentContent = ref('');
const commentRef = ref(); const commentRef = ref();
@ -232,7 +219,7 @@
const showDrawerVisible = defineModel<boolean>('visible', { default: false }); const showDrawerVisible = defineModel<boolean>('visible', { default: false });
const bugDetailTabRef = ref(); const bugDetailTabRef = ref();
const activeTab = ref<string | number>('detail'); const activeTab = ref<string>('detail');
const detailInfo = ref<Record<string, any>>({ match: [] }); // loadBug const detailInfo = ref<Record<string, any>>({ match: [] }); // loadBug
const tags = ref([]); const tags = ref([]);
@ -279,6 +266,7 @@
const { templateId } = detail; const { templateId } = detail;
// tag // tag
tags.value = detail.tags || []; tags.value = detail.tags || [];
caseCount.value = detail.linkCaseCount;
const tmpObj = {}; const tmpObj = {};
if (detail.customFields && Array.isArray(detail.customFields)) { if (detail.customFields && Array.isArray(detail.customFields)) {
detail.customFields.forEach((item) => { detail.customFields.forEach((item) => {
@ -292,6 +280,23 @@
// //
await templateChange(templateId, tmpObj, { platformBugKey: detail.platformBugId, fromStatusId: detail.status }); await templateChange(templateId, tmpObj, { platformBugKey: detail.platformBugId, fromStatusId: detail.status });
} }
/**
* 获取 tab 的参数数量徽标
*/
function getTabBadge(tabKey: string) {
switch (tabKey) {
case 'detail':
return '';
case 'case':
return `${caseCount.value > 0 ? caseCount.value : ''}`;
case 'comment':
return '';
case 'history':
return '';
default:
return '';
}
}
const editLoading = ref<boolean>(false); const editLoading = ref<boolean>(false);
@ -299,6 +304,27 @@
detailDrawerRef.value?.initDetail(); detailDrawerRef.value?.initDetail();
} }
const contentTabList = computed(() => {
return [
{
value: 'detail',
label: t('bugManagement.detail.detail'),
},
{
value: 'case',
label: t('bugManagement.detail.case'),
},
{
value: 'comment',
label: t('bugManagement.detail.comment'),
},
{
value: 'history',
label: t('bugManagement.detail.changeHistory'),
},
];
});
function updateHandler() { function updateHandler() {
router.push({ router.push({
name: RouteEnum.BUG_MANAGEMENT_DETAIL, name: RouteEnum.BUG_MANAGEMENT_DETAIL,

View File

@ -115,6 +115,7 @@
(e: 'update:project', val: string): void; (e: 'update:project', val: string): void;
(e: 'success', val: string[]): void; (e: 'success', val: string[]): void;
(e: 'close'): void; (e: 'close'): void;
(e: 'updateCaseSuccess'): void;
}>(); }>();
const keyword = ref<string>(''); const keyword = ref<string>('');
@ -218,6 +219,7 @@
const { relateId } = record; const { relateId } = record;
await cancelAssociation(relateId); await cancelAssociation(relateId);
await getFetch(); await getFetch();
emit('updateCaseSuccess');
Message.success(t('common.unLinkSuccess')); Message.success(t('common.unLinkSuccess'));
} catch (error) { } catch (error) {
console.log(error); console.log(error);
@ -236,6 +238,7 @@
await batchAssociation(params); await batchAssociation(params);
await getFetch(); await getFetch();
Message.success(t('common.linkSuccess')); Message.success(t('common.linkSuccess'));
emit('updateCaseSuccess');
innerVisible.value = false; innerVisible.value = false;
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console