fix(项目管理): 环境管理断言参数调整&部项目管理bug修复

This commit is contained in:
xinxin.wu 2024-03-11 10:01:32 +08:00 committed by 刘瑞斌
parent de60f207be
commit ad7bcaa7cf
9 changed files with 310 additions and 200 deletions

View File

@ -7,14 +7,16 @@
</a-radio>
</a-radio-group>
</div>
<div v-if="activeTab === 'jsonPath'" class="mt-[16px]">
<!-- jsonPath开始 -->
<div v-if="activeTab === ResponseBodyAssertionType.JSON_PATH" class="mt-[16px]">
<paramsTable
v-model:params="innerParams.jsonPath"
ref="extractParamsTableRef"
v-model:params="condition.jsonPathAssertion.assertions"
:selectable="false"
:columns="jsonPathColumns"
:scroll="{ minWidth: '700px' }"
:default-param-item="jsonPathDefaultParamItem"
@change="(data) => handleChange(data, 'jsonPath')"
@change="(data) => handleChange(data, ResponseBodyAssertionType.JSON_PATH)"
@more-action-select="(e,r)=> handleExtractParamMoreActionSelect(e,r as ExpressionConfig)"
>
<template #expression="{ record, rowIndex }">
@ -82,24 +84,22 @@
</template>
</paramsTable>
</div>
<div v-if="activeTab === 'xPath'" class="mt-[16px]">
<!-- jsonPath结束 -->
<!-- xPath开始 -->
<div v-if="activeTab === ResponseBodyAssertionType.XPATH" class="mt-[16px]">
<div class="text-[var(--color-text-1)]">{{ t('ms.assertion.responseContentType') }}</div>
<a-radio-group
v-model:model-value="innerParams.xPath.responseFormat"
class="mb-[16px] mt-[16px]"
type="button"
size="small"
>
<a-radio value="XML">XML</a-radio>
<a-radio value="HTML">HTML</a-radio>
<a-radio-group v-model="activeResponseFormat" class="mb-[16px] mt-[16px]" type="button" size="small">
<a-radio key="XML" value="XML">XML</a-radio>
<a-radio key="HTML" value="HTML">HTML</a-radio>
</a-radio-group>
<paramsTable
v-model:params="innerParams.xPath.data"
ref="extractParamsTableRef"
v-model:params="condition.xpathAssertion.assertions"
:selectable="false"
:columns="xPathColumns"
:scroll="{ minWidth: '700px' }"
:default-param-item="xPathDefaultParamItem"
@change="(data) => handleChange(data, 'xPath')"
@change="(data) => handleChange(data, ResponseBodyAssertionType.XPATH)"
@more-action-select="(e,r)=> handleExtractParamMoreActionSelect(e,r as ExpressionConfig)"
>
<template #expression="{ record, rowIndex }">
@ -167,22 +167,24 @@
</template>
</paramsTable>
</div>
<div v-if="activeTab === 'document'" class="relative mt-[16px]">
<!-- xPath结束 -->
<!-- document开始 -->
<div v-if="activeTab === ResponseBodyAssertionType.DOCUMENT" class="relative mt-[16px]">
<div class="text-[var(--color-text-1)]">
{{ t('ms.assertion.responseContentType') }}
</div>
<a-radio-group v-model:model-value="innerParams.document.responseFormat" class="mt-[16px]" size="small">
<a-radio-group v-model:model-value="condition.document.responseFormat" class="mt-[16px]" size="small">
<a-radio value="JSON">JSON</a-radio>
<a-radio value="XML">XML</a-radio>
</a-radio-group>
<div class="mt-[16px]">
<a-checkbox v-model:model-value="innerParams.document.followApi">
<a-checkbox v-model:model-value="condition.document.followApi">
<span class="text-[var(--color-text-1)]">{{ t('ms.assertion.followApi') }}</span>
</a-checkbox>
</div>
<div class="mt-[16px]">
<paramsTable
v-model:params="innerParams.document.data"
v-model:params="condition.document.jsonAssertion"
:selectable="false"
:columns="documentColumns"
:scroll="{
@ -193,7 +195,7 @@
:span-method="documentSpanMethod"
is-tree-table
@tree-delete="deleteAllParam"
@change="(data) => handleChange(data, 'document')"
@change="(data) => handleChange(data, ResponseBodyAssertionType.DOCUMENT)"
>
<template #matchValueDelete="{ record }">
<icon-minus-circle
@ -227,14 +229,17 @@
</paramsTable>
</div>
</div>
<div v-if="activeTab === 'regular'" class="mt-[16px]">
<!-- document结束 -->
<!-- 正则开始 -->
<div v-if="activeTab === ResponseBodyAssertionType.REGEX" class="mt-[16px]">
<paramsTable
v-model:params="innerParams.regular"
ref="extractParamsTableRef"
v-model:params="condition.regexAssertion.assertions"
:selectable="false"
:columns="xPathColumns"
:scroll="{ minWidth: '700px' }"
:default-param-item="xPathDefaultParamItem"
@change="(data) => handleChange(data, 'regular')"
@change="(data) => handleChange(data, ResponseBodyAssertionType.REGEX)"
@more-action-select="(e,r)=> handleExtractParamMoreActionSelect(e,r as ExpressionConfig)"
>
<template #expression="{ record, rowIndex }">
@ -302,14 +307,17 @@
</template>
</paramsTable>
</div>
<div v-if="activeTab === 'script'" class="mt-[16px]">
<conditionContent v-model:data="innerParams.script" :height-used="600" is-build-in class="mt-[16px]" />
</div>
<!-- 正则结束 -->
<!-- 这一版断言里边的脚本不需要 -->
<!-- <div v-if="activeTab === ResponseBodyAssertionType.SCRIPT" class="mt-[16px]">
<conditionContent v-model:data="condition.script" :height-used="600" is-build-in class="mt-[16px]" />
</div> -->
</div>
<fastExtraction v-model:visible="fastExtractionVisible" :config="activeRecord" @apply="handleFastExtractionApply" />
</template>
<script setup lang="ts">
import { useVModel } from '@vueuse/core';
import { TableColumnData, TableData } from '@arco-design/web-vue';
import { statusCodeOptions } from '@/components/pure/ms-advance-filter';
@ -345,6 +353,7 @@
RequestExtractExpressionRuleType,
RequestExtractResultMatchingRule,
RequestExtractScope,
ResponseBodyAssertionType,
ResponseBodyXPathAssertionFormat,
} from '@/enums/apiEnum';
@ -353,7 +362,7 @@
}
const emit = defineEmits<{
(e: 'update:data', data: ExecuteConditionProcessor): void;
// (e: 'update:data', data: ExecuteConditionProcessor): void;
(e: 'copy'): void;
(e: 'delete', id: number): void;
(e: 'change', param: Param): void;
@ -362,44 +371,43 @@
const rootId = 0; // 1970-01-01 00:00:00 UTC
const props = defineProps<{
value: Param;
data: Param;
}>();
const activeTab = ref(ResponseBodyAssertionType.JSON_PATH);
const activeResponseFormat = ref('XML');
const defaultParamItem = {
jsonPath: [],
xPath: { responseFormat: 'XML', data: [] },
document: {
data: [
{
id: rootId,
paramsName: 'root',
mustInclude: false,
typeChecking: false,
paramType: 'object',
matchCondition: '',
matchValue: '',
},
],
responseFormat: 'JSON',
followApi: false,
jsonPathAssertion: {
assertions: [],
},
script: {
id: new Date().getTime(),
processorType: RequestConditionProcessor.SCRIPT,
scriptName: '断言脚本名称',
enableCommonScript: false,
params: [],
scriptId: '',
scriptLanguage: RequestConditionScriptLanguage.JAVASCRIPT,
script: new Date().getTime().toString(),
xpathAssertion: { responseFormat: 'XML', assertions: [] },
assertionBodyType: activeTab.value,
regexAssertion: {
assertions: [],
},
// TODO
// documentAssertion: {
// jsonAssertion: [
// {
// id: rootId,
// paramsName: 'root',
// mustInclude: false,
// typeChecking: false,
// paramType: 'object',
// matchCondition: '',
// matchValue: '',
// },
// ],
// responseFormat: 'JSON',
// followApi: false,
// },
};
const innerParams = ref<Param>(props.value || defaultParamItem);
watchEffect(() => {
emit('change', innerParams.value);
});
const activeTab = ref('jsonPath');
const condition = useVModel(props, 'data', emit);
// const condition = ref<Param>(props.data || defaultParamItem);
// watchEffect(() => {
// emit('change', { ...condition.value });
// });
const extractParamsTableRef = ref<InstanceType<typeof paramsTable>>();
const fastExtractionVisible = ref(false);
const disabledExpressionSuffix = ref(false);
@ -422,11 +430,10 @@
const activeRecord = ref({ ...defaultExtractParamItem }); //
const responseRadios = [
{ label: 'ms.assertion.jsonPath', value: 'jsonPath' },
{ label: 'ms.assertion.xpath', value: 'xPath' },
{ label: 'ms.assertion.jsonPath', value: ResponseBodyAssertionType.JSON_PATH },
{ label: 'ms.assertion.xpath', value: ResponseBodyAssertionType.XPATH },
// { label: 'ms.assertion.document', value: 'document' },
{ label: 'ms.assertion.regular', value: 'regular' },
{ label: 'ms.assertion.script', value: 'script' },
{ label: 'ms.assertion.regular', value: ResponseBodyAssertionType.REGEX },
];
const jsonPathColumns: ParamTableColumn[] = [
@ -438,15 +445,15 @@
},
{
title: 'ms.assertion.matchCondition',
dataIndex: 'matchCondition',
slotName: 'matchCondition',
dataIndex: 'condition',
slotName: 'condition',
options: statusCodeOptions,
width: 120,
},
{
title: 'ms.assertion.matchValue',
dataIndex: 'matchValue',
slotName: 'matchValue',
dataIndex: 'expectedValue',
slotName: 'expectedValue',
},
{
title: '',
@ -469,19 +476,38 @@
const jsonPathDefaultParamItem = {
expression: '',
matchCondition: '',
matchValue: '',
enable: true,
condition: '',
expectedValue: '',
valid: true,
};
const handleChange = (data: any[], type: string) => {
if (type === 'jsonPath') {
innerParams.value.jsonPath = data;
} else if (type === 'xPath') {
innerParams.value.xPath.data = data;
} else if (type === 'document') {
innerParams.value.document.data = data;
} else if (type === 'regular') {
innerParams.value.regular = data;
switch (type) {
case ResponseBodyAssertionType.JSON_PATH:
if (data.length > 1) {
data.splice(data.length - 1, 1);
}
condition.value.jsonPathAssertion.assertions = data;
emit('change', { ...defaultParamItem, ...condition.value, assertionBodyType: activeTab.value });
break;
case ResponseBodyAssertionType.XPATH:
condition.value.xpathAssertion.assertions = data;
emit('change', {
...defaultParamItem,
...condition.value,
assertionBodyType: activeTab.value,
responseFormat: activeResponseFormat.value,
});
break;
case ResponseBodyAssertionType.DOCUMENT:
condition.value.documentAssertion.jsonAssertion = data;
break;
case ResponseBodyAssertionType.REGEX:
condition.value.regexAssertion.assertions = data;
emit('change', { ...defaultParamItem, ...condition.value, assertionBodyType: activeTab.value });
break;
default:
break;
}
};
function handleExpressionChange(rowIndex: number) {
@ -615,20 +641,22 @@
* 提取参数表格-保存快速提取的配置
*/
function handleFastExtractionApply(config: RegexExtract | JSONPathExtract | XPathExtract) {
// condition.value.extractParams = condition.value.extractParams?.map((e) => {
// if (e.id === activeRecord.value.id) {
// return {
// ...e,
// ...config,
// };
// }
// return e;
// });
// fastExtractionVisible.value = false;
// nextTick(() => {
// extractParamsTableRef.value?.addTableLine();
// });
// emit('change');
condition.value.jsonPathAssertion.assertions = condition.value.jsonPathAssertion.assertions?.map((e) => {
if (e.id === activeRecord.value.id) {
return {
...e,
...config,
};
}
return e;
});
fastExtractionVisible.value = false;
nextTick(() => {
extractParamsTableRef.value?.addTableLine(
condition.value.jsonPathAssertion.assertions?.findIndex((e) => e.id === activeRecord.value.id) || 0
);
});
emit('change', { ...condition.value });
}
/**
@ -672,9 +700,9 @@
const addValidateChild = (record: Record<string, any>) => {
if (record.groupId) {
//
const parent = innerParams.value.document.data.find((item: any) => item.id === record.groupId);
const parent = condition.value.documentAssertion.jsonAssertion.find((item: any) => item.id === record.groupId);
insertNode(
innerParams.value.document.data,
condition.value.documentAssertion.jsonAssertion,
{ id: record.id, groupId: record.groupId },
{
...record,
@ -688,18 +716,18 @@
parent.rowSpan = parent.rowSpan ? parent.rowSpan + 1 : 2;
} else {
//
const fisrtChildNode = findFirstByGroupId(innerParams.value.document.data, record.groupId);
const fisrtChildNode = findFirstByGroupId(condition.value.documentAssertion.jsonAssertion, record.groupId);
if (fisrtChildNode) {
fisrtChildNode.rowSpan = fisrtChildNode.rowSpan
? fisrtChildNode.rowSpan + 1
: countNodesByGroupId(innerParams.value.document.data, record.groupId) + 1;
: countNodesByGroupId(condition.value.documentAssertion.jsonAssertion, record.groupId) + 1;
}
}
} else {
record.rowSpan = record.rowSpan ? record.rowSpan + 1 : 2;
//
insertNode(
innerParams.value.document.data,
condition.value.documentAssertion.jsonAssertion,
{ id: record.id, groupId: record.groupId },
{
...record,
@ -712,23 +740,23 @@
}
};
const showDeleteSingle = computed(() => {
return countNodes(innerParams.value.document.data) > 1;
return countNodes(condition.value.documentAssertion.jsonAssertion) > 1;
});
const deleteSingleParam = (record: Record<string, any>) => {
deleteNodeById(innerParams.value.document.data, record.id);
deleteNodeById(condition.value.documentAssertion.jsonAssertion, record.id);
};
const deleteAllParam = (record: Record<string, any>) => {
if (record.groupId) {
// ,groupId
deleteNodesByGroupId(innerParams.value.document.data, record.groupId);
deleteNodesByGroupId(condition.value.documentAssertion.jsonAssertion, record.groupId);
} else if (record.rowspan > 2) {
// , id groupId
deleteNodesByGroupId(innerParams.value.document.data, record.id);
deleteNodesByGroupId(condition.value.documentAssertion.jsonAssertion, record.id);
//
deleteNodeById(innerParams.value.document.data, record.id);
deleteNodeById(condition.value.documentAssertion.jsonAssertion, record.id);
} else {
//
deleteNodeById(innerParams.value.document.data, record.id);
deleteNodeById(condition.value.documentAssertion.jsonAssertion, record.id);
}
};
@ -752,6 +780,6 @@
}
};
const handleScriptChange = (data: ExecuteConditionProcessor) => {
innerParams.value.script = data;
condition.value.script = data;
};
</script>

View File

@ -11,86 +11,101 @@
<a-doption v-for="item in assertOptionSource" :key="item.value" :value="item.value">{{ item.label }}</a-doption>
</template>
</a-dropdown>
<div v-if="showBody" class="ms-assertion-body">
<VueDraggable v-model="assertions" class="ms-assertion-body-left" ghost-class="ghost" handle=".sort-handle">
<div
v-for="(item, index) in assertions"
:key="item.id"
class="ms-assertion-body-left-item"
:class="{
'ms-assertion-body-left-item-active': activeKey === item.id,
'ms-assertion-body-left-item-active-focus': focusKey === item.id,
}"
@click="handleItemClick(item)"
>
<div class="ms-assertion-body-left-item-row">
<span class="ms-assertion-body-left-item-row-num">{{ index + 1 }}</span>
<span class="ms-assertion-body-left-item-row-title">{{ item.name }}</span>
</div>
<div class="ms-assertion-body-left-item-switch">
<div class="ms-assertion-body-left-item-switch-action">
<MsIcon
type="icon-icon_drag"
class="action-btn-move sort-handle cursor-move text-[12px] text-[var(--color-text-4)]"
/>
<MsTableMoreAction
:list="itemMoreActions"
trigger="click"
@select="handleMoreActionSelect($event, item)"
@close="focusKey = ''"
>
<MsButton type="icon" size="mini" class="action-btn-more">
<MsIcon
type="icon-icon_more_outlined"
size="14"
class="text-[var(--color-text-4)]"
@click="focusKey = item.id"
/>
</MsButton>
</MsTableMoreAction>
</div>
<a-switch v-model:model-value="item.enable" type="line" size="small" />
<div v-if="showBody" class="ms-assertion-body">
<a-scrollbar
:style="{
overflow: 'auto',
height: 'calc(100vh - 458px)',
}"
>
<VueDraggable v-model="assertions" class="ms-assertion-body-left" ghost-class="ghost" handle=".sort-handle">
<div
v-for="(item, index) in assertions"
:key="item.id"
class="ms-assertion-body-left-item"
:class="{
'ms-assertion-body-left-item-active': activeKey === item.id,
'ms-assertion-body-left-item-active-focus': focusKey === item.id,
}"
@click="handleItemClick(item)"
>
<div class="ms-assertion-body-left-item-row">
<span class="ms-assertion-body-left-item-row-num">{{ index + 1 }}</span>
<span class="ms-assertion-body-left-item-row-title">{{ item.name }}</span>
</div>
<div class="ms-assertion-body-left-item-switch">
<div class="ms-assertion-body-left-item-switch-action">
<MsIcon
type="icon-icon_drag"
class="action-btn-move sort-handle cursor-move text-[12px] text-[var(--color-text-4)]"
/>
<MsTableMoreAction
:list="itemMoreActions"
trigger="click"
@select="handleMoreActionSelect($event, item)"
@close="focusKey = ''"
>
<MsButton type="icon" size="mini" class="action-btn-more">
<MsIcon
type="icon-icon_more_outlined"
size="14"
class="text-[var(--color-text-4)]"
@click="focusKey = item.id"
/>
</MsButton>
</MsTableMoreAction>
</div>
<a-switch v-model:model-value="item.enable" type="line" size="small" />
</div>
</div>
</div>
</VueDraggable>
</VueDraggable>
</a-scrollbar>
<section class="ms-assertion-body-right">
<!-- 响应头 -->
<ResponseHeaderTab
v-if="valueKey === ResponseAssertionType.RESPONSE_HEADER"
v-model:data="getCurrentItemState"
@change="handleChange"
/>
<!-- 状态码 -->
<StatusCodeTab
v-if="valueKey === ResponseAssertionType.RESPONSE_CODE"
v-model:data="getCurrentItemState"
@change="handleChange"
/>
<!-- 响应体 -->
<ResponseBodyTab
v-if="valueKey === ResponseAssertionType.RESPONSE_BODY"
:value="getCurrentItemState"
@change="handleChange"
/>
<!-- 响应时间 -->
<ResponseTimeTab
v-if="valueKey === ResponseAssertionType.RESPONSE_TIME"
v-model:data="getCurrentItemState"
@change="handleChange"
/>
<!-- 变量 -->
<VariableTab
v-if="valueKey === ResponseAssertionType.VARIABLE"
v-model:data="getCurrentItemState"
@change="handleChange"
/>
<!-- 脚本 -->
<ScriptTab
v-if="valueKey === ResponseAssertionType.SCRIPT"
:value="getCurrentItemState"
@change="handleChange"
/>
<a-scrollbar
:style="{
overflow: 'auto',
height: '200px',
}"
>
<!-- 响应头 -->
<ResponseHeaderTab
v-if="valueKey === ResponseAssertionType.RESPONSE_HEADER"
v-model:data="getCurrentItemState"
@change="handleChange"
/>
<!-- 状态码 -->
<StatusCodeTab
v-if="valueKey === ResponseAssertionType.RESPONSE_CODE"
v-model:data="getCurrentItemState"
@change="handleChange"
/>
<!-- 响应体 -->
<ResponseBodyTab
v-if="valueKey === ResponseAssertionType.RESPONSE_BODY"
v-model:data="getCurrentItemState"
@change="handleChange"
/>
<!-- 响应时间 -->
<ResponseTimeTab
v-if="valueKey === ResponseAssertionType.RESPONSE_TIME"
v-model:data="getCurrentItemState"
@change="handleChange"
/>
<!-- 变量 -->
<VariableTab
v-if="valueKey === ResponseAssertionType.VARIABLE"
v-model:data="getCurrentItemState"
@change="handleChange"
/>
<!-- 脚本 -->
<ScriptTab
v-if="valueKey === ResponseAssertionType.SCRIPT"
:value="getCurrentItemState"
@change="handleChange"
/>
</a-scrollbar>
</section>
</div>
</div>
@ -133,11 +148,50 @@
const valueKey = computed(() => {
return activeKey.value && assertions.value.find((item) => item.id === activeKey.value)?.assertionType;
});
const defaultResBodyItem = {
jsonPathAssertion: {
assertions: [],
},
xpathAssertion: { responseFormat: 'XML', assertions: [] },
assertionBodyType: '',
regexAssertion: {
assertions: [],
},
// TODO
// documentAssertion: {
// jsonAssertion: [
// {
// id: rootId,
// paramsName: 'root',
// mustInclude: false,
// typeChecking: false,
// paramType: 'object',
// matchCondition: '',
// matchValue: '',
// },
// ],
// responseFormat: 'JSON',
// followApi: false,
// },
};
//
const getCurrentItemState = computed({
get: () => {
return assertions.value.find((item) => item.id === activeKey.value);
const currentResItem =
assertions.value.find((item: any) => item.id === activeKey.value) || assertions.value[0] || {};
if (currentResItem && currentResItem?.assertionType === ResponseAssertionType.RESPONSE_BODY) {
const { jsonPathAssertion, xpathAssertion, regexAssertion } = currentResItem;
return {
...currentResItem,
jsonPathAssertion: jsonPathAssertion || defaultResBodyItem.jsonPathAssertion,
xpathAssertion: xpathAssertion || defaultResBodyItem.xpathAssertion,
assertionBodyType: '',
regexAssertion: regexAssertion || defaultResBodyItem.regexAssertion,
bodyAssertionDataByType: {},
};
}
return currentResItem;
},
set: (val: ExecuteAssertion) => {
const currentIndex = assertions.value.findIndex((item) => item.id === activeKey.value);
@ -223,11 +277,12 @@
assertions: [],
},
xpathAssertion: {
responseFormat: 'XML',
assertions: [],
},
regexAssertion: {
assertions: [],
},
// regexAssertion: {
// assertions: [],
// },
bodyAssertionDataByType: {},
});
break;
@ -284,6 +339,7 @@
getCurrentItemState.value = { ...val };
break;
case ResponseAssertionType.RESPONSE_BODY:
getCurrentItemState.value = { ...val };
break;
case ResponseAssertionType.RESPONSE_TIME:
getCurrentItemState.value = { ...val };
@ -300,7 +356,9 @@
};
watchEffect(() => {
console.log(getCurrentItemState.value);
getCurrentItemState.value =
assertions.value.find((item: any) => item.id === activeKey.value) || assertions.value[0] || {};
activeKey.value = getCurrentItemState.value.id;
});
</script>
@ -317,7 +375,6 @@
padding: 12px;
width: 216px;
min-width: 216px;
height: calc(100vh - 394px);
background-color: var(--color-text-n9);
flex-direction: column;
gap: 4px;

View File

@ -119,4 +119,8 @@ export const editorProps = {
type: Boolean as PropType<boolean>,
default: false,
},
widthClass: {
type: String as PropType<string>,
default: '',
},
};

View File

@ -68,10 +68,9 @@ export const MEMBER = {
value: '',
options: [],
props: {
'multiple': false,
multiple: false,
// 'placeholder': t('formCreate.PleaseSelect'),
'modelValue': '',
'allow-clear': true,
modelValue: '',
},
};
@ -82,11 +81,10 @@ export const MULTIPLE_MEMBER = {
value: [],
options: [],
props: {
'multiple': true,
multiple: true,
// 'placeholder': t('formCreate.PleaseSelect'),
'options': [],
'modelValue': [],
'allow-clear': true,
options: [],
modelValue: [],
},
};

View File

@ -657,7 +657,7 @@ export const pathMap: PathMapItem[] = [
level: MENU_LEVEL[2],
},
{
key: 'PROJECT_MANAGEMENT_COMMON_SCRIPT', // 项目管理-公共脚本
key: ' PROJECT_CUSTOM_FUNCTION', // 项目管理-公共脚本
locale: 'menu.projectManagement.commonScript',
route: RouteEnum.PROJECT_MANAGEMENT_COMMON_SCRIPT,
permission: [],

View File

@ -113,6 +113,7 @@ export enum ResponseBodyAssertionType {
JSON_PATH = 'JSON_PATH',
REGEX = 'REGEX', // 正则表达式
XPATH = 'XPATH',
SCRIPT = 'SCRIPT',
}
// 接口断言-响应体断言-文档类型
export enum ResponseBodyAssertionDocumentType {

View File

@ -270,6 +270,7 @@
import { useI18n } from '@/hooks/useI18n';
import useAppStore from '@/store/modules/app';
import useFeatureCaseStore from '@/store/modules/case/featureCase';
import useUserStore from '@/store/modules/user';
import { downloadByteFile, getGenerateId } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
@ -279,12 +280,15 @@
CreateOrUpdateCase,
CustomAttributes,
DetailCase,
OptionsFieldId,
StepList,
} from '@/models/caseManagement/featureCase';
import type { ModuleTreeNode, TableQueryParams } from '@/models/common';
import { convertToFile, initFormCreate } from './utils';
const userStore = useUserStore();
const { t } = useI18n();
const route = useRoute();
const appStore = useAppStore();
@ -382,16 +386,33 @@
const { customFields, id } = res;
form.value.templateId = id;
const result = customFields.map((item: any) => {
const memberType = ['MEMBER', 'MULTIPLE_MEMBER'];
let initValue = item.defaultValue;
let optionsValue: OptionsFieldId[] = item.options;
if (memberType.includes(item.type)) {
optionsValue = [
{
fieldId: item.fieldId,
internal: item.internal,
text: userStore.name || '',
value: userStore.id || '',
},
];
if (item.defaultValue === 'CREATE_USER') {
initValue = item.type === 'MEMBER' ? userStore.id : [userStore.id];
}
}
return {
type: item.type,
name: item.fieldId,
label: item.fieldName,
value: item.defaultValue,
value: initValue,
required: item.required,
options: item.options || [],
props: {
modelValue: item.defaultValue,
options: item.options || [],
modelValue: initValue,
options: optionsValue || [],
},
};
});

View File

@ -119,7 +119,7 @@
tableSelectData: DefinedFieldItem[]; //
}>();
const emit = defineEmits(['confirm', 'update:visible', 'update-data']);
const emit = defineEmits(['confirm', 'update:visible', 'update-data', 'brash']);
const totalList = ref<DefinedFieldItem[]>([]);
@ -229,9 +229,9 @@
showAddDrawer.value = false;
};
const okHandler = () => {
const okHandler = (editFlag: boolean, fieldId: string) => {
// eslint-disable-next-line vue/custom-event-name-casing
emit('update-data');
emit('update-data', editFlag, fieldId);
};
watch(

View File

@ -182,6 +182,7 @@
:table-select-data="(selectData as DefinedFieldItem[])"
:mode="props.mode"
@confirm="confirmHandler"
@update-data="updateFieldHandler"
/>
<EditFieldDrawer
ref="fieldDrawerRef"