import beforeSend from './modules/beforeSend.js' import { getObjectType } from '@/static/js/utils/index.js' const parseThirdOptions = Symbol('parseThirdOptions'); const goLogin = Symbol('goLogin'); const api = Symbol('api'); class CreateApi { constructor(store,config){ this.$store = store; this.$config = config; this.$noTokenMsg = 'Token丢失!'; this.$invalidTokenMsg = '登录已超时,请重新登录!'; } /* 内部方法,解析额外设置 */ [parseThirdOptions](opts){ const defaultOpts = { warn:true, host:'default', block:'default', needToken:true, fullRes:false, loading:true } let result = {...defaultOpts} if (opts) { if (typeof opts === 'string') { result.block = opts } else if (getObjectType(opts)==='object') { result = {...result,...opts} } } return result; } /* 跳转到登录页面 */ [goLogin](){ let pages = getCurrentPages(); if (('/'+pages[0].route)!==this.$config.path.login){ uni.redirectTo({url:this.$config.path.login}) } } /* api调用 */ [api](httpMethod,method,params={},opts,paramsX){ return new Promise((resolve, reject)=>{ httpMethod = httpMethod.toUpperCase() let beforeRes = this.getHeaders(opts) //获取请求头 let headerOption = {}; if (!beforeRes.flag) { //token丢失错误 this[goLogin]() reject(this.$noTokenMsg); } else { headerOption = beforeRes.headers; //请求头赋值 let url = this.getUrl(method,opts,true); //组成请求地址 if (httpMethod==='POST'||httpMethod==='PUT'||httpMethod==='PATCH') { //POST和PUT方法,却使用GET方式传参,需要做参数处理 let tempStr = ''; if (getObjectType(paramsX)==='object') { let tempArr = []; for (let fieldName in paramsX) { tempArr.push(fieldName+'='+paramsX[fieldName]) } tempStr = tempArr.join('&'); } if (tempStr) { if (url.indexOf('?')<0) { url += '?' + tempStr; } else { url += '&' + tempStr; } } } else { //GET和DELETE方法,加时间戳 params = {...params,...{timekey:new Date().getTime()}}; } let ajaxOptions = { url:url, data:params, method:httpMethod, header:headerOption, success:(response)=>{ if (response.header['access-token'] && response.header['access-token'] !== 'invalid_token') { this.$store.commit('user/setToken',response.header['access-token']) //console.log(url) //console.log('sercer token',response.header['access-token']) } if (response.header['x-access-token']) { this.$store.commit('user/setRefreshToken',response.header['x-access-token']) } if (response.statusCode===200) { //请求状态为200,成功 if (!this.$config.ajax.host[opts.host] || opts.host==='mock') { resolve(response.data); } else { if (response.data.code===401) { this[goLogin]() let eMsgA = response.data.message; if (!eMsgA) eMsgA = this.$invalidTokenMsg; reject(eMsgA); } else if (response.data.code===200) { if (!opts.fullRes) { resolve(response.data.data||response.data.result); } else { console.log(response.data,'1'); resolve(response.data); } } else { //后端返回其它code,出错 console.log('Ajax backstage Error, return: ',response.data) let eMsg = response.data.message; if (!eMsg) eMsg = this.$config.ajax.errMsg; reject(eMsg); } } } else { //请求状态为非200,出错 console.log('Ajax Error Code: '+response.statusCode) reject(this.$config.ajax.errMsg); } }, fail:(err1)=>{ //api调用失败,出错 reject(this.$config.ajax.errMsg); } } uni.request(ajaxOptions) } }) } /* 获取请求头 opts 请求参数,JSON对象,其中 needToken: boolean 是否需要传递token headers 原有的headers,JSON对象 self 是否是内部调用,外部调用不传 */ getHeaders(opts,headers,self=false){ let res = {flag:true,headers:{}}; if (!self) { opts = this[parseThirdOptions](opts) } if (headers && getObjectType(headers)==='object') { res.headers=headers; } let temp = beforeSend(opts,this.$store,res.headers) if (temp.flag) { res.headers = temp.headers; } else { res.flag = false; } return res; } /* 获取请求地址 method 请求的后端方法名称 opts 求参数,JSON对象,其中 host 为config中配置的域名名称, block 为 config 中配置的接口模块名称, self 是否是内部调用,外部调用不传 */ getUrl(method,opts,self=false){ let res = method; if (!self) { opts = this[parseThirdOptions](opts) } let host = this.$config.ajax.host[opts.host]; let saveHost; try{ saveHost = this.$store.getters['system/get'+opts.host+'Host']; }catch(hoste){ //TODO handle the exception } if (saveHost) { host = saveHost; } res = host + this.$config.ajax.block[opts.block] + res; return res; } /* httpMethod: get post put dellete patch method:接口方法名 params:传递给后端的数据(JSON) opts:接口调用方法额外设置 paramsX:post put时,如果需要url后面带的其他参数,JSON格式 */ base(httpMethod,method,params={},opts,paramsX){ opts = this[parseThirdOptions](opts) if (opts.loading) { uni.showLoading({ title: '加载中...', mask:true }); } return new Promise((resolve, reject)=>{ this[api](httpMethod,method,params,opts,paramsX).then((d)=>{ if (opts.loading) { uni.hideLoading(); } resolve(d) }).catch(err=>{ if (opts.loading) { uni.hideLoading(); } if (typeof err !== 'string') { err = this.$config.ajax.errMsg; } if (opts.warn) { setTimeout(()=>{ uni.showModal({ title:'系统提示', content:err, showCancel:false }) },100) } reject(err) }) }) } } CreateApi.prototype.get = function(method,params,opts){ return this.base('GET',method,params,opts,{}) } CreateApi.prototype.post = function(method,params,opts,paramsX){ return this.base('POST',method,params,opts,paramsX) } CreateApi.prototype.put = function(method,params,opts,paramsX){ return this.base('PUT',method,params,opts,paramsX) } CreateApi.prototype.delete = function(method,params,opts){ return this.base('DELETE',method,params,opts,{}) } CreateApi.prototype.patch = function(method,params,opts,paramsX){ return this.base('PATCH',method,params,opts,paramsX) } export default CreateApi