fix(项目管理): 修复环境管理tab展示bug&报告bug

This commit is contained in:
xinxin.wu 2024-04-11 16:27:27 +08:00 committed by Craftsman
parent ff74e55944
commit dffac08451
12 changed files with 115 additions and 56 deletions

View File

@ -51,7 +51,7 @@
v-model:model-value="record.tableChecked" v-model:model-value="record.tableChecked"
@change="(val) => handleRadioChange(val as boolean, record)" @change="(val) => handleRadioChange(val as boolean, record)"
/> />
<div v-if="attrs.showPagination" class="w-[16px]"></div> <div v-if="attrs.showPagination && props.showSelectorAll" class="w-[16px]"></div>
</template> </template>
</a-table-column> </a-table-column>
<a-table-column <a-table-column

View File

@ -9,3 +9,15 @@ export enum EnvAuthTypeEnum {
ENVIRONMENT_PARAM = 'ENVIRONMENT_PARAM', // 环境参数 ENVIRONMENT_PARAM = 'ENVIRONMENT_PARAM', // 环境参数
ENVIRONMENT_GROUP = 'ENVIRONMENT_GROUP', // 环境组 ENVIRONMENT_GROUP = 'ENVIRONMENT_GROUP', // 环境组
} }
// 环境的tab
export enum EnvTabTypeEnum {
ENVIRONMENT_PARAM = 'ENVIRONMENT_PARAM', // 环境变量
ENVIRONMENT_HTTP = 'ENVIRONMENT_HTTP', // Http
ENVIRONMENT_DATABASE = 'ENVIRONMENT_DATABASE', // 数据库
ENVIRONMENT_HOST = 'ENVIRONMENT_HOST', // 域名
ENVIRONMENT_PRE = 'ENVIRONMENT_PRE', // 前置
ENVIRONMENT_POST = 'ENVIRONMENT_POST', // 后置
ENVIRONMENT_ASSERT = 'ENVIRONMENT_ASSERT', // 断言
ENVIRONMENT_SETTING = 'SETTING', // 设置
}

View File

@ -343,10 +343,10 @@
} }
function showStatus(item: ScenarioItemType) { function showStatus(item: ScenarioItemType) {
if (showApiType.value.includes(item.stepType)) { if (showApiType.value.includes(item.stepType) && item.status && item.status !== 'PENDING') {
return true; return true;
} }
return item.children && item.children.length > 0; return item.children && item.children.length > 0 && item.status && item.status !== 'PENDING';
} }
function handleStop(event: Event, step: ScenarioItemType) { function handleStop(event: Event, step: ScenarioItemType) {

View File

@ -89,11 +89,11 @@
color: 'rgb(var(--success-6))', color: 'rgb(var(--success-6))',
}, },
{ {
percentage: (props.reportDetail.stepFakeErrorCount / getCountTotal.value) * 100, percentage: (props.reportDetail.stepErrorCount / getCountTotal.value) * 100,
color: 'rgb(var(--danger-6))', color: 'rgb(var(--danger-6))',
}, },
{ {
percentage: (props.reportDetail.stepErrorCount / getCountTotal.value) * 100, percentage: (props.reportDetail.stepFakeErrorCount / getCountTotal.value) * 100,
color: 'rgb(var(--warning-6))', color: 'rgb(var(--warning-6))',
}, },
{ {

View File

@ -35,15 +35,24 @@
v-model:pre-processor-config="scenario.scenarioConfig.preProcessorConfig" v-model:pre-processor-config="scenario.scenarioConfig.preProcessorConfig"
/> />
</a-tab-pane> </a-tab-pane>
<a-tab-pane <a-tab-pane :key="ScenarioCreateComposition.ASSERTION" class="scenario-create-tab-pane">
:key="ScenarioCreateComposition.ASSERTION"
:title="t('apiScenario.assertion')"
class="scenario-create-tab-pane"
>
<assertion <assertion
v-if="activeKey === ScenarioCreateComposition.ASSERTION" v-if="activeKey === ScenarioCreateComposition.ASSERTION"
v-model:assertion-config="scenario.scenarioConfig.assertionConfig" v-model:assertion-config="scenario.scenarioConfig.assertionConfig"
/> />
<template #title>
<div class="flex items-center">
<div> {{ t('apiScenario.assertion') }}</div>
<a-badge
v-if="scenario.scenarioConfig.assertionConfig.assertions.length"
class="-mb-[2px] ml-2"
:class="activeKey === ScenarioCreateComposition.ASSERTION ? 'active-badge' : ''"
:max-count="99"
:text="assertCount"
>
</a-badge>
</div>
</template>
</a-tab-pane> </a-tab-pane>
<a-tab-pane <a-tab-pane
:key="ScenarioCreateComposition.SETTING" :key="ScenarioCreateComposition.SETTING"
@ -159,6 +168,12 @@
}); });
} }
const assertCount = computed(() => {
return scenario.value.scenarioConfig.assertionConfig.assertions.length > 99
? '99+'
: `${scenario.value.scenarioConfig.assertionConfig.assertions.length}` || '';
});
defineExpose({ defineExpose({
validScenarioForm, validScenarioForm,
}); });
@ -182,4 +197,10 @@
padding: 8px 16px; padding: 8px 16px;
} }
} }
:deep(.active-badge) {
.arco-badge-text,
.arco-badge-number {
background-color: rgb(var(--primary-5));
}
}
</style> </style>

View File

@ -32,30 +32,27 @@
/> />
</a-form-item> </a-form-item>
</a-form> </a-form>
<MsTab
<a-tabs v-if="contentTabList.length" v-model:active-key="activeKey" class="no-content" @change="handleTabChange"> v-model:active-key="activeKey"
<a-tab-pane v-for="item of contentTabList" :key="item.value" :title="t(item.label)" /> :content-tab-list="contentTabList"
<a-tab-pane key="displaySetting" :title="t('project.environmental.displaySetting')" /> :get-text-func="getTabBadge"
</a-tabs> class="no-content relative mb-[16px] border-b"
@change="handleTabChange"
/>
</div> </div>
<a-divider
:margin="0"
:class="{
'!mb-[16px]': !(activeKey === 'pre' || activeKey === 'post'),
}"
/>
<div class="content h-full"> <div class="content h-full">
<EnvParamsTab v-if="activeKey === 'envParams'" /> <EnvParamsTab v-if="activeKey === EnvTabTypeEnum.ENVIRONMENT_PARAM" />
<HttpTab v-else-if="activeKey === 'http'" /> <HttpTab v-else-if="activeKey === EnvTabTypeEnum.ENVIRONMENT_HTTP" />
<DataBaseTab v-else-if="activeKey === 'database'" /> <DataBaseTab v-else-if="activeKey === EnvTabTypeEnum.ENVIRONMENT_DATABASE" />
<HostTab v-else-if="activeKey === 'host'" ref="hostTabRef" /> <HostTab v-else-if="activeKey === EnvTabTypeEnum.ENVIRONMENT_HOST" ref="hostTabRef" />
<!-- <PreTab v-else-if="activeKey === 'pre'" /> <div
<PostTab v-else-if="activeKey === 'post'" /> --> v-else-if="activeKey === EnvTabTypeEnum.ENVIRONMENT_PRE || activeKey === EnvTabTypeEnum.ENVIRONMENT_POST"
<div v-else-if="activeKey === 'pre' || activeKey === 'post'" class="h-full"> class="h-full"
>
<PreAndPostTab :active-type="activeKey" /> <PreAndPostTab :active-type="activeKey" />
</div> </div>
<AssertTab v-else-if="activeKey === 'assert'" /> <AssertTab v-else-if="activeKey === EnvTabTypeEnum.ENVIRONMENT_ASSERT" />
<template v-for="item in envPluginList" :key="item.pluginId"> <template v-for="item in envPluginList" :key="item.pluginId">
<PluginTab <PluginTab
v-if="activeKey === item.pluginId" v-if="activeKey === item.pluginId"
@ -81,6 +78,7 @@
import { Message } from '@arco-design/web-vue'; import { Message } from '@arco-design/web-vue';
import { cloneDeep } from 'lodash-es'; import { cloneDeep } from 'lodash-es';
import MsTab from '@/components/pure/ms-tab/index.vue';
import TabSettingDrawer from './common/TabSettingDrawer.vue'; import TabSettingDrawer from './common/TabSettingDrawer.vue';
import AssertTab from './envParams/AssertTab.vue'; import AssertTab from './envParams/AssertTab.vue';
import DataBaseTab from './envParams/DatabaseTab.vue'; import DataBaseTab from './envParams/DatabaseTab.vue';
@ -98,6 +96,7 @@
import { hasAnyPermission } from '@/utils/permission'; import { hasAnyPermission } from '@/utils/permission';
import { ContentTabItem, EnvPluginListItem } from '@/models/projectManagement/environmental'; import { ContentTabItem, EnvPluginListItem } from '@/models/projectManagement/environmental';
import { EnvTabTypeEnum } from '@/enums/envEnum';
import { defaultHeaderParamsItem } from '@/views/api-test/components/config'; import { defaultHeaderParamsItem } from '@/views/api-test/components/config';
import { filterKeyValParams } from '@/views/api-test/components/utils'; import { filterKeyValParams } from '@/views/api-test/components/utils';
@ -109,7 +108,7 @@
(e: 'resetEnv'): void; (e: 'resetEnv'): void;
}>(); }>();
const activeKey = ref('envParams'); const activeKey = ref<string>(EnvTabTypeEnum.ENVIRONMENT_PARAM);
const envForm = ref(); const envForm = ref();
const { t } = useI18n(); const { t } = useI18n();
const loading = ref(false); const loading = ref(false);
@ -136,46 +135,55 @@
const contentTabList = ref<ContentTabItem[]>([]); const contentTabList = ref<ContentTabItem[]>([]);
const isDisabled = computed(() => !hasAnyPermission(['PROJECT_ENVIRONMENT:READ+UPDATE'])); const isDisabled = computed(() => !hasAnyPermission(['PROJECT_ENVIRONMENT:READ+UPDATE']));
const settingList = [
{
value: EnvTabTypeEnum.ENVIRONMENT_SETTING,
label: t('project.environmental.displaySetting'),
canHide: false,
isShow: true,
},
];
const sourceTabList = [ const sourceTabList = [
{ {
value: 'envParams', value: EnvTabTypeEnum.ENVIRONMENT_PARAM,
label: 'project.environmental.envParams', label: t('project.environmental.envParams'),
canHide: false, canHide: false,
isShow: true, isShow: true,
}, },
{ {
value: 'http', value: EnvTabTypeEnum.ENVIRONMENT_HTTP,
label: 'project.environmental.HTTP', label: t('project.environmental.HTTP'),
canHide: true, canHide: true,
isShow: true, isShow: true,
}, },
{ {
value: 'database', value: EnvTabTypeEnum.ENVIRONMENT_DATABASE,
label: 'project.environmental.database', label: t('project.environmental.database'),
canHide: true, canHide: true,
isShow: true, isShow: true,
}, },
{ {
value: 'host', value: EnvTabTypeEnum.ENVIRONMENT_HOST,
label: 'project.environmental.HOST', label: t('project.environmental.HOST'),
canHide: true, canHide: true,
isShow: true, isShow: true,
}, },
{ {
value: 'pre', value: EnvTabTypeEnum.ENVIRONMENT_PRE,
label: 'project.environmental.pre', label: t('project.environmental.pre'),
canHide: true, canHide: true,
isShow: true, isShow: true,
}, },
{ {
value: 'post', value: EnvTabTypeEnum.ENVIRONMENT_POST,
label: 'project.environmental.post', label: t('project.environmental.post'),
canHide: true, canHide: true,
isShow: true, isShow: true,
}, },
{ {
value: 'assert', value: EnvTabTypeEnum.ENVIRONMENT_ASSERT,
label: 'project.environmental.assert', label: t('project.environmental.assert'),
canHide: true, canHide: true,
isShow: true, isShow: true,
}, },
@ -191,7 +199,7 @@
} }
}; };
await initPlugin(); await initPlugin();
await store.initContentTabList([...sourceTabList, ...pluginTabList.value]); await store.initContentTabList([...sourceTabList, ...pluginTabList.value, ...settingList]);
contentTabList.value = ((await store.getContentTabList()) || []).filter((item) => item.isShow); contentTabList.value = ((await store.getContentTabList()) || []).filter((item) => item.isShow);
// //
@ -274,10 +282,20 @@
}; };
const handleTabChange = (key: string | number) => { const handleTabChange = (key: string | number) => {
if (key === 'displaySetting') { if (key === 'SETTING') {
tabSettingVisible.value = true; tabSettingVisible.value = true;
} }
}; };
function getTabBadge(tabKey: string) {
switch (tabKey) {
case EnvTabTypeEnum.ENVIRONMENT_ASSERT:
const assertLength = store.currentEnvDetailInfo.config.assertionConfig.assertions.length;
return `${assertLength > 99 ? '99+' : assertLength || ''}`;
default:
return '';
}
}
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>

View File

@ -73,7 +73,7 @@
const loadColumn = async () => { const loadColumn = async () => {
const res = (await store.getContentTabList()) || []; const res = (await store.getContentTabList()) || [];
nonCloseColumn.value = res.filter((item) => !item.canHide); nonCloseColumn.value = res.filter((item) => !item.canHide && item.value !== 'SETTING');
couldCloseColumn.value = res.filter((item) => item.canHide); couldCloseColumn.value = res.filter((item) => item.canHide);
}; };

View File

@ -13,13 +13,13 @@
}" }"
> >
<PreTab <PreTab
v-if="props.activeType === 'pre'" v-if="props.activeType === EnvTabTypeEnum.ENVIRONMENT_PRE"
:show-associated-scene="showAssociatedScene" :show-associated-scene="showAssociatedScene"
:show-pre-post-request="!showAssociatedScene" :show-pre-post-request="!showAssociatedScene"
:active-tab="activeTab" :active-tab="activeTab"
/> />
<PostTab <PostTab
v-if="props.activeType === 'post'" v-if="props.activeType === EnvTabTypeEnum.ENVIRONMENT_POST"
:show-associated-scene="showAssociatedScene" :show-associated-scene="showAssociatedScene"
:show-pre-post-request="!showAssociatedScene" :show-pre-post-request="!showAssociatedScene"
:active-tab="activeTab" :active-tab="activeTab"
@ -29,14 +29,14 @@
<div v-if="activeTab === 'requestProcessorConfig'" class="mt-4 h-full"> <div v-if="activeTab === 'requestProcessorConfig'" class="mt-4 h-full">
<a-alert class="mb-4" closable> {{ t('project.environmental.requestAlertDesc') }} </a-alert> <a-alert class="mb-4" closable> {{ t('project.environmental.requestAlertDesc') }} </a-alert>
<PreTab <PreTab
v-if="props.activeType === 'pre'" v-if="props.activeType === EnvTabTypeEnum.ENVIRONMENT_PRE"
:show-associated-scene="showAssociatedScene" :show-associated-scene="showAssociatedScene"
:show-pre-post-request="!showAssociatedScene" :show-pre-post-request="!showAssociatedScene"
:request-radio-text-props="requestPropsText" :request-radio-text-props="requestPropsText"
:active-tab="activeTab" :active-tab="activeTab"
/> />
<PostTab <PostTab
v-if="props.activeType === 'post'" v-if="props.activeType === EnvTabTypeEnum.ENVIRONMENT_POST"
:show-associated-scene="showAssociatedScene" :show-associated-scene="showAssociatedScene"
:show-pre-post-request="!showAssociatedScene" :show-pre-post-request="!showAssociatedScene"
:request-radio-text-props="requestPropsText" :request-radio-text-props="requestPropsText"
@ -52,10 +52,11 @@
import PostTab from './PostTab.vue'; import PostTab from './PostTab.vue';
import PreTab from './PreTab.vue'; import PreTab from './PreTab.vue';
import { getEnvironment } from '@/api/modules/api-test/common';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import useProjectEnvStore from '@/store/modules/setting/useProjectEnvStore'; import useProjectEnvStore from '@/store/modules/setting/useProjectEnvStore';
import { EnvTabTypeEnum } from '@/enums/envEnum';
const store = useProjectEnvStore(); const store = useProjectEnvStore();
const { t } = useI18n(); const { t } = useI18n();
@ -67,11 +68,11 @@
const tabList = ref<{ key: string; label: string }[]>([ const tabList = ref<{ key: string; label: string }[]>([
{ {
key: 'scenarioProcessorConfig', key: 'scenarioProcessorConfig',
label: '场景', label: t('project.environmental.scenario'),
}, },
{ {
key: 'requestProcessorConfig', key: 'requestProcessorConfig',
label: '请求', label: t('project.environmental.request'),
}, },
]); ]);
const activeTab = ref<string>('scenarioProcessorConfig'); const activeTab = ref<string>('scenarioProcessorConfig');
@ -81,7 +82,7 @@
const requestPropsText = computed(() => { const requestPropsText = computed(() => {
if (activeTab.value === 'requestProcessorConfig') { if (activeTab.value === 'requestProcessorConfig') {
return props.activeType === 'pre' return props.activeType === EnvTabTypeEnum.ENVIRONMENT_PRE
? { ? {
pre: t('project.environmental.preScriptBefore'), pre: t('project.environmental.preScriptBefore'),
post: t('project.environmental.preScriptAfter'), post: t('project.environmental.preScriptAfter'),

View File

@ -23,6 +23,8 @@ export default {
'project.environmental.envDescPlaceholder': 'Please enter the description', 'project.environmental.envDescPlaceholder': 'Please enter the description',
'project.environmental.envDesc': 'description', 'project.environmental.envDesc': 'description',
'project.environmental.envNameRequired': 'Environment name cannot be empty', 'project.environmental.envNameRequired': 'Environment name cannot be empty',
'project.environmental.scenario': 'scenario',
'project.environmental.request': 'request',
'project.environmental.database': 'Database', 'project.environmental.database': 'Database',
'project.environmental.HTTP': 'HTTP', 'project.environmental.HTTP': 'HTTP',
'project.environmental.HOST': 'HOST', 'project.environmental.HOST': 'HOST',
@ -129,4 +131,5 @@ export default {
'project.environmental.http.noneDataExist': 'There is already a domain name with an enabled range of none!', 'project.environmental.http.noneDataExist': 'There is already a domain name with an enabled range of none!',
'project.environmental.http.selectModule': 'Please select module', 'project.environmental.http.selectModule': 'Please select module',
'script.delete.confirm': 'After deletion, it cannot be restored. Please exercise caution.', 'script.delete.confirm': 'After deletion, it cannot be restored. Please exercise caution.',
'script.delete.scenario': 'scenario',
}; };

View File

@ -30,6 +30,8 @@ export default {
'project.environmental.envDescPlaceholder': '请输入描述', 'project.environmental.envDescPlaceholder': '请输入描述',
'project.environmental.envDesc': '描述', 'project.environmental.envDesc': '描述',
'project.environmental.envNameRequired': '环境名称不能为空', 'project.environmental.envNameRequired': '环境名称不能为空',
'project.environmental.scenario': '场景',
'project.environmental.request': '请求',
'project.environmental.HTTP': 'HTTP', 'project.environmental.HTTP': 'HTTP',
'project.environmental.HOST': 'HOST', 'project.environmental.HOST': 'HOST',
'project.environmental.TCP': 'TCP', 'project.environmental.TCP': 'TCP',

View File

@ -10,6 +10,7 @@
class="mx-[8px] w-[240px]" class="mx-[8px] w-[240px]"
@search="searchList" @search="searchList"
@press-enter="searchList" @press-enter="searchList"
@clear="searchList"
></a-input-search> ></a-input-search>
</div> </div>
</div> </div>
@ -179,7 +180,7 @@
const { t } = useI18n(); const { t } = useI18n();
const props = defineProps<{ const props = defineProps<{
group: string; group: 'system' | 'organization' | 'project';
moduleType: keyof typeof TaskCenterEnum; moduleType: keyof typeof TaskCenterEnum;
name: string; name: string;
}>(); }>();

View File

@ -14,6 +14,7 @@
class="mx-[8px] w-[240px]" class="mx-[8px] w-[240px]"
@search="searchList" @search="searchList"
@press-enter="searchList" @press-enter="searchList"
@clear="searchList"
></a-input-search> ></a-input-search>
</div> </div>
</div> </div>