feat(项目管理): 环境管理前后置条件限制和组件扩展

This commit is contained in:
xinxin.wu 2024-03-07 14:06:07 +08:00 committed by 刘瑞斌
parent daf58ceeb3
commit 79c382e536
6 changed files with 123 additions and 8 deletions

View File

@ -399,7 +399,7 @@
watchEffect(() => {
emit('change', innerParams.value);
});
const activeTab = ref('document');
const activeTab = ref('jsonPath');
const extractParamsTableRef = ref<InstanceType<typeof paramsTable>>();
const fastExtractionVisible = ref(false);
const disabledExpressionSuffix = ref(false);

View File

@ -8,6 +8,8 @@ export const conditionTypeNameMap = {
[RequestConditionProcessor.SQL]: 'apiTestDebug.sql',
[RequestConditionProcessor.TIME_WAITING]: 'apiTestDebug.waitTime',
[RequestConditionProcessor.EXTRACT]: 'apiTestDebug.extractParameter',
[RequestConditionProcessor.SCENARIO_SCRIPT]: 'apiTestDebug.script',
[RequestConditionProcessor.REQUEST_SCRIPT]: 'apiTestDebug.script',
};
// 代码字符集
export const codeCharset = ['UTF-8', 'UTF-16', 'GBK', 'GB2312', 'ISO-8859-1', 'Shift_JIS', 'ASCII', 'BIG5', 'KOI8-R'];

View File

@ -10,8 +10,14 @@
>
<!-- 前后置请求开始 -->
<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-group
v-model="condition.beforeStepScript"
type="button"
size="small"
:default-value="true"
:disabled="hasPreAndPost"
>
<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')">
@ -446,6 +452,7 @@
showAssociatedScene?: boolean; //
requestRadioTextProps?: Record<string, any>; //
showPrePostRequest?: boolean; //
totalList?: ExecuteConditionProcessor[]; //
}>(),
{
showAssociatedScene: false,
@ -808,6 +815,20 @@ if (!result){
console.log(error);
}
});
const hasPreAndPost = computed(() => {
if (props.showPrePostRequest) {
return (
(props?.totalList || []).filter(
(item) => item.beforeStepScript && item.processorType === RequestConditionProcessor.REQUEST_SCRIPT
).length > 0 &&
(props?.totalList || []).filter(
(item) => !item.beforeStepScript && item.processorType === RequestConditionProcessor.REQUEST_SCRIPT
).length > 0
);
}
return true;
});
</script>
<style lang="less" scoped>

View File

