<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.msg" />
        </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.msg" />
        </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="10"
          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: ""
        },
      },
    }
  },

  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")

      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')
            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> 
.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>

 

原文地址:http://www.cnblogs.com/yan122/p/16813836.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性