feat(接口定义): 添加JSON编辑器,处理导入JSON数据

This commit is contained in:
fit2-zhao 2020-12-31 09:57:37 +08:00
parent 0a85155932
commit 1d908479e5
24 changed files with 161 additions and 26 deletions

View File

@ -21,6 +21,7 @@
"echarts": "^4.6.0",
"el-table-infinite-scroll": "^1.0.10",
"element-ui": "^2.13.0",
"generate-schema": "^2.6.0",
"html2canvas": "^1.0.0-rc.7",
"js-base64": "^3.4.4",
"json-bigint": "^1.0.0",

View File

@ -2,8 +2,9 @@
<div id="app">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="模版" name="apiTemplate">
<el-button type="primary" size="mini" style="margin-left: 10px" @click="openOneClickOperation">导入</el-button>
<div style="min-height: 400px">
<json-schema-editor class="schema" :value.sync="schema" lang="zh_CN" custom/>
<json-schema-editor class="schema" :value="schema" lang="zh_CN" custom/>
</div>
</el-tab-pane>
<el-tab-pane label="预览" name="preview">
@ -11,25 +12,26 @@
<pre>{{this.preview}}</pre>
</div>
</el-tab-pane>
</el-tabs>
<ms-import-json ref="importJson" @jsonData="jsonData"/>
</div>
</template>
<script>
import {schemaToJson} from './common';
import json5 from 'json5';
import MsImportJson from './import/ImportJson';
export default {
name: 'App',
components: {},
components: {MsImportJson},
data() {
return {
schema:
{
"root": {
"type": "object",
"mock": {"mock": ""},
"properties": {},
}
},
@ -42,6 +44,16 @@
if (this.activeName === 'preview') {
this.preview = schemaToJson(json5.parse(JSON.stringify(this.schema)));
}
},
openOneClickOperation() {
this.$refs.importJson.openOneClickOperation();
},
jsonData(data) {
let obj =
{
"root": data
}
this.schema = obj;
}
}
}

View File

@ -0,0 +1,117 @@
<template>
<el-dialog
title="导入"
:visible.sync="importVisible"
width="50%"
show-close
:close-on-click-modal="false"
@closed="handleClose">
<el-tabs v-model="activeName">
<el-tab-pane label="JSON" name="JSON">
<div style="height: 400px">
<ms-code-edit :mode="mode"
:data.sync="json" theme="eclipse" :modes="[]"
ref="codeEdit"/>
</div>
</el-tab-pane>
<el-tab-pane label="JSON-SCHEMA" name="JSON-SCHEMA">
<div style="height: 400px">
<ms-code-edit :mode="mode"
:data.sync="jsonSchema" theme="eclipse" :modes="[]"
ref="codeEdit"/>
</div>
</el-tab-pane>
</el-tabs>
<span slot="footer" class="dialog-footer">
<ms-dialog-footer
@cancel="importVisible = false"
@confirm="saveConfirm"/>
</span>
</el-dialog>
</template>
<script>
import MsDialogFooter from '../../../common/components/MsDialogFooter'
import MsCodeEdit from "../../../common/components/MsCodeEdit";
import json5 from 'json5';
const GenerateSchema = require('generate-schema/src/schemas/json.js');
export default {
name: "MsImportJson",
components: {MsDialogFooter, MsCodeEdit},
data() {
return {
importVisible: false,
activeName: "JSON",
mode: "json",
json: "",
jsonSchema: "",
};
},
watch: {},
props: {},
methods: {
openOneClickOperation() {
this.importVisible = true;
},
checkIsJson(json) {
try {
json5.parse(json);
return true;
} catch (e) {
alert(1);
return false;
}
},
checkIsJsonSchema(json) {
try {
json = json5.parse(json);
if (json.properties && typeof json.properties === 'object' && !json.type) {
json.type = 'object';
}
if (json.items && typeof json.items === 'object' && !json.type) {
json.type = 'array';
}
if (!json.type) {
return false;
}
json.type = json.type.toLowerCase();
let types = ['object', 'string', 'number', 'array', 'boolean', 'integer'];
if (types.indexOf(json.type) === -1) {
return false;
}
return JSON.stringify(json);
} catch (e) {
return false;
}
},
saveConfirm() {
if (this.activeName === 'JSON') {
if (!this.checkIsJson(this.json)) {
this.$error("导入的数据非JSON格式");
return;
}
let jsonData = GenerateSchema(json5.parse(this.json));
this.$emit('jsonData', jsonData);
} else {
if (!this.checkIsJsonSchema(this.jsonSchema)) {
this.$error("导入的数据非JSON-SCHEMA 格式");
return;
}
let obj = json5.parse(this.jsonSchema);
this.$emit('jsonData', obj);
}
this.importVisible = false;
},
handleClose() {
this.importVisible = false;
},
}
}
</script>
<style scoped>
</style>

View File

@ -1,8 +1,8 @@
<meta charset="utf-8">
<title>json-schema-editor-vue demo</title>
<script src="./json-schema-editor-vue.umd.js"></script>
<script src="json-schema-editor-vue.umd.js"></script>
<link rel="stylesheet" href="./json-schema-editor-vue.css">
<link rel="stylesheet" href="json-schema-editor-vue.css">
<script>

View File

