refactor(项目管理): 环境管理断言对接&样式调整
This commit is contained in:
parent
dd470ba328
commit
8265d5f21b
|
@ -37,7 +37,7 @@ export function exportEnv(selectIds: string[]) {
|
|||
{ isTransformResponse: false }
|
||||
);
|
||||
}
|
||||
export function editPosEnv(data: EnvListItem) {
|
||||
export function editPosEnv(data: DragParam) {
|
||||
return MSR.post<EnvListItem>({ url: envURL.editPosEnvUrl, data });
|
||||
}
|
||||
|
||||
|
|
|
@ -303,13 +303,7 @@
|
|||
</paramsTable>
|
||||
</div>
|
||||
<div v-if="activeTab === 'script'" class="mt-[16px]">
|
||||
<conditionContent
|
||||
:data="innerParams.script"
|
||||
class="mt-[16px]"
|
||||
@copy="copyListItem"
|
||||
@delete="deleteListItem"
|
||||
@change="emit('change')"
|
||||
/>
|
||||
<conditionContent v-model:data="innerParams.script" :height-used="600" is-build-in class="mt-[16px]" />
|
||||
</div>
|
||||
</div>
|
||||
<fastExtraction v-model:visible="fastExtractionVisible" :config="activeRecord" @apply="handleFastExtractionApply" />
|
||||
|
@ -362,25 +356,16 @@
|
|||
(e: 'update:data', data: ExecuteConditionProcessor): void;
|
||||
(e: 'copy'): void;
|
||||
(e: 'delete', id: number): void;
|
||||
(e: 'change'): void;
|
||||
(e: 'change', param: Param): void;
|
||||
}>();
|
||||
const { t } = useI18n();
|
||||
const rootId = 0; // 1970-01-01 00:00:00 UTC
|
||||
|
||||
// const innerParams = defineModel<Param>('modelValue', {
|
||||
// default: {
|
||||
// jsonPath: [],
|
||||
// xPath: { responseFormat: 'XML', data: [] },
|
||||
// script: {
|
||||
// id: new Date().getTime(),
|
||||
// processorType: RequestConditionProcessor.SCRIPT,
|
||||
// scriptName: '断言脚本名称',
|
||||
// enableCommonScript: false,
|
||||
// params: [],
|
||||
// },
|
||||
// },
|
||||
// });
|
||||
const innerParams = ref<Param>({
|
||||
const props = defineProps<{
|
||||
value: Param;
|
||||
}>();
|
||||
|
||||
const defaultParamItem = {
|
||||
jsonPath: [],
|
||||
xPath: { responseFormat: 'XML', data: [] },
|
||||
document: {
|
||||
|
@ -408,6 +393,11 @@
|
|||
scriptLanguage: RequestConditionScriptLanguage.JAVASCRIPT,
|
||||
script: new Date().getTime().toString(),
|
||||
},
|
||||
};
|
||||
|
||||
const innerParams = ref<Param>(props.value || defaultParamItem);
|
||||
watchEffect(() => {
|
||||
emit('change', innerParams.value);
|
||||
});
|
||||
const activeTab = ref('document');
|
||||
const extractParamsTableRef = ref<InstanceType<typeof paramsTable>>();
|
||||
|
@ -764,4 +754,7 @@
|
|||
}
|
||||
}
|
||||
};
|
||||
const handleScriptChange = (data: ExecuteConditionProcessor) => {
|
||||
innerParams.value.script = data;
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
const innerParams = defineModel<Param[]>('modelValue', { default: [] });
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'change'): void; // 数据发生变化
|
||||
(e: 'change', val: any[]): void; // 数据发生变化
|
||||
}>();
|
||||
|
||||
const defaultParamItem = {
|
||||
|
@ -85,7 +85,7 @@
|
|||
function handleParamTableChange(resultArr: any[], isInit?: boolean) {
|
||||
innerParams.value = [...resultArr];
|
||||
if (!isInit) {
|
||||
emit('change');
|
||||
emit('change', resultArr);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -4,18 +4,28 @@
|
|||
<span class="text-[var(--color-text-1)]">{{ t('ms.assertion.responseTime') }}</span>
|
||||
<span class="text-[var(--color-text-4)]">(ms)</span>
|
||||
</div>
|
||||
<a-input-number v-model:model-value="value" :step="100" mode="button" />
|
||||
<a-input-number v-model:model-value="innerParams" :step="100" mode="button" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script lang="ts" setup>
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const value = defineModel('modelValue', {
|
||||
default: 1000,
|
||||
type: Number,
|
||||
interface ResponseTimeTabProps {
|
||||
responseTime: number;
|
||||
}
|
||||
const props = defineProps<{
|
||||
value: ResponseTimeTabProps;
|
||||
}>();
|
||||
|
||||
const innerParams = ref(props.value.responseTime);
|
||||
const emit = defineEmits<{
|
||||
(e: 'change', val: ResponseTimeTabProps): void; // 数据发生变化
|
||||
}>();
|
||||
watchEffect(() => {
|
||||
emit('change', { responseTime: innerParams.value });
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,246 +1,41 @@
|
|||
<template>
|
||||
<div class="flex h-full w-full flex-col">
|
||||
<a-radio-group v-model:model-value="condition.scriptType" size="small" class="mb-[16px]">
|
||||
<a-radio value="manual">{{ t('apiTestDebug.manual') }}</a-radio>
|
||||
<a-radio value="quote">{{ t('apiTestDebug.quote') }}</a-radio>
|
||||
</a-radio-group>
|
||||
<div
|
||||
v-if="scriptType === 'manual'"
|
||||
class="relative h-full w-full rounded-[var(--border-radius-small)] bg-[var(--color-text-n9)] p-[12px]"
|
||||
>
|
||||
<div v-if="isShowEditScriptNameInput" class="absolute left-[12px] z-10 w-[calc(100%-24px)]">
|
||||
<a-input
|
||||
ref="scriptNameInputRef"
|
||||
v-model:model-value="condition.name"
|
||||
:placeholder="t('apiTestDebug.preconditionScriptNamePlaceholder')"
|
||||
:max-length="255"
|
||||
size="small"
|
||||
@press-enter="isShowEditScriptNameInput = false"
|
||||
@blur="isShowEditScriptNameInput = false"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center">
|
||||
<a-tooltip :content="condition.name">
|
||||
<div class="script-name-container">
|
||||
<div class="one-line-text mr-[4px] max-w-[110px] font-medium text-[var(--color-text-1)]">
|
||||
{{ condition.name }}
|
||||
</div>
|
||||
<MsIcon type="icon-icon_edit_outlined" class="edit-script-name-icon" @click="showEditScriptNameInput" />
|
||||
</div>
|
||||
</a-tooltip>
|
||||
<a-popover class="h-auto" position="top">
|
||||
<div class="text-[rgb(var(--primary-5))]">{{ t('apiTestDebug.scriptEx') }}</div>
|
||||
<template #content>
|
||||
<div class="mb-[8px] flex items-center justify-between">
|
||||
<div class="text-[14px] font-medium text-[var(--color-text-1)]">
|
||||
{{ t('apiTestDebug.scriptEx') }}
|
||||
</div>
|
||||
<a-button
|
||||
type="outline"
|
||||
class="arco-btn-outline--secondary p-[0_8px]"
|
||||
size="mini"
|
||||
@click="copyScriptEx"
|
||||
>
|
||||
{{ t('common.copy') }}
|
||||
</a-button>
|
||||
</div>
|
||||
<div class="flex h-[412px]">
|
||||
<MsCodeEditor
|
||||
v-model:model-value="scriptEx"
|
||||
class="flex-1"
|
||||
theme="MS-text"
|
||||
width="500px"
|
||||
height="388px"
|
||||
:show-full-screen="false"
|
||||
:show-theme-change="false"
|
||||
read-only
|
||||
>
|
||||
</MsCodeEditor>
|
||||
</div>
|
||||
</template>
|
||||
</a-popover>
|
||||
</div>
|
||||
<div class="flex items-center gap-[8px]">
|
||||
<a-button type="outline" class="arco-btn-outline--secondary p-[0_8px]" size="mini">
|
||||
<template #icon>
|
||||
<MsIcon type="icon-icon_undo_outlined" class="text-var(--color-text-4)" size="12" />
|
||||
</template>
|
||||
{{ t('common.revoke') }}
|
||||
</a-button>
|
||||
<a-button type="outline" class="arco-btn-outline--secondary p-[0_8px]" size="mini" @click="clearScript">
|
||||
<template #icon>
|
||||
<MsIcon type="icon-icon_clear" class="text-var(--color-text-4)" size="12" />
|
||||
</template>
|
||||
{{ t('common.clear') }}
|
||||
</a-button>
|
||||
<a-button type="outline" class="arco-btn-outline--secondary p-[0_8px]" size="mini" @click="copyCondition">
|
||||
{{ t('common.copy') }}
|
||||
</a-button>
|
||||
<a-button type="outline" class="arco-btn-outline--secondary p-[0_8px]" size="mini" @click="deleteCondition">
|
||||
{{ t('common.delete') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="flex h-[calc(100%-47px)] flex-col">
|
||||
<div class="mb-[16px] flex w-full items-center bg-[var(--color-text-n9)] p-[12px]">
|
||||
<div class="text-[var(--color-text-2)]">
|
||||
{{ condition.quoteScript.name || '-' }}
|
||||
</div>
|
||||
<a-divider margin="8px" direction="vertical" />
|
||||
<MsButton type="text" class="font-medium">
|
||||
{{ t('apiTestDebug.quote') }}
|
||||
</MsButton>
|
||||
</div>
|
||||
<a-radio-group v-model:model-value="commonScriptShowType" size="small" type="button" class="mb-[8px] w-fit">
|
||||
<a-radio value="parameters">{{ t('apiTestDebug.parameters') }}</a-radio>
|
||||
<a-radio value="scriptContent">{{ t('apiTestDebug.scriptContent') }}</a-radio>
|
||||
</a-radio-group>
|
||||
<MsBaseTable v-show="commonScriptShowType === 'parameters'" v-bind="propsRes" v-on="propsEvent">
|
||||
<template #value="{ record }">
|
||||
<a-tooltip :content="t(record.required ? 'apiTestDebug.paramRequired' : 'apiTestDebug.paramNotRequired')">
|
||||
<div
|
||||
:class="[
|
||||
record.required ? '!text-[rgb(var(--danger-5))]' : '!text-[var(--color-text-brand)]',
|
||||
'!mr-[4px] !p-[4px]',
|
||||
]"
|
||||
>
|
||||
<div>*</div>
|
||||
</div>
|
||||
</a-tooltip>
|
||||
{{ record.type }}
|
||||
</template>
|
||||
</MsBaseTable>
|
||||
<div v-show="commonScriptShowType === 'scriptContent'" class="h-[calc(100%-76px)]">
|
||||
<MsCodeEditor
|
||||
v-model:model-value="condition.quoteScript.script"
|
||||
theme="MS-text"
|
||||
height="100%"
|
||||
:show-full-screen="false"
|
||||
:show-theme-change="false"
|
||||
read-only
|
||||
>
|
||||
</MsCodeEditor>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<conditionContent v-model:data="innerParams" :height-used="600" is-build-in class="mt-[16px]" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { defineModel } from 'vue';
|
||||
import { useClipboard } from '@vueuse/core';
|
||||
import { InputInstance, Message } from '@arco-design/web-vue';
|
||||
import conditionContent from '@/views/api-test/components/condition/content.vue';
|
||||
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
import MsCodeEditor from '@/components/pure/ms-code-editor/index.vue';
|
||||
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
|
||||
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||
import type { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||
import useTable from '@/components/pure/ms-table/useTable';
|
||||
import { RequestConditionProcessor, RequestConditionScriptLanguage } from '@/enums/apiEnum';
|
||||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
interface ScriptItem {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
const { t } = useI18n();
|
||||
interface ScriptTabProps {
|
||||
value: ScriptItem;
|
||||
}
|
||||
|
||||
const scriptType = defineModel('scriptType', {
|
||||
type: String,
|
||||
default: 'manual',
|
||||
});
|
||||
|
||||
const condition = defineModel('modelValue', {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
scriptType: 'manual',
|
||||
name: '',
|
||||
const defaultScriptItem: ScriptItem = {
|
||||
id: new Date().getTime(),
|
||||
processorType: RequestConditionProcessor.SCRIPT,
|
||||
scriptName: '断言脚本名称',
|
||||
enableCommonScript: false,
|
||||
params: [],
|
||||
scriptId: '',
|
||||
scriptLanguage: RequestConditionScriptLanguage.JAVASCRIPT,
|
||||
script: '',
|
||||
quoteScript: {
|
||||
name: '',
|
||||
script: '',
|
||||
},
|
||||
}),
|
||||
});
|
||||
};
|
||||
|
||||
const columns: MsTableColumn = [
|
||||
{
|
||||
title: 'apiTestDebug.paramName',
|
||||
dataIndex: 'name',
|
||||
showTooltip: true,
|
||||
},
|
||||
{
|
||||
title: 'apiTestDebug.paramValue',
|
||||
dataIndex: 'value',
|
||||
slotName: 'value',
|
||||
},
|
||||
{
|
||||
title: 'apiTestDebug.desc',
|
||||
dataIndex: 'desc',
|
||||
showTooltip: true,
|
||||
},
|
||||
];
|
||||
|
||||
const { propsRes, propsEvent } = useTable(() => Promise.resolve([]), {
|
||||
scroll: { x: '100%' },
|
||||
columns,
|
||||
});
|
||||
const props = defineProps<ScriptTabProps>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:data', data: Record<string, any>): void;
|
||||
(e: 'copy'): void;
|
||||
(e: 'delete', id: string): void;
|
||||
(e: 'change'): void;
|
||||
(e: 'change', val: ScriptItem): void; // 数据发生变化
|
||||
}>();
|
||||
|
||||
// 是否显示脚本名称编辑框
|
||||
const isShowEditScriptNameInput = ref(false);
|
||||
const scriptNameInputRef = ref<InputInstance>();
|
||||
|
||||
function showEditScriptNameInput() {
|
||||
isShowEditScriptNameInput.value = true;
|
||||
nextTick(() => {
|
||||
scriptNameInputRef.value?.focus();
|
||||
const innerParams = ref<any>(props.value || defaultScriptItem);
|
||||
watchEffect(() => {
|
||||
emit('change', innerParams.value);
|
||||
});
|
||||
}
|
||||
|
||||
const scriptEx = ref(`2023-12-04 11:19:28 INFO 9026fd6a 1-1 Thread started: 9026fd6a 1-1
|
||||
2023-12-04 11:19:28 ERROR 9026fd6a 1-1 Problem in JSR223 script JSR223Sampler, message: {}
|
||||
In file: inline evaluation of: prev.getResponseCode() import java.net.URI; import org.apache.http.client.method . . . '' Encountered "import" at line 2, column 1.
|
||||
in inline evaluation of: prev.getResponseCode() import java.net.URI; import org.apache.http.client.method . . . '' at line number 2
|
||||
javax.script.ScriptException '' at line number 2
|
||||
javax.script.ScriptException '' at line number 2
|
||||
javax.script.ScriptException '' at line number 2
|
||||
javax.script.ScriptException '' at line number 2
|
||||
javax.script.ScriptException '' at line number 2
|
||||
javax.script.ScriptException
|
||||
org.apache.http.client.method . . . '' at line number 2
|
||||
`);
|
||||
const { copy, isSupported } = useClipboard();
|
||||
const commonScriptShowType = ref<'parameters' | 'scriptContent'>('parameters');
|
||||
function copyScriptEx() {
|
||||
if (isSupported) {
|
||||
copy(scriptEx.value);
|
||||
Message.success(t('apiTestDebug.scriptExCopySuccess'));
|
||||
} else {
|
||||
Message.warning(t('apiTestDebug.copyNotSupport'));
|
||||
}
|
||||
}
|
||||
function clearScript() {
|
||||
condition.value.script = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制条件
|
||||
*/
|
||||
function copyCondition() {
|
||||
emit('copy');
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除条件
|
||||
*/
|
||||
function deleteCondition() {
|
||||
emit('delete', condition.value.id);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
|
|
@ -2,28 +2,60 @@
|
|||
<div class="flex h-[62px] flex-row items-end gap-[8px] text-[var(--color-text-1)]">
|
||||
<div>
|
||||
<div class="mb-[8px]">{{ t('ms.assertion.statusCode') }}</div>
|
||||
<a-select v-model="selectValue" class="w-[157px]">
|
||||
<a-select
|
||||
v-model="selectValue"
|
||||
class="w-[157px]"
|
||||
@change="
|
||||
emit('change', {
|
||||
statusCode: statusCode,
|
||||
selectValue: selectValue,
|
||||
})
|
||||
"
|
||||
>
|
||||
<a-option v-for="item in statusCodeOptions" :key="item.value" :value="item.value">
|
||||
{{ t(item.label) }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
</div>
|
||||
<a-input-number v-if="showInput" v-model:modelValue="statusCode" hide-button class="w-[157px]" />
|
||||
<a-input-number
|
||||
v-if="showInput"
|
||||
v-model:modelValue="statusCode"
|
||||
hide-button
|
||||
class="w-[157px]"
|
||||
@change="
|
||||
emit('change', {
|
||||
statusCode: statusCode,
|
||||
selectValue: selectValue,
|
||||
})
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, defineModel } from 'vue';
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { statusCodeOptions } from '@/components/pure/ms-advance-filter/index';
|
||||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
|
||||
const selectValue = defineModel<string>('selectValue');
|
||||
const statusCode = defineModel<number>('statusCode');
|
||||
const props = defineProps<{
|
||||
value: {
|
||||
statusCode: number;
|
||||
selectValue: string;
|
||||
};
|
||||
}>();
|
||||
|
||||
const emit = defineEmits(['change']);
|
||||
const selectValue = ref<string>('');
|
||||
const statusCode = ref<number>(200);
|
||||
const showInput = computed(() => selectValue.value !== 'none' && selectValue.value !== '');
|
||||
|
||||
const { t } = useI18n();
|
||||
watchEffect(() => {
|
||||
selectValue.value = props.value.selectValue;
|
||||
statusCode.value = props.value.statusCode;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<template>
|
||||
<div>
|
||||
<paramsTable
|
||||
v-model:params="innerParams"
|
||||
:selectable="false"
|
||||
|
@ -8,12 +7,9 @@
|
|||
:default-param-item="defaultParamItem"
|
||||
@change="handleParamTableChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { defineModel } from 'vue';
|
||||
|
||||
import { statusCodeOptions } from '@/components/pure/ms-advance-filter/index';
|
||||
import paramsTable, { type ParamTableColumn } from '@/views/api-test/components/paramTable.vue';
|
||||
|
||||
|
@ -21,7 +17,11 @@
|
|||
[key: string]: any;
|
||||
}
|
||||
|
||||
const innerParams = defineModel<Param[]>('modelValue', { default: [] });
|
||||
const props = defineProps<{
|
||||
value?: Param[];
|
||||
}>();
|
||||
|
||||
const innerParams = ref(props.value || []);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'change'): void; // 数据发生变化
|
||||
|
|
|
@ -57,20 +57,41 @@
|
|||
<section class="ms-assertion-body-right">
|
||||
<StatusCodeTab
|
||||
v-if="valueKey === 'statusCode'"
|
||||
v-model:selectValue="codeTabState.selectValue"
|
||||
v-model:statusCode="codeTabState.statusCode"
|
||||
:value="codeTabState.statusCode"
|
||||
@change="(val) => handleChange(val, 'statusCode')"
|
||||
/>
|
||||
<ResponseHeaderTab
|
||||
v-if="valueKey === 'responseHeader'"
|
||||
:value="codeTabState.responseHeader"
|
||||
@change="(val) => handleChange(val, 'responseHeader')"
|
||||
/>
|
||||
<ResponseBodyTab
|
||||
v-if="valueKey === 'responseBody'"
|
||||
:value="codeTabState.responseBody"
|
||||
@change="(val) => handleChange(val, 'responseBody')"
|
||||
/>
|
||||
<ResponseTimeTab
|
||||
v-if="valueKey === 'responseTime'"
|
||||
:value="codeTabState.responseTime"
|
||||
@="(val) => handleChange(val, 'responseTime')"
|
||||
/>
|
||||
<VariableTab
|
||||
v-if="valueKey === 'variable'"
|
||||
:value="codeTabState.variable"
|
||||
@change="(val) => handleChange(val, 'variable')"
|
||||
/>
|
||||
<ScriptTab
|
||||
v-if="valueKey === 'script'"
|
||||
:value="codeTabState.script"
|
||||
@change="(val) => handleChange(val, 'script')"
|
||||
/>
|
||||
<ResponseHeaderTab v-if="valueKey === 'responseHeader'" />
|
||||
<ResponseBodyTab v-if="valueKey === 'responseBody'" />
|
||||
<ResponseTimeTab v-if="valueKey === 'responseTime'" />
|
||||
<VariableTab v-if="valueKey === 'variable'" />
|
||||
<ScriptTab v-if="valueKey === 'script'" />
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { defineModel } from 'vue';
|
||||
import { VueDraggable } from 'vue-draggable-plus';
|
||||
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
|
@ -86,7 +107,7 @@
|
|||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
|
||||
import { MsAssertionItem } from './type';
|
||||
import { MsAssertionItem, ValueObject } from './type';
|
||||
|
||||
defineOptions({
|
||||
name: 'MsAssertion',
|
||||
|
@ -96,17 +117,24 @@
|
|||
// 当前鼠标所在的key
|
||||
const focusKey = ref<string>('');
|
||||
// 选中的选项
|
||||
const selectItems = ref<MsAssertionItem[]>([]);
|
||||
const selectItems = defineModel<any[]>('params', { default: [] });
|
||||
// Item点击的key
|
||||
const activeKey = ref<string>('');
|
||||
// valueKey
|
||||
const valueKey = computed(() => {
|
||||
return activeKey.value && selectItems.value.find((item) => item.id === activeKey.value)?.value;
|
||||
});
|
||||
|
||||
const codeTabState = reactive({
|
||||
selectValue: '',
|
||||
statusCode: 200,
|
||||
// 存储当前页面的所有状态
|
||||
const codeTabState = computed({
|
||||
get: () => {
|
||||
return (selectItems.value.find((item) => item.id === activeKey.value)?.valueObj || {}) as ValueObject;
|
||||
},
|
||||
set: (val: ValueObject) => {
|
||||
const currentIndex = selectItems.value.findIndex((item) => item.id === val.assertionType);
|
||||
const tmpArr = selectItems.value;
|
||||
tmpArr[currentIndex].valueObj = { ...val };
|
||||
selectItems.value = tmpArr;
|
||||
},
|
||||
});
|
||||
const itemMoreActions: ActionsItem[] = [
|
||||
{
|
||||
|
@ -186,6 +214,10 @@
|
|||
const handleItemClick = (item: MsAssertionItem) => {
|
||||
activeKey.value = item.id;
|
||||
};
|
||||
|
||||
const handleChange = (val: any, key: string) => {
|
||||
codeTabState[key] = { ...val, assertionType: key };
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
export interface ValueObject {
|
||||
assertionType: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
export interface MsAssertionItem {
|
||||
id: string;
|
||||
label: string;
|
||||
value: string;
|
||||
valueObj: ValueObject;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,9 @@ export interface EnvConfigItem {
|
|||
export interface ProcessorConfig {
|
||||
apiProcessorConfig: ExecuteConditionProcessor[];
|
||||
}
|
||||
export interface AssertionConfig {
|
||||
assertions: EnvConfigItem[];
|
||||
}
|
||||
export interface EnvConfig {
|
||||
commonParams?: EnvConfigItem;
|
||||
commmonVariables: EnvConfigItem[];
|
||||
|
@ -42,7 +45,7 @@ export interface EnvConfig {
|
|||
hostConfig: EnvConfigItem;
|
||||
preProcessorConfig: ProcessorConfig;
|
||||
postProcessorConfig: ProcessorConfig;
|
||||
assertionConfig: EnvConfigItem[];
|
||||
assertionConfig: AssertionConfig;
|
||||
pluginConfigMap: EnvConfigItem;
|
||||
}
|
||||
export interface EnvDetailItem {
|
||||
|
|
|
@ -24,7 +24,7 @@ const envParmasDefaultConfig = {
|
|||
postProcessorConfig: {
|
||||
apiProcessorConfig: [],
|
||||
},
|
||||
assertionConfig: [],
|
||||
assertionConfig: { assertions: [] },
|
||||
pluginConfigMap: {},
|
||||
};
|
||||
|
||||
|
|
|
@ -77,10 +77,22 @@
|
|||
</template>
|
||||
{{ t('common.clear') }}
|
||||
</a-button>
|
||||
<a-button type="outline" class="arco-btn-outline--secondary p-[0_8px]" size="mini" @click="copyCondition">
|
||||
<a-button
|
||||
v-if="!props.isBuildIn"
|
||||
type="outline"
|
||||
class="arco-btn-outline--secondary p-[0_8px]"
|
||||
size="mini"
|
||||
@click="copyCondition"
|
||||
>
|
||||
{{ t('common.copy') }}
|
||||
</a-button>
|
||||
<a-button type="outline" class="arco-btn-outline--secondary p-[0_8px]" size="mini" @click="deleteCondition">
|
||||
<a-button
|
||||
v-if="!props.isBuildIn"
|
||||
type="outline"
|
||||
class="arco-btn-outline--secondary p-[0_8px]"
|
||||
size="mini"
|
||||
@click="deleteCondition"
|
||||
>
|
||||
{{ t('common.delete') }}
|
||||
</a-button>
|
||||
</div>
|
||||
|
@ -370,6 +382,7 @@
|
|||
data: ExecuteConditionProcessor;
|
||||
response?: string; // 响应内容
|
||||
heightUsed?: number;
|
||||
isBuildIn?: boolean; // 是否是内置的条件
|
||||
}>();
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:data', data: ExecuteConditionProcessor): void;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
</a-tabs>
|
||||
</div>
|
||||
<a-divider :margin="0" class="!mb-[16px]" />
|
||||
<div class="px-[24px]">
|
||||
<div class="content">
|
||||
<EnvParamsTab v-if="activeKey === 'envParams'" />
|
||||
<HttpTab v-else-if="activeKey === 'http'" />
|
||||
<DataBaseTab v-else-if="activeKey === 'database'" />
|
||||
|
@ -34,16 +34,21 @@
|
|||
<PostTab v-else-if="activeKey === 'post'" />
|
||||
<AssertTab v-else-if="activeKey === 'assert'" />
|
||||
<template v-for="item in envPluginList" :key="item.pluginId">
|
||||
<PluginTab v-if="activeKey === item.pluginId" :script="item.script" />
|
||||
<PluginTab
|
||||
v-if="activeKey === item.pluginId"
|
||||
:model-value="store.currentEnvDetailInfo.config.pluginConfigMap[item.pluginId]"
|
||||
:script="item.script"
|
||||
@update:model-value="store.currentEnvDetailInfo.config.pluginConfigMap[item.pluginId] = $event"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
<TabSettingDrawer v-model:visible="tabSettingVisible" @init-data="initTab" />
|
||||
|
||||
<div class="footer" :style="{ width: '100%' }">
|
||||
<a-button @click="handleReset">{{ t('common.cancel') }}</a-button>
|
||||
<a-button :disabled="!canSave" type="primary" @click="handleSave">{{ t('common.save') }}</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<TabSettingDrawer v-model:visible="tabSettingVisible" @init-data="initTab" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@ -148,6 +153,7 @@
|
|||
await initPlugin();
|
||||
await store.initContentTabList([...sourceTabList, ...pluginTabList.value]);
|
||||
contentTabList.value = ((await store.getContentTabList()) || []).filter((item) => item.isShow);
|
||||
// 插件状态存储
|
||||
|
||||
const handleReset = () => {
|
||||
envForm.value?.resetFields();
|
||||
|
@ -208,18 +214,24 @@
|
|||
|
||||
<style lang="less" scoped>
|
||||
.page {
|
||||
position: relative;
|
||||
transform: scale3d(1, 1, 1);
|
||||
padding-bottom: 180px;
|
||||
height: 100%;
|
||||
.header {
|
||||
padding: 24px 24px 0;
|
||||
}
|
||||
.content {
|
||||
overflow-y: auto;
|
||||
padding: 0 24px;
|
||||
max-height: calc(100% - 260px);
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.no-content {
|
||||
:deep(.arco-tabs-content) {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
.footer {
|
||||
gap: 16px;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
@ -227,7 +239,9 @@
|
|||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 24px;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0 -1px 4px rgb(2 2 2 / 10%);
|
||||
gap: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -4,16 +4,17 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import MsAssertion from '@/components/business/ms-assertion/index.vue';
|
||||
import { MsAssertionItem } from '@/components/business/ms-assertion/type';
|
||||
|
||||
import useProjectEnvStore from '@/store/modules/setting/useProjectEnvStore';
|
||||
|
||||
const store = useProjectEnvStore();
|
||||
|
||||
const params = computed({
|
||||
set: (value: any) => {
|
||||
store.currentEnvDetailInfo.config.assertionConfig = value;
|
||||
set: (value: any[]) => {
|
||||
store.currentEnvDetailInfo.config.assertionConfig.assertions = (value || []) as MsAssertionItem[];
|
||||
},
|
||||
get: () => store.currentEnvDetailInfo.config.assertionConfig || [],
|
||||
get: () => (store.currentEnvDetailInfo.config.assertionConfig.assertions || []) as MsAssertionItem[],
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -55,7 +55,12 @@
|
|||
<div>
|
||||
<!-- 环境list-->
|
||||
<div v-if="envList.length">
|
||||
<VueDraggable v-model="envList" ghost-class="ghost" handle=".drag-handle">
|
||||
<VueDraggable
|
||||
v-model="envList"
|
||||
ghost-class="ghost"
|
||||
handle=".drag-handle"
|
||||
@update="handleEnvGroupPosChange($event, EnvAuthTypeEnum.ENVIRONMENT_GROUP)"
|
||||
>
|
||||
<div
|
||||
v-for="element in envList"
|
||||
:key="element.id"
|
||||
|
@ -125,7 +130,7 @@
|
|||
v-model="evnGroupList"
|
||||
ghost-class="ghost"
|
||||
handle=".drag-handle"
|
||||
@update="handleEnvGroupPosChange"
|
||||
@update="handleEnvGroupPosChange($event, EnvAuthTypeEnum.ENVIRONMENT_GROUP)"
|
||||
>
|
||||
<div
|
||||
v-for="element in evnGroupList"
|
||||
|
@ -215,6 +220,7 @@
|
|||
import {
|
||||
deleteEnv,
|
||||
deleteEnvGroup,
|
||||
editPosEnv,
|
||||
exportEnv,
|
||||
exportGlobalParam,
|
||||
groupEditPosEnv,
|
||||
|
@ -380,7 +386,7 @@
|
|||
store.setCurrentGroupId(id);
|
||||
};
|
||||
// 排序更新
|
||||
const handleEnvGroupPosChange = async (event: SortableEvent) => {
|
||||
const handleEnvGroupPosChange = async (event: SortableEvent, type: EnvAuthTypeEnum) => {
|
||||
try {
|
||||
const { oldIndex, newIndex } = event;
|
||||
if (oldIndex === newIndex) {
|
||||
|
@ -394,7 +400,11 @@
|
|||
moveId: evnGroupList.value[_newIndex].id,
|
||||
moveMode: _oldIndex > _newIndex ? 'BEFORE' : 'AFTER',
|
||||
};
|
||||
if (type === EnvAuthTypeEnum.ENVIRONMENT) {
|
||||
await editPosEnv(params);
|
||||
} else if (type === EnvAuthTypeEnum.ENVIRONMENT_GROUP) {
|
||||
await groupEditPosEnv(params);
|
||||
}
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(e);
|
||||
|
|
Loading…
Reference in New Issue