api接口封装

184 阅读2分钟
import axios from 'axios'
import qs from 'qs'
import store from '../store'
import {Message} from 'view-design'
import {clearSystemInfo} from "./util";
import router from "../router";
import Cookies from "js-cookie";
 
axios.defaults.withCredentials = true
 
// 拦截重复请求
let pending = {}
const CancelToken = axios.CancelToken
// 请求标识;完成请求后也需要执行删除记录,所以添加此参数避免执行无用操作
const removePending = (key, isRequest = false) => {
    if (pending[key] && isRequest) {
        pending[key]('取消重复请求')
    }
    delete pending[key]
}
/**
 * 由于我们请求用了代理 直接代理到测试服务器 因此请求响应拦截器的config.url是一致的,不需要标识值区分
 * 如果请求拦截器和响应拦截器的config.url不一致,就需要一个标识值用来区分判断
 */
const getRequestIdentify = (config) => {
    const url = config.url
    // 返回url及请求参数 post方法请求参数为config.data  get方法请求参数为config.params
    if (config.method === 'post') {
        return encodeURIComponent(config.url + JSON.stringify(config.data))
    }
    return encodeURIComponent(url + JSON.stringify(config.params))
}
 
 
class HttpRequest {
    constructor() {
        this.baseUrl = ''
        this.queue = {}
    }
 
    getInsideConfig() {
        const config = {
            baseURL: '',
            // baseURL: this.baseUrl,
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            timeout: 10000  // 请求响应超时时间
        }
        return config
    }
 
    destroy(url) {
        delete this.queue[url]
        if (!Object.keys(this.queue).length) {
            // Spin.hide()
        }
    }
 
    interceptors(instance, url) {
        // 请求拦截
        instance.interceptors.request.use(config => {
            if (!config.data || !config.data.allowedRepeat) {
                const requestData = getRequestIdentify(config)
                removePending(requestData, true)
                // 使用 cancel token 取消请求 参考:http://www.axios-js.com/zh-cn/docs/#%E6%8B%A6%E6%88%AA%E5%99%A8
                config.cancelToken = new CancelToken((c) => {
                    pending[requestData] = c
                })
            } else {
                delete config.data.allowedRepeat
            }
 
 
            let adminId = Cookies.get('adminId')
            if (adminId) {
                config.headers.common['userToken'] = adminId || '';
            }
 
            // 添加全局的loading...
            config.data = qs.stringify(config.data)
            if (!Object.keys(this.queue).length) {
                // Spin.show() // 不建议开启,因为界面不友好
            }
            this.queue[url] = true
            return config
        }, error => {
            return Promise.reject(error)
        })
        // 响应拦截
        instance.interceptors.response.use(res => {
            this.destroy(url)
            res.data = typeof res.data == 'object' && res.data ? res.data : {}
            res.data.status = res.status
 
            if(!res.data.success){
                Message.error(res.data.msg)
 
                if(res.data.code == "100012"){
                    // 用户登录失效
                    // console.log(res,111111111)
                    clearSystemInfo()  // 清空路由用户信息
                    // eslint-disable-next-line no-undef
                    store.dispatch('handleLogOut')
                    router.push({
                        name: 'login'
                    })
                    return
                }
 
                if (res.data.code == '100039') {
                    // 用户距离上次修改密码时间过长或者是管理员修改密码
                    router.push('/pwd-edit')
                    // return
                }
 
                return Promise.reject()
 
            }else {
                return res.data
            }
        }, error => {
            this.destroy(url)
            return Promise.reject(error)
        })
    }
 
    request(options) {
        const instance = axios.create()
        options = Object.assign(this.getInsideConfig(), options)
        this.interceptors(instance, options.url)
        return instance(options)
    }
}
 
 
export default HttpRequest
// api.request.js
import HttpRequest from './axios'
import {Message} from 'view-design'
 
 
const axios = new HttpRequest()
const ajax = (option) => {
    return new Promise((resolve, reject) => {
        axios.request(option).then(res => {
            if (res.success) {
                resolve(res)
            } else {
                Message.error(res.msg)
                reject(res)
            }
        }).catch(error => {
            reject(error)
        })
    })
}
 
const get = (url, data) => {
    return ajax({
        url,
        method: 'get',
        data
    })
}
 
const post = (url, data) => {
    return ajax({
        url,
        method: 'post',
        data
    })
}
 
export {ajax, get, post}
//  api/index.js
const files = require.context(".", true, /\.js$/);
const modules = {};
files.keys().forEach((e) => {
    const path = e.replace(/\.\/|\.js/g, "");
    if (path === "index") return;
    if (!modules[path]) {
        modules[path] = {
            namespace: true,
        };
    }
    modules[path] = files(e).default ? files(e).default : files(e);
});
 
export default modules;
// user.js
import {ajax, post} from '../libs/api.request'
 
export const login = ({userName, password, isRemember}) => {
    const data = {
        loginName: userName,
        loginPwd: password,
        isRemember
    }
    return post('/mp/login', data)
}
 
export const logout = () => {
    return ajax({
        url: '/mp/logout',
        method: 'post'
    })
}
 
export const editPassword = ({adminId, newPassword, oldPassword}) => {
    return post('/mp/admin/editPassword', {adminId, newPassword, oldPassword})
}
// main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import api from "@/api";
 
/**
 * @description 生产环境关掉提示
 */
Vue.config.productionTip = false
 
/**
 * @description 全局注册应用配置
 */
 
Vue.prototype.$api = api
 
new Vue({
    router, store, print, render: h => h(App)
}).$mount('#app')