feat(测试计划): 测试计划-报告-详情-缺陷和功能用例tab
This commit is contained in:
parent
553ebde094
commit
c3f576d544
|
@ -1,7 +1,8 @@
|
|||
import MSR from '@/api/http';
|
||||
import * as reportUrl from '@/api/requrls/test-plan/report';
|
||||
|
||||
import type { TableQueryParams } from '@/models/common';
|
||||
import { CommonList, TableQueryParams } from '@/models/common';
|
||||
import { FeatureCaseItem, ReportBugItem, UpdateReportDetailParams } from '@/models/testPlan/report';
|
||||
|
||||
// 报告列表
|
||||
export function reportList(data: TableQueryParams) {
|
||||
|
@ -23,4 +24,19 @@ export function reportBathDelete(data: TableQueryParams) {
|
|||
return MSR.post({ url: reportUrl.PlanBatchDeleteUrl, data });
|
||||
}
|
||||
|
||||
// 测试计划-报告-详情-缺陷分页查询
|
||||
export function getReportBugList(data: TableQueryParams) {
|
||||
return MSR.post<CommonList<ReportBugItem>>({ url: reportUrl.ReportBugListUrl, data });
|
||||
}
|
||||
|
||||
// 测试计划-报告-详情-功能用例分页查询
|
||||
export function getReportFeatureCaseList(data: TableQueryParams) {
|
||||
return MSR.post<CommonList<FeatureCaseItem>>({ url: reportUrl.ReportFeatureCaseListUrl, data });
|
||||
}
|
||||
|
||||
// 测试计划-报告-详情-报告内容更新
|
||||
export function updateReportDetail(data: UpdateReportDetailParams) {
|
||||
return MSR.post({ url: reportUrl.UpdateReportDetailUrl, data });
|
||||
}
|
||||
|
||||
export default {};
|
||||
|
|
|
@ -6,3 +6,9 @@ export const PlanReportRenameUrl = '/test-plan/report/rename';
|
|||
export const PlanDeleteUrl = '/test-plan/report/delete';
|
||||
// 批量删除报告
|
||||
export const PlanBatchDeleteUrl = '/test-plan/report/batch-delete';
|
||||
// 测试计划-报告-详情-缺陷分页查询
|
||||
export const ReportBugListUrl = '/test-plan/report/detail/bug/page';
|
||||
// 测试计划-报告-详情-功能用例分页查询
|
||||
export const ReportFeatureCaseListUrl = '/test-plan/report/detail/functional/case/page';
|
||||
// 测试计划-报告-详情-报告内容更新
|
||||
export const UpdateReportDetailUrl = '/test-plan/report/detail/edit';
|
||||
|
|
|
@ -67,6 +67,8 @@ export enum TableKeyEnum {
|
|||
TEST_PLAN_DETAIL_FEATURE_CASE_TABLE = 'testPlanDetailFeatureCaseTable',
|
||||
TEST_PLAN_DETAIL_BUG_TABLE_CASE_COUNT = 'testPlanDetailBugCaseCount',
|
||||
TEST_PLAN_REPORT_TABLE = 'testPlanReportTable',
|
||||
TEST_PLAN_REPORT_DETAIL_BUG = 'testPlanReportDetailBug',
|
||||
TEST_PLAN_REPORT_DETAIL_FEATURE_CASE = 'testPlanReportDetailFeatureCase',
|
||||
TASK_API_CASE_SYSTEM = 'taskCenterApiCaseSystem',
|
||||
TASK_API_CASE_ORGANIZATION = 'taskCenterApiCaseOrganization',
|
||||
TASK_API_CASE_PROJECT = 'taskCenterApiCaseProject',
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
export interface ReportBugItem {
|
||||
id: string;
|
||||
num: number;
|
||||
title: string;
|
||||
status: string;
|
||||
handleUserName: string;
|
||||
relationCaseCount: number;
|
||||
}
|
||||
|
||||
export interface FeatureCaseItem {
|
||||
id: string;
|
||||
num: number;
|
||||
name: string;
|
||||
moduleName: string;
|
||||
priority: string;
|
||||
executeResult: string;
|
||||
executeUserName: string;
|
||||
bugCount: number;
|
||||
}
|
||||
|
||||
export interface UpdateReportDetailParams {
|
||||
id: string;
|
||||
summary: string;
|
||||
richTextTmpFileIds: string[];
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
<template>
|
||||
<MsBaseTable v-bind="propsRes" v-on="propsEvent"> </MsBaseTable>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onBeforeMount } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||
import type { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||
import useTable from '@/components/pure/ms-table/useTable';
|
||||
|
||||
import { getReportBugList } from '@/api/modules/test-plan/report';
|
||||
import { useTableStore } from '@/store';
|
||||
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
|
||||
const props = defineProps<{
|
||||
reportId: string;
|
||||
}>();
|
||||
|
||||
const tableStore = useTableStore();
|
||||
const route = useRoute();
|
||||
|
||||
const columns: MsTableColumn = [
|
||||
{
|
||||
title: 'ID',
|
||||
dataIndex: 'num',
|
||||
slotName: 'num',
|
||||
sortIndex: 1,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
fixed: 'left',
|
||||
width: 100,
|
||||
ellipsis: true,
|
||||
showTooltip: true,
|
||||
},
|
||||
{
|
||||
title: 'bugManagement.bugName',
|
||||
dataIndex: 'title',
|
||||
width: 150,
|
||||
showTooltip: true,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'bugManagement.status',
|
||||
dataIndex: 'status',
|
||||
width: 100,
|
||||
showTooltip: true,
|
||||
},
|
||||
{
|
||||
title: 'bugManagement.handleMan',
|
||||
dataIndex: 'handleUserName',
|
||||
showTooltip: true,
|
||||
width: 125,
|
||||
},
|
||||
{
|
||||
title: 'bugManagement.numberOfCase',
|
||||
dataIndex: 'relationCaseCount',
|
||||
width: 80,
|
||||
},
|
||||
];
|
||||
const { propsRes, propsEvent, loadList, setLoadListParams } = useTable(getReportBugList, {
|
||||
scroll: { x: '100%' },
|
||||
columns,
|
||||
tableKey: TableKeyEnum.TEST_PLAN_REPORT_DETAIL_BUG,
|
||||
showSelectorAll: false,
|
||||
});
|
||||
|
||||
async function loadCaseList() {
|
||||
setLoadListParams({ reportId: props.reportId, shareId: route.query.shareId as string | undefined });
|
||||
loadList();
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
loadCaseList();
|
||||
});
|
||||
|
||||
await tableStore.initColumn(TableKeyEnum.TEST_PLAN_REPORT_DETAIL_BUG, columns, 'drawer');
|
||||
</script>
|
|
@ -0,0 +1,120 @@
|
|||
<template>
|
||||
<MsBaseTable v-bind="propsRes" v-on="propsEvent">
|
||||
<template #caseLevel="{ record }">
|
||||
<CaseLevel :case-level="record.priority" />
|
||||
</template>
|
||||
<template #[FilterSlotNameEnum.CASE_MANAGEMENT_EXECUTE_RESULT]="{ filterContent }">
|
||||
<ExecuteResult :execute-result="filterContent.key" />
|
||||
</template>
|
||||
<template #lastExecResult="{ record }">
|
||||
<ExecuteResult :execute-result="record.executeResult" />
|
||||
</template>
|
||||
</MsBaseTable>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onBeforeMount } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||
import type { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||
import useTable from '@/components/pure/ms-table/useTable';
|
||||
import CaseLevel from '@/components/business/ms-case-associate/caseLevel.vue';
|
||||
import ExecuteResult from '@/components/business/ms-case-associate/executeResult.vue';
|
||||
|
||||
import { getReportFeatureCaseList } from '@/api/modules/test-plan/report';
|
||||
import { useTableStore } from '@/store';
|
||||
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
|
||||
|
||||
import { executionResultMap } from '@/views/case-management/caseManagementFeature/components/utils';
|
||||
|
||||
const props = defineProps<{
|
||||
reportId: string;
|
||||
}>();
|
||||
|
||||
const tableStore = useTableStore();
|
||||
const route = useRoute();
|
||||
|
||||
const columns: MsTableColumn = [
|
||||
{
|
||||
title: 'ID',
|
||||
dataIndex: 'num',
|
||||
slotName: 'num',
|
||||
sortIndex: 1,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
fixed: 'left',
|
||||
width: 100,
|
||||
ellipsis: true,
|
||||
showTooltip: true,
|
||||
},
|
||||
{
|
||||
title: 'case.caseName',
|
||||
dataIndex: 'name',
|
||||
showTooltip: true,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: 'case.caseLevel',
|
||||
dataIndex: 'priority',
|
||||
slotName: 'caseLevel',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: 'common.executionResult',
|
||||
dataIndex: 'executeResult',
|
||||
slotName: 'lastExecResult',
|
||||
filterConfig: {
|
||||
valueKey: 'key',
|
||||
labelKey: 'statusText',
|
||||
options: Object.values(executionResultMap),
|
||||
filterSlotName: FilterSlotNameEnum.CASE_MANAGEMENT_EXECUTE_RESULT,
|
||||
},
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: 'common.belongModule',
|
||||
dataIndex: 'moduleName',
|
||||
ellipsis: true,
|
||||
showTooltip: true,
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: 'testPlan.featureCase.bugCount',
|
||||
dataIndex: 'bugCount',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: 'testPlan.featureCase.executor',
|
||||
dataIndex: 'executeUserName',
|
||||
showTooltip: true,
|
||||
width: 150,
|
||||
},
|
||||
];
|
||||
const { propsRes, propsEvent, loadList, setLoadListParams } = useTable(getReportFeatureCaseList, {
|
||||
scroll: { x: '100%' },
|
||||
columns,
|
||||
tableKey: TableKeyEnum.TEST_PLAN_REPORT_DETAIL_FEATURE_CASE,
|
||||
heightUsed: 20,
|
||||
showSelectorAll: false,
|
||||
});
|
||||
|
||||
async function loadCaseList() {
|
||||
setLoadListParams({ reportId: props.reportId, shareId: route.query.shareId as string | undefined });
|
||||
loadList();
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
loadCaseList();
|
||||
});
|
||||
|
||||
await tableStore.initColumn(TableKeyEnum.TEST_PLAN_REPORT_DETAIL_FEATURE_CASE, columns, 'drawer');
|
||||
</script>
|
|
@ -1,13 +1,79 @@
|
|||
<template>
|
||||
<MsCard class="mb-[16px]" hide-back hide-footer auto-height no-content-padding hide-divider> </MsCard>
|
||||
<MsCard class="mb-[16px]" hide-back hide-footer auto-height no-content-padding hide-divider> </MsCard>
|
||||
<MsCard class="mb-[16px]" hide-back hide-footer auto-height no-content-padding hide-divider> </MsCard>
|
||||
<MsCard class="mb-[16px]" simple auto-height>
|
||||
<div class="font-medium">{{ t('report.detail.reportSummary') }}</div>
|
||||
<MsRichText
|
||||
v-model:raw="richText.summary"
|
||||
v-model:filedIds="richText.richTextTmpFileIds"
|
||||
:upload-image="handleUploadImage"
|
||||
:preview-url="PreviewEditorImageUrl"
|
||||
class="mt-[8px] w-full"
|
||||
/>
|
||||
<div class="mt-[16px] flex items-center gap-[12px]">
|
||||
<a-button type="primary" @click="handleUpdateReportDetail">{{ t('common.save') }}</a-button>
|
||||
<a-button type="secondary" @click="handleCancel">{{ t('common.cancel') }}</a-button>
|
||||
</div>
|
||||
</MsCard>
|
||||
<MsCard simple auto-height>
|
||||
<MsTab
|
||||
v-model:active-key="activeTab"
|
||||
:show-badge="false"
|
||||
:content-tab-list="contentTabList"
|
||||
no-content
|
||||
class="relative mb-[16px] border-b"
|
||||
/>
|
||||
<BugTable v-if="activeTab === 'bug'" :report-id="reportId" />
|
||||
<FeatureCaseTable v-if="activeTab === 'featureCase'" :report-id="reportId" />
|
||||
</MsCard>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import MsCard from '@/components/pure/ms-card/index.vue';
|
||||
import MsRichText from '@/components/pure/ms-rich-text/MsRichText.vue';
|
||||
import MsTab from '@/components/pure/ms-tab/index.vue';
|
||||
import BugTable from './component/bugTable.vue';
|
||||
import FeatureCaseTable from './component/featureCaseTable.vue';
|
||||
|
||||
import { editorUploadFile } from '@/api/modules/case-management/featureCase';
|
||||
import { PreviewEditorImageUrl } from '@/api/requrls/case-management/featureCase';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
|
||||
const reportId = ref(route.query.id as string);
|
||||
const activeTab = ref('bug');
|
||||
const contentTabList = ref([
|
||||
{
|
||||
value: 'bug',
|
||||
label: t('report.detail.bugDetails'),
|
||||
},
|
||||
{
|
||||
value: 'featureCase',
|
||||
label: t('report.detail.featureCaseDetails'),
|
||||
},
|
||||
]);
|
||||
|
||||
// TODO 暂时
|
||||
const richText = ref({
|
||||
summary: '',
|
||||
richTextTmpFileIds: [],
|
||||
});
|
||||
async function handleUploadImage(file: File) {
|
||||
const { data } = await editorUploadFile({
|
||||
fileList: [file],
|
||||
});
|
||||
return data;
|
||||
}
|
||||
function handleUpdateReportDetail() {
|
||||
// TODO: 更新
|
||||
}
|
||||
function handleCancel() {
|
||||
// TODO: 取消 数据还原
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
|
@ -33,4 +33,7 @@ export default {
|
|||
'report.passRate': 'Pass rate',
|
||||
'report.completed': 'Completed',
|
||||
'report.passRateTip': 'Pass rate: successful cases in the plan / cases in the plan * 100%',
|
||||
'report.detail.reportSummary': 'Report summary',
|
||||
'report.detail.bugDetails': 'Bug details',
|
||||
'report.detail.featureCaseDetails': 'Feature case details',
|
||||
};
|
||||
|
|
|
@ -33,4 +33,7 @@ export default {
|
|||
'report.passRate': '通过率',
|
||||
'report.passRateTip': '通过率:执行成功的用例/计划内用例 * 100%',
|
||||
'report.completed': '已完成',
|
||||
'report.detail.reportSummary': '报告总结',
|
||||
'report.detail.bugDetails': '缺陷明细',
|
||||
'report.detail.featureCaseDetails': '功能用例明细',
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue