mirror of
https://gitee.com/fit2cloud-feizhiyun/MeterSphere.git
synced 2024-12-03 12:39:12 +08:00
feat(项目管理): 环境功能修改和部分bug修改
This commit is contained in:
parent
79bdb3eee2
commit
eb235d9a97
@ -25,7 +25,7 @@ export function updateOrAddEnv(data: { request: EnvDetailItem; fileList: FileIte
|
||||
export function listEnv(data: { projectId: string; keyword: string }) {
|
||||
return MSR.post<EnvListItem[]>({ url: envURL.listEnvUrl, data });
|
||||
}
|
||||
export function importEnv(data: { request: any; fileList: FileItem[] }) {
|
||||
export function importEnv(data: { request: any; fileList: File[] }) {
|
||||
return MSR.uploadFile({ url: envURL.importEnvUrl }, data, '', false);
|
||||
}
|
||||
export function getEntryEnv(data: EnvListItem) {
|
||||
@ -94,7 +94,7 @@ export function updateOrAddGlobalParam(data: GlobalParams) {
|
||||
return MSR.post<EnvListItem>({ url: data.id ? envURL.updateGlobalParamUrl : envURL.addGlobalParamUrl, data });
|
||||
}
|
||||
/** 项目管理-环境-全局参数-导入 */
|
||||
export function importGlobalParam(data: { request: any; fileList: FileItem[] }) {
|
||||
export function importGlobalParam(data: { request: any; fileList: File[] }) {
|
||||
return MSR.uploadFile<EnvListItem>({ url: envURL.importGlobalParamUrl }, data, '', false);
|
||||
}
|
||||
/** 项目管理-环境-全局参数-详情 */
|
||||
|
@ -88,7 +88,13 @@
|
||||
<!-- xPath开始 -->
|
||||
<div v-if="activeTab === ResponseBodyAssertionType.XPATH" class="mt-[16px]">
|
||||
<div class="text-[var(--color-text-1)]">{{ t('ms.assertion.responseContentType') }}</div>
|
||||
<a-radio-group v-model="activeResponseFormat" class="mb-[16px] mt-[16px]" type="button" size="small">
|
||||
<a-radio-group
|
||||
v-model="activeResponseFormat"
|
||||
class="mb-[16px] mt-[16px]"
|
||||
type="button"
|
||||
size="small"
|
||||
@change="(value: string | number | boolean)=>changeHandler(value,ResponseBodyAssertionType.XPATH)"
|
||||
>
|
||||
<a-radio key="XML" value="XML">XML</a-radio>
|
||||
<a-radio key="HTML" value="HTML">HTML</a-radio>
|
||||
</a-radio-group>
|
||||
@ -328,6 +334,7 @@
|
||||
import moreSetting from '@/views/api-test/components/fastExtraction/moreSetting.vue';
|
||||
import paramsTable, { type ParamTableColumn } from '@/views/api-test/components/paramTable.vue';
|
||||
|
||||
import { conditionTypeNameMap } from '@/config/apiTest';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import {
|
||||
countNodes,
|
||||
@ -403,10 +410,6 @@
|
||||
};
|
||||
|
||||
const condition = useVModel(props, 'data', emit);
|
||||
// const condition = ref<Param>(props.data || defaultParamItem);
|
||||
// watchEffect(() => {
|
||||
// emit('change', { ...condition.value });
|
||||
// });
|
||||
|
||||
const extractParamsTableRef = ref<InstanceType<typeof paramsTable>>();
|
||||
const fastExtractionVisible = ref(false);
|
||||
@ -782,4 +785,10 @@
|
||||
const handleScriptChange = (data: ExecuteConditionProcessor) => {
|
||||
condition.value.script = data;
|
||||
};
|
||||
// XML改变
|
||||
function changeHandler(value: string | number | boolean, type: string) {
|
||||
if (value === condition.value.responseFormat) {
|
||||
handleChange([], type);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,40 +1,53 @@
|
||||
<template>
|
||||
<conditionContent v-model:data="innerParams" :height-used="600" is-build-in class="mt-[16px]" />
|
||||
<div class="h-full w-full">
|
||||
<a-scrollbar
|
||||
:style="{
|
||||
overflow: 'auto',
|
||||
height: 'calc(100vh - 490px)',
|
||||
}"
|
||||
>
|
||||
<conditionContent v-model:data="condition" is-build-in />
|
||||
</a-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useVModel } from '@vueuse/core';
|
||||
|
||||
import conditionContent from '@/views/api-test/components/condition/content.vue';
|
||||
|
||||
import { RequestConditionProcessor, RequestConditionScriptLanguage } from '@/enums/apiEnum';
|
||||
import { getEnvironment } from '@/api/modules/api-test/common';
|
||||
import useProjectEnvStore from '@/store/modules/setting/useProjectEnvStore';
|
||||
|
||||
const store = useProjectEnvStore();
|
||||
interface ScriptItem {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
interface ScriptTabProps {
|
||||
value: ScriptItem;
|
||||
data: any;
|
||||
}
|
||||
|
||||
const defaultScriptItem: ScriptItem = {
|
||||
id: new Date().getTime(),
|
||||
processorType: RequestConditionProcessor.SCRIPT,
|
||||
scriptName: '断言脚本名称',
|
||||
enableCommonScript: false,
|
||||
params: [],
|
||||
scriptId: '',
|
||||
scriptLanguage: RequestConditionScriptLanguage.JAVASCRIPT,
|
||||
script: '',
|
||||
};
|
||||
|
||||
const props = defineProps<ScriptTabProps>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'change', val: ScriptItem): void; // 数据发生变化
|
||||
}>();
|
||||
|
||||
const innerParams = ref<any>(props.value || defaultScriptItem);
|
||||
watchEffect(() => {
|
||||
emit('change', innerParams.value);
|
||||
const condition = useVModel(props, 'data', emit);
|
||||
const currentEnvConfig = ref({});
|
||||
async function initEnvironment() {
|
||||
try {
|
||||
currentEnvConfig.value = await getEnvironment(store.currentId);
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
/** 向孙组件提供属性 */
|
||||
provide('currentEnvConfig', readonly(currentEnvConfig));
|
||||
onBeforeMount(() => {
|
||||
initEnvironment();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -12,11 +12,12 @@
|
||||
</template>
|
||||
</a-dropdown>
|
||||
|
||||
<div v-if="showBody" class="ms-assertion-body">
|
||||
<div v-if="showBody" class="ms-assertion-body w-full">
|
||||
<a-scrollbar
|
||||
:style="{
|
||||
overflow: 'auto',
|
||||
height: 'calc(100vh - 458px)',
|
||||
width: '100%',
|
||||
}"
|
||||
>
|
||||
<VueDraggable v-model="assertions" class="ms-assertion-body-left" ghost-class="ghost" handle=".sort-handle">
|
||||
@ -63,49 +64,49 @@
|
||||
</VueDraggable>
|
||||
</a-scrollbar>
|
||||
<section class="ms-assertion-body-right">
|
||||
<a-scrollbar
|
||||
<!-- <a-scrollbar
|
||||
:style="{
|
||||
overflow: 'auto',
|
||||
height: '200px',
|
||||
height: 'calc(100vh - 458px)',
|
||||
}"
|
||||
>
|
||||
<!-- 响应头 -->
|
||||
<ResponseHeaderTab
|
||||
v-if="valueKey === ResponseAssertionType.RESPONSE_HEADER"
|
||||
v-model:data="getCurrentItemState"
|
||||
@change="handleChange"
|
||||
/>
|
||||
<!-- 状态码 -->
|
||||
<StatusCodeTab
|
||||
v-if="valueKey === ResponseAssertionType.RESPONSE_CODE"
|
||||
v-model:data="getCurrentItemState"
|
||||
@change="handleChange"
|
||||
/>
|
||||
<!-- 响应体 -->
|
||||
<ResponseBodyTab
|
||||
v-if="valueKey === ResponseAssertionType.RESPONSE_BODY"
|
||||
v-model:data="getCurrentItemState"
|
||||
@change="handleChange"
|
||||
/>
|
||||
<!-- 响应时间 -->
|
||||
<ResponseTimeTab
|
||||
v-if="valueKey === ResponseAssertionType.RESPONSE_TIME"
|
||||
v-model:data="getCurrentItemState"
|
||||
@change="handleChange"
|
||||
/>
|
||||
<!-- 变量 -->
|
||||
<VariableTab
|
||||
v-if="valueKey === ResponseAssertionType.VARIABLE"
|
||||
v-model:data="getCurrentItemState"
|
||||
@change="handleChange"
|
||||
/>
|
||||
<!-- 脚本 -->
|
||||
<ScriptTab
|
||||
v-if="valueKey === ResponseAssertionType.SCRIPT"
|
||||
:value="getCurrentItemState"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</a-scrollbar>
|
||||
> -->
|
||||
<!-- 响应头 -->
|
||||
<ResponseHeaderTab
|
||||
v-if="valueKey === ResponseAssertionType.RESPONSE_HEADER"
|
||||
v-model:data="getCurrentItemState"
|
||||
@change="handleChange"
|
||||
/>
|
||||
<!-- 状态码 -->
|
||||
<StatusCodeTab
|
||||
v-if="valueKey === ResponseAssertionType.RESPONSE_CODE"
|
||||
v-model:data="getCurrentItemState"
|
||||
@change="handleChange"
|
||||
/>
|
||||
<!-- 响应体 -->
|
||||
<ResponseBodyTab
|
||||
v-if="valueKey === ResponseAssertionType.RESPONSE_BODY"
|
||||
v-model:data="getCurrentItemState"
|
||||
@change="handleChange"
|
||||
/>
|
||||
<!-- 响应时间 -->
|
||||
<ResponseTimeTab
|
||||
v-if="valueKey === ResponseAssertionType.RESPONSE_TIME"
|
||||
v-model:data="getCurrentItemState"
|
||||
@change="handleChange"
|
||||
/>
|
||||
<!-- 变量 -->
|
||||
<VariableTab
|
||||
v-if="valueKey === ResponseAssertionType.VARIABLE"
|
||||
v-model:data="getCurrentItemState"
|
||||
@change="handleChange"
|
||||
/>
|
||||
<!-- 脚本 -->
|
||||
<ScriptTab
|
||||
v-if="valueKey === ResponseAssertionType.SCRIPT"
|
||||
v-model:data="getCurrentItemState"
|
||||
@change="handleChange"
|
||||
/>
|
||||
<!-- </a-scrollbar> -->
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
@ -117,6 +118,7 @@
|
||||
import { VueDraggable } from 'vue-draggable-plus';
|
||||
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
import { LanguageEnum } from '@/components/pure/ms-code-editor/types';
|
||||
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
|
||||
import MsTableMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
||||
import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
||||
@ -129,7 +131,8 @@
|
||||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
|
||||
import { ResponseAssertionType } from '@/enums/apiEnum';
|
||||
import { ExecuteConditionProcessor } from '@/models/apiTest/common';
|
||||
import { RequestConditionScriptLanguage, ResponseAssertionType } from '@/enums/apiEnum';
|
||||
|
||||
import { ExecuteAssertion, MsAssertionItem } from './type';
|
||||
|
||||
@ -192,6 +195,12 @@
|
||||
bodyAssertionDataByType: {},
|
||||
};
|
||||
}
|
||||
if (currentResItem && currentResItem?.assertionType === ResponseAssertionType.SCRIPT) {
|
||||
return {
|
||||
...currentResItem,
|
||||
processorType: ResponseAssertionType.SCRIPT,
|
||||
};
|
||||
}
|
||||
return currentResItem;
|
||||
},
|
||||
set: (val: ExecuteAssertion) => {
|
||||
@ -303,6 +312,23 @@
|
||||
});
|
||||
break;
|
||||
case ResponseAssertionType.SCRIPT:
|
||||
assertions.value.push({
|
||||
...tmpObj,
|
||||
id,
|
||||
processorType: ResponseAssertionType.SCRIPT,
|
||||
scriptName: t('apiTestDebug.preconditionScriptName'),
|
||||
enableCommonScript: true,
|
||||
script: '',
|
||||
scriptId: '',
|
||||
scriptLanguage: LanguageEnum.BEANSHELL,
|
||||
commonScriptInfo: {
|
||||
id: '',
|
||||
name: '',
|
||||
script: '',
|
||||
params: [{}],
|
||||
scriptLanguage: LanguageEnum.BEANSHELL,
|
||||
},
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -360,6 +386,7 @@
|
||||
getCurrentItemState.value =
|
||||
assertions.value.find((item: any) => item.id === activeKey.value) || assertions.value[0] || {};
|
||||
activeKey.value = getCurrentItemState.value.id;
|
||||
console.log(getCurrentItemState.value, 'getCurrentItemState.value');
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
<template #name="{ record }">
|
||||
<div class="flex items-center">
|
||||
<div class="one-line-text max-w-[200px] cursor-pointer text-[rgb(var(--primary-5))]">{{ record.name }}</div>
|
||||
<a-popover :title="t('project.commonScript.publicScriptName')" position="right">
|
||||
<a-popover :title="record.name" position="right">
|
||||
<a-button type="text" class="ml-2 px-0">{{ t('project.commonScript.preview') }}</a-button>
|
||||
<template #content>
|
||||
<div class="w-[436px] bg-[var(--color-bg-3)] px-2 pb-2">
|
||||
|
@ -15,7 +15,9 @@
|
||||
<div class="inner-wrapper">
|
||||
<div class="optional-field">
|
||||
<div class="optional-header">
|
||||
<div class="font-medium">{{ t('system.orgTemplate.optionalField') }}</div>
|
||||
<div class="font-medium">{{
|
||||
props.titleProps?.selectableTitle || t('system.orgTemplate.optionalField')
|
||||
}}</div>
|
||||
<a-checkbox :model-value="isCheckedAll" :indeterminate="indeterminate" @change="handleChangeAll">
|
||||
<span class="font-medium text-[var(--color-text-3)]">{{ t('system.orgTemplate.selectAll') }}</span>
|
||||
</a-checkbox>
|
||||
@ -23,7 +25,9 @@
|
||||
<div class="p-[16px]">
|
||||
<a-checkbox-group :model-value="selectedIds" @change="handleGroupChange">
|
||||
<div v-if="systemList.length" class="mb-[32px]">
|
||||
<div class="text-[var(--color-text-4)]">{{ t('ms-export-drawer.systemFiled') }}</div>
|
||||
<div class="text-[var(--color-text-4)]">{{
|
||||
props.titleProps?.systemTitle || t('ms-export-drawer.systemFiled')
|
||||
}}</div>
|
||||
<div class="flex flex-row flex-wrap">
|
||||
<a-checkbox
|
||||
v-for="item in systemList"
|
||||
@ -80,7 +84,9 @@
|
||||
</div>
|
||||
<div>
|
||||
<div class="optional-header min-w-[270px]">
|
||||
<div class="font-medium">{{ t('system.orgTemplate.selectedField') }}</div>
|
||||
<div class="font-medium">{{
|
||||
props.titleProps?.selectedTitle || t('system.orgTemplate.selectedField')
|
||||
}}</div>
|
||||
<MsButton @click="handleReset">{{ t('system.orgTemplate.clear') }}</MsButton>
|
||||
</div>
|
||||
<div class="p-[16px]">
|
||||
@ -140,6 +146,11 @@
|
||||
defaultSelectedKeys?: string[];
|
||||
isArrayColumn?: boolean;
|
||||
arrayColumn?: EnvListItem[];
|
||||
titleProps?: {
|
||||
selectableTitle: string; // 可选字段
|
||||
systemTitle: string; // 已选字段| 环境
|
||||
selectedTitle: string; // 已选字段| 环境
|
||||
};
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<MsExportDrawerProps>(), {
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="condition-content">
|
||||
<div class="condition-content h-full">
|
||||
<!-- 脚本操作 -->
|
||||
<template
|
||||
v-if="
|
||||
@ -45,7 +45,7 @@
|
||||
</div>
|
||||
<!-- 前后置请求结束 -->
|
||||
<div class="flex items-center justify-between">
|
||||
<a-radio-group v-model:model-value="condition.enableCommonScript" class="mb-[8px]">
|
||||
<a-radio-group v-model="condition.enableCommonScript" class="mb-[8px]">
|
||||
<a-radio :value="false">{{ t('apiTestDebug.manual') }}</a-radio>
|
||||
<a-radio :value="true">{{ t('apiTestDebug.quote') }}</a-radio>
|
||||
</a-radio-group>
|
||||
|
@ -679,6 +679,36 @@
|
||||
color: var(--color-text-1);
|
||||
}
|
||||
}
|
||||
:deep(.arco-input-tag) {
|
||||
border-color: transparent !important;
|
||||
&:hover {
|
||||
border-color: rgb(var(--primary-5)) !important;
|
||||
}
|
||||
}
|
||||
:deep(.arco-select-view-multiple) {
|
||||
border-color: transparent !important;
|
||||
.arco-select-view-suffix {
|
||||
visibility: hidden;
|
||||
}
|
||||
&:hover {
|
||||
border-color: rgb(var(--primary-5)) !important;
|
||||
.arco-select-view-suffix {
|
||||
visibility: visible !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep(.arco-textarea-wrapper) {
|
||||
border-color: transparent !important;
|
||||
&:hover {
|
||||
border-color: rgb(var(--primary-5)) !important;
|
||||
}
|
||||
}
|
||||
:deep(.arco-input-number) {
|
||||
border-color: transparent !important;
|
||||
&:hover {
|
||||
border-color: rgb(var(--primary-5)) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.rightButtons {
|
||||
:deep(.ms-button--secondary):hover,
|
||||
|
@ -409,7 +409,7 @@
|
||||
label: item.fieldName,
|
||||
value: initValue,
|
||||
required: item.required,
|
||||
options: item.options || [],
|
||||
options: optionsValue || [],
|
||||
props: {
|
||||
modelValue: initValue,
|
||||
options: optionsValue || [],
|
||||
|
@ -5,11 +5,14 @@ import type { MsFileItem } from '@/components/pure/ms-upload/types';
|
||||
import type { CaseLevel } from '@/components/business/ms-case-associate/types';
|
||||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import type { AssociatedList, CustomAttributes } from '@/models/caseManagement/featureCase';
|
||||
import { StatusType } from '@/enums/caseEnum';
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
export interface ReviewResult {
|
||||
@ -171,19 +174,45 @@ export function initFormCreate(customFields: CustomAttributes[], permission: str
|
||||
return customFields.map((item: any) => {
|
||||
const multipleType = ['MULTIPLE_SELECT', 'CHECKBOX', 'MULTIPLE_MEMBER', 'MULTIPLE_INPUT'];
|
||||
const numberType = ['INT', 'FLOAT'];
|
||||
const memberType = ['MEMBER', 'MULTIPLE_MEMBER'];
|
||||
let currentDefaultValue;
|
||||
let optionsValue = item.options;
|
||||
// 处理数字类型
|
||||
if (numberType.includes(item.type)) {
|
||||
currentDefaultValue = item.defaultValue * 1;
|
||||
// 处理多选项类型为空的默认值
|
||||
} else if (multipleType.includes(item.type) && Array.isArray(item.defaultValue) && item.defaultValue.length === 0) {
|
||||
currentDefaultValue = item.defaultValue;
|
||||
// 处理多选情况
|
||||
} else if (multipleType.includes(item.type)) {
|
||||
const tempValue = JSON.parse(item.defaultValue);
|
||||
if (item.type !== 'MULTIPLE_INPUT') {
|
||||
if (item.type !== 'MULTIPLE_INPUT' && !item.type.includes('MEMBER')) {
|
||||
const optionsIds = item.options?.map((e: any) => e.value);
|
||||
currentDefaultValue = optionsIds.filter((e: any) => tempValue.includes(e));
|
||||
// 多选成员
|
||||
} else if (memberType.includes(item.type)) {
|
||||
optionsValue = [
|
||||
{
|
||||
fieldId: item.fieldId,
|
||||
internal: item.internal,
|
||||
text: userStore.name || '',
|
||||
value: userStore.id || '',
|
||||
},
|
||||
];
|
||||
currentDefaultValue = item.defaultValue;
|
||||
} else {
|
||||
currentDefaultValue = JSON.parse(item.defaultValue);
|
||||
}
|
||||
} else if (memberType.includes(item.type)) {
|
||||
optionsValue = [
|
||||
{
|
||||
fieldId: item.fieldId,
|
||||
internal: item.internal,
|
||||
text: userStore.name || '',
|
||||
value: userStore.id || '',
|
||||
},
|
||||
];
|
||||
currentDefaultValue = item.defaultValue;
|
||||
} else {
|
||||
currentDefaultValue = item.defaultValue;
|
||||
}
|
||||
@ -194,11 +223,11 @@ export function initFormCreate(customFields: CustomAttributes[], permission: str
|
||||
label: item.fieldName,
|
||||
value: currentDefaultValue,
|
||||
required: item.required,
|
||||
options: item.options || [],
|
||||
options: optionsValue || [],
|
||||
props: {
|
||||
modelValue: currentDefaultValue,
|
||||
disabled: !hasAnyPermission(permission),
|
||||
options: item.options || [],
|
||||
options: optionsValue || [],
|
||||
},
|
||||
};
|
||||
}) as FormItem[];
|
||||
|
@ -54,6 +54,13 @@
|
||||
},
|
||||
];
|
||||
|
||||
function initEnvDetail() {
|
||||
projectEnvStore.initEnvDetail().then(() => {
|
||||
headerParams.value = projectEnvStore.allParamDetailInfo?.globalParams.headers || [];
|
||||
GlobalVariable.value = projectEnvStore.allParamDetailInfo?.globalParams.commonVariables || [];
|
||||
});
|
||||
}
|
||||
|
||||
const handleSave = async () => {
|
||||
try {
|
||||
loading.value = true;
|
||||
@ -75,6 +82,7 @@
|
||||
await updateOrAddGlobalParam(params);
|
||||
Message.success(t('common.saveSuccess'));
|
||||
canSave.value = false;
|
||||
initEnvDetail();
|
||||
} catch (error) {
|
||||
Message.error(t('common.saveFailed'));
|
||||
// eslint-disable-next-line no-console
|
||||
@ -83,11 +91,13 @@
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
onBeforeMount(() => {
|
||||
projectEnvStore.initEnvDetail().then(() => {
|
||||
headerParams.value = projectEnvStore.allParamDetailInfo?.globalParams.headers || [];
|
||||
GlobalVariable.value = projectEnvStore.allParamDetailInfo?.globalParams.commonVariables || [];
|
||||
});
|
||||
initEnvDetail();
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
initEnvDetail,
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -45,14 +45,17 @@
|
||||
'!mb-[16px]': !(activeKey === 'pre' || activeKey === 'post'),
|
||||
}"
|
||||
/>
|
||||
<div class="content">
|
||||
<div class="content h-full">
|
||||
<EnvParamsTab v-if="activeKey === 'envParams'" />
|
||||
<HttpTab v-else-if="activeKey === 'http'" />
|
||||
<DataBaseTab v-else-if="activeKey === 'database'" />
|
||||
<HostTab v-else-if="activeKey === 'host'" />
|
||||
<!-- <PreTab v-else-if="activeKey === 'pre'" />
|
||||
<PostTab v-else-if="activeKey === 'post'" /> -->
|
||||
<PreAndPostTab v-else-if="activeKey === 'pre' || activeKey === 'post'" :active-type="activeKey" />
|
||||
<div v-else-if="activeKey === 'pre' || activeKey === 'post'" class="h-full">
|
||||
<PreAndPostTab :active-type="activeKey" />
|
||||
</div>
|
||||
|
||||
<AssertTab v-else-if="activeKey === 'assert'" />
|
||||
<template v-for="item in envPluginList" :key="item.pluginId">
|
||||
<PluginTab
|
||||
@ -67,7 +70,7 @@
|
||||
</div>
|
||||
|
||||
<div class="footer" :style="{ width: '100%' }">
|
||||
<a-button @click="handleReset">{{ t('common.cancel') }}</a-button>
|
||||
<a-button :disabled="loading" @click="handleReset">{{ t('common.cancel') }}</a-button>
|
||||
<a-button type="primary" :loading="loading" @click="handleSave">{{ t('common.save') }}</a-button>
|
||||
</div>
|
||||
</div>
|
||||
@ -98,6 +101,7 @@
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'ok'): void;
|
||||
(e: 'resetEnv'): void;
|
||||
}>();
|
||||
|
||||
const activeKey = ref('envParams');
|
||||
@ -186,7 +190,7 @@
|
||||
|
||||
const handleReset = () => {
|
||||
envForm.value?.resetFields();
|
||||
store.initEnvDetail();
|
||||
emit('resetEnv');
|
||||
};
|
||||
|
||||
const handleSave = async () => {
|
||||
@ -256,6 +260,7 @@
|
||||
.content {
|
||||
overflow-y: auto;
|
||||
padding: 0 24px;
|
||||
height: 100%;
|
||||
max-height: calc(100% - 320px);
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
@ -57,8 +57,10 @@
|
||||
</a-spin>
|
||||
</a-spin>
|
||||
<div>
|
||||
<a-button type="secondary">{{ t('system.plugin.pluginCancel') }}</a-button>
|
||||
<a-button class="ml-3" type="primary" @click="confirmHandler">{{ t('common.import') }}</a-button>
|
||||
<a-button type="secondary" @click="handleCancel(false)">{{ t('system.plugin.pluginCancel') }}</a-button>
|
||||
<a-button class="ml-3" type="primary" :loading="confirmLoading" @click="confirmHandler">{{
|
||||
t('common.import')
|
||||
}}</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -102,15 +104,19 @@
|
||||
const confirmHandler = async () => {
|
||||
try {
|
||||
confirmLoading.value = true;
|
||||
const params = {
|
||||
const params: { request: Record<string, any>; fileList: File[] } = {
|
||||
request: { cover: isCover.value },
|
||||
fileList: fileList.value,
|
||||
fileList: fileList.value.map((item: any) => item.file),
|
||||
};
|
||||
if (props.type === EnvAuthTypeEnum.GLOBAL) {
|
||||
await importGlobalParam(params);
|
||||
emit('submit', true);
|
||||
} else if (props.type === EnvAuthTypeEnum.ENVIRONMENT) {
|
||||
await importEnv(params);
|
||||
emit('submit', true);
|
||||
}
|
||||
fileList.value = [];
|
||||
|
||||
Message.success(t('common.importSuccess'));
|
||||
handleCancel(true);
|
||||
} catch (error) {
|
||||
|
@ -222,6 +222,7 @@
|
||||
if (errors) {
|
||||
return;
|
||||
}
|
||||
const { driverId } = form.value;
|
||||
try {
|
||||
const index = store.currentEnvDetailInfo.config.dataSources.findIndex((item: any) => item.id === form.value.id);
|
||||
if (index > -1 && !props.isCopy) {
|
||||
@ -231,12 +232,14 @@
|
||||
...form.value,
|
||||
dataSource: `copy_${form.value.dataSource}`,
|
||||
id: getGenerateId(),
|
||||
driver: driverOption.value.find((item) => item.value === driverId)?.label,
|
||||
};
|
||||
store.currentEnvDetailInfo.config.dataSources.splice(index + 1, 0, insertItem);
|
||||
} else {
|
||||
const dataSourceItem = {
|
||||
...form.value,
|
||||
id: getGenerateId(),
|
||||
driver: driverOption.value.find((item) => item.value === driverId)?.label,
|
||||
};
|
||||
store.currentEnvDetailInfo.config.dataSources.push(dataSourceItem);
|
||||
}
|
||||
|
@ -1,25 +1,32 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="h-full">
|
||||
<a-tabs v-model:active-key="activeTab" lazy-load class="no-content">
|
||||
<a-tab-pane v-for="item of tabList" :key="item.key" :title="item.label"></a-tab-pane>
|
||||
</a-tabs>
|
||||
<a-divider margin="0"></a-divider>
|
||||
<div v-if="activeTab === 'scenarioProcessorConfig'" class="mt-4">
|
||||
<div v-if="activeTab === 'scenarioProcessorConfig'" class="h-[calc(100vh - 100px)] mt-4">
|
||||
<a-alert class="mb-4"> {{ t('project.environmental.sceneAlertDesc') }} </a-alert>
|
||||
<PreTab
|
||||
v-if="props.activeType === 'pre'"
|
||||
:show-associated-scene="showAssociatedScene"
|
||||
:show-pre-post-request="!showAssociatedScene"
|
||||
:active-tab="activeTab"
|
||||
/>
|
||||
<PostTab
|
||||
v-if="props.activeType === 'post'"
|
||||
:show-associated-scene="showAssociatedScene"
|
||||
:show-pre-post-request="!showAssociatedScene"
|
||||
:active-tab="activeTab"
|
||||
/>
|
||||
<a-scrollbar
|
||||
:style="{
|
||||
overflow: 'auto',
|
||||
height: 'calc(100vh - 540px)',
|
||||
}"
|
||||
>
|
||||
<PreTab
|
||||
v-if="props.activeType === 'pre'"
|
||||
:show-associated-scene="showAssociatedScene"
|
||||
:show-pre-post-request="!showAssociatedScene"
|
||||
:active-tab="activeTab"
|
||||
/>
|
||||
<PostTab
|
||||
v-if="props.activeType === 'post'"
|
||||
:show-associated-scene="showAssociatedScene"
|
||||
:show-pre-post-request="!showAssociatedScene"
|
||||
:active-tab="activeTab"
|
||||
/>
|
||||
</a-scrollbar>
|
||||
</div>
|
||||
<div v-if="activeTab === 'requestProcessorConfig'" class="mt-4">
|
||||
<div v-if="activeTab === 'requestProcessorConfig'" class="mt-4 h-full">
|
||||
<a-alert class="mb-4"> {{ t('project.environmental.requestAlertDesc') }} </a-alert>
|
||||
<PreTab
|
||||
v-if="props.activeType === 'pre'"
|
||||
@ -45,7 +52,11 @@
|
||||
import PostTab from './PostTab.vue';
|
||||
import PreTab from './PreTab.vue';
|
||||
|
||||
import { getEnvironment } from '@/api/modules/api-test/common';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useProjectEnvStore from '@/store/modules/setting/useProjectEnvStore';
|
||||
|
||||
const store = useProjectEnvStore();
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
@ -85,6 +96,14 @@
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
const currentEnvConfig = ref({});
|
||||
/** 向孙组件提供属性 */
|
||||
provide('currentEnvConfig', readonly(currentEnvConfig));
|
||||
|
||||
onBeforeMount(() => {
|
||||
currentEnvConfig.value = store.currentEnvDetailInfo.config;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
@ -182,9 +182,13 @@
|
||||
</template>
|
||||
<template #second>
|
||||
<!-- 全局参数 -->
|
||||
<AllParamBox v-if="showType === 'PROJECT' && activeKey === ALL_PARAM" />
|
||||
<AllParamBox v-if="showType === 'PROJECT' && activeKey === ALL_PARAM" ref="globalEnvRef" />
|
||||
<!-- 环境变量 -->
|
||||
<EnvParamBox v-else-if="showType === 'PROJECT' && activeKey !== ALL_PARAM" @ok="initData()" />
|
||||
<EnvParamBox
|
||||
v-else-if="showType === 'PROJECT' && activeKey !== ALL_PARAM"
|
||||
@reset-env="resetHandler"
|
||||
@ok="initData()"
|
||||
/>
|
||||
<!-- 环境组 -->
|
||||
<EnvGroupBox v-else-if="showType === 'PROJECT_GROUP'" @save-or-update="handleUpdateEnvGroup" />
|
||||
</template>
|
||||
@ -197,6 +201,11 @@
|
||||
:default-selected-keys="[]"
|
||||
is-array-column
|
||||
:array-column="envList"
|
||||
:title-props="{
|
||||
selectableTitle: t('project.environmental.env.selectableTitle'),
|
||||
systemTitle: t('project.environmental.env.systemTitle'),
|
||||
selectedTitle: t('project.environmental.env.selectedTitle'),
|
||||
}"
|
||||
@confirm="(v) => handleEnvExport(v.map((item) => item.id))"
|
||||
/>
|
||||
</template>
|
||||
@ -339,13 +348,13 @@
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
const globalEnvRef = ref();
|
||||
const handleSubmit = (shouldSearch: boolean) => {
|
||||
if (shouldSearch) {
|
||||
if (importAuthType.value === EnvAuthTypeEnum.GLOBAL && store.currentId === ALL_PARAM) {
|
||||
store.initEnvDetail();
|
||||
globalEnvRef.value.initEnvDetail();
|
||||
} else if (importAuthType.value === EnvAuthTypeEnum.ENVIRONMENT && store.currentId !== ALL_PARAM) {
|
||||
store.initEnvDetail();
|
||||
globalEnvRef.value.initEnvDetail();
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -358,12 +367,15 @@
|
||||
// 创建环境变量
|
||||
const handleCreateEnv = () => {
|
||||
const tmpArr = envList.value;
|
||||
tmpArr.unshift({
|
||||
id: NEW_ENV_PARAM,
|
||||
name: t('project.environmental.newEnv'),
|
||||
});
|
||||
store.setCurrentId(NEW_ENV_PARAM);
|
||||
envList.value = tmpArr;
|
||||
const unSaveEnv = envList.value.filter((item) => item.id === NEW_ENV_PARAM).length < 1;
|
||||
if (unSaveEnv) {
|
||||
tmpArr.unshift({
|
||||
id: NEW_ENV_PARAM,
|
||||
name: t('project.environmental.newEnv'),
|
||||
});
|
||||
store.setCurrentId(NEW_ENV_PARAM);
|
||||
envList.value = tmpArr;
|
||||
}
|
||||
};
|
||||
// 创建环境组
|
||||
const handleCreateGroup = () => {
|
||||
@ -562,6 +574,21 @@
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
function resetHandler() {
|
||||
const unSaveEnv = envList.value.filter((item) => item.id === NEW_ENV_PARAM).length < 2;
|
||||
// 如果未保存环境存在环境为NEW_ENV_PARAM的id类型
|
||||
if (unSaveEnv) {
|
||||
envList.value = envList.value.filter((item: any) => item.id !== NEW_ENV_PARAM);
|
||||
const excludeMock = envList.value.filter((item) => !item.mock);
|
||||
if (showType.value === 'PROJECT' && !excludeMock.length) {
|
||||
store.setCurrentId(ALL_PARAM);
|
||||
} else if (excludeMock.length) {
|
||||
store.setCurrentId(excludeMock[0].id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
initData(keyword.value, true);
|
||||
});
|
||||
|
@ -3,7 +3,7 @@ export default {
|
||||
'project.environmental.project': 'Project',
|
||||
'project.environmental.envGroup': 'Environmental group',
|
||||
'project.environmental.searchHolder': 'Please enter the environment name',
|
||||
'project.environmental.allParam': 'All Parameters',
|
||||
'project.environmental.allParam': 'Global request header',
|
||||
'project.environmental.env': 'Environment',
|
||||
'project.environmental.envListIsNull': 'No data, please click "+" above to create an environment',
|
||||
'project.environmental.requestHeader': 'Request Header',
|
||||
@ -108,4 +108,7 @@ export default {
|
||||
'project.environmental.cover.enable': 'Enable: Import and cover the environment with the same name',
|
||||
'project.environmental.cover.disable': 'Disable: Import and do not cover the environment with the same name',
|
||||
'project.environmental.ENVIRONMENT': 'Environment',
|
||||
'project.environmental.env.selectableTitle': 'Optional Environments',
|
||||
'project.environmental.env.systemTitle': 'environment',
|
||||
'project.environmental.env.selectedTitle': 'Selected environment',
|
||||
};
|
||||
|
@ -3,11 +3,11 @@ export default {
|
||||
'project.environmental.project': '项目',
|
||||
'project.environmental.envGroup': '环境组',
|
||||
'project.environmental.searchHolder': '请输入环境名称',
|
||||
'project.environmental.allParam': '全局参数',
|
||||
'project.environmental.allParam': '全局请求头',
|
||||
'project.environmental.env': '环境',
|
||||
'project.environmental.envListIsNull': '暂无数据,请点击上方“+”创建环境',
|
||||
'project.environmental.requestHeader': '请求头',
|
||||
'project.environmental.allParams': '全局参数',
|
||||
'project.environmental.allParams': '全局请求',
|
||||
'project.environmental.GLOBAL': '全局参数',
|
||||
'project.environmental.ENVIRONMENT': '环境',
|
||||
'project.environmental.ENVIRONMENT_PARAM': '全局参数',
|
||||
@ -119,4 +119,7 @@ export default {
|
||||
'project.environmental.cover': '覆盖',
|
||||
'project.environmental.cover.enable': '开启: 环境名称重复则覆盖,不重复则新增',
|
||||
'project.environmental.cover.disable': '关闭: 环境名称重复则不导入',
|
||||
'project.environmental.env.selectableTitle': '可选环境',
|
||||
'project.environmental.env.systemTitle': '环境',
|
||||
'project.environmental.env.selectedTitle': '已选环境',
|
||||
};
|
||||
|
@ -519,6 +519,16 @@
|
||||
|
||||
currentFormRules.options = selectOptions;
|
||||
}
|
||||
// 如果为成员需要默认创建人
|
||||
if (item.type === 'MEMBER' || item.type === 'MULTIPLE_MEMBER') {
|
||||
selectOptions = [
|
||||
{
|
||||
label: t('system.organization.creator'),
|
||||
value: 'CREATE_USER',
|
||||
},
|
||||
];
|
||||
currentFormRules.options = selectOptions;
|
||||
}
|
||||
let initValue;
|
||||
if (multipleType.includes(item.type)) {
|
||||
const optionsIds = selectOptions.map((e: any) => e.value);
|
||||
|
Loading…
Reference in New Issue
Block a user