feat: 首次提交
This commit is contained in:
120
components/firstui/fui-request/fui-common.js
Normal file
120
components/firstui/fui-request/fui-common.js
Normal file
@ -0,0 +1,120 @@
|
||||
// 本文件由FirstUI授权予新疆天衡创新研究院有限公司(手机号:1 86 1 4 07 2 549,身份证尾号:5A07X5)专用,请尊重知识产权,勿私下传播,违者追究法律责任。
|
||||
const base = {
|
||||
//所有配置项,未设置则使用默认值
|
||||
config() {
|
||||
return {
|
||||
//接口域名,如:https://firstui.cn(如果host为空,则直接使用传入的目标地址url)
|
||||
host: '',
|
||||
// 接口地址:/order/getList(如果host为空,直接传入:https://firstui.cn/order/getList)
|
||||
url: '',
|
||||
//参数
|
||||
data: {},
|
||||
//请求头
|
||||
header: {
|
||||
/*
|
||||
* content-type:
|
||||
* application/x-www-form-urlencoded
|
||||
* application/json
|
||||
*/
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
//必须大写
|
||||
method: 'POST',
|
||||
//大于0时才生效,否则使用全局配置或者默认值
|
||||
timeout: 0,
|
||||
dataType: 'json',
|
||||
//是否阻止拦截重复的请求(重复:请求地址url + method + 参数data 一致)
|
||||
prevent: false,
|
||||
//Array<String> 参数data中的key,prevent为true时有效,进行重复请求判断时移除keys中相关参数,如时间戳、随机数等.
|
||||
keys: [],
|
||||
//是否仅返回简要数据:true-仅返回接口数据data,false-返回包含header、statusCode、errMsg、data等数据
|
||||
brief: false,
|
||||
//String 请求标记,用于中断该请求,不同请求不可重复,只可包含数字、字母、下划线,如:firstui_001
|
||||
cancelToken: '',
|
||||
showLoading: true,
|
||||
//加载中提示文本,showLoading为true时有效
|
||||
loadingText: '',
|
||||
errorMsg: '网络不给力,请检查网络设置!',
|
||||
//跨域请求时是否携带凭证(cookies)仅H5支持(HBuilderX 2.6.15+)
|
||||
withCredentials: false,
|
||||
//DNS解析时优先使用ipv4,仅 App-Android 支持 (HBuilderX 2.8.0+)
|
||||
firstIpv4: false,
|
||||
//get请求时参数值为数组时处理方式,可选值:comma-值逗号拼接,repeat-重复参数名,brackets-带中括号参数名,indices-数组下标参数名
|
||||
arrayFormat: 'comma'
|
||||
}
|
||||
},
|
||||
getOptions(config) {
|
||||
let options = {
|
||||
...config
|
||||
};
|
||||
['host', 'timeout', 'prevent', 'keys', 'brief', 'cancelToken', 'showLoading', 'loadingText', 'errorMsg',
|
||||
'arrayFormat'
|
||||
]
|
||||
.forEach(item => {
|
||||
delete options[item];
|
||||
})
|
||||
return options;
|
||||
},
|
||||
getParamsHandle(config, arrayFormat) {
|
||||
const options = {
|
||||
...config
|
||||
}
|
||||
const idx = ['indices', 'repeat', 'brackets'].indexOf(arrayFormat)
|
||||
if (options.data && Object.keys(options.data).length > 0 && idx !== -1) {
|
||||
let params = []
|
||||
Object.entries(options.data).forEach(([key, value]) => {
|
||||
if (Array.isArray(value)) {
|
||||
let _key = key;
|
||||
if (arrayFormat === 'brackets') {
|
||||
_key = `${key}[]`
|
||||
}
|
||||
value.forEach((item, index) => {
|
||||
if (arrayFormat === 'indices') {
|
||||
_key = `${key}[${index}]`
|
||||
}
|
||||
const val = Object.prototype.toString.call(item) === '[object Object]' ?
|
||||
JSON.stringify(item) : item;
|
||||
params.push(`${_key}=${val}`)
|
||||
})
|
||||
} else {
|
||||
params.push(`${key}=${value}`)
|
||||
}
|
||||
})
|
||||
|
||||
options.url = `${options.url}?${params.join('&')}`
|
||||
options.data = {}
|
||||
}
|
||||
return options;
|
||||
},
|
||||
merge(a, b) {
|
||||
return Object.assign({}, a, b);
|
||||
},
|
||||
mergeConfig(defaultConfig, config, init) {
|
||||
let header = base.merge(defaultConfig.header, config.header || {});
|
||||
let params = base.merge(defaultConfig, config)
|
||||
params.header = header;
|
||||
if (!init) {
|
||||
let url = base.combineURLs(params.host, params.url)
|
||||
params.url = url;
|
||||
}
|
||||
return params;
|
||||
},
|
||||
//如果host为空,则直接使用传入的目标地址
|
||||
combineURLs(host, target) {
|
||||
return host ? host.replace(/\s+/g, '') + '/' + target.replace(/\s+/g, '').replace(/^\/+/, '') : target;
|
||||
},
|
||||
toast(text, duration, success) {
|
||||
text && uni.showToast({
|
||||
title: text,
|
||||
icon: success ? 'success' : 'none',
|
||||
duration: duration || 2000
|
||||
})
|
||||
},
|
||||
showLoading(title, mask = true) {
|
||||
uni.showLoading({
|
||||
mask: mask,
|
||||
title: title || '请稍候...'
|
||||
})
|
||||
}
|
||||
}
|
||||
export default base
|
57
components/firstui/fui-request/fui-taskStore.js
Normal file
57
components/firstui/fui-request/fui-taskStore.js
Normal file
@ -0,0 +1,57 @@
|
||||
// 本文件由FirstUI授权予新疆天衡创新研究院有限公司(手机号:1 8 6 14 07 25 49,身份证尾号:5A07X5)专用,请尊重知识产权,勿私下传播,违者追究法律责任。
|
||||
class RequestTaskStore {
|
||||
constructor(taskList = []) {
|
||||
this.taskStore = taskList
|
||||
}
|
||||
setRequestTaskStore(taskArr, taskKey) {
|
||||
taskKey && taskArr.push(taskKey)
|
||||
this.taskStore = taskArr;
|
||||
}
|
||||
removeRequestTask(task) {
|
||||
if (!task) return;
|
||||
const taskKey = this.getRequestTask(task)
|
||||
let taskArr = [...this.taskStore]
|
||||
const index = taskArr.indexOf(taskKey)
|
||||
if (~index) {
|
||||
taskArr.splice(index, 1)
|
||||
this.setRequestTaskStore(taskArr)
|
||||
}
|
||||
}
|
||||
getRequestTask(task) {
|
||||
let {
|
||||
url,
|
||||
method,
|
||||
keys,
|
||||
data
|
||||
} = task;
|
||||
keys = keys || []
|
||||
data = typeof data === 'string' ? JSON.parse(data) : data;
|
||||
let taskArr = [];
|
||||
for (let key in data) {
|
||||
if (data.hasOwnProperty(key) && !~keys.indexOf(key)) {
|
||||
let value = data[key] === null ? '' : data[key];
|
||||
taskArr.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));
|
||||
}
|
||||
}
|
||||
return url + method + taskArr.join('');
|
||||
}
|
||||
requestTaskStore(task) {
|
||||
let result = false;
|
||||
if (!task) return result;
|
||||
const taskKey = this.getRequestTask(task)
|
||||
let taskArr = [...this.taskStore]
|
||||
if (taskArr.length > 0) {
|
||||
if (~taskArr.indexOf(taskKey)) {
|
||||
result = true;
|
||||
} else {
|
||||
this.setRequestTaskStore(taskArr, taskKey)
|
||||
}
|
||||
} else {
|
||||
taskKey && this.setRequestTaskStore(taskArr, taskKey)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
export default function createTaskStore(taskList = []) {
|
||||
return new RequestTaskStore(taskList)
|
||||
}
|
179
components/firstui/fui-request/index.js
Normal file
179
components/firstui/fui-request/index.js
Normal file
@ -0,0 +1,179 @@
|
||||
// 本文件由FirstUI授权予新疆天衡创新研究院有限公司(手机号:186 1 4 0 7 2 5 4 9,身份证尾号:5A07X5)专用,请尊重知识产权,勿私下传播,违者追究法律责任。
|
||||
/**
|
||||
* 网络请求
|
||||
* 文档地址:https://doc.firstui.cn/
|
||||
**/
|
||||
|
||||
import base from './fui-common.js'
|
||||
import createTaskStore from './fui-taskStore.js'
|
||||
|
||||
const store = createTaskStore()
|
||||
|
||||
class FIRSTUI_INNER {
|
||||
constructor(initConfig = {}) {
|
||||
this.initConfig = initConfig
|
||||
this.request = []
|
||||
this.response = []
|
||||
this.cancelToken = {}
|
||||
this.dispatchRequest = this.dispatchRequest.bind(this)
|
||||
this.loading = false
|
||||
}
|
||||
dispatchRequest(config = {}) {
|
||||
let params = base.mergeConfig(this.initConfig, config)
|
||||
const task = {
|
||||
url: params.url,
|
||||
method: params.method,
|
||||
keys: params.keys,
|
||||
data: params.data
|
||||
}
|
||||
if (params.prevent && store.requestTaskStore(task)) {
|
||||
return new Promise((resolve, reject) => {
|
||||
reject({
|
||||
statusCode: -9998,
|
||||
errMsg: 'request:prevented'
|
||||
})
|
||||
});
|
||||
}
|
||||
const arrayFormat = params.arrayFormat;
|
||||
let options = base.getOptions(params)
|
||||
if (options.method.toLocaleLowerCase() === 'get' && arrayFormat !== 'comma') {
|
||||
options = base.getParamsHandle(options, arrayFormat)
|
||||
}
|
||||
let promise = Promise.resolve(options);
|
||||
promise = promise.then(config => {
|
||||
if (params.showLoading && !this.loading) {
|
||||
base.showLoading(params.loadingText)
|
||||
this.loading = true
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
let requestTask = uni.request({
|
||||
...options,
|
||||
success: (res) => {
|
||||
if (params.showLoading && this.loading) {
|
||||
uni.hideLoading()
|
||||
this.loading = false
|
||||
}
|
||||
resolve(params.brief ? res.data : res)
|
||||
},
|
||||
fail: (err) => {
|
||||
if (params.showLoading && this.loading) {
|
||||
uni.hideLoading()
|
||||
this.loading = false
|
||||
}
|
||||
|
||||
if (params.errorMsg) {
|
||||
base.toast(params.errorMsg)
|
||||
}
|
||||
reject(err)
|
||||
},
|
||||
complete: () => {
|
||||
store.removeRequestTask(task)
|
||||
if (params.cancelToken && this.cancelToken[params
|
||||
.cancelToken]) {
|
||||
delete this.cancelToken[params.cancelToken]
|
||||
}
|
||||
}
|
||||
})
|
||||
if (params.cancelToken) {
|
||||
this.cancelToken[params.cancelToken] = requestTask;
|
||||
}
|
||||
if (params.timeout && typeof params.timeout === 'number' && params.timeout > 3000) {
|
||||
setTimeout(() => {
|
||||
try {
|
||||
store.removeRequestTask(task)
|
||||
if (params.cancelToken) {
|
||||
delete this.cancelToken[params.cancelToken]
|
||||
}
|
||||
requestTask.abort();
|
||||
} catch (e) {}
|
||||
resolve({
|
||||
statusCode: -9999,
|
||||
errMsg: 'request:cancelled'
|
||||
});
|
||||
}, params.timeout)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
return promise
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const inner = new FIRSTUI_INNER(base.config())
|
||||
|
||||
const http = {
|
||||
interceptors: {
|
||||
request: {
|
||||
use: (fulfilled, rejected) => {
|
||||
inner.request.push({
|
||||
fulfilled,
|
||||
rejected
|
||||
})
|
||||
},
|
||||
eject: (name) => {
|
||||
if (inner.request[name]) {
|
||||
inner.request[name] = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
response: {
|
||||
use: (fulfilled, rejected) => {
|
||||
inner.response.push({
|
||||
fulfilled,
|
||||
rejected
|
||||
})
|
||||
},
|
||||
eject: (name) => {
|
||||
if (inner.response[name]) {
|
||||
inner.response[name] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
create(config) {
|
||||
inner.initConfig = base.mergeConfig(base.config(), config, true);
|
||||
},
|
||||
get(url, config = {}) {
|
||||
config.method = 'GET'
|
||||
config.url = url || config.url || ''
|
||||
return http.request(config)
|
||||
},
|
||||
post(url, config = {}) {
|
||||
config.method = 'POST'
|
||||
config.url = url || config.url || ''
|
||||
return http.request(config)
|
||||
},
|
||||
all(requests) {
|
||||
return Promise.all(requests)
|
||||
},
|
||||
request(config = {}) {
|
||||
let chain = [inner.dispatchRequest, undefined];
|
||||
let promise = Promise.resolve(config);
|
||||
|
||||
inner.request.forEach(interceptor => {
|
||||
chain.unshift(interceptor.fulfilled, interceptor.rejected);
|
||||
});
|
||||
|
||||
inner.response.forEach(interceptor => {
|
||||
chain.push(interceptor.fulfilled, interceptor.rejected);
|
||||
});
|
||||
|
||||
while (chain.length) {
|
||||
promise = promise.then(chain.shift(), chain.shift());
|
||||
}
|
||||
|
||||
return promise;
|
||||
},
|
||||
abort(cancelToken) {
|
||||
if (!cancelToken) return;
|
||||
try {
|
||||
if (inner.cancelToken[cancelToken]) {
|
||||
inner.cancelToken[cancelToken].abort()
|
||||
delete inner.cancelToken[cancelToken]
|
||||
// console.log('request:cancelled')
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
export default http
|
Reference in New Issue
Block a user