feat(接口定义): 添加JSON编辑器,处理导入JSON数据
This commit is contained in:
parent
0a85155932
commit
1d908479e5
|
@ -21,6 +21,7 @@
|
||||||
"echarts": "^4.6.0",
|
"echarts": "^4.6.0",
|
||||||
"el-table-infinite-scroll": "^1.0.10",
|
"el-table-infinite-scroll": "^1.0.10",
|
||||||
"element-ui": "^2.13.0",
|
"element-ui": "^2.13.0",
|
||||||
|
"generate-schema": "^2.6.0",
|
||||||
"html2canvas": "^1.0.0-rc.7",
|
"html2canvas": "^1.0.0-rc.7",
|
||||||
"js-base64": "^3.4.4",
|
"js-base64": "^3.4.4",
|
||||||
"json-bigint": "^1.0.0",
|
"json-bigint": "^1.0.0",
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<el-tabs v-model="activeName" @tab-click="handleClick">
|
<el-tabs v-model="activeName" @tab-click="handleClick">
|
||||||
<el-tab-pane label="模版" name="apiTemplate">
|
<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">
|
<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>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="预览" name="preview">
|
<el-tab-pane label="预览" name="preview">
|
||||||
|
@ -11,25 +12,26 @@
|
||||||
<pre>{{this.preview}}</pre>
|
<pre>{{this.preview}}</pre>
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
|
|
||||||
|
<ms-import-json ref="importJson" @jsonData="jsonData"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {schemaToJson} from './common';
|
import {schemaToJson} from './common';
|
||||||
import json5 from 'json5';
|
import json5 from 'json5';
|
||||||
|
import MsImportJson from './import/ImportJson';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
components: {},
|
components: {MsImportJson},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
schema:
|
schema:
|
||||||
{
|
{
|
||||||
"root": {
|
"root": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"mock": {"mock": ""},
|
|
||||||
"properties": {},
|
"properties": {},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -42,6 +44,16 @@
|
||||||
if (this.activeName === 'preview') {
|
if (this.activeName === 'preview') {
|
||||||
this.preview = schemaToJson(json5.parse(JSON.stringify(this.schema)));
|
this.preview = schemaToJson(json5.parse(JSON.stringify(this.schema)));
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
openOneClickOperation() {
|
||||||
|
this.$refs.importJson.openOneClickOperation();
|
||||||
|
},
|
||||||
|
jsonData(data) {
|
||||||
|
let obj =
|
||||||
|
{
|
||||||
|
"root": data
|
||||||
|
}
|
||||||
|
this.schema = obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
|
@ -1,8 +1,8 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>json-schema-editor-vue demo</title>
|
<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>
|
<script>
|
|
@ -21,12 +21,12 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<ms-mock :schema="pickValue.mock"/>
|
<ms-mock :schema="pickValue"/>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col>
|
<el-col>
|
||||||
<el-input v-model="pickValue.description" class="ant-col-title" :placeholder="local['description']" size="small"/>
|
<el-input v-model="pickValue.description" class="ant-col-title" :placeholder="local['description']" size="small"/>
|
||||||
</el-col>
|
</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">
|
<el-tooltip class="item" effect="dark" content="高级设置" placement="top">
|
||||||
<i class="el-icon-setting" @click="onSetting"/>
|
<i class="el-icon-setting" @click="onSetting"/>
|
||||||
</el-tooltip>
|
</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"/>
|
<json-schema-editor :value="{items:pickValue.items}" :deep="deep+1" disabled isItem :root="false" class="children" :lang="lang" :custom="custom"/>
|
||||||
</template>
|
</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">
|
@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">-->
|
<p class="tip">基础设置 </p>
|
||||||
<h3 v-text="local['base_setting']">基础设置</h3>
|
|
||||||
<el-form v-model="advancedValue" class="ant-advanced-search-form">
|
<el-form v-model="advancedValue" class="ant-advanced-search-form">
|
||||||
<el-row :gutter="6">
|
<el-row :gutter="6">
|
||||||
<el-col :span="8" v-for="(item,key) in advancedValue" :key="key">
|
<el-col :span="8" v-for="(item,key) in advancedValue" :key="key">
|
||||||
<el-form-item>
|
<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-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"/>
|
<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%">
|
<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>
|
</span>
|
||||||
<el-select v-else-if="advancedAttr[key].type === 'array'" v-model="advancedValue[key]" style="width:100%" size="small">
|
<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>
|
<el-option value="" :label="local['nothing']"></el-option>
|
||||||
|
@ -93,7 +93,7 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>-->
|
</el-form>-->
|
||||||
<h3 v-text="local['preview']">预览</h3>
|
<p class="tip">预览 </p>
|
||||||
<pre style="width:100%">{{completeNodeValue}}</pre>
|
<pre style="width:100%">{{completeNodeValue}}</pre>
|
||||||
|
|
||||||
<span slot="footer" class="dialog-footer">
|
<span slot="footer" class="dialog-footer">
|
||||||
|
@ -108,8 +108,8 @@
|
||||||
import {isNull} from './util'
|
import {isNull} from './util'
|
||||||
import {TYPE_NAME, TYPE} from './type/type'
|
import {TYPE_NAME, TYPE} from './type/type'
|
||||||
import MsMock from './mock/index'
|
import MsMock from './mock/index'
|
||||||
import MsDialogFooter from '../../../../../common/components/MsDialogFooter'
|
import MsDialogFooter from '../../../components/MsDialogFooter'
|
||||||
import LocalProvider from './LocalProvider'
|
import LocalProvider from './LocalProvider/index'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'JsonSchemaEditor',
|
name: 'JsonSchemaEditor',
|
||||||
|
@ -221,7 +221,7 @@
|
||||||
this.$delete(this.pickValue, 'items')
|
this.$delete(this.pickValue, 'items')
|
||||||
this.$delete(this.pickValue, 'required')
|
this.$delete(this.pickValue, 'required')
|
||||||
if (this.isArray) {
|
if (this.isArray) {
|
||||||
this.$set(this.pickValue, 'items', {type: 'string',mock: {mock: ""}})
|
this.$set(this.pickValue, 'items', {type: 'string', mock: {mock: ""}})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onCheck(e) {
|
onCheck(e) {
|
||||||
|
@ -352,8 +352,7 @@
|
||||||
color: #888;
|
color: #888;
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
<style>
|
|
||||||
.json-schema-editor-advanced-modal {
|
.json-schema-editor-advanced-modal {
|
||||||
color: rgba(0, 0, 0, 0.65);
|
color: rgba(0, 0, 0, 0.65);
|
||||||
min-width: 600px;
|
min-width: 600px;
|
||||||
|
@ -388,4 +387,11 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tip {
|
||||||
|
padding: 3px 5px;
|
||||||
|
font-size: 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border-left: 4px solid #783887;
|
||||||
|
margin: 0px 0px 10px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
|
@ -89,7 +89,6 @@
|
||||||
name: "MsApiVariableAdvance",
|
name: "MsApiVariableAdvance",
|
||||||
props: {
|
props: {
|
||||||
parameters: Array,
|
parameters: Array,
|
||||||
environment: Object,
|
|
||||||
currentItem: Object,
|
currentItem: Object,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
|
@ -4,7 +4,7 @@
|
||||||
size="small"
|
size="small"
|
||||||
:disabled="false"
|
:disabled="false"
|
||||||
class="input-with-autocomplete"
|
class="input-with-autocomplete"
|
||||||
v-model="schema.mock"
|
v-model="mock.mock"
|
||||||
:fetch-suggestions="funcSearch"
|
:fetch-suggestions="funcSearch"
|
||||||
:placeholder="$t('api_test.value')"
|
:placeholder="$t('api_test.value')"
|
||||||
value-key="name"
|
value-key="name"
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
<i slot="suffix" class="el-input__icon el-icon-edit pointer" @click="advanced()"></i>
|
<i slot="suffix" class="el-input__icon el-icon-edit pointer" @click="advanced()"></i>
|
||||||
</el-autocomplete>
|
</el-autocomplete>
|
||||||
|
|
||||||
<ms-advance ref="variableAdvance" :current-item="schema"/>
|
<ms-advance ref="variableAdvance" :current-item="mock"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
import MsAdvance from "./Advance";
|
import MsAdvance from "./Advance";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MockSelect',
|
name: 'MsMock',
|
||||||
components: {MsAdvance},
|
components: {MsAdvance},
|
||||||
props: {
|
props: {
|
||||||
schema: {
|
schema: {
|
||||||
|
@ -34,12 +34,12 @@
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
mockValue: ''
|
mock: {mock: ""}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
if (!this.schema.mock) {
|
if (this.schema.mock && Object.prototype.toString.call(this.schema.mock).match(/\[object (\w+)\]/)[1].toLowerCase() === 'object') {
|
||||||
this.schema.mock = "";
|
this.mock = this.schema.mock;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
|
@ -19,7 +19,7 @@ import '../common/css/main.css';
|
||||||
import CKEditor from '@ckeditor/ckeditor5-vue';
|
import CKEditor from '@ckeditor/ckeditor5-vue';
|
||||||
import VueFab from 'vue-float-action-button'
|
import VueFab from 'vue-float-action-button'
|
||||||
import {horizontalDrag} from "../common/js/directive";
|
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.use(JsonSchemaEditor);
|
||||||
|
|
||||||
Vue.config.productionTip = false;
|
Vue.config.productionTip = false;
|
||||||
|
|
Loading…
Reference in New Issue