feat(项目管理): 环境管理&模块&前后置组件扩展和参数对接
This commit is contained in:
parent
a2254a9c44
commit
b362fd6a0c
|
@ -424,7 +424,7 @@
|
|||
const responseRadios = [
|
||||
{ label: 'ms.assertion.jsonPath', value: 'jsonPath' },
|
||||
{ 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.script', value: 'script' },
|
||||
];
|
||||
|
|
|
@ -246,6 +246,9 @@ export interface ExecuteConditionProcessorCommon {
|
|||
enable: boolean; // 是否启用
|
||||
name?: string; // 条件处理器名称
|
||||
processorType: RequestConditionProcessor;
|
||||
associateScenarioResult?: boolean; // 是否关联场景结果
|
||||
ignoreProtocols: string[]; // 忽略协议
|
||||
beforeStepScript: boolean; // 是否是步骤内前置脚本前
|
||||
}
|
||||
// 执行请求-前后置条件-脚本处理器
|
||||
export type ScriptProcessor = ScriptCommonConfig & ExecuteConditionProcessorCommon;
|
||||
|
|
|
@ -101,7 +101,7 @@ export interface SelectedModule {
|
|||
// 定义-获取环境的模块树参数
|
||||
export interface ApiDefinitionGetEnvModuleParams {
|
||||
projectId: string;
|
||||
selectedModules: SelectedModule[];
|
||||
selectedModules?: SelectedModule[];
|
||||
}
|
||||
// 环境-模块树
|
||||
export interface EnvModule {
|
||||
|
|
|
@ -35,6 +35,9 @@ export interface ProcessorConfig {
|
|||
scenarioProcessorConfig: {
|
||||
processors: ExecuteConditionProcessor[];
|
||||
};
|
||||
requestProcessorConfig: {
|
||||
processors: [];
|
||||
};
|
||||
};
|
||||
}
|
||||
export interface AssertionConfig {
|
||||
|
@ -138,5 +141,16 @@ export interface HttpForm {
|
|||
// pathMatchRule: {
|
||||
path: 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() {
|
||||
try {
|
||||
this.packageType = await getPackageType();
|
||||
// this.packageType = 'community';
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
|
|
|
@ -30,18 +30,19 @@ const envParamsDefaultConfig: EnvConfig = {
|
|||
scenarioProcessorConfig: {
|
||||
processors: [],
|
||||
},
|
||||
requestProcessorConfig: {
|
||||
processors: [],
|
||||
},
|
||||
},
|
||||
|
||||
// TODO 环境参数问题
|
||||
// apiProcessorConfig: [],
|
||||
},
|
||||
postProcessorConfig: {
|
||||
// TODO 环境参数问题
|
||||
// apiProcessorConfig: [],
|
||||
apiProcessorConfig: {
|
||||
scenarioProcessorConfig: {
|
||||
processors: [],
|
||||
},
|
||||
requestProcessorConfig: {
|
||||
processors: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
assertionConfig: { assertions: [] },
|
||||
|
|
|
@ -632,3 +632,32 @@ export function customFieldDataToTableData(customFieldData: Record<string, any>[
|
|||
});
|
||||
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">
|
||||
<!-- 脚本操作 -->
|
||||
<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>
|
||||
<a-radio :value="true">{{ t('apiTestDebug.quote') }}</a-radio>
|
||||
</a-radio-group>
|
||||
<!-- 前后置请求开始 -->
|
||||
<div v-if="props.showPrePostRequest" class="mt-4">
|
||||
<a-radio-group v-model="condition.beforeStepScript" type="button" size="small" :default-value="true">
|
||||
<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
|
||||
v-if="!condition.enableCommonScript"
|
||||
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 AddScriptDrawer from '@/components/business/ms-common-script/ms-addScriptDrawer.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 moreSetting from '../fastExtraction/moreSetting.vue';
|
||||
import paramTable, { type ParamTableColumn } from '../paramTable.vue';
|
||||
import quoteSqlSourceDrawer from '../quoteSqlSourceDrawer.vue';
|
||||
|
||||
import { getProtocolList } from '@/api/modules/api-test/common';
|
||||
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 { ParamsRequestType } from '@/models/projectManagement/commonScript';
|
||||
import {
|
||||
|
@ -378,13 +430,22 @@
|
|||
} from '@/enums/apiEnum';
|
||||
|
||||
export type ExpressionConfig = (RegexExtract | JSONPathExtract | XPathExtract) & Record<string, any>;
|
||||
|
||||
const props = defineProps<{
|
||||
data: ExecuteConditionProcessor;
|
||||
response?: string; // 响应内容
|
||||
heightUsed?: number;
|
||||
isBuildIn?: boolean; // 是否是内置的条件
|
||||
}>();
|
||||
const appStore = useAppStore();
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
data: ExecuteConditionProcessor;
|
||||
response?: string; // 响应内容
|
||||
heightUsed?: number;
|
||||
isBuildIn?: boolean; // 是否是内置的条件
|
||||
showAssociatedScene?: boolean; // 是否展示关联场景结果
|
||||
requestRadioTextProps?: Record<string, any>; // 前后置请求前后置按钮文本
|
||||
showPrePostRequest?: boolean; // 是否展示前后置请求忽略
|
||||
}>(),
|
||||
{
|
||||
showAssociatedScene: false,
|
||||
showPrePostRequest: false,
|
||||
}
|
||||
);
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:data', data: ExecuteConditionProcessor): void;
|
||||
(e: 'copy'): void;
|
||||
|
@ -732,6 +793,15 @@ if (!result){
|
|||
});
|
||||
emit('change');
|
||||
}
|
||||
|
||||
const protocolList = ref<ProtocolItem[]>([]);
|
||||
onBeforeMount(async () => {
|
||||
try {
|
||||
protocolList.value = await getProtocolList(appStore.currentOrgId);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
v-model:data="activeItem"
|
||||
:response="props.response"
|
||||
:height-used="props.heightUsed"
|
||||
:show-associated-scene="props.showAssociatedScene"
|
||||
:show-pre-post-request="props.showPrePostRequest"
|
||||
:request-radio-text-props="props.requestRadioTextProps"
|
||||
@copy="copyListItem"
|
||||
@delete="deleteListItem"
|
||||
@change="emit('change')"
|
||||
|
@ -48,13 +51,21 @@
|
|||
import { ConditionType, ExecuteConditionProcessor } from '@/models/apiTest/common';
|
||||
import { RequestConditionProcessor } from '@/enums/apiEnum';
|
||||
|
||||
const props = defineProps<{
|
||||
list: ExecuteConditionProcessor[];
|
||||
conditionTypes: Array<ConditionType>;
|
||||
addText: string;
|
||||
heightUsed?: number;
|
||||
response?: string; // 响应内容
|
||||
}>();
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
list: ExecuteConditionProcessor[];
|
||||
conditionTypes: Array<ConditionType>;
|
||||
addText: string;
|
||||
requestRadioTextProps?: Record<string, any>;
|
||||
heightUsed?: number;
|
||||
response?: string; // 响应内容
|
||||
showAssociatedScene?: boolean;
|
||||
showPrePostRequest?: boolean; // 是否展示前后置请求忽略选项
|
||||
}>(),
|
||||
{
|
||||
showAssociatedScene: false,
|
||||
}
|
||||
);
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:list', list: ExecuteConditionProcessor[]): void;
|
||||
(e: 'change'): void;
|
||||
|
@ -107,6 +118,9 @@
|
|||
processorType: RequestConditionProcessor.SCRIPT,
|
||||
scriptName: t('apiTestDebug.preconditionScriptName'),
|
||||
enableCommonScript: false,
|
||||
associateScenarioResult: false,
|
||||
ignoreProtocols: [],
|
||||
beforeStepScript: true,
|
||||
enable: true,
|
||||
script: '',
|
||||
scriptId: '',
|
||||
|
@ -125,6 +139,9 @@
|
|||
id,
|
||||
processorType: RequestConditionProcessor.SQL,
|
||||
enableCommonScript: false,
|
||||
associateScenarioResult: false,
|
||||
ignoreProtocols: [],
|
||||
beforeStepScript: true,
|
||||
description: '',
|
||||
enable: true,
|
||||
dataSourceId: '',
|
||||
|
@ -141,6 +158,9 @@
|
|||
data.value.push({
|
||||
id,
|
||||
processorType: RequestConditionProcessor.TIME_WAITING,
|
||||
associateScenarioResult: false,
|
||||
ignoreProtocols: [],
|
||||
beforeStepScript: true,
|
||||
enable: true,
|
||||
delay: 1000,
|
||||
});
|
||||
|
@ -149,6 +169,10 @@
|
|||
data.value.push({
|
||||
id,
|
||||
processorType: RequestConditionProcessor.EXTRACT,
|
||||
enableCommonScript: false,
|
||||
associateScenarioResult: false,
|
||||
ignoreProtocols: [],
|
||||
beforeStepScript: true,
|
||||
enable: true,
|
||||
extractors: [],
|
||||
});
|
||||
|
|
|
@ -70,7 +70,10 @@ export default {
|
|||
'apiTestDebug.wait': 'Wait',
|
||||
'apiTestDebug.script': 'Script',
|
||||
'apiTestDebug.preconditionScriptName': 'Pre-script name',
|
||||
'apiTestDebug.preconditionAssociatedSceneResult': 'Associated scene result',
|
||||
'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.quote': 'Quoting public scripts',
|
||||
'apiTestDebug.commonScriptList': 'Public script list',
|
||||
|
|
|
@ -66,7 +66,10 @@ export default {
|
|||
'apiTestDebug.wait': '等待',
|
||||
'apiTestDebug.script': '脚本操作',
|
||||
'apiTestDebug.preconditionScriptName': '前置脚本名称',
|
||||
'apiTestDebug.preconditionAssociatedSceneResult': '关联场景结果',
|
||||
'apiTestDebug.preconditionScriptNamePlaceholder': '请输入前置脚本名称',
|
||||
'apiTestDebug.preconditionAssociateResultDesc':
|
||||
'当作自定义脚本步骤统计到场景执行结果中,执行报错时会影响场景的最终执行结果',
|
||||
'apiTestDebug.manual': '手动录入',
|
||||
'apiTestDebug.quote': '引用公共脚本',
|
||||
'apiTestDebug.commonScriptList': '公共脚本列表',
|
||||
|
|
|
@ -39,14 +39,20 @@
|
|||
<a-tab-pane key="displaySetting" :title="t('project.environmental.displaySetting')" />
|
||||
</a-tabs>
|
||||
</div>
|
||||
<a-divider :margin="0" class="!mb-[16px]" />
|
||||
<a-divider
|
||||
:margin="0"
|
||||
:class="{
|
||||
'!mb-[16px]': activeKey === 'pre' || activeKey === 'post' ? false : true,
|
||||
}"
|
||||
/>
|
||||
<div class="content">
|
||||
<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'" />
|
||||
<!-- <PreTab v-else-if="activeKey === 'pre'" />
|
||||
<PostTab v-else-if="activeKey === 'post'" /> -->
|
||||
<PreAndPostTab v-else-if="activeKey === 'pre' || activeKey === 'post'" :active-type="activeKey" />
|
||||
<AssertTab v-else-if="activeKey === 'assert'" />
|
||||
<template v-for="item in envPluginList" :key="item.pluginId">
|
||||
<PluginTab
|
||||
|
@ -80,6 +86,7 @@
|
|||
import HttpTab from './envParams/HttpTab.vue';
|
||||
import PluginTab from './envParams/PluginTab.vue';
|
||||
import PostTab from './envParams/PostTab.vue';
|
||||
import PreAndPostTab from './envParams/preAndPost.vue';
|
||||
import PreTab from './envParams/PreTab.vue';
|
||||
|
||||
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" />
|
||||
<div class="text-[var(--color-text-1)]">{{ t('project.environmental.host.config') }}</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
|
||||
ref="batchFormRef"
|
||||
:models="batchFormModels"
|
||||
:form-mode="ruleFormMode"
|
||||
add-text="project.menu.rule.addRule"
|
||||
:default-vals="currentList.hosts"
|
||||
show-enable
|
||||
:show-enable="false"
|
||||
:is-show-drag="false"
|
||||
></MsBatchForm>
|
||||
</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>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
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 { FormItemModel } from '@/components/business/ms-batch-form/types';
|
||||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useProjectEnvStore from '@/store/modules/setting/useProjectEnvStore';
|
||||
import { getGenerateId } from '@/utils';
|
||||
|
||||
import { EnvConfigItem } from '@/models/projectManagement/environmental';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const store = useProjectEnvStore();
|
||||
const addType = ref<string>('single');
|
||||
|
||||
const currentList = computed({
|
||||
get: () => store.currentEnvDetailInfo.config.hostConfig || {},
|
||||
|
@ -56,20 +86,58 @@
|
|||
],
|
||||
},
|
||||
{
|
||||
filed: 'hostName',
|
||||
filed: 'domain',
|
||||
type: 'input',
|
||||
label: 'project.environmental.host.hostName',
|
||||
placeholder: 'project.environmental.host.hostNamePlaceholder',
|
||||
rules: [{ required: true, message: t('project.environmental.host.hostNameIsRequire') }],
|
||||
},
|
||||
{
|
||||
filed: 'desc',
|
||||
filed: 'description',
|
||||
type: 'input',
|
||||
label: 'project.environmental.host.desc',
|
||||
placeholder: 'project.environmental.host.descPlaceholder',
|
||||
},
|
||||
]);
|
||||
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>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
|
|
@ -18,20 +18,26 @@
|
|||
<span class="text-[var(--color-text-3)]">{{ t('project.environmental.http.linkTimeOut') }}</span>
|
||||
</template>
|
||||
</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>
|
||||
<span class="text-[var(--color-text-3)]">{{ t('project.environmental.http.authType') }}</span>
|
||||
</template>
|
||||
<a-option>Basic Auth</a-option>
|
||||
<a-option>Basic Auth2</a-option>
|
||||
<a-option>Basic Auth3</a-option>
|
||||
</a-select>
|
||||
</a-select> -->
|
||||
</div>
|
||||
</div>
|
||||
<MsBaseTable class="mt-[16px]" v-bind="propsRes" v-on="propsEvent" @change="changeHandler">
|
||||
<template #type="{ record }">
|
||||
<span>{{ getEnableScope(record.type) }}</span>
|
||||
</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 }">
|
||||
<div class="flex flex-row flex-nowrap items-center">
|
||||
<MsButton class="!mr-0" @click="handleCopy(record)">{{ t('common.copy') }}</MsButton>
|
||||
|
@ -42,7 +48,13 @@
|
|||
</div>
|
||||
</template>
|
||||
</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>
|
||||
|
||||
<script lang="ts" async setup>
|
||||
|
@ -56,15 +68,19 @@
|
|||
import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
||||
import AddHttpDrawer from './popUp/AddHttpDrawer.vue';
|
||||
|
||||
import { getEnvModules } from '@/api/modules/api-test/management';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { useTableStore } from '@/store';
|
||||
import { useAppStore, useTableStore } from '@/store';
|
||||
import useProjectEnvStore from '@/store/modules/setting/useProjectEnvStore';
|
||||
import { findNodeNames } from '@/utils';
|
||||
|
||||
import { BugListItem } from '@/models/bug-management';
|
||||
import type { ModuleTreeNode } from '@/models/common';
|
||||
import type { CommonParams } from '@/models/projectManagement/environmental';
|
||||
import { HttpForm } from '@/models/projectManagement/environmental';
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
|
||||
const appStore = useAppStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
const store = useProjectEnvStore();
|
||||
|
@ -97,7 +113,8 @@
|
|||
{
|
||||
title: 'project.environmental.http.value',
|
||||
dataIndex: 'value',
|
||||
showTooltip: true,
|
||||
slotName: 'moduleValue',
|
||||
showTooltip: false,
|
||||
showDrag: true,
|
||||
showInTable: true,
|
||||
},
|
||||
|
@ -223,6 +240,27 @@
|
|||
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>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
add-text="apiTestDebug.postCondition"
|
||||
response=""
|
||||
:height-used="600"
|
||||
:show-associated-scene="props.showAssociatedScene"
|
||||
:show-pre-post-request="props.showPrePostRequest"
|
||||
:request-radio-text-props="props.requestRadioTextProps"
|
||||
>
|
||||
</condition>
|
||||
</template>
|
||||
|
@ -16,14 +19,35 @@
|
|||
|
||||
import { RequestConditionProcessor } from '@/enums/apiEnum';
|
||||
|
||||
const props = defineProps<{
|
||||
showAssociatedScene?: boolean;
|
||||
showPrePostRequest?: boolean;
|
||||
requestRadioTextProps?: Record<string, any>;
|
||||
activeTab: string;
|
||||
}>();
|
||||
|
||||
const store = useProjectEnvStore();
|
||||
const innerParams = computed({
|
||||
set: (value: any) => {
|
||||
store.currentEnvDetailInfo.config.postProcessorConfig.apiProcessorConfig.scenarioProcessorConfig.processors =
|
||||
value || [];
|
||||
if (props.activeTab === 'scenarioProcessorConfig') {
|
||||
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>
|
||||
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
add-text="apiTestDebug.precondition"
|
||||
response=""
|
||||
:height-used="600"
|
||||
:show-associated-scene="props.showAssociatedScene"
|
||||
:show-pre-post-request="props.showPrePostRequest"
|
||||
:request-radio-text-props="props.requestRadioTextProps"
|
||||
>
|
||||
</condition>
|
||||
</template>
|
||||
|
@ -16,14 +19,35 @@
|
|||
|
||||
import { RequestConditionProcessor } from '@/enums/apiEnum';
|
||||
|
||||
const props = defineProps<{
|
||||
showAssociatedScene?: boolean;
|
||||
showPrePostRequest?: boolean;
|
||||
requestRadioTextProps?: Record<string, any>;
|
||||
activeTab: string;
|
||||
}>();
|
||||
|
||||
const store = useProjectEnvStore();
|
||||
const innerParams = computed({
|
||||
set: (value: any) => {
|
||||
store.currentEnvDetailInfo.config.preProcessorConfig.apiProcessorConfig.scenarioProcessorConfig.processors =
|
||||
value || [];
|
||||
if (props.activeTab === 'scenarioProcessorConfig') {
|
||||
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>
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<a-form-item
|
||||
class="mb-[16px]"
|
||||
asterisk-position="end"
|
||||
field="hostname"
|
||||
field="url"
|
||||
:label="t('project.environmental.http.hostName')"
|
||||
:rules="[{ required: true, message: t('project.environmental.http.hostNameRequired') }]"
|
||||
>
|
||||
|
@ -36,7 +36,7 @@
|
|||
<a-option value="https">https://</a-option>
|
||||
</a-select>
|
||||
<a-input
|
||||
v-model="form.hostname"
|
||||
v-model="form.url"
|
||||
class="w-full"
|
||||
:max-length="255"
|
||||
:placeholder="
|
||||
|
@ -85,8 +85,14 @@
|
|||
</a-form-item> -->
|
||||
<!-- 展示模块 -->
|
||||
<!-- TODO 模块还没有加 -->
|
||||
<!-- <a-form-item class="mb-[16px]" field="description" :label="t('project.environmental.http.selectApiModule')">
|
||||
<ApiTree
|
||||
<a-form-item
|
||||
v-if="form.type === 'MODULE'"
|
||||
class="mb-[16px]"
|
||||
field="description"
|
||||
:label="t('project.environmental.http.selectApiModule')"
|
||||
>
|
||||
<!-- TODO 先做普通树 放在下一个版本 -->
|
||||
<!-- <ApiTree
|
||||
v-model:focus-node-key="focusNodeKey"
|
||||
:placeholder="t('project.environmental.http.selectApiModule')"
|
||||
:selected-keys="selectedKeys"
|
||||
|
@ -108,8 +114,25 @@
|
|||
<template #tree-slot-extra="nodeData">
|
||||
<span><MsTableMoreAction :list="moreActions" @select="handleMoreActionSelect($event, nodeData)" /></span>
|
||||
</template>
|
||||
</ApiTree>
|
||||
</a-form-item> -->
|
||||
</ApiTree> -->
|
||||
<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
|
||||
v-if="showPathInput"
|
||||
|
@ -142,21 +165,26 @@
|
|||
import MsDrawer from '@/components/pure/ms-drawer/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 { 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 { getEnvModules } from '@/api/modules/api-test/management';
|
||||
// import ApiTree from './apiTree.vue';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { useAppStore } from '@/store';
|
||||
import useProjectEnvStore from '@/store/modules/setting/useProjectEnvStore';
|
||||
import { getGenerateId } from '@/utils';
|
||||
|
||||
import type { EnvModule } from '@/models/apiTest/management';
|
||||
import type { ModuleTreeNode } from '@/models/common';
|
||||
import { HttpForm } from '@/models/projectManagement/environmental';
|
||||
|
||||
const props = defineProps<{
|
||||
currentId: string;
|
||||
isCopy: boolean;
|
||||
moduleTree: ModuleTreeNode[];
|
||||
}>();
|
||||
|
||||
const appStore = useAppStore();
|
||||
const store = useProjectEnvStore();
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
@ -174,7 +202,7 @@
|
|||
},
|
||||
];
|
||||
|
||||
const initForm = {
|
||||
const initForm: HttpForm = {
|
||||
id: '',
|
||||
hostname: '',
|
||||
type: 'NONE',
|
||||
|
@ -182,7 +210,21 @@
|
|||
path: '',
|
||||
condition: 'CONTAINS',
|
||||
description: '',
|
||||
url: '',
|
||||
protocol: 'http',
|
||||
moduleId: [],
|
||||
moduleMatchRule: {
|
||||
modules: [
|
||||
// {
|
||||
// moduleId: '',
|
||||
// containChildModule: false,
|
||||
// },
|
||||
],
|
||||
},
|
||||
pathMatchRule: {
|
||||
path: '',
|
||||
condition: '',
|
||||
},
|
||||
};
|
||||
|
||||
const form = ref<HttpForm>({ ...initForm });
|
||||
|
@ -202,437 +244,59 @@
|
|||
|
||||
const handleAddOrUpdate = () => {
|
||||
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) {
|
||||
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) {
|
||||
const insertItem = {
|
||||
...form.value,
|
||||
id: getGenerateId(),
|
||||
hostname: `copy_${form.value.hostname}`,
|
||||
hostname: `${protocol}:${url}`,
|
||||
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 {
|
||||
const { protocol, hostname, condition, path } = form.value;
|
||||
const httpItem = {
|
||||
...form.value,
|
||||
hostname: `${protocol}://${hostname}`,
|
||||
hostname: `${protocol}://${url}`,
|
||||
pathMatchRule: {
|
||||
path,
|
||||
condition,
|
||||
},
|
||||
id: getGenerateId(),
|
||||
order: store.currentEnvDetailInfo.config.httpConfig.length + 1,
|
||||
moduleMatchRule: { modules },
|
||||
};
|
||||
store.currentEnvDetailInfo.config.httpConfig.push(httpItem);
|
||||
}
|
||||
emit('close');
|
||||
};
|
||||
|
||||
const moduleTree = ref([
|
||||
{
|
||||
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 envTree = ref<ModuleTreeNode[]>([]);
|
||||
|
||||
const moreActions: ActionsItem[] = [
|
||||
{
|
||||
|
@ -654,14 +318,35 @@
|
|||
(item) => item.id === props.currentId
|
||||
) as HttpForm;
|
||||
if (currentItem) {
|
||||
const { path, condition } = currentItem.pathMatchRule;
|
||||
const urlPath = currentItem.hostname.match(/\/\/(.*)/);
|
||||
form.value = {
|
||||
...currentItem,
|
||||
moduleId: currentItem.moduleMatchRule.modules.map((item) => item.moduleId) || [],
|
||||
path,
|
||||
condition,
|
||||
url: urlPath && urlPath?.length > 1 ? `//${urlPath[1]}` : '',
|
||||
};
|
||||
}
|
||||
} else {
|
||||
resetForm();
|
||||
}
|
||||
});
|
||||
|
||||
async function initModuleTree() {
|
||||
try {
|
||||
const res = await getEnvModules({
|
||||
projectId: appStore.currentProjectId,
|
||||
});
|
||||
envTree.value = res.moduleTree;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
initModuleTree();
|
||||
});
|
||||
</script>
|
||||
|
||||
<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.pre': 'Pre',
|
||||
'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.assert': 'Assertion',
|
||||
'project.environmental.displaySetting': 'Display Setting',
|
||||
|
@ -87,4 +91,17 @@ export default {
|
|||
'project.environmental.host.descPlaceholder': 'Please enter the description',
|
||||
'project.environmental.newEnv': 'New Environment',
|
||||
'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.pre': '前置',
|
||||
'project.environmental.post': '后置',
|
||||
'project.environmental.sceneAlertDesc': '场景执行前执行一次,如token获取及场景初始化',
|
||||
'project.environmental.requestAlertDesc': '每一个API步骤执行前均执行一次,如请求内容加密',
|
||||
'project.environmental.host': '域名',
|
||||
'project.environmental.assert': '断言',
|
||||
'project.environmental.displaySetting': '显示设置',
|
||||
|
@ -103,4 +105,13 @@ export default {
|
|||
'project.environmental.group.envGroupNameIsRequire': '环境组名称不能为空',
|
||||
'project.environmental.group.envGroupPlaceholder': '请输入环境组',
|
||||
'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 { useI18n } from '@/hooks/useI18n';
|
||||
import { useAppStore } from '@/store';
|
||||
import useLicenseStore from '@/store/modules/setting/license';
|
||||
import useTemplateStore from '@/store/modules/setting/template';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
const { t } = useI18n();
|
||||
const appStore = useAppStore();
|
||||
const templateStore = useTemplateStore();
|
||||
|
||||
const licenseStore = useLicenseStore();
|
||||
const currentOrgId = computed(() => appStore.currentOrgId);
|
||||
|
||||
const props = defineProps<{
|
||||
|
@ -142,7 +143,10 @@
|
|||
const confirmLoading = ref<boolean>(false);
|
||||
|
||||
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() {
|
||||
|
|
Loading…
Reference in New Issue