diff --git a/frontend/src/business/components/api/definition/components/complete/EditCompleteHTTPApi.vue b/frontend/src/business/components/api/definition/components/complete/EditCompleteHTTPApi.vue index bf9648c614..30b3964cc9 100644 --- a/frontend/src/business/components/api/definition/components/complete/EditCompleteHTTPApi.vue +++ b/frontend/src/business/components/api/definition/components/complete/EditCompleteHTTPApi.vue @@ -134,6 +134,32 @@ + + + + 取 消 + 确 定 + + + @@ -151,6 +177,11 @@ import MsChangeHistory from "../../../../history/ChangeHistory"; import {getCurrentProjectID, getCurrentUser, getUUID, hasLicense} from "@/common/js/utils"; import MsFormDivider from "@/business/components/common/components/MsFormDivider"; 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 versionHistory = requireComponent.keys().length > 0 ? requireComponent("./version/VersionHistory.vue") : {}; @@ -161,7 +192,8 @@ export default { 'MsVersionHistory': versionHistory.default, ApiOtherInfo, MsFormDivider, - MsJsr233Processor, MsResponseText, MsApiRequestForm, MsInputTag, MsSelectTree, MsChangeHistory + MsJsr233Processor, MsResponseText, MsApiRequestForm, MsInputTag, MsSelectTree, MsChangeHistory, + HttpApiVersionDiff }, data() { let validateURL = (rule, value, callback) => { @@ -185,8 +217,11 @@ export default { status: [{required: true, message: this.$t('commons.please_select'), trigger: 'change'}], }, httpForm: {environmentId: "", path: "", tags: []}, + newData:{environmentId: "", path: "", tags: []}, + dialogVisible:false, isShowEnable: true, showFollow: false, + newShowFollow:false, maintainerOptions: [], currentModule: {}, reqOptions: REQ_METHOD, @@ -197,8 +232,11 @@ export default { label: 'name', }, mockBaseUrl: "", + newMockBaseUrl: "", count: 0, versionData: [], + oldRequest:{}, + oldResponse:{} }; }, props: {moduleOptions: {}, request: {}, response: {}, basisData: {}, syncTabs: Array, projectId: String}, @@ -314,6 +352,39 @@ export default { } 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: { @@ -428,6 +499,7 @@ export default { conditions.forEach(condition => { if (condition.type === httpType) { this.mockBaseUrl = condition.protocol + "://" + condition.socket; + this.newMockBaseUrl = this.mockBaseUrl; } }); } @@ -466,7 +538,95 @@ export default { }); }, 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 0) { + this.sort(stepArray[i].hashTree); + } + } + } }, checkout(row) { let api = this.versionData.filter(v => v.versionId === row.id)[0]; diff --git a/frontend/src/business/components/api/definition/components/complete/version/HttpApiVersionDiff.vue b/frontend/src/business/components/api/definition/components/complete/version/HttpApiVersionDiff.vue new file mode 100644 index 0000000000..61d3c98d1b --- /dev/null +++ b/frontend/src/business/components/api/definition/components/complete/version/HttpApiVersionDiff.vue @@ -0,0 +1,316 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Mock地址: + {{ this.oldMockUrl }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Mock地址: + {{ this.newMockUrl }} + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/src/business/components/performance/v_node_diff.js b/frontend/src/business/components/performance/v_node_diff.js index 8feeed4d49..0cfd72ca89 100644 --- a/frontend/src/business/components/performance/v_node_diff.js +++ b/frontend/src/business/components/performance/v_node_diff.js @@ -70,24 +70,32 @@ function changeStyle(diffNode){ console.log(diffNode.oldNodeArray); console.log(diffNode.nodeArray); 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 } if(diffNode.oldNodeArray[i].className==='cell'){ let rowVnodeElm = findRowVnodeElm(diffNode.oldNodeArray[i]); - rowVnodeElm.style.setProperty("background-color","rgb(241,200,196)",'important') + if(isDef(rowVnodeElm.style)){ + 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{ changeStyleBySubset(diffNode.oldNodeArray[i],"rgb(241,200,196)"); } } 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 } if(diffNode.nodeArray[i].className==='cell'){ let rowVnodeElm = findRowVnodeElm(diffNode.nodeArray[i]); - rowVnodeElm.style.setProperty("background-color","rgb(215, 243, 215)",'important') + if(isDef(rowVnodeElm.style)){ + 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{ 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.style)){ 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++) { changeStyleBySubset(vnodeElm.children[i],color); @@ -105,7 +115,7 @@ function changeStyleBySubset(vnodeElm,color){ }else { if(isDef(vnodeElm.style)){ vnodeElm.style.setProperty("background-color",color,'important') - }else { + }else if(isDef(vnodeElm.parentNode.style)&&vnodeElm!=='comment'){ vnodeElm.parentNode.style.setProperty("background-color",color,'important') } } @@ -164,12 +174,12 @@ function diffChildren(oldChildren,newChildren,diffNode,isCompareChildren){ let newVnode = newChildren[i] diffDetail(oldVnode,newVnode,diffNode) } - for (let i = childrenLength; i <= (oldLength - childrenLength); i++) { + for (let i = childrenLength; i < oldLength; i++) { if(oldChildren[i]){ diffNode.oldNodeArray.push(oldChildren[i].elm); } } - for (let i = childrenLength; i <= (newLength - childrenLength); i++) { + for (let i = childrenLength; i < newLength; i++) { if(newChildren[i]){ diffNode.nodeArray.push(newChildren[i].elm); } @@ -236,7 +246,6 @@ function sameDetail(oldVnode,newVnode,sameNode){ } - function diffDetail(oldVnode,newVnode,diffNode){ if(isDef(oldVnode.child)&&isUndef(newVnode.child)){ diffNode.oldNodeArray.push(oldVnode.child._vnode.elm); @@ -268,21 +277,15 @@ function diffDetail(oldVnode,newVnode,diffNode){ } diffChildren(oldVnode.children,newVnode.children,diffNode,isCompareChildren) } - //剩最后的子节点的时候,分类型做判断 + //剩最后的子节点的时候,分类型做判断(注意,最后的子节点的真实dom里可能还有dom节点) 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(oldVnode.text!==newVnode.text){ - if(isDef(oldVnode.elm.style)){ - diffNode.oldNodeArray.push(oldVnode.elm); - }else { - diffNode.oldNodeArray.push(oldVnode.elm.parentNode); - } - if(isDef(newVnode.elm.style)){ - diffNode.nodeArray.push(newVnode.elm); - }else { - diffNode.nodeArray.push(newVnode.elm.parentNode); - } + diffNode.oldNodeArray.push(oldVnode.elm); + diffNode.nodeArray.push(newVnode.elm); } }else if(isDef(oldVnode.tag)&&isDef(newVnode.tag)){ 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) { return ( 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){ if(nodeElm.localName==="td"||nodeElm.className==="cell"){ return findRowVnodeElm(nodeElm.parentNode)