feat(项目管理): 环境管理&模块&前后置组件扩展和参数对接
This commit is contained in:
parent
a2254a9c44
commit
b362fd6a0c
|
@ -424,7 +424,7 @@
|
||||||
const responseRadios = [
|
const responseRadios = [
|
||||||
{ label: 'ms.assertion.jsonPath', value: 'jsonPath' },
|
{ label: 'ms.assertion.jsonPath', value: 'jsonPath' },
|
||||||
{ label: 'ms.assertion.xpath', value: 'xPath' },
|
{ label: 'ms.assertion.xpath', value: 'xPath' },
|
||||||
{ label: 'ms.assertion.document', value: 'document' },
|
// { label: 'ms.assertion.document', value: 'document' },
|
||||||
{ label: 'ms.assertion.regular', value: 'regular' },
|
{ label: 'ms.assertion.regular', value: 'regular' },
|
||||||
{ label: 'ms.assertion.script', value: 'script' },
|
{ label: 'ms.assertion.script', value: 'script' },
|
||||||
];
|
];
|
||||||
|
|
|
@ -246,6 +246,9 @@ export interface ExecuteConditionProcessorCommon {
|
||||||
enable: boolean; // 是否启用
|
enable: boolean; // 是否启用
|
||||||
name?: string; // 条件处理器名称
|
name?: string; // 条件处理器名称
|
||||||
processorType: RequestConditionProcessor;
|
processorType: RequestConditionProcessor;
|
||||||
|
associateScenarioResult?: boolean; // 是否关联场景结果
|
||||||
|
ignoreProtocols: string[]; // 忽略协议
|
||||||
|
beforeStepScript: boolean; // 是否是步骤内前置脚本前
|
||||||
}
|
}
|
||||||
// 执行请求-前后置条件-脚本处理器
|
// 执行请求-前后置条件-脚本处理器
|
||||||
export type ScriptProcessor = ScriptCommonConfig & ExecuteConditionProcessorCommon;
|
export type ScriptProcessor = ScriptCommonConfig & ExecuteConditionProcessorCommon;
|
||||||
|
|
|
@ -101,7 +101,7 @@ export interface SelectedModule {
|
||||||
// 定义-获取环境的模块树参数
|
// 定义-获取环境的模块树参数
|
||||||
export interface ApiDefinitionGetEnvModuleParams {
|
export interface ApiDefinitionGetEnvModuleParams {
|
||||||
projectId: string;
|
projectId: string;
|
||||||
selectedModules: SelectedModule[];
|
selectedModules?: SelectedModule[];
|
||||||
}
|
}
|
||||||
// 环境-模块树
|
// 环境-模块树
|
||||||
export interface EnvModule {
|
export interface EnvModule {
|
||||||
|
|
|
@ -35,6 +35,9 @@ export interface ProcessorConfig {
|
||||||
scenarioProcessorConfig: {
|
scenarioProcessorConfig: {
|
||||||
processors: ExecuteConditionProcessor[];
|
processors: ExecuteConditionProcessor[];
|
||||||
};
|
};
|
||||||
|
requestProcessorConfig: {
|
||||||
|
processors: [];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
export interface AssertionConfig {
|
export interface AssertionConfig {
|
||||||
|
@ -138,5 +141,16 @@ export interface HttpForm {
|
||||||
// pathMatchRule: {
|
// pathMatchRule: {
|
||||||
path: string;
|
path: string;
|
||||||
condition: string;
|
condition: string;
|
||||||
// };
|
moduleId: string[];
|
||||||
|
moduleMatchRule: {
|
||||||
|
modules: {
|
||||||
|
moduleId: string;
|
||||||
|
containChildModule: boolean;
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
url: string;
|
||||||
|
pathMatchRule: {
|
||||||
|
path: '';
|
||||||
|
condition: '';
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,6 +240,7 @@ const useAppStore = defineStore('app', {
|
||||||
async initSystemPackage() {
|
async initSystemPackage() {
|
||||||
try {
|
try {
|
||||||
this.packageType = await getPackageType();
|
this.packageType = await getPackageType();
|
||||||
|
// this.packageType = 'community';
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
|
|
@ -30,18 +30,19 @@ const envParamsDefaultConfig: EnvConfig = {
|
||||||
scenarioProcessorConfig: {
|
scenarioProcessorConfig: {
|
||||||
processors: [],
|
processors: [],
|
||||||
},
|
},
|
||||||
|
requestProcessorConfig: {
|
||||||
|
processors: [],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
// TODO 环境参数问题
|
|
||||||
// apiProcessorConfig: [],
|
|
||||||
},
|
},
|
||||||
postProcessorConfig: {
|
postProcessorConfig: {
|
||||||
// TODO 环境参数问题
|
|
||||||
// apiProcessorConfig: [],
|
|
||||||
apiProcessorConfig: {
|
apiProcessorConfig: {
|
||||||
scenarioProcessorConfig: {
|
scenarioProcessorConfig: {
|
||||||
processors: [],
|
processors: [],
|
||||||
},
|
},
|
||||||
|
requestProcessorConfig: {
|
||||||
|
processors: [],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
assertionConfig: { assertions: [] },
|
assertionConfig: { assertions: [] },
|
||||||
|
|
|
@ -632,3 +632,32 @@ export function customFieldDataToTableData(customFieldData: Record<string, any>[
|
||||||
});
|
});
|
||||||
return tableData;
|
return tableData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取模块树多选节点目标Id对应的name列表
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* 获取模块树多选节点目标Id对应的name列表
|
||||||
|
* @param trees 属性数组
|
||||||
|
* @param targetIds 需要匹配的属性值
|
||||||
|
*/
|
||||||
|
export function findNodeNames<T>(trees: TreeNode<T>[], targetIds: string[]) {
|
||||||
|
const result: string[] = [];
|
||||||
|
// eslint-disable-next-line no-shadow
|
||||||
|
function findNameRecursive(node: TreeNode<T>, targetIds: string[]) {
|
||||||
|
if (targetIds.includes(node.id)) {
|
||||||
|
result.push(node.name);
|
||||||
|
}
|
||||||
|
if (node.children) {
|
||||||
|
node.children.forEach((child) => {
|
||||||
|
findNameRecursive(child, targetIds);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trees.forEach((module) => {
|
||||||
|
findNameRecursive(module, targetIds);
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
|
@ -2,10 +2,58 @@
|
||||||
<div class="condition-content">
|
<div class="condition-content">
|
||||||
<!-- 脚本操作 -->
|
<!-- 脚本操作 -->
|
||||||
<template v-if="condition.processorType === RequestConditionProcessor.SCRIPT">
|
<template v-if="condition.processorType === RequestConditionProcessor.SCRIPT">
|
||||||
<a-radio-group v-model:model-value="condition.enableCommonScript" class="mb-[8px]">
|
<!-- 前后置请求开始 -->
|
||||||
<a-radio :value="false">{{ t('apiTestDebug.manual') }}</a-radio>
|
<div v-if="props.showPrePostRequest" class="mt-4">
|
||||||
<a-radio :value="true">{{ t('apiTestDebug.quote') }}</a-radio>
|
<a-radio-group v-model="condition.beforeStepScript" type="button" size="small" :default-value="true">
|
||||||
</a-radio-group>
|
<a-radio :value="true"> {{ props?.requestRadioTextProps?.pre }} </a-radio>
|
||||||
|
<a-radio :value="false"> {{ props?.requestRadioTextProps?.post }} </a-radio>
|
||||||
|
</a-radio-group>
|
||||||
|
<a-tooltip position="br" :content="t('apiTestDebug.preconditionAssociateResultDesc')">
|
||||||
|
<IconQuestionCircle class="ml-2 h-[16px] w-[16px] text-[--color-text-4] hover:text-[rgb(var(--primary-5))]" />
|
||||||
|
<template #content>
|
||||||
|
<div>{{ props?.requestRadioTextProps?.preTip }}</div>
|
||||||
|
<div>{{ props?.requestRadioTextProps?.postTip }}</div>
|
||||||
|
</template>
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
<div v-if="props.showPrePostRequest" class="my-4">
|
||||||
|
<MsSelect
|
||||||
|
v-model:model-value="condition.ignoreProtocols"
|
||||||
|
:style="{ width: '332px' }"
|
||||||
|
:allow-search="false"
|
||||||
|
allow-clear
|
||||||
|
:options="protocolList"
|
||||||
|
:multiple="true"
|
||||||
|
:has-all-select="true"
|
||||||
|
value-key="protocol"
|
||||||
|
label-key="protocol"
|
||||||
|
:prefix="t('project.environmental.preOrPost.ignoreProtocols')"
|
||||||
|
>
|
||||||
|
</MsSelect>
|
||||||
|
</div>
|
||||||
|
<!-- 前后置请求结束 -->
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<a-radio-group v-model:model-value="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>
|
||||||
|
<div v-if="props.showAssociatedScene" class="flex items-center">
|
||||||
|
<a-switch
|
||||||
|
v-model="condition.associateScenarioResult"
|
||||||
|
class="mr-2"
|
||||||
|
size="small"
|
||||||
|
type="line"
|
||||||
|
@change="emit('change')"
|
||||||
|
/>
|
||||||
|
{{ t('apiTestDebug.preconditionAssociatedSceneResult') }}
|
||||||
|
<a-tooltip position="br" :content="t('apiTestDebug.preconditionAssociateResultDesc')">
|
||||||
|
<IconQuestionCircle
|
||||||
|
class="ml-2 h-[16px] w-[16px] text-[--color-text-4] hover:text-[rgb(var(--primary-5))]"
|
||||||
|
/>
|
||||||
|
</a-tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="!condition.enableCommonScript"
|
v-if="!condition.enableCommonScript"
|
||||||
class="relative flex-1 rounded-[var(--border-radius-small)] bg-[var(--color-text-n9)]"
|
class="relative flex-1 rounded-[var(--border-radius-small)] bg-[var(--color-text-n9)]"
|
||||||
|
@ -358,13 +406,17 @@
|
||||||
import InsertCommonScript from '@/components/business/ms-common-script/insertCommonScript.vue';
|
import InsertCommonScript from '@/components/business/ms-common-script/insertCommonScript.vue';
|
||||||
import AddScriptDrawer from '@/components/business/ms-common-script/ms-addScriptDrawer.vue';
|
import AddScriptDrawer from '@/components/business/ms-common-script/ms-addScriptDrawer.vue';
|
||||||
import MsScriptDefined from '@/components/business/ms-common-script/scriptDefined.vue';
|
import MsScriptDefined from '@/components/business/ms-common-script/scriptDefined.vue';
|
||||||
|
import MsSelect from '@/components/business/ms-select';
|
||||||
import fastExtraction from '../fastExtraction/index.vue';
|
import fastExtraction from '../fastExtraction/index.vue';
|
||||||
import moreSetting from '../fastExtraction/moreSetting.vue';
|
import moreSetting from '../fastExtraction/moreSetting.vue';
|
||||||
import paramTable, { type ParamTableColumn } from '../paramTable.vue';
|
import paramTable, { type ParamTableColumn } from '../paramTable.vue';
|
||||||
import quoteSqlSourceDrawer from '../quoteSqlSourceDrawer.vue';
|
import quoteSqlSourceDrawer from '../quoteSqlSourceDrawer.vue';
|
||||||
|
|
||||||
|
import { getProtocolList } from '@/api/modules/api-test/common';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
import useAppStore from '@/store/modules/app';
|
||||||
|
|
||||||
|
import type { ProtocolItem } from '@/models/apiTest/common';
|
||||||
import { ExecuteConditionProcessor, JSONPathExtract, RegexExtract, XPathExtract } from '@/models/apiTest/common';
|
import { ExecuteConditionProcessor, JSONPathExtract, RegexExtract, XPathExtract } from '@/models/apiTest/common';
|
||||||
import { ParamsRequestType } from '@/models/projectManagement/commonScript';
|
import { ParamsRequestType } from '@/models/projectManagement/commonScript';
|
||||||
import {
|
import {
|
||||||
|
@ -378,13 +430,22 @@
|
||||||
} from '@/enums/apiEnum';
|
} from '@/enums/apiEnum';
|
||||||
|
|
||||||
export type ExpressionConfig = (RegexExtract | JSONPathExtract | XPathExtract) & Record<string, any>;
|
export type ExpressionConfig = (RegexExtract | JSONPathExtract | XPathExtract) & Record<string, any>;
|
||||||
|
const appStore = useAppStore();
|
||||||
const props = defineProps<{
|
const props = withDefaults(
|
||||||
data: ExecuteConditionProcessor;
|
defineProps<{
|
||||||
response?: string; // 响应内容
|
data: ExecuteConditionProcessor;
|
||||||
heightUsed?: number;
|
response?: string; // 响应内容
|
||||||
isBuildIn?: boolean; // 是否是内置的条件
|
heightUsed?: number;
|
||||||
}>();
|
isBuildIn?: boolean; // 是否是内置的条件
|
||||||
|
showAssociatedScene?: boolean; // 是否展示关联场景结果
|
||||||
|
requestRadioTextProps?: Record<string, any>; // 前后置请求前后置按钮文本
|
||||||
|
showPrePostRequest?: boolean; // 是否展示前后置请求忽略
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
showAssociatedScene: false,
|
||||||
|
showPrePostRequest: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:data', data: ExecuteConditionProcessor): void;
|
(e: 'update:data', data: ExecuteConditionProcessor): void;
|
||||||
(e: 'copy'): void;
|
(e: 'copy'): void;
|
||||||
|
@ -732,6 +793,15 @@ if (!result){
|
||||||
});
|
});
|
||||||
emit('change');
|
emit('change');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const protocolList = ref<ProtocolItem[]>([]);
|
||||||
|
onBeforeMount(async () => {
|
||||||
|
try {
|
||||||
|
protocolList.value = await getProtocolList(appStore.currentOrgId);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
|
@ -30,6 +30,9 @@
|
||||||
v-model:data="activeItem"
|
v-model:data="activeItem"
|
||||||
:response="props.response"
|
:response="props.response"
|
||||||
:height-used="props.heightUsed"
|
:height-used="props.heightUsed"
|
||||||
|
:show-associated-scene="props.showAssociatedScene"
|
||||||
|
:show-pre-post-request="props.showPrePostRequest"
|
||||||
|
:request-radio-text-props="props.requestRadioTextProps"
|
||||||
@copy="copyListItem"
|
@copy="copyListItem"
|
||||||
@delete="deleteListItem"
|
@delete="deleteListItem"
|
||||||
@change="emit('change')"
|
@change="emit('change')"
|
||||||
|
@ -48,13 +51,21 @@
|
||||||
import { ConditionType, ExecuteConditionProcessor } from '@/models/apiTest/common';
|
import { ConditionType, ExecuteConditionProcessor } from '@/models/apiTest/common';
|
||||||
import { RequestConditionProcessor } from '@/enums/apiEnum';
|
import { RequestConditionProcessor } from '@/enums/apiEnum';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = withDefaults(
|
||||||
list: ExecuteConditionProcessor[];
|
defineProps<{
|
||||||
conditionTypes: Array<ConditionType>;
|
list: ExecuteConditionProcessor[];
|
||||||
addText: string;
|
conditionTypes: Array<ConditionType>;
|
||||||
heightUsed?: number;
|
addText: string;
|
||||||
response?: string; // 响应内容
|
requestRadioTextProps?: Record<string, any>;
|
||||||
}>();
|
heightUsed?: number;
|
||||||
|
response?: string; // 响应内容
|
||||||
|
showAssociatedScene?: boolean;
|
||||||
|
showPrePostRequest?: boolean; // 是否展示前后置请求忽略选项
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
showAssociatedScene: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:list', list: ExecuteConditionProcessor[]): void;
|
(e: 'update:list', list: ExecuteConditionProcessor[]): void;
|
||||||
(e: 'change'): void;
|
(e: 'change'): void;
|
||||||
|
@ -107,6 +118,9 @@
|
||||||
processorType: RequestConditionProcessor.SCRIPT,
|
processorType: RequestConditionProcessor.SCRIPT,
|
||||||
scriptName: t('apiTestDebug.preconditionScriptName'),
|
scriptName: t('apiTestDebug.preconditionScriptName'),
|
||||||
enableCommonScript: false,
|
enableCommonScript: false,
|
||||||
|
associateScenarioResult: false,
|
||||||
|
ignoreProtocols: [],
|
||||||
|
beforeStepScript: true,
|
||||||
enable: true,
|
enable: true,
|
||||||
script: '',
|
script: '',
|
||||||
scriptId: '',
|
scriptId: '',
|
||||||
|
@ -125,6 +139,9 @@
|
||||||
id,
|
id,
|
||||||
processorType: RequestConditionProcessor.SQL,
|
processorType: RequestConditionProcessor.SQL,
|
||||||
enableCommonScript: false,
|
enableCommonScript: false,
|
||||||
|
associateScenarioResult: false,
|
||||||
|
ignoreProtocols: [],
|
||||||
|
beforeStepScript: true,
|
||||||
description: '',
|
description: '',
|
||||||
enable: true,
|
enable: true,
|
||||||
dataSourceId: '',
|
dataSourceId: '',
|
||||||
|
@ -141,6 +158,9 @@
|
||||||
data.value.push({
|
data.value.push({
|
||||||
id,
|
id,
|
||||||
processorType: RequestConditionProcessor.TIME_WAITING,
|
processorType: RequestConditionProcessor.TIME_WAITING,
|
||||||
|
associateScenarioResult: false,
|
||||||
|
ignoreProtocols: [],
|
||||||
|
beforeStepScript: true,
|
||||||
enable: true,
|
enable: true,
|
||||||
delay: 1000,
|
delay: 1000,
|
||||||
});
|
});
|
||||||
|
@ -149,6 +169,10 @@
|
||||||
data.value.push({
|
data.value.push({
|
||||||
id,
|
id,
|
||||||
processorType: RequestConditionProcessor.EXTRACT,
|
processorType: RequestConditionProcessor.EXTRACT,
|
||||||
|
enableCommonScript: false,
|
||||||
|
associateScenarioResult: false,
|
||||||
|
ignoreProtocols: [],
|
||||||
|
beforeStepScript: true,
|
||||||
enable: true,
|
enable: true,
|
||||||
extractors: [],
|
extractors: [],
|
||||||
});
|
});
|
||||||
|
|
|
@ -70,7 +70,10 @@ export default {
|
||||||
'apiTestDebug.wait': 'Wait',
|
'apiTestDebug.wait': 'Wait',
|
||||||
'apiTestDebug.script': 'Script',
|
'apiTestDebug.script': 'Script',
|
||||||
'apiTestDebug.preconditionScriptName': 'Pre-script name',
|
'apiTestDebug.preconditionScriptName': 'Pre-script name',
|
||||||
|
'apiTestDebug.preconditionAssociatedSceneResult': 'Associated scene result',
|
||||||
'apiTestDebug.preconditionScriptNamePlaceholder': 'Please enter the pre-script name',
|
'apiTestDebug.preconditionScriptNamePlaceholder': 'Please enter the pre-script name',
|
||||||
|
'apiTestDebug.preconditionAssociateResultDesc':
|
||||||
|
'Counted in the scene execution result as a custom script step. Execution error will affect the final scene execution result',
|
||||||
'apiTestDebug.manual': 'Manual entry',
|
'apiTestDebug.manual': 'Manual entry',
|
||||||
'apiTestDebug.quote': 'Quoting public scripts',
|
'apiTestDebug.quote': 'Quoting public scripts',
|
||||||
'apiTestDebug.commonScriptList': 'Public script list',
|
'apiTestDebug.commonScriptList': 'Public script list',
|
||||||
|
|
|
@ -66,7 +66,10 @@ export default {
|
||||||
'apiTestDebug.wait': '等待',
|
'apiTestDebug.wait': '等待',
|
||||||
'apiTestDebug.script': '脚本操作',
|
'apiTestDebug.script': '脚本操作',
|
||||||
'apiTestDebug.preconditionScriptName': '前置脚本名称',
|
'apiTestDebug.preconditionScriptName': '前置脚本名称',
|
||||||
|
'apiTestDebug.preconditionAssociatedSceneResult': '关联场景结果',
|
||||||
'apiTestDebug.preconditionScriptNamePlaceholder': '请输入前置脚本名称',
|
'apiTestDebug.preconditionScriptNamePlaceholder': '请输入前置脚本名称',
|
||||||
|
'apiTestDebug.preconditionAssociateResultDesc':
|
||||||
|
'当作自定义脚本步骤统计到场景执行结果中,执行报错时会影响场景的最终执行结果',
|
||||||
'apiTestDebug.manual': '手动录入',
|
'apiTestDebug.manual': '手动录入',
|
||||||
'apiTestDebug.quote': '引用公共脚本',
|
'apiTestDebug.quote': '引用公共脚本',
|
||||||
'apiTestDebug.commonScriptList': '公共脚本列表',
|
'apiTestDebug.commonScriptList': '公共脚本列表',
|
||||||
|
|
|
@ -39,14 +39,20 @@
|
||||||
<a-tab-pane key="displaySetting" :title="t('project.environmental.displaySetting')" />
|
<a-tab-pane key="displaySetting" :title="t('project.environmental.displaySetting')" />
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
</div>
|
</div>
|
||||||
<a-divider :margin="0" class="!mb-[16px]" />
|
<a-divider
|
||||||
|
:margin="0"
|
||||||
|
:class="{
|
||||||
|
'!mb-[16px]': activeKey === 'pre' || activeKey === 'post' ? false : true,
|
||||||
|
}"
|
||||||
|
/>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<EnvParamsTab v-if="activeKey === 'envParams'" />
|
<EnvParamsTab v-if="activeKey === 'envParams'" />
|
||||||
<HttpTab v-else-if="activeKey === 'http'" />
|
<HttpTab v-else-if="activeKey === 'http'" />
|
||||||
<DataBaseTab v-else-if="activeKey === 'database'" />
|
<DataBaseTab v-else-if="activeKey === 'database'" />
|
||||||
<HostTab v-else-if="activeKey === 'host'" />
|
<HostTab v-else-if="activeKey === 'host'" />
|
||||||
<PreTab v-else-if="activeKey === 'pre'" />
|
<!-- <PreTab v-else-if="activeKey === 'pre'" />
|
||||||
<PostTab v-else-if="activeKey === 'post'" />
|
<PostTab v-else-if="activeKey === 'post'" /> -->
|
||||||
|
<PreAndPostTab v-else-if="activeKey === 'pre' || activeKey === 'post'" :active-type="activeKey" />
|
||||||
<AssertTab v-else-if="activeKey === 'assert'" />
|
<AssertTab v-else-if="activeKey === 'assert'" />
|
||||||
<template v-for="item in envPluginList" :key="item.pluginId">
|
<template v-for="item in envPluginList" :key="item.pluginId">
|
||||||
<PluginTab
|
<PluginTab
|
||||||
|
@ -80,6 +86,7 @@
|
||||||
import HttpTab from './envParams/HttpTab.vue';
|
import HttpTab from './envParams/HttpTab.vue';
|
||||||
import PluginTab from './envParams/PluginTab.vue';
|
import PluginTab from './envParams/PluginTab.vue';
|
||||||
import PostTab from './envParams/PostTab.vue';
|
import PostTab from './envParams/PostTab.vue';
|
||||||
|
import PreAndPostTab from './envParams/preAndPost.vue';
|
||||||
import PreTab from './envParams/PreTab.vue';
|
import PreTab from './envParams/PreTab.vue';
|
||||||
|
|
||||||
import { getEnvPlugin, updateOrAddEnv } from '@/api/modules/project-management/envManagement';
|
import { getEnvPlugin, updateOrAddEnv } from '@/api/modules/project-management/envManagement';
|
||||||
|
|
|
@ -4,34 +4,64 @@
|
||||||
<a-switch v-model:model-value="currentList.enable" type="line" size="small" />
|
<a-switch v-model:model-value="currentList.enable" type="line" size="small" />
|
||||||
<div class="text-[var(--color-text-1)]">{{ t('project.environmental.host.config') }}</div>
|
<div class="text-[var(--color-text-1)]">{{ t('project.environmental.host.config') }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-[8px]">
|
<!-- <a-radio-group v-model:model-value="addType" class="mt-[16px]" size="small" type="button">
|
||||||
|
<a-radio value="single">单个添加</a-radio>
|
||||||
|
<a-radio value="multiple">批量添加</a-radio>
|
||||||
|
</a-radio-group> -->
|
||||||
|
<div v-show="addType === 'single'" class="mt-[8px]">
|
||||||
<MsBatchForm
|
<MsBatchForm
|
||||||
ref="batchFormRef"
|
ref="batchFormRef"
|
||||||
:models="batchFormModels"
|
:models="batchFormModels"
|
||||||
:form-mode="ruleFormMode"
|
:form-mode="ruleFormMode"
|
||||||
add-text="project.menu.rule.addRule"
|
add-text="project.menu.rule.addRule"
|
||||||
:default-vals="currentList.hosts"
|
:default-vals="currentList.hosts"
|
||||||
show-enable
|
:show-enable="false"
|
||||||
:is-show-drag="false"
|
:is-show-drag="false"
|
||||||
></MsBatchForm>
|
></MsBatchForm>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- <div v-show="addType === 'multiple'">
|
||||||
|
<MsCodeEditor
|
||||||
|
v-model:model-value="editorContent"
|
||||||
|
width="100%"
|
||||||
|
height="250px"
|
||||||
|
theme="MS-text"
|
||||||
|
:show-theme-change="false"
|
||||||
|
>
|
||||||
|
<template #leftTitle>
|
||||||
|
<a-form-item
|
||||||
|
:label="t('system.resourcePool.batchAddResource')"
|
||||||
|
asterisk-position="end"
|
||||||
|
class="hide-wrapper mb-0 w-auto"
|
||||||
|
required
|
||||||
|
>
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
</MsCodeEditor>
|
||||||
|
<div class="mb-[24px] text-[12px] leading-[16px] text-[var(--color-text-4)]">
|
||||||
|
{{ t('system.resourcePool.nodeConfigEditorTip') }}
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onClickOutside } from '@vueuse/core';
|
import { onClickOutside } from '@vueuse/core';
|
||||||
|
import { debounce } from 'lodash-es';
|
||||||
|
|
||||||
|
import MsCodeEditor from '@/components/pure/ms-code-editor/index.vue';
|
||||||
import MsBatchForm from '@/components/business/ms-batch-form/index.vue';
|
import MsBatchForm from '@/components/business/ms-batch-form/index.vue';
|
||||||
import { FormItemModel } from '@/components/business/ms-batch-form/types';
|
import { FormItemModel } from '@/components/business/ms-batch-form/types';
|
||||||
|
|
||||||
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 { getGenerateId } from '@/utils';
|
||||||
|
|
||||||
import { EnvConfigItem } from '@/models/projectManagement/environmental';
|
import { EnvConfigItem } from '@/models/projectManagement/environmental';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const store = useProjectEnvStore();
|
const store = useProjectEnvStore();
|
||||||
|
const addType = ref<string>('single');
|
||||||
|
|
||||||
const currentList = computed({
|
const currentList = computed({
|
||||||
get: () => store.currentEnvDetailInfo.config.hostConfig || {},
|
get: () => store.currentEnvDetailInfo.config.hostConfig || {},
|
||||||
|
@ -56,20 +86,58 @@
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filed: 'hostName',
|
filed: 'domain',
|
||||||
type: 'input',
|
type: 'input',
|
||||||
label: 'project.environmental.host.hostName',
|
label: 'project.environmental.host.hostName',
|
||||||
placeholder: 'project.environmental.host.hostNamePlaceholder',
|
placeholder: 'project.environmental.host.hostNamePlaceholder',
|
||||||
rules: [{ required: true, message: t('project.environmental.host.hostNameIsRequire') }],
|
rules: [{ required: true, message: t('project.environmental.host.hostNameIsRequire') }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filed: 'desc',
|
filed: 'description',
|
||||||
type: 'input',
|
type: 'input',
|
||||||
label: 'project.environmental.host.desc',
|
label: 'project.environmental.host.desc',
|
||||||
placeholder: 'project.environmental.host.descPlaceholder',
|
placeholder: 'project.environmental.host.descPlaceholder',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
const ruleFormMode = ref<UserModalMode>('create');
|
const ruleFormMode = ref<UserModalMode>('create');
|
||||||
|
|
||||||
|
// 代码编辑器内容
|
||||||
|
const editorContent = ref('');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析代码编辑器内容
|
||||||
|
*/
|
||||||
|
function analyzeCode() {
|
||||||
|
const arr = editorContent.value.replaceAll('\r', '\n').split('\n'); // 先将回车符替换成换行符,避免粘贴的代码是以回车符分割的,然后以换行符分割
|
||||||
|
// 将代码编辑器内写的内容抽取出来
|
||||||
|
arr.forEach((e, i) => {
|
||||||
|
if (e.trim() !== '') {
|
||||||
|
// 排除空串
|
||||||
|
const line = e.split(',');
|
||||||
|
if (line.every((s) => s.trim() !== '')) {
|
||||||
|
const item = {
|
||||||
|
ip: line[0],
|
||||||
|
domain: line[1],
|
||||||
|
};
|
||||||
|
if (i === 0) {
|
||||||
|
// 第四个是concurrentNumber,需要是数字
|
||||||
|
currentList.value = [item];
|
||||||
|
} else {
|
||||||
|
currentList.value.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => editorContent.value,
|
||||||
|
(val) => {
|
||||||
|
if (val) {
|
||||||
|
debounce(analyzeCode, 300);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped></style>
|
<style lang="less" scoped></style>
|
||||||
|
|
|
@ -18,20 +18,26 @@
|
||||||
<span class="text-[var(--color-text-3)]">{{ t('project.environmental.http.linkTimeOut') }}</span>
|
<span class="text-[var(--color-text-3)]">{{ t('project.environmental.http.linkTimeOut') }}</span>
|
||||||
</template>
|
</template>
|
||||||
</a-input-number>
|
</a-input-number>
|
||||||
<a-select v-model:model-value="form.authType" class="w-[200px]">
|
<!-- TOTO 第一个版本不做 -->
|
||||||
|
<!-- <a-select v-model:model-value="form.authType" class="w-[200px]">
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<span class="text-[var(--color-text-3)]">{{ t('project.environmental.http.authType') }}</span>
|
<span class="text-[var(--color-text-3)]">{{ t('project.environmental.http.authType') }}</span>
|
||||||
</template>
|
</template>
|
||||||
<a-option>Basic Auth</a-option>
|
<a-option>Basic Auth</a-option>
|
||||||
<a-option>Basic Auth2</a-option>
|
<a-option>Basic Auth2</a-option>
|
||||||
<a-option>Basic Auth3</a-option>
|
<a-option>Basic Auth3</a-option>
|
||||||
</a-select>
|
</a-select> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<MsBaseTable class="mt-[16px]" v-bind="propsRes" v-on="propsEvent" @change="changeHandler">
|
<MsBaseTable class="mt-[16px]" v-bind="propsRes" v-on="propsEvent" @change="changeHandler">
|
||||||
<template #type="{ record }">
|
<template #type="{ record }">
|
||||||
<span>{{ getEnableScope(record.type) }}</span>
|
<span>{{ getEnableScope(record.type) }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
<template #moduleValue="{ record }">
|
||||||
|
<a-tooltip :content="getModuleName(record)" position="left">
|
||||||
|
<span class="one-line-text max-w-[300px]">{{ getModuleName(record) }}</span>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
<template #operation="{ record }">
|
<template #operation="{ record }">
|
||||||
<div class="flex flex-row flex-nowrap items-center">
|
<div class="flex flex-row flex-nowrap items-center">
|
||||||
<MsButton class="!mr-0" @click="handleCopy(record)">{{ t('common.copy') }}</MsButton>
|
<MsButton class="!mr-0" @click="handleCopy(record)">{{ t('common.copy') }}</MsButton>
|
||||||
|
@ -42,7 +48,13 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</MsBaseTable>
|
</MsBaseTable>
|
||||||
<AddHttpDrawer v-model:visible="addVisible" :is-copy="isCopy" :current-id="httpId" @close="addVisible = false" />
|
<AddHttpDrawer
|
||||||
|
v-model:visible="addVisible"
|
||||||
|
:module-tree="moduleTree"
|
||||||
|
:is-copy="isCopy"
|
||||||
|
:current-id="httpId"
|
||||||
|
@close="addVisible = false"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" async setup>
|
<script lang="ts" async setup>
|
||||||
|
@ -56,15 +68,19 @@
|
||||||
import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
||||||
import AddHttpDrawer from './popUp/AddHttpDrawer.vue';
|
import AddHttpDrawer from './popUp/AddHttpDrawer.vue';
|
||||||
|
|
||||||
|
import { getEnvModules } from '@/api/modules/api-test/management';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import { useTableStore } from '@/store';
|
import { useAppStore, useTableStore } from '@/store';
|
||||||
import useProjectEnvStore from '@/store/modules/setting/useProjectEnvStore';
|
import useProjectEnvStore from '@/store/modules/setting/useProjectEnvStore';
|
||||||
|
import { findNodeNames } from '@/utils';
|
||||||
|
|
||||||
import { BugListItem } from '@/models/bug-management';
|
import { BugListItem } from '@/models/bug-management';
|
||||||
|
import type { ModuleTreeNode } from '@/models/common';
|
||||||
import type { CommonParams } from '@/models/projectManagement/environmental';
|
import type { CommonParams } from '@/models/projectManagement/environmental';
|
||||||
import { HttpForm } from '@/models/projectManagement/environmental';
|
import { HttpForm } from '@/models/projectManagement/environmental';
|
||||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||||
|
|
||||||
|
const appStore = useAppStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const store = useProjectEnvStore();
|
const store = useProjectEnvStore();
|
||||||
|
@ -97,7 +113,8 @@
|
||||||
{
|
{
|
||||||
title: 'project.environmental.http.value',
|
title: 'project.environmental.http.value',
|
||||||
dataIndex: 'value',
|
dataIndex: 'value',
|
||||||
showTooltip: true,
|
slotName: 'moduleValue',
|
||||||
|
showTooltip: false,
|
||||||
showDrag: true,
|
showDrag: true,
|
||||||
showInTable: true,
|
showInTable: true,
|
||||||
},
|
},
|
||||||
|
@ -223,6 +240,27 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const moduleTree = ref<ModuleTreeNode[]>([]);
|
||||||
|
async function initModuleTree() {
|
||||||
|
try {
|
||||||
|
const res = await getEnvModules({
|
||||||
|
projectId: appStore.currentProjectId,
|
||||||
|
});
|
||||||
|
moduleTree.value = res.moduleTree;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await initModuleTree();
|
||||||
|
|
||||||
|
function getModuleName(record: HttpForm) {
|
||||||
|
if (record.type === 'MODULE') {
|
||||||
|
const moduleIds: string[] = record.moduleMatchRule.modules.map((item) => item.moduleId);
|
||||||
|
const result = findNodeNames(moduleTree.value, moduleIds);
|
||||||
|
return result.join(',');
|
||||||
|
}
|
||||||
|
return '-';
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
add-text="apiTestDebug.postCondition"
|
add-text="apiTestDebug.postCondition"
|
||||||
response=""
|
response=""
|
||||||
:height-used="600"
|
:height-used="600"
|
||||||
|
:show-associated-scene="props.showAssociatedScene"
|
||||||
|
:show-pre-post-request="props.showPrePostRequest"
|
||||||
|
:request-radio-text-props="props.requestRadioTextProps"
|
||||||
>
|
>
|
||||||
</condition>
|
</condition>
|
||||||
</template>
|
</template>
|
||||||
|
@ -16,14 +19,35 @@
|
||||||
|
|
||||||
import { RequestConditionProcessor } from '@/enums/apiEnum';
|
import { RequestConditionProcessor } from '@/enums/apiEnum';
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
showAssociatedScene?: boolean;
|
||||||
|
showPrePostRequest?: boolean;
|
||||||
|
requestRadioTextProps?: Record<string, any>;
|
||||||
|
activeTab: string;
|
||||||
|
}>();
|
||||||
|
|
||||||
const store = useProjectEnvStore();
|
const store = useProjectEnvStore();
|
||||||
const innerParams = computed({
|
const innerParams = computed({
|
||||||
set: (value: any) => {
|
set: (value: any) => {
|
||||||
store.currentEnvDetailInfo.config.postProcessorConfig.apiProcessorConfig.scenarioProcessorConfig.processors =
|
if (props.activeTab === 'scenarioProcessorConfig') {
|
||||||
value || [];
|
store.currentEnvDetailInfo.config.postProcessorConfig.apiProcessorConfig.scenarioProcessorConfig.processors =
|
||||||
|
value || [];
|
||||||
|
} else {
|
||||||
|
store.currentEnvDetailInfo.config.postProcessorConfig.apiProcessorConfig.requestProcessorConfig.processors =
|
||||||
|
value || [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: () => {
|
||||||
|
if (props.activeTab === 'scenarioProcessorConfig') {
|
||||||
|
return (
|
||||||
|
store.currentEnvDetailInfo.config.postProcessorConfig.apiProcessorConfig.scenarioProcessorConfig.processors ||
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
store.currentEnvDetailInfo.config.postProcessorConfig.apiProcessorConfig.requestProcessorConfig.processors || []
|
||||||
|
);
|
||||||
},
|
},
|
||||||
get: () =>
|
|
||||||
store.currentEnvDetailInfo.config.postProcessorConfig.apiProcessorConfig.scenarioProcessorConfig.processors || [],
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
add-text="apiTestDebug.precondition"
|
add-text="apiTestDebug.precondition"
|
||||||
response=""
|
response=""
|
||||||
:height-used="600"
|
:height-used="600"
|
||||||
|
:show-associated-scene="props.showAssociatedScene"
|
||||||
|
:show-pre-post-request="props.showPrePostRequest"
|
||||||
|
:request-radio-text-props="props.requestRadioTextProps"
|
||||||
>
|
>
|
||||||
</condition>
|
</condition>
|
||||||
</template>
|
</template>
|
||||||
|
@ -16,14 +19,35 @@
|
||||||
|
|
||||||
import { RequestConditionProcessor } from '@/enums/apiEnum';
|
import { RequestConditionProcessor } from '@/enums/apiEnum';
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
showAssociatedScene?: boolean;
|
||||||
|
showPrePostRequest?: boolean;
|
||||||
|
requestRadioTextProps?: Record<string, any>;
|
||||||
|
activeTab: string;
|
||||||
|
}>();
|
||||||
|
|
||||||
const store = useProjectEnvStore();
|
const store = useProjectEnvStore();
|
||||||
const innerParams = computed({
|
const innerParams = computed({
|
||||||
set: (value: any) => {
|
set: (value: any) => {
|
||||||
store.currentEnvDetailInfo.config.preProcessorConfig.apiProcessorConfig.scenarioProcessorConfig.processors =
|
if (props.activeTab === 'scenarioProcessorConfig') {
|
||||||
value || [];
|
store.currentEnvDetailInfo.config.preProcessorConfig.apiProcessorConfig.scenarioProcessorConfig.processors =
|
||||||
|
value || [];
|
||||||
|
} else {
|
||||||
|
store.currentEnvDetailInfo.config.preProcessorConfig.apiProcessorConfig.requestProcessorConfig.processors =
|
||||||
|
value || [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: () => {
|
||||||
|
if (props.activeTab === 'scenarioProcessorConfig') {
|
||||||
|
return (
|
||||||
|
store.currentEnvDetailInfo.config.preProcessorConfig.apiProcessorConfig.scenarioProcessorConfig.processors ||
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
store.currentEnvDetailInfo.config.preProcessorConfig.apiProcessorConfig.requestProcessorConfig.processors || []
|
||||||
|
);
|
||||||
},
|
},
|
||||||
get: () =>
|
|
||||||
store.currentEnvDetailInfo.config.preProcessorConfig.apiProcessorConfig.scenarioProcessorConfig.processors || [],
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<a-form-item
|
<a-form-item
|
||||||
class="mb-[16px]"
|
class="mb-[16px]"
|
||||||
asterisk-position="end"
|
asterisk-position="end"
|
||||||
field="hostname"
|
field="url"
|
||||||
:label="t('project.environmental.http.hostName')"
|
:label="t('project.environmental.http.hostName')"
|
||||||
:rules="[{ required: true, message: t('project.environmental.http.hostNameRequired') }]"
|
:rules="[{ required: true, message: t('project.environmental.http.hostNameRequired') }]"
|
||||||
>
|
>
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
<a-option value="https">https://</a-option>
|
<a-option value="https">https://</a-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
<a-input
|
<a-input
|
||||||
v-model="form.hostname"
|
v-model="form.url"
|
||||||
class="w-full"
|
class="w-full"
|
||||||
:max-length="255"
|
:max-length="255"
|
||||||
:placeholder="
|
:placeholder="
|
||||||
|
@ -85,8 +85,14 @@
|
||||||
</a-form-item> -->
|
</a-form-item> -->
|
||||||
<!-- 展示模块 -->
|
<!-- 展示模块 -->
|
||||||
<!-- TODO 模块还没有加 -->
|
<!-- TODO 模块还没有加 -->
|
||||||
<!-- <a-form-item class="mb-[16px]" field="description" :label="t('project.environmental.http.selectApiModule')">
|
<a-form-item
|
||||||
<ApiTree
|
v-if="form.type === 'MODULE'"
|
||||||
|
class="mb-[16px]"
|
||||||
|
field="description"
|
||||||
|
:label="t('project.environmental.http.selectApiModule')"
|
||||||
|
>
|
||||||
|
<!-- TODO 先做普通树 放在下一个版本 -->
|
||||||
|
<!-- <ApiTree
|
||||||
v-model:focus-node-key="focusNodeKey"
|
v-model:focus-node-key="focusNodeKey"
|
||||||
:placeholder="t('project.environmental.http.selectApiModule')"
|
:placeholder="t('project.environmental.http.selectApiModule')"
|
||||||
:selected-keys="selectedKeys"
|
:selected-keys="selectedKeys"
|
||||||
|
@ -108,8 +114,25 @@
|
||||||
<template #tree-slot-extra="nodeData">
|
<template #tree-slot-extra="nodeData">
|
||||||
<span><MsTableMoreAction :list="moreActions" @select="handleMoreActionSelect($event, nodeData)" /></span>
|
<span><MsTableMoreAction :list="moreActions" @select="handleMoreActionSelect($event, nodeData)" /></span>
|
||||||
</template>
|
</template>
|
||||||
</ApiTree>
|
</ApiTree> -->
|
||||||
</a-form-item> -->
|
<a-tree-select
|
||||||
|
v-model="form.moduleId"
|
||||||
|
:data="envTree"
|
||||||
|
class="w-full"
|
||||||
|
:tree-checkable="true"
|
||||||
|
:allow-search="true"
|
||||||
|
:field-names="{
|
||||||
|
title: 'name',
|
||||||
|
key: 'id',
|
||||||
|
children: 'children',
|
||||||
|
}"
|
||||||
|
:tree-props="{
|
||||||
|
virtualListProps: {
|
||||||
|
height: 200,
|
||||||
|
},
|
||||||
|
}"
|
||||||
|
></a-tree-select>
|
||||||
|
</a-form-item>
|
||||||
<!-- 路径 -->
|
<!-- 路径 -->
|
||||||
<a-form-item
|
<a-form-item
|
||||||
v-if="showPathInput"
|
v-if="showPathInput"
|
||||||
|
@ -142,21 +165,26 @@
|
||||||
import MsDrawer from '@/components/pure/ms-drawer/index.vue';
|
import MsDrawer from '@/components/pure/ms-drawer/index.vue';
|
||||||
import MsTableMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
import MsTableMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
||||||
import type { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
import type { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
||||||
import type { MsTreeFieldNames, MsTreeNodeData, MsTreeSelectedData } from '@/components/business/ms-tree/types';
|
import type { MsTreeNodeData } from '@/components/business/ms-tree/types';
|
||||||
import RequestHeader from '../../requestHeader/index.vue';
|
import RequestHeader from '../../requestHeader/index.vue';
|
||||||
|
|
||||||
|
import { getEnvModules } from '@/api/modules/api-test/management';
|
||||||
// import ApiTree from './apiTree.vue';
|
// import ApiTree from './apiTree.vue';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
import { useAppStore } from '@/store';
|
||||||
import useProjectEnvStore from '@/store/modules/setting/useProjectEnvStore';
|
import useProjectEnvStore from '@/store/modules/setting/useProjectEnvStore';
|
||||||
import { getGenerateId } from '@/utils';
|
import { getGenerateId } from '@/utils';
|
||||||
|
|
||||||
|
import type { EnvModule } from '@/models/apiTest/management';
|
||||||
|
import type { ModuleTreeNode } from '@/models/common';
|
||||||
import { HttpForm } from '@/models/projectManagement/environmental';
|
import { HttpForm } from '@/models/projectManagement/environmental';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
currentId: string;
|
currentId: string;
|
||||||
isCopy: boolean;
|
isCopy: boolean;
|
||||||
|
moduleTree: ModuleTreeNode[];
|
||||||
}>();
|
}>();
|
||||||
|
const appStore = useAppStore();
|
||||||
const store = useProjectEnvStore();
|
const store = useProjectEnvStore();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
|
@ -174,7 +202,7 @@
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const initForm = {
|
const initForm: HttpForm = {
|
||||||
id: '',
|
id: '',
|
||||||
hostname: '',
|
hostname: '',
|
||||||
type: 'NONE',
|
type: 'NONE',
|
||||||
|
@ -182,7 +210,21 @@
|
||||||
path: '',
|
path: '',
|
||||||
condition: 'CONTAINS',
|
condition: 'CONTAINS',
|
||||||
description: '',
|
description: '',
|
||||||
|
url: '',
|
||||||
protocol: 'http',
|
protocol: 'http',
|
||||||
|
moduleId: [],
|
||||||
|
moduleMatchRule: {
|
||||||
|
modules: [
|
||||||
|
// {
|
||||||
|
// moduleId: '',
|
||||||
|
// containChildModule: false,
|
||||||
|
// },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
pathMatchRule: {
|
||||||
|
path: '',
|
||||||
|
condition: '',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const form = ref<HttpForm>({ ...initForm });
|
const form = ref<HttpForm>({ ...initForm });
|
||||||
|
@ -202,437 +244,59 @@
|
||||||
|
|
||||||
const handleAddOrUpdate = () => {
|
const handleAddOrUpdate = () => {
|
||||||
const index = store.currentEnvDetailInfo.config.httpConfig.findIndex((item) => item.id === form.value.id);
|
const index = store.currentEnvDetailInfo.config.httpConfig.findIndex((item) => item.id === form.value.id);
|
||||||
|
let modules: { moduleId: string; containChildModule: boolean }[] = [];
|
||||||
|
const { protocol, url, condition, path } = form.value;
|
||||||
|
if (form.value.type === 'MODULE') {
|
||||||
|
modules = form.value.moduleId.map((item) => {
|
||||||
|
return {
|
||||||
|
moduleId: item,
|
||||||
|
containChildModule: false,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 编辑
|
// 编辑
|
||||||
if (index > -1 && !props.isCopy) {
|
if (index > -1 && !props.isCopy) {
|
||||||
store.currentEnvDetailInfo.config.httpConfig.splice(index + 1, 1, form.value);
|
const httpItem = {
|
||||||
|
...form.value,
|
||||||
|
hostname: `${protocol}:${url}`,
|
||||||
|
pathMatchRule: {
|
||||||
|
path,
|
||||||
|
condition,
|
||||||
|
},
|
||||||
|
order: store.currentEnvDetailInfo.config.httpConfig.length + 1,
|
||||||
|
moduleMatchRule: { modules },
|
||||||
|
};
|
||||||
|
store.currentEnvDetailInfo.config.httpConfig.splice(index, 1, httpItem);
|
||||||
// 复制
|
// 复制
|
||||||
} else if (index > -1 && props.isCopy) {
|
} else if (index > -1 && props.isCopy) {
|
||||||
const insertItem = {
|
const insertItem = {
|
||||||
...form.value,
|
...form.value,
|
||||||
id: getGenerateId(),
|
id: getGenerateId(),
|
||||||
hostname: `copy_${form.value.hostname}`,
|
hostname: `${protocol}:${url}`,
|
||||||
order: store.currentEnvDetailInfo.config.httpConfig.length + 1,
|
order: store.currentEnvDetailInfo.config.httpConfig.length + 1,
|
||||||
|
moduleMatchRule: { modules },
|
||||||
};
|
};
|
||||||
store.currentEnvDetailInfo.config.httpConfig.splice(index, 0, insertItem);
|
store.currentEnvDetailInfo.config.httpConfig.splice(index + 1, 0, insertItem);
|
||||||
// 添加
|
// 添加
|
||||||
} else {
|
} else {
|
||||||
const { protocol, hostname, condition, path } = form.value;
|
|
||||||
const httpItem = {
|
const httpItem = {
|
||||||
...form.value,
|
...form.value,
|
||||||
hostname: `${protocol}://${hostname}`,
|
hostname: `${protocol}://${url}`,
|
||||||
pathMatchRule: {
|
pathMatchRule: {
|
||||||
path,
|
path,
|
||||||
condition,
|
condition,
|
||||||
},
|
},
|
||||||
id: getGenerateId(),
|
id: getGenerateId(),
|
||||||
order: store.currentEnvDetailInfo.config.httpConfig.length + 1,
|
order: store.currentEnvDetailInfo.config.httpConfig.length + 1,
|
||||||
|
moduleMatchRule: { modules },
|
||||||
};
|
};
|
||||||
store.currentEnvDetailInfo.config.httpConfig.push(httpItem);
|
store.currentEnvDetailInfo.config.httpConfig.push(httpItem);
|
||||||
}
|
}
|
||||||
emit('close');
|
emit('close');
|
||||||
};
|
};
|
||||||
|
|
||||||
const moduleTree = ref([
|
const envTree = ref<ModuleTreeNode[]>([]);
|
||||||
{
|
|
||||||
id: 'root',
|
|
||||||
name: '未规划请求',
|
|
||||||
type: 'MODULE',
|
|
||||||
parentId: 'NONE',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
id: '4112912223068160',
|
|
||||||
name: '随便写的',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'HTTP',
|
|
||||||
method: 'OPTIONS',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '1150192243335168',
|
|
||||||
name: '文件儿',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'HTTP',
|
|
||||||
method: 'GET',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '1165379247169536',
|
|
||||||
name: '901',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'TCP',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '1165705664684032',
|
|
||||||
name: '888',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'TCP',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '2125544956010496',
|
|
||||||
name: '0129-1',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'SPX',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '2126988065021952',
|
|
||||||
name: '0129-2',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'SPX',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '2171827523477504',
|
|
||||||
name: 'fffggg',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'HTTP',
|
|
||||||
method: 'GET',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '2297223388766208',
|
|
||||||
name: '0129-3',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'SPX',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '4034709458542592',
|
|
||||||
name: '测试一下百度',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'HTTP',
|
|
||||||
method: 'PATCH',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '1017890070175744',
|
|
||||||
name: 'TTTTTCCCCCPPPPP',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'TCP',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '864679996792832',
|
|
||||||
name: '委托',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'SPX',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '867463135600640',
|
|
||||||
name: '登入',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'SPX',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '868236229713920',
|
|
||||||
name: '买入',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'SPX',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '927008562290689',
|
|
||||||
name: '账号校验1',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'SPX',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '943707395039232',
|
|
||||||
name: 'ddd',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'TCP',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '1068845561815040',
|
|
||||||
name: 'TCP测试2',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'TCP',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '1131706704060416',
|
|
||||||
name: 'aaa',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'HTTP',
|
|
||||||
method: 'GET',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '921184586637312',
|
|
||||||
name: '读取系统日期22',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'SPX',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '642853526609920',
|
|
||||||
name: 'Test',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'HTTP',
|
|
||||||
method: 'GET',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '851760736174080',
|
|
||||||
name: 'dd',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'HTTP',
|
|
||||||
method: 'GET',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '853891039952896',
|
|
||||||
name: 'fasdfd',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'HTTP',
|
|
||||||
method: 'GET',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '1118186147643392',
|
|
||||||
name: 'eeee',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'HTTP',
|
|
||||||
method: 'GET',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '1120161832599552',
|
|
||||||
name: 'eeeeqqq',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'HTTP',
|
|
||||||
method: 'GET',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '1162149432885248',
|
|
||||||
name: 'a',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'HTTP',
|
|
||||||
method: 'GET',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '1177147458682880',
|
|
||||||
name: '这是Curl导入的请求',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'HTTP',
|
|
||||||
method: 'GET',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '2226957725106176',
|
|
||||||
name: 'test12',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'HTTP',
|
|
||||||
method: 'GET',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '2601169635672064',
|
|
||||||
name: 'testvvvv',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'HTTP',
|
|
||||||
method: 'GET',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '885467640184832',
|
|
||||||
name: 'okko',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'HTTP',
|
|
||||||
method: 'GET',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '891635213221888',
|
|
||||||
name: 'gs',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'HTTP',
|
|
||||||
method: 'GET',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '640018849742848',
|
|
||||||
name: '0228',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'SPX',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '2178166898065408',
|
|
||||||
name: '0304',
|
|
||||||
type: 'API',
|
|
||||||
parentId: 'root',
|
|
||||||
children: [],
|
|
||||||
attachInfo: {
|
|
||||||
protocol: 'SPX',
|
|
||||||
},
|
|
||||||
count: 0,
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
attachInfo: {},
|
|
||||||
count: 0,
|
|
||||||
path: '/未规划请求',
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
const moreActions: ActionsItem[] = [
|
const moreActions: ActionsItem[] = [
|
||||||
{
|
{
|
||||||
|
@ -654,14 +318,35 @@
|
||||||
(item) => item.id === props.currentId
|
(item) => item.id === props.currentId
|
||||||
) as HttpForm;
|
) as HttpForm;
|
||||||
if (currentItem) {
|
if (currentItem) {
|
||||||
|
const { path, condition } = currentItem.pathMatchRule;
|
||||||
|
const urlPath = currentItem.hostname.match(/\/\/(.*)/);
|
||||||
form.value = {
|
form.value = {
|
||||||
...currentItem,
|
...currentItem,
|
||||||
|
moduleId: currentItem.moduleMatchRule.modules.map((item) => item.moduleId) || [],
|
||||||
|
path,
|
||||||
|
condition,
|
||||||
|
url: urlPath && urlPath?.length > 1 ? `//${urlPath[1]}` : '',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
resetForm();
|
resetForm();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function initModuleTree() {
|
||||||
|
try {
|
||||||
|
const res = await getEnvModules({
|
||||||
|
projectId: appStore.currentProjectId,
|
||||||
|
});
|
||||||
|
envTree.value = res.moduleTree;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onBeforeMount(() => {
|
||||||
|
initModuleTree();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<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">
|
||||||
|
<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"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-if="activeTab === 'requestProcessorConfig'" class="mt-4">
|
||||||
|
<a-alert class="mb-4"> {{ t('project.environmental.requestAlertDesc') }} </a-alert>
|
||||||
|
<PreTab
|
||||||
|
v-if="props.activeType === 'pre'"
|
||||||
|
:show-associated-scene="showAssociatedScene"
|
||||||
|
:show-pre-post-request="!showAssociatedScene"
|
||||||
|
:request-radio-text-props="requestPropsText"
|
||||||
|
:active-tab="activeTab"
|
||||||
|
/>
|
||||||
|
<PostTab
|
||||||
|
v-if="props.activeType === 'post'"
|
||||||
|
:show-associated-scene="showAssociatedScene"
|
||||||
|
:show-pre-post-request="!showAssociatedScene"
|
||||||
|
:request-radio-text-props="requestPropsText"
|
||||||
|
:active-tab="activeTab"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
import PostTab from './PostTab.vue';
|
||||||
|
import PreTab from './PreTab.vue';
|
||||||
|
|
||||||
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
activeType: string;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const tabList = ref<{ key: string; label: string }[]>([
|
||||||
|
{
|
||||||
|
key: 'scenarioProcessorConfig',
|
||||||
|
label: '场景',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'requestProcessorConfig',
|
||||||
|
label: '请求',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const activeTab = ref<string>('scenarioProcessorConfig');
|
||||||
|
const showAssociatedScene = computed(() => {
|
||||||
|
return activeTab.value === 'scenarioProcessorConfig';
|
||||||
|
});
|
||||||
|
|
||||||
|
const requestPropsText = computed(() => {
|
||||||
|
if (activeTab.value === 'requestProcessorConfig') {
|
||||||
|
return props.activeType === 'pre'
|
||||||
|
? {
|
||||||
|
pre: t('project.environmental.preScriptBefore'),
|
||||||
|
post: t('project.environmental.preScriptAfter'),
|
||||||
|
preTip: t('project.environmental.http.preTextPreTip'),
|
||||||
|
postTip: t('project.environmental.http.preTextPostTip'),
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
pre: t('project.environmental.postScriptBefore'),
|
||||||
|
post: t('project.environmental.postScriptAfter'),
|
||||||
|
preTip: t('project.environmental.http.postTextPreTip'),
|
||||||
|
postTip: t('project.environmental.http.postTextPostTip'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
.no-content {
|
||||||
|
:deep(.arco-tabs-content) {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -29,6 +29,10 @@ export default {
|
||||||
'project.environmental.TCP': 'TCP',
|
'project.environmental.TCP': 'TCP',
|
||||||
'project.environmental.pre': 'Pre',
|
'project.environmental.pre': 'Pre',
|
||||||
'project.environmental.post': 'Post',
|
'project.environmental.post': 'Post',
|
||||||
|
'project.environmental.sceneAlertDesc':
|
||||||
|
'Perform this operation once before scenario execution, such as obtaining a token and scenario initialization',
|
||||||
|
'project.environmental.requestAlertDesc':
|
||||||
|
'Each API step is executed once before execution, such as request content encryption',
|
||||||
'project.environmental.host': 'Host',
|
'project.environmental.host': 'Host',
|
||||||
'project.environmental.assert': 'Assertion',
|
'project.environmental.assert': 'Assertion',
|
||||||
'project.environmental.displaySetting': 'Display Setting',
|
'project.environmental.displaySetting': 'Display Setting',
|
||||||
|
@ -87,4 +91,17 @@ export default {
|
||||||
'project.environmental.host.descPlaceholder': 'Please enter the description',
|
'project.environmental.host.descPlaceholder': 'Please enter the description',
|
||||||
'project.environmental.newEnv': 'New Environment',
|
'project.environmental.newEnv': 'New Environment',
|
||||||
'project.environmental.http.hostNamePlaceholder': 'Please enter the host name',
|
'project.environmental.http.hostNamePlaceholder': 'Please enter the host name',
|
||||||
|
'project.environmental.preScriptBefore': 'Pre script before',
|
||||||
|
'project.environmental.preScriptAfter': 'After pre script',
|
||||||
|
'project.environmental.postScriptBefore': 'Post script front',
|
||||||
|
'project.environmental.postScriptAfter': 'After the script',
|
||||||
|
'project.environmental.http.preTextPreTip':
|
||||||
|
'Before pre script, environment scripts executed before buy scripts in the request;',
|
||||||
|
'project.environmental.http.preTextPostTip':
|
||||||
|
'After the preset script, the script in the environment is executed after the requested preset script is executed;',
|
||||||
|
'project.environmental.http.postTextPreTip':
|
||||||
|
'The script in the environment is executed before the requested script is executed.',
|
||||||
|
'project.environmental.http.postTextPostTip':
|
||||||
|
'After rear script, environment a prerequisite for the script in the request after the script execution;',
|
||||||
|
'project.environmental.preOrPost.ignoreProtocols': 'Ignore request:',
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,6 +36,8 @@ export default {
|
||||||
'project.environmental.database': '数据库',
|
'project.environmental.database': '数据库',
|
||||||
'project.environmental.pre': '前置',
|
'project.environmental.pre': '前置',
|
||||||
'project.environmental.post': '后置',
|
'project.environmental.post': '后置',
|
||||||
|
'project.environmental.sceneAlertDesc': '场景执行前执行一次,如token获取及场景初始化',
|
||||||
|
'project.environmental.requestAlertDesc': '每一个API步骤执行前均执行一次,如请求内容加密',
|
||||||
'project.environmental.host': '域名',
|
'project.environmental.host': '域名',
|
||||||
'project.environmental.assert': '断言',
|
'project.environmental.assert': '断言',
|
||||||
'project.environmental.displaySetting': '显示设置',
|
'project.environmental.displaySetting': '显示设置',
|
||||||
|
@ -103,4 +105,13 @@ export default {
|
||||||
'project.environmental.group.envGroupNameIsRequire': '环境组名称不能为空',
|
'project.environmental.group.envGroupNameIsRequire': '环境组名称不能为空',
|
||||||
'project.environmental.group.envGroupPlaceholder': '请输入环境组',
|
'project.environmental.group.envGroupPlaceholder': '请输入环境组',
|
||||||
'project.environmental.http.hostNamePlaceholder': '请输入域名',
|
'project.environmental.http.hostNamePlaceholder': '请输入域名',
|
||||||
|
'project.environmental.preScriptBefore': '前置脚本前',
|
||||||
|
'project.environmental.preScriptAfter': '前置脚本后',
|
||||||
|
'project.environmental.postScriptBefore': '后置脚本前',
|
||||||
|
'project.environmental.postScriptAfter': '后置脚本后',
|
||||||
|
'project.environmental.http.preTextPreTip': '前置脚本前,环境中脚本在请求的置脚本执行前执行;',
|
||||||
|
'project.environmental.http.preTextPostTip': '前置置脚本后,环境中脚本在请求的前置脚本执行后执行;',
|
||||||
|
'project.environmental.http.postTextPreTip': '后置脚本前,环境中脚本在请求的置脚本执行前执行;',
|
||||||
|
'project.environmental.http.postTextPostTip': '后置脚本后,环境中脚本在请求的前置脚本执行后执行;',
|
||||||
|
'project.environmental.preOrPost.ignoreProtocols': '忽略请求:',
|
||||||
};
|
};
|
||||||
|
|
|
@ -102,13 +102,14 @@
|
||||||
import { enableOrOffTemplate } from '@/api/modules/setting/template';
|
import { enableOrOffTemplate } from '@/api/modules/setting/template';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import { useAppStore } from '@/store';
|
import { useAppStore } from '@/store';
|
||||||
|
import useLicenseStore from '@/store/modules/setting/license';
|
||||||
import useTemplateStore from '@/store/modules/setting/template';
|
import useTemplateStore from '@/store/modules/setting/template';
|
||||||
import { hasAnyPermission } from '@/utils/permission';
|
import { hasAnyPermission } from '@/utils/permission';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
const templateStore = useTemplateStore();
|
const templateStore = useTemplateStore();
|
||||||
|
const licenseStore = useLicenseStore();
|
||||||
const currentOrgId = computed(() => appStore.currentOrgId);
|
const currentOrgId = computed(() => appStore.currentOrgId);
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
@ -142,7 +143,10 @@
|
||||||
const confirmLoading = ref<boolean>(false);
|
const confirmLoading = ref<boolean>(false);
|
||||||
|
|
||||||
const orgName = computed(() => {
|
const orgName = computed(() => {
|
||||||
return appStore.ordList.find((item: any) => item.id === appStore.currentOrgId)?.name;
|
if (licenseStore.hasLicense()) {
|
||||||
|
return appStore.ordList.find((item: any) => item.id === appStore.currentOrgId)?.name;
|
||||||
|
}
|
||||||
|
return '默认组织';
|
||||||
});
|
});
|
||||||
|
|
||||||
async function okHandler() {
|
async function okHandler() {
|
||||||
|
|
Loading…
Reference in New Issue