<template>
  <section class="app-main">
    <transition name="fade-transform" mode="out-in">
      <keep-alive :include="cachedViews">
        <router-view :key="key" />
      </keep-alive>
    </transition>
    <message :result="dialogFormVisible" :message-info="message" @dialogData="closeDialog" />
  </section>
</template>

<script>
import Message from '../../components/Notice/message'
import Utils from '../../utils/contact.js'
import { transactionTable } from '@/api/dashboard'
export default {
  name: 'AppMain',
  components: { Message },
  data() {
    return {
      userId: this.$store.getters.userId,
      dialogFormVisible: false,
      activeName: 'first',
      message: [],
      websock: null,
      lockReconnect: false, // 是否真正建立连接
      timeout: 5 * 60 * 1000, // 5分钟一次心跳
      timeoutObj: null, // 心跳倒计时
      serverTimeoutObj: null, // 检测连接是否正常 倒计时
      timeoutNum: null, // 断开 重连倒计时
      bjd: {
        id: '',
        shebeizhonglei: '',
        shebeizhongleidaima: '',
        jianyanleibie: ''
      }
    }
  },
  computed: {
    cachedViews() {
      return this.$store.state.tagsView.cachedViews
    },
    key() {
      return this.$route.fullPath
    }
  },
  created() {
    // 页面创建生命周期函数
    this.initWebSocket()
    this.initMessage()
  },
  destroyed: function() {
    // 离开页面生命周期函数
    this.websocketclose()
  },
  methods: {
    initWebSocket: function() {
      const url = process.env.VUE_APP_WEBSOCKET + this.userId
      this.websock = this.getWebsoceket(url)
    },
    getWebsoceket(url) {
      const websock = new WebSocket(url)
      websock.onopen = this.websocketonopen
      websock.onerror = this.websocketonerror
      websock.onmessage = this.websocketonmessage
      websock.onclose = this.websocketclose
      return websock
    },
    reconnect() { // 重新连接
      const that = this
      if (that.lockReconnect) {
        return
      }
      that.lockReconnect = true
      // 没连接上会一直重连，设置延迟避免请求过多
      that.timeoutnum && clearTimeout(that.timeoutnum)
      that.timeoutnum = setTimeout(function() {
        // 新连接
        that.initWebSocket()
        that.lockReconnect = false
      }, 5000)
    },
    start() { // 开启心跳
      const self = this
      self.timeoutObj && clearTimeout(self.timeoutObj)
      self.serverTimeoutObj && clearTimeout(self.serverTimeoutObj)
      self.timeoutObj = setTimeout(function() {
        // 这里发送一个心跳，后端收到后，返回一个心跳消息，
        if (self.websock.readyState === WebSocket.OPEN) { // 如果连接正常
          self.websock.send(localStorage.getItem('token'))
        } else { // 否则重连
          self.reconnect()
        }
        self.serverTimeoutObj = setTimeout(function() {
          // 检测连接是否正常
          if (self.websock.readyState === WebSocket.OPEN) {
            self.start()
          } else {
            // 超时关闭
            self.websock.close()
          }
        }, self.timeout)
      }, self.timeout)
    },
    websocketonopen: function() {
      console.log('WebSocket连接成功')
      this.start()
    },
    websocketonerror: function(e) {
      console.log('WebSocket连接发生错误' + e)
      // 重连
      this.reconnect()
    },
    websocketonmessage: function(e) {
      const result = e.data
      if (result === '') {
        this.api({
          url: '/message/getAllMessageByUserId',
          method: 'get',
          params: {
            userId: this.userId
          }
        }).then(data => {
          this.message = JSON.parse(data)
          this.homePage()
        })
        this.dialogFormVisible = true
      } else if (result === 'homeRefresh') {
        this.homePage()
      } else {
        if (result === '超时') {
          this.$confirm('登录状态已过期，请重新登录', '系统提示', {
            confirmButtonText: '重新登录',
            showClose: false,
            showCancelButton: false,
            closeOnClickModal: false,
            type: 'warning'
          }).then(() => {
            this.$store.dispatch('LogOut').then(() => {
              location.reload() // 为了重新实例化vue-router对象 避免bug
            })
          })
        } else if (result.indexOf('查看报检单') !== -1) {
          const bjdresult = result.substring(result.indexOf('：') + 1, result.length)
          this.bjd = JSON.parse(bjdresult)
          if (this.bjd.jianyanleibie === 'DJ') {
            this.$router.push({ path: '/bjd/bjd-dj-input/' + this.bjd.id + '/' + this.bjd.shebeizhongleidaima + '/' + this.bjd.shebeizhonglei + '/finish' })
          } else {
            this.$router.push({ path: '/bjd/bjd-jj-input/' + this.bjd.id + '/' + this.bjd.shebeizhongleidaima + '/' + this.bjd.shebeizhonglei + '/finish' })
          }
        } else {
          this.message = JSON.parse(result)
          if (this.message.length > 0) {
            if (this.message[0].length > 0) {
              this.homePage()
              this.dialogFormVisible = true
            }
          } else {
            this.$notify.info({
              title: this.message.title,
              message: this.message.content,
              dangerouslyUseHTMLString: true,
              duration: 0,
              position: 'bottom-right'
            })
            this.message = []
          }
        }
      }
    },
    websocketclose: function(e) {
      console.log('connection closed (' + e.code + ')')
      // 重连
      this.reconnect()
    },
    closeDialog(data) {
      this.dialogFormVisible = data
    },
    initMessage() {
      this.api({
        url: '/message/initMessage',
        method: 'get',
        params: {
          userId: this.userId
        }
      })
    },
    homePage() {
      let ifExistence = false
      const data = this.$store.state.tagsView.visitedViews
      if (data.length > 0) {
        data.forEach((e) => {
          if (e.title === '首页') {
            ifExistence = true
          }
        })
      }
      if (ifExistence) {
        transactionTable(this.$store.getters.userId, this.$store.getters.departmentId, this.$store.getters.roles.map(role => role.roleId), true, this.$store.getters.clientType).then((data) => {
          Utils.$emit('initHomePage', data)
        })
      }
    }
  }
}
</script>

<style scoped>
  .app-main {
    /*50 = navbar  */
    min-height: calc(100vh - 90px);
    position: relative;
    overflow: hidden;
  }
</style>
