From 6178b241034f00a954f82464e2720cdf7faaf448 Mon Sep 17 00:00:00 2001 From: baiqi Date: Mon, 8 Apr 2024 21:03:20 +0800 Subject: [PATCH] =?UTF-8?q?fix(all):=20=E5=9C=BA=E6=99=AFapi=E3=80=81case?= =?UTF-8?q?=E6=9B=BF=E6=8D=A2&=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/config/vite.config.dev.ts | 14 +-- frontend/src/assets/style/arco-reset.less | 6 +- .../business/ms-assertion/index.vue | 5 +- .../components/pure/ms-table/base-table.vue | 19 ++-- .../src/components/pure/ms-table/useTable.ts | 18 +-- frontend/src/enums/apiEnum.ts | 1 + frontend/src/locale/zh-CN/common.ts | 2 +- frontend/src/models/apiTest/scenario.ts | 1 + frontend/src/utils/index.ts | 2 +- .../api-test/components/environmentSelect.vue | 20 +++- .../response/result/body.vue | 2 +- .../response/result/console.vue | 2 +- .../report/component/caseReportDrawer.vue | 2 +- .../components/common/customApiDrawer.vue | 35 +++++- .../components/common/customCaseDrawer.vue | 29 ++++- .../components/common/executeStatus.vue | 5 + .../common/importApiDrawer/index.vue | 20 +++- .../common/importApiDrawer/table.vue | 20 +++- .../components/common/replaceButton.vue | 86 +++++++++++++++ .../components/common/responsePopover.vue | 57 ++++++++-- .../common/scriptOperationDrawer.vue | 4 +- .../api-test/scenario/components/config.ts | 3 +- .../step/createAction/useCreateActions.ts | 4 +- .../scenario/components/step/index.vue | 6 +- .../step/stepNodeComposition/loopContent.vue | 2 +- .../scenario/components/step/stepTree.vue | 104 ++++++++++-------- .../api-test/scenario/components/utils.ts | 22 +++- .../src/views/api-test/scenario/index.vue | 12 +- .../views/api-test/scenario/locale/zh-CN.ts | 1 + 29 files changed, 379 insertions(+), 125 deletions(-) create mode 100644 frontend/src/views/api-test/scenario/components/common/replaceButton.vue diff --git a/frontend/config/vite.config.dev.ts b/frontend/config/vite.config.dev.ts index e7ddff02fc..f93feff307 100644 --- a/frontend/config/vite.config.dev.ts +++ b/frontend/config/vite.config.dev.ts @@ -13,38 +13,38 @@ export default mergeConfig( }, proxy: { '/ws': { - target: 'http://172.16.200.18:8081/', + target: 'https://qadevtest.fit2cloud.com/', changeOrigin: true, rewrite: (path: string) => path.replace(/^\/front\/ws/, ''), ws: true, }, '/front': { - target: 'http://172.16.200.18:8081/', + target: 'https://qadevtest.fit2cloud.com/', changeOrigin: true, rewrite: (path: string) => path.replace(/^\/front/, ''), }, '/file': { - target: 'http://172.16.200.18:8081/', + target: 'https://qadevtest.fit2cloud.com/', changeOrigin: true, rewrite: (path: string) => path.replace(/^\/front\/file/, ''), }, '/attachment': { - target: 'http://172.16.200.18:8081/', + target: 'https://qadevtest.fit2cloud.com/', changeOrigin: true, rewrite: (path: string) => path.replace(/^\/front\/attachment/, ''), }, '/bug/attachment': { - target: 'http://172.16.200.18:8081/', + target: 'https://qadevtest.fit2cloud.com/', changeOrigin: true, rewrite: (path: string) => path.replace(/^\/front\/bug\/attachment/, ''), }, '/plugin/image': { - target: 'http://172.16.200.18:8081/', + target: 'https://qadevtest.fit2cloud.com/', changeOrigin: true, rewrite: (path: string) => path.replace(/^\/front\/plugin\/image/, ''), }, '/base-display': { - target: 'http://172.16.200.18:8081/', + target: 'https://qadevtest.fit2cloud.com/', changeOrigin: true, rewrite: (path: string) => path.replace(/^\/front\/base-display/, ''), }, diff --git a/frontend/src/assets/style/arco-reset.less b/frontend/src/assets/style/arco-reset.less index af2140b17f..fe23298c68 100644 --- a/frontend/src/assets/style/arco-reset.less +++ b/frontend/src/assets/style/arco-reset.less @@ -745,6 +745,9 @@ background-color: rgb(var(--primary-5)) !important; } .arco-switch-type-circle.arco-switch-disabled { + background-color: var(--color-text-n8) !important; +} +.arco-switch-type-circle.arco-switch-checked.arco-switch-disabled { background-color: rgb(var(--primary-3)) !important; } .arco-switch-type-line.arco-switch-small { @@ -774,13 +777,14 @@ display: flex; align-items: center; padding: 2px 8px; + border-radius: var(--border-radius-small); background: var(--color-text-n9); gap: 8px; .ms-pagination-jumper-input { padding: 3px 8px; width: 57px; border: 1px solid var(--color-text-input-border); - border-radius: 3px; + border-radius: var(--border-radius-small); color: var(--color-text-1); background: var(--color-text-10); box-sizing: border-box; diff --git a/frontend/src/components/business/ms-assertion/index.vue b/frontend/src/components/business/ms-assertion/index.vue index 0154347237..fe8a35f2ad 100644 --- a/frontend/src/components/business/ms-assertion/index.vue +++ b/frontend/src/components/business/ms-assertion/index.vue @@ -132,7 +132,7 @@ v-model:data="getCurrentItemState" :disabled="props.disabled" @change="handleChange" - @deleteScriptItem="deleteScriptItem" + @delete-script-item="deleteScriptItem" /> @@ -157,6 +157,7 @@ import ScriptTab from './comp/ScriptTab.vue'; import StatusCodeTab from './comp/StatusCodeTab.vue'; import VariableTab from './comp/VariableTab.vue'; + import { useI18n } from '@/hooks/useI18n'; import useModal from '@/hooks/useModal'; import { characterLimit } from '@/utils'; @@ -556,4 +557,4 @@ opacity: 1; } } - \ No newline at end of file + diff --git a/frontend/src/components/pure/ms-table/base-table.vue b/frontend/src/components/pure/ms-table/base-table.vue index 83b7a30cdb..f64ce4b32a 100644 --- a/frontend/src/components/pure/ms-table/base-table.vue +++ b/frontend/src/components/pure/ms-table/base-table.vue @@ -207,11 +207,11 @@
- + {{ t('msTable.batch.selected', { count: selectedCount }) }} {{ t('msTable.batch.clear') }} @@ -232,7 +232,8 @@ v-if="!!attrs.showPagination" size="small" v-bind="(attrs.msPagination as MsPaginationI)" - :simple="showBatchAction" + :simple="!!showBatchAction" + :show-jumper="(attrs.msPagination as MsPaginationI).total / (attrs.msPagination as MsPaginationI).pageSize > 5" @change="pageChange" @page-size-change="pageSizeChange" /> @@ -293,7 +294,6 @@ const props = defineProps<{ selectedKeys: Set; - selectedKey: string; excludeKeys: Set; selectorStatus: SelectAllEnum; actionConfig?: BatchActionConfig; @@ -316,7 +316,6 @@ firstColumnWidth?: number; // 选择、拖拽列的宽度 }>(); const emit = defineEmits<{ - (e: 'update:selectedKey', value: string): void; (e: 'batchAction', value: BatchActionParams, queryParams: BatchActionQueryParams): void; (e: 'pageChange', value: number): void; (e: 'pageSizeChange', value: number): void; @@ -413,15 +412,15 @@ } }; - const innerSelectedKey = defineModel('selectedKey', { default: '' }); // 内部维护的单选选中项 + const selectedKey = defineModel('selectedKey', { default: '' }); // 内部维护的单选选中项 const tempRecord = ref({}); watch( () => attrs.data, (arr) => { - if (innerSelectedKey.value && Array.isArray(arr) && arr.length > 0) { + if (selectedKey.value && Array.isArray(arr) && arr.length > 0) { arr = arr.map((item: TableData) => { - if (item.id === innerSelectedKey.value) { + if (item.id === selectedKey.value) { item.tableChecked = true; tempRecord.value = item; } @@ -436,7 +435,7 @@ function handleRadioChange(val: boolean, record: TableData) { if (val) { - innerSelectedKey.value = record.id; + selectedKey.value = record.id; record.tableChecked = true; tempRecord.value.tableChecked = false; tempRecord.value = record; @@ -469,7 +468,7 @@ }); const showBatchAction = computed(() => { - return selectedCount.value > 0 && !!attrs.selectable; + return selectedCount.value > 0 && !!attrs.selectable && props.actionConfig; }); const handleBatchAction = (value: BatchActionParams) => { diff --git a/frontend/src/components/pure/ms-table/useTable.ts b/frontend/src/components/pure/ms-table/useTable.ts index 23aa635fe0..bf2e00345f 100644 --- a/frontend/src/components/pure/ms-table/useTable.ts +++ b/frontend/src/components/pure/ms-table/useTable.ts @@ -79,7 +79,6 @@ export default function useTableProps( emptyDataShowLine: true, // 空数据是否显示 "-" /** Column Selector */ showJumpMethod: false, // 是否显示跳转方法 - showFooterActionWrap: false, // 是否显示底部操作区域 isSimpleSetting: false, // 是否是简易column设置 filterIconAlignLeft: true, // 筛选图标是否靠左 ...props, @@ -446,22 +445,9 @@ export default function useTableProps( }); watchEffect(() => { - const { heightUsed, showPagination, selectedKeys, msPagination } = propsRes.value; - let hasFooterAction = false; - if (showPagination) { - const { pageSize, total } = msPagination as Pagination; - /* - * 是否有底部操作栏 包括 批量操作 和 分页器 - * 1. 有分页器,且总条数大于每页条数 - * 2. 有选中项 - */ - hasFooterAction = total > pageSize || selectedKeys.size > 0; - } - - propsRes.value.showFooterActionWrap = hasFooterAction; + const { heightUsed } = propsRes.value; if (props?.heightUsed) { - const currentY = - appStore.innerHeight - (heightUsed || defaultHeightUsed) + (hasFooterAction ? 0 : footerActionWrapHeight); + const currentY = appStore.innerHeight - (heightUsed || defaultHeightUsed); propsRes.value.scroll = { ...propsRes.value.scroll, y: currentY }; } }); diff --git a/frontend/src/enums/apiEnum.ts b/frontend/src/enums/apiEnum.ts index e2d3434232..6e11f33577 100644 --- a/frontend/src/enums/apiEnum.ts +++ b/frontend/src/enums/apiEnum.ts @@ -249,6 +249,7 @@ export enum ScenarioExecuteStatus { FAILED = 'FAILED', STOP = 'STOP', UN_EXECUTE = 'UN_EXECUTE', + FAKE_ERROR = 'FAKE_ERROR', } // 场景步骤类型 export enum ScenarioStepType { diff --git a/frontend/src/locale/zh-CN/common.ts b/frontend/src/locale/zh-CN/common.ts index fa8ef8b8bb..a06246aebd 100644 --- a/frontend/src/locale/zh-CN/common.ts +++ b/frontend/src/locale/zh-CN/common.ts @@ -148,7 +148,7 @@ export default { 'common.value.notNull': '属性值不能为空', 'common.nameNotNull': '名称不能为空', 'common.namePlaceholder': '请输入名称,按回车键保存', - 'common.unsavedLeave': '有标签页的内容未保存,离开后后未保存的内容将丢失,确定要离开吗?', + 'common.unsavedLeave': '有标签页的内容未保存,离开后未保存的内容将丢失,确定要离开吗?', 'common.image': '图片', 'common.text': '文本', }; diff --git a/frontend/src/models/apiTest/scenario.ts b/frontend/src/models/apiTest/scenario.ts index 9c6ff329d3..37aaf5f252 100644 --- a/frontend/src/models/apiTest/scenario.ts +++ b/frontend/src/models/apiTest/scenario.ts @@ -402,6 +402,7 @@ export interface Scenario { executeTime?: string | number; // 执行时间 executeSuccessCount: number; // 执行成功数量 executeFailCount: number; // 执行失败数量 + executeFakeErrorCount: number; // 执行误报数量 reportId: string | number; // 场景报告 id stepResponses: Record>; // 步骤响应集合,key 为步骤 id,value 为步骤响应内容 isExecute?: boolean; // 是否从列表执行进去场景详情 diff --git a/frontend/src/utils/index.ts b/frontend/src/utils/index.ts index 6294a4182c..d8e5611dff 100644 --- a/frontend/src/utils/index.ts +++ b/frontend/src/utils/index.ts @@ -261,7 +261,7 @@ export function mapTree( if (newNode) { newNode.level = _level; if (newNode[customChildrenKey] && newNode[customChildrenKey].length > 0) { - newNode[customChildrenKey] = mapFunc(newNode[customChildrenKey], fullPath, _level + 1, node); + newNode[customChildrenKey] = mapFunc(newNode[customChildrenKey], fullPath, _level + 1, newNode); } } return newNode; diff --git a/frontend/src/views/api-test/components/environmentSelect.vue b/frontend/src/views/api-test/components/environmentSelect.vue index 53775ec711..d766cf0d64 100644 --- a/frontend/src/views/api-test/components/environmentSelect.vue +++ b/frontend/src/views/api-test/components/environmentSelect.vue @@ -61,9 +61,11 @@ value: item.id, })); currentEnv.value = currentEnv.value.length ? currentEnv.value : res[0]?.id; - if (currentEnv.value) { - await initEnvironment(); - } + nextTick(() => { + if (currentEnv.value) { + initEnvironment(); + } + }); } catch (error) { // eslint-disable-next-line no-console console.log(error); @@ -82,6 +84,18 @@ openNewPage(ProjectManagementRouteEnum.PROJECT_MANAGEMENT_ENVIRONMENT_MANAGEMENT); } + watch( + () => currentEnv.value, + (val) => { + if (!val) { + currentEnv.value = (envOptions.value[0]?.value as string) || ''; + nextTick(() => { + initEnvironment(); + }); + } + } + ); + onBeforeMount(() => { initEnvList(); }); diff --git a/frontend/src/views/api-test/components/requestComposition/response/result/body.vue b/frontend/src/views/api-test/components/requestComposition/response/result/body.vue index 9dcddd503e..c570cd6961 100644 --- a/frontend/src/views/api-test/components/requestComposition/response/result/body.vue +++ b/frontend/src/views/api-test/components/requestComposition/response/result/body.vue @@ -14,7 +14,7 @@
+
+ +
(); const appStore = useAppStore(); @@ -492,7 +512,11 @@ }); // 抽屉标题 const title = computed(() => { - if (_stepType.value.isCopyApi || _stepType.value.isQuoteApi) { + if ( + _stepType.value.isCopyApi || + _stepType.value.isQuoteApi || + props.step?.stepType === ScenarioStepType.CUSTOM_REQUEST + ) { return props.step?.name; } return t('apiScenario.customApi'); @@ -1014,6 +1038,7 @@ } function stopDebug() { + requestVModel.value.executeLoading = false; emit('stopDebug'); } @@ -1097,6 +1122,14 @@ } } + /** + * 替换步骤 + * @param newStep 替换的新步骤 + */ + function handleReplace(newStep: ScenarioStepItem) { + emit('replace', newStep); + } + watch( () => visible.value, async (val) => { diff --git a/frontend/src/views/api-test/scenario/components/common/customCaseDrawer.vue b/frontend/src/views/api-test/scenario/components/common/customCaseDrawer.vue index 553dacc2ec..9ade015568 100644 --- a/frontend/src/views/api-test/scenario/components/common/customCaseDrawer.vue +++ b/frontend/src/views/api-test/scenario/components/common/customCaseDrawer.vue @@ -28,11 +28,17 @@
-
- - - {{ t('common.replace') }} - +
+ {{ t('common.delete') }} @@ -255,6 +261,7 @@ import MsTab from '@/components/pure/ms-tab/index.vue'; import assertion from '@/components/business/ms-assertion/index.vue'; import loopPagination from './loopPagination.vue'; + import replaceButton from './replaceButton.vue'; import stepType from './stepType/stepType.vue'; import auth from '@/views/api-test/components/requestComposition/auth.vue'; import postcondition from '@/views/api-test/components/requestComposition/postcondition.vue'; @@ -306,6 +313,7 @@ const props = defineProps<{ request?: RequestParam; // 请求参数集合 + steps: ScenarioStepItem[]; stepResponses?: Record; fileParams?: ScenarioStepFileParams; permissionMap?: { @@ -317,6 +325,7 @@ (e: 'deleteStep'): void; (e: 'execute', request: RequestParam, executeType?: 'localExec' | 'serverExec'): void; (e: 'stopDebug'): void; + (e: 'replace', newStep: ScenarioStepItem): void; }>(); const appStore = useAppStore(); @@ -903,6 +912,7 @@ } function stopDebug() { + requestVModel.value.executeLoading = false; emit('stopDebug'); } @@ -956,6 +966,14 @@ } } + /** + * 替换步骤 + * @param newStep 替换的新步骤 + */ + function handleReplace(newStep: ScenarioStepItem) { + emit('replace', newStep); + } + watch( () => visible.value, async (val) => { @@ -968,6 +986,7 @@ ...defaultApiParams, ...props.request, isNew: false, + stepId: activeStep.value?.uniqueId || '', }); if (isQuote.value || isCopyNeedInit.value) { // 引用时,需要初始化引用的详情;复制只在第一次初始化的时候需要加载后台数据(request.request是复制请求时列表参数字段request会为 null,以此判断释放第一次初始化) diff --git a/frontend/src/views/api-test/scenario/components/common/executeStatus.vue b/frontend/src/views/api-test/scenario/components/common/executeStatus.vue index b5e2db05f0..285e4e0967 100644 --- a/frontend/src/views/api-test/scenario/components/common/executeStatus.vue +++ b/frontend/src/views/api-test/scenario/components/common/executeStatus.vue @@ -38,6 +38,11 @@ color: 'rgb(var(--danger-6))', text: 'common.fail', }, + [ScenarioExecuteStatus.FAKE_ERROR]: { + bgColor: 'rgb(var(--warning-2))', + color: 'rgb(var(--warning-5))', + text: 'report.fake.error', + }, [ScenarioExecuteStatus.SUCCESS]: { bgColor: 'rgb(var(--success-2))', color: 'rgb(var(--success-6))', diff --git a/frontend/src/views/api-test/scenario/components/common/importApiDrawer/index.vue b/frontend/src/views/api-test/scenario/components/common/importApiDrawer/index.vue index 876f9df22a..f1a4a2a1ae 100644 --- a/frontend/src/views/api-test/scenario/components/common/importApiDrawer/index.vue +++ b/frontend/src/views/api-test/scenario/components/common/importApiDrawer/index.vue @@ -1,7 +1,7 @@