微信小程序静默登录流程和统一错误处理与后置

重点涉及:静默登录、自动重新登录,
fly使用方法详见https://www.npmjs.com/package/flyio
关键点:使用lock方法,形成请求队列,保证登录完成在执行普通请求。

//httpMethods.js
import wxx from '../vendor/promisify.js';
import util from './util';
const config = require("../config/index"); // 必须相对路径
import Fly from '../vendor/fly';

const fly = new Fly()
const loginFly = new Fly()

loginFly.config.baseURL = config.host;
const login = async () => {
    fly.lock()
    const { code } = await wxx.loginAsync();
    loginFly.post('/api/v4/user/user/loginPlus', { loginType: 'WXMA', code })
    .then(res => {
        if(res.data.statusCode === 200) {
            if(res.data.code == 200) {
                let obj = res.data.data;
                console.log(obj);// code=203 需携带手机号加密信息请求登录接口,引导登录
                const { token, user } = obj;
                getApp().setEnvStorageSync('token', token);
                getApp().setEnvStorageSync('userInfo', user);
                fly.unlock()
                return {
                    userInfo: { token, user }
                }
            }
            else if(res.data.code == 204) { //补充用户信息
                let {token, user} = res.data.data;
                getApp().setEnvStorageSync('token', token);
                getApp().setEnvStorageSync('userInfo', user);
            }
        }
        fly.unlock();
    }).catch(err => {
        fly.unlock();
    })
}
login()
fly.config.baseURL = config.host;

fly.interceptors.request.use((request) => {
  return request
})

fly.interceptors.response.use(
    async (response) => {
        if(response.data.statusCode === 200 || response.data.status_code === 200){
            return response
        }
        else if(response.data.statusCode === 401 || response.data.status_code === 401){
            let result = await login()
            if(result) {
                console.log('静默登录成功')
                return fly.request(response.request)
            } else {
                console.log('login---------',response)
                redirectLogin();
                return Promise.reject('未登录')
            }
        } else {
            console.log('statusCode异常---------',response)
            response.data.message && wx.showToast({ title: response.data.message, icon:'none' })
        }
        return response
    },
    async (err) => {
        console.log(err)
        let isShowNormalError = true
        const hideNormalMessage = () => isShowNormalError = false
        setTimeout(() => {
            if (isShowNormalError) wx.showToast({title: err.message + ' code:'+err.status, icon: 'none'});
        })
        console.log({ ...err.response, hideNormalMessage })
        throw { ...err.response, hideNormalMessage }
    }
)

function httpRequest(requestParam) {
    let { url, method = 'GET', data = {}, token, query, mustAuth = true } = requestParam;
    if(token === undefined) { mustAuth = false; }//有的无关用户信息的接口token和mustAuth都没传
    token = token || (mustAuth ? undefined : '');
    if(mustAuth && !token) { //前置校验 放在interceptor.request中
        redirectLogin();
        console.log('前置校验,未登录! 参数:', requestParam); 
        return Promise.reject('暂未登录')
    }
    let param = (mustAuth || token) && `token=${token}` || '';
    if(query) {
        let queryStr = util.urlEncode(query);
        param += param ? queryStr : queryStr.slice(1);
    }
    url += param ? '?' + param : '';
    return fly[method.toLowerCase()](url, data);
}
function httpRequestNotoken({url, method = 'GET', data = {}, mustAuth = true}) {
    return fly[method.toLowerCase()](url, data);
}

export {
    httpRequest
}

使用:
import { httpRequest } from '../../utils/httpMethods';
login()就会自动执行,并且仅执行一次,此为自动登录。
httpRequest({ url:/api/v4/cashier/yunAccount/payProductFromChannel, method: 'POST', data });

你可能感兴趣的:(微信小程序静默登录流程和统一错误处理与后置)