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

View File

@ -11,7 +11,14 @@
<a-doption v-for="item in assertOptionSource" :key="item.value" :value="item.value">{{ item.label }}</a-doption> <a-doption v-for="item in assertOptionSource" :key="item.value" :value="item.value">{{ item.label }}</a-doption>
</template> </template>
</a-dropdown> </a-dropdown>
<div v-if="showBody" class="ms-assertion-body"> <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"> <VueDraggable v-model="assertions" class="ms-assertion-body-left" ghost-class="ghost" handle=".sort-handle">
<div <div
v-for="(item, index) in assertions" v-for="(item, index) in assertions"
@ -54,7 +61,14 @@
</div> </div>
</div> </div>
</VueDraggable> </VueDraggable>
</a-scrollbar>
<section class="ms-assertion-body-right"> <section class="ms-assertion-body-right">
<a-scrollbar
:style="{
overflow: 'auto',
height: '200px',
}"
>
<!-- 响应头 --> <!-- 响应头 -->
<ResponseHeaderTab <ResponseHeaderTab
v-if="valueKey === ResponseAssertionType.RESPONSE_HEADER" v-if="valueKey === ResponseAssertionType.RESPONSE_HEADER"
@ -70,7 +84,7 @@
<!-- 响应体 --> <!-- 响应体 -->
<ResponseBodyTab <ResponseBodyTab
v-if="valueKey === ResponseAssertionType.RESPONSE_BODY" v-if="valueKey === ResponseAssertionType.RESPONSE_BODY"
:value="getCurrentItemState" v-model:data="getCurrentItemState"
@change="handleChange" @change="handleChange"
/> />
<!-- 响应时间 --> <!-- 响应时间 -->
@ -91,6 +105,7 @@
:value="getCurrentItemState" :value="getCurrentItemState"
@change="handleChange" @change="handleChange"
/> />
</a-scrollbar>
</section> </section>
</div> </div>
</div> </div>
@ -133,11 +148,50 @@
const valueKey = computed(() => { const valueKey = computed(() => {
return activeKey.value && assertions.value.find((item) => item.id === activeKey.value)?.assertionType; 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({ const getCurrentItemState = computed({
get: () => { 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) => { set: (val: ExecuteAssertion) => {
const currentIndex = assertions.value.findIndex((item) => item.id === activeKey.value); const currentIndex = assertions.value.findIndex((item) => item.id === activeKey.value);
@ -223,11 +277,12 @@
assertions: [], assertions: [],
}, },
xpathAssertion: { xpathAssertion: {
responseFormat: 'XML',
assertions: [], assertions: [],
}, },
regexAssertion: { // regexAssertion: {
assertions: [], // assertions: [],
}, // },
bodyAssertionDataByType: {}, bodyAssertionDataByType: {},
}); });
break; break;
@ -284,6 +339,7 @@
getCurrentItemState.value = { ...val }; getCurrentItemState.value = { ...val };
break; break;
case ResponseAssertionType.RESPONSE_BODY: case ResponseAssertionType.RESPONSE_BODY:
getCurrentItemState.value = { ...val };
break; break;
case ResponseAssertionType.RESPONSE_TIME: case ResponseAssertionType.RESPONSE_TIME:
getCurrentItemState.value = { ...val }; getCurrentItemState.value = { ...val };
@ -300,7 +356,9 @@
}; };
watchEffect(() => { 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> </script>
@ -317,7 +375,6 @@
padding: 12px; padding: 12px;
width: 216px; width: 216px;
min-width: 216px; min-width: 216px;
height: calc(100vh - 394px);
background-color: var(--color-text-n9); background-color: var(--color-text-n9);
flex-direction: column; flex-direction: column;
gap: 4px; gap: 4px;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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