fix(接口测试): 后置条件公共脚本参数修改不生效修复

--bug=1051974 --user=白奇 【接口测试】github#34965 https://www.tapd.cn/55049933/s/1657572
This commit is contained in:
baiqi 2025-02-24 15:46:19 +08:00 committed by Craftsman
parent bae19b0d86
commit c5da98320b
7 changed files with 55 additions and 36 deletions

View File

@ -62,6 +62,13 @@
"watch": true, "watch": true,
"watchEffect": true, "watchEffect": true,
"watchPostEffect": true, "watchPostEffect": true,
"watchSyncEffect": true "watchSyncEffect": true,
"DirectiveBinding": true,
"MaybeRef": true,
"MaybeRefOrGetter": true,
"onWatcherCleanup": true,
"useId": true,
"useModel": true,
"useTemplateRef": true
} }
} }

View File

@ -35,6 +35,7 @@ declare global {
const onServerPrefetch: typeof import('vue')['onServerPrefetch'] const onServerPrefetch: typeof import('vue')['onServerPrefetch']
const onUnmounted: typeof import('vue')['onUnmounted'] const onUnmounted: typeof import('vue')['onUnmounted']
const onUpdated: typeof import('vue')['onUpdated'] const onUpdated: typeof import('vue')['onUpdated']
const onWatcherCleanup: typeof import('vue')['onWatcherCleanup']
const provide: typeof import('vue')['provide'] const provide: typeof import('vue')['provide']
const reactive: typeof import('vue')['reactive'] const reactive: typeof import('vue')['reactive']
const readonly: typeof import('vue')['readonly'] const readonly: typeof import('vue')['readonly']
@ -52,7 +53,10 @@ declare global {
const useAttrs: typeof import('vue')['useAttrs'] const useAttrs: typeof import('vue')['useAttrs']
const useCssModule: typeof import('vue')['useCssModule'] const useCssModule: typeof import('vue')['useCssModule']
const useCssVars: typeof import('vue')['useCssVars'] const useCssVars: typeof import('vue')['useCssVars']
const useId: typeof import('vue')['useId']
const useModel: typeof import('vue')['useModel']
const useSlots: typeof import('vue')['useSlots'] const useSlots: typeof import('vue')['useSlots']
const useTemplateRef: typeof import('vue')['useTemplateRef']
const watch: typeof import('vue')['watch'] const watch: typeof import('vue')['watch']
const watchEffect: typeof import('vue')['watchEffect'] const watchEffect: typeof import('vue')['watchEffect']
const watchPostEffect: typeof import('vue')['watchPostEffect'] const watchPostEffect: typeof import('vue')['watchPostEffect']
@ -61,6 +65,6 @@ declare global {
// for type re-export // for type re-export
declare global { declare global {
// @ts-ignore // @ts-ignore
export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue' export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
import('vue') import('vue')
} }

View File

@ -196,9 +196,9 @@
{{ t('ms.paramsInput.value') }} {{ t('ms.paramsInput.value') }}
</div> </div>
<div class="ms-params-popover-value mb-[8px]"> <div class="ms-params-popover-value mb-[8px]">
{{ innerValue }} {{ value }}
</div> </div>
<template v-if="/^@/.test(innerValue)"> <template v-if="/^@/.test(value)">
<div class="ms-params-popover-subtitle"> <div class="ms-params-popover-subtitle">
{{ t('ms.paramsInput.preview') }} {{ t('ms.paramsInput.preview') }}
</div> </div>
@ -209,7 +209,7 @@
</template> </template>
<a-auto-complete <a-auto-complete
ref="autoCompleteRef" ref="autoCompleteRef"
v-model:model-value="innerValue" v-model:model-value="value"
:disabled="props.disabled" :disabled="props.disabled"
:data="autoCompleteParams" :data="autoCompleteParams"
:placeholder="t('ms.paramsInput.placeholder', { at: '@' })" :placeholder="t('ms.paramsInput.placeholder', { at: '@' })"
@ -253,7 +253,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { useEventListener, useStorage, useVModel } from '@vueuse/core'; import { useEventListener, useStorage } from '@vueuse/core';
import { cloneDeep } from 'lodash-es'; import { cloneDeep } from 'lodash-es';
import MsButton from '@/components/pure/ms-button/index.vue'; import MsButton from '@/components/pure/ms-button/index.vue';
@ -277,7 +277,6 @@
import type { AutoComplete, FormInstance } from '@arco-design/web-vue'; import type { AutoComplete, FormInstance } from '@arco-design/web-vue';
const props = defineProps<{ const props = defineProps<{
value: string;
disabled?: boolean; disabled?: boolean;
size?: 'small' | 'large' | 'medium' | 'mini'; size?: 'small' | 'large' | 'medium' | 'mini';
setDefaultClass?: boolean; setDefaultClass?: boolean;
@ -291,7 +290,9 @@
}>(); }>();
const { t } = useI18n(); const { t } = useI18n();
const innerValue = useVModel(props, 'value', emit); const value = defineModel<string>('value', {
required: true,
});
const autoCompleteParams = ref<MockParamItem[]>([]); const autoCompleteParams = ref<MockParamItem[]>([]);
const isFocusAutoComplete = ref(false); const isFocusAutoComplete = ref(false);
const popoverVisible = ref(false); const popoverVisible = ref(false);
@ -371,11 +372,7 @@
}); });
const disabledPopover = computed(() => { const disabledPopover = computed(() => {
return ( return !value.value || (typeof value.value === 'string' && value.value.trim() === '') || isFocusAutoComplete.value;
!innerValue.value ||
(typeof innerValue.value === 'string' && innerValue.value.trim() === '') ||
isFocusAutoComplete.value
);
}); });
const paramSettingVisible = ref(false); const paramSettingVisible = ref(false);
@ -483,17 +480,17 @@
* 打开变量设置弹窗 * 打开变量设置弹窗
*/ */
function openParamSetting() { function openParamSetting() {
if (/^\$/.test(innerValue.value)) { if (/^\$/.test(value.value)) {
// JMeter // JMeter
paramSettingType.value = 'jmeter'; paramSettingType.value = 'jmeter';
if (JMeterAllVars.findIndex((e) => e.value === innerValue.value) !== -1) { if (JMeterAllVars.findIndex((e) => e.value === value.value) !== -1) {
paramForm.value.JMeterType = innerValue.value; paramForm.value.JMeterType = value.value;
} else { } else {
paramForm.value.JMeterType = ''; paramForm.value.JMeterType = '';
} }
} else if (/^@/.test(innerValue.value)) { } else if (/^@/.test(value.value)) {
// Mock // Mock
const valueArr = innerValue.value.split('|'); // mock const valueArr = value.value.split('|'); // mock
if (valueArr[0]) { if (valueArr[0]) {
// @ // @
const variableRegex = /@([a-zA-Z]+)(?:\(([^)]*)\))?/; const variableRegex = /@([a-zA-Z]+)(?:\(([^)]*)\))?/;
@ -636,14 +633,14 @@
watch( watch(
() => popoverVisible.value, () => popoverVisible.value,
(val) => { (val) => {
if (val && /^@/.test(innerValue.value)) { if (val && /^@/.test(value.value)) {
getMockValue(innerValue.value); getMockValue(value.value);
} }
} }
); );
function selectAutoComplete(val: string) { function selectAutoComplete(val: string) {
innerValue.value = val; value.value = val;
setLastTenParams(val); setLastTenParams(val);
} }
@ -657,7 +654,7 @@
result = paramForm.value.JMeterType; result = paramForm.value.JMeterType;
} }
setLastTenParams(paramForm.value.type); setLastTenParams(paramForm.value.type);
innerValue.value = result; value.value = result;
emit('apply', result); emit('apply', result);
cancel(); cancel();
} }

