<template>
  <div class="semantics-edit-page">
    <div class="semantics-tool page-block-wrap">
      <div class="tool-btn" @click="handleBtnClick({type:'search'})">
        <img :src="toolIcon['search']" />
        搜索
      </div>
      <div class="tool-btns">
        <el-popover
          placement="right"
          v-model="isSelectLabelShow"
          v-if="compareFiles.length"
          trigger="manual">
          <select-label-detail 
            :isSelectLabelShow="isSelectLabelShow"
            :lastSelectLabelArr="selectedLabelArr"
            :selectedFileArr="selectedFileArr"
            :newAddLabelArr="newAddLabelArr"
            @close="handleSelectLabel"
          />
          <div slot="reference" class="tool-btn" style="padding:0 30px !important;border-right: 1px solid #DCDFE6;"
            @click="handleBtnClick({type:'selectLabel'},isSelectLabelShow?'close':'open')">
            <img :src="toolIcon['eye']" style="width:14px,height:9px"/>
            选择标签
          </div>
        </el-popover>
        
        <div class="tool-btn" v-for="btn in toolBtnArr" :key="btn.type" @click="handleBtnClick(btn)">
          <img :src="toolIcon[btn.icon]" :style="btn.icon==='eye'?{'width':'14px','height':'9px'}:{}"/>
          {{btn.text}}
        </div>
      </div>
    </div>
    <div class="semantics-content" v-if="compareFiles.length">
      <div class="file-page-label-wrap">
        <draggable
          class="drag-cont"
          v-model="compareFiles"
          animation="300"
          @start="dragStartHandler"
          @update="dragEnter"
          @end="movePageLabel"
        >
          <div class="page-label" :class="{'active':currentPageIndex===index}" 
            v-for="(label,index) in compareFiles" :key="label.DocId"
            @click="changePageLabel(index)"
          >
            <span class="text-ellipsis">{{label.Title}}</span>
            <span class="close" @click.stop="deleteCompareFile(label,index)"><i class="el-icon-close"></i></span>
          </div>
        </draggable>
        
      </div>
      <div class="files">
        <div class="file-item overflow-hide-scrollbar" 
          @scroll="hideTextAreaTool('scroll',document)"
          :class="{'couple':showingFiles.length===2||showingFiles.length===1}"
          v-for="(document,index) in showingFiles" :key="document.DocId">
          <div class="file-item-info">
            <p class="file-title">{{document.Title}}</p>
            <p class="file-sub-info"><!-- <span style="margin-right:30px;">{{document.Theme}}</span> --><span>所属目录：{{document.ClassifyName}}</span></p>
            <!-- <span class="close-btn" @click.stop="deleteCompareFile(document,index)"><i class="el-icon-circle-close"></i></span> -->
          </div>
          <div class="file-item-content" :id="`file-content-${index}`" 
            v-click-outside="hideTextAreaTool"
            @mouseup.stop="e=>{handleMouseUp(e,index)}">
            <div class="file-item-block" :class="{'this-block':block.ishasThisLabel,'select-block':block.isSelectLabel}" 
              v-for="block in document.SectionList" :key="block.SectionId"
              >
              <!-- @mousemove="e=>checkTextArea(e,document)" -->
              <p class="block-innerText" :id="block.SectionId">{{block.innerText}}</p>
              <div class="file-item-icon">
                <el-popover
                  placement="right"                
                  trigger="hover">
                  <section-label-detail 
                    :detailArr="[
                      {title:'当前标签',isThis:1,arr:block.isThisLabelArr||[]},
                      {title:'历史标签（我的）',isThis:0,arr:block.isHistoryLabelArr||[]},
                      {title:'Ta的标签',isThis:0,arr:block.isOtherLabelArr||[]},
                    ]"
                    @deleteLab="(label)=>{deleteSelectLabel(document,block,label)}"
                    @addLab="(label)=>{quickAddSelectLabel(document,block,label)}"
                  />
                  <span slot="reference" @click.stop><img :src="require(`@/assets/img/document_m/menu.svg`)"></span>
                </el-popover>
                <span class="label" @click.stop="handleAddSelectionLabel(document,block)"><img :src="require(`@/assets/img/document_m/label.svg`)"></span>
              </div> 
              
            </div>
            <!--  高亮方案的兼容版本
                <highlight-canvas 
                ref="HighlightCanvas"
                :parentDomId="`file-content-${index}`" 
                :parentIndex="index"/> -->
          </div>
        </div>
      </div>
    </div>
    <div class="semantics-content" v-if="compareFiles.length===0">
      <tableNoData text="暂无信息" class="empty"/>
    </div>
    <!-- 选择对比文档弹窗 -->
    <select-file-dialog 
      :isSelectFileShow="isSelectFileShow"
      :selectedFileArr="selectedFileArr"
      @selectFile="AddCompareFiles"
      @close="handleBtnClick({type:'selectFile'},'close')"
    />
    <!-- 打标签弹窗 -->
    <add-section-label-dialog 
      :isAddSectionLabelShow="isAddSectionLabelShow"
      :sectionInfo="sectionInfo"
      @addSection="addSectionLabel"
      @close="handleBtnClick({type:'addSectionLabel'},'close')"
    />
    <!-- 搜索框弹窗 -->
    <search-box 
      ref="searchBox"
      :isSearchBoxShow="isSearchBoxShow"
      @close="handleBtnClick({type:'search'},'close')"
    />
    <!-- 保存/另存为+上传图片弹窗 -->
    <save-semantic-dialog 
      ref="saveDialog"
      :isSaveFileShow="isSaveFileShow"
      :semanticInfo="semanticInfo"
      :saveType="saveType"
      :resultData="resultData"
      :dialogLoading="dialogLoading"
      @saveSemantic="saveSemantic"
      @uploadImg="uploadImg"
      @close="checkSemanticId"
    />
    <!-- 选定文字操作栏 -->
    <select-text-area-tool 
        v-show="isShowTextArea"
        ref="SelectTextAreaTool"
        :isShowTextArea="isShowTextArea"
        :positionInfo="positionInfo"
        :textAreaInfo="textAreaInfo"
        :currentTextArea="currentTextArea"
        @addTextAreaLabel="addTextAreaLabel"
        @quickAddTextAreaLabel="quickAddTextAreaLabel"
        @deleteTextAreaLabel="deleteTextAreaLabel"
    />
  </div>
