<template>
  <div class="containers" ref="content" v-loading="vLoading" style="margin: 0;">
    <div class="hjjd-box">
      <div class="jd-list">
        <span class="jd-wzx"></span>
        <span class="text">未执行</span>
      </div>
      <div class="jd-list">
        <span class="jd-yzx"></span>
        <span class="text">已执行</span>
      </div>
      <div class="jd-list">
        <span class="jd-dqjd"></span>
        <span class="text">当前节点</span>
      </div>
      <div class="jd-list">
        <span class="jd-yzf"></span>
        <span class="text">已作废</span>
      </div>
    </div>
    <!--hjjd-box 流程节点-->
    <div class="canvas" ref="canvas"></div>
    <div class="console"></div>
    <!-- <div style="width:200px;height:400px;border: 1px solid;" onmouseout="alert(111)">
      <div>
      <p>1111</p>
      <p>22</p>
      </div>
    </div>-->
  </div>
</template>

<script>
// 引入相关的依赖
import BpmnModeler from '../../public/js/bpmn-js/lib/NavigatedViewer'
import BpmnImporter from '../../public/js/bpmn-js/lib/import/BpmnImporter.js'
//'bpmn-js/lib/NavigatedViewer'
import XEUtils from 'xe-utils'
//import $ from 'jquery';
export default {
  data() {
    return {
      // bpmn建模器
      bpmnModeler: null,
      canvas: null,
      bpmnXmlStr: '',
      procDefId: '',
      //accessUrl:'http://192.168.1.33:8080',
      vLoading: false,
      processTrace: [],
      processDetailLogs: [],
      arrayActId: [],
      bpmnImporter: null, //用于输出线来查看处理的名称
    }
  },
  created() {
    window.hidenDiv = this.hidenDiv
    window.showDiv = this.showDiv
  },
  methods: {
    createNewDiagram() {
      let _this = this
      let nodeCodes = _this.processTrace
      _this.bpmnModeler.importXML(_this.bpmnXmlStr, function (err) {
        if (err) {
          console.error(err)
        } else {
          const canvas = _this.bpmnModeler.get('canvas')
          canvas.zoom('fit-viewport')
          _this.setNodeColor(nodeCodes, canvas)
          _this.appendHtml()
          _this.addActNum()
          _this.dealLine(canvas)
        }
      })
    },
    //处理线的名称样式
    dealLine(canvas) {
      let _this = this
      _this.bpmnImporter = new BpmnImporter()
      let hash = {} //数组去重
      let lineList = _this.bpmnImporter._getLineId.reduce(function (
        item,
        next,
      ) {
        hash[next] ? '' : (hash[next] = true && item.push(next))
        return item
      },
      [])
      var colorClass = 'highlight-label'
      lineList.forEach(function (item) {
        canvas.addMarker(item + '_label', colorClass)
      })
    },
    //添加环节处理次数
    addActNum() {
      let _this = this
      let overlays = _this.bpmnModeler.get('overlays')
      _this.processTrace.forEach(function (item) {
        if (item.type == 'multi' || item.type == 'call') {
          let list = _this.processDetailLogs.filter(function (it) {
            //获取处理记录信息
            return it.historicTaskInstance.taskDefinitionKey == item.activityId
          })
          overlays.add(item.activityId, 'note', {
            position: {
              bottom: 10,
              right: 10,
            },
            html: "<span class='num-color'>" + list.length + '</span>',
          })
        }
      })
    },
    //拼接环节详细信息
    appendHistoryHtml(overlays, event, e) {
      let _this = this
      let thisNode = document.getElementById('div_' + e.element.id)
      let listAct = _this.arrayActId.filter(function (item) {
        //判断这个节点是否
        return item == e.element.id
      })
      if (listAct.length == 0) {
        _this.arrayActId.push('div_' + e.element.id)
      }
      if (thisNode != null && listAct.length == 0) {
        document.getElementById('div_' + e.element.id).style = 'display:block'
        return
      }
      let list = _this.processDetailLogs.filter(function (item) {
        //获取处理记录信息
        return item.historicTaskInstance.taskDefinitionKey == e.element.id
      })
      let html = new Array()
      //onmouseout="javascript:document.getElementById(\'div_'+e.element.id+'\').style.display=\'none\';" <a class="link">流程梳理环节详情</a>
      html.push(
        '<div class="lchj-box" signDiv="flag"  onmouseover="showDiv(\'div_' +
          e.element.id +
          '\')" onmouseleave="hidenDiv(\'div_' +
          e.element.id +
          '\')" id="div_' +
          e.element.id +
          '"><div class="box-head"><span class="title">任务执行情况</span></div><div class="box-body">',
      )
      list.forEach(function (item) {
        html.push('<table  cellpadding="0" cellspacing="0" class="lchj-table">')
        html.push('<tbody><tr>')
        html.push('<td class="clum" width="100">接收环节: </td>')
        html.push('<td>' + item.historicTaskInstance.name + '</td>')
        html.push('</tr>')
        html.push('<tr>')
        html.push('<td class="clum">发送环节: </td>')
        if (item.historicTaskInstance.preTaskDefName != null) {
          html.push('<td>' + item.historicTaskInstance.preTaskDefName + '</td>')
        } else {
          html.push('<td></td>')
        }

        html.push('</tr>')
        html.push('<tr>')
        html.push('<td class="clum">发送人: </td>')
        html.push('<td>' + item.sendUserName + '</td>')
        html.push('</tr>')
        html.push('<tr>')
        html.push(
          '<td class="clum" title="' + item.assigneeInfo + '">接收人: </td>',
        )
        if (item.reiceiveUserName != null || item.receiveOrgName != null) {
          html.push(
            '<td>' +
              item.reiceiveUserName +
              '（' +
              item.receiveOrgName +
              '）' +
              '</td>',
          )
        } else {
          html.push('<td></td>')
        }
        html.push('</tr>')
        if (item.ownerName != undefined) {
          html.push('<tr>')
          html.push('<td class="clum">委托人: </td>')
          html.push('<td>' + item.ownerName + '</td>')
          html.push('</tr>')
        }
        html.push('<tr>')
        html.push('<td class="clum">审批意见: </td>')
        let fullCommentMsg =
          item.comment != null && item.comment.fullMessage != null
            ? item.comment.fullMessage
            : ''
        let shortCommentMsg = ''
        if (
          item.historicTaskInstance.deleteReason != null &&
          'cancel_process' == item.historicTaskInstance.actionType
        ) {
          let cancelCommentMsg =
            '当前流程已作废,作废意见为:' +
            item.historicTaskInstance.deleteReason
          fullCommentMsg =
            fullCommentMsg == ''
              ? cancelCommentMsg
              : cancelCommentMsg + ',发送环节意见为:' + fullCommentMsg
          if (fullCommentMsg.length > 7) {
            shortCommentMsg = fullCommentMsg.substring(0, 7) + '...'
            html.push(
              '<td title="' +
                fullCommentMsg +
                '" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">',
            )
            html.push(
              '<a href="#" style="text-decoration:none;">' +
                shortCommentMsg +
                '</a></td>',
            )
          } else {
            html.push('<td>' + fullCommentMsg + '</td>')
          }
        } else {
          if (fullCommentMsg.length > 7) {
            shortCommentMsg = fullCommentMsg.substring(0, 7) + '...'
            html.push(
              '<td title="' +
                fullCommentMsg +
                '" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">',
            )
            html.push(
              '<a href="#" style="text-decoration:none;">' +
                shortCommentMsg +
                '</a></td>',
            )
          } else {
            html.push('<td class="qTipmessage">' + fullCommentMsg + '</td>')
          }
        }
        html.push('</tr>')
        html.push('<tr>')
        html.push('<td class="clum">开始时间: </td>')
        html.push(
          '<td>' +
            _this.dateFormat(item.historicTaskInstance.startTime) +
            '</td>',
        )
        html.push('</tr>')
        if (item.historicTaskInstance.endTime != null) {
          html.push('<tr>')
          html.push('<td class="clum">结束时间: </td>')
          html.push(
            '<td>' +
              _this.dateFormat(item.historicTaskInstance.endTime) +
              '</td>',
          )
          html.push('</tr>')
        }
        html.push('<tr>')
        html.push('<td class="clum">任务状态: </td>')
        if (item.historicTaskInstance.actionType == 'cancel_process') {
          html.push('<td><font color="red">作废</font></td>')
        } else {
          if (item.historicTaskInstance.endTime != null) {
            html.push('<td>已完成</td>')
          } else {
            html.push('<td><font color="red">正在审批</font></td>')
          }
        }
        html.push('</tr></tbody>')
        html.push('</table> <br>')
      })
      html.push('</div>')
      let content = html.join('')
      if (event == 'element.hover') {
        overlays.add(e.element.id, 'note', {
          position: {
            bottom: 0,
            right: 0,
          },
          html: content,
        })
      }
    },
    hidenDiv: function (id) {
      document.getElementById(id).style = 'display:none'
      document.querySelectorAll('[signDiv]').forEach(function (item) {
        if (document.getElementById(item.id) != null) {
          //去掉所有的环节详细数据，防止页面延迟，没有消失显示的详情信息
          document.getElementById(item.id).style = 'display:none'
        }
      })
    },
    showDiv: function (id) {
      document.getElementById(id).style = 'display:block'
    },
    //拼接环节详细信息
    appendHtml() {
      let _this = this
      _this.bpmnImporter = new BpmnImporter()
      var eventBus = _this.bpmnModeler.get('eventBus')
      var events = ['element.hover', 'element.out']
      let overlays = _this.bpmnModeler.get('overlays')
      events.forEach(function (event) {
        eventBus.on(event, function (e) {
          let thisNode = document.getElementById('div_' + e.element.id)
          let thisLinkNode = document.getElementById('line_' + e.element.id)
          if (e.element.type == 'bpmn:UserTask' || e.element.type == 'multi') {
            if (event == 'element.hover') {
              let temp = _this.processTrace.filter(function (item) {
                //是否已处理
                return item.activityId == e.element.id
              })
              if (temp.length > 0) {
                //历史记录环节详细数据
                _this.appendHistoryHtml(overlays, event, e)
              } else {
                //流程环节信息
                _this.dealActHtml(overlays, event, e)
              }
            }
            if (event == 'element.out' && thisNode != null) {
              document.getElementById('div_' + e.element.id).style =
                'display:none'
              document.querySelectorAll('[signDiv]').forEach(function (item) {
                if (document.getElementById(item.id) != null) {
                  //去掉所有的环节详细数据，防止页面延迟，没有消失显示的详情信息
                  document.getElementById(item.id).style = 'display:none'
                }
              })
            }
          } else if (e.element.type == 'bpmn:SequenceFlow') {
            //处理输出线的名称
            let listLine = _this.bpmnImporter._getLineName.filter(function (
              item,
            ) {
              //判断这个输出线是否是截取的输出线名称
              return item.id == e.element.id
            })
            if (listLine.length > 0) {
              if (event == 'element.hover') {
                if (thisLinkNode != null) {
                  document.getElementById('line_' + e.element.id).style =
                    'display:block'
                } else {
                  _this.appendLineHtml(overlays, event, e)
                }
              }
            }
            if (event == 'element.out') {
              if (document.getElementById('line_' + e.element.id) != null) {
                //去掉输出线的显示
                document.getElementById('line_' + e.element.id).style =
                  'display:none'
              }
              document.querySelectorAll('[lineDiv]').forEach(function (item) {
                if (document.getElementById(item.id) != null) {
                  //去掉所有的输出线显示
                  document.getElementById(item.id).style = 'display:none'
                }
              })
            }
          }
        })
      })
    },
    appendLineHtml(overlays, event, e) {
      //拼写输出线名称
      let _this = this
      console.log(e.element.id)
      let html = new Array()
      let hash = {} //数组去重
      let lineList = _this.bpmnImporter._getLineName.reduce(function (
        item,
        next,
      ) {
        hash[next.id] ? '' : (hash[next.id] = true && item.push(next))
        return item
      },
      [])
      let list = lineList.filter(function (item) {
        //判断这个输出线是否是截取的输出线名称
        return item.id == e.element.id
      })

      //html.push('<div id="line_'+list[0].id+'">'+list[0].name+'</div>');
      html.push(
        '<div class="lchj-box" lineDiv="flag" id="line_' +
          list[0].id +
          '"><div class="box-body">' +
          list[0].name,
      )
      html.push('</div></div>')
      let content = html.join('')
      //alert(list[0].name)
      if (event == 'element.hover') {
        overlays.add(e.element.id, {
          position: {
            bottom: 0,
            right: 0,
          },
          html: content,
        })
      }
    },
    //环节信息
    dealActHtml(overlays, event, e) {
      let _this = this
      let html = new Array()
      let thisNode = document.getElementById('div_' + e.element.id)
      let listAct = _this.arrayActId.filter(function (item) {
        //判断这个节点是否
        return item == 'div_' + e.element.id
      })
      if (listAct.length == 0) {
        _this.arrayActId.push('div_' + e.element.id)
      }
      if (listAct.length > 0) {
        if (thisNode != null) {
          document.getElementById('div_' + e.element.id).style = 'display:block'
        }
        return
      }
      let url =
        this.$get_bpmn_manage_url() +
        '/procDefMgr/getActivityDefModel.do?procDefId=' +
        _this.procDefId +
        '&actDefId=' +
        e.element.id
      _this.$axios
        .post(url)
        .then(function (res) {
          let actDefObject = eval(res.data)
          html.push(
            '<div class="lchj-box" signDiv="flag" onmouseover="showDiv(\'div_' +
              e.element.id +
              '\')" onmouseleave="hidenDiv(\'div_' +
              e.element.id +
              '\')" id="div_' +
              e.element.id +
              '"><div class="box-head"><span class="title">任务执行情况</span></div><div class="box-body">',
          )
          html.push(
            '<table cellpadding="0" cellspacing="0" class="lchj-table">',
          )
          html.push('<tbody><tr>')
          html.push('<td class="clum" width="100">任务名称: </td>')
          html.push('<td>' + actDefObject.actDefName + '</td>')
          html.push('</tr>')
          html.push('<tr>')
          html.push('<td class="clum">任务资源: </td>')
          html.push('<td>')
          var roleStrs = ''
          var orgStrs = ''
          var userStrs = ''
          var activityResources = eval(actDefObject.activityResources)
          activityResources.forEach(function (item) {
            // alert(activityResource.name);
            if (item.type == 'ROLE') {
              roleStrs += item.name + ','
            } else if (item.type == 'ORG') {
              orgStrs += item.name + ','
            } else if (item.type == 'USER') {
              userStrs += item.name + ','
            }
          })
          roleStrs = roleStrs.substring(0, roleStrs.lastIndexOf(','))
          orgStrs = orgStrs.substring(0, orgStrs.lastIndexOf(','))
          userStrs = userStrs.substring(0, userStrs.lastIndexOf(','))
          if (roleStrs.length > 0) {
            html.push('角色:' + roleStrs + '<br/>')
          }
          if (orgStrs.length > 0) {
            html.push('组织:' + orgStrs + '<br/>')
          }
          if (userStrs.length > 0) {
            html.push('人员:' + userStrs + '<br/>')
          }
          html.push('</td>')
          html.push('</tr>')
          html.push('<tr>')
          html.push('<td class="clum">任务类型: </td>')
          html.push('<td>单人处理</td>')
          html.push('</tr>')
          html.push('<tr>')
          html.push('<td class="clum">任务状态: </td>')
          html.push('<td>未执行</td>')
          html.push('</tr></tbody>')
          html.push('</table>')
          html.push('</div>')
          let content = html.join('')
          if (event == 'element.hover') {
            overlays.add(e.element.id, 'note', {
              position: {
                bottom: 0,
                right: 0,
              },
              html: content,
            })
          }
        })
        .catch(function (error) {
          console.log(error)
        })
    },
    // 给已经走过的流程添加颜色
    setNodeColor(nodeCodes, canvas) {
      let colorClass = ''
      for (let i = 0; i < nodeCodes.length; i++) {
        if (nodeCodes[i].status == '1') {
          colorClass = 'highlight-run'
        } else if (nodeCodes[i].status == '2') {
          colorClass = 'highlight'
        } else {
          colorClass = 'highlight-cancle'
        }
        if (nodeCodes[i].type == 'SEQ') {
          colorClass = 'highlight-line'
          canvas.addMarker(nodeCodes[i].activityId, colorClass)
        } else {
          canvas.addMarker(nodeCodes[i].activityId, colorClass)
        }
      }
    },
    //获取流程监控数据
    getProcessMonitorImage() {
      let _this = this
      let url =
        this.$get_bpmn_manage_url() +
        '/workflow/trace/traceNewByImage.do?' +
        'processInstanceId=' +
        _this.$route.query.processInstanceId
      _this.$axios
        .post(url)
        .then(function (res) {
          _this.procDefId = res.data.processInstance.processDefinitionId
          _this.processTrace = res.data.processTrace
          _this.processDetailLogs = res.data.hisTaskLog.processDetailLogs
          /**  let hash = {};//数组去重
            _this.processTrace = _this.processTrace.reduce(function(item, next) {
              hash[next.activityId] ? '' : hash[next.activityId] = true && item.push(next);
              return item;
          }, []);**/
          _this.getProcessXml()
        })
        .catch(function (error) {
          console.log(error)
        })
    },
    //解析xml生成流程图
    getProcessXml() {
      let _this = this
      let openProcessUrl =
        this.$get_bpmn_manage_url() +
        '/procDefModelMgr/showProcessXml.do?' +
        'procDefId=' +
        _this.procDefId
      _this.$axios
        .get(openProcessUrl)
        .then(function (res) {
          _this.bpmnXmlStr = res.data.bpmnXml
          _this.createNewDiagram(_this.bpmnModeler)
          _this.vLoading = false
        })
        .catch(function (error) {
          console.log(error)
          _this.vLoading = false
        })
      /** let imgs= document.getElementsByClassName("bjs-powered-by");
      for(let i = 0;i<imgs.length;i++){
        imgs[i].style.display = 'none';
      }**/
    },
    dateFormat(time) {
      // 时期格式化
      let date = new Date(time)
      return XEUtils.toDateString(date, 'yyyy-MM-dd HH:mm:ss')
    },
  },
  mounted() {
    this.vLoading = true
    // 获取到属性ref为“content”的dom节点
    this.container = this.$refs.content
    // 获取到属性ref为“canvas”的dom节点
    const canvas = this.$refs.canvas
    // 建模，官方文档这里讲的很详细
    let options = {
      container: canvas,
      additionalModules: [
        //汉字转换模块
      ],
      keyboard: {
        bindTo: window,
      },
    }
    this.bpmnModeler = new BpmnModeler(options)
    // 解析xml生成图形
    this.getProcessMonitorImage()
  },
}
</script>

<style lang="scss">
/*左边工具栏以及编辑节点的样式*/
@import '../../node_modules/bpmn-js/dist/assets/diagram-js.css';
@import '../../node_modules/bpmn-js/dist/assets/bpmn-font/css/bpmn.css';
@import '../../node_modules/bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css';
@import '../../node_modules/bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css';
.canvas {
  width: 100%;
  height: calc(100% - 48px);
}
body {
  margin: 0;
}
</style>
