feat(json-schema): ms-json-schema组件-json预览接口&json导入
This commit is contained in:
parent
d37fe74580
commit
2fc5db0745
|
@ -1,3 +1,5 @@
|
||||||
|
import type { JsonSchema } from '@/components/pure/ms-json-schema/types';
|
||||||
|
|
||||||
import MSR from '@/api/http/index';
|
import MSR from '@/api/http/index';
|
||||||
import {
|
import {
|
||||||
AddCaseUrl,
|
AddCaseUrl,
|
||||||
|
@ -19,6 +21,7 @@ import {
|
||||||
BatchUpdateDefinitionUrl,
|
BatchUpdateDefinitionUrl,
|
||||||
CasePageUrl,
|
CasePageUrl,
|
||||||
CheckDefinitionScheduleUrl,
|
CheckDefinitionScheduleUrl,
|
||||||
|
ConvertJsonSchemaToJsonUrl,
|
||||||
CopyMockUrl,
|
CopyMockUrl,
|
||||||
DebugCaseUrl,
|
DebugCaseUrl,
|
||||||
DebugDefinitionUrl,
|
DebugDefinitionUrl,
|
||||||
|
@ -298,6 +301,11 @@ export function getDefinitionReference(data: DefinitionReferencePageParams) {
|
||||||
return MSR.post({ url: DefinitionReferenceUrl, data });
|
return MSR.post({ url: DefinitionReferenceUrl, data });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 将json-schema转换为 json 数据
|
||||||
|
export function convertJsonSchemaToJson(data: JsonSchema) {
|
||||||
|
return MSR.post({ url: ConvertJsonSchemaToJsonUrl, data });
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock
|
* Mock
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -35,6 +35,7 @@ export const OperationHistoryUrl = '/api/definition/operation-history'; // 接
|
||||||
export const SaveOperationHistoryUrl = '/api/definition/operation-history/save'; // 接口定义-另存变更历史为指定版本
|
export const SaveOperationHistoryUrl = '/api/definition/operation-history/save'; // 接口定义-另存变更历史为指定版本
|
||||||
export const RecoverOperationHistoryUrl = '/api/definition/operation-history/recover'; // 接口定义-变更历史恢复
|
export const RecoverOperationHistoryUrl = '/api/definition/operation-history/recover'; // 接口定义-变更历史恢复
|
||||||
export const DefinitionReferenceUrl = '/api/definition/get-reference'; // 获取接口引用关系
|
export const DefinitionReferenceUrl = '/api/definition/get-reference'; // 获取接口引用关系
|
||||||
|
export const ConvertJsonSchemaToJsonUrl = '/api/definition/preview'; // 将json-schema转换为 json 数据
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock
|
* Mock
|
||||||
|
|
|
@ -363,7 +363,11 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
const disabledPopover = computed(() => {
|
const disabledPopover = computed(() => {
|
||||||
return !innerValue.value || innerValue.value.trim() === '' || isFocusAutoComplete.value;
|
return (
|
||||||
|
!innerValue.value ||
|
||||||
|
(typeof innerValue.value === 'string' && innerValue.value.trim() === '') ||
|
||||||
|
isFocusAutoComplete.value
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const paramSettingVisible = ref(false);
|
const paramSettingVisible = ref(false);
|
||||||
|
|
|
@ -421,7 +421,7 @@
|
||||||
<div>
|
<div>
|
||||||
<div class="mb-[8px]">{{ t('ms.json.schema.preview') }}</div>
|
<div class="mb-[8px]">{{ t('ms.json.schema.preview') }}</div>
|
||||||
<MsCodeEditor
|
<MsCodeEditor
|
||||||
v-model:model-value="activePreviewValue"
|
v-model:model-value="activePreviewJsonSchemaValue"
|
||||||
theme="vs"
|
theme="vs"
|
||||||
height="500px"
|
height="500px"
|
||||||
:show-full-screen="false"
|
:show-full-screen="false"
|
||||||
|
@ -447,9 +447,9 @@
|
||||||
:show-full-screen="false"
|
:show-full-screen="false"
|
||||||
>
|
>
|
||||||
<template #leftTitle>
|
<template #leftTitle>
|
||||||
<a-radio-group default-value="json" type="button" @change="batchAddValue = ''">
|
<a-radio-group v-model:model-value="batchAddType" type="button" @change="batchAddValue = ''">
|
||||||
<a-radio value="json">Json</a-radio>
|
<a-radio value="json">Json</a-radio>
|
||||||
<a-radio value="jsonSchema">JsonSchema</a-radio>
|
<a-radio value="schema">JsonSchema</a-radio>
|
||||||
</a-radio-group>
|
</a-radio-group>
|
||||||
</template>
|
</template>
|
||||||
<template #rightTitle>
|
<template #rightTitle>
|
||||||
|
@ -462,14 +462,23 @@
|
||||||
</MsCodeEditor>
|
</MsCodeEditor>
|
||||||
</MsDrawer>
|
</MsDrawer>
|
||||||
<MsDrawer v-model:visible="previewDrawerVisible" :width="600" :title="t('common.preview')" :footer="false">
|
<MsDrawer v-model:visible="previewDrawerVisible" :width="600" :title="t('common.preview')" :footer="false">
|
||||||
<MsCodeEditor
|
<a-spin class="block" :loading="previewDrawerLoading">
|
||||||
v-model:model-value="activePreviewValue"
|
<MsCodeEditor
|
||||||
theme="vs"
|
v-model:model-value="activePreviewValue"
|
||||||
height="100%"
|
theme="vs"
|
||||||
:language="LanguageEnum.JSON"
|
height="100%"
|
||||||
:show-full-screen="false"
|
:language="LanguageEnum.JSON"
|
||||||
read-only
|
:show-full-screen="false"
|
||||||
/>
|
read-only
|
||||||
|
>
|
||||||
|
<template #leftTitle>
|
||||||
|
<a-radio-group v-model:model-value="previewShowType" type="button" @change="batchAddValue = ''">
|
||||||
|
<a-radio value="json">Json</a-radio>
|
||||||
|
<a-radio value="schema">JsonSchema</a-radio>
|
||||||
|
</a-radio-group>
|
||||||
|
</template>
|
||||||
|
</MsCodeEditor>
|
||||||
|
</a-spin>
|
||||||
</MsDrawer>
|
</MsDrawer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -485,13 +494,14 @@
|
||||||
import MsParamsInput from '@/components/business/ms-params-input/index.vue';
|
import MsParamsInput from '@/components/business/ms-params-input/index.vue';
|
||||||
import MsQuickInput from '@/components/business/ms-quick-input/index.vue';
|
import MsQuickInput from '@/components/business/ms-quick-input/index.vue';
|
||||||
|
|
||||||
|
import { convertJsonSchemaToJson } from '@/api/modules/api-test/management';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import { getGenerateId, traverseTree } from '@/utils';
|
import { getGenerateId, traverseTree } from '@/utils';
|
||||||
|
|
||||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||||
|
|
||||||
import { JsonSchemaTableItem } from './types';
|
import { JsonSchema, JsonSchemaTableItem } from './types';
|
||||||
import { convertToJsonSchema } from './utils';
|
import { parseJsonToJsonSchemaTableItem, tableItemToJsonSchema } from './utils';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
@ -828,38 +838,52 @@
|
||||||
|
|
||||||
const batchAddDrawerVisible = ref(false);
|
const batchAddDrawerVisible = ref(false);
|
||||||
const batchAddValue = ref('');
|
const batchAddValue = ref('');
|
||||||
|
const batchAddType = ref<'json' | 'schema'>('json');
|
||||||
|
|
||||||
function batchAdd() {
|
function batchAdd() {
|
||||||
batchAddDrawerVisible.value = true;
|
batchAddDrawerVisible.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyBatchAdd() {
|
function applyBatchAdd() {
|
||||||
|
if (batchAddType.value === 'json') {
|
||||||
|
const res = parseJsonToJsonSchemaTableItem(batchAddValue.value);
|
||||||
|
if (res.result.length > 0) {
|
||||||
|
data.value = res.result;
|
||||||
|
selectedKeys.value = res.ids;
|
||||||
|
}
|
||||||
|
}
|
||||||
batchAddDrawerVisible.value = false;
|
batchAddDrawerVisible.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const settingDrawerVisible = ref(false);
|
const settingDrawerVisible = ref(false);
|
||||||
const activeRecord = ref<any>({});
|
const activeRecord = ref<any>({});
|
||||||
const activePreviewValue = ref('');
|
const previewShowType = ref<'json' | 'schema'>('json');
|
||||||
|
const activePreviewJsonValue = ref('');
|
||||||
|
const activePreviewJsonSchemaValue = ref('');
|
||||||
|
const activePreviewValue = computed(() => {
|
||||||
|
return previewShowType.value === 'json' ? activePreviewJsonValue.value : activePreviewJsonSchemaValue.value;
|
||||||
|
});
|
||||||
|
|
||||||
function openSetting(record: JsonSchemaTableItem) {
|
async function openSetting(record: JsonSchemaTableItem) {
|
||||||
// 浅拷贝,以保留 parent 和 children 的引用
|
// 浅拷贝,以保留 parent 和 children 的引用
|
||||||
activeRecord.value = {
|
activeRecord.value = {
|
||||||
...record,
|
...record,
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
activePreviewValue.value = JSON.stringify(convertToJsonSchema(record, record.id === 'root'));
|
const schema = tableItemToJsonSchema(record, record.id === 'root');
|
||||||
|
activePreviewJsonSchemaValue.value = JSON.stringify(schema);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(error);
|
console.log(error);
|
||||||
activePreviewValue.value = t('ms.json.schema.convertFailed');
|
activePreviewJsonSchemaValue.value = t('ms.json.schema.convertFailed');
|
||||||
} finally {
|
} finally {
|
||||||
settingDrawerVisible.value = true;
|
settingDrawerVisible.value = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSettingFormChange() {
|
function handleSettingFormChange() {
|
||||||
activePreviewValue.value = JSON.stringify(
|
activePreviewJsonSchemaValue.value = JSON.stringify(
|
||||||
convertToJsonSchema(activeRecord.value, activeRecord.value.id === 'root')
|
tableItemToJsonSchema(activeRecord.value, activeRecord.value.id === 'root')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -901,9 +925,24 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const previewDrawerVisible = ref(false);
|
const previewDrawerVisible = ref(false);
|
||||||
function previewSchema() {
|
const previewDrawerLoading = ref(false);
|
||||||
|
|
||||||
|
async function previewSchema() {
|
||||||
previewDrawerVisible.value = true;
|
previewDrawerVisible.value = true;
|
||||||
activePreviewValue.value = JSON.stringify(convertToJsonSchema(data.value[0]));
|
try {
|
||||||
|
previewDrawerLoading.value = true;
|
||||||
|
const schema = tableItemToJsonSchema(data.value[0]);
|
||||||
|
const res = await convertJsonSchemaToJson(schema as JsonSchema);
|
||||||
|
activePreviewJsonValue.value = JSON.stringify(res);
|
||||||
|
activePreviewJsonSchemaValue.value = JSON.stringify(schema);
|
||||||
|
} catch (error) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log(error);
|
||||||
|
activePreviewJsonValue.value = t('ms.json.schema.convertFailed');
|
||||||
|
activePreviewJsonSchemaValue.value = t('ms.json.schema.convertFailed');
|
||||||
|
} finally {
|
||||||
|
previewDrawerLoading.value = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|
|
@ -21,4 +21,5 @@ export default {
|
||||||
'ms.json.schema.convertFailed': '数据转换失败,请重试',
|
'ms.json.schema.convertFailed': '数据转换失败,请重试',
|
||||||
'ms.json.schema.minItems': '最小元素数量',
|
'ms.json.schema.minItems': '最小元素数量',
|
||||||
'ms.json.schema.maxItems': '最大元素数量',
|
'ms.json.schema.maxItems': '最大元素数量',
|
||||||
|
'ms.json.schema.illegalJsonConvertFailed': '转换失败,请检查输入的json 结构是否合法',
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,7 +17,7 @@ export interface JsonSchemaCommon {
|
||||||
}
|
}
|
||||||
// json-schema 表格组件的表格项
|
// json-schema 表格组件的表格项
|
||||||
export interface JsonSchemaTableItem extends JsonSchemaCommon {
|
export interface JsonSchemaTableItem extends JsonSchemaCommon {
|
||||||
required?: string[]; // 是否必填
|
required?: boolean; // 是否必填
|
||||||
children?: JsonSchemaTableItem[];
|
children?: JsonSchemaTableItem[];
|
||||||
parent?: JsonSchemaTableItem; // 父级
|
parent?: JsonSchemaTableItem; // 父级
|
||||||
enumValues?: string; // 参数值的枚举
|
enumValues?: string; // 参数值的枚举
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
import { Message } from '@arco-design/web-vue';
|
||||||
|
|
||||||
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
import { getGenerateId } from '@/utils';
|
||||||
|
|
||||||
import type { JsonSchema, JsonSchemaItem, JsonSchemaTableItem } from './types';
|
import type { JsonSchema, JsonSchemaItem, JsonSchemaTableItem } from './types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,7 +10,7 @@ import type { JsonSchema, JsonSchemaItem, JsonSchemaTableItem } from './types';
|
||||||
* @param schemaItem 表格组件项
|
* @param schemaItem 表格组件项
|
||||||
* @param isRoot 是否为根节点
|
* @param isRoot 是否为根节点
|
||||||
*/
|
*/
|
||||||
export function convertToJsonSchema(
|
export function tableItemToJsonSchema(
|
||||||
schemaItem: JsonSchemaTableItem,
|
schemaItem: JsonSchemaTableItem,
|
||||||
isRoot: boolean = true
|
isRoot: boolean = true
|
||||||
): JsonSchema | JsonSchemaItem {
|
): JsonSchema | JsonSchemaItem {
|
||||||
|
@ -41,7 +46,7 @@ export function convertToJsonSchema(
|
||||||
required: [],
|
required: [],
|
||||||
};
|
};
|
||||||
schemaItem.children.forEach((child) => {
|
schemaItem.children.forEach((child) => {
|
||||||
const childSchema = convertToJsonSchema(child, false);
|
const childSchema = tableItemToJsonSchema(child, false);
|
||||||
schema.properties![child.title] = childSchema as JsonSchemaItem;
|
schema.properties![child.title] = childSchema as JsonSchemaItem;
|
||||||
if (child.required) {
|
if (child.required) {
|
||||||
schema.required!.push(child.title);
|
schema.required!.push(child.title);
|
||||||
|
@ -54,11 +59,97 @@ export function convertToJsonSchema(
|
||||||
schema = {
|
schema = {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
enable: schemaItem.enable,
|
enable: schemaItem.enable,
|
||||||
items: schemaItem.children.map((child) => convertToJsonSchema(child, false) as JsonSchemaItem),
|
items: schemaItem.children.map((child) => tableItemToJsonSchema(child, false) as JsonSchemaItem),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return schema;
|
return schema;
|
||||||
}
|
}
|
||||||
export default {};
|
|
||||||
|
/**
|
||||||
|
* 创建 json-schema 表格组件的表格项
|
||||||
|
* @param key 对象/数组/普通子项的 key名
|
||||||
|
* @param value 对象/数组/普通子项的值
|
||||||
|
* @param parent 父级
|
||||||
|
*/
|
||||||
|
function createItem(key: string, value: any, parent?: JsonSchemaTableItem): JsonSchemaTableItem {
|
||||||
|
let exampleValue; // 默认情况下,example 值为 undefined
|
||||||
|
const itemType = Array.isArray(value) ? 'array' : typeof value;
|
||||||
|
|
||||||
|
// 如果值不是对象或数组,则直接将值作为 example
|
||||||
|
if (itemType !== 'object' && itemType !== 'array') {
|
||||||
|
exampleValue = typeof value === 'boolean' ? value.toString() : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: getGenerateId(),
|
||||||
|
title: key,
|
||||||
|
type: itemType,
|
||||||
|
description: '',
|
||||||
|
enable: true,
|
||||||
|
required: true,
|
||||||
|
defaultValue: '',
|
||||||
|
example: exampleValue, // 仅当值不是对象或数组时,才赋予 example 值
|
||||||
|
parent,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 将 json 转换为 json-schema 表格组件的表格项
|
||||||
|
* @param json json 字符串或对象或数组
|
||||||
|
* @param parent 父级
|
||||||
|
*/
|
||||||
|
export function parseJsonToJsonSchemaTableItem(
|
||||||
|
json: string | object | Array<any>,
|
||||||
|
parent?: JsonSchemaTableItem
|
||||||
|
): { result: JsonSchemaTableItem[]; ids: Array<string> } {
|
||||||
|
if (typeof json === 'string') {
|
||||||
|
// 尝试将 json 字符串转换为对象
|
||||||
|
try {
|
||||||
|
json = JSON.parse(json);
|
||||||
|
} catch (error) {
|
||||||
|
const { t } = useI18n();
|
||||||
|
Message.warning(t('ms.json.schema.illegalJsonConvertFailed'));
|
||||||
|
return { result: [], ids: [] };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!parent) {
|
||||||
|
// 创建根节点
|
||||||
|
const rootItem: JsonSchemaTableItem = {
|
||||||
|
id: 'root',
|
||||||
|
title: 'root',
|
||||||
|
type: Array.isArray(json) ? 'array' : 'object',
|
||||||
|
description: '',
|
||||||
|
enable: true,
|
||||||
|
required: true,
|
||||||
|
example: '',
|
||||||
|
defaultValue: '',
|
||||||
|
};
|
||||||
|
const children = parseJsonToJsonSchemaTableItem(json, rootItem);
|
||||||
|
rootItem.children = children.result;
|
||||||
|
children.ids.push(rootItem.id);
|
||||||
|
return { result: [rootItem], ids: children.ids };
|
||||||
|
}
|
||||||
|
|
||||||
|
const items: JsonSchemaTableItem[] = [];
|
||||||
|
const type = Array.isArray(json) ? 'array' : 'object';
|
||||||
|
const ids: Array<string> = [];
|
||||||
|
|
||||||
|
if (type === 'object' || type === 'array') {
|
||||||
|
// 遍历对象或数组
|
||||||
|
Object.entries(json).forEach(([key, value]) => {
|
||||||
|
const item: JsonSchemaTableItem = createItem(key, value, parent);
|
||||||
|
if (typeof value === 'object' || Array.isArray(value)) {
|
||||||
|
const children = parseJsonToJsonSchemaTableItem(value, item);
|
||||||
|
item.children = children.result;
|
||||||
|
ids.push(...children.ids);
|
||||||
|
} else {
|
||||||
|
item.example = typeof value === 'boolean' ? value.toString() : value;
|
||||||
|
}
|
||||||
|
items.push(item);
|
||||||
|
ids.push(item.id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return { result: items, ids };
|
||||||
|
}
|
||||||
|
|
|
@ -276,7 +276,7 @@
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
height: 'calc(100vh - 298px)',
|
height: 'calc(100vh - 250px)',
|
||||||
threshold: 200,
|
threshold: 200,
|
||||||
fixedSize: true,
|
fixedSize: true,
|
||||||
buffer: 15, // 缓冲区默认 10 的时候,虚拟滚动的底部 padding 计算有问题
|
buffer: 15, // 缓冲区默认 10 的时候,虚拟滚动的底部 padding 计算有问题
|
||||||
|
|
Loading…
Reference in New Issue