@ -21,12 +21,12 @@
</el-select>
</el-col>
<el-col :span="8">
<ms-mock :schema="pickValue.mock"/>
<ms-mock :schema="pickValue"/>
</el-col>
<el-col>
<el-input v-model="pickValue.description" class="ant-col-title" :placeholder="local['description']" size="small"/>
</el-col>
<el-col :span="4" class="col-item-setting">
<el-col :span="5" class="col-item-setting">
<el-tooltip class="item" effect="dark" content="高级设置" placement="top">
<i class="el-icon-setting" @click="onSetting"/>
</el-tooltip>
@ -46,18 +46,18 @@
<json-schema-editor :value="{items:pickValue.items}" :deep="deep+1" disabled isItem :root="false" class="children" :lang="lang" :custom="custom"/>
</template>
<!-- 高级设置-->
<el-dialog :close-on-click-modal="false" :title="local['adv_setting']" :visible.sync="modalVisible" width="60%" :destroy-on-close="true"
<el-dialog :close-on-click-modal="false" :title="local['adv_setting']" :visible.sync="modalVisible" width="800px" :destroy-on-close="true"
@close="handleClose">
<!--<el-dialog v-model="modalVisible" :title="local['adv_setting']" :maskClosable="false" :okText="local['ok']" :cancelText="local['cancel']" width="800px" @ok="handleOk" dialogClass="json-schema-editor-advanced-modal">-->
<h3 v-text="local['base_setting']">基础设置</h3>
<p class="tip">基础设置 </p>
<el-form v-model="advancedValue" class="ant-advanced-search-form">
<el-row :gutter="6">
<el-col :span="8" v-for="(item,key) in advancedValue" :key="key">
<el-form-item>
<span>{{ local[key] }}</span>
<el-input-number v-model="advancedValue[key]" v-if="advancedAttr[key].type === 'integer'" style="width:100%" :placeholder="key" size="small"/>
<el-input-number v-model="advancedValue[key]" v-else-if="advancedAttr[key].type === 'number'" style="width:100%" :placeholder="key" size="small"/>
<span v-else-if="advancedAttr[key].type === 'boolean'" style="display:inline-block;width:100%">
<el-switch :active-text="local[key]" v-model="advancedValue[key]"/>
<el-switch v-model="advancedValue[key]"/>
</span>
<el-select v-else-if="advancedAttr[key].type === 'array'" v-model="advancedValue[key]" style="width:100%" size="small">
<el-option value="" :label="local['nothing']"></el-option>
@ -93,7 +93,7 @@
</el-col>
</el-row>
</el-form>-->
<h3 v-text="local['preview']">预览</h3>
<p class="tip">预览 </p>
<pre style="width:100%">{{completeNodeValue}}</pre>
<span slot="footer" class="dialog-footer">
@ -108,8 +108,8 @@
import {isNull} from './util'
import {TYPE_NAME, TYPE} from './type/type'
import MsMock from './mock/index'
import MsDialogFooter from '../../../../../common/components/MsDialogFooter'
import LocalProvider from './LocalProvider'
import MsDialogFooter from '../../../components/MsDialogFooter'
import LocalProvider from './LocalProvider/index'
export default {
name: 'JsonSchemaEditor',
@ -221,7 +221,7 @@
this.$delete(this.pickValue, 'items')
this.$delete(this.pickValue, 'required')
if (this.isArray) {
this.$set(this.pickValue, 'items', {type: 'string',mock: {mock: ""}})
this.$set(this.pickValue, 'items', {type: 'string', mock: {mock: ""}})
}
},
onCheck(e) {
@ -352,8 +352,7 @@
color: #888;
border: none;
}
</style>
<style>
.json-schema-editor-advanced-modal {
color: rgba(0, 0, 0, 0.65);
min-width: 600px;
@ -388,4 +387,11 @@
cursor: pointer;
}
.tip {
padding: 3px 5px;
font-size: 16px;
border-radius: 4px;
border-left: 4px solid #783887;
margin: 0px 0px 10px;
}
</style>

View File

@ -89,7 +89,6 @@
name: "MsApiVariableAdvance",
props: {
parameters: Array,
environment: Object,
currentItem: Object,
},
data() {

View File

@ -4,7 +4,7 @@
size="small"
:disabled="false"
class="input-with-autocomplete"
v-model="schema.mock"
v-model="mock.mock"
:fetch-suggestions="funcSearch"
:placeholder="$t('api_test.value')"
value-key="name"
@ -13,7 +13,7 @@
<i slot="suffix" class="el-input__icon el-icon-edit pointer" @click="advanced()"></i>
</el-autocomplete>
<ms-advance ref="variableAdvance" :current-item="schema"/>
<ms-advance ref="variableAdvance" :current-item="mock"/>
</div>
</template>
@ -23,7 +23,7 @@
import MsAdvance from "./Advance";
export default {
name: 'MockSelect',
name: 'MsMock',
components: {MsAdvance},
props: {
schema: {
@ -34,12 +34,12 @@
},
data() {
return {
mockValue: ''
mock: {mock: ""}
}
},
created() {
if (!this.schema.mock) {
this.schema.mock = "";
if (this.schema.mock && Object.prototype.toString.call(this.schema.mock).match(/\[object (\w+)\]/)[1].toLowerCase() === 'object') {
this.mock = this.schema.mock;
}
},
mounted() {

View File

@ -19,7 +19,7 @@ import '../common/css/main.css';
import CKEditor from '@ckeditor/ckeditor5-vue';
import VueFab from 'vue-float-action-button'
import {horizontalDrag} from "../common/js/directive";
import JsonSchemaEditor from './components/common/json-schema/ot/packages/index';
import JsonSchemaEditor from './components/common/json-schema/packages/index';
Vue.use(JsonSchemaEditor);
Vue.config.productionTip = false;