feat(测试计划): 脑图执行用例-执行
This commit is contained in:
parent
46259da117
commit
b5a3592e46
|
@ -154,7 +154,7 @@
|
|||
|
||||
const emit = defineEmits<{
|
||||
(e: 'operation', type: string, node: MinderJsonNode): void;
|
||||
(e: 'handleReviewDone', refreshTree?: boolean): void;
|
||||
(e: 'handleReviewDone'): void;
|
||||
}>();
|
||||
|
||||
const route = useRoute();
|
||||
|
@ -484,10 +484,10 @@
|
|||
selectNode.value.data?.resource?.includes(caseTag)
|
||||
) {
|
||||
window.minder.execCommand('resource', [statusTagMap[status], caseTag]);
|
||||
emit('handleReviewDone');
|
||||
} else {
|
||||
emit('handleReviewDone', true);
|
||||
initCaseTree();
|
||||
}
|
||||
emit('handleReviewDone');
|
||||
}
|
||||
|
||||
// 递归更新子节点的用例标签
|
||||
|
|
|
@ -13,7 +13,7 @@ import { getGenerateId } from '@/utils';
|
|||
* 封装用例脑图基础功能,包含菜单显隐判断、节点插入、节点替换、节点拖拽等
|
||||
* @returns API 集合
|
||||
*/
|
||||
export default function useMinderBaseApi({ hasEditPermission }: { hasEditPermission: boolean }) {
|
||||
export default function useMinderBaseApi({ hasEditPermission }: { hasEditPermission?: boolean }) {
|
||||
const { t } = useI18n();
|
||||
const minderStore = useMinderStore();
|
||||
|
||||
|
|
|
@ -42,14 +42,33 @@
|
|||
</template>
|
||||
</a-dropdown>
|
||||
<!-- 执行 -->
|
||||
<a-trigger
|
||||
v-model:popup-visible="executeVisible"
|
||||
trigger="click"
|
||||
position="bl"
|
||||
:click-outside-to-close="false"
|
||||
popup-container=".ms-minder-container"
|
||||
>
|
||||
<a-tooltip
|
||||
v-if="props.canEdit && hasAnyPermission(['PROJECT_TEST_PLAN:READ+EXECUTE'])"
|
||||
:content="t('common.execute')"
|
||||
>
|
||||
<MsButton type="icon" class="ms-minder-node-float-menu-icon-button">
|
||||
<MsButton
|
||||
type="icon"
|
||||
:class="[
|
||||
'ms-minder-node-float-menu-icon-button',
|
||||
`${executeVisible ? 'ms-minder-node-float-menu-icon-button--focus' : ''}`,
|
||||
]"
|
||||
>
|
||||
<MsIcon type="icon-icon_play-round_filled" class="text-[var(--color-text-4)]" />
|
||||
</MsButton>
|
||||
</a-tooltip>
|
||||
<template #content>
|
||||
<div class="w-[440px] rounded bg-white p-[16px] shadow-[0_0_10px_rgba(0,0,0,0.05)]">
|
||||
<ExecuteSubmit :select-node="selectNode" :test-plan-id="props.planId" @done="handleExecuteDone" />
|
||||
</div>
|
||||
</template>
|
||||
</a-trigger>
|
||||
<!-- 查看详情 -->
|
||||
<a-tooltip v-if="canShowDetail" :content="t('common.detail')">
|
||||
<MsButton
|
||||
|
@ -113,6 +132,29 @@
|
|||
}"
|
||||
@success="handleAddBugDone"
|
||||
/>
|
||||
<a-modal
|
||||
v-model:visible="stepExecuteModelVisible"
|
||||
:title="t('common.executionResult')"
|
||||
class="p-[4px]"
|
||||
title-align="start"
|
||||
body-class="p-0"
|
||||
:width="800"
|
||||
:cancel-button-props="{ disabled: submitStepExecuteLoading }"
|
||||
:ok-loading="submitStepExecuteLoading"
|
||||
:ok-text="t('caseManagement.caseReview.commitResult')"
|
||||
@before-ok="submitStepExecute"
|
||||
@cancel="cancelStepExecute"
|
||||
>
|
||||
<AddStep
|
||||
v-model:step-list="stepData"
|
||||
is-scroll-y
|
||||
is-test-plan
|
||||
:scroll-y="190"
|
||||
:is-disabled-test-plan="false"
|
||||
is-disabled
|
||||
/>
|
||||
<ExecuteForm v-model:form="executeForm" class="mt-[24px]" rich-text-max-height="150px" />
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -134,21 +176,29 @@
|
|||
import { MsFileItem } from '@/components/pure/ms-upload/types';
|
||||
import Attachment from '@/components/business/ms-minders/featureCaseMinder/attachment.vue';
|
||||
import BugList from '@/components/business/ms-minders/featureCaseMinder/bugList.vue';
|
||||
import useMinderBaseApi from '@/components/business/ms-minders/featureCaseMinder/useMinderBaseApi';
|
||||
import AddStep from '@/views/case-management/caseManagementFeature/components/addStep.vue';
|
||||
import AddDefectDrawer from '@/views/case-management/caseManagementFeature/components/tabContent/tabBug/addDefectDrawer.vue';
|
||||
import LinkDefectDrawer from '@/views/case-management/caseManagementFeature/components/tabContent/tabBug/linkDefectDrawer.vue';
|
||||
import ReviewCommentList from '@/views/case-management/caseManagementFeature/components/tabContent/tabComment/reviewCommentList.vue';
|
||||
import ExecuteForm from '@/views/test-plan/testPlan/detail/featureCase/components/executeForm.vue';
|
||||
import ExecuteSubmit from '@/views/test-plan/testPlan/detail/featureCase/detail/executeSubmit.vue';
|
||||
|
||||
import { getCasePlanMinder } from '@/api/modules/case-management/caseReview';
|
||||
import { associateBugToPlan, executeHistory, getCaseDetail } from '@/api/modules/test-plan/testPlan';
|
||||
import { associateBugToPlan, executeHistory, getCaseDetail, runFeatureCase } from '@/api/modules/test-plan/testPlan';
|
||||
import { defaultExecuteForm } from '@/config/testPlan';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import useMinderStore from '@/store/modules/components/minder-editor/index';
|
||||
import useTestPlanFeatureCaseStore from '@/store/modules/testPlan/testPlanFeatureCase';
|
||||
import { findNodeByKey, mapTree, replaceNodeInTree } from '@/utils';
|
||||
import { findNodeByKey, getGenerateId, mapTree, replaceNodeInTree } from '@/utils';
|
||||
import { hasAllPermission, hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import type { StepList } from '@/models/caseManagement/featureCase';
|
||||
import type { TableQueryParams } from '@/models/common';
|
||||
import { ModuleTreeNode } from '@/models/common';
|
||||
import type { ExecuteHistoryItem } from '@/models/testPlan/testPlan';
|
||||
import type { ExecuteFeatureCaseFormParams, ExecuteHistoryItem } from '@/models/testPlan/testPlan';
|
||||
import { LastExecuteResults } from '@/enums/caseEnum';
|
||||
import { MinderEventName, MinderKeyEnum } from '@/enums/minderEnum';
|
||||
|
||||
import {
|
||||
|
@ -166,15 +216,16 @@
|
|||
|
||||
const emit = defineEmits<{
|
||||
(e: 'operation', type: string, node: MinderJsonNode): void;
|
||||
(e: 'handleAddBugDone'): void;
|
||||
(e: 'refreshPlan'): void;
|
||||
}>();
|
||||
|
||||
const { t } = useI18n();
|
||||
const appStore = useAppStore();
|
||||
const minderStore = useMinderStore();
|
||||
const testPlanFeatureCaseStore = useTestPlanFeatureCaseStore();
|
||||
|
||||
const caseTag = t('common.case');
|
||||
const moduleTag = t('common.module');
|
||||
const { caseTag, moduleTag, stepTag, stepExpectTag } = useMinderBaseApi({});
|
||||
const actualResultTag = t('system.orgTemplate.actualResult');
|
||||
const importJson = ref<MinderJson>({
|
||||
root: {} as MinderJsonNode,
|
||||
treePath: [],
|
||||
|
@ -455,6 +506,172 @@
|
|||
}
|
||||
}
|
||||
|
||||
const selectNode = ref();
|
||||
|
||||
// 添加缺陷
|
||||
const showLinkDefectDrawer = ref(false);
|
||||
const showAddDefectDrawer = ref(false);
|
||||
const linkDrawerLoading = ref(false);
|
||||
const bugListRef = ref<InstanceType<typeof BugList>>();
|
||||
function handleAddBugDone() {
|
||||
if (extraVisible.value && activeExtraKey.value === 'bug') {
|
||||
bugListRef.value?.handleShowTypeChange();
|
||||
}
|
||||
emit('refreshPlan');
|
||||
}
|
||||
async function associateSuccessHandler(params: TableQueryParams) {
|
||||
try {
|
||||
linkDrawerLoading.value = true;
|
||||
await associateBugToPlan({
|
||||
...params,
|
||||
testPlanCaseId: selectNode.value.data?.id,
|
||||
caseId: selectNode.value.data?.caseId,
|
||||
testPlanId: props.planId,
|
||||
});
|
||||
Message.success(t('caseManagement.featureCase.associatedSuccess'));
|
||||
linkDrawerLoading.value = false;
|
||||
handleAddBugDone();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
} finally {
|
||||
linkDrawerLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 执行
|
||||
const executeVisible = ref(false);
|
||||
// 新增或更新用例的实际结果节点
|
||||
function updateCaseActualResultNode(node: MinderJsonNode, content: string) {
|
||||
let actualResultNode;
|
||||
actualResultNode = node.children?.find((item: MinderJsonNode) => item.data?.id === `actualResult-${node.data?.id}`);
|
||||
if (actualResultNode) {
|
||||
actualResultNode
|
||||
.setData('resource', [actualResultTag])
|
||||
.setData('text', content ?? '')
|
||||
.render();
|
||||
} else {
|
||||
actualResultNode = createNode(
|
||||
{ resource: [actualResultTag], text: content ?? '', id: `actualResult-${node.data?.id}` },
|
||||
node
|
||||
);
|
||||
handleRenderNode(node, [actualResultNode]);
|
||||
}
|
||||
}
|
||||
// 点击模块/用例执行
|
||||
function handleExecuteDone(status: LastExecuteResults, content: string) {
|
||||
executeVisible.value = false;
|
||||
const resource = selectNode.value.data?.resource;
|
||||
if (resource?.includes(caseTag)) {
|
||||
// 用例添加标签
|
||||
window.minder.execCommand('resource', [executionResultMap[status].statusText, caseTag]);
|
||||
// 新增或更新用例的实际结果节点
|
||||
updateCaseActualResultNode(selectNode.value, content);
|
||||
// 更新执行历史
|
||||
if (extraVisible.value && activeExtraKey.value === 'history') {
|
||||
initExecuteHistory(selectNode.value.data);
|
||||
}
|
||||
} else if (resource?.includes(moduleTag)) {
|
||||
initCaseTree();
|
||||
}
|
||||
emit('refreshPlan');
|
||||
}
|
||||
|
||||
const stepExecuteModelVisible = ref(false);
|
||||
const caseNodeAboveSelectStep = ref(); // 选中的步骤节点对应的用例节点信息
|
||||
const submitStepExecuteLoading = ref(false);
|
||||
const executeForm = ref<ExecuteFeatureCaseFormParams>({ ...defaultExecuteForm });
|
||||
const stepData = ref<StepList[]>([
|
||||
{
|
||||
id: getGenerateId(),
|
||||
step: '',
|
||||
expected: '',
|
||||
showStep: false,
|
||||
showExpected: false,
|
||||
},
|
||||
]);
|
||||
async function getStepData(id: string) {
|
||||
try {
|
||||
const res = await getCaseDetail(id);
|
||||
if (res.steps) {
|
||||
stepData.value = JSON.parse(res.steps).map((item: any) => {
|
||||
return {
|
||||
id: item.id,
|
||||
step: item.desc,
|
||||
expected: item.result,
|
||||
actualResult: item.actualResult,
|
||||
executeResult: item.executeResult,
|
||||
};
|
||||
});
|
||||
} else {
|
||||
stepData.value = [];
|
||||
}
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
watch(
|
||||
() => stepData.value,
|
||||
() => {
|
||||
const executionResultList = stepData.value?.map((item) => item.executeResult);
|
||||
if (executionResultList?.includes(LastExecuteResults.ERROR)) {
|
||||
executeForm.value.lastExecResult = LastExecuteResults.ERROR;
|
||||
} else if (executionResultList?.includes(LastExecuteResults.BLOCKED)) {
|
||||
executeForm.value.lastExecResult = LastExecuteResults.BLOCKED;
|
||||
} else {
|
||||
executeForm.value.lastExecResult = LastExecuteResults.SUCCESS;
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
function cancelStepExecute() {
|
||||
executeForm.value = { ...defaultExecuteForm };
|
||||
}
|
||||
function submitStepExecuteDone(status: string, content: string) {
|
||||
// 用例更新标签
|
||||
caseNodeAboveSelectStep.value.setData('resource', [executionResultMap[status].statusText, caseTag]).render();
|
||||
// 新增或更新用例的实际结果节点
|
||||
updateCaseActualResultNode(caseNodeAboveSelectStep.value, content);
|
||||
// 更新步骤数据:标签和实际结果
|
||||
caseNodeAboveSelectStep.value.children.forEach((child: MinderJsonNode) => {
|
||||
const step = stepData.value.find((item) => item.id === child.data?.id);
|
||||
if (step?.executeResult?.length) {
|
||||
child.setData('resource', [executionResultMap[step?.executeResult].statusText, stepTag]).render();
|
||||
}
|
||||
if (step?.actualResult?.length) {
|
||||
child.children?.[0].children?.[0].setData('text', step?.actualResult).render();
|
||||
}
|
||||
});
|
||||
caseNodeAboveSelectStep.value.layout();
|
||||
}
|
||||
async function submitStepExecute() {
|
||||
try {
|
||||
submitStepExecuteLoading.value = true;
|
||||
const params = {
|
||||
projectId: appStore.currentProjectId,
|
||||
testPlanId: props.planId,
|
||||
caseId: caseNodeAboveSelectStep.value.data.caseId,
|
||||
id: caseNodeAboveSelectStep.value.data.id,
|
||||
...executeForm.value,
|
||||
notifier: executeForm.value?.commentIds?.join(';'),
|
||||
stepsExecResult: JSON.stringify(stepData.value),
|
||||
};
|
||||
await runFeatureCase(params);
|
||||
stepExecuteModelVisible.value = false;
|
||||
Message.success(t('common.updateSuccess'));
|
||||
cancelStepExecute();
|
||||
emit('refreshPlan');
|
||||
submitStepExecuteDone(params.lastExecResult, params.content ?? '');
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
} finally {
|
||||
submitStepExecuteLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 菜单显隐
|
||||
const hasOperationPermission = computed(
|
||||
() => hasAnyPermission(['PROJECT_TEST_PLAN:READ+UPDATE', 'PROJECT_TEST_PLAN:READ+ASSOCIATION']) && props.canEdit
|
||||
);
|
||||
|
@ -485,8 +702,25 @@
|
|||
];
|
||||
}
|
||||
|
||||
const selectNode = ref();
|
||||
/**
|
||||
* 获取步骤节点对应的用例节点
|
||||
* @param node 选中节点
|
||||
* @param resource 标签
|
||||
*/
|
||||
function getCaseNodeWithResource(node: MinderJsonNode, resource: string) {
|
||||
while (node.parent) {
|
||||
if (node?.data?.resource?.includes(resource)) {
|
||||
return node.parent;
|
||||
}
|
||||
if (node.data?.resource?.includes(caseTag)) {
|
||||
return null;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// 选中节点
|
||||
async function handleNodeSelect(node: MinderJsonNode) {
|
||||
const { data } = node;
|
||||
// 点击更多节点,加载更多用例
|
||||
|
@ -511,6 +745,16 @@
|
|||
canShowFloatMenu.value = false;
|
||||
}
|
||||
|
||||
// 点步骤描述下的【步骤描述/预期结果/实际结果】标签
|
||||
if ([actualResultTag, stepTag, stepExpectTag].some((item) => node.data?.resource?.includes(item))) {
|
||||
caseNodeAboveSelectStep.value = getCaseNodeWithResource(node, stepTag);
|
||||
if (caseNodeAboveSelectStep.value.data.id) {
|
||||
getStepData(caseNodeAboveSelectStep.value.data.id);
|
||||
stepExecuteModelVisible.value = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 不展示更多:没操作权限的用例
|
||||
if (node.data?.resource?.includes(caseTag) && !hasOperationPermission.value) {
|
||||
canShowMoreMenu.value = false;
|
||||
|
@ -525,6 +769,8 @@
|
|||
canShowEnterNode.value = false;
|
||||
}
|
||||
|
||||
executeVisible.value = false;
|
||||
|
||||
if (data?.resource?.includes(caseTag)) {
|
||||
canShowDetail.value = true;
|
||||
showAssociateBugMenu.value = true;
|
||||
|
@ -555,37 +801,6 @@
|
|||
extraVisible.value = false;
|
||||
}
|
||||
|
||||
// 添加缺陷
|
||||
const showLinkDefectDrawer = ref(false);
|
||||
const showAddDefectDrawer = ref(false);
|
||||
const linkDrawerLoading = ref(false);
|
||||
const bugListRef = ref<InstanceType<typeof BugList>>();
|
||||
function handleAddBugDone() {
|
||||
if (extraVisible.value && activeExtraKey.value === 'bug') {
|
||||
bugListRef.value?.handleShowTypeChange();
|
||||
}
|
||||
emit('handleAddBugDone');
|
||||
}
|
||||
async function associateSuccessHandler(params: TableQueryParams) {
|
||||
try {
|
||||
linkDrawerLoading.value = true;
|
||||
await associateBugToPlan({
|
||||
...params,
|
||||
testPlanCaseId: selectNode.value.data?.id,
|
||||
caseId: selectNode.value.data?.caseId,
|
||||
testPlanId: props.planId,
|
||||
});
|
||||
Message.success(t('caseManagement.featureCase.associatedSuccess'));
|
||||
linkDrawerLoading.value = false;
|
||||
handleAddBugDone();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
} finally {
|
||||
linkDrawerLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
initCaseTree,
|
||||
});
|
||||
|
@ -599,4 +814,10 @@
|
|||
margin: 0;
|
||||
height: 100%;
|
||||
}
|
||||
:deep(.execute-form) .rich-wrapper .halo-rich-text-editor .editor-content {
|
||||
max-height: 54px !important;
|
||||
.ProseMirror {
|
||||
min-height: 38px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -134,7 +134,7 @@ export interface BatchReviewCaseParams extends BatchApiParams {
|
|||
reviewId: string; // 评审id
|
||||
userId: string; // 用户id, 用来判断是否只看我的
|
||||
reviewPassRule: ReviewPassRule; // 评审规则
|
||||
status: ReviewResult; // 评审结果
|
||||
status: StartReviewStatus; // 评审结果
|
||||
content: string; // 评论内容
|
||||
notifier: string; // 评论@的人的Id, 多个以';'隔开
|
||||
reviewCommentFileIds?: string[]; // 富文本ids
|
||||
|
|
|
@ -105,6 +105,7 @@
|
|||
stepList: any;
|
||||
isDisabled?: boolean;
|
||||
isScrollY?: boolean;
|
||||
scrollY?: number;
|
||||
isTestPlan?: boolean;
|
||||
isDisabledTestPlan?: boolean;
|
||||
isPreview?: boolean; // 仅预览不展示状态可操作下拉和文本框
|
||||
|
@ -212,7 +213,7 @@
|
|||
|
||||
const tableProps = ref<Partial<MsTableProps<StepList>>>({
|
||||
columns: templateFieldColumns.value,
|
||||
scroll: { x: '100%', y: props.isScrollY ? 400 : '' },
|
||||
scroll: { x: '100%', y: props.isScrollY ? props.scrollY ?? 400 : '' },
|
||||
selectable: false,
|
||||
noDisable: true,
|
||||
showSetting: false,
|
||||
|
|
|
@ -175,7 +175,7 @@
|
|||
:review-progress="props.reviewProgress"
|
||||
:review-pass-rule="props.reviewPassRule"
|
||||
@operation="handleMinderOperation"
|
||||
@handle-review-done="handleReviewDone"
|
||||
@handle-review-done="emit('refresh')"
|
||||
/>
|
||||
</div>
|
||||
<a-modal
|
||||
|
@ -372,6 +372,7 @@
|
|||
|
||||
import { ReviewCaseItem, ReviewItem, ReviewPassRule, ReviewResult } from '@/models/caseManagement/caseReview';
|
||||
import { BatchApiParams, TableQueryParams } from '@/models/common';
|
||||
import { StartReviewStatus } from '@/enums/caseEnum';
|
||||
import { CaseManagementRouteEnum } from '@/enums/routeEnum';
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
|
||||
|
@ -907,7 +908,7 @@
|
|||
reviewId: route.query.id as string,
|
||||
userId: props.onlyMine ? userStore.id || '' : '',
|
||||
reviewPassRule: props.reviewPassRule,
|
||||
status: dialogForm.value.result as ReviewResult,
|
||||
status: dialogForm.value.result as StartReviewStatus,
|
||||
content: dialogForm.value.reason,
|
||||
notifier: dialogForm.value.commentIds.join(';'),
|
||||
moduleIds: props.activeFolder === 'all' ? [] : [props.activeFolder, ...props.offspringIds],
|
||||
|
@ -989,13 +990,6 @@
|
|||
handleOperation(type);
|
||||
}
|
||||
|
||||
function handleReviewDone(refreshTree?: boolean) {
|
||||
if (refreshTree) {
|
||||
refresh(false);
|
||||
}
|
||||
emit('refresh');
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理表格选中后批量操作
|
||||
* @param event 批量操作事件对象
|
||||
|
|
|
@ -73,10 +73,11 @@
|
|||
|
||||
const modalVisible = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
const submitForm = computed(() => (modalVisible.value ? dialogForm.value : form.value));
|
||||
const submitDisabled = computed(
|
||||
() =>
|
||||
form.value.status !== StartReviewStatus.PASS &&
|
||||
(form.value.content === '' || form.value.content.trim() === '<p style=""></p>')
|
||||
submitForm.value.status !== StartReviewStatus.PASS &&
|
||||
(submitForm.value.content === '' || submitForm.value.content.trim() === '<p style=""></p>')
|
||||
);
|
||||
|
||||
// 双击富文本内容打开弹窗
|
||||
|
@ -114,14 +115,14 @@
|
|||
userId: props.userId,
|
||||
reviewId: props.reviewId,
|
||||
reviewPassRule: props.reviewPassRule,
|
||||
...(modalVisible.value ? dialogForm.value : form.value),
|
||||
notifier: form.value.notifiers?.join(';') ?? '',
|
||||
...submitForm.value,
|
||||
notifier: submitForm.value.notifiers?.join(';') ?? '',
|
||||
...getMinderOperationParams(props.selectNode),
|
||||
};
|
||||
await batchReview(params);
|
||||
modalVisible.value = false;
|
||||
Message.success(t('caseManagement.caseReview.reviewSuccess'));
|
||||
emit('done', form.value.status);
|
||||
emit('done', params.status);
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
|
|
|
@ -117,7 +117,7 @@
|
|||
:plan-id="props.planId"
|
||||
:can-edit="props.canEdit"
|
||||
@operation="handleMinderOperation"
|
||||
@handle-add-bug-done="emit('refresh')"
|
||||
@refresh-plan="emit('refresh')"
|
||||
/>
|
||||
</div>
|
||||
<!-- 批量执行 -->
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
:preview-url="PreviewEditorImageUrl"
|
||||
:auto-height="false"
|
||||
class="w-full"
|
||||
:max-height="props.richTextMaxHeight"
|
||||
:placeholder="
|
||||
props.isDblclickPlaceholder
|
||||
? t('testPlan.featureCase.richTextDblclickPlaceholder')
|
||||
|
@ -44,6 +45,7 @@
|
|||
|
||||
const props = defineProps<{
|
||||
isDblclickPlaceholder?: boolean;
|
||||
richTextMaxHeight?: string;
|
||||
}>();
|
||||
|
||||
const form = defineModel<ExecuteFeatureCaseFormParams>('form', {
|
||||
|
|
|
@ -26,26 +26,29 @@
|
|||
import { Message } from '@arco-design/web-vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
|
||||
import type { MinderJsonNode } from '@/components/pure/ms-minder-editor/props';
|
||||
import { getMinderOperationParams } from '@/components/business/ms-minders/caseReviewMinder/utils';
|
||||
import ExecuteForm from '@/views/test-plan/testPlan/detail/featureCase/components/executeForm.vue';
|
||||
|
||||
import { runFeatureCase } from '@/api/modules/test-plan/testPlan';
|
||||
import { batchExecuteCase, runFeatureCase } from '@/api/modules/test-plan/testPlan';
|
||||
import { defaultExecuteForm } from '@/config/testPlan';
|
||||
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 type { BatchExecuteFeatureCaseParams, ExecuteFeatureCaseFormParams } from '@/models/testPlan/testPlan';
|
||||
import { LastExecuteResults } from '@/enums/caseEnum';
|
||||
|
||||
const props = defineProps<{
|
||||
caseId: string;
|
||||
caseId?: string;
|
||||
testPlanId: string;
|
||||
id: string;
|
||||
id?: string;
|
||||
selectNode?: MinderJsonNode;
|
||||
stepExecutionResult?: StepExecutionResult[];
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'done'): void;
|
||||
(e: 'done', status: LastExecuteResults, content: string): void;
|
||||
}>();
|
||||
|
||||
const { t } = useI18n();
|
||||
|
@ -104,18 +107,28 @@
|
|||
submitLoading.value = true;
|
||||
const params = {
|
||||
projectId: appStore.currentProjectId,
|
||||
caseId: props.caseId,
|
||||
testPlanId: props.testPlanId,
|
||||
id: props.id,
|
||||
...(modalVisible.value ? dialogForm.value : form.value),
|
||||
stepsExecResult: JSON.stringify(props.stepExecutionResult) ?? '',
|
||||
notifier: form.value?.commentIds?.join(';'),
|
||||
stepsExecResult: JSON.stringify(props.stepExecutionResult),
|
||||
notifier: (modalVisible.value ? dialogForm.value : form.value)?.commentIds?.join(';'),
|
||||
};
|
||||
await runFeatureCase(params);
|
||||
// 脑图执行是批量执行
|
||||
if (props.selectNode) {
|
||||
await batchExecuteCase({
|
||||
...params,
|
||||
...getMinderOperationParams(props.selectNode),
|
||||
} as BatchExecuteFeatureCaseParams);
|
||||
} else {
|
||||
await runFeatureCase({
|
||||
...params,
|
||||
caseId: props.caseId ?? '',
|
||||
id: props.id ?? '',
|
||||
});
|
||||
}
|
||||
modalVisible.value = false;
|
||||
Message.success(t('common.updateSuccess'));
|
||||
form.value = { ...defaultExecuteForm };
|
||||
emit('done');
|
||||
emit('done', params.lastExecResult, params.content ?? '');
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
|
|
Loading…
Reference in New Issue