fix(用例管理): 修改用例bug

This commit is contained in:
xinxin.wu 2024-02-29 12:59:14 +08:00 committed by 刘瑞斌
parent f17dd9a6bf
commit 367ab71336
12 changed files with 139 additions and 77 deletions

View File

@ -513,6 +513,7 @@
@apply relative overflow-hidden; @apply relative overflow-hidden;
:deep(.halo-rich-text-editor .ProseMirror) { :deep(.halo-rich-text-editor .ProseMirror) {
padding: 16px 24px !important; padding: 16px 24px !important;
height: 130px;
p:first-child { p:first-child {
margin-top: 0; margin-top: 0;
} }

View File

@ -119,7 +119,16 @@ const useFeatureCaseStore = defineStore('featureCase', {
async getCaseCounts(caseId: string) { async getCaseCounts(caseId: string) {
try { try {
const result = await getCaseDetail(caseId); const result = await getCaseDetail(caseId);
const { bugCount, caseCount, caseReviewCount, demandCount, relateEdgeCount, testPlanCount } = result; const {
bugCount,
caseCount,
caseReviewCount,
demandCount,
relateEdgeCount,
testPlanCount,
historyCount,
commentCount,
} = result;
const countMap: Record<string, any> = { const countMap: Record<string, any> = {
case: caseCount, case: caseCount,
dependency: relateEdgeCount, dependency: relateEdgeCount,
@ -127,6 +136,8 @@ const useFeatureCaseStore = defineStore('featureCase', {
testPlan: testPlanCount, testPlan: testPlanCount,
bug: bugCount, bug: bugCount,
requirement: demandCount, requirement: demandCount,
changeHistory: historyCount,
comments: commentCount,
}; };
this.initCountMap(countMap); this.initCountMap(countMap);
} catch (error) { } catch (error) {

View File

@ -247,7 +247,6 @@
async function getEnabledModules() { async function getEnabledModules() {
const result = await postTabletList({ projectId: currentProjectId.value }); const result = await postTabletList({ projectId: currentProjectId.value });
debugger;
const caseArr = result.filter((item) => Object.keys(moduleMaps).includes(item.module)); const caseArr = result.filter((item) => Object.keys(moduleMaps).includes(item.module));
caseArr.forEach((item: any) => { caseArr.forEach((item: any) => {
const currentModule = moduleMaps[item.module]; const currentModule = moduleMaps[item.module];

View File

@ -92,7 +92,7 @@
height: 'calc(100% - 86px)', height: 'calc(100% - 86px)',
}" }"
> >
<MsSplitBox :size="800" :max="0.7" :min="0.5" direction="horizontal" expand-direction="right"> <MsSplitBox :size="900" :max="0.7" :min="0.5" direction="horizontal" expand-direction="right">
<template #first> <template #first>
<div class="leftWrapper h-full"> <div class="leftWrapper h-full">
<div class="header h-[50px]"> <div class="header h-[50px]">

View File

@ -58,7 +58,7 @@
<span class="text-[var(--color-text-2)]"> <caseLevel :case-level="record.caseLevel" /></span> <span class="text-[var(--color-text-2)]"> <caseLevel :case-level="record.caseLevel" /></span>
</template> </template>
<a-option v-for="item of caseLevelList" :key="item.value" :value="item.value"> <a-option v-for="item of caseLevelList" :key="item.value" :value="item.value">
<caseLevel :case-level="item.value" /> <caseLevel :case-level="item.text" />
</a-option> </a-option>
</a-select> </a-select>
</template> </template>
@ -307,6 +307,7 @@
v-model:visible="showThirdDrawer" v-model:visible="showThirdDrawer"
:case-id="caseId" :case-id="caseId"
:drawer-loading="drawerLoading" :drawer-loading="drawerLoading"
:platform-info="platformInfo"
@save="saveThirdDemand" @save="saveThirdDemand"
/> />
</template> </template>
@ -351,6 +352,7 @@
getCustomFieldsTable, getCustomFieldsTable,
updateCaseRequest, updateCaseRequest,
} from '@/api/modules/case-management/featureCase'; } from '@/api/modules/case-management/featureCase';
import { getCaseRelatedInfo } from '@/api/modules/project-management/menuManagement';
import { getProjectOptions } from '@/api/modules/project-management/projectMember'; import { getProjectOptions } from '@/api/modules/project-management/projectMember';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import useModal from '@/hooks/useModal'; import useModal from '@/hooks/useModal';
@ -610,7 +612,7 @@
width: hasOperationPermission.value ? 260 : 50, width: hasOperationPermission.value ? 260 : 50,
}, },
]; ];
const platformInfo = ref<Record<string, any>>({});
const tableBatchActions = { const tableBatchActions = {
baseAction: [ baseAction: [
// { // {
@ -803,7 +805,6 @@
} }
} }
const initDefaultFields = ref<CustomAttributes[]>([]); const initDefaultFields = ref<CustomAttributes[]>([]);
let fullColumns: MsTableColumn = []; //
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector, setKeyword, setAdvanceFilter } = useTable( const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector, setKeyword, setAdvanceFilter } = useTable(
getCaseList, getCaseList,
@ -1197,6 +1198,7 @@
let customFieldsColumns: Record<string, any>[] = []; let customFieldsColumns: Record<string, any>[] = [];
const tableRef = ref<InstanceType<typeof MsBaseTable> | null>(null); const tableRef = ref<InstanceType<typeof MsBaseTable> | null>(null);
let fullColumns: MsTableColumn = [];
// //
async function getDefaultFields() { async function getDefaultFields() {
customFieldsColumns = []; customFieldsColumns = [];
@ -1449,17 +1451,29 @@
async function saveThirdDemand(params: CreateOrUpdateDemand) { async function saveThirdDemand(params: CreateOrUpdateDemand) {
try { try {
drawerLoading.value = true; drawerLoading.value = true;
const { demandPlatform, demandList } = params; const { demandPlatform, demandList, functionalDemandBatchRequest } = params;
const batchAddParams: CreateOrUpdateDemand = { const batchAddParams: CreateOrUpdateDemand = {
selectIds: batchParams.value?.selectAll ? [] : batchParams.value.selectedIds, selectIds: batchParams.value?.selectAll ? [] : batchParams.value.selectedIds,
selectAll: !!batchParams.value?.selectAll, selectAll: !!batchParams.value?.selectAll,
excludeIds: batchParams.value?.excludeIds || [], excludeIds: batchParams.value?.excludeIds || [],
condition: { keyword: keyword.value },
projectId: currentProjectId.value, projectId: currentProjectId.value,
moduleIds: props.activeFolder === 'all' ? [] : [props.activeFolder, ...props.offspringIds], moduleIds: props.activeFolder === 'all' ? [] : [props.activeFolder, ...props.offspringIds],
moduleId: selectedModuleKeys.value[0], moduleId: selectedModuleKeys.value[0],
demandPlatform, demandPlatform,
demandList, demandList,
filter: {
reviewStatus: statusFilters.value,
caseLevel: caseFilters.value,
lastExecuteResult: executeResultFilters.value,
updateUserName: updateUserFilters.value,
createUserName: createUserFilters.value,
},
condition: {
keyword: keyword.value,
filter: propsRes.value.filter,
combine: batchParams.value.condition,
},
functionalDemandBatchRequest,
}; };
await batchAssociationDemand(batchAddParams); await batchAssociationDemand(batchAddParams);
Message.success(t('caseManagement.featureCase.associatedSuccess')); Message.success(t('caseManagement.featureCase.associatedSuccess'));
@ -1481,11 +1495,29 @@
} }
} }
//
onBeforeMount(async () => {
try {
const result = await getCaseRelatedInfo(currentProjectId.value);
if (result && result.platform_key) {
platformInfo.value = { ...result };
}
if (Object.keys(result).length === 0) {
tableBatchActions.moreAction = [
...tableBatchActions.moreAction.slice(0, 1),
...tableBatchActions.moreAction.slice(-2),
];
}
} catch (error) {
console.log(error);
}
});
onMounted(async () => { onMounted(async () => {
if (route.query.id) { if (route.query.id) {
showCaseDetail(route.query.id as string, 0); showCaseDetail(route.query.id as string, 0);
} }
await getDefaultFields();
await initFilter(); await initFilter();
initData(); initData();
}); });
@ -1507,6 +1539,7 @@
} }
} }
); );
await getDefaultFields();
</script> </script>
<style scoped lang="less"> <style scoped lang="less">

View File

@ -755,8 +755,9 @@
return data; return data;
} }
function resetForm() { async function resetForm() {
form.value = { ...initForm, templateId: form.value.templateId }; form.value = { ...initForm, templateId: form.value.templateId };
await initDefaultFields();
form.value.customFields = formItem.value.map((item: any) => { form.value.customFields = formItem.value.map((item: any) => {
return { return {
fieldId: item.field, fieldId: item.field,

View File

@ -41,7 +41,9 @@
<div class="ml-2"> {{ item.name }} </div> <div class="ml-2"> {{ item.name }} </div>
</div> </div>
<a-button type="outline"> {{ t('caseManagement.featureCase.addContinueCreate') }} </a-button> <a-button type="outline" @click="goNavigation(item.route)">
{{ t('caseManagement.featureCase.addContinueCreate') }}
</a-button>
</div> </div>
</div> </div>
</template> </template>
@ -61,7 +63,7 @@
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import useVisit from '@/hooks/useVisit'; import useVisit from '@/hooks/useVisit';
import { CaseManagementRouteEnum } from '@/enums/routeEnum'; import { RouteEnum } from '@/enums/routeEnum';
const { t } = useI18n(); const { t } = useI18n();
@ -71,13 +73,14 @@
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const cardList = ref([ const cardList = ref([
{ // {
key: 'testPlanTemplate', // key: 'testPlanTemplate',
name: t('caseManagement.featureCase.createTestPlan'), // name: t('caseManagement.featureCase.createTestPlan'),
}, // },
{ {
key: 'caseReview', key: 'caseReview',
name: t('caseManagement.featureCase.createCaseReview'), name: t('caseManagement.featureCase.createCaseReview'),
route: RouteEnum.CASE_MANAGEMENT_REVIEW_CREATE,
}, },
]); ]);
@ -91,7 +94,7 @@
} else { } else {
clearInterval(timer.value); clearInterval(timer.value);
router.push({ router.push({
name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE, name: RouteEnum.CASE_MANAGEMENT_CASE,
}); });
} }
}, 1000); }, 1000);
@ -108,7 +111,7 @@
clearInterval(timer.value); clearInterval(timer.value);
timer.value = null; timer.value = null;
router.push({ router.push({
name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE, name: RouteEnum.CASE_MANAGEMENT_CASE,
}); });
} }
@ -117,18 +120,24 @@
clearInterval(timer.value); clearInterval(timer.value);
timer.value = null; timer.value = null;
router.push({ router.push({
name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE_DETAIL, name: RouteEnum.CASE_MANAGEMENT_CASE_DETAIL,
}); });
} }
function goDetail() { function goDetail() {
clearInterval(timer.value); clearInterval(timer.value);
router.push({ router.push({
name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE, name: RouteEnum.CASE_MANAGEMENT_CASE,
query: route.query, query: route.query,
}); });
} }
function goNavigation(name: string) {
router.push({
name,
});
}
watch( watch(
() => isNextTip.value, () => isNextTip.value,
() => { () => {

View File

@ -63,14 +63,14 @@
<template #second> <template #second>
<div class="p-[24px]"> <div class="p-[24px]">
<MsAdvanceFilter <MsAdvanceFilter
v-model:keyword="keyword"
:filter-config-list="filterConfigList" :filter-config-list="filterConfigList"
:custom-fields-config-list="searchCustomFields" :custom-fields-config-list="searchCustomFields"
:row-count="filterRowCount" :row-count="filterRowCount"
:search-placeholder="t('caseManagement.featureCase.searchPlaceholder')"
@keyword-search="fetchData" @keyword-search="fetchData"
@adv-search="handleAdvSearch" @adv-search="handleAdvSearch"
@refresh="fetchData()" @refresh="fetchData()"
v-model:keyword="keyword"
:search-placeholder="t('caseManagement.featureCase.searchPlaceholder')"
> >
<template #left> <template #left>
<div class="text-[var(--color-text-1)]" <div class="text-[var(--color-text-1)]"
@ -150,11 +150,11 @@
</template> </template>
<template #deleteUserFilter="{ columnConfig }"> <template #deleteUserFilter="{ columnConfig }">
<TableFilter <TableFilter
v-model:visible="deleteUserFilterVisible" v-model:visible="deleteUserFilterVisible"
v-model:status-filters="deleteUserFilters" v-model:status-filters="deleteUserFilters"
:title="(columnConfig.title as string)" :title="(columnConfig.title as string)"
:list="memberOptions" :list="memberOptions"
@search="initRecycleList()" @search="initRecycleList()"
> >
<template #item="{ item }"> <template #item="{ item }">
{{ item.label }} {{ item.label }}
@ -669,7 +669,7 @@
lastExecuteResult: executeResultFilters.value, lastExecuteResult: executeResultFilters.value,
updateUserName: updateUserFilters.value, updateUserName: updateUserFilters.value,
createUserName: createUserFilters.value, createUserName: createUserFilters.value,
deleteUserName: deleteUserFilters.value deleteUserName: deleteUserFilters.value,
}, },
condition: { condition: {
keyword: keyword.value, keyword: keyword.value,

View File

@ -107,23 +107,19 @@
} }
} }
function setCount(list: CommentItem[]) {
featureCaseStore.setListCount(featureCaseStore.activeTab, list.length);
}
async function getAllCommentList() { async function getAllCommentList() {
switch (activeComment.value) { switch (activeComment.value) {
case 'caseComment': case 'caseComment':
await initCommentList(); await initCommentList();
setCount(commentList.value); featureCaseStore.getCaseCounts(props.caseId);
break; break;
case 'reviewComment': case 'reviewComment':
await initReviewCommentList(); await initReviewCommentList();
setCount(reviewCommentList.value); featureCaseStore.getCaseCounts(props.caseId);
break; break;
case 'executiveComment': case 'executiveComment':
await initCommentList(); await initCommentList();
setCount(commentList.value); featureCaseStore.getCaseCounts(props.caseId);
break; break;
default: default:
break; break;

View File

@ -17,6 +17,10 @@
<template v-if="(props.funParams.keyword || '').trim() === '' && props.showEmpty" #empty> <template v-if="(props.funParams.keyword || '').trim() === '' && props.showEmpty" #empty>
<div class="flex w-full items-center justify-center"> <div class="flex w-full items-center justify-center">
{{ t('caseManagement.caseReview.tableNoData') }} {{ t('caseManagement.caseReview.tableNoData') }}
<MsButton class="ml-[8px]" @click="emit('associate')">
{{ t('caseManagement.featureCase.associatedDemand') }}
</MsButton>
{{ t('caseManagement.featureCase.or') }}
<MsButton class="ml-[8px]" @click="emit('create')"> <MsButton class="ml-[8px]" @click="emit('create')">
{{ t('caseManagement.featureCase.addDemand') }} {{ t('caseManagement.featureCase.addDemand') }}
</MsButton> </MsButton>
@ -65,6 +69,7 @@
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'update', record: DemandItem): void; (e: 'update', record: DemandItem): void;
(e: 'create'): void; (e: 'create'): void;
(e: 'associate'): void;
(e: 'cancel', record: DemandItem): void; (e: 'cancel', record: DemandItem): void;
}>(); }>();

View File

@ -2,7 +2,7 @@
<div> <div>
<div class="mb-4 flex items-center justify-between"> <div class="mb-4 flex items-center justify-between">
<div> <div>
<a-button type="primary" @click="associatedDemand"> <a-button v-if="platformInfo.platform_key" type="primary" @click="associatedDemand">
{{ t('caseManagement.featureCase.associatedDemand') }}</a-button {{ t('caseManagement.featureCase.associatedDemand') }}</a-button
> >
<a-button class="mx-3" type="outline" @click="addDemand"> <a-button class="mx-3" type="outline" @click="addDemand">
@ -22,9 +22,11 @@
<AssociatedDemandTable <AssociatedDemandTable
ref="demandRef" ref="demandRef"
:fun-params="{ caseId: props.caseId, keyword, projectId: currentProjectId }" :fun-params="{ caseId: props.caseId, keyword, projectId: currentProjectId }"
:show-empty="true"
@update="updateDemand" @update="updateDemand"
@create="addDemand" @create="addDemand"
@cancel="cancelLink" @cancel="cancelLink"
@associate="linkDemandDrawer = true"
></AssociatedDemandTable> ></AssociatedDemandTable>
<AddDemandModal <AddDemandModal
ref="demandModalRef" ref="demandModalRef"
@ -174,7 +176,7 @@
// ellipsis: true, // ellipsis: true,
// }, // },
]; ];
const fullColumns = ref<MsTableColumn>([]); const fullColumns = ref<MsTableColumn>([...columns]);
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(getThirdDemandList, { const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(getThirdDemandList, {
tableKey: TableKeyEnum.CASE_MANAGEMENT_TAB_DEMAND_PLATFORM, tableKey: TableKeyEnum.CASE_MANAGEMENT_TAB_DEMAND_PLATFORM,
@ -228,6 +230,7 @@
const tableRef = ref(); const tableRef = ref();
const customFields = ref<any[]>([]); const customFields = ref<any[]>([]);
async function initColumn() { async function initColumn() {
fullColumns.value = [...columns];
try { try {
const res = await getThirdDemandList({ const res = await getThirdDemandList({
current: 1, current: 1,
@ -244,9 +247,7 @@
}; };
}) as any; }) as any;
fullColumns.value = [...columns, ...customFields.value]; fullColumns.value = [...columns, ...customFields.value];
tableRef.value.initColumn(fullColumns.value);
} catch (error) { } catch (error) {
tableRef.value.initColumn(columns);
console.log(error); console.log(error);
} }
} }
@ -324,12 +325,8 @@
async (val) => { async (val) => {
if (val) { if (val) {
resetSelector(); resetSelector();
await initColumn();
initData(); initData();
} }
},
{
immediate: true,
} }
); );
@ -362,12 +359,13 @@
showAddModel.value = true; showAddModel.value = true;
modelForm.value = { ...initModelForm }; modelForm.value = { ...initModelForm };
} }
// const activeTab = computed(() => featureCaseStore.activeTab);
onMounted(async () => { onMounted(async () => {
try { try {
const result = await getCaseRelatedInfo(currentProjectId.value); const result = await getCaseRelatedInfo(currentProjectId.value);
if (result && result.platform_key) { if (result && result.platform_key) {
platformInfo.value = { ...result }; platformInfo.value = { ...result };
initColumn();
} }
} catch (error) { } catch (error) {
console.log(error); console.log(error);

View File

@ -52,7 +52,6 @@
import useTable from '@/components/pure/ms-table/useTable'; import useTable from '@/components/pure/ms-table/useTable';
import { getThirdDemandList } from '@/api/modules/case-management/featureCase'; import { getThirdDemandList } from '@/api/modules/case-management/featureCase';
import { getCaseRelatedInfo } from '@/api/modules/project-management/menuManagement';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { useAppStore } from '@/store'; import { useAppStore } from '@/store';
@ -66,6 +65,7 @@
visible: boolean; visible: boolean;
caseId: string; caseId: string;
drawerLoading: boolean; drawerLoading: boolean;
platformInfo: Record<string, any>;
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{
@ -107,7 +107,7 @@
// }, // },
]; ];
const fullColumns = ref<MsTableColumn>([]); const fullColumns = ref<MsTableColumn>([...columns]);
const customFields = ref<Record<string, any>[]>([]); const customFields = ref<Record<string, any>[]>([]);
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(getThirdDemandList, { const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(getThirdDemandList, {
@ -138,11 +138,13 @@
return filteredData; return filteredData;
}); });
const platformInfo = ref<Record<string, any>>({}); // const platformInfo = ref<Record<string, any>>({});
function getPlatName() { function getPlatName() {
switch (platformInfo.value.platform_key) { switch (props.platformInfo.platform_key) {
case 'zentao': case 'zentao':
return t('caseManagement.featureCase.zentao'); return t('caseManagement.featureCase.zentao');
case 'jira':
return t('caseManagement.featureCase.jira');
default: default:
break; break;
} }
@ -159,10 +161,15 @@
}); });
const params = { const params = {
id: JSON.parse(platformInfo.value.demand_platform_config).zentaoId, id: JSON.parse(props.platformInfo.demand_platform_config).zentaoId,
caseId: props.caseId, caseId: props.caseId,
demandPlatform: platformInfo.value.platform_key, demandPlatform: props.platformInfo.platform_key,
demandList, demandList: propsRes.value.selectorStatus === 'all' ? [] : demandList,
functionalDemandBatchRequest: {
keyword: platformKeyword.value,
excludeIds: [...propsRes.value.excludeKeys],
selectAll: propsRes.value.selectorStatus === 'all',
},
}; };
emit('save', params); emit('save', params);
} }
@ -198,50 +205,52 @@
const tableRef = ref(); const tableRef = ref();
async function initColumn() { async function initColumn() {
fullColumns.value = [...columns];
try { try {
const res = await getThirdDemandList({ const res = await getThirdDemandList({
current: 1, current: 1,
pageSize: 10, pageSize: 10,
projectId: currentProjectId.value, projectId: currentProjectId.value,
}); });
customFields.value = (res.data.customHeaders || []).map((item: any) => { if (res.data.customHeaders.length) {
return { customFields.value = (res.data.customHeaders || []).map((item: any) => {
title: item.name, return {
slotName: item.id, title: item.name,
dataIndex: item.id, slotName: item.id,
width: 200, dataIndex: item.id,
options: item.options, width: 200,
}; options: item.options,
}) as any; };
fullColumns.value = [...columns, ...customFields.value]; }) as any;
}
fullColumns.value.push(...customFields.value);
} catch (error) { } catch (error) {
tableRef.value.initColumn(columns);
console.log(error); console.log(error);
} }
} }
onBeforeMount(async () => { // onBeforeMount(async () => {
try { // try {
const result = await getCaseRelatedInfo(currentProjectId.value); // const result = await getCaseRelatedInfo(currentProjectId.value);
if (result && result.platform_key) { // if (result && result.platform_key) {
platformInfo.value = { ...result }; // platformInfo.value = { ...result };
} // initColumn();
} catch (error) { // }
console.log(error); // } catch (error) {
} // console.log(error);
}); // }
// });
watch( watch(
() => innerLinkDemandVisible.value, () => innerLinkDemandVisible.value,
async (val) => { async (val) => {
if (val) { if (val) {
resetSelector(); resetSelector();
await initColumn(); if (props.platformInfo.demand_platform_config) {
initData(); initData();
}
} }
},
{
immediate: true,
} }
); );
</script> </script>