<template>
	<div id="app">
		<transition name='fade' mode="out-in">
			<router-view/>
		</transition>
	</div>
</template>

<script>
	import Vue from 'vue';
	export default {
		name: 'App',
		// apiToken:'',//WebSocket链接凭证
		// time:'',
		data(){
			return{
				reconnectData:null,
				lockReconnect:false,    //避免重复连接，因为onerror之后会立即触发 onclose
				timeout:10000,          //10s一次心跳检测
				timeoutObj:null,
				serverTimeoutObj:null,
				apiToken:'',
				linkfailure:true,

			}
		},
		methods:{
			/**************************************/
			//初始化weosocket
			initWebSocket(apiToken) {
				// 书写接口信息
				const wsuri = "ws://103.108.43.176:9101?apiToken=" + apiToken;//www.service.com 线上
				// const wsuri = "ws://192.168.2.187:9101?apiToken=" + apiToken;//www.service.com //192.168.2.186 本地
				// 创建websocket实例
				Vue.prototype.$websocket = new WebSocket(wsuri);
				this.$websocket.onopen = this.websocketonopen; //连接成功
				this.$websocket.onmessage = this.websocketonmessage; //接收消息
				this.$websocket.onerror = this.websocketonerror;//链接错误提示
				this.$websocket.onclose = this.socket_close;//链接断开提示
			},


			/**************************************/
			//连接成功
			websocketonopen() {
				console.log('已经链接');
				Vue.prototype.$socket_open = true;
				this.heatBeat();
			},

			/*******************************************/
			//连接关闭触发
			socket_close(e){
				console.log('断开连接',e);
				//this.init()
				this.reconnect();
			},

			/******************************************/
			//数据接收
			websocketonmessage(e){
				this.heatBeat();//收到消息会刷新心跳检测，如果一直收到消息，就推迟心跳发送
				const redata = JSON.parse(e.data);//接收数据源
				if(redata.type != "pong"){
					console.log(redata);
				}
				let  getters = this.$store.getters;
				//获取vuex数据
				let session = getters.get_session;//会话列表
				let offline  = getters.get_offline;//离线列表
				let sessionType  = getters.get_type;//选择状态(会话/离线)
				let dataIndex  = getters.get_num;//列表下标
				let current_session  = getters.get_current;//当前会话
				let session_name  = getters.get_session_name;//当前用户名

				if(e.data.type == "pong" ) return
				this.$store.dispatch("SET_SESSION_MESSAGE",JSON.parse(e.data));

				// 用户接入数据
				if(redata.message_type == "connect"){
					let _this  = this;
					let arr =[
						redata.data,
						offline,
						session,
						sessionType,
						dataIndex,
						current_session,
						session_name
					]
					_this.$public.visitorsConnect(arr,function(data){
						//离线匹配列表访客链接回调
						_this.$store.dispatch("SET_OFFLINE",data);

					},function(data,session,offline,type,num,dataList,name){
						//将用户添加到会话列表中
						session.push(data.user_info);
						//获取接入的用户信息
						//_this.get_user_info(list);
						//获取接入的用户信息写入vuex
						_this.$store.dispatch("SET_SESSION",session);//会话列表
						_this.$store.dispatch("SET_OFFLINE",offline);//离线列表
						_this.$store.dispatch("SET_TYPE",type);//选择类型(会话/离线)
						_this.$store.dispatch("SET_NUM",num);//列表下标
						_this.$store.dispatch("SET_CURRENT",dataList);//当前会话数据
						_this.$store.dispatch("SET_SESSION_NAME",name);//当前会话对象名

					})
				}


				//用户离线后会话窗口切换
				if(redata.message_type == "userClose"){
					let _this =this;
					let	arr= [
						redata.data,
						session,
						offline,
						sessionType,
						dataIndex,
						session_name,
						current_session,
					]
					_this.$public.userOffline(arr,function(session,offline,type,index,name,list,userInfo){
						_this.$store.dispatch("SET_CURRENT",list);//当前会话数据
						_this.$store.dispatch("SET_SESSION_NAME",name);//当前会话对象名
						_this.$store.dispatch("SET_NUM",index);
						_this.$store.dispatch("SET_TYPE",type);
						_this.$store.dispatch("SET_SESSION",session);
						_this.$store.dispatch("SET_OFFLINE",offline);
						// _this.get_user_info(userInfo);
					})
				}


				//用户会话结束窗口切换
				if(redata.message_type == "delUser"){
					let _this =this;
					let	arr= [
						redata.data,
						session,
						offline,
						sessionType,
						dataIndex,
						session_name,
						current_session,
					]
					_this.$public.sessionEnd(arr,function(session,offline,type,index,name,list,userInfo){
						_this.$store.dispatch("SET_CURRENT",list);//当前会话数据
						_this.$store.dispatch("SET_SESSION_NAME",name);//当前会话对象名
						_this.$store.dispatch("SET_NUM",index);
						_this.$store.dispatch("SET_TYPE",type);
						_this.$store.dispatch("SET_SESSION",session);
						_this.$store.dispatch("SET_OFFLINE",offline);
						//	_this.get_user_info(userInfo);
					})
				}

				//接收用户消息数据
				if(redata.message_type == "chatMessage"){

					this.receiveAudio();
					let _this =this;
					this.$public.receivesMessage(redata.data,session,this.$frce,function(data,chatList,index){
						//判断是否是当前对话信息
						if(dataIndex == index){
							// _this.data =[];
							// _this.data = chatList.data;
							_this.$store.dispatch("SET_CURRENT",chatList.data);//当前会话数据
						}else{
							let num = Number.isInteger(chatList.num) ? chatList.num : 0;
							// _this.$set(chatList,'num',num+1)
							session[index].num = num+1
						}
						//更新会话时间
						// _this.$set(chatList,'intime',data.time);
						session[index].intime =data.time

						//更新会话列表中最新回复消息
						if(data.content.text){
							// _this.$set(chatList,'text',data.content.text)
							session[index].text =data.content.text
						}
						_this.$store.dispatch("SET_SESSION",session);
					})
				}

				//reLoginErr
				if(redata.message_type == "reLoginErr"){
					console.log('haha');
					this.init()
				}

			},

			/**************************************/
			//连接断开，失败
			websocketonerror(e) {
				console.log('失败',e);
				if(this.linkfailure){
					this.init()
				}
			},

			/******************************************/
			//断开链接数据初始化
			init(){
				this.$store.dispatch("SET_STATEVALUE",'隐身');
				this.$store.dispatch("SET_SESSION",[]);
				this.$store.dispatch("SET_OFFLINE",[]);
				this.$store.dispatch("SET_SESSION",[]);//会话列表
				this.$store.dispatch("SET_OFFLINE",[]);//离线列表
				this.$store.dispatch("SET_TYPE",1);//选择类型(会话/离线)
				this.$store.dispatch("SET_NUM",0);//列表下标
				this.$store.dispatch("SET_CURRENT",[]);//当前会话数据
				this.$store.dispatch("SET_SESSION_NAME",'');//当前会话对象名
				this.$store.dispatch("SET_SESSION_MESSAGE",{});
				this.$store.dispatch("SET_IS_INIT",false);
				this.$token = '';
				this.$router.push('/login')
				this.linkfailure = true;
				//this.reconnect();
			},

			/*******************************************/
			// 接收消息音频提示
			receiveAudio() {
				let receive = new Audio()
				receive.src = "../static/audio/receive.wav";
				receive.play();
			},

			/*****************获取当前聊天用户信息****************/
			get_user_info(type) {

				let  getters = this.$store.getters;
				//获取vuex数据
				let session = getters.get_session;//会话列表
				let offline  = getters.get_offline;//离线列表
				let sessionType  = getters.get_type;//选择状态(会话/离线)
				let dataIndex  = getters.get_num;//列表下标
				let current_session  = getters.get_current;//当前会话
				let session_name  = getters.get_session_name;//当前用户名


					// _this.$store.dispatch("SET_CURRENT",list);//当前会话数据
					// 	_this.$store.dispatch("SET_SESSION_NAME",name);//当前会话对象名
					// 	_this.$store.dispatch("SET_NUM",index);
					// 	_this.$store.dispatch("SET_TYPE",type);
					// 	_this.$store.dispatch("SET_SESSION",session);
					// 	_this.$store.dispatch("SET_OFFLINE",offline);
				if (type.length > 0) {
					// this.session_user_info = {};
					if (dataIndex <= type.length) {

						let obj = {
							headers: {
								"apiToken": this.$md5('accountInfo' + "customer-service" + 'service' + this.time[0] + 'service'),
								'userToken': this.token
							},
							account_id: type[dataIndex].id
						};

						this.post('api' + this.$ports.userInfo.accountInfo, obj).then(res => {
							if (res.data.code == 1) {
								// console.log(res.data.data);
								// this.session_user_info = res.data.data;
								this.$store.dispatch("SET_SESSSION_USER",res.data.data)
								// console.log(this.options);
								// for (let i = 0; this.options.length > i; i++) {
								// 	if (this.options[i].id == res.data.data.label_id) {
								// 		this.value = this.options[i].name;
								// 	}
								// 	break;
								// }
								//this.value = res.data.data.label_id
							}
						})


						//this.session_user_info = type[this.dataIndex].id;
						// console.log(type[this.dataIndex].id);
						// this.value = this.session_user_info.label;
					}
				} else {
					// this.session_user_info = {};
					this.$store.dispatch("SET_SESSSION_USER",{})
				}
			},

			/***************************************/
			//socket重连
			reconnect(){
				if(this.lockReconnect){   //这里很关键，因为连接失败之后之后会相继触发 连接关闭，不然会连接上两个 WebSocket
					return
				}
				this.lockReconnect = true;
				this.reconnectData && clearTimeout(this.reconnectData);
				this.reconnectData = setTimeout(()=>{
					this.initWebSocket(this.apiToken);
					this.lockReconnect = false;
				},3000)
			},

			/*************************************/
			//心跳检测
			heatBeat(){
				this.timeoutObj && clearTimeout(this.timeoutObj);
				this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
				this.timeoutObj = setTimeout(()=>{
					// console.log('发送',{type:'ping'});
					this.$websocket.send(JSON.stringify({type:'ping'}))   //根据后台要求发送
					this.serverTimeoutObj = setTimeout(()=> {
						this.$websocket.close(); //如果  5秒之后我们没有收到 后台返回的心跳检测数据 断开socket，断开后会启动重连机制
					}, 5000);
				}, this.timeout)
			},

			/******************************/

		},
		mounted() {
			// 获取系统时间
			let t = new Date().getTime();
			//this.get('api'+this.$ports.TIME+'?t='+t).then(res => {
			this.get('http://kfadmin.bocai186.com'+this.$ports.TIME+'?t='+t).then(res => {
				if (res.data.code == 1) {
					let time = res.data.data.time.split(' ');
					time[0] =(new Date( time[0].replace(/-/g,'/')).getTime()) /1000;
					sessionStorage.setItem("time",JSON.stringify(time));
					sessionStorage.setItem("logo",res.data.data.logo);
					this.apiToken = this.$md5('customer-service'+time[0]+window.location.origin)
					this.initWebSocket(this.apiToken);
				}
			});
		},
		destroyed() {
			this.lockReconnect = true;
			this.websock.close()                   //离开路由之后断开websocket连接
			clearTimeout(this.reconnectData);      //离开清除 timeout
			clearTimeout(this.timeoutObj);         //离开清除 timeout
			clearTimeout(this.serverTimeoutObj);   //离开清除 timeout
		}
	}
</script>

<style>
	.fade-enter-active, .fade-leave-active {
		transition: opacity .5s;
	}

	.fade-enter, .fade-leave-to {
		opacity: 0;
	}
</style>