</template>

<script>
/* js */
import {toolIcon,toolBtnArr,dialogMap,textAreaToolWidth} from '../utils/config';
import {formatSemanticFile,formatCompareListItem,
    checkSelectionAndRange,getCurrentRange,
    getTextRange,updateLabelList,
    addNewTextRange,checkIsSelectLabelInFile,
    checkAllLabelsAreEmpty} from '../utils/index';

/*components */
import draggable from 'vuedraggable';
import selectFileDialog from './components/selectFileDialog.vue';
import AddSectionLabelDialog from './components/addSectionLabelDialog.vue';
import SectionLabelDetail from './components/sectionLabelDetail.vue';
import SelectLabelDetail from './components/selectLabelDetail.vue';
import SaveSemanticDialog from './components/saveSemanticDialog.vue';
import SearchBox from './components/searchBox.vue';
import HighlightCanvas from './components/highlightCanvas.vue';
import SelectTextAreaTool from './components/selectTextAreaTool.vue';

/* api */
import {semanticInterface} from '@/api/modules/semanticsApi.js';


export default {
  components: { 
      draggable,selectFileDialog, AddSectionLabelDialog, 
      SectionLabelDetail, SelectLabelDetail, SaveSemanticDialog, 
      SearchBox,HighlightCanvas, SelectTextAreaTool
    },
  directives: {
    'click-outside':{
      bind(el, binding) {
        const clickHandle = (e)=>{
          //点击file-item-content之外的地方，隐藏选定文字操作栏
          const legalClassNameArr = ['file-item-content','block-innerText','select-text-area-tool']
          const SelectTextAreaTool = document.querySelector('.select-text-area-tool')
          if(el.contains(e.target)||legalClassNameArr.includes(e.target.className)||SelectTextAreaTool.contains(e.target)){
            return false
          }
          if(binding.value && typeof binding.value === 'function'){
            binding.value(_,_,e)
          }
        }
        el.__click__outside = clickHandle
        document.addEventListener('click',clickHandle)
      },
      unbind(el,binding,vnode){
        document.removeEventListener('click',el.__click__outside)
      }
    },
  },
  data() {
    return {
      /* button 页面操作按钮相关*/
      toolIcon:toolIcon,//操作栏
      selectedLabelArr:[],//选择标签-已选择的标签

      /* document-files 文档相关*/
      selectedFileArr:[],//已选择的文档ids
      compareFiles:[],//对比的文档
      showingFiles:[],//展示在可视区的文档 是compareFiles中的其中三个

      /* block and block-label 段落及段落标签相关*/
      newAddLabelArr:[],//当前页(段落)新打的标签
      sectionInfo:{},//当前选择的段落

      /* page-label 标签页 */
      currentPageIndex:0,//当前选择的标签页,与showingFiles[0]对应
      dragStartIndex:0,//拖拽标签页的标识

      /* semantic 文档对比信息 */
      semanticId:0,//文档对比id，为0时是新增
      saveType:0,//0 另存为 1保存
      resultData:{},//文档对比保存的结果,用于生成预览图片
      semanticInfo:{},//语义分析信息

      /* textArea text-label 选定文字及选定文字标签 */
      blockInfo:{SectionId:'',DocId:''},//选定文字时,选区所属的段落信息,为document.SectionList的其中一项
      positionInfo:{top:0,left:0},//选定文字时,操作栏应展示的位置
      textAreaInfo:[],//选定文字时,该选定文字区域信息
      currentTextArea:{},//当前选择的textArea textAreaInfo中的某一项
      isShowTextArea:false,//控制选定文字操作栏展示

      /* dialog */
      isSearchBoxShow:false,//搜索框弹窗
      isSelectLabelShow:false,//全部标签弹窗
      isSelectFileShow:false,//选择对比文档弹窗
      isSaveFileShow:false,//保存弹窗
      isAddSectionLabelShow:false,//打标签弹窗
      dialogLoading:false,//保存弹窗用的
    };
  },
  computed:{
    toolBtnArr(){//操作栏
      //新增
      if(this.semanticId===0){
        return this.compareFiles.length?toolBtnArr.slice(0,-1):[toolBtnArr[0]]
      }else{
        //编辑
        return toolBtnArr
      }
    },
  },
  methods: {
    //获取语义分析详情
    getSemanticData(){
      const {fileId} = this.$route.query
      if(fileId&&Number(fileId.split('_')[1])){
        this.semanticId = Number(fileId.split('_')[1])
        semanticInterface.getSemanticDetail({
          CompareId:this.semanticId
        }).then(res=>{
          if(res.Ret!==200) return
          this.initSemantic(res.Data)
        })
      }else{
        this.semanticId = 0
        this.semanticInfo = {
          SaCompareId:this.semanticId,
          Title:'',
          ClassifyId:''
        }
      }
    },
    //初始化语义分析
    initSemantic(data){
      const {SaCompareId,Title,ClassifyId,KeywordsList} = data
      this.semanticInfo = {SaCompareId,Title,ClassifyId}
      const {DocList} = data
      //初始化 selectedFileArr
      this.selectedFileArr = DocList.map(doc=>{
        return doc.DocId
      })
      //初始化 compareFiles
      this.compareFiles = DocList?DocList.map(doc=>{
        doc = formatSemanticFile(doc,this.selectedLabelArr)
        return doc
      }):[]
      //初始化 showingFiles
      this.initShowingFiles()
      //初始化搜索词
      if(KeywordsList.length){
          this.$refs.searchBox.searchArr = KeywordsList
      }
    },
    //点击工具栏按钮
    handleBtnClick(btn,operate='open'){
      const {type} = btn
      this.saveType = type==='saveOther'?0:1
      this[dialogMap[type]] = operate==='open'?true:false
      if(operate==='close'){
        this.dialogLoading = false
      }
    },
    /* 移动标签相关 */
    dragStartHandler({oldIndex}){
      //console.log('start',oldIndex)
      this.currentPageIndex = oldIndex
      this.dragStartIndex = oldIndex
    },
    //拖动后 compareFiles的顺序也会改变
    dragEnter({newIndex}){},
    movePageLabel({newIndex}){
      //console.log('end',newIndex)
      if(this.dragStartIndex===newIndex) return
      //切换标签
      this.changePageLabel(newIndex)
    },
    /*--------- */
    //切换文档标签页
    changePageLabel(index){
      //切换当前标签索引
      this.currentPageIndex = index
      //标签视口宽度
      const dragContWidth = $('.drag-cont').width()
      //单个标签宽度（）
      const pageLabelWidth = $('.page-label').outerWidth() 
      //标签总宽度（包括不可见部分）
      const pageLabelTotalWidth = pageLabelWidth*this.compareFiles.length
      //当前偏移位置
      const dragMarginLeft = Number($('.drag-cont').css('marginLeft').slice(0,-2))
      //当前选择标签在drag-cont的位置（加上偏移修正）
      const currentPosition = pageLabelWidth*index+dragMarginLeft
      //如果当前选择标签的前后三个不在视口，则移动确保这7个标签在视口处
      const safeWidth = pageLabelWidth*3
      //currentPosition>dragContWidth-safeWidth marginLeft为负
      const minusMargin = (currentPosition>(dragContWidth-safeWidth))
      //currentPosition<pageLabelWidth*2 marginLeft为正
      const plusMargin = (currentPosition<safeWidth)
      //但|marginLeft|+dragContWidth<=pageLabelTotalWidth
      const isMove = (dragContWidth<pageLabelTotalWidth)&&(minusMargin||plusMargin)
      //打印只是为了调试
      /* console.table([{
        'pageIndex':index,
        'dragContWidth':dragContWidth,
        'pageLabelWidth':pageLabelWidth,
        'pageLabelTotalWidth':pageLabelTotalWidth,
        'dragMarginLeft':dragMarginLeft,
        'currentPosition':currentPosition,
        'minusMargin':minusMargin,
        'plusMargin':plusMargin,
      }]) */
      if(isMove){
        let isLimit = pageLabelWidth*3+dragContWidth+Math.abs(dragMarginLeft)>=pageLabelTotalWidth
        let marginLeft = minusMargin&&isLimit?pageLabelTotalWidth-dragContWidth:pageLabelWidth*3
        const indexLimit = this.compareFiles.length<=10||index<3
        marginLeft = (plusMargin&&isLimit)||indexLimit?0:pageLabelWidth*3
        marginLeft = minusMargin?marginLeft*-1:marginLeft
        //console.log('isLimit',isLimit)
        //console.log('move',marginLeft)
        $('.drag-cont').css('marginLeft',isLimit?marginLeft:(marginLeft+dragMarginLeft))
      }
      //更新视口文档
      this.initShowingFiles()
    },
    //初始化展示视口文档
    initShowingFiles(){
      //切换前先关掉搜索框
      this.handleBtnClick({type:'search'},'close')
      //showingFiles为currentPageIndex,currentPageIndex+1,currentPageIndex+2的三个文档
      const currentPageIndex = this.currentPageIndex
      if(this.compareFiles.length===0){
        this.showingFiles = []
        return 
      }
      //判断currentPageIndex+1,currentPageIndex+2是否越界
      if(currentPageIndex===this.compareFiles.length-1){
        this.showingFiles = [this.compareFiles[currentPageIndex]]
      }else if(currentPageIndex===this.compareFiles.length-2){
        this.showingFiles = [this.compareFiles[currentPageIndex],this.compareFiles[currentPageIndex+1]]
      }else{
        this.showingFiles = [this.compareFiles[currentPageIndex],this.compareFiles[currentPageIndex+1],this.compareFiles[currentPageIndex+2]]
      }
    
      this.$nextTick(()=>{
        //初始化showingFiles中选定文字标签
        const textAreaRange = []
        const ortherTextAreaRange = []
        this.showingFiles.forEach(file=>{
            if(file.textAreaList){
                file.textAreaList = file.textAreaList.map(text=>{
                    const {rangeInfo,range} = getTextRange(text)
                    text.areaRangeInfo = rangeInfo
                    if(text.ishasThisLabel){
                        textAreaRange.push(range)
                    }
                    if(text.isSelectLabel){
                        ortherTextAreaRange.push(range)
                    }
                    return text
                })
            }
        })
        this.$nextTick(()=>{
            if(!CSS.highlights){
                this.$message.warning('该浏览器不支持高亮效果，请切换至chrome浏览器105版本以上')
                return
            }
            CSS.highlights&&CSS.highlights.set('show-result',new Highlight(...textAreaRange))
            CSS.highlights&&CSS.highlights.set('show-result-other',new Highlight(...ortherTextAreaRange))
        })
        /* //重新渲染highlightCanvas
        const canvasList = this.$refs.HighlightCanvas
        canvasList.forEach(canvas=>{
            canvas.initCanvasStyle()
        }) */
        //重新渲染搜索文字
        this.$refs.searchBox.searchWord(_,'research')
      })
    },
    //点击段落打标签icon
    handleAddSelectionLabel(file,block){
      const {DocId} = file
      const {SectionId,isThisLabelArr} = block
      //获取段落信息
      this.sectionInfo = {
        DocId,SectionId,isThisLabelArr
      }
      this.isAddSectionLabelShow = true
    },
    //点击上方选择标签icon
    handleSelectLabel({type,selectedLabelArr}){
      if(type!=='close'){
        this.selectedLabelArr = selectedLabelArr
        this.compareFiles = this.compareFiles.map(doc=>{
            //检测文档标签是否有被筛选的，有则将段落/片段的isSelectLabel设置为true
          doc = checkIsSelectLabelInFile(doc,this.selectedLabelArr)
          return doc
        })
        //更新视口文档
        this.initShowingFiles()
      }
      this.isSelectLabelShow = false
    },
    //段落打标签,可以一次打多个
    addSectionLabel(labelArr){
      //console.log('addArr',labelArr)
      //转换拿到的标签格式
      const labelList = labelArr.map(item=>{
        let temp = {
          LabelId :item.SaLabelId||item.LabelId,
          LabelName:item.LabelName,
          IsHistory:0,IsOther:0,
          IsThis:1,
        }
        return temp
      })
      this.updateSectionLabel(labelList,this.sectionInfo)
      this.checkLabel(labelList)
      this.isAddSectionLabelShow = false
    },
    //删除当前段落标签
    deleteSelectLabel(document,block,label){
      //获取当前段落的LabelList isThisLabelArr
      const {LabelList,isThisLabelArr} = block
      //labelList为isThisLabelArr删掉label这一项的数组
      const labelList = isThisLabelArr.filter(l=>l.LabelId!==label.LabelId)
      //LabelList对应的项要将IsThis改为0,存在IsThis IsHistory IsOther三者都为0的label不影响展示和数据,可以不管
      const newLabelList = LabelList.map(l=>{
          if(l.LabelId===label.LabelId&&l.IsThis===1){
              l.IsThis=0
          }
          return l
      })
      //updateSectionLabel type = 'delete'
      this.updateSectionLabel(labelList,{
        DocId:document.DocId,
        SectionId:block.SectionId
      },'delete',newLabelList)

    },
    //段落快速打标签,一次打一个
    quickAddSelectLabel(document,block,label){
      //获取当前段落的isThisLabelArr
      const {isThisLabelArr} = block
      //判断label在isThisLabelArr有没有,没有就 addSectionLabel
      if(isThisLabelArr.find(l=>l.LabelId===label.LabelId)){
        return
      }
      this.sectionInfo = {
        DocId:document.DocId,
        SectionId:block.SectionId,
        isThisLabelArr
      }
      this.addSectionLabel([...isThisLabelArr,label])
    },
    //更新段落标签
    updateSectionLabel(labelList,{DocId,SectionId},type='add',LabelList=[]){
      //找到更新的是哪篇文章
      let fileIndex = 0
      const file = this.compareFiles.find((file,index)=>{
        fileIndex=index
        return file.DocId===DocId
      })
      //找到更新的是哪个段落
      let sectionIndex=0
      const section = file.SectionList.find((section,index)=>{
        sectionIndex=index
        return section.SectionId===SectionId
      })
      if(!section) return 
      //更新段落的标签信息,实际上更换的只有isThisLabelArr 和LabelList中对应的部分
      //其他两个数组不会做更改
      section.isThisLabelArr = labelList||[]
      section.ishasThisLabel = labelList.length?true:false
      if(type==='add'){
        //需要去重和更新LabelList的对应项
        const {LabelList,isThisLabelArr} = section
        section.LabelList = updateLabelList(LabelList,isThisLabelArr)
      }else{
        section.LabelList = LabelList
      }
      //更新段落和文章
      file.SectionList.splice(sectionIndex,1,section)
      this.compareFiles.splice(fileIndex,1,file)
    },
    //检查是否有新加的标签,如果有 更新newAddLabelArr
    checkLabel(arr){
      arr.forEach(label=>{
        if(this.newAddLabelArr.findIndex(l=>l.LabelId===label.LabelId)===-1){
          this.newAddLabelArr.push(label)
        }
      })
    },
    //添加对比文档
    AddCompareFiles(fileKeys){
      //获取新选的文档标签 HeadLabel 按理说 应该与selectedLabelArr合并去重
      //但是打开selectedLabel的时候会重新请求一次选择对比文档详情 所以这里可以什么都不用做
      semanticInterface.getCompareDocumentDetail({
        DocIds:fileKeys.join(',')
      }).then(res=>{
        if(res.Ret!==200) return 
        const {DocList} = res.Data
        const newCompareFiles = DocList.map(doc=>{
          return formatSemanticFile(doc,this.selectedLabelArr)
        })
        this.compareFiles = [...this.compareFiles,...newCompareFiles]
        this.selectedFileArr = [...this.selectedFileArr,...fileKeys]
        this.initShowingFiles()
        //最后关闭这个弹窗
        this.handleBtnClick({type:'selectFile'},'close')
      })
    },
    //删除对比文档
    deleteCompareFile({DocId},index){
      //更新currentPageIndex
      const length = this.compareFiles.length
      if(length===1){
        this.$message.warning('请至少保留一个文档')
        return
      }
      if(this.currentPageIndex===length-1){
        this.currentPageIndex--
      }
      //compareFiles删除一项
      const fileIndex = this.compareFiles.findIndex(f=>f.DocId===DocId)
      this.compareFiles.splice(fileIndex,1)
      this.initShowingFiles()
      //selectedFileArr删除fileid
      const selectedIndex = this.selectedFileArr.findIndex(f=>f===DocId)
      this.selectedFileArr.splice(selectedIndex,1)
      //隐藏选定文字操作栏
      this.hideTextAreaTool()
    },
    //保存/另存为语义分析
    saveSemantic(semanticInfo){
      const{SaCompareId,Title,ClassifyId} = semanticInfo
      //参数格式转换
      const CompareList = this.compareFiles.map(file=>{
        return formatCompareListItem(file)
      })
      /* console.log('result',CompareList) 
      return */
      this.dialogLoading = true
      semanticInterface.saveSemantic({
        SaCompareId:this.saveType===0?0:Number(SaCompareId),
        Title,ClassifyId:Number(ClassifyId),
        CompareList
      }).then(async (res)=>{
        this.dialogLoading = false
        if(res.Ret!==200) return
        const hintWord = this.saveType===0?'另存为':SaCompareId?'保存':'新增'
        this.$message.success(`${hintWord}成功`)
        this.semanticId = res.Data.SaCompareId
        this.semanticInfo.SaCompareId = res.Data.SaCompareId
        this.semanticInfo.Title = Title
        this.semanticInfo.ClassifyId = ClassifyId
        this.resultData = res.Data
        //检查是否有搜索词,有则保存搜索词
        const searchArr = this.$refs.searchBox.searchArr
        await semanticInterface.saveKeyWords({
            SaCompareId:this.semanticId,
            Keywords:searchArr
        })
        this.$refs.saveDialog.goNext()
      })
    },
    //保存/另存为弹窗关闭时触发
    //检查当前页面的语义分析id是否一致，不一致则replace对应的详情页
    checkSemanticId(type){
        //console.log('type',type)
        //console.log('show',this.isSaveFileShow)
        const {SaCompareId,ClassifyId} = this.semanticInfo
        const fileId = this.$route.query.fileId
        //type为toList时，需要跳转回列表页
        //关闭弹窗时，会触发两次close事件，第一次是按钮触发，第二次是父级组件改变了isSaveFileShow触发
        //第一次的type为toList，第二次的type为undefined，因为需要跳转，所以将这段逻辑提前并return
        if(type==='toList'){
            sessionStorage.setItem('fileClassify',ClassifyId+'')
            sessionStorage.setItem('fileId',SaCompareId+'')
            this.$router.replace('/semanticsPage')
            return
        }
        //edit的情况
        if(SaCompareId&&fileId&&Number(this.$route.query.fileId.split('_')[1])!==SaCompareId){
            this.$router.replace({path:'/editSemantics',query:{fileId:'children_'+SaCompareId}})
        }
        //add的情况
        if(this.$route.path==='/addSemantics'&&SaCompareId){
            this.$router.replace({path:'/editSemantics',query:{fileId:'children_'+SaCompareId}})
        }
        this.handleBtnClick({type:'saveFile'},'close')
    },
    //上传结果图片
    async uploadImg(imgData){
      //将base64上传获得线上地址
      const form  = new FormData();
      form.append('Image', imgData);
      const res = await semanticInterface.uploadImg(form)
      if(res.Ret!==200) return 
      //上传结果图片
      semanticInterface.updateSemanticImg({
        SaCompareId:this.semanticId,
        ResultImg:res.Data.ResourceUrl
      }).then(res=>{
        if(res.Ret!==200) return 
        this.$message.success('上传结果图片成功')
        this.checkSemanticId('toList')
      })
    },
    //在file-item-content区域鼠标抬起触发 
    handleMouseUp(e,index){
        if(e.type!=="mouseup") return
        //关闭选定文字操作栏
        this.hideTextAreaTool()
        const selection = document.getSelection()
        const file = this.showingFiles[index]
        //获取该段落的选定文字标签
        if(!checkSelectionAndRange(selection)){
            //不是选区,单纯的鼠标点击后抬起
            if(e.target.nodeName==='P'&&e.target.className.includes('block-innerText')){
                const blockId = Number(e.target.id)||0
                blockId&&this.checkPosTextLabel(e,file,blockId)
            }
            return
        }
        //是选区
        this.getSelectionRange(selection,file)
    },
    //检测位置是否有选定文字标签,若有则展示操作栏
    checkPosTextLabel({clientX,clientY},file,SectionId){
        //获取该段落的选定文字标签
        const textAreaList = file.textAreaList.filter(t=>t.SectionId===SectionId)
        const block = file.SectionList.find(s=>s.SectionId===SectionId&&s.IsPart===0) 
        const textAreaInfo = []
        //判断文字标签是否在点击位置内
        textAreaList.forEach(text=>{
            if(text.areaRangeInfo){
                const {BoundingXRange,BoundingYRange} = text.areaRangeInfo
                const isBoundingX = clientX>=BoundingXRange[0]&&clientX<=BoundingXRange[1]
                const isBoundingY = clientY>=BoundingYRange[0]&&clientY<=BoundingYRange[1]
                isBoundingX&&isBoundingY&&(textAreaInfo.push(text))
            }
        })
        /* console.log('arr',textAreaInfo) */
        if(textAreaInfo.length){
            //根据最大范围确定操作栏应展示的位置
            const maxWidth = Math.max.apply(null,textAreaInfo.map(i=>i.areaRangeInfo.rangeWidth))
            const maxTextRange = textAreaInfo.find(item=>item.areaRangeInfo.rangeWidth===maxWidth)
            this.positionInfo = {
                left:maxTextRange.areaRangeInfo.BoundingXRange[0]+maxWidth/2 - textAreaToolWidth/2,
                top:maxTextRange.areaRangeInfo.BoundingYRange[1]
            }
            this.blockInfo = {DocId:file.DocId,...block}
            this.currentTextArea = maxTextRange
            this.textAreaInfo = textAreaInfo
            this.isShowTextArea = true
        }else{
            this.hideTextAreaTool()
        }
    },
    //获取选区并展示操作栏
    getSelectionRange(selection,file){
        const range = selection.getRangeAt(0)
        //因为鼠标点击选区时选区会消失,重新渲染一次
        selection.removeAllRanges()
        selection.addRange(range)

        const {currentRange,currentNode} = getCurrentRange(selection,range)
        //根据id找到选定文字所属段落
        const SectionId = Number(currentNode.parentNode.id)
        const block = file.SectionList.find(s=>s.SectionId===SectionId)
        this.blockInfo = {...block,DocId:file.DocId}
        //根据currentRange确定选定文字操作栏应该出现的位置
        const bounding = currentRange.getClientRects()
        this.positionInfo = {
            left:bounding[bounding.length-1].left+bounding[bounding.length-1].width/2 - textAreaToolWidth/2,
            top:bounding[bounding.length-1].top+bounding[bounding.length-1].height
        }
        //根据currentRange确定是选区是否已有标签 并展示操作栏
        this.checkOffsetPosTextLabel(currentRange,file,SectionId,currentRange.toString())
        //无论是否有标签,都需要展示操作栏
        this.isShowTextArea = true
    },
    //检测段落指定位置是否有选定文字标签
    checkOffsetPosTextLabel({startOffset,endOffset},file,SectionId,rangeString){
        //获取该段落的选定文字标签
        const textAreaList = file.textAreaList.filter(t=>t.SectionId===SectionId)
        const textAreaInfo = []
        textAreaList.forEach(text=>{
            if(text.areaRangeInfo){
                const {StartOffset,EndOffset} = text.areaRangeInfo
                const isIncludeStart = startOffset<=StartOffset
                const isIncludeEnd = endOffset<=EndOffset
                isIncludeStart&&isIncludeEnd&&(textAreaInfo.push(text))
            }
        })
        this.textAreaInfo = textAreaInfo
        if(this.textAreaInfo.length){
            //根据最大范围确定currentTextArea
            const maxOffset = Math.max.apply(null,textAreaInfo.map(i=>i.areaRangeInfo.rangeOffset))
            const maxTextRange = textAreaInfo.find(item=>item.areaRangeInfo.rangeOffset===maxOffset)
            this.currentTextArea = maxTextRange
        }else{
            //如果当前指定位置内,没有选定文字标签,则新生成一个作为currentTextArea
            this.currentTextArea = addNewTextRange(Number(SectionId),startOffset,endOffset,rangeString)
            /* const fileIndex = this.compareFiles.findIndex(f=>f.DocId===file.DocId)
            file.textAreaList.push(_.cloneDeep(this.currentTextArea))
            this.compareFiles.splice(fileIndex,1,file) */
        }
    },
    //隐藏选定文字操作栏,并清除选区
    hideTextAreaTool(type,doc,e){
        //页面滚动触发,需要判断滚动的文章是否是当前选定文字操作框对应的文章
        //如果不是,啥都不做;如果是,隐藏操作框
        if(type==='scroll'){
            if(!this.isShowTextArea) return 
            if(doc.DocId===this.blockInfo.DocId){
                document.getSelection().removeAllRanges()
                this.isShowTextArea = false
            }
        }else{
        //点击页面外的区域触发,隐藏操作栏
            //document.getSelection().removeAllRanges()
            this.isShowTextArea = false
        }
    },
    //选定文字打标签,一次可以打多个/零个 零个的时候单独处理
    addTextAreaLabel(labelArr){
        //更改currentTextArea 
        this.currentTextArea.isThisLabelArr = labelArr
        this.currentTextArea.ishasThisLabel = labelArr.length?true:false
        const {LabelList,isThisLabelArr} = this.currentTextArea
        this.currentTextArea.LabelList = updateLabelList(LabelList,isThisLabelArr)
        //更改file.textAreaList[] 
        const {startOffset,endOffset} = this.currentTextArea
        const textAreaListItem = _.cloneDeep(this.currentTextArea)
        const {DocId,SectionId} = this.blockInfo
        let fileIndex = 0
        const file = this.compareFiles.find((file,index)=>{
            fileIndex=index
            return file.DocId===DocId
        }) 
        const textAreaListIndex = file.textAreaList.findIndex(i=>{
            return i.startOffset===startOffset&&i.endOffset===endOffset&&i.SectionId===SectionId
        })
        textAreaListIndex!==-1&&labelArr.length!==0&&file.textAreaList.splice(textAreaListIndex,1,textAreaListItem)
        textAreaListIndex===-1&&labelArr.length!==0&&file.textAreaList.push(textAreaListItem)
        //labelArr为空时,检查是否应该删除这一项
        if(textAreaListIndex!==-1&&labelArr.length===0){
            checkAllLabelsAreEmpty(textAreaListItem)&&
                file.textAreaList.splice(textAreaListIndex,1)
        }
        
        //更改textAreaInfo
        const textAreaInfoIndex = this.textAreaInfo.findIndex(i=>{
            return i.startOffset===startOffset&&i.endOffset===endOffset&&i.SectionId===SectionId
        })
        textAreaInfoIndex!==-1&&labelArr.length!==0&&this.textAreaInfo.splice(textAreaInfoIndex,1,textAreaListItem)
        textAreaInfoIndex===-1&&labelArr.length!==0&&this.textAreaInfo.push(textAreaListItem)
        //labelArr为空时,检查是否应该删除这一项
        if(textAreaInfoIndex!==-1&&labelArr.length===0){
            checkAllLabelsAreEmpty(textAreaListItem)&&
                this.textAreaInfo.splice(textAreaInfoIndex,1)
        }
        
        //initShowingFiles
        this.compareFiles.splice(fileIndex,1,file)
        this.initShowingFiles()
        this.checkLabel(labelArr)
    },
    //选定文字快速打标签,一次只能打一个
    quickAddTextAreaLabel(label){
        //获取当前选定文字的isThisLabelArr 步骤与段落快速打标签基本相同
        const {isThisLabelArr} = this.currentTextArea
        if(isThisLabelArr.find(l=>l.LabelId===label.LabelId)){
            return 
        }
        this.addTextAreaLabel([...isThisLabelArr,label])
    },
    //删除选定文字标签
    deleteTextAreaLabel(label){
        //检查label.areaRangeInfo,rangeSectionId与currentTextArea是否匹配
        const {rangeSectionId,areaRangeInfo} = label
        const {startOffset,endOffset} = this.currentTextArea
        if(!(startOffset===areaRangeInfo.startOffset&&
            endOffset===areaRangeInfo.endOffset&&
            rangeSectionId===this.currentTextArea.SectionId)
        ){
            const textAreaInfoIndex = this.textAreaInfo.findIndex(i=>{
                return i.startOffset===areaRangeInfo.StartOffset&&i.endOffset===areaRangeInfo.EndOffset&&i.SectionId===rangeSectionId
            })
            textAreaInfoIndex!==-1&&(this.currentTextArea = this.textAreaInfo[textAreaInfoIndex])
        }
        const {isThisLabelArr} = this.currentTextArea
        const labelList = isThisLabelArr.filter(l=>l.LabelId!==label.LabelId)
        this.addTextAreaLabel(labelList)
    },
    //鼠标是否经过有选区的位置
/*     checkTextArea(e,doc){
        console.log('move',e)
    } */
  },
  mounted(){
    this.getSemanticData()
  },
  destroyed(){
    CSS.highlights&&CSS.highlights.clear();
  }
};
</script>

<style lang="scss">
.semantics-edit-page{
  .el-popover__reference{
    width: 100%;
    display: block;
    height: 100%;
    padding: 0 !important;
  }
}

</style>
<style scoped lang="scss">
@import "../css/basePage.scss";
@import "../css/semanticsEditPage.scss";
</style>
