UNPKG

@coon/utils

Version:
251 lines (230 loc) 6.26 kB
import axios from 'axios'; import utils from './utils' type CacheItem = { [prop: number]: any } enum Method { GET = 'get', POST = 'post', HEAD = 'head', REQUEST = 'request', DELETE = 'delete', PUT = 'put', PATCH = 'patch', OPTIONS = 'options', } interface IOption { apis: any config: any // vuex: boolean adapter: string } interface IUseOption { // 请求参数 params?: any // 请求发送的数据 data?: any // restful风格化数据 rest?: any // 强制更新 forceUpdate?: boolean // 请求超时时间 timeout?: number // 此次请求的过期时间 expire?: number | string } interface IApi { // url地址 url?: string // 请求类型 type?: Method // 缓存过期时间 expire?: number | string // 请求超时时间 timeout?: number // 默认数据 default?: any } interface IFullParams extends IUseOption, IApi { } // 默认配置 const defaultConfig = { type: Method.GET, adapter: 'axios' } export default class NoneData { // 缓存数据都以过期时间为key的方式存在于此 /** * key为0时表示session * { * 0:['keyName0'], * 1616383496048:['keyName1','keyName2'], * } * */ public cache: CacheItem public option: IOption public state: any public config: any public apis: { [prop: string]: any } public adapter: string static adapters = { axios: axios, } constructor(option: IOption) { this.option = option; this.state = {}; this.config = option.config; this.adapter = option.adapter; this.apis = {}; this.cache = {} } public getAdapter() { return NoneData.adapters[this.adapter]; } public async use(apiKey: string, option: IUseOption = {}) { const fullParams: IFullParams = this.getFullParams(apiKey, option); this.apis[apiKey] = { ...fullParams, apiKey }; // 如果没有配置url则直接返回默认数据或已存在的数据 if (!fullParams.url) { return this.getData(apiKey, fullParams); } // 将扩展url解析为正常url及请求方式 // 如果强制更新或者已经过期或者state中没有数据则发送请求 if (fullParams.forceUpdate || this.hadExpire(apiKey) || !this.state[apiKey]) { return this.request(fullParams); } } // 判断是否已经过期 public hadExpire(apiKey: string) { } // 获取单次请求的完整参数 public getFullParams(apiKey: string, option: IUseOption): IFullParams { const api = this.getApiFromKey(apiKey); const params = this.parseEurl(api, option); return utils.merge({}, params, option) as IFullParams; } // 通过apikey获取api对象 /** // api对象格式如下: { // url地址 url:'user/info', // 请求类型 type:'get', // 缓存过期时间 expire:0, // 请求超时时间 timeout:0, // 默认数据 default:{}, } // option对象的格式如下 { // 请求参数 params:{}, // 请求发送的数据 data:{}, // restful风格化数据 rest:{}, // 强制更新 forceUpdate:true, // 请求超时时间 timeout:0, // 此次请求的过期时间 expire:0, } */ public getApiFromKey(apiKey: string) { //把apiKey分隔成两部分moduleName & apiName const [moduleName, ...tApiName] = apiKey.split('.'); const apiName = tApiName.join('.'); let api = this.option.apis?.[moduleName]?.[apiName]; if (!api) { console.warn(`noneData数据:${apiKey}未配置`); return false; } // 扩展的url if (typeof api === 'string') { // if (api[0] == ' ' || !/^(request|get|post|delete|head|options|put|patch)\s/.test(api)) { // api = (' ' + api).replace(/^\s+/, ' ') // } api = { url: api } } return api; } public requestHandler(res) { debugger; } // 解析形如 'post api/userOther/:userId/:pageSize/:pageNo 100s' 的URL public parseEurl(api: any, option: any) { let eurl = api.url || ''; if (eurl?.[0] == ' ' || !/^(request|get|post|delete|head|options|put|patch)\s/.test(eurl)) { eurl = (' ' + eurl).replace(/^\s+/, ' ') } const [dtype, furl, sexpire = '0'] = eurl.split(' '); const expire = utils.parseTime(sexpire); const type = api.type || (option.data ? 'post' : dtype) || Method.GET; let url = furl; if (option.rest) { url = this.restUrl(furl, option.rest); } return { url, type, expire } } // 解析restURL public restUrl(furl = '', restObj = {}) { // const restKeys=furl.match(/\{\w+\}/g); const restKeys = furl.match(/\:[^\/\b]+/g); restKeys?.forEach(item => { furl = furl.replace(item, restObj[item.replace(':', '')] || '') }); return furl; } // 获取数据 public getData(apiKey: string, fullParams: IFullParams) { // 如果未配置url取本地数据 return this.state[apiKey] || fullParams.default; } // 发送请求 public async request(fullParams: IFullParams) { // if () } } // 使用方法----------------------------------------------------------------------- // 在此之前需要如下的api配置 const apis = { moduleName: { // remote api data 'user.info': ' api/userInfo', // 'get api/userInfo' // rest api 'userOther': 'api/userOther/{userId}/{pageSize}/{pageNo}', // 默认本地数据,如果有url,就去请求 'userStore': { expire: 'session', url: 'api/userStore', type: 'post', timeout: 0, }, // 本地默认空数据 'userBlank': { default: {} }, // 直接在此也可配置缓存时间(单位为秒),作为此请求的默认缓存时间使用 'userLogs': { expire: 10 }, } } // 配置 const nd = new NoneData({ apis, config: {}, // 使用vuex // vuex: true, // adapter用来发送请求的,比如axios,uni.callFunction,uni.request等等。 adapter: 'axios' }) // store 版 vuex // 使用可能带本地缓存的服务器数据 // const data=await nd.use('moduleName.user.info', { // // 强制远程更新 // forceUpdate:false, // // 单独配置缓存时间 单位毫秒 // cache: 1000, // type: 'post', // rest:, // params:, // // 有此参数时默认切换为post请求,除非配置了type // data:, // })