View File

@ -118,7 +118,7 @@ const Image = TiptapImage.extend<ExtensionOptions & ImageOptions>({
}, },
addNodeView() { addNodeView() {
return VueNodeViewRenderer(ImageView); return VueNodeViewRenderer(ImageView as Component);
}, },
parseHTML() { parseHTML() {

View File

@ -6,7 +6,7 @@ import useAppStore from '@/store/modules/app';
import { ReviewUserItem } from '@/models/caseManagement/caseReview'; import { ReviewUserItem } from '@/models/caseManagement/caseReview';
import { VueRenderer } from '@halo-dev/richtext-editor'; import { VueRenderer } from '@halo-dev/richtext-editor';
import type { Instance } from 'tippy.js'; import type { Content, Instance } from 'tippy.js';
import tippy from 'tippy.js'; import tippy from 'tippy.js';
const appStore = useAppStore(); const appStore = useAppStore();
@ -53,7 +53,7 @@ export default {
popup = tippy('body', { popup = tippy('body', {
getReferenceClientRect: props.clientRect, getReferenceClientRect: props.clientRect,
appendTo: () => document.body, appendTo: () => document.body,
content: component.element, content: component.element as Content, // FIX TS ERROR
showOnCreate: true, showOnCreate: true,
interactive: true, interactive: true,
trigger: 'manual', trigger: 'manual',

View File

@ -17,7 +17,7 @@
@expand="(rowKey, record) => emit('expand', record)" @expand="(rowKey, record) => emit('expand', record)"
@change="(data: TableData[], extra: TableChangeExtra, currentData: TableData[]) => handleDragChange(data, extra, currentData)" @change="(data: TableData[], extra: TableChangeExtra, currentData: TableData[]) => handleDragChange(data, extra, currentData)"
@sorter-change="(dataIndex: string,direction: string) => handleSortChange(dataIndex, direction)" @sorter-change="(dataIndex: string,direction: string) => handleSortChange(dataIndex, direction)"
@cell-click="(record: TableData,column: TableColumnData,ev: Event) => emit('cell-click',record, column,ev)" @cell-click="(record: TableData,column: TableColumnData,ev: Event) => emit('cellClick',record, column,ev)"
@column-resize="columnResize" @column-resize="columnResize"
> >
<template #optional="{ rowIndex, record }"> <template #optional="{ rowIndex, record }">
@ -386,7 +386,7 @@
(e: 'dragChange', value: DragSortParams): void; (e: 'dragChange', value: DragSortParams): void;
(e: 'sorterChange', value: { [key: string]: string }): void; (e: 'sorterChange', value: { [key: string]: string }): void;
(e: 'expand', record: TableData): void | Promise<any>; (e: 'expand', record: TableData): void | Promise<any>;
(e: 'cell-click', record: TableData, column: TableColumnData, ev: Event): void | Promise<any>; (e: 'cellClick', record: TableData, column: TableColumnData, ev: Event): void | Promise<any>;
(e: 'clearSelector'): void; (e: 'clearSelector'): void;
(e: 'enableChange', record: any, newValue: string | number | boolean): void; (e: 'enableChange', record: any, newValue: string | number | boolean): void;
( (

View File

@ -223,8 +223,8 @@
</div> </div>
<div class="h-[calc(100%-76px)]"> <div class="h-[calc(100%-76px)]">
<paramTable <paramTable
v-if="commonScriptShowType === 'parameters'" v-if="commonScriptShowType === 'parameters' && condition.commonScriptInfo"
v-model:params="scriptParams" v-model:params="condition.commonScriptInfo.params"
:disabled-param-value="props.disabled" :disabled-param-value="props.disabled"
:scroll="{ x: '100%' }" :scroll="{ x: '100%' }"
:columns="scriptColumns" :columns="scriptColumns"
@ -236,7 +236,7 @@
}" }"
:selectable="false" :selectable="false"
:show-quick-copy="props.showQuickCopy" :show-quick-copy="props.showQuickCopy"
@change="() => emit('change')" @change="handleScriptParamsChange"
/> />
<MsCodeEditor <MsCodeEditor
v-else-if="commonScriptShowType === 'scriptContent' && condition.commonScriptInfo" v-else-if="commonScriptShowType === 'scriptContent' && condition.commonScriptInfo"
@ -425,7 +425,7 @@
</template> </template>
<template #operationPre="{ record }"> <template #operationPre="{ record }">
<a-popover <a-popover
v-model:popupVisible="record.moreSettingPopoverVisible" v-model:popup-visible="record.moreSettingPopoverVisible"
position="tr" position="tr"
trigger="click" trigger="click"
:title="t('common.setting')" :title="t('common.setting')"
@ -584,6 +584,14 @@
} }
try { try {
const res = await getCommonScript(condition.value.commonScriptInfo.id); const res = await getCommonScript(condition.value.commonScriptInfo.id);
if (condition.value.commonScriptInfo.params.length > 0) {
res.params.forEach((item: any) => {
const param = condition.value.commonScriptInfo?.params.find((e: any) => e.key === item.key);
if (param) {
item.value = param.value;
}
});
}
condition.value.commonScriptInfo = res; condition.value.commonScriptInfo = res;
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
@ -681,8 +689,6 @@
const commonScriptShowType = ref<'parameters' | 'scriptContent'>('parameters'); const commonScriptShowType = ref<'parameters' | 'scriptContent'>('parameters');
const scriptParams = ref<any[]>([]);
const scriptColumns: MsTableColumn = [ const scriptColumns: MsTableColumn = [
{ {
title: 'project.commonScript.ParameterNames', title: 'project.commonScript.ParameterNames',
@ -720,6 +726,13 @@
isShowEditScriptNameInput.value = false; isShowEditScriptNameInput.value = false;
} }
function handleScriptParamsChange(resultArr: any[]) {
if (condition.value.commonScriptInfo) {
condition.value.commonScriptInfo.params = resultArr;
}
emit('change');
}
const showQuoteDrawer = ref(false); const showQuoteDrawer = ref(false);
function saveQuoteScriptHandler(item: any) { function saveQuoteScriptHandler(item: any) {
// TODO:any // TODO:any
@ -735,7 +748,6 @@
}; };
}), }),
}; };
scriptParams.value = (condition.value.commonScriptInfo?.params as any[]) || [];
showQuoteDrawer.value = false; showQuoteDrawer.value = false;
Message.success(t('apiTestDebug.introduceSourceApplySuccess')); Message.success(t('apiTestDebug.introduceSourceApplySuccess'));
} }
@ -1037,8 +1049,7 @@
}); });
watch( watch(
() => condition.value.commonScriptInfo, () => condition.value.commonScriptInfo,
(info) => { () => {
scriptParams.value = info?.params as any[]; //
if (!showParameters()) { if (!showParameters()) {
commonScriptShowType.value = 'scriptContent'; commonScriptShowType.value = 'scriptContent';
} }