The requirement is to get the export record. Features, no matter which route can access the record; When the export operation is performed, the download data will be transmitted through websocket and the record will be re-rendered after waiting for background processing

The effect

vuex

import { getExportLogs } from "@/api/login";

const store = new Vuex.Store({
  // Global status
  state: {
    logs: [].// Export records
  },
    
  getters: {
    logs:state= >state.logs,
  },
  
  // Change the state
  mutations: {SET_LOGS(state, val){ state.logs = val; }},// Asynchronous events
  actions: {_getLogs({ commit }) {
    return new Promise((resolve, reject) = > {
      getExportLogs()// Call the function - get the export record
        .then(res= > {
          if (res.msg == 'ok') { 
            commit("SET_LOGS", res.data);// Resets the state when the call succeeds
            resolve(res.data);// Export record data
          } 
        .catch(error= >{ reject(error); }); }); }})Copy the code

I made a component and embedded it in the header of the page. Here is the component that guides out the record when it is mounted

import { mapGetters } from 'vuex'

export default{
	async mounted(){
	    this.$store.dispatch("user/_getLogs")},// So that the view can be rendered in real time when data is updated
	computed: {
	    ...mapGetters([
	        'logs',])}}Copy the code

websocket

The process is to establish a connection — bind the account (omitted) — after the export operation, the data will be sent after the background processing is finished, at this time the front end is responsible for popup the download box

The heartbeat detection reference: www.jianshu.com/p/1141dcf6d…

import store from "@/store/index";
import { Message } from "element-ui";

export default function initWebsocket() {
    // Heartbeat detection, send a message every 28 seconds to prevent disconnection
    var heartCheck = {
        timeout: 28000.timeoutObj: null.serverTimeoutObj: null.reset: function(){
            clearTimeout(this.timeoutObj);
            clearTimeout(this.serverTimeoutObj);
            return this;
        },
        start: function(){
            var self = this;
            this.timeoutObj = setTimeout(function(){
                // A heartbeat message is sent, and the back end returns a heartbeat message,
                // if onMessage receives the returned heartbeat, the connection is normal
                ws.send("HeartBeat");
                self.serverTimeoutObj = setTimeout(function(){// If it has not been reset for a certain amount of time, the backend is disconnected
                    ws.close();     // If onclose would reconnect, we would reconnect to ws.close(). A reconnect would trigger onClose and cause the reconnect to occur twice
                }, self.timeout)
            }, this.timeout)
        }
    }

    var lockReconnect = false;  // Avoid ws duplication
    var ws = null;          // Check whether the current browser supports WebSocket
    var wsUrl = "ws://url"
    createWebSocket(wsUrl);   Ws / / connection

    / / create the websocket
    function createWebSocket(url) {
        try{
            if('WebSocket' in window){
                ws = new WebSocket(url);
            }else if('MozWebSocket' in window){  
                ws = new MozWebSocket(url);
            }else{
                layui.use(['layer'].function(){
                  var layer = layui.layer;
                  layer.alert("Your browser does not support webSocket protocol, it is recommended to use the new version of Google, Firefox and other browsers, do not use IE10 browser, 360 browser please use speed mode, do not use compatible mode!"); 
                });
            }
            initEventHandle();
        }catch(e){
            reconnect(url);
            console.log(e); }}// Callback processing
    function initEventHandle() {
        // Successful connection
        ws.onopen = function () {
            heartCheck.reset().start();      // Heartbeat detection reset
            console.log("Connection successful"+new Date().toUTCString());
        };
        
        // Receive information
        ws.onmessage = async function (event) {    // If a message is received, heartbeat detection is reset
            heartCheck.reset().start();      // If you get any messages, the current connection is normal
            
            // Get data
            let data=JSON.parse(event.data)
            // The download box is displayed
            if(data.type=='down_excel'){
                openDownloadDialog(data.url,data.file_name)
            }
            
        }
            
        ws.onclose = function () {
            reconnect(wsUrl);
            console.log("Connection closed!"+new Date().toUTCString());
        };
            
        ws.onerror = function () {
            reconnect(wsUrl);
            console.log("Wrong connection!");
        };
    }

    function reconnect(url) {
        if(lockReconnect) return;
        lockReconnect = true;
        setTimeout(function () {     // Set delay to avoid too many requests
            createWebSocket(url);
            lockReconnect = false;
        }, 2000);
    }

    // popbox - this function is called when the download data is received from the Websocket
    function openDownloadDialog(url, saveName){
        // Call the function to indicate that the background has finished processing the export asynchronously, and send the event to re-render the export record
        store.dispatch("_getLogs")
        window.open(url);
        Message.success('Export successful! ')}}Copy the code

Establish a connection

App.vue

import initWebsocket from '@/utils/createWebSocket'
export default {
  name: "App".mounted(){
    initWebsocket()
  }
};
Copy the code