Merge remote-tracking branch 'origin/master'

This commit is contained in:
Captain.B 2021-03-24 13:30:26 +08:00
commit 5a25f3ad97
7 changed files with 213 additions and 25 deletions

View File

@ -22,14 +22,22 @@
"el-table-infinite-scroll": "^1.0.10", "el-table-infinite-scroll": "^1.0.10",
"el-tree-transfer": "^2.4.7", "el-tree-transfer": "^2.4.7",
"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",
"jsencrypt": "^3.1.0",
"json-bigint": "^1.0.0", "json-bigint": "^1.0.0",
"json-schema-faker": "^0.5.0-rcv.32", "json-schema-faker": "^0.5.0-rcv.32",
"json5": "^2.1.3", "json5": "^2.1.3",
"jsoneditor": "^9.1.2", "jsoneditor": "^9.1.2",
"jsonpath": "^1.1.0",
"jspdf": "^2.1.1", "jspdf": "^2.1.1",
"lodash.isboolean": "^3.0.3",
"lodash.isempty": "^4.4.0",
"lodash.isinteger": "^4.0.4",
"lodash.isnull": "^3.0.0",
"lodash.isnumber": "^3.0.3",
"lodash.isobject": "^3.0.2",
"lodash.isstring": "^4.0.1",
"md5": "^2.3.0", "md5": "^2.3.0",
"mockjs": "^1.1.0", "mockjs": "^1.1.0",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
@ -41,16 +49,14 @@
"vue-float-action-button": "^0.6.6", "vue-float-action-button": "^0.6.6",
"vue-i18n": "^8.15.3", "vue-i18n": "^8.15.3",
"vue-jsonpath-picker": "^1.1.5", "vue-jsonpath-picker": "^1.1.5",
"vue-minder-editor-plus": "^1.0.19",
"vue-papa-parse": "^2.0.0", "vue-papa-parse": "^2.0.0",
"vue-pdf": "^4.2.0", "vue-pdf": "^4.2.0",
"vue-router": "^3.1.3", "vue-router": "^3.1.3",
"vuedraggable": "^2.24.3", "vuedraggable": "^2.24.3",
"vuex": "^3.1.2", "vuex": "^3.1.2",
"xml-js": "^1.6.11", "xml-js": "^1.6.11",
"yan-progress": "^1.0.3", "yan-progress": "^1.0.3"
"jsonpath": "^1.1.0",
"vue-minder-editor-plus": "^1.0.19",
"jsencrypt": "^3.1.0"
}, },
"devDependencies": { "devDependencies": {
"@vue/cli-plugin-babel": "^4.1.0", "@vue/cli-plugin-babel": "^4.1.0",

View File

@ -31,7 +31,7 @@
<el-switch v-model="data.enable" class="enable-switch" size="mini" :disabled="data.disabled"/> <el-switch v-model="data.enable" class="enable-switch" size="mini" :disabled="data.disabled"/>
</el-tooltip> </el-tooltip>
<slot name="button"></slot> <slot name="button"></slot>
<step-extend-btns style="display: contents" :data="data" @copy="copyRow" @remove="remove" @openScenario="openScenario" v-if="showBtn && !data.disabled"/> <step-extend-btns style="display: contents" :data="data" @copy="copyRow" @remove="remove" @openScenario="openScenario" v-if="showBtn && (!data.disabled || data.root)"/>
</div> </div>
</div> </div>

View File

@ -83,6 +83,7 @@
import ApiBaseComponent from "../common/ApiBaseComponent"; import ApiBaseComponent from "../common/ApiBaseComponent";
import ApiResponseComponent from "./ApiResponseComponent"; import ApiResponseComponent from "./ApiResponseComponent";
import CustomizeReqInfo from "@/business/components/api/automation/scenario/common/CustomizeReqInfo"; import CustomizeReqInfo from "@/business/components/api/automation/scenario/common/CustomizeReqInfo";
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/); const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
const esbDefinition = (requireComponent != null && requireComponent.keys().length) > 0 ? requireComponent("./apidefinition/EsbDefinition.vue") : {}; const esbDefinition = (requireComponent != null && requireComponent.keys().length) > 0 ? requireComponent("./apidefinition/EsbDefinition.vue") : {};
const esbDefinitionResponse = (requireComponent != null && requireComponent.keys().length) > 0 ? requireComponent("./apidefinition/EsbDefinitionResponse.vue") : {}; const esbDefinitionResponse = (requireComponent != null && requireComponent.keys().length) > 0 ? requireComponent("./apidefinition/EsbDefinitionResponse.vue") : {};
@ -245,7 +246,8 @@
} }
this.request.requestResult = requestResult; this.request.requestResult = requestResult;
this.request.id = response.data.id; this.request.id = response.data.id;
//this.request.disabled = true; this.request.disabled = true;
this.request.root = true;
if (!this.request.projectId) { if (!this.request.projectId) {
this.request.projectId = response.data.projectId; this.request.projectId = response.data.projectId;
} }

View File

@ -7,9 +7,9 @@
<el-tabs v-model="activeName"> <el-tabs v-model="activeName">
<el-tab-pane :label="$t('api_test.scenario.variables')" name="variable"> <el-tab-pane :label="$t('api_test.scenario.variables')" name="variable">
<div style="margin-top: 10px"> <div>
<el-row style="margin-bottom: 10px"> <el-row style="margin-bottom: 10px">
<el-col :span="8"> <div style="float: left">
<el-input placeholder="变量名称搜索" v-model="selectVariable" size="small" @change="filter" <el-input placeholder="变量名称搜索" v-model="selectVariable" size="small" @change="filter"
@keyup.enter="filter"> @keyup.enter="filter">
<el-select v-model="searchType" slot="prepend" placeholder="类型" style="width: 90px" @change="filter"> <el-select v-model="searchType" slot="prepend" placeholder="类型" style="width: 90px" @change="filter">
@ -20,9 +20,9 @@
<el-option value="RANDOM" label="随机数"></el-option> <el-option value="RANDOM" label="随机数"></el-option>
</el-select> </el-select>
</el-input> </el-input>
</el-col> </div>
<el-col :span="6"> <div style="float: right">
<el-dropdown split-button type="primary" @command="handleClick" @click="handleClick('CONSTANT')" <el-dropdown split-button type="primary" @command="handleClick" @click="handleClick('CONSTANT')"
size="small" style="margin-left: 10px"> size="small" style="margin-left: 10px">
{{ $t('commons.add') }} {{ $t('commons.add') }}
@ -37,7 +37,7 @@
<el-button size="small" style="margin-left: 10px" @click="deleteVariable">{{ $t('commons.delete') }} <el-button size="small" style="margin-left: 10px" @click="deleteVariable">{{ $t('commons.delete') }}
</el-button> </el-button>
</el-col> </div>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
@ -313,6 +313,7 @@
float: right; float: right;
margin-right: 45px; margin-right: 45px;
} }
fieldset { fieldset {
padding: 0px; padding: 0px;
margin: 0px; margin: 0px;

View File

@ -21,8 +21,8 @@
<script> <script>
import {schemaToJson} from './common'; import {schemaToJson} from './common';
import MsImportJson from './import/ImportJson'; import MsImportJson from './import/ImportJson';
const Convert = require('./convert/convert.js');
const GenerateSchema = require('generate-schema/src/schemas/json.js'); const MsConvert = new Convert();
export default { export default {
name: 'App', name: 'App',
@ -32,7 +32,7 @@
}, },
created() { created() {
if (!this.body.jsonSchema && this.body.raw && this.checkIsJson(this.body.raw)) { if (!this.body.jsonSchema && this.body.raw && this.checkIsJson(this.body.raw)) {
let obj = {"root": GenerateSchema(JSON.parse(this.body.raw))} let obj = {"root": MsConvert.format(JSON.parse(this.body.raw))}
this.schema = obj; this.schema = obj;
} }
else if (this.body.jsonSchema) { else if (this.body.jsonSchema) {

View File

@ -0,0 +1,178 @@
const isBoolean = require("lodash.isboolean")
const isEmpty = require("lodash.isempty")
const isInteger = require("lodash.isinteger")
const isNull = require("lodash.isnull")
const isNumber = require("lodash.isnumber")
const isObject = require("lodash.isobject")
const isString = require("lodash.isstring")
const isArray = Array.isArray
class Convert {
constructor() {
this._option = {
$id: "http://example.com/root.json",
$schema: "http://json-schema.org/draft-07/schema#",
}
this._object = null
}
/**
* 转换函数
* @param {*} object 需要转换的对象
* @param {*} ?option 可选参数目前只有能设置 root 节点的 $id $schema
*/
format(object, option = {}) {
// 数据校验确保传入的的object只能是对象或数组
if (!isObject(object)) {
throw new TypeError("传入参数只能是对象或数组")
}
// 合并属性
this._option = Object.assign(this._option, option)
// 需要转换的对象
this._object = object
let convertRes
// 数组类型和对象类型结构不一样
if (isArray(object)) {
convertRes = this._arrayToSchema()
} else {
convertRes = this._objectToSchema()
}
// 释放
this._object = null
return convertRes
}
/**
* 数组类型转换成JSONSCHEMA
*/
_arrayToSchema() {
// root节点基本信息
let result = this._value2object(this._object, this._option.$id, "", true)
if (this._object.length > 0) {
// 创建items对象的基本信息
let objectItem = this._object[0]
result["items"] = this._value2object(objectItem, `#/items`, 'items')
if (isObject(objectItem) && !isEmpty(objectItem)) {
// 递归遍历
let objectItemSchema = this._json2schema(objectItem, `#/items`)
// 合并对象
result["items"] = Object.assign(result["items"], objectItemSchema)
}
}
return result
}
/**
* 对象类型转换成JSONSCHEMA
*/
_objectToSchema() {
let baseResult = this._value2object(this._object, this._option.$id, "", true)
let objectSchema = this._json2schema(this._object)
baseResult = Object.assign(baseResult, objectSchema)
return baseResult
}
/**
* 递归函数转换object对象为json schmea 格式
* @param {*} object 需要转换对象
* @param {*} name $id值
*/
_json2schema(object, name = "") {
// 如果递归值不是对象那么return掉
if (!isObject(object)) {
return;
}
// 处理当前路径$id
if (name === "" || name == undefined) {
name = "#"
}
let result = {};
// 判断传入object是对象还是数组。
if (isArray(object)) {
result.items = {}
} else {
result.properties = {}
}
// 遍历传入的对象
for (const key in object) {
if (object.hasOwnProperty(key)) {
const element = object[key];
// 如果只是undefined。跳过
if (element === undefined) {
continue
}
let $id = `${name}/properties/${key}`
// 判断当前 element 的值 是否也是对象如果是就继续递归不是就赋值给result
if (isObject(element)) {
// 创建当前属性的基本信息
result["properties"][key] = this._value2object(element, $id, key)
if (isArray(element)) {
// 针对空数组和有值的数组做不同处理
if (element.length > 0) {
// 如果是数组,那么就取第一项
let elementItem = element[0]
// 创建items对象的基本信息
result["properties"][key]["items"] = this._value2object(elementItem, `${$id}/items`, key + 'items')
// 判断第一项是否是对象,且对象属性不为空
if (isObject(elementItem) && !isEmpty(elementItem)) {
// 新增的properties才合并进来
result["properties"][key]["items"] = Object.assign(result["properties"][key]["items"], this._json2schema(elementItem, `${$id}/items`))
}
}
} else {
// 不是数组,递归遍历获取,然后合并对象属性
result["properties"][key] = Object.assign(result["properties"][key], this._json2schema(element, $id))
}
} else {
// 一般属性直接获取基本信息
result["properties"][key] = this._value2object(element, $id, key)
}
}
}
return result;
}
/**
* 把json的值转换成对象类型
* @param {*} value
* @param {*} $id
* @param {*} key
*/
_value2object(value, $id, key = '', root = false) {
let objectTemplate = {
$id: $id,
title: `The ${key} Schema`,
mock: {
"mock": value
},
}
// 判断是否为初始化root数据
if (root) {
objectTemplate["$schema"] = this._option.$schema
objectTemplate["title"] = `The Root Schema`
objectTemplate["mock"] = undefined
}
if (isInteger(value)) {
objectTemplate.type = "integer"
} else if (isNumber(value)) {
objectTemplate.type = "number"
} else if (isString(value)) {
objectTemplate.type = "string"
} else if (isBoolean(value)) {
objectTemplate.type = "boolean"
} else if (isNull(value)) {
objectTemplate.type = "null"
} else if (isArray(value)) {
objectTemplate.type = "array"
} else if (isObject(value)) {
objectTemplate.type = "object"
}
return objectTemplate
}
}
module.exports = Convert

View File

@ -36,8 +36,8 @@
import MsDialogFooter from '../../../common/components/MsDialogFooter' import MsDialogFooter from '../../../common/components/MsDialogFooter'
import MsCodeEdit from "../../../common/components/MsCodeEdit"; import MsCodeEdit from "../../../common/components/MsCodeEdit";
import json5 from 'json5'; import json5 from 'json5';
const Convert = require('../convert/convert.js');
const GenerateSchema = require('generate-schema/src/schemas/json.js'); const MsConvert = new Convert();
export default { export default {
name: "MsImportJson", name: "MsImportJson",
@ -93,7 +93,8 @@
this.$error("导入的数据非JSON格式"); this.$error("导入的数据非JSON格式");
return; return;
} }
let jsonData = GenerateSchema(json5.parse(this.json)); let jsonData = MsConvert.format(json5.parse(this.json));
//let jsonData = GenerateSchema(json5.parse(this.json));
this.$emit('jsonData', jsonData); this.$emit('jsonData', jsonData);
} else { } else {
if (!this.checkIsJsonSchema(this.jsonSchema)) { if (!this.checkIsJsonSchema(this.jsonSchema)) {