feat(环境管理): 断言基本页面&评论逻辑修改
This commit is contained in:
parent
e1bfeadd2e
commit
ba3d33c24e
|
@ -0,0 +1,152 @@
|
||||||
|
<template>
|
||||||
|
<div class="ms-assertion">
|
||||||
|
<a-dropdown trigger="hover" @select="handleSelect">
|
||||||
|
<a-button class="w-[84px]" type="outline">
|
||||||
|
<div class="flex flex-row items-center gap-[8px]">
|
||||||
|
<icon-plus />
|
||||||
|
<span>{{ t('ms.assertion.button') }}</span>
|
||||||
|
</div>
|
||||||
|
</a-button>
|
||||||
|
<template #content>
|
||||||
|
<a-doption v-for="item in assertOption" :key="item.value" :value="item.value">{{ item.label }}</a-doption>
|
||||||
|
</template>
|
||||||
|
</a-dropdown>
|
||||||
|
<div class="ms-assertion-body">
|
||||||
|
<article class="ms-assertion-body-left">
|
||||||
|
<div
|
||||||
|
v-for="(item, index) in activeOption"
|
||||||
|
:key="item.value"
|
||||||
|
class="ms-assertion-body-left-item"
|
||||||
|
@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.label }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="ms-assertion-body-left-item-switch">
|
||||||
|
<a-switch type="line" size="small" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
<section class="ms-assertion-body-right"> </section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: 'MsAssertion',
|
||||||
|
});
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const assertOptionSource = [
|
||||||
|
{
|
||||||
|
label: t('ms.assertion.statusCode'),
|
||||||
|
value: 'statusCode',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('ms.assertion.responseHeader'),
|
||||||
|
value: 'responseHeader',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('ms.assertion.responseBody'),
|
||||||
|
value: 'responseBody',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('ms.assertion.responseTime'),
|
||||||
|
value: 'responseTime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('ms.assertion.param'),
|
||||||
|
value: 'param',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('ms.assertion.script'),
|
||||||
|
value: 'script',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const selectIds = ref<string[]>([]);
|
||||||
|
|
||||||
|
const activeKey = ref<string>('');
|
||||||
|
|
||||||
|
const assertOption = computed(() => {
|
||||||
|
return assertOptionSource.filter((item) => !selectIds.value.includes(item.value));
|
||||||
|
});
|
||||||
|
|
||||||
|
const activeOption = computed(() => {
|
||||||
|
return assertOptionSource.filter((item) => selectIds.value.includes(item.value));
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleSelect = (value: string | number | Record<string, any> | undefined) => {
|
||||||
|
selectIds.value.push(value as string);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleItemClick = (item: { label: string; value: string }) => {
|
||||||
|
activeKey.value = item.value;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.ms-assertion {
|
||||||
|
width: 100%;
|
||||||
|
&-body {
|
||||||
|
display: flex;
|
||||||
|
margin-top: 8px;
|
||||||
|
flex-flow: row nowrap;
|
||||||
|
gap: 8px;
|
||||||
|
&-left {
|
||||||
|
display: flex;
|
||||||
|
padding: 12px;
|
||||||
|
width: 216px;
|
||||||
|
height: calc(100vh - 394px);
|
||||||
|
background-color: var(--color-text-n9);
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
&-item {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row nowrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: var(--color-text-fff);
|
||||||
|
cursor: pointer;
|
||||||
|
&-row {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
&-num {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
border-radius: 50%;
|
||||||
|
text-align: center;
|
||||||
|
color: var(--color-text-4);
|
||||||
|
background-color: var(--color-text-n8);
|
||||||
|
line-height: 16px;
|
||||||
|
}
|
||||||
|
&-title {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 400;
|
||||||
|
color: var(--color-text-1);
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&-right {
|
||||||
|
display: flex;
|
||||||
|
flex-grow: 1;
|
||||||
|
border: 1px solid var(--color-text-n8);
|
||||||
|
border-radius: 4px;
|
||||||
|
background: var(--color-text-fff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,3 @@
|
||||||
|
export default {
|
||||||
|
'ms.assertion.button': 'Assertion',
|
||||||
|
};
|
|
@ -0,0 +1,9 @@
|
||||||
|
export default {
|
||||||
|
'ms.assertion.button': '断言',
|
||||||
|
'ms.assertion.statusCode': '状态码',
|
||||||
|
'ms.assertion.responseHeader': '响应头',
|
||||||
|
'ms.assertion.responseBody': '响应体',
|
||||||
|
'ms.assertion.responseTime': '响应时间',
|
||||||
|
'ms.assertion.param': '变量',
|
||||||
|
'ms.assertion.script': '脚本',
|
||||||
|
};
|
|
@ -26,7 +26,7 @@
|
||||||
<MsIconfont type="icon-icon_edit_outlined" />
|
<MsIconfont type="icon-icon_edit_outlined" />
|
||||||
<span>{{ t('ms.comment.edit') }}</span>
|
<span>{{ t('ms.comment.edit') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="hasEditAuth" class="comment-btn" @click="deleteClick">
|
<div class="comment-btn" @click="deleteClick">
|
||||||
<MsIconfont type="icon-icon_delete-trash_outlined" />
|
<MsIconfont type="icon-icon_delete-trash_outlined" />
|
||||||
<span>{{ t('ms.comment.delete') }}</span>
|
<span>{{ t('ms.comment.delete') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -51,14 +51,19 @@
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
defineOptions({ name: 'MsCommentItem' });
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
element: CommentItem; // 评论的具体内容
|
element: CommentItem; // 评论的具体内容
|
||||||
mode: 'parent' | 'child'; // 父级评论还是子级评论
|
mode: 'parent' | 'child'; // 父级评论还是子级评论
|
||||||
|
onReply?: () => void; // 回复
|
||||||
|
onEdit?: () => void; // 编辑
|
||||||
|
onDelete?: () => void; // 删除
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
// 是否拥有编辑|删除权限
|
// 是否拥有编辑|删除权限
|
||||||
const hasEditAuth = computed(() => {
|
const hasEditAuth = computed(() => {
|
||||||
return props.element.commentUserInfo.id === userStore.id;
|
return props.element.createUser === userStore.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
|
|
|
@ -16,6 +16,10 @@ export default defineComponent({
|
||||||
type: Array as PropType<CommentItem[]>,
|
type: Array as PropType<CommentItem[]>,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean as PropType<boolean>,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
emits: {
|
emits: {
|
||||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||||
|
@ -23,11 +27,19 @@ export default defineComponent({
|
||||||
delete: (value: string) => true, // 删除评论
|
delete: (value: string) => true, // 删除评论
|
||||||
},
|
},
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
const { commentList } = toRefs(props);
|
const { commentList, disabled } = toRefs(props);
|
||||||
const currentItem = reactive<{ id: string; parentId: string }>({ id: '', parentId: '' });
|
const currentItem = reactive<{ id: string; parentId?: string }>({
|
||||||
|
id: '',
|
||||||
|
parentId: '',
|
||||||
|
});
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { openModal } = useModal();
|
const { openModal } = useModal();
|
||||||
|
|
||||||
|
const resetCurrentItem = () => {
|
||||||
|
currentItem.id = '';
|
||||||
|
currentItem.parentId = '';
|
||||||
|
};
|
||||||
|
|
||||||
const handlePublish = (content: string, item: CommentItem) => {
|
const handlePublish = (content: string, item: CommentItem) => {
|
||||||
const params: CommentParams = {
|
const params: CommentParams = {
|
||||||
...item,
|
...item,
|
||||||
|
@ -36,9 +48,10 @@ export default defineComponent({
|
||||||
};
|
};
|
||||||
emit('updateOrAdd', params, (result: boolean) => {
|
emit('updateOrAdd', params, (result: boolean) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
message.success(t('common.publishSuccess'));
|
message.success(t('common.publishSuccessfully'));
|
||||||
|
resetCurrentItem();
|
||||||
} else {
|
} else {
|
||||||
message.error(t('common.publishFail'));
|
message.error(t('common.publishFailed'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -60,12 +73,30 @@ export default defineComponent({
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleReply = (item: CommentItem) => {
|
||||||
|
if (item.childComments) {
|
||||||
|
// 父级评论
|
||||||
|
currentItem.id = item.id;
|
||||||
|
} else {
|
||||||
|
// 子级评论
|
||||||
|
currentItem.id = item.parentId || '';
|
||||||
|
currentItem.parentId = item.id;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handelEdit = (item: CommentItem) => {
|
||||||
|
currentItem.id = item.id;
|
||||||
|
currentItem.parentId = item.parentId || '';
|
||||||
|
};
|
||||||
|
|
||||||
const renderInput = (item: CommentItem) => {
|
const renderInput = (item: CommentItem) => {
|
||||||
return (
|
return (
|
||||||
<CommentInput
|
<CommentInput
|
||||||
isShowAvatar={false}
|
isShowAvatar={false}
|
||||||
isUseBottom={false}
|
isUseBottom={false}
|
||||||
onPublish={(content: string) => handlePublish(content, item)}
|
onPublish={(content: string) => handlePublish(content, item)}
|
||||||
|
defaultValue={item.content || ''}
|
||||||
|
onCancel={() => resetCurrentItem()}
|
||||||
{...item}
|
{...item}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -79,14 +110,8 @@ export default defineComponent({
|
||||||
return (
|
return (
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<Item
|
<Item
|
||||||
onReply={() => {
|
onReply={() => handleReply(item)}
|
||||||
currentItem.id = item.id;
|
onEdit={() => handelEdit(item)}
|
||||||
currentItem.parentId = item.parentId || '';
|
|
||||||
}}
|
|
||||||
onEdit={() => {
|
|
||||||
currentItem.id = item.id;
|
|
||||||
currentItem.parentId = item.parentId || '';
|
|
||||||
}}
|
|
||||||
onDelete={() => handleDelete(item)}
|
onDelete={() => handleDelete(item)}
|
||||||
mode={'child'}
|
mode={'child'}
|
||||||
element={item}
|
element={item}
|
||||||
|
@ -100,11 +125,18 @@ export default defineComponent({
|
||||||
const renderParentList = (list: CommentItem[]) => {
|
const renderParentList = (list: CommentItem[]) => {
|
||||||
return list.map((item) => {
|
return list.map((item) => {
|
||||||
return (
|
return (
|
||||||
<Item mode={'parent'} onDelete={() => handleDelete(item)} element={item}>
|
<>
|
||||||
<div class="rounded border border-[var(--color-text-7)] p-[16px]">
|
<Item
|
||||||
{renderChildrenList(item.childComments)}
|
mode={'parent'}
|
||||||
</div>
|
onReply={() => handleReply(item)}
|
||||||
|
onEdit={() => handelEdit(item)}
|
||||||
|
onDelete={() => handleDelete(item)}
|
||||||
|
element={item}
|
||||||
|
>
|
||||||
|
<div class="rounded border border-[var(--color-text-7)] p-[16px]"></div>
|
||||||
</Item>
|
</Item>
|
||||||
|
{item.id === currentItem.id && renderInput(item)}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,28 +22,32 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { useVModel } from '@vueuse/core';
|
|
||||||
|
|
||||||
import MsAvatar from '@/components/pure/ms-avatar/index.vue';
|
import MsAvatar from '@/components/pure/ms-avatar/index.vue';
|
||||||
import MsRichText from '@/components/pure/ms-rich-text/MsRichText.vue';
|
import MsRichText from '@/components/pure/ms-rich-text/MsRichText.vue';
|
||||||
|
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
|
||||||
|
defineOptions({ name: 'MsCommentInput' });
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
// const currentContent = defineModel<string>('content', { required: true });
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
content: string;
|
|
||||||
isShowAvatar: boolean; // 是否显示评论人头像
|
isShowAvatar: boolean; // 是否显示评论人头像
|
||||||
isUseBottom: boolean; // 是否被用于底部
|
isUseBottom: boolean; // 是否被用于底部
|
||||||
|
defaultValue?: string; // 默认值
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const currentContent = ref(props.defaultValue || '');
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(event: 'update:content', value: string): void;
|
|
||||||
(event: 'publish', value: string): void;
|
(event: 'publish', value: string): void;
|
||||||
|
(event: 'cancel'): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const isActive = ref(false);
|
const isActive = ref(false);
|
||||||
const currentContent = useVModel(props, 'content', emit);
|
|
||||||
|
|
||||||
const publish = () => {
|
const publish = () => {
|
||||||
emit('publish', currentContent.value);
|
emit('publish', currentContent.value);
|
||||||
|
@ -53,6 +57,7 @@
|
||||||
const cancelClick = () => {
|
const cancelClick = () => {
|
||||||
isActive.value = false;
|
isActive.value = false;
|
||||||
currentContent.value = '';
|
currentContent.value = '';
|
||||||
|
emit('cancel');
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,7 @@ export default {
|
||||||
'common.newSuccess': 'Added successfully',
|
'common.newSuccess': 'Added successfully',
|
||||||
'common.publish': 'Publish',
|
'common.publish': 'Publish',
|
||||||
'common.publishSuccessfully': 'Published successfully',
|
'common.publishSuccessfully': 'Published successfully',
|
||||||
|
'common.publishFailed': 'Published failed',
|
||||||
'common.string': 'String',
|
'common.string': 'String',
|
||||||
'common.number': 'Number',
|
'common.number': 'Number',
|
||||||
'common.boolean': 'Boolean',
|
'common.boolean': 'Boolean',
|
||||||
|
|
|
@ -83,6 +83,7 @@ export default {
|
||||||
'common.newSuccess': '新增成功',
|
'common.newSuccess': '新增成功',
|
||||||
'common.publish': '发布',
|
'common.publish': '发布',
|
||||||
'common.publishSuccessfully': '发布成功',
|
'common.publishSuccessfully': '发布成功',
|
||||||
|
'common.publishFailed': '发布失败',
|
||||||
'common.string': '字符串',
|
'common.string': '字符串',
|
||||||
'common.number': '数字',
|
'common.number': '数字',
|
||||||
'common.boolean': '布尔',
|
'common.boolean': '布尔',
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { MsTableColumn } from '@/components/pure/ms-table/type';
|
import type { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||||
import AllParamsTable from '../allParams/AllParamsTable.vue';
|
import AllParamsTable from './allParams/AllParamsTable.vue';
|
||||||
|
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import useProjectEnvStore from '@/store/modules/setting/useProjectEnvStore';
|
import useProjectEnvStore from '@/store/modules/setting/useProjectEnvStore';
|
|
@ -43,19 +43,19 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import AssertTab from './AssertTab.vue';
|
import AssertTab from './envParams/AssertTab.vue';
|
||||||
import DataBaseTab from './DatabaseTab.vue';
|
import DataBaseTab from './envParams/DatabaseTab.vue';
|
||||||
import DisplayTab from './DisplayTab.vue';
|
import DisplayTab from './envParams/DisplayTab.vue';
|
||||||
import EnvParamsTab from './EnvParamsTab.vue';
|
import EnvParamsTab from './envParams/EnvParamsTab.vue';
|
||||||
import HostTab from './HostTab.vue';
|
import HostTab from './envParams/HostTab.vue';
|
||||||
import HttpTab from './HttpTab.vue';
|
import HttpTab from './envParams/HttpTab.vue';
|
||||||
import PostTab from './PostTab.vue';
|
import PostTab from './envParams/PostTab.vue';
|
||||||
import PreTab from './PreTab.vue';
|
import PreTab from './envParams/PreTab.vue';
|
||||||
import TcpTab from './TcpTab.vue';
|
import TcpTab from './envParams/TcpTab.vue';
|
||||||
|
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
|
||||||
const activeKey = ref('http');
|
const activeKey = ref('assert');
|
||||||
const envForm = ref();
|
const envForm = ref();
|
||||||
const canSave = ref(false);
|
const canSave = ref(false);
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
|
@ -12,7 +12,7 @@
|
||||||
</template>
|
</template>
|
||||||
<a-input
|
<a-input
|
||||||
v-model:model-value="record.name"
|
v-model:model-value="record.name"
|
||||||
:placeholder="t('ms.apiTestDebug.paramNamePlaceholder')"
|
:placeholder="t('project.environmental.paramNamePlaceholder')"
|
||||||
class="param-input"
|
class="param-input"
|
||||||
@input="(val) => addTableLine(val)"
|
@input="(val) => addTableLine(val)"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="p-[24px]">
|
<div>
|
||||||
<a-divider :margin="0" class="!mb-[16px]" />
|
<ms-assertion />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import MsAssertion from '@/components/business/ms-assertion/index.vue';
|
||||||
|
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
|
@ -188,8 +188,8 @@
|
||||||
import MsMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
import MsMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
||||||
import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
||||||
import AllParamBox from './components/AllParamBox.vue';
|
import AllParamBox from './components/AllParamBox.vue';
|
||||||
import EnvGroupBox from './components/envGroup/EnvGroupBox.vue';
|
import EnvGroupBox from './components/EnvGroupBox.vue';
|
||||||
import EnvParamBox from './components/envParams/EnvParamBox.vue';
|
import EnvParamBox from './components/EnvParamBox.vue';
|
||||||
import RenamePop from './components/RenamePop.vue';
|
import RenamePop from './components/RenamePop.vue';
|
||||||
|
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
|
|
@ -11,6 +11,7 @@ export default {
|
||||||
'project.environmental.mustContain': '必含',
|
'project.environmental.mustContain': '必含',
|
||||||
'project.environmental.searchParamsHolder': '通过名称或标签搜索',
|
'project.environmental.searchParamsHolder': '通过名称或标签搜索',
|
||||||
'project.environmental.paramName': '参数名称',
|
'project.environmental.paramName': '参数名称',
|
||||||
|
'project.environmental.paramNamePlaceholder': '请输入参数名称',
|
||||||
'project.environmental.paramType': '类型',
|
'project.environmental.paramType': '类型',
|
||||||
'project.environmental.paramTypeTooltip': 'json:仅支持 UI 测试',
|
'project.environmental.paramTypeTooltip': 'json:仅支持 UI 测试',
|
||||||
'project.environmental.paramValue': '参数值',
|
'project.environmental.paramValue': '参数值',
|
||||||
|
|
Loading…
Reference in New Issue