parent
51fbe8e2d5
commit
dab9c08ee6
|
@ -134,6 +134,32 @@
|
||||||
|
|
||||||
<ms-change-history ref="changeHistory"/>
|
<ms-change-history ref="changeHistory"/>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
:fullscreen="true"
|
||||||
|
:visible.sync="dialogVisible"
|
||||||
|
width="100%"
|
||||||
|
>
|
||||||
|
<http-api-version-diff
|
||||||
|
:old-data="httpForm"
|
||||||
|
:show-follow="showFollow"
|
||||||
|
:new-data="newData"
|
||||||
|
:new-show-follow="newShowFollow"
|
||||||
|
:old-mock-url="getUrlPrefix"
|
||||||
|
:new-mock-url="newMockUrl"
|
||||||
|
:rule="rule"
|
||||||
|
:maintainer-options="maintainerOptions"
|
||||||
|
:module-options="moduleOptions"
|
||||||
|
:request="request"
|
||||||
|
:old-request="oldRequest"
|
||||||
|
:response="response"
|
||||||
|
:old-response="oldResponse"
|
||||||
|
></http-api-version-diff>
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible=false">取 消</el-button>
|
||||||
|
<el-button type="primary" >确 定</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -151,6 +177,11 @@ import MsChangeHistory from "../../../../history/ChangeHistory";
|
||||||
import {getCurrentProjectID, getCurrentUser, getUUID, hasLicense} from "@/common/js/utils";
|
import {getCurrentProjectID, getCurrentUser, getUUID, hasLicense} from "@/common/js/utils";
|
||||||
import MsFormDivider from "@/business/components/common/components/MsFormDivider";
|
import MsFormDivider from "@/business/components/common/components/MsFormDivider";
|
||||||
import ApiOtherInfo from "@/business/components/api/definition/components/complete/ApiOtherInfo";
|
import ApiOtherInfo from "@/business/components/api/definition/components/complete/ApiOtherInfo";
|
||||||
|
import HttpApiVersionDiff from "./version/HttpApiVersionDiff"
|
||||||
|
import {createComponent } from ".././jmeter/components";
|
||||||
|
import { TYPE_TO_C} from "@/business/components/api/automation/scenario/Setting";
|
||||||
|
|
||||||
|
const {Body} = require("@/business/components/api/definition/model/ApiTestModel");
|
||||||
|
|
||||||
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
||||||
const versionHistory = requireComponent.keys().length > 0 ? requireComponent("./version/VersionHistory.vue") : {};
|
const versionHistory = requireComponent.keys().length > 0 ? requireComponent("./version/VersionHistory.vue") : {};
|
||||||
|
@ -161,7 +192,8 @@ export default {
|
||||||
'MsVersionHistory': versionHistory.default,
|
'MsVersionHistory': versionHistory.default,
|
||||||
ApiOtherInfo,
|
ApiOtherInfo,
|
||||||
MsFormDivider,
|
MsFormDivider,
|
||||||
MsJsr233Processor, MsResponseText, MsApiRequestForm, MsInputTag, MsSelectTree, MsChangeHistory
|
MsJsr233Processor, MsResponseText, MsApiRequestForm, MsInputTag, MsSelectTree, MsChangeHistory,
|
||||||
|
HttpApiVersionDiff
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
let validateURL = (rule, value, callback) => {
|
let validateURL = (rule, value, callback) => {
|
||||||
|
@ -185,8 +217,11 @@ export default {
|
||||||
status: [{required: true, message: this.$t('commons.please_select'), trigger: 'change'}],
|
status: [{required: true, message: this.$t('commons.please_select'), trigger: 'change'}],
|
||||||
},
|
},
|
||||||
httpForm: {environmentId: "", path: "", tags: []},
|
httpForm: {environmentId: "", path: "", tags: []},
|
||||||
|
newData:{environmentId: "", path: "", tags: []},
|
||||||
|
dialogVisible:false,
|
||||||
isShowEnable: true,
|
isShowEnable: true,
|
||||||
showFollow: false,
|
showFollow: false,
|
||||||
|
newShowFollow:false,
|
||||||
maintainerOptions: [],
|
maintainerOptions: [],
|
||||||
currentModule: {},
|
currentModule: {},
|
||||||
reqOptions: REQ_METHOD,
|
reqOptions: REQ_METHOD,
|
||||||
|
@ -197,8 +232,11 @@ export default {
|
||||||
label: 'name',
|
label: 'name',
|
||||||
},
|
},
|
||||||
mockBaseUrl: "",
|
mockBaseUrl: "",
|
||||||
|
newMockBaseUrl: "",
|
||||||
count: 0,
|
count: 0,
|
||||||
versionData: [],
|
versionData: [],
|
||||||
|
oldRequest:{},
|
||||||
|
oldResponse:{}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: {moduleOptions: {}, request: {}, response: {}, basisData: {}, syncTabs: Array, projectId: String},
|
props: {moduleOptions: {}, request: {}, response: {}, basisData: {}, syncTabs: Array, projectId: String},
|
||||||
|
@ -314,6 +352,39 @@ export default {
|
||||||
}
|
}
|
||||||
return this.mockBaseUrl + path;
|
return this.mockBaseUrl + path;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
newMockUrl() {
|
||||||
|
if (this.newData.path == null) {
|
||||||
|
return this.newMockBaseUrl;
|
||||||
|
} else {
|
||||||
|
let path = this.newData.path;
|
||||||
|
let protocol = this.newData.method;
|
||||||
|
if (protocol === 'GET' || protocol === 'DELETE') {
|
||||||
|
if (this.newData.request != null && this.newData.request.rest != null) {
|
||||||
|
let pathUrlArr = path.split("/");
|
||||||
|
let newPath = "";
|
||||||
|
pathUrlArr.forEach(item => {
|
||||||
|
if (item !== "") {
|
||||||
|
let pathItem = item;
|
||||||
|
if (item.indexOf("{") === 0 && item.indexOf("}") === (item.length - 1)) {
|
||||||
|
let paramItem = item.substr(1, item.length - 2);
|
||||||
|
for (let i = 0; i < this.newData.request.rest.length; i++) {
|
||||||
|
let param = this.newData.request.rest[i];
|
||||||
|
if (param.name === paramItem) {
|
||||||
|
pathItem = param.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newPath += "/" + pathItem;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (newPath !== "") {
|
||||||
|
path = newPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.newMockBaseUrl + path;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -428,6 +499,7 @@ export default {
|
||||||
conditions.forEach(condition => {
|
conditions.forEach(condition => {
|
||||||
if (condition.type === httpType) {
|
if (condition.type === httpType) {
|
||||||
this.mockBaseUrl = condition.protocol + "://" + condition.socket;
|
this.mockBaseUrl = condition.protocol + "://" + condition.socket;
|
||||||
|
this.newMockBaseUrl = this.mockBaseUrl;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -466,7 +538,95 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
compare(row) {
|
compare(row) {
|
||||||
// console.log(row);
|
this.$get('/api/definition/get/' + row.id+"/"+this.httpForm.refId, response => {
|
||||||
|
this.$get('/api/definition/get/' + response.data.id, res => {
|
||||||
|
if (res.data) {
|
||||||
|
this.newData = res.data;
|
||||||
|
this.$get('/api/definition/follow/' + response.data.id, resp => {
|
||||||
|
if(resp.data&&resp.data.follows){
|
||||||
|
for (let i = 0; i <resp.data.follows.length; i++) {
|
||||||
|
if(resp.data.follows[i]===this.currentUser().id){
|
||||||
|
this.newShowFollow = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.setRequest(res.data)
|
||||||
|
if (!this.setRequest(res.data)) {
|
||||||
|
this.oldRequest = createComponent("HTTPSamplerProxy");
|
||||||
|
}
|
||||||
|
this.formatApi(res.data)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
if(this.newData){
|
||||||
|
this.dialogVisible = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setRequest(api) {
|
||||||
|
if (api.request !== undefined) {
|
||||||
|
if (Object.prototype.toString.call(api.request).match(/\[object (\w+)\]/)[1].toLowerCase() === 'object') {
|
||||||
|
this.oldRequest = api.request;
|
||||||
|
} else {
|
||||||
|
this.oldRequest = JSON.parse(api.request);
|
||||||
|
}
|
||||||
|
if (!this.oldRequest.headers) {
|
||||||
|
this.oldRequest.headers = [];
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
formatApi(api) {
|
||||||
|
if (api.response != null && api.response !== 'null' && api.response !== undefined) {
|
||||||
|
if (Object.prototype.toString.call(api.response).match(/\[object (\w+)\]/)[1].toLowerCase() === 'object') {
|
||||||
|
this.oldResponse = api.response;
|
||||||
|
} else {
|
||||||
|
this.oldResponse = JSON.parse(api.response);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.oldResponse = {headers: [], body: new Body(), statusCode: [], type: "HTTP"};
|
||||||
|
}
|
||||||
|
if (!this.oldRequest.hashTree) {
|
||||||
|
this.oldRequest.hashTree = [];
|
||||||
|
}
|
||||||
|
if (this.oldRequest.body && !this.oldRequest.body.binary) {
|
||||||
|
this.oldRequest.body.binary = [];
|
||||||
|
}
|
||||||
|
// 处理导入数据缺失问题
|
||||||
|
if (this.oldResponse.body) {
|
||||||
|
let body = new Body();
|
||||||
|
Object.assign(body, this.oldResponse.body);
|
||||||
|
if (!body.binary) {
|
||||||
|
body.binary = [];
|
||||||
|
}
|
||||||
|
if (!body.kvs) {
|
||||||
|
body.kvs = [];
|
||||||
|
}
|
||||||
|
if (!body.binary) {
|
||||||
|
body.binary = [];
|
||||||
|
}
|
||||||
|
this.oldResponse.body = body;
|
||||||
|
}
|
||||||
|
this.oldRequest.clazzName = TYPE_TO_C.get(this.oldRequest.type);
|
||||||
|
|
||||||
|
this.sort(this.oldRequest.hashTree);
|
||||||
|
},
|
||||||
|
sort(stepArray) {
|
||||||
|
if (stepArray) {
|
||||||
|
for (let i in stepArray) {
|
||||||
|
if (!stepArray[i].clazzName) {
|
||||||
|
stepArray[i].clazzName = TYPE_TO_C.get(stepArray[i].type);
|
||||||
|
}
|
||||||
|
if (stepArray[i].type === "Assertions" && !stepArray[i].document) {
|
||||||
|
stepArray[i].document = {type: "JSON", data: {xmlFollowAPI: false, jsonFollowAPI: false, json: [], xml: []}};
|
||||||
|
}
|
||||||
|
if (stepArray[i].hashTree && stepArray[i].hashTree.length > 0) {
|
||||||
|
this.sort(stepArray[i].hashTree);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
checkout(row) {
|
checkout(row) {
|
||||||
let api = this.versionData.filter(v => v.versionId === row.id)[0];
|
let api = this.versionData.filter(v => v.versionId === row.id)[0];
|
||||||
|
|
|
@ -0,0 +1,316 @@
|
||||||
|
<template>
|
||||||
|
<div class="compare-class">
|
||||||
|
<el-card style="width: 50%;" ref="old">
|
||||||
|
<el-form :model="oldData" :rules="rule" ref="httpForm" label-width="80px" label-position="right">
|
||||||
|
<!-- 操作按钮 -->
|
||||||
|
<div style="float: right;margin-right: 20px" class="ms-opt-btn">
|
||||||
|
<el-tooltip :content="$t('commons.follow')" placement="bottom" effect="dark" v-if="!showFollow">
|
||||||
|
<i class="el-icon-star-off"
|
||||||
|
style="color: #783987; font-size: 25px; margin-right: 5px; position: relative; top: 5px; cursor: pointer "/>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip :content="$t('commons.cancel')" placement="bottom" effect="dark" v-if="showFollow">
|
||||||
|
<i class="el-icon-star-on"
|
||||||
|
style="color: #783987; font-size: 28px; margin-right: 5px; position: relative; top: 5px; cursor: pointer "/>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
<ms-form-divider :title="$t('test_track.plan_view.base_info')"/>
|
||||||
|
|
||||||
|
<!-- 基础信息 -->
|
||||||
|
<div class="base-info">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item :label="$t('commons.name')" prop="name">
|
||||||
|
<el-input class="ms-http-input" size="small" v-model="oldData.name"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="16">
|
||||||
|
<el-form-item :label="$t('api_report.request')" prop="path">
|
||||||
|
<el-input :placeholder="$t('api_test.definition.request.path_info')" v-model="oldData.path"
|
||||||
|
class="ms-http-input" size="small" style="margin-top: 5px" >
|
||||||
|
<el-select v-model="oldData.method" slot="prepend" style="width: 100px" size="small">
|
||||||
|
<el-option v-for="item in reqOptions" :key="item.id" :label="item.label" :value="item.id"/>
|
||||||
|
</el-select>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item :label="$t('api_test.definition.request.responsible')" prop="userId">
|
||||||
|
<el-select v-model="oldData.userId"
|
||||||
|
:placeholder="$t('api_test.definition.request.responsible')" filterable size="small"
|
||||||
|
class="ms-http-select">
|
||||||
|
<el-option
|
||||||
|
v-for="item in maintainerOptions"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name + ' (' + item.id + ')'"
|
||||||
|
:value="item.id">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item :label="$t('test_track.module.module')" prop="moduleId">
|
||||||
|
<ms-select-tree size="small" :data="moduleOptions" :defaultKey="oldData.moduleId"
|
||||||
|
:obj="moduleObj" clearable checkStrictly/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item :label="$t('commons.status')" prop="status">
|
||||||
|
<el-select class="ms-http-select" size="small" v-model="oldData.status">
|
||||||
|
<el-option v-for="item in options" :key="item.id" :label="$t(item.label)" :value="item.id"/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item :label="$t('commons.tag')" prop="tag">
|
||||||
|
<ms-input-tag :currentScenario="oldData" ref="tag" v-model="oldData.tags"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item :label="$t('commons.description')" prop="description">
|
||||||
|
<el-input class="ms-http-textarea"
|
||||||
|
v-model="oldData.description"
|
||||||
|
type="textarea"
|
||||||
|
:autosize="{ minRows: 1, maxRows: 10}"
|
||||||
|
:rows="1" size="small"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- MOCK信息 -->
|
||||||
|
<ms-form-divider :title="$t('test_track.plan_view.mock_info')"/>
|
||||||
|
<div class="base-info mock-info">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="20">
|
||||||
|
Mock地址:
|
||||||
|
<el-link :href="oldMockUrl" target="_blank" style="color: black"
|
||||||
|
type="primary">{{ this.oldMockUrl }}
|
||||||
|
</el-link>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 请求参数 -->
|
||||||
|
<div>
|
||||||
|
<ms-form-divider :title="$t('api_test.definition.request.req_param')"/>
|
||||||
|
<ms-api-request-form :showScript="false" :request="request" :headers="request.headers"
|
||||||
|
:isShowEnable="isShowEnable"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<!-- 响应内容-->
|
||||||
|
<ms-form-divider :title="$t('api_test.definition.request.res_param')"/>
|
||||||
|
<ms-response-text :response="response"/>
|
||||||
|
|
||||||
|
<api-other-info :api="oldData"/>
|
||||||
|
|
||||||
|
</el-card>
|
||||||
|
<el-card style="width: 50%;" ref="new">
|
||||||
|
<el-form :model="newData" :rules="rule" ref="httpForm" label-width="80px" label-position="right">
|
||||||
|
<!-- 操作按钮 -->
|
||||||
|
<div style="float: right;margin-right: 20px" class="ms-opt-btn">
|
||||||
|
<el-tooltip :content="$t('commons.follow')" placement="bottom" effect="dark" v-if="!newShowFollow">
|
||||||
|
<i class="el-icon-star-off"
|
||||||
|
style="color: #783987; font-size: 25px; margin-right: 5px; position: relative; top: 5px; cursor: pointer "/>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip :content="$t('commons.cancel')" placement="bottom" effect="dark" v-if="newShowFollow">
|
||||||
|
<i class="el-icon-star-on"
|
||||||
|
style="color: #783987; font-size: 28px; margin-right: 5px; position: relative; top: 5px; cursor: pointer "/>
|
||||||
|
</el-tooltip>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<ms-form-divider :title="$t('test_track.plan_view.base_info')"/>
|
||||||
|
|
||||||
|
<!-- 基础信息 -->
|
||||||
|
<div class="base-info">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item :label="$t('commons.name')" prop="name">
|
||||||
|
<el-input class="ms-http-input" size="small" v-model="newData.name"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="16">
|
||||||
|
<el-form-item :label="$t('api_report.request')" prop="path">
|
||||||
|
<el-input :placeholder="$t('api_test.definition.request.path_info')" v-model="newData.path"
|
||||||
|
class="ms-http-input" size="small" style="margin-top: 5px" >
|
||||||
|
<el-select v-model="newData.method" slot="prepend" style="width: 100px" size="small">
|
||||||
|
<el-option v-for="item in reqOptions" :key="item.id" :label="item.label" :value="item.id"/>
|
||||||
|
</el-select>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item :label="$t('api_test.definition.request.responsible')" prop="userId">
|
||||||
|
<el-select v-model="newData.userId"
|
||||||
|
:placeholder="$t('api_test.definition.request.responsible')" filterable size="small"
|
||||||
|
class="ms-http-select">
|
||||||
|
<el-option
|
||||||
|
v-for="item in maintainerOptions"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name + ' (' + item.id + ')'"
|
||||||
|
:value="item.id">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item :label="$t('test_track.module.module')" prop="moduleId">
|
||||||
|
<ms-select-tree size="small" :data="moduleOptions" :defaultKey="newData.moduleId"
|
||||||
|
:obj="moduleObj" clearable checkStrictly/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item :label="$t('commons.status')" prop="status">
|
||||||
|
<el-select class="ms-http-select" size="small" v-model="newData.status">
|
||||||
|
<el-option v-for="item in options" :key="item.id" :label="$t(item.label)" :value="item.id"/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item :label="$t('commons.tag')" prop="tag">
|
||||||
|
<ms-input-tag :currentScenario="newData" ref="tag" v-model="newData.tags"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item :label="$t('commons.description')" prop="description">
|
||||||
|
<el-input class="ms-http-textarea"
|
||||||
|
v-model="newData.description"
|
||||||
|
type="textarea"
|
||||||
|
:autosize="{ minRows: 1, maxRows: 10}"
|
||||||
|
:rows="1" size="small"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- MOCK信息 -->
|
||||||
|
<ms-form-divider :title="$t('test_track.plan_view.mock_info')"/>
|
||||||
|
<div class="base-info mock-info">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="20">
|
||||||
|
Mock地址:
|
||||||
|
<el-link :href="newMockUrl" target="_blank" style="color: black"
|
||||||
|
type="primary">{{ this.newMockUrl }}
|
||||||
|
</el-link>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 请求参数 -->
|
||||||
|
<div>
|
||||||
|
<ms-form-divider :title="$t('api_test.definition.request.req_param')"/>
|
||||||
|
<ms-api-request-form :showScript="false" :request="oldRequest" :headers="oldRequest.headers"
|
||||||
|
:isShowEnable="isShowEnable"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<!-- 响应内容-->
|
||||||
|
<ms-form-divider :title="$t('api_test.definition.request.res_param')"/>
|
||||||
|
<ms-response-text :response="oldResponse"/>
|
||||||
|
|
||||||
|
<api-other-info :api="newData"/>
|
||||||
|
</el-card>
|
||||||
|
<button @click="getDiff"></button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import {API_STATUS, REQ_METHOD} from "../../../model/JsonData";
|
||||||
|
import MsFormDivider from "@/business/components/common/components/MsFormDivider";
|
||||||
|
import ApiOtherInfo from "@/business/components/api/definition/components/complete/ApiOtherInfo";
|
||||||
|
import MsResponseText from "../../response/ResponseText";
|
||||||
|
import MsApiRequestForm from "../../request/http/ApiHttpRequestForm";
|
||||||
|
import MsSelectTree from "../../../../../common/select-tree/SelectTree";
|
||||||
|
import MsInputTag from "@/business/components/api/automation/scenario/MsInputTag";
|
||||||
|
|
||||||
|
const {diff} = require("@/business/components/performance/v_node_diff");
|
||||||
|
|
||||||
|
export default{
|
||||||
|
name: "HttpApiVersionDiff",
|
||||||
|
components: {
|
||||||
|
ApiOtherInfo,
|
||||||
|
MsFormDivider,
|
||||||
|
MsResponseText,
|
||||||
|
MsApiRequestForm,
|
||||||
|
MsInputTag,
|
||||||
|
MsSelectTree,
|
||||||
|
},
|
||||||
|
props:{
|
||||||
|
oldData:{
|
||||||
|
type:Object
|
||||||
|
},
|
||||||
|
newData:{
|
||||||
|
type:Object
|
||||||
|
},
|
||||||
|
showFollow:{
|
||||||
|
type:Boolean
|
||||||
|
},
|
||||||
|
newShowFollow:{
|
||||||
|
type:Boolean
|
||||||
|
},
|
||||||
|
rule:{
|
||||||
|
type:Object
|
||||||
|
},
|
||||||
|
maintainerOptions:{
|
||||||
|
type:Array
|
||||||
|
},
|
||||||
|
moduleOptions:{},
|
||||||
|
oldMockUrl:{
|
||||||
|
},
|
||||||
|
newMockUrl:{
|
||||||
|
},
|
||||||
|
request: {},
|
||||||
|
oldRequest:{},
|
||||||
|
response: {},
|
||||||
|
oldResponse:{}
|
||||||
|
},
|
||||||
|
|
||||||
|
data(){
|
||||||
|
return{
|
||||||
|
reqOptions: REQ_METHOD,
|
||||||
|
options: API_STATUS,
|
||||||
|
moduleObj: {
|
||||||
|
id: 'id',
|
||||||
|
label: 'name',
|
||||||
|
},
|
||||||
|
isShowEnable: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
getDiff(){
|
||||||
|
let oldVnode = this.$refs.old
|
||||||
|
let vnode = this.$refs.new
|
||||||
|
//oldVnode.style.backgroundColor = "rgb(241,200,196)";
|
||||||
|
console.log(this.$refs.old)
|
||||||
|
console.log(this.$refs.new)
|
||||||
|
diff(oldVnode,vnode);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.compare-class{
|
||||||
|
display: flex;
|
||||||
|
justify-content:space-between;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -70,24 +70,32 @@ function changeStyle(diffNode){
|
||||||
console.log(diffNode.oldNodeArray);
|
console.log(diffNode.oldNodeArray);
|
||||||
console.log(diffNode.nodeArray);
|
console.log(diffNode.nodeArray);
|
||||||
for (let i = 0; i < diffNode.oldNodeArray.length; i++) {
|
for (let i = 0; i < diffNode.oldNodeArray.length; i++) {
|
||||||
if(diffNode.oldNodeArray[i]==='comment'||isUndef(diffNode.oldNodeArray[i].style)){
|
if(diffNode.oldNodeArray[i]==='comment'||diffNode.oldNodeArray[i].nodeName==="#comment"){
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if(diffNode.oldNodeArray[i].className==='cell'){
|
if(diffNode.oldNodeArray[i].className==='cell'){
|
||||||
let rowVnodeElm = findRowVnodeElm(diffNode.oldNodeArray[i]);
|
let rowVnodeElm = findRowVnodeElm(diffNode.oldNodeArray[i]);
|
||||||
|
if(isDef(rowVnodeElm.style)){
|
||||||
rowVnodeElm.style.setProperty("background-color","rgb(241,200,196)",'important')
|
rowVnodeElm.style.setProperty("background-color","rgb(241,200,196)",'important')
|
||||||
|
}else if(isDef(rowVnodeElm.parentNode.style)&&rowVnodeElm!=='comment'){
|
||||||
|
rowVnodeElm.parentNode.style.setProperty("background-color","rgb(241,200,196)",'important')
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
changeStyleBySubset(diffNode.oldNodeArray[i],"rgb(241,200,196)");
|
changeStyleBySubset(diffNode.oldNodeArray[i],"rgb(241,200,196)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < diffNode.nodeArray.length; i++) {
|
for (let i = 0; i < diffNode.nodeArray.length; i++) {
|
||||||
if(diffNode.nodeArray[i]==='comment'||isUndef(diffNode.nodeArray[i].style)){
|
if(diffNode.nodeArray[i]==='comment'||diffNode.nodeArray[i].nodeName==="#comment"){
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if(diffNode.nodeArray[i].className==='cell'){
|
if(diffNode.nodeArray[i].className==='cell'){
|
||||||
let rowVnodeElm = findRowVnodeElm(diffNode.nodeArray[i]);
|
let rowVnodeElm = findRowVnodeElm(diffNode.nodeArray[i]);
|
||||||
|
if(isDef(rowVnodeElm.style)){
|
||||||
rowVnodeElm.style.setProperty("background-color","rgb(215, 243, 215)",'important')
|
rowVnodeElm.style.setProperty("background-color","rgb(215, 243, 215)",'important')
|
||||||
|
}else if(isDef(rowVnodeElm.parentNode.style)&&rowVnodeElm!=='comment'){
|
||||||
|
rowVnodeElm.parentNode.style.setProperty("background-color","rgb(215, 243, 215)",'important')
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
changeStyleBySubset(diffNode.nodeArray[i],"rgb(215, 243, 215)");
|
changeStyleBySubset(diffNode.nodeArray[i],"rgb(215, 243, 215)");
|
||||||
}
|
}
|
||||||
|
@ -98,6 +106,8 @@ function changeStyleBySubset(vnodeElm,color){
|
||||||
if(isDef(vnodeElm.children)&&vnodeElm.children.length>0){
|
if(isDef(vnodeElm.children)&&vnodeElm.children.length>0){
|
||||||
if(isDef(vnodeElm.style)){
|
if(isDef(vnodeElm.style)){
|
||||||
vnodeElm.style.setProperty("background-color",color,'important')
|
vnodeElm.style.setProperty("background-color",color,'important')
|
||||||
|
}else if(isDef(vnodeElm.parentNode.style)&&vnodeElm!=='comment'){
|
||||||
|
vnodeElm.parentNode.style.setProperty("background-color",color,'important')
|
||||||
}
|
}
|
||||||
for (let i = 0; i < vnodeElm.children.length; i++) {
|
for (let i = 0; i < vnodeElm.children.length; i++) {
|
||||||
changeStyleBySubset(vnodeElm.children[i],color);
|
changeStyleBySubset(vnodeElm.children[i],color);
|
||||||
|
@ -105,7 +115,7 @@ function changeStyleBySubset(vnodeElm,color){
|
||||||
}else {
|
}else {
|
||||||
if(isDef(vnodeElm.style)){
|
if(isDef(vnodeElm.style)){
|
||||||
vnodeElm.style.setProperty("background-color",color,'important')
|
vnodeElm.style.setProperty("background-color",color,'important')
|
||||||
}else {
|
}else if(isDef(vnodeElm.parentNode.style)&&vnodeElm!=='comment'){
|
||||||
vnodeElm.parentNode.style.setProperty("background-color",color,'important')
|
vnodeElm.parentNode.style.setProperty("background-color",color,'important')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,12 +174,12 @@ function diffChildren(oldChildren,newChildren,diffNode,isCompareChildren){
|
||||||
let newVnode = newChildren[i]
|
let newVnode = newChildren[i]
|
||||||
diffDetail(oldVnode,newVnode,diffNode)
|
diffDetail(oldVnode,newVnode,diffNode)
|
||||||
}
|
}
|
||||||
for (let i = childrenLength; i <= (oldLength - childrenLength); i++) {
|
for (let i = childrenLength; i < oldLength; i++) {
|
||||||
if(oldChildren[i]){
|
if(oldChildren[i]){
|
||||||
diffNode.oldNodeArray.push(oldChildren[i].elm);
|
diffNode.oldNodeArray.push(oldChildren[i].elm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let i = childrenLength; i <= (newLength - childrenLength); i++) {
|
for (let i = childrenLength; i < newLength; i++) {
|
||||||
if(newChildren[i]){
|
if(newChildren[i]){
|
||||||
diffNode.nodeArray.push(newChildren[i].elm);
|
diffNode.nodeArray.push(newChildren[i].elm);
|
||||||
}
|
}
|
||||||
|
@ -236,7 +246,6 @@ function sameDetail(oldVnode,newVnode,sameNode){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function diffDetail(oldVnode,newVnode,diffNode){
|
function diffDetail(oldVnode,newVnode,diffNode){
|
||||||
if(isDef(oldVnode.child)&&isUndef(newVnode.child)){
|
if(isDef(oldVnode.child)&&isUndef(newVnode.child)){
|
||||||
diffNode.oldNodeArray.push(oldVnode.child._vnode.elm);
|
diffNode.oldNodeArray.push(oldVnode.child._vnode.elm);
|
||||||
|
@ -268,21 +277,15 @@ function diffDetail(oldVnode,newVnode,diffNode){
|
||||||
}
|
}
|
||||||
diffChildren(oldVnode.children,newVnode.children,diffNode,isCompareChildren)
|
diffChildren(oldVnode.children,newVnode.children,diffNode,isCompareChildren)
|
||||||
}
|
}
|
||||||
//剩最后的子节点的时候,分类型做判断
|
//剩最后的子节点的时候,分类型做判断(注意,最后的子节点的真实dom里可能还有dom节点)
|
||||||
if(isUndef(oldVnode.child)&&isUndef(newVnode.child)&&isUndef(oldVnode.children)&&isUndef(newVnode.children)){
|
if(isUndef(oldVnode.child)&&isUndef(newVnode.child)&&isUndef(oldVnode.children)&&isUndef(newVnode.children)){
|
||||||
|
//比较真实的dom
|
||||||
|
diffRealNode(oldVnode.elm,newVnode.elm,diffNode);
|
||||||
|
|
||||||
if(isDef(oldVnode.text)&&isDef(newVnode.text)){
|
if(isDef(oldVnode.text)&&isDef(newVnode.text)){
|
||||||
if(oldVnode.text!==newVnode.text){
|
if(oldVnode.text!==newVnode.text){
|
||||||
if(isDef(oldVnode.elm.style)){
|
|
||||||
diffNode.oldNodeArray.push(oldVnode.elm);
|
diffNode.oldNodeArray.push(oldVnode.elm);
|
||||||
}else {
|
|
||||||
diffNode.oldNodeArray.push(oldVnode.elm.parentNode);
|
|
||||||
}
|
|
||||||
if(isDef(newVnode.elm.style)){
|
|
||||||
diffNode.nodeArray.push(newVnode.elm);
|
diffNode.nodeArray.push(newVnode.elm);
|
||||||
}else {
|
|
||||||
diffNode.nodeArray.push(newVnode.elm.parentNode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}else if(isDef(oldVnode.tag)&&isDef(newVnode.tag)){
|
}else if(isDef(oldVnode.tag)&&isDef(newVnode.tag)){
|
||||||
if(oldVnode.tag==='input'&&newVnode.tag==='input'){
|
if(oldVnode.tag==='input'&&newVnode.tag==='input'){
|
||||||
|
@ -309,6 +312,86 @@ function diffDetail(oldVnode,newVnode,diffNode){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function diffRealNode(oldNode,newNode,diffNode){
|
||||||
|
let oldNodeLength = oldNode.childNodes.length;
|
||||||
|
let newNodeLength = newNode.childNodes.length;
|
||||||
|
let childrenLength = Math.min(oldNodeLength, newNodeLength);
|
||||||
|
for (let i = 0; i < childrenLength; i++) {
|
||||||
|
let oldnode = oldNode.childNodes[i]
|
||||||
|
let newnode = newNode.childNodes[i]
|
||||||
|
if(oldnode.childNodes.length>0&&newnode.childNodes.length>0){
|
||||||
|
diffRealNode(oldnode,newnode,diffNode)
|
||||||
|
}else {
|
||||||
|
diffRealNodeDetail(oldnode,newnode,diffNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i = childrenLength; i < oldNodeLength; i++) {
|
||||||
|
if(oldNode.childNodes[i]){
|
||||||
|
if(isDef(oldNode.childNodes[i].data)){
|
||||||
|
if(oldNode.childNodes[i].data!=="\n"){
|
||||||
|
diffNode.oldNodeArray.push(oldNode.childNodes[i]);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
diffNode.oldNodeArray.push(oldNode.childNodes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i = childrenLength; i < newNodeLength; i++) {
|
||||||
|
if(newNode.childNodes[i]){
|
||||||
|
if(isDef(newNode.childNodes[i].data)){
|
||||||
|
if(newNode.childNodes[i].data!=="\n"){
|
||||||
|
diffNode.nodeArray.push(newNode.childNodes[i]);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
diffNode.nodeArray.push(newNode.childNodes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function diffRealNodeDetail(oldNode,newNode,diffNode){
|
||||||
|
if(!sameNode(oldNode,newNode)){
|
||||||
|
if(isDef(oldNode.data)){
|
||||||
|
if(oldNode.data!=="\n"){
|
||||||
|
diffNode.oldNodeArray.push(oldNode);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
diffNode.oldNodeArray.push(oldNode);
|
||||||
|
}
|
||||||
|
if(isDef(newNode.data)){
|
||||||
|
if(newNode.data!=="\n"){
|
||||||
|
diffNode.nodeArray.push(newNode);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
diffNode.nodeArray.push(newNode);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
//如果是相同的,但是这时候新旧节点有一个的length一定为0,所以要处理剩下的
|
||||||
|
if(oldNode.childNodes.length>0){
|
||||||
|
for (let i = 0; i < oldNode.childNodes.length; i++){
|
||||||
|
if(isDef(oldNode.childNodes[i].data)){
|
||||||
|
if(oldNode.childNodes[i].data!=="\n"){
|
||||||
|
diffNode.oldNodeArray.push(oldNode.childNodes[i]);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
diffNode.oldNodeArray.push(oldNode.childNodes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(newNode.childNodes.length>0){
|
||||||
|
for (let i = 0; i < newNode.childNodes.length; i++){
|
||||||
|
if(isDef(newNode.childNodes[i].data)){
|
||||||
|
if(newNode.childNodes[i].data!=="\n"){
|
||||||
|
diffNode.nodeArray.push(newNode.childNodes[i]);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
diffNode.nodeArray.push(newNode.childNodes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function sameVnode (a, b) {
|
function sameVnode (a, b) {
|
||||||
return (
|
return (
|
||||||
a.key === b.key &&
|
a.key === b.key &&
|
||||||
|
@ -326,6 +409,15 @@ function sameVnode (a, b) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sameNode (a, b) {
|
||||||
|
return (
|
||||||
|
(isDef(a.data) === isDef(b.data) &&a.data===b.data&&isDef(a.nodeValue) === isDef(b.nodeValue) &&a.nodeValue===b.nodeValue)||(
|
||||||
|
isUndef(a.data)&&isUndef(b.data)&&isUndef(a.nodeValue)&&isUndef(b.nodeValue)&&
|
||||||
|
isDef(a.textContent) === isDef(b.textContent)&&a.textContent===b.textContent
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
function findRowVnodeElm(nodeElm){
|
function findRowVnodeElm(nodeElm){
|
||||||
if(nodeElm.localName==="td"||nodeElm.className==="cell"){
|
if(nodeElm.localName==="td"||nodeElm.className==="cell"){
|
||||||
return findRowVnodeElm(nodeElm.parentNode)
|
return findRowVnodeElm(nodeElm.parentNode)
|
||||||
|
|
Loading…
Reference in New Issue