@ -22,12 +22,15 @@
<conditionList
v-model:list="data"
:active-id="activeItem.id"
:show-associated-scene="props.showAssociatedScene"
:show-pre-post-request="props.showPrePostRequest"
@active-change="handleListActiveChange"
@change="emit('change')"
/>
</div>
<conditionContent
v-model:data="activeItem"
:total-list="data"
:response="props.response"
:height-used="props.heightUsed"
:show-associated-scene="props.showAssociatedScene"
@ -120,6 +123,17 @@
} else if (props.showPrePostRequest) {
type = RequestConditionProcessor.REQUEST_SCRIPT;
}
const isExistPre = data.value.filter(
(item) => item.beforeStepScript && item.processorType === RequestConditionProcessor.REQUEST_SCRIPT
).length;
const isExistPost = data.value.filter(
(item) => !item.beforeStepScript && item.processorType === RequestConditionProcessor.REQUEST_SCRIPT
).length;
//
if (isExistPre && isExistPost && props.showPrePostRequest) {
return;
}
data.value.push({
id,
processorType: type,
@ -127,7 +141,7 @@
enableCommonScript: false,
associateScenarioResult: false,
ignoreProtocols: [],
beforeStepScript: true,
beforeStepScript: !isExistPre,
enable: true,
script: '',
scriptId: '',
@ -140,8 +154,14 @@
scriptLanguage: LanguageEnum.BEANSHELL,
},
});
break;
case RequestConditionProcessor.SQL:
const isSQL = data.value.find((item) => item.processorType === RequestConditionProcessor.SQL);
if (props.showPrePostRequest && isSQL) {
return;
}
data.value.push({
id,
processorType: RequestConditionProcessor.SQL,
@ -160,6 +180,7 @@
variables: [],
extractParams: [],
});
break;
case RequestConditionProcessor.TIME_WAITING:
data.value.push({

View File

@ -8,7 +8,7 @@
:item-border="false"
class="h-full rounded-[var(--border-radius-small)] bg-[var(--color-text-n9)] p-[12px]"
item-class="mb-[4px] bg-white !p-[4px_8px]"
:item-more-actions="itemMoreActions"
:item-more-actions="moreActions"
active-item-class="!bg-[rgb(var(--primary-1))] text-[rgb(var(--primary-5))]"
draggable
@item-click="handleItemClick"
@ -31,8 +31,18 @@
>
{{ `${t('apiTestDebug.wait')}${item.delay}` }} ms
</div>
<div v-else>
<div v-else class="flex items-center">
{{ t(conditionTypeNameMap[item.processorType]) }}
<a-badge
v-if="item.processorType === RequestConditionProcessor.REQUEST_SCRIPT"
class="ml-1 mt-[2px]"
:text="
item.beforeStepScript
? t('project.environmental.preOrPost.pre')
: t('project.environmental.preOrPost.post')
"
/>
</div>
</div>
</template>
@ -57,6 +67,8 @@
const props = defineProps<{
list: ExecuteConditionProcessor[];
activeId?: string | number;
showAssociatedScene?: boolean;
showPrePostRequest?: boolean; //
}>();
const emit = defineEmits<{
(e: 'update:list', list: ExecuteConditionProcessor[]): void;
@ -71,10 +83,30 @@
const focusItemKey = ref<any>('');
//
const activeItem = ref<ExecuteConditionProcessor>({} as ExecuteConditionProcessor);
const hasPreAndPost = computed(() => {
if (props.showPrePostRequest) {
const hasPre =
data.value.filter(
(item) => item.beforeStepScript && item.processorType === RequestConditionProcessor.REQUEST_SCRIPT
).length > 0;
const hasPost =
data.value.filter(
(item) => !item.beforeStepScript && item.processorType === RequestConditionProcessor.REQUEST_SCRIPT
).length > 0;
if (hasPre && hasPost) {
return true;
}
return false;
}
return false;
});
const itemMoreActions: ActionsItem[] = [
{
label: 'common.copy',
eventTag: 'copy',
disabled: hasPreAndPost.value,
},
{
label: 'common.delete',
@ -82,6 +114,18 @@
},
];
let moreActions: ActionsItem[] = [...itemMoreActions];
watch(
() => hasPreAndPost.value,
(val) => {
if (val) {
moreActions = itemMoreActions.slice(-1);
} else {
moreActions = itemMoreActions;
}
}
);
watchEffect(() => {
activeItem.value = data.value.find((item) => item.id === props.activeId) || data.value[0] || {};
emit('activeChange', activeItem.value);
@ -97,10 +141,28 @@
* @param item 列表项
*/
function copyListItem(item: ExecuteConditionProcessor) {
const copyItem = {
let copyItem = {
...item,
id: new Date().getTime(),
};
const isExistPre = data.value.filter(
(current) => current.beforeStepScript && current.processorType === RequestConditionProcessor.REQUEST_SCRIPT
).length;
const isExistPost = data.value.filter(
(current) => !current.beforeStepScript && current.processorType === RequestConditionProcessor.REQUEST_SCRIPT
).length;
//
if (isExistPre && isExistPost && props.showPrePostRequest) {
return;
}
copyItem = {
...item,
beforeStepScript: !isExistPre,
id: new Date().getTime(),
};
data.value.push(copyItem);
activeItem.value = copyItem;
emit('activeChange', activeItem.value);
@ -132,4 +194,11 @@
}
</script>
<style lang="less" scoped></style>
<style lang="less" scoped>
:deep(.arco-badge-text) {
font-size: 12px;
color: var(--color-text-4) !important;
background: white !important;
box-shadow: 0 0 0 1px var(--color-text-n8);
}
</style>

View File

@ -114,4 +114,6 @@ export default {
'project.environmental.http.postTextPreTip': '后置脚本前,环境中脚本在请求的置脚本执行前执行;',
'project.environmental.http.postTextPostTip': '后置脚本后,环境中脚本在请求的前置脚本执行后执行;',
'project.environmental.preOrPost.ignoreProtocols': '忽略请求:',
'project.environmental.preOrPost.pre': '脚本前',
'project.environmental.preOrPost.post': '脚本后',
};