feat(接口测试): mock接口联调完成
This commit is contained in:
parent
9315555a09
commit
26b054f96f
|
@ -28,7 +28,7 @@
|
|||
</a-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showBody" class="ms-assertion-body w-full">
|
||||
<div v-if="showBody" class="ms-assertion-body w-full overflow-hidden">
|
||||
<div class="ms-assertion-body-left h-full w-[25%] min-w-[220px]">
|
||||
<VueDraggable v-model="assertions" ghost-class="ghost" handle=".sort-handle">
|
||||
<div
|
||||
|
@ -77,14 +77,13 @@
|
|||
</VueDraggable>
|
||||
</div>
|
||||
<div
|
||||
class="ms-assertion-body-right h-full"
|
||||
class="ms-assertion-body-right h-full flex-1 overflow-hidden"
|
||||
:class="{
|
||||
'p-4 pr-0': getCurrentItemState.assertionType !== ResponseAssertionType.SCRIPT,
|
||||
'border border-solid border-[var(--color-text-n8)]':
|
||||
getCurrentItemState.assertionType !== ResponseAssertionType.SCRIPT,
|
||||
}"
|
||||
>
|
||||
<div class="w-full">
|
||||
<!-- 响应头 -->
|
||||
<ResponseHeaderTab
|
||||
v-if="getCurrentItemState.assertionType === ResponseAssertionType.RESPONSE_HEADER"
|
||||
|
@ -136,7 +135,6 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
|
|
@ -893,6 +893,7 @@
|
|||
...file,
|
||||
fileId: res.data,
|
||||
fileName: file.name || '',
|
||||
fileAlias: file.name || '',
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
@ -902,7 +903,8 @@
|
|||
record.files = files.map((e) => ({
|
||||
...e,
|
||||
fileId: e.uid || e.fileId || '',
|
||||
fileName: e.name || e.fileName || '',
|
||||
fileName: e.originalName || '',
|
||||
fileAlias: e.name || '',
|
||||
}));
|
||||
}
|
||||
addTableLine(rowIndex);
|
||||
|
|
|
@ -376,7 +376,10 @@
|
|||
(e: 'openCopyApiTab', record: ApiDefinitionDetail): void;
|
||||
(e: 'addApiTab'): void;
|
||||
(e: 'import'): void;
|
||||
(e: 'openEditApiTab', record: ApiDefinitionDetail, isCopy: boolean, isExecute: boolean, isEdit: boolean): void;
|
||||
(
|
||||
e: 'openEditApiTab',
|
||||
options: { apiInfo: ApiDefinitionDetail; isCopy: boolean; isExecute: boolean; isEdit: boolean }
|
||||
): void;
|
||||
}>();
|
||||
|
||||
const appStore = useAppStore();
|
||||
|
@ -977,7 +980,7 @@
|
|||
}
|
||||
|
||||
function editDefinition(record: ApiDefinitionDetail) {
|
||||
emit('openEditApiTab', record, false, false, true);
|
||||
emit('openEditApiTab', { apiInfo: record, isCopy: false, isExecute: false, isEdit: true });
|
||||
}
|
||||
|
||||
// 拖拽排序
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
:protocol="props.protocol"
|
||||
:refresh-time-stamp="refreshTableTimeStamp"
|
||||
:member-options="memberOptions"
|
||||
@open-api-tab="(record, isExecute) => openApiTab(record, false, isExecute)"
|
||||
@open-copy-api-tab="openApiTab($event, true)"
|
||||
@open-api-tab="(record, isExecute) => openApiTab({ apiInfo: record, isCopy: false, isExecute })"
|
||||
@open-copy-api-tab="openApiTab({ apiInfo: $event, isCopy: true })"
|
||||
@add-api-tab="addApiTab"
|
||||
@import="emit('import')"
|
||||
@open-edit-api-tab="openApiTab"
|
||||
|
@ -117,6 +117,7 @@
|
|||
:definition-detail="activeApiTab"
|
||||
:protocol="activeApiTab.protocol"
|
||||
is-api
|
||||
@debug="openApiTabAndDebugMock"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
|
@ -158,10 +159,18 @@
|
|||
RequestComposition,
|
||||
RequestDefinitionStatus,
|
||||
RequestMethods,
|
||||
RequestParamsType,
|
||||
ResponseComposition,
|
||||
} from '@/enums/apiEnum';
|
||||
|
||||
import { defaultBodyParams, defaultResponse, defaultResponseItem } from '@/views/api-test/components/config';
|
||||
import {
|
||||
defaultBodyParams,
|
||||
defaultBodyParamsItem,
|
||||
defaultHeaderParamsItem,
|
||||
defaultRequestParamsItem,
|
||||
defaultResponse,
|
||||
defaultResponseItem,
|
||||
} from '@/views/api-test/components/config';
|
||||
import type { RequestParam } from '@/views/api-test/components/requestComposition/index.vue';
|
||||
import { parseRequestBodyFiles } from '@/views/api-test/components/utils';
|
||||
// 懒加载requestComposition组件
|
||||
|
@ -315,20 +324,29 @@
|
|||
|
||||
const loading = ref(false);
|
||||
const requestCompositionRef = ref<InstanceType<typeof requestComposition>>();
|
||||
async function openApiTab(
|
||||
apiInfo: ModuleTreeNode | ApiDefinitionDetail | string,
|
||||
isCopy = false,
|
||||
isExecute = false,
|
||||
isEdit = false
|
||||
) {
|
||||
async function openApiTab(options: {
|
||||
apiInfo: ModuleTreeNode | ApiDefinitionDetail | string;
|
||||
isCopy?: boolean;
|
||||
isExecute?: boolean;
|
||||
isEdit?: boolean;
|
||||
isDebugMock?: boolean;
|
||||
}) {
|
||||
const { apiInfo, isCopy = false, isExecute = false, isEdit = false, isDebugMock = false } = options;
|
||||
const isLoadedTabIndex = apiTabs.value.findIndex(
|
||||
(e) => e.id === (typeof apiInfo === 'string' ? apiInfo : apiInfo.id)
|
||||
);
|
||||
if (isLoadedTabIndex > -1 && !isCopy) {
|
||||
const preActiveApiTabId = activeApiTab.value.id;
|
||||
let loadedApiTab = apiTabs.value[isLoadedTabIndex] as RequestParam;
|
||||
if (isDebugMock) {
|
||||
loadedApiTab = {
|
||||
...loadedApiTab,
|
||||
...(apiInfo as ApiDefinitionDetail).request,
|
||||
};
|
||||
}
|
||||
// 如果点击的请求在tab中已经存在,则直接切换到该tab
|
||||
activeApiTab.value = {
|
||||
...(apiTabs.value[isLoadedTabIndex] as RequestParam),
|
||||
...loadedApiTab,
|
||||
definitionActiveKey: isCopy || isExecute || isEdit ? 'definition' : 'preview',
|
||||
isExecute,
|
||||
mode: isExecute ? 'debug' : 'definition',
|
||||
|
@ -352,10 +370,17 @@
|
|||
if (res.protocol === 'HTTP') {
|
||||
parseRequestBodyResult = parseRequestBodyFiles(res.request.body, res.response); // 解析请求体中的文件,将详情中的文件 id 集合收集,更新时以判断文件是否删除以及是否新上传的文件
|
||||
}
|
||||
let { request } = res;
|
||||
if (isDebugMock) {
|
||||
request = {
|
||||
...res.request,
|
||||
...(apiInfo as ApiDefinitionDetail).request,
|
||||
};
|
||||
}
|
||||
addApiTab({
|
||||
label: name,
|
||||
...res.request,
|
||||
...res,
|
||||
...request,
|
||||
response: cloneDeep(defaultResponse),
|
||||
responseDefinition: res.response.map((e) => ({ ...e, responseActiveTab: ResponseComposition.BODY })),
|
||||
url: res.path,
|
||||
|
@ -382,7 +407,58 @@
|
|||
}
|
||||
|
||||
async function openApiTabAndDebugMock(mock: MockDetail) {
|
||||
await openApiTab(mock.apiDefinitionId as string);
|
||||
openApiTab({
|
||||
apiInfo: {
|
||||
id: mock.apiDefinitionId as string,
|
||||
request: {
|
||||
body: {
|
||||
bodyType: mock.mockMatchRule.body.bodyType,
|
||||
binaryBody: mock.mockMatchRule.body.binaryBody,
|
||||
rawBody: mock.mockMatchRule.body.rawBody,
|
||||
xmlBody: mock.mockMatchRule.body.xmlBody,
|
||||
wwwFormBody: {
|
||||
formValues:
|
||||
mock.mockMatchRule.body.wwwFormBody.matchRules.map((e) => ({
|
||||
...defaultBodyParamsItem,
|
||||
key: e.key,
|
||||
value: e.value,
|
||||
})) || [],
|
||||
},
|
||||
jsonBody: mock.mockMatchRule.body.jsonBody,
|
||||
formDataBody: {
|
||||
formValues:
|
||||
mock.mockMatchRule.body.formDataBody.matchRules.map((e) => ({
|
||||
...defaultBodyParamsItem,
|
||||
key: e.key,
|
||||
value: e.value,
|
||||
files: e.files || [],
|
||||
paramType: e.files && e.files.length > 0 ? RequestParamsType.FILE : defaultBodyParamsItem.paramType,
|
||||
})) || [],
|
||||
},
|
||||
},
|
||||
headers:
|
||||
mock.mockMatchRule.header.matchRules.map((e) => ({
|
||||
...defaultHeaderParamsItem,
|
||||
key: e.key,
|
||||
value: e.value,
|
||||
})) || [],
|
||||
query:
|
||||
mock.mockMatchRule.query.matchRules.map((e) => ({
|
||||
...defaultRequestParamsItem,
|
||||
key: e.key,
|
||||
value: e.value,
|
||||
})) || [],
|
||||
rest:
|
||||
mock.mockMatchRule.rest.matchRules.map((e) => ({
|
||||
...defaultRequestParamsItem,
|
||||
key: e.key,
|
||||
value: e.value,
|
||||
})) || [],
|
||||
},
|
||||
} as unknown as ApiDefinitionDetail,
|
||||
isExecute: true,
|
||||
isDebugMock: true,
|
||||
});
|
||||
}
|
||||
|
||||
// 新建接口后没有创建人,创建时间,更新时间的信息。所以需要刷新数据
|
||||
|
|
|
@ -135,7 +135,11 @@
|
|||
|
||||
function newTab(apiInfo?: ModuleTreeNode | string, isCopy?: boolean, isExecute?: boolean) {
|
||||
if (apiInfo) {
|
||||
apiRef.value?.openApiTab(apiInfo, isCopy, isExecute);
|
||||
apiRef.value?.openApiTab({
|
||||
apiInfo,
|
||||
isCopy,
|
||||
isExecute,
|
||||
});
|
||||
} else {
|
||||
apiRef.value?.addApiTab();
|
||||
}
|
||||
|
|
|
@ -60,20 +60,23 @@
|
|||
</MsDetailCard>
|
||||
<a-form ref="mockForm" :model="mockDetail" :disabled="isReadOnly">
|
||||
<a-form-item
|
||||
class="hidden-item"
|
||||
class="hidden-item mb-[16px]"
|
||||
field="name"
|
||||
:rules="[{ required: true, message: t('mockManagement.nameNotNull') }]"
|
||||
>
|
||||
<a-input
|
||||
v-model:model-value="mockDetail.name"
|
||||
:placeholder="t('mockManagement.namePlaceholder')"
|
||||
class="mb-[16px] w-[732px]"
|
||||
class="w-[732px]"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item class="hidden-item" :rules="[{ required: true, message: t('mockManagement.nameNotNull') }]">
|
||||
<a-form-item
|
||||
class="hidden-item mb-[16px]"
|
||||
:rules="[{ required: true, message: t('mockManagement.nameNotNull') }]"
|
||||
>
|
||||
<MsTagsInput
|
||||
v-model:model-value="mockDetail.tags"
|
||||
class="mb-[16px] w-[732px]"
|
||||
class="w-[732px]"
|
||||
allow-clear
|
||||
unique-value
|
||||
retain-input-value
|
||||
|
@ -374,17 +377,23 @@
|
|||
const currentKeyOptions = computed(() => {
|
||||
switch (activeTab.value) {
|
||||
case RequestComposition.HEADER:
|
||||
return filterKeyValParams(props.definitionDetail.headers, defaultMatchRuleItem).validParams.map((e) => ({
|
||||
return filterKeyValParams(props.definitionDetail.headers, defaultMatchRuleItem)
|
||||
.validParams.filter((e, index, self) => self.findIndex((item) => item.key === e.key) === index)
|
||||
.map((e) => ({
|
||||
label: e.key,
|
||||
value: e.key,
|
||||
}));
|
||||
case RequestComposition.QUERY:
|
||||
return filterKeyValParams(props.definitionDetail.query, defaultMatchRuleItem).validParams.map((e) => ({
|
||||
return filterKeyValParams(props.definitionDetail.query, defaultMatchRuleItem)
|
||||
.validParams.filter((e, index, self) => self.findIndex((item) => item.key === e.key) === index)
|
||||
.map((e) => ({
|
||||
label: e.key,
|
||||
value: e.key,
|
||||
}));
|
||||
case RequestComposition.REST:
|
||||
return filterKeyValParams(props.definitionDetail.rest, defaultMatchRuleItem).validParams.map((e) => ({
|
||||
return filterKeyValParams(props.definitionDetail.rest, defaultMatchRuleItem)
|
||||
.validParams.filter((e, index, self) => self.findIndex((item) => item.key === e.key) === index)
|
||||
.map((e) => ({
|
||||
label: e.key,
|
||||
value: e.key,
|
||||
}));
|
||||
|
@ -396,19 +405,17 @@
|
|||
const currentBodyKeyOptions = computed(() => {
|
||||
switch (mockDetail.value.mockMatchRule.body.bodyType) {
|
||||
case RequestBodyFormat.FORM_DATA:
|
||||
return filterKeyValParams(
|
||||
props.definitionDetail.body.formDataBody.formValues,
|
||||
defaultMatchRuleItem
|
||||
).validParams.map((e) => ({
|
||||
return filterKeyValParams(props.definitionDetail.body.formDataBody.formValues, defaultMatchRuleItem)
|
||||
.validParams.filter((e, index, self) => self.findIndex((item) => item.key === e.key) === index)
|
||||
.map((e) => ({
|
||||
label: e.key,
|
||||
value: e.key,
|
||||
paramType: e.paramType,
|
||||
}));
|
||||
case RequestBodyFormat.WWW_FORM:
|
||||
return filterKeyValParams(
|
||||
props.definitionDetail.body.wwwFormBody.formValues,
|
||||
defaultMatchRuleItem
|
||||
).validParams.map((e) => ({
|
||||
return filterKeyValParams(props.definitionDetail.body.wwwFormBody.formValues, defaultMatchRuleItem)
|
||||
.validParams.filter((e, index, self) => self.findIndex((item) => item.key === e.key) === index)
|
||||
.map((e) => ({
|
||||
label: e.key,
|
||||
value: e.key,
|
||||
paramType: e.paramType,
|
||||
|
@ -569,10 +576,10 @@
|
|||
} else {
|
||||
// 关联文件
|
||||
mockDetail.value.mockMatchRule.body.binaryBody.file = {
|
||||
...fileList.value[0],
|
||||
fileId: fileList.value[0]?.uid,
|
||||
fileName: fileList.value[0]?.originalName || '',
|
||||
fileAlias: fileList.value[0]?.name || '',
|
||||
...file,
|
||||
fileId: file?.uid || '',
|
||||
fileName: file?.originalName || '',
|
||||
fileAlias: file?.name || '',
|
||||
local: false,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<a-form ref="formRef" :model="formModel" layout="vertical">
|
||||
<a-spin :loading="loading" class="block">
|
||||
<div
|
||||
v-if="matchRules.length > 0"
|
||||
:class="`flex ${
|
||||
matchRules.length > 1 ? 'items-stretch' : 'items-center'
|
||||
} gap-[16px] bg-[var(--color-text-n9)] p-[12px]`"
|
||||
|
@ -97,6 +98,9 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<a-empty :description="t('mockManagement.noMatchRules')"></a-empty>
|
||||
</div>
|
||||
</a-spin>
|
||||
</a-form>
|
||||
<a-modal
|
||||
|
@ -265,6 +269,7 @@
|
|||
...file,
|
||||
fileId: res.data,
|
||||
fileName: file.name || '',
|
||||
fileAlias: file.name || '',
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
@ -274,7 +279,8 @@
|
|||
record.files = files.map((e) => ({
|
||||
...e,
|
||||
fileId: e.uid || e.fileId || '',
|
||||
fileName: e.name || e.fileName || '',
|
||||
fileName: e.originalName || '',
|
||||
fileAlias: e.name || '',
|
||||
}));
|
||||
}
|
||||
addMatchRule(rowIndex);
|
||||
|
|
|
@ -1,225 +1,251 @@
|
|||
export default {
|
||||
'apiTestManagement.newApi': 'Create request',
|
||||
'apiTestManagement.importApi': 'Import api',
|
||||
'apiTestManagement.fileImport': 'Import file',
|
||||
'apiTestManagement.timeImport': 'Scheduled import',
|
||||
'apiTestManagement.timeTask': 'Timed tasks',
|
||||
'apiTestManagement.name': 'Task name',
|
||||
'apiTestManagement.taskRunRule': 'Run rules',
|
||||
'apiTestManagement.taskNextRunTime': 'Next execution time',
|
||||
'apiTestManagement.newApi': 'New API',
|
||||
'apiTestManagement.importApi': 'Import API',
|
||||
'apiTestManagement.fileImport': 'File Import',
|
||||
'apiTestManagement.timeImport': 'Time Import',
|
||||
'apiTestManagement.timeTask': 'Time Task',
|
||||
'apiTestManagement.name': 'Name',
|
||||
'apiTestManagement.taskRunRule': 'Run Rule',
|
||||
'apiTestManagement.taskNextRunTime': 'Next Run Time',
|
||||
'apiTestManagement.taskOperator': 'Operator',
|
||||
'apiTestManagement.taskOperationTime': 'Operating time',
|
||||
'apiTestManagement.createTaskSuccess': 'Create scheduled import task successfully',
|
||||
'apiTestManagement.enableTaskSuccess': 'Start scheduled import task successfully',
|
||||
'apiTestManagement.disableTaskSuccess': 'Closing the scheduled import task successfully',
|
||||
'apiTestManagement.addSubModule': 'Add submodule',
|
||||
'apiTestManagement.allApi': 'All api',
|
||||
'apiTestManagement.allCase': 'All case',
|
||||
'apiTestManagement.searchTip': 'Please enter module/api name',
|
||||
'apiTestManagement.moveSearchTip': 'Please enter the module name to search',
|
||||
'apiTestManagement.noMatchModuleAndApi': 'No matching module/api yet',
|
||||
'apiTestManagement.noMatchModule': 'No matching module yet',
|
||||
'apiTestManagement.taskOperationTime': 'Operation Time',
|
||||
'apiTestManagement.createTaskSuccess': 'Create Time Import Task Success',
|
||||
'apiTestManagement.enableTaskSuccess': 'Enable Time Import Task Success',
|
||||
'apiTestManagement.disableTaskSuccess': 'Disable Time Import Task Success',
|
||||
'apiTestManagement.addSubModule': 'Add Submodule',
|
||||
'apiTestManagement.allApi': 'All APIs',
|
||||
'apiTestManagement.allCase': 'All Cases',
|
||||
'apiTestManagement.searchTip': 'Please enter module/interface name',
|
||||
'apiTestManagement.moveSearchTip': 'Please enter module name to search',
|
||||
'apiTestManagement.noMatchModuleAndApi': 'No matching module/interface found',
|
||||
'apiTestManagement.noMatchModule': 'No matching module found',
|
||||
'apiTestManagement.execute': 'Execute',
|
||||
'apiTestManagement.executeMethod': 'Execute method',
|
||||
'apiTestManagement.executeMethod': 'Execute Method',
|
||||
'apiTestManagement.recycle.batchRecover': 'Recover',
|
||||
'apiTestManagement.recycle.recoveredSuccessfully': 'recovery was successful',
|
||||
'apiTestManagement.recycle.batchCleanOut': 'Completely delete',
|
||||
'apiTestManagement.recycle.completedDeleteCaseTitle': 'Confirm complete deletion {name}?',
|
||||
'apiTestManagement.recycle.recoveredSuccessfully': 'Recovered Successfully',
|
||||
'apiTestManagement.recycle.batchCleanOut': 'Clean Out',
|
||||
'apiTestManagement.recycle.completedDeleteCaseTitle': 'Confirm to completely delete {name}?',
|
||||
'apiTestManagement.recycle.cleanOutDeleteOnRecycleTip':
|
||||
'After deletion, the API cannot be restored. Please operate with caution!',
|
||||
'apiTestManagement.recycle.batchDeleteApiTip': 'Are you sure to completely delete the selected {count} interfaces?',
|
||||
'After deletion, the API cannot be recovered. Please proceed with caution!',
|
||||
'apiTestManagement.recycle.batchDeleteApiTip': 'Confirm to completely delete the selected {count} APIs?',
|
||||
'apiTestManagement.share': 'Share API',
|
||||
'apiTestManagement.shareModule': 'Share module',
|
||||
'apiTestManagement.doc': 'Document',
|
||||
'apiTestManagement.closeAll': 'Close all tabs',
|
||||
'apiTestManagement.closeOther': 'Close other tabs',
|
||||
'apiTestManagement.showSubdirectory': 'Show subdirectory use case',
|
||||
'apiTestManagement.searchPlaceholder': 'Enter ID/name/api path search',
|
||||
'apiTestManagement.searchTaskPlaceholder': 'Enter resource Id/name/URL search',
|
||||
'apiTestManagement.apiName': 'Api name',
|
||||
'apiTestManagement.apiType': 'Api type',
|
||||
'apiTestManagement.shareModule': 'Share Module',
|
||||
'apiTestManagement.doc': 'Documentation',
|
||||
'apiTestManagement.closeAll': 'Close All Tabs',
|
||||
'apiTestManagement.closeOther': 'Close Other Tabs',
|
||||
'apiTestManagement.showSubdirectory': 'Show Subdirectory Cases',
|
||||
'apiTestManagement.searchPlaceholder': 'Enter ID/Name/API Path to search',
|
||||
'apiTestManagement.searchTaskPlaceholder': 'Enter Resource ID/Name/URL to search',
|
||||
'apiTestManagement.apiName': 'API Name',
|
||||
'apiTestManagement.apiType': 'Request Type',
|
||||
'apiTestManagement.apiStatus': 'Status',
|
||||
'apiTestManagement.path': 'Path',
|
||||
'apiTestManagement.version': 'Version',
|
||||
'apiTestManagement.createTime': 'Creation time',
|
||||
'apiTestManagement.updateTime': 'Update time',
|
||||
'apiTestManagement.deleteTime': 'Delete time',
|
||||
'apiTestManagement.deleteUser': 'Delete user',
|
||||
'apiTestManagement.createTime': 'Creation Time',
|
||||
'apiTestManagement.updateTime': 'Update Time',
|
||||
'apiTestManagement.deleteTime': 'Deletion Time',
|
||||
'apiTestManagement.deleteUser': 'Deleted By',
|
||||
'apiTestManagement.deprecate': 'Deprecated',
|
||||
'apiTestManagement.processing': 'Processing',
|
||||
'apiTestManagement.debugging': 'Debugging',
|
||||
'apiTestManagement.done': 'Completed',
|
||||
'apiTestManagement.deleteApiTipTitle': 'Are you sure you want to delete {name}?',
|
||||
'apiTestManagement.done': 'Done',
|
||||
'apiTestManagement.deleteApiTipTitle': 'Confirm to delete {name}?',
|
||||
'apiTestManagement.deleteApiTip':
|
||||
'After deletion, the interface will be placed in the recycle bin, where data recovery can be performed',
|
||||
'apiTestManagement.batchDeleteApiTip': 'Are you sure you want to delete {count} selected interfaces?',
|
||||
'apiTestManagement.batchModalSubTitle': '({count} interfaces selected)',
|
||||
'apiTestManagement.chooseAttr': 'Select properties',
|
||||
'apiTestManagement.attrRequired': 'Property cannot be empty',
|
||||
'apiTestManagement.batchUpdate': 'Batch update to',
|
||||
'apiTestManagement.valueRequired': 'Attribute value cannot be empty',
|
||||
'After deletion, the API will be moved to the recycle bin and can be restored from there',
|
||||
'apiTestManagement.batchDeleteApiTip': 'Confirm to delete the selected {count} APIs?',
|
||||
'apiTestManagement.batchModalSubTitle': '(Selected {count} APIs)',
|
||||
'apiTestManagement.chooseAttr': 'Choose Attribute',
|
||||
'apiTestManagement.attrRequired': 'Attribute cannot be empty',
|
||||
'apiTestManagement.batchUpdate': 'Batch Update to',
|
||||
'apiTestManagement.valueRequired': 'Value cannot be empty',
|
||||
'apiTestManagement.envRequired': 'Environment value cannot be empty',
|
||||
'apiTestManagement.reportNameRequired': 'Report name cannot be empty',
|
||||
'apiTestManagement.poolRequired': 'Resource pool cannot be empty',
|
||||
'apiTestManagement.batchMoveConfirm': 'Move to selected module',
|
||||
'apiTestManagement.belongModule': 'Belonging module',
|
||||
'apiTestManagement.importMode': 'Import mode',
|
||||
'apiTestManagement.belongModule': 'Belong to Module',
|
||||
'apiTestManagement.importMode': 'Import Mode',
|
||||
'apiTestManagement.importModeTip1': 'Cover:',
|
||||
'apiTestManagement.importModeTip2':
|
||||
'1.The same interface already exists in the system (the request type + path are consistent). If the request parameter content is inconsistent, the original interface of the system will be overwritten.',
|
||||
'1. If the same API (same request type + path) already exists in the system and the request parameter content is different, it will overwrite the original API',
|
||||
'apiTestManagement.importModeTip3':
|
||||
'2.The same interface already exists in the system (request type + path are consistent), if the content of the request parameters is consistent, no changes will be made.',
|
||||
'apiTestManagement.importModeTip4': '3.Interfaces that do not exist in the system are added.',
|
||||
'apiTestManagement.importModeTip5': 'Not covered:',
|
||||
'2. If the same API (same request type + path) already exists in the system and the request parameter content is the same, no changes will be made',
|
||||
'apiTestManagement.importModeTip4': '3. If the API does not exist in the system, it will be added',
|
||||
'apiTestManagement.importModeTip5': 'Do Not Cover:',
|
||||
'apiTestManagement.importModeTip6':
|
||||
'1.If the same interface already exists in the system (the request type + path is the same), no changes will be made.',
|
||||
'apiTestManagement.importModeTip7': '2.Interfaces that do not exist in the system are added.',
|
||||
'1. If the same API (same request type + path) already exists in the system, no changes will be made',
|
||||
'apiTestManagement.importModeTip7': '2. If the API does not exist in the system, it will be added',
|
||||
'apiTestManagement.cover': 'Cover',
|
||||
'apiTestManagement.uncover': 'Not covered',
|
||||
'apiTestManagement.moreSetting': 'More settings',
|
||||
'apiTestManagement.importType': 'Import method',
|
||||
'apiTestManagement.urlImport': 'URL import',
|
||||
'apiTestManagement.syncImportCase': 'Synchronous import interface use case',
|
||||
'apiTestManagement.syncUpdateDirectory': 'Synchronously update the directory where the interface is located',
|
||||
'apiTestManagement.importSwaggerFileTip1': 'Supports json files of Swagger 3.0 version,',
|
||||
'apiTestManagement.importSwaggerFileTip2': '2.0 files can be converted to 3.0 on the official website with one click',
|
||||
'apiTestManagement.importSwaggerFileTip3': ', the size does not exceed 50M',
|
||||
'apiTestManagement.urlImportPlaceholder': 'Please enter the OpenAPI/Swagger URL',
|
||||
'apiTestManagement.uncover': 'Do Not Cover',
|
||||
'apiTestManagement.moreSetting': 'More Settings',
|
||||
'apiTestManagement.importType': 'Import Type',
|
||||
'apiTestManagement.urlImport': 'URL Import',
|
||||
'apiTestManagement.syncImportCase': 'Sync Import API Cases',
|
||||
'apiTestManagement.syncUpdateDirectory': 'Sync Update API Directory',
|
||||
'apiTestManagement.importSwaggerFileTip1': 'Supports Swagger 3.0 version JSON files,',
|
||||
'apiTestManagement.importSwaggerFileTip2': '2.0 files can be converted to 3.0 on the official website',
|
||||
'apiTestManagement.importSwaggerFileTip3': 'with a size limit of 50MB',
|
||||
'apiTestManagement.urlImportPlaceholder': 'Please enter OpenAPI/URL',
|
||||
'apiTestManagement.swaggerURLRequired': 'Swagger URL cannot be empty',
|
||||
'apiTestManagement.basicAuth': 'Basic Authentication',
|
||||
'apiTestManagement.basicAuth': 'Basic Auth',
|
||||
'apiTestManagement.account': 'Account',
|
||||
'apiTestManagement.accountRequired': 'Account cannot be empty',
|
||||
'apiTestManagement.password': 'Password',
|
||||
'apiTestManagement.passwordRequired': 'Password can not be blank',
|
||||
'apiTestManagement.taskName': 'Task name',
|
||||
'apiTestManagement.taskNamePlaceholder': 'Please enter a task name',
|
||||
'apiTestManagement.passwordRequired': 'Password cannot be empty',
|
||||
'apiTestManagement.taskName': 'Task Name',
|
||||
'apiTestManagement.taskNamePlaceholder': 'Please enter task name',
|
||||
'apiTestManagement.taskNameRequired': 'Task name cannot be empty',
|
||||
'apiTestManagement.syncFrequency': 'Sync frequency',
|
||||
'apiTestManagement.timeTaskList': 'Scheduled task list',
|
||||
'apiTestManagement.timeTaskHour': '(per hour)',
|
||||
'apiTestManagement.timeTaskSixHour': '(every 6 hours)',
|
||||
'apiTestManagement.timeTaskTwelveHour': '(every 12 hours)',
|
||||
'apiTestManagement.timeTaskDay': '(every day)',
|
||||
'apiTestManagement.customFrequency': 'Custom frequency',
|
||||
'apiTestManagement.syncFrequency': 'Sync Frequency',
|
||||
'apiTestManagement.timeTaskList': 'Time Task List',
|
||||
'apiTestManagement.timeTaskHour': '(Every Hour)',
|
||||
'apiTestManagement.timeTaskSixHour': '(Every 6 Hours)',
|
||||
'apiTestManagement.timeTaskTwelveHour': '(Every 12 Hours)',
|
||||
'apiTestManagement.timeTaskDay': '(Every Day)',
|
||||
'apiTestManagement.customFrequency': 'Custom Frequency',
|
||||
'apiTestManagement.case': 'Case',
|
||||
'apiTestManagement.definition': 'API',
|
||||
'apiTestManagement.definition': 'Definition',
|
||||
'apiTestManagement.debug': 'Debug',
|
||||
'apiTestManagement.addDependency': 'Select dependency use case',
|
||||
'apiTestManagement.clearSelected': 'Clear selected use cases',
|
||||
'apiTestManagement.preDependency': 'Front interface',
|
||||
'apiTestManagement.addPreDependency': 'Add pre-dependency',
|
||||
'apiTestManagement.postDependency': 'Rear interface',
|
||||
'apiTestManagement.addPostDependency': 'Add post-dependency',
|
||||
'apiTestManagement.dependencyUnit': 'item',
|
||||
'apiTestManagement.saveAsCase': 'Save as new use case',
|
||||
'apiTestManagement.apiNamePlaceholder': 'Please enter the interface name',
|
||||
'apiTestManagement.executeResult': 'Execution result',
|
||||
'apiTestManagement.addDependency': 'Select Dependent Cases',
|
||||
'apiTestManagement.clearSelected': 'Clear Selected Cases',
|
||||
'apiTestManagement.preDependency': 'Pre-dependent API',
|
||||
'apiTestManagement.addPreDependency': 'Add Pre-dependency',
|
||||
'apiTestManagement.postDependency': 'Post-dependent API',
|
||||
'apiTestManagement.addPostDependency': 'Add Post-dependency',
|
||||
'apiTestManagement.dependencyUnit': 'unit(s)',
|
||||
'apiTestManagement.saveAsCase': 'Save as New Case',
|
||||
'apiTestManagement.apiNamePlaceholder': 'Please enter API name',
|
||||
'apiTestManagement.executeResult': 'Execution Result',
|
||||
'apiTestManagement.setDefault': 'Set as Default',
|
||||
'apiTestManagement.confirmDelete': 'Are you sure you want to delete {name}?',
|
||||
'apiTestManagement.confirmDelete': 'Confirm to delete {name}?',
|
||||
'apiTestManagement.response': 'Response {count}',
|
||||
'apiTestManagement.responseCode': 'Response code',
|
||||
'apiTestManagement.dynamicConversion': 'Dynamic conversion',
|
||||
'apiTestManagement.expandApi': 'Show all requests',
|
||||
'apiTestManagement.collapseApi': 'Hide all requests',
|
||||
'apiTestManagement.paramName': 'Parameter name',
|
||||
'apiTestManagement.paramVal': 'Parameter value',
|
||||
'apiTestManagement.responseCode': 'Response Code',
|
||||
'apiTestManagement.dynamicConversion': 'Dynamic Conversion',
|
||||
'apiTestManagement.expandApi': 'Show All Requests',
|
||||
'apiTestManagement.collapseApi': 'Hide All Requests',
|
||||
'apiTestManagement.paramName': 'Parameter Name',
|
||||
'apiTestManagement.paramVal': 'Parameter Value',
|
||||
'apiTestManagement.deleteMockTip':
|
||||
'Deleting a mock expectation will cause the test task using the expectation to fail, so please operate with caution!',
|
||||
'Deleting the expected response will cause the test task that uses it to fail. Please proceed with caution!',
|
||||
'apiTestManagement.preview': 'Preview',
|
||||
'apiTestManagement.shareUrlCopied': 'Sharing link copied to clipboard',
|
||||
'apiTestManagement.shareUrlCopied': 'Share link has been copied to the clipboard',
|
||||
'apiTestManagement.detail': 'Detail',
|
||||
'apiTestManagement.reference': 'Reference',
|
||||
'apiTestManagement.dependencies': 'Dependency',
|
||||
'apiTestManagement.changeHistory': 'Change history',
|
||||
'apiTestManagement.executeHistory': 'Execute history',
|
||||
'apiTestManagement.requestParams': 'Request parameters',
|
||||
'apiTestManagement.responseContent': 'Response content',
|
||||
'apiTestManagement.requestHeader': 'Request header',
|
||||
'apiTestManagement.requestBody': 'Request body',
|
||||
'apiTestManagement.paramsType': 'Param type',
|
||||
'apiTestManagement.dependencies': 'Dependencies',
|
||||
'apiTestManagement.changeHistory': 'Change History',
|
||||
'apiTestManagement.executeHistory': 'Execution History',
|
||||
'apiTestManagement.requestParams': 'Request Parameters',
|
||||
'apiTestManagement.responseContent': 'Response Content',
|
||||
'apiTestManagement.requestHeader': 'Request Header',
|
||||
'apiTestManagement.requestBody': 'Request Body',
|
||||
'apiTestManagement.paramsType': 'Parameter Type',
|
||||
'apiTestManagement.required': 'Required',
|
||||
'apiTestManagement.requestData': 'Request data',
|
||||
'apiTestManagement.apiNameRequired': 'Interface name cannot be empty',
|
||||
'apiTestManagement.requestData': 'Request Data',
|
||||
'apiTestManagement.apiNameRequired': 'API name cannot be empty',
|
||||
'apiTestManagement.historyListTip':
|
||||
'View and compare historical changes. According to the rules set by the administrator, the change history data will be automatically deleted.',
|
||||
'apiTestManagement.changeOrder': 'Change serial number',
|
||||
'apiTestManagement.order': 'Serial number',
|
||||
"View and compare historical changes. According to the administrator's settings, historical data will be automatically deleted",
|
||||
'apiTestManagement.changeOrder': 'Change Order',
|
||||
'apiTestManagement.order': 'Order',
|
||||
'apiTestManagement.type': 'Type',
|
||||
'apiTestManagement.recover': 'Recover',
|
||||
'apiTestManagement.quote': 'Quote',
|
||||
'apiTestManagement.resourceName': 'Resource name',
|
||||
'apiTestManagement.resourceType': 'Resource type',
|
||||
'apiTestManagement.quoteType': 'Quote type',
|
||||
'apiTestManagement.belongOrg': 'Organization',
|
||||
'apiTestManagement.belongProject': 'Project',
|
||||
'apiTestManagement.resourceName': 'Resource Name',
|
||||
'apiTestManagement.resourceType': 'Resource Type',
|
||||
'apiTestManagement.quoteType': 'Quote Type',
|
||||
'apiTestManagement.belongOrg': 'Belong to Organization',
|
||||
'apiTestManagement.belongProject': 'Belong to Project',
|
||||
'apiTestManagement.quoteSearchPlaceholder': 'Enter ID or name to search',
|
||||
'apiTestManagement.tableNoDataAndPlease': 'No data yet, please',
|
||||
'apiTestManagement.click': 'Click',
|
||||
'apiTestManagement.getResponse': 'Get Response Content',
|
||||
'apiTestManagement.tableNoDataAndPlease': 'No data, please',
|
||||
'apiTestManagement.or': 'or',
|
||||
'apiTestManagement.document': 'Document',
|
||||
'apiTestManagement.responseHeader': 'Response header',
|
||||
'apiTestManagement.responseTime': 'Response time',
|
||||
'apiTestManagement.document': 'Document Assertion',
|
||||
'apiTestManagement.responseHeader': 'Response Header',
|
||||
'apiTestManagement.responseTime': 'Response Time',
|
||||
'apiTestManagement.script': 'Script',
|
||||
'apiTestManagement.variable': 'Variable',
|
||||
'apiTestManagement.regex': 'Regular',
|
||||
'case.execute.selectEnv': 'Environmental choice',
|
||||
'case.execute.defaultEnv': 'Default environment',
|
||||
'case.execute.newEnv': 'New environment',
|
||||
'case.execute.defaultEnvTip': 'The environment where the use case is saved',
|
||||
'case.execute.model': 'Model',
|
||||
'apiTestManagement.regex': 'Regular Expression',
|
||||
'case.execute.selectEnv': 'Select Environment',
|
||||
'case.execute.defaultEnv': 'Default Environment',
|
||||
'case.execute.newEnv': 'New Environment',
|
||||
'case.execute.defaultEnvTip': 'Environment saved with the case',
|
||||
'case.execute.model': 'Mode',
|
||||
'case.execute.serial': 'Serial',
|
||||
'case.execute.parallel': 'Parallel',
|
||||
'case.execute.StopOnFailure': 'Stop on failure',
|
||||
'case.execute.reportSetting': 'Report configuration',
|
||||
'case.execute.independentReporting': 'Independent reporting',
|
||||
'case.execute.CollectionReport': 'Collection report',
|
||||
'case.execute.reportName': 'Report name',
|
||||
'case.execute.pool': 'Resource pool operation',
|
||||
'case.allCase': 'All Case',
|
||||
'case.execute.StopOnFailure': 'Stop on Failure',
|
||||
'case.execute.reportSetting': 'Report Configuration',
|
||||
'case.execute.independentReporting': 'Independent Reporting',
|
||||
'case.execute.CollectionReport': 'Collection Report',
|
||||
'case.execute.reportName': 'Report Name',
|
||||
'case.execute.pool': 'Run in Resource Pool',
|
||||
'case.allCase': 'All Cases',
|
||||
'case.detail': 'Case Detail',
|
||||
'case.caseName': 'Case Name',
|
||||
'case.caseNameRequired': 'Case name cannot be empty',
|
||||
'case.caseNamePlaceholder': 'Please enter case name',
|
||||
'case.caseLevel': 'Case Level',
|
||||
'case.caseEnvironment': 'Case Environment',
|
||||
'case.tableColumnCreateUser': 'CreateUser',
|
||||
'case.tableColumnCreateTime': 'CreateTime',
|
||||
'case.tableColumnUpdateUser': 'UpdateUser',
|
||||
'case.tableColumnCreateUser': 'Created By',
|
||||
'case.tableColumnCreateTime': 'Creation Time',
|
||||
'case.tableColumnUpdateUser': 'Updated By',
|
||||
'case.tableColumnUpdateTime': 'Update Time',
|
||||
'case.lastReportStatus': 'Results Of Execution',
|
||||
'case.passRate': 'Pass Rate',
|
||||
'case.passRateTip': 'Number of success case executions/Total number of case executions *%',
|
||||
'case.batchModalSubTitle': '({count} cases selected)',
|
||||
'case.batchDeleteCaseTipTitle': 'Are you sure you want to delete {name} ?',
|
||||
'case.batchRecoverCaseTipTitle': 'Are you sure you want to recover {name} ?',
|
||||
'case.batchDeleteCaseTip': 'Are you sure you want to delete {count} selected cases?',
|
||||
'case.lastReportStatus': 'Execution Result',
|
||||
'case.passRate': 'Case Pass Rate',
|
||||
'case.passRateTip': 'Success cases executed / Total cases executed *%',
|
||||
'case.batchModalSubTitle': '(Selected {count} cases)',
|
||||
'case.batchDeleteCaseTip': 'Confirm to delete the selected {count} cases?',
|
||||
'case.batchDeleteCaseTipTitle': 'Confirm to delete {name}?',
|
||||
'case.batchRecoverCaseTipTitle': 'Confirm to recover {name}?',
|
||||
'case.recycle.cleanOutDeleteOnRecycleTip':
|
||||
'After deletion, the case cannot be restored. Please operate with caution!',
|
||||
'After deletion, the case cannot be recovered. Please proceed with caution!',
|
||||
'case.deleteCaseTip':
|
||||
'Deleting an case will result in the execution failure of the test task that references the use case. Please be cautious!',
|
||||
'apiTestManagement.click': 'Click',
|
||||
'apiTestManagement.getResponse': 'Get response content',
|
||||
'case.batchRecoverCaseTip': 'Are you sure you want to recover {count} selected cases?',
|
||||
'case.recycle.recoverCaseTip': 'When restoring the case, the deleted API will be restored simultaneously.',
|
||||
'case.recycle.confirmRecovery': 'Confirm recovery',
|
||||
'Deleting the case will cause the test task that references it to fail. Please proceed with caution!',
|
||||
'case.batchRecoverCaseTip': 'Confirm to recover the selected {count} cases?',
|
||||
'case.recycle.recoverCaseTip': 'Recovering the case will also restore the deleted API',
|
||||
'case.recycle.confirmRecovery': 'Confirm Recovery',
|
||||
'case.createCase': 'Create Case',
|
||||
'case.updateCase': 'Update Case',
|
||||
'case.saveContinueText': 'Save & continue',
|
||||
'case.detail.changeHistoryTip': `View and compare historical changes. According to the administrator's setting rules, historical changes will be automatically deleted`,
|
||||
'case.detail.noReminders': 'No longer remind',
|
||||
'case.detail.changeNumber': 'Change sequence',
|
||||
'case.detail.changeType': 'type',
|
||||
'case.detail.operator': 'operator',
|
||||
'case.saveContinueText': 'Save and Continue Creating',
|
||||
'case.detail.changeHistoryTip':
|
||||
"View and compare historical changes. According to the administrator's settings, historical data will be automatically deleted",
|
||||
'case.detail.noReminders': 'Do not remind again',
|
||||
'case.detail.changeNumber': 'Change Number',
|
||||
'case.detail.changeType': 'Change Type',
|
||||
'case.detail.operator': 'Operator',
|
||||
'case.detail.tableColumnUpdateTime': 'Update Time',
|
||||
'case.detail.execute.success': 'Execute success',
|
||||
'case.detail.execute.history.list': 'Execution history list',
|
||||
'case.detail.dependency.list': 'Reference relationship list',
|
||||
'case.detail.resource.api': 'API',
|
||||
'case.detail.report.delete': 'Report cleared',
|
||||
'mockManagement.name': 'Expected name',
|
||||
'mockManagement.apiPath': 'Interface path',
|
||||
'case.detail.execute.success': 'Execution Successful',
|
||||
'case.detail.execute.history.list': 'Execution History List',
|
||||
'case.detail.dependency.list': 'Dependency List',
|
||||
'case.detail.resource.api': 'API Test',
|
||||
'case.detail.report.delete': 'Report has been cleared',
|
||||
'mockManagement.name': 'Expectation Name',
|
||||
'mockManagement.apiPath': 'API Path',
|
||||
'mockManagement.operationUser': 'Operator',
|
||||
'mockManagement.updateTime': 'Update time',
|
||||
'mockManagement.copyMock': 'Copy mock address',
|
||||
'mockManagement.batchEnable': 'Batch enable',
|
||||
'mockManagement.batchDisEnable': 'Batch disable',
|
||||
'mockManagement.batchDeleteMockTip': 'Are you sure you want to delete the selected {count} mocks?',
|
||||
'mockManagement.allMock': 'All MOCK',
|
||||
'mockManagement.updateTime': 'Update Time',
|
||||
'mockManagement.copyMock': 'Copy Mock URL',
|
||||
'mockManagement.batchEnable': 'Batch Enable',
|
||||
'mockManagement.batchDisEnable': 'Batch Disable',
|
||||
'mockManagement.batchDeleteMockTip': 'Confirm to delete the selected {count} mocks?',
|
||||
'mockManagement.allMock': 'All Mocks',
|
||||
'mockManagement.createMock': 'Create Mock',
|
||||
'mockManagement.updateMock': 'Update Mock',
|
||||
'mockManagement.mockDetail': 'Mock Detail',
|
||||
'mockManagement.namePlaceholder': 'Please enter expectation name',
|
||||
'mockManagement.nameNotNull': 'Expectation name cannot be empty',
|
||||
'mockManagement.matchRule': 'Match Rule',
|
||||
'mockManagement.saveAndContinue': 'Save and Continue Creating',
|
||||
'mockManagement.paramNameNotNull': 'Parameter name cannot be empty',
|
||||
'mockManagement.followDefinition': 'Follow API Definition',
|
||||
'mockManagement.equals': 'Equals',
|
||||
'mockManagement.notEquals': 'Not Equals',
|
||||
'mockManagement.lengthEquals': 'Length Equals',
|
||||
'mockManagement.lengthLarge': 'Length Larger Than',
|
||||
'mockManagement.lengthLess': 'Length Less Than',
|
||||
'mockManagement.lengthNotEquals': 'Length Not Equals',
|
||||
'mockManagement.contain': 'Contain',
|
||||
'mockManagement.notContain': 'Not Contain',
|
||||
'mockManagement.empty': 'Empty',
|
||||
'mockManagement.notEmpty': 'Not Empty',
|
||||
'mockManagement.regular': 'Regular Expression',
|
||||
'mockManagement.batchEdit': 'Batch Edit',
|
||||
'mockManagement.batchDelete': 'Batch Delete',
|
||||
'mockManagement.noMatchRules': 'No matching rules found',
|
||||
};
|
||||
|
|
|
@ -237,4 +237,5 @@ export default {
|
|||
'mockManagement.regular': '正则匹配',
|
||||
'mockManagement.batchEdit': '批量编辑',
|
||||
'mockManagement.batchDelete': '批量删除',
|
||||
'mockManagement.noMatchRules': '无该类匹配规则',
|
||||
};
|
||||
|
|
|
@ -128,7 +128,7 @@ export default {
|
|||
'system.config.auth.nameRequired': 'Authentication source name cannot be empty',
|
||||
'system.config.auth.namePlaceholder': 'Please enter the authentication source name',
|
||||
'system.config.auth.descPlaceholder': 'Please describe the certification source',
|
||||
'system.config.auth.addResource': 'Add resource',
|
||||
'system.config.auth.addResource': 'Add auth',
|
||||
'system.config.auth.serviceUrl': 'Server address',
|
||||
'system.config.auth.serviceUrlRequired': 'Server address cannot be empty',
|
||||
'system.config.auth.commonUrlPlaceholder': 'eg: {url}',
|
||||
|
|
|
@ -124,7 +124,7 @@ export default {
|
|||
'system.config.auth.nameRequired': '认证源名称不能为空',
|
||||
'system.config.auth.namePlaceholder': '请输入认证源名称',
|
||||
'system.config.auth.descPlaceholder': '请对该认证源进行描述',
|
||||
'system.config.auth.addResource': '添加资源',
|
||||
'system.config.auth.addResource': '添加认证',
|
||||
'system.config.auth.serviceUrl': '服务端地址',
|
||||
'system.config.auth.serviceUrlRequired': '服务端地址不能为空',
|
||||
'system.config.auth.commonUrlPlaceholder': '例如:{url}',
|
||||
|
|
Loading…
Reference in New Issue