<template>
<div class="version-diff-content">
<div class="version-diff-top">
<div>
<el-select v-model="versionDiffSelected.selectOne.version" placeholder="" size="mini">
<el-option
v-for="item in tagList"
:key="item.commitId"
:value="item.commitId"
:label="item.version" />
</el-select>
</div>
<div>
<el-button type="primary" size="mini" @click="handleContrast">对比</el-button>
</div>
<div>
<el-select
:disabled="!!replaceData"
v-model="versionDiffSelected.selectTwo.version"
placeholder=""
size="mini">
<el-option
v-for="item in tagList"
:key="item.commitId"
:value="item.commitId"
:label="item.version" />
</el-select>
</div>
</div>
<div v-loading="diffLoading" :element-loading-text="diffLoadingText">
<el-scrollbar class="version-diff-bottom">
<div
v-if=" versionDiffSelected.selectOne.json != versionDiffSelected.selectTwo.json "
class="version-diff-bottom-item"
>
<code-diff
class="center"
:renderNothingWhenEmpty="true"
:old-string="versionDiffSelected.selectOne.json"
:new-string="versionDiffSelected.selectTwo.json"
:context="1000000"
outputFormat="side-by-side" />
<div id="diffView" style="margin-top:10px"></div>
</div>
<div
class="version-diff-bottom-item flex-center"
v-if="
versionDiffSelected.selectOne.json !== undefined &&
versionDiffSelected.selectTwo.json !== undefined &&
versionDiffSelected.selectOne.json == versionDiffSelected.selectTwo.json ">
规则无变化
</div>
</el-scrollbar>
</div>
</div>
</template>
<script>
import { readAssetTree } from '@/api/rule/asset'
import { getVersionDifference } from "@/api/rule/project"
import { getRuleFileString } from "@/utils/getRuleString"
import CodeDiff from 'vue-code-diff'
export default {
components: { CodeDiff },
props: {
// 版本列表
tagList: {
type: Array,
default: (() => {return []})
},
// 对比的数据
objectForm: {
type: Object,
},
// 当前规则数据,有则传递数据,后面不用重新请求
momentRule: {
type: Object,
default: (() => {return {}})
},
// 被替换的数据(需要做当前内容的替换时传递)
replaceData: {
type: Object,
default: null
}
},
data() {
return {
versionDiffDialog: false,
diffLoading: false,
diffLoadingText: "规则对比中,请稍后......",
versionDiffData: "",
versionDiffSelected: {
selectOne: {
version: "",
json: undefined,
rule: ""
},
selectTwo: {
version: "",
json: undefined,
rule: ""
},
},
btnList: []
}
},
watch: {
versionDiffDialogProp: {
handler(n) {
this.versionDiffDialog = n
}
}
},
methods: {
// 执行版本对比
handleContrast() {
console.log("对比的版本", this.versionDiffSelected)
if( this.versionDiffSelected.selectOne.version == this.versionDiffSelected.selectTwo.version ){
this.$message.warning("相同的版本")
return
}
this.diffLoading = true
let { type, parentPath, aliasName, projectName, spaceName } = this.objectForm
const diffPromiseList = []; // 这里存放异步操作的 Promise
const output = (version, key) => new Promise((resolve) => {
if( version ){
// 获取历史版本
let data = { commitId: version, projectName, spaceName, type, parentPath, aliasName }
getVersionDifference(data).then((response) => {
console.log("历史版本数据", response)
resolve({responseData: response, key: key})
})
}else{
// 获取当前规则内容
if( this.replaceData ){
resolve(
{
responseData: {
code: 200,
data: this.momentRule
},
key: key
}
)
}else{
readAssetTree({ projectName, spaceName, type, parentPath, aliasName }).then(response => {
console.log("规则数据", response)
resolve({responseData: response, key: key})
})
}
}
});
// 生成全部的异步操作
for( let key in this.versionDiffSelected ) {
if( key == "selectOne" || key == "selectTwo" ){
let version = this.versionDiffSelected[key].version
diffPromiseList.push(output(version, key));
}
}
// 异步操作完成之后,输出resolve的数据
Promise.all(diffPromiseList).then((allResponse) => {
console.log("版本对比获取对比数据", allResponse)
allResponse.forEach((response) => {
let ruleData
if (response.responseData.code == 200) {
ruleData = response.responseData.data.content? JSON.parse(response.responseData.data.content): []
this.versionDiffSelected[response.key].rule = ruleData
// 获取规则自然语言
this.versionDiffSelected[response.key].json = getRuleFileString(ruleData)
}
})
this.diffLoading = false
// 获取对比元素,添加覆盖按钮
if( this.replaceData ){
setTimeout(() => {
this.getDiffDome()
}, 100)
}
});
},
getDiffDome() {
let diffBox = document.getElementsByClassName("d2h-diff-tbody")
// 去除之前添加的覆盖按钮
this.btnList.forEach((domItem) => {
domItem.remove();
})
this.btnList = []
let ruleOptionsObj = {
left: {
actionType: "",
map: [
{
type: "if",
label: "如果"
},
{
type: "do",
label: "那么"
},
{
type: "else",
label: "否则"
}
],
if: {
label: "如果",
children: []
},
do: {
label: "那么",
children: []
},
else: {
label: "否则",
children: []
},
childrenMap: {}
},
right: {
actionType: "",
map: [
{
type: "if",
label: "如果"
},
{
type: "do",
label: "那么"
},
{
type: "else",
label: "否则"
}
],
if: {
label: "如果",
children: []
},
do: {
label: "那么",
children: []
},
else: {
label: "否则",
children: []
},
childrenMap: {}
}
}
diffBox.forEach((parentDome, parentIndex) => {
let ruleOptions
parentDome.children.forEach((childrenItem, row) => {
if( parentIndex == 0 ){
ruleOptions = ruleOptionsObj.left
}else{
ruleOptions = ruleOptionsObj.right
}
// 获取规则对应数据
ruleOptions.map.forEach((ruleOptionItem) => {
if( childrenItem.outerText.replace(/\s*/g,"") == ruleOptionItem.label ){
ruleOptions.actionType = ruleOptionItem.type
}
})
// 筛选去除类型的标题
if( ruleOptions.map.filter(v => v.label == childrenItem.outerText).length == 0 ){
let childrenData = {
index: row,
hasData: !!childrenItem.outerText.replace(/\s*/g,""),
childrenItem
}
if(
ruleOptions.actionType &&
childrenItem &&
childrenItem.outerText.replace(/\s*/g,"") != ruleOptions[ruleOptions.actionType].label){
ruleOptions[ruleOptions.actionType].children.push(childrenData)
ruleOptions.childrenMap[row] = {
type: ruleOptions.actionType,
index: ruleOptions[ruleOptions.actionType].children.length - 1,
hasData: !!childrenItem.outerText.replace(/\s*/g,"")
}
}
}
if( parentIndex == 0 && (childrenItem.outerText[0] == "+" || childrenItem.outerText[0] == "-") ){
let btn = document.createElement('div')
this.btnList.push(btn)
btn.innerHTML = "=>"
btn.style.cursor="pointer"
childrenItem.appendChild(btn)
btn.addEventListener('click', () => {
this.overDiff( childrenItem, row, parentDome, parentIndex, ruleOptionsObj )
})
}
})
})
console.log(5346643, ruleOptionsObj)
},
// 规则不同覆盖
overDiff( childrenItem, row, parentDome, parentIndex, ruleOptionsObj ){
console.log("覆盖", childrenItem, row, parentDome, parentIndex, ruleOptionsObj)
// 获取选择的覆盖规则
let selectRuleChildren = ruleOptionsObj.left.childrenMap[row]
let selectRuleType = selectRuleChildren.type
let selectRuleTypeIndex = selectRuleChildren.index
let selectTypeInfo = ruleOptionsObj.left[selectRuleType]
// 获取选择的覆盖规则的index
let selectRuleIndex = -1
selectTypeInfo.children.forEach((v, i) => {
if( i <= selectRuleTypeIndex && v.hasData ){
selectRuleIndex ++
}
})
let selectRule = this.versionDiffSelected.selectOne.rule[selectRuleChildren.type][selectRuleIndex]
console.log("覆盖选择规则", selectRule)
// 获取被覆盖的规则
// let selectRuleType = selectRuleChildren.type
// let selectRuleTypeIndex = selectRuleChildren.index
let overTypeInfo = ruleOptionsObj.right[selectRuleType]
// 获取被覆盖规则的当条规则的index
let overRuleIndex = -1
overTypeInfo.children.forEach((v, i) => {
if( i <= selectRuleTypeIndex && v.hasData ){
overRuleIndex ++
}
})
let overRuleDataType = this.versionDiffSelected.selectTwo.rule[selectRuleChildren.type]
// 根据被覆盖的规则是否有内容,判断有内容做覆盖操作,无内容做插入操作
if( ruleOptionsObj.right.childrenMap[row].hasData ){
overRuleDataType.splice( overRuleIndex, 1, selectRule )
}else{
overRuleDataType.splice( overRuleIndex + 1, 0, selectRule )
}
setTimeout(() => {
this.replaceData[selectRuleChildren.type] = overRuleDataType
this.$emit("reSetData", this.replaceData)
this.versionDiffSelected.selectTwo.json = getRuleFileString(this.replaceData)
// 获取对比元素
setTimeout(() => {
this.getDiffDome()
}, 500)
}, 100)
console.log("获取被覆盖规则的当条规则的index", overRuleIndex, overRuleDataType, this.replaceData)
},
}
}
</script>
<style lang="scss" scoped>
.flex-center{
display: flex;
align-items: center;
justify-content: center;
}
.version-diff-content{
.version-diff-top{
width: 100%;
display: flex;
justify-content: space-between;
}
}
::v-deep .version-diff-bottom{
.el-scrollbar__view{
height: 460px;
display: flex;
}
.version-diff-bottom-item{
width: 100%;
margin-top: 10px;
}
// 解决vue-code-diff对不齐和显示下拉标志问题
.center {
max-height: 600px;
overflow-y: auto;
overflow-x: hidden;
/* 样式穿透-起始行左右对齐,*/
.d2h-code-side-line{
height:15px;
}
code.hljs{
padding: 0;
}
// 删除行统计显示
.d2h-code-side-linenumber{
display: none;
}
.d2h-code-side-line{
padding: unset;
}
.d2h-code-line-ctn{
width: unset;
}
// 删除第一行的统计结果
.d2h-info {
display: none;
}
}
}
</style>