feat(测试计划): 测试计划详情-修改功能用例步骤执行结果
This commit is contained in:
parent
f24b54c9e9
commit
7db01bf024
|
@ -86,8 +86,12 @@ export interface StepList {
|
|||
expected: string; // 预期
|
||||
showStep: boolean; // 编辑步骤模式
|
||||
showExpected: boolean; // 编辑预期模式
|
||||
actualResult?: string; // 实际
|
||||
executeResult?: string; // 步骤执行结果
|
||||
}
|
||||
|
||||
export type StepExecutionResult = Pick<StepList, 'actualResult' | 'executeResult'>;
|
||||
|
||||
// 关联文件列表
|
||||
export interface AssociatedList {
|
||||
id: string;
|
||||
|
|
|
@ -28,8 +28,31 @@
|
|||
@blur="blurHandler(record, 'expected')"
|
||||
/>
|
||||
</template>
|
||||
<template #actualResult="{ record }">
|
||||
<a-textarea
|
||||
v-model="record.actualResult"
|
||||
:max-length="1000"
|
||||
size="mini"
|
||||
:auto-size="true"
|
||||
class="w-max-[267px] param-input"
|
||||
:placeholder="t('system.orgTemplate.actualResultTip')"
|
||||
/>
|
||||
</template>
|
||||
<template #lastExecResult="{ record }">
|
||||
<ExecuteResult :execute-result="record.executeResult" />
|
||||
<a-select
|
||||
v-if="hasAnyPermission(['PROJECT_TEST_PLAN:READ+EXECUTE'])"
|
||||
v-model:model-value="record.executeResult"
|
||||
:placeholder="t('common.pleaseSelect')"
|
||||
class="param-input w-full"
|
||||
>
|
||||
<template #label>
|
||||
<span class="text-[var(--color-text-2)]"><ExecuteResult :execute-result="record.executeResult" /></span>
|
||||
</template>
|
||||
<a-option v-for="item in executionResultList" :key="item.key" :value="item.key">
|
||||
<ExecuteResult :execute-result="item.key" />
|
||||
</a-option>
|
||||
</a-select>
|
||||
<span v-else class="text-[var(--color-text-2)]"><ExecuteResult :execute-result="record.executeResult" /></span>
|
||||
</template>
|
||||
<template #operation="{ record }">
|
||||
<MsTableMoreAction
|
||||
|
@ -60,10 +83,14 @@
|
|||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { getGenerateId } from '@/utils';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import type { StepList } from '@/models/caseManagement/featureCase';
|
||||
import { LastExecuteResults } from '@/enums/caseEnum';
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
|
||||
import { executionResultMap } from '@/views/case-management/caseManagementFeature/components/utils';
|
||||
|
||||
type refItem = Element | ComponentPublicInstance | null;
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@ -82,6 +109,10 @@
|
|||
|
||||
const emit = defineEmits(['update:stepList']);
|
||||
|
||||
const executionResultList = computed(() =>
|
||||
Object.values(executionResultMap).filter((item) => item.key !== LastExecuteResults.UN_EXECUTED)
|
||||
);
|
||||
|
||||
// 步骤描述
|
||||
const stepData = ref<StepList[]>([
|
||||
{
|
||||
|
|
|
@ -745,6 +745,7 @@
|
|||
defineExpose({
|
||||
handleOK,
|
||||
getParams,
|
||||
stepData,
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -103,6 +103,7 @@ export default {
|
|||
'system.orgTemplate.textDescription': 'Text description',
|
||||
'system.orgTemplate.stepTip': 'Please enter steps',
|
||||
'system.orgTemplate.expectationTip': 'Please enter expectations',
|
||||
'system.orgTemplate.actualResultTip': 'Please enter actuality',
|
||||
'system.orgTemplate.addAttachment': 'Add attachment',
|
||||
'system.orgTemplate.addAttachmentTip': 'Support any type of file, the file size does not exceed 50MB',
|
||||
'system.orgTemplate.enabledSuccessfully': 'Enabled successfully',
|
||||
|
|
|
@ -102,6 +102,7 @@ export default {
|
|||
'system.orgTemplate.textDescription': '文本描述',
|
||||
'system.orgTemplate.stepTip': '请输入步骤',
|
||||
'system.orgTemplate.expectationTip': '请输入预期',
|
||||
'system.orgTemplate.actualResultTip': '请输入实际',
|
||||
'system.orgTemplate.addAttachment': '添加附件',
|
||||
'system.orgTemplate.addAttachmentTip': '支持任意类型文件,文件大小不超过 50MB',
|
||||
'system.orgTemplate.enabledSuccessfully': '启用成功',
|
||||
|
|
|
@ -103,6 +103,7 @@
|
|||
|
||||
import { ModuleTreeNode } from '@/models/common';
|
||||
import type { PlanDetailFeatureCaseItem, PlanDetailFeatureCaseListQueryParams } from '@/models/testPlan/testPlan';
|
||||
import { LastExecuteResults } from '@/enums/caseEnum';
|
||||
import { TestPlanRouteEnum } from '@/enums/routeEnum';
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
|
||||
|
@ -217,6 +218,7 @@
|
|||
{
|
||||
title: 'testPlan.featureCase.executor',
|
||||
dataIndex: 'executeUserName',
|
||||
showTooltip: true,
|
||||
width: 150,
|
||||
showDrag: true,
|
||||
},
|
||||
|
@ -243,6 +245,7 @@
|
|||
(record) => {
|
||||
return {
|
||||
...record,
|
||||
lastExecResult: record.lastExecResult ?? LastExecuteResults.UN_EXECUTED,
|
||||
caseLevel: getCaseLevels(record.customFields),
|
||||
moduleId: getModules(record.moduleId, props.moduleTree),
|
||||
};
|
||||
|
|
|
@ -33,17 +33,18 @@
|
|||
import { defaultExecuteForm } from '@/config/testPlan';
|
||||
|
||||
import type { ExecuteFeatureCaseFormParams } from '@/models/testPlan/testPlan';
|
||||
import { LastExecuteResults } from '@/enums/caseEnum';
|
||||
|
||||
import { executionResultMap } from '@/views/case-management/caseManagementFeature/components/utils';
|
||||
|
||||
const form = defineModel<ExecuteFeatureCaseFormParams>('form', {
|
||||
required: true,
|
||||
default: () => ({ ...defaultExecuteForm }),
|
||||
});
|
||||
|
||||
const formRef = ref<FormInstance>();
|
||||
|
||||
const executionResultList = computed(() =>
|
||||
Object.values(executionResultMap).filter((item) => item.key !== 'UN_EXECUTED')
|
||||
Object.values(executionResultMap).filter((item) => item.key !== LastExecuteResults.UN_EXECUTED)
|
||||
);
|
||||
|
||||
async function handleUploadImage(file: File) {
|
||||
|
|
|
@ -38,12 +38,15 @@
|
|||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
|
||||
import type { StepExecutionResult } from '@/models/caseManagement/featureCase';
|
||||
import type { ExecuteFeatureCaseFormParams } from '@/models/testPlan/testPlan';
|
||||
import { LastExecuteResults } from '@/enums/caseEnum';
|
||||
|
||||
const props = defineProps<{
|
||||
caseId: string;
|
||||
testPlanId: string;
|
||||
id: string;
|
||||
stepExecutionResult?: StepExecutionResult[];
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
@ -63,6 +66,21 @@
|
|||
(form.value.content === '' || form.value.content?.trim() === '<p style=""></p>')
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.stepExecutionResult,
|
||||
() => {
|
||||
const executionResultList = props.stepExecutionResult?.map((item) => item.executeResult);
|
||||
if (executionResultList?.includes(LastExecuteResults.FAILED)) {
|
||||
form.value.lastExecResult = LastExecuteResults.FAILED;
|
||||
} else if (executionResultList?.includes(LastExecuteResults.BLOCKED)) {
|
||||
form.value.lastExecResult = LastExecuteResults.BLOCKED;
|
||||
} else {
|
||||
form.value.lastExecResult = LastExecuteResults.PASSED;
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
// 提交执行
|
||||
async function submit() {
|
||||
try {
|
||||
|
@ -73,6 +91,7 @@
|
|||
testPlanId: props.testPlanId,
|
||||
id: props.id,
|
||||
lastExecResult: form.value.lastExecResult,
|
||||
stepsExecResult: JSON.stringify(props.stepExecutionResult) ?? '',
|
||||
content: form.value.content,
|
||||
notifier: form.value?.commentIds?.join(';'),
|
||||
};
|
||||
|
|
|
@ -32,12 +32,12 @@
|
|||
<div
|
||||
v-for="item of caseList"
|
||||
:key="item.id"
|
||||
:class="['case-item', caseDetail.id === item.caseId ? 'case-item--active' : '']"
|
||||
:class="['case-item', activeId === item.id ? 'case-item--active' : '']"
|
||||
@click="changeActiveCase(item)"
|
||||
>
|
||||
<div class="mb-[8px] flex items-center justify-between">
|
||||
<div class="text-[var(--color-text-4)]">{{ item.num }}</div>
|
||||
<ExecuteResult :execute-result="item.lastExecResult" />
|
||||
<ExecuteResult :execute-result="item.lastExecResult ?? LastExecuteResults.UN_EXECUTED" />
|
||||
</div>
|
||||
<a-tooltip :content="item.name">
|
||||
<div class="one-line-text">{{ item.name }}</div>
|
||||
|
@ -88,7 +88,7 @@
|
|||
<!-- TODO: 属性的样式 -->
|
||||
<MsDescription v-if="activeTab === 'baseInfo'" :descriptions="descriptions" :column="2" />
|
||||
<div v-else-if="activeTab === 'detail'" class="align-content-start flex h-full flex-col">
|
||||
<CaseTabDetail is-test-plan :form="caseDetail" />
|
||||
<CaseTabDetail ref="caseTabDetailRef" is-test-plan :form="caseDetail" />
|
||||
<!-- 开始执行 -->
|
||||
<div class="px-[16px] py-[8px] shadow-[0_-1px_4px_rgba(2,2,2,0.1)]">
|
||||
<div class="mb-[12px] flex items-center justify-between">
|
||||
|
@ -115,6 +115,7 @@
|
|||
:id="activeId"
|
||||
:case-id="activeCaseId"
|
||||
:test-plan-id="route.query.id as string"
|
||||
:step-execution-result="stepExecutionResult"
|
||||
@done="executeDone"
|
||||
/>
|
||||
</div>
|
||||
|
@ -153,6 +154,7 @@
|
|||
import useAppStore from '@/store/modules/app';
|
||||
|
||||
import type { PlanDetailFeatureCaseItem, TestPlanDetail } from '@/models/testPlan/testPlan';
|
||||
import { LastExecuteResults } from '@/enums/caseEnum';
|
||||
import { CaseManagementRouteEnum } from '@/enums/routeEnum';
|
||||
|
||||
import { executionResultMap, getCustomField } from '@/views/case-management/caseManagementFeature/components/utils';
|
||||
|
@ -308,7 +310,7 @@
|
|||
}
|
||||
|
||||
function changeActiveCase(item: PlanDetailFeatureCaseItem) {
|
||||
if (activeCaseId.value !== item.caseId) {
|
||||
if (activeId.value !== item.id) {
|
||||
activeCaseId.value = item.caseId;
|
||||
activeId.value = item.id;
|
||||
}
|
||||
|
@ -317,6 +319,7 @@
|
|||
() => activeCaseId.value,
|
||||
() => {
|
||||
loadCaseDetail();
|
||||
// TODO 更新历史列表
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -325,11 +328,21 @@
|
|||
await loadCaseDetail();
|
||||
}
|
||||
|
||||
const caseTabDetailRef = ref<InstanceType<typeof CaseTabDetail>>();
|
||||
const stepExecutionResult = computed(() => {
|
||||
const stepData = caseTabDetailRef.value?.stepData;
|
||||
return stepData?.map((item) => {
|
||||
return {
|
||||
actualResult: item.actualResult,
|
||||
executeResult: item.executeResult,
|
||||
};
|
||||
});
|
||||
});
|
||||
const autoNext = ref(true);
|
||||
async function executeDone() {
|
||||
if (autoNext.value) {
|
||||
// 自动下一个,更改激活的 id会刷新详情
|
||||
const index = caseList.value.findIndex((e) => e.caseId === activeCaseId.value);
|
||||
const index = caseList.value.findIndex((e) => e.id === activeId.value);
|
||||
if (index < caseList.value.length - 1) {
|
||||
await loadCaseList();
|
||||
activeCaseId.value = caseList.value[index + 1].caseId;
|
||||
|
@ -344,10 +357,12 @@
|
|||
// 当前是最后一个,刷新数据
|
||||
loadCaseDetail();
|
||||
loadCaseList();
|
||||
// TODO 更新历史列表
|
||||
}
|
||||
} else {
|
||||
// 不自动下一个才请求详情
|
||||
loadCase();
|
||||
// TODO 更新历史列表
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue