@@ -1,18 +1,162 @@ | |||
import request from '@/utils/request' | |||
// api地址 | |||
const api = { | |||
// TODO: 根据自身需求,修改登录和获取用户信息接口 | |||
login: `/user/login`, | |||
getUserInfo: `` | |||
} | |||
// 用户登录 | |||
export function login(data) { | |||
return request.post(api.login, data) | |||
} | |||
// 获取用户信息 | |||
export function getUserInfo() { | |||
return request.get(api.getUserInfo) | |||
} | |||
import Vue from "vue"; | |||
import store from '@/store' | |||
// 基础 | |||
// 根据体验版本和线上版本区分接口地址 | |||
const baseUrl = __wxConfig.envVersion !== "release" ? "" : ""; | |||
const apiArray = { | |||
// 登录 | |||
Login: { | |||
url: baseUrl + "/api/User/Login", | |||
config: {}, | |||
}, | |||
}; | |||
let api = {}; | |||
Object.keys(apiArray).forEach((item) => { | |||
api[item] = async function (config = {}, deep = false) { | |||
return new Promise(async (res, rej) => { | |||
let temp = apiArray[item]; | |||
let apiconfig = temp.config; | |||
let header = config.header | |||
? config.header | |||
: apiconfig.header | |||
? apiconfig.header | |||
: { | |||
"content-type": "application/json;charset:utf-8", | |||
}; | |||
// 鉴权-登录检测 | |||
if (!(temp.auth === false)) { | |||
// 如果没有用户信息则跳转至登录页 | |||
// Replace | |||
// if (!store.state.agentId) { | |||
// setTimeout(() => { | |||
// uni.showToast({ | |||
// title: '请先登录', | |||
// icon: 'none', | |||
// duration: 4000, | |||
// }) | |||
// }, 500) | |||
// uni.reLaunch({ | |||
// url: '/pages/login/login', | |||
// }) | |||
// return | |||
// } | |||
// 统一注入token | |||
} | |||
let url = config.url ? config.url : temp.url; | |||
if (config.query) { | |||
url += Vue.prototype.$u.queryParams(config.query); | |||
} | |||
uni.request({ | |||
url: url, | |||
data: config.data ? config.data : {}, | |||
method: config.method | |||
? config.method | |||
: apiconfig.method | |||
? apiconfig.method | |||
: "POST", | |||
timeout: config.timeout | |||
? config.timeout | |||
: apiconfig.timeout | |||
? apiconfig.timeout | |||
: 60000, | |||
header: header, | |||
dataType: config.dataType | |||
? config.dataType | |||
: apiconfig.dataType | |||
? apiconfig.dataType | |||
: "json", | |||
responseType: config.responseType | |||
? config.responseType | |||
: apiconfig.responseType | |||
? apiconfig.responseType | |||
: "text", | |||
sslVerify: | |||
config.sslVerify === false | |||
? false | |||
: apiconfig.sslVerify === false | |||
? false | |||
: true, | |||
withCredentials: | |||
config.withCredentials === false | |||
? false | |||
: apiconfig.withCredentials === true | |||
? true | |||
: false, | |||
firstIpv4: | |||
config.firstIpv4 === false | |||
? false | |||
: apiconfig.firstIpv4 === false | |||
? false | |||
: true, | |||
async success(data) { | |||
// console.log(config.url?config.url:temp.url); | |||
if (data.statusCode === 200) { | |||
console.log("请求数据", { | |||
...config, | |||
}); | |||
console.log("响应数据", { | |||
...data, | |||
}); | |||
let re = data.data; | |||
if ( | |||
re.code === 200 || | |||
re.stateCode === 0 || | |||
re.code === 106 || | |||
apiconfig.err === false | |||
) { | |||
res(re); | |||
} else { | |||
setTimeout(() => { | |||
uni.showToast({ | |||
icon: "none", | |||
title: re.msg || re.message, | |||
duration: 3000, | |||
}); | |||
}, 500); | |||
res(false); | |||
} | |||
} else { | |||
let str = `${data.statusCode}:${data.data.msg}`; | |||
setTimeout(() => { | |||
uni.showToast({ | |||
icon: "none", | |||
title: str, | |||
duration: 3000, | |||
}); | |||
}, 500); | |||
res(false); | |||
} | |||
}, | |||
fail(err) { | |||
console.log(err); | |||
let str = | |||
"网络错误:" + (err.statusCode ? err.statusCode : err.errMsg); | |||
if (err.errMsg == "request:fail timeout") { | |||
str = "网络异常,请检查网络"; | |||
} | |||
setTimeout(() => { | |||
uni.showToast({ | |||
icon: "none", | |||
title: str, | |||
duration: 3000, | |||
}); | |||
}, 500); | |||
res(false); | |||
}, | |||
}); | |||
}); | |||
}; | |||
}); | |||
export default { | |||
api, | |||
baseUrl, | |||
}; |
@@ -1,7 +1,9 @@ | |||
import App from './App' | |||
import Vue from 'vue' | |||
import './uni.promisify.adaptor' | |||
Vue.config.productionTip = false | |||
App.mpType = 'app' | |||
// 引入uView2.0 | |||
import uView from "uview-ui" | |||
@@ -14,7 +16,13 @@ import { | |||
Vue.use(router) | |||
// 引入vuex | |||
import store from '@/store' | |||
// 引入全局api | |||
import api from '@/api' | |||
Vue.prototype.$api = api.api | |||
Vue.prototype.$baseUrl = api.baseUrl | |||
import util from 'utils/index.js' | |||
Vue.prototype.$util = util | |||
// #ifdef APP-PLUS | |||
// 请勿删除此代码块 | |||
plus.runtime.quit = () => { | |||
@@ -0,0 +1,10 @@ | |||
uni.addInterceptor({ | |||
returnValue (res) { | |||
if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) { | |||
return res; | |||
} | |||
return new Promise((resolve, reject) => { | |||
res.then((res) => res[0] ? reject(res[0]) : resolve(res[1])); | |||
}); | |||
}, | |||
}); |
@@ -0,0 +1,149 @@ | |||
const mimeMap = require('./mimeMap.js') | |||
function FormData(){ | |||
let fileManager = wx.getFileSystemManager(); | |||
let data = {}; | |||
let files = []; | |||
this.append = (name, value)=>{ | |||
data[name] = value; | |||
return true; | |||
} | |||
this.appendFile = (name, path, fileName)=>{ | |||
let buffer = fileManager.readFileSync(path); | |||
if(Object.prototype.toString.call(buffer).indexOf("ArrayBuffer") < 0){ | |||
return false; | |||
} | |||
if(!fileName){ | |||
fileName = getFileNameFromPath(path); | |||
} | |||
files.push({ | |||
name: name, | |||
buffer: buffer, | |||
fileName: fileName | |||
}); | |||
return true; | |||
} | |||
this.getData = ()=>convert(data, files) | |||
} | |||
function getFileNameFromPath(path){ | |||
let idx=path.lastIndexOf("/"); | |||
return path.substr(idx+1); | |||
} | |||
function convert(data, files){ | |||
let boundaryKey = 'wxmpFormBoundary' + randString(); // 数据分割符,一般是随机的字符串 | |||
let boundary = '--' + boundaryKey; | |||
let endBoundary = boundary + '--'; | |||
let postArray = []; | |||
//拼接参数 | |||
if(data && Object.prototype.toString.call(data) == "[object Object]"){ | |||
for(let key in data){ | |||
postArray = postArray.concat(formDataArray(boundary, key, data[key])); | |||
} | |||
} | |||
//拼接文件 | |||
if(files && Object.prototype.toString.call(files) == "[object Array]"){ | |||
for(let i in files){ | |||
let file = files[i]; | |||
postArray = postArray.concat(formDataArray(boundary, file.name, file.buffer, file.fileName)); | |||
} | |||
} | |||
//结尾 | |||
let endBoundaryArray = []; | |||
endBoundaryArray.push(...endBoundary.toUtf8Bytes()); | |||
postArray = postArray.concat(endBoundaryArray); | |||
return { | |||
contentType: 'multipart/form-data; boundary=' + boundaryKey, | |||
buffer: new Uint8Array(postArray).buffer | |||
} | |||
} | |||
function randString() { | |||
var result = ''; | |||
var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' | |||
for (var i = 17; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)]; | |||
return result; | |||
} | |||
function formDataArray(boundary, name, value, fileName){ | |||
let dataString = ''; | |||
let isFile = !!fileName; | |||
dataString += boundary + '\r\n'; | |||
dataString += 'Content-Disposition: form-data; name="' + name + '"'; | |||
if (isFile){ | |||
dataString += '; filename="' + fileName + '"' + '\r\n'; | |||
dataString += 'Content-Type: ' + getFileMime(fileName) + '\r\n\r\n'; | |||
} | |||
else{ | |||
dataString += '\r\n\r\n'; | |||
dataString += value; | |||
} | |||
var dataArray = []; | |||
dataArray.push(...dataString.toUtf8Bytes()); | |||
if (isFile) { | |||
let fileArray = new Uint8Array(value); | |||
dataArray = dataArray.concat(Array.prototype.slice.call(fileArray)); | |||
} | |||
dataArray.push(..."\r".toUtf8Bytes()); | |||
dataArray.push(..."\n".toUtf8Bytes()); | |||
return dataArray; | |||
} | |||
function getFileMime(fileName){ | |||
let idx = fileName.lastIndexOf("."); | |||
let mime = mimeMap[fileName.substr(idx)]; | |||
return mime?mime:"application/octet-stream" | |||
} | |||
String.prototype.toUtf8Bytes = function(){ | |||
var str = this; | |||
var bytes = []; | |||
for (var i = 0; i < str.length; i++) { | |||
bytes.push(...str.utf8CodeAt(i)); | |||
if (str.codePointAt(i) > 0xffff) { | |||
i++; | |||
} | |||
} | |||
return bytes; | |||
} | |||
String.prototype.utf8CodeAt = function(i) { | |||
var str = this; | |||
var out = [], p = 0; | |||
var c = str.charCodeAt(i); | |||
if (c < 128) { | |||
out[p++] = c; | |||
} else if (c < 2048) { | |||
out[p++] = (c >> 6) | 192; | |||
out[p++] = (c & 63) | 128; | |||
} else if ( | |||
((c & 0xFC00) == 0xD800) && (i + 1) < str.length && | |||
((str.charCodeAt(i + 1) & 0xFC00) == 0xDC00)) { | |||
// Surrogate Pair | |||
c = 0x10000 + ((c & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF); | |||
out[p++] = (c >> 18) | 240; | |||
out[p++] = ((c >> 12) & 63) | 128; | |||
out[p++] = ((c >> 6) & 63) | 128; | |||
out[p++] = (c & 63) | 128; | |||
} else { | |||
out[p++] = (c >> 12) | 224; | |||
out[p++] = ((c >> 6) & 63) | 128; | |||
out[p++] = (c & 63) | 128; | |||
} | |||
return out; | |||
}; | |||
module.exports = FormData; | |||
@@ -0,0 +1,264 @@ | |||
import Vue from 'vue' | |||
const FormData = require('./formData.js') | |||
function formateDate(fmt = 'yyyy-mm-dd', date = '') { | |||
if (!date) { | |||
date = new Date() | |||
} | |||
try { | |||
if (typeof date == 'string') { | |||
date = date.replace(/-/g, '/').replace(/T/g, ' ') | |||
if (date.indexOf('/') == -1) { | |||
date = new Date(parseFloat(date)) | |||
} | |||
date = new Date(date) | |||
} else if (typeof date == 'number') { | |||
date = new Date(date) | |||
} | |||
} catch (error) { | |||
console.log('时间格式化出错', error) | |||
date = new Date() | |||
} | |||
let ret | |||
let weak = (function (date) { | |||
let days = date.getDay() | |||
let weekArrTxt = [ | |||
'星期天', | |||
'星期一', | |||
'星期二', | |||
'星期三', | |||
'星期四', | |||
'星期五', | |||
'星期六', | |||
] | |||
let weekArrTxt2 = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'] | |||
return [weekArrTxt[days], weekArrTxt2[days]] | |||
})(date) | |||
const opt = { | |||
'y+': date.getFullYear().toString(), // 年 | |||
'm+': (date.getMonth() + 1).toString(), // 月 | |||
'd+': date.getDate().toString(), // 日 | |||
'H+': date.getHours().toString(), // 时 | |||
'M+': date.getMinutes().toString(), // 分 | |||
'S+': date.getSeconds().toString(), // 秒 | |||
// 有其他格式化字符需求可以继续添加,必须转化成字符串 | |||
'W+': weak[0], | |||
'w+': weak[1], | |||
} | |||
for (let k in opt) { | |||
ret = new RegExp('(' + k + ')').exec(fmt) | |||
if (ret) { | |||
fmt = fmt.replace( | |||
ret[1], | |||
ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, '0') | |||
) | |||
} | |||
} | |||
return fmt | |||
} | |||
function getDateDiff(time = new Date()) { | |||
if (time == '') return '未知' | |||
// 当前时间 | |||
let now = new Date() | |||
let ny = formateDate('yyyy', now) | |||
let nm = formateDate('mm', now) | |||
let nd = formateDate('dd', now) | |||
let nH = formateDate('HH', now) | |||
let nM = formateDate('MM', now) | |||
let nS = formateDate('SS', now) | |||
let oDate = new Date(formateDate('yyyy/mm/dd HH:MM:SS', time)) | |||
let oy = formateDate('yyyy', oDate) | |||
let om = formateDate('mm', oDate) | |||
let od = formateDate('dd', oDate) | |||
let oH = formateDate('HH', oDate) | |||
let oM = formateDate('MM', oDate) | |||
let oS = formateDate('SS', oDate) | |||
// console.log(parseInt(nm), parseInt(om)); | |||
if ('' + ny + nm + nd + nH + nM == '' + oy + om + od + oH + oM) { | |||
//同分 | |||
return '刚刚' | |||
} else if ('' + ny + nm + nd + nH == '' + oy + om + od + oH) { | |||
//同时 | |||
return parseInt(nM) - parseInt(oM) + '分钟前' | |||
} else if ('' + ny + nm + nd == '' + oy + om + od) { | |||
//同天 | |||
return oH + ':' + oM | |||
} else if ('' + ny + nm == '' + oy + om) { | |||
//同月 | |||
return om + '-' + od + ' ' + oH + ':' + oM | |||
} else if ('' + ny == '' + oy) { | |||
//同年 | |||
return om + '-' + od + ' ' + oH + ':' + oM | |||
} else { | |||
return oy + '-' + om + '-' + od | |||
} | |||
} | |||
//检测url是否合法 | |||
function TestUrl(url) { | |||
let regex = new RegExp( | |||
'(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]' | |||
) | |||
if (regex.test(url)) { | |||
return true | |||
} else { | |||
return false | |||
} | |||
} | |||
var ThrottleObject = new Map() | |||
//节流器 程序名 执行函数 节流时间 | |||
function InitThrottle(name, event, time) { | |||
if (ThrottleObject.get(name)) clearTimeout(ThrottleObject.get(name)) //清除前程序 | |||
//执行方法 | |||
let obj = setTimeout(() => { | |||
ThrottleObject.delete(name) | |||
event() | |||
}, time) | |||
//存入栈 | |||
ThrottleObject.set(name, obj) | |||
} | |||
//页面数据持久化工具 , app 使用 页面名称 this对象 带 async 的回调函数 | |||
async function PersistencePages(name, vdom, callback) { | |||
// #ifndef APP-PLUS | |||
callback() | |||
// #endif | |||
// #ifdef APP-PLUS | |||
let key = 'Persistence_' + name | |||
let odata = await uni.getStorageSync(key) | |||
let net = await getNetWork() | |||
if (odata && !net) { | |||
//取 | |||
Object.keys(odata).forEach((item) => { | |||
vdom[item] = odata[item] | |||
}) | |||
} else if (net) { | |||
//存 | |||
//先执行页面数据获取 | |||
await callback() | |||
let data = {} | |||
Object.keys(vdom).forEach((item) => { | |||
if (item.indexOf('_') == -1 && item.indexOf('$') == -1) { | |||
//排除原生、全局参数 | |||
if (typeof vdom[item] != 'function') { | |||
//排除方法 | |||
data[item] = vdom[item] | |||
} | |||
} | |||
}) | |||
//缓存数据 | |||
uni.setStorageSync(key, data) | |||
} | |||
// #endif | |||
} | |||
async function getNetWork() { | |||
return new Promise((res, rej) => { | |||
uni.getNetworkType({ | |||
success: (re) => { | |||
if (re.networkType == 'none') { | |||
res(false) | |||
} else { | |||
res(true) | |||
} | |||
}, | |||
fail() { | |||
res(false) | |||
}, | |||
}) | |||
}) | |||
} | |||
// 文件tempUrl 转 上传参数 | |||
function tempUrlToUpload(tempUrl, fileName, other = {}) { | |||
let formData = new FormData() | |||
if (tempUrl) { | |||
formData.appendFile('File', tempUrl, fileName) | |||
} | |||
// 遍历增加额外参数 | |||
Object.keys(other).forEach((key) => { | |||
formData.append(key, other[`${key}`]) | |||
}) | |||
let data = formData.getData() | |||
return { | |||
data: data.buffer, | |||
header: { | |||
'content-type': data.contentType, | |||
}, | |||
} | |||
} | |||
// 列表追加key | |||
function listAddKey(list) { | |||
console.log(list) | |||
return list.map((item) => { | |||
return { | |||
...item, | |||
key: Vue.prototype.$u.guid(), | |||
} | |||
}) | |||
} | |||
function getColorForStr(str) { | |||
if (!str) { | |||
return '#ffffff' | |||
} | |||
// 姓名拼音首字母为基础生成背景色,过滤白色及相近色 | |||
// 定义26个颜色 | |||
const colors = [ | |||
'#000000', // 黑色 | |||
'#1C1C1C', // 深灰色 | |||
'#333333', // 较深灰色 | |||
'#400000', // 深红色 | |||
'#004000', // 深绿色 | |||
'#000040', // 深蓝色 | |||
'#590059', // 深紫红色 | |||
'#404000', // 深橄榄色 | |||
'#004040', // 深青色 | |||
'#660000', // 更深红色 | |||
'#006600', // 更浅绿色 | |||
'#000066', // 更深蓝色 | |||
'#7F0000', // 极深红色 | |||
'#007F00', // 极深绿色 | |||
'#00007F', // 极深蓝色 | |||
'#8B008B', // 深洋红色 | |||
'#990000', // 非常深红色 | |||
'#009900', // 非常深绿色 | |||
'#000099', // 非常深蓝色 | |||
'#A52A2A', // 褐红色 | |||
'#00A500', // 深草绿色 | |||
'#0000A5', // 深宝蓝色 | |||
'#B22222', // 耐火砖色 | |||
'#00B200', // 深翠绿色 | |||
'#0000B2', // 深海军蓝色 | |||
'#C71585', // 洋红色 | |||
] | |||
const index = str.charCodeAt(0) % 26 | |||
return colors[index] | |||
} | |||
const util = { | |||
formateDate, | |||
PersistencePages, | |||
getNetWork, | |||
getDateDiff, | |||
TestUrl, | |||
tempUrlToUpload, | |||
listAddKey, | |||
toMD5, | |||
getColorForStr, | |||
} | |||
export default util |
@@ -0,0 +1,345 @@ | |||
module.exports = { | |||
"0.001": "application/x-001", | |||
"0.323": "text/h323", | |||
"0.907": "drawing/907", | |||
".acp": "audio/x-mei-aac", | |||
".aif": "audio/aiff", | |||
".aiff": "audio/aiff", | |||
".asa": "text/asa", | |||
".asp": "text/asp", | |||
".au": "audio/basic", | |||
".awf": "application/vnd.adobe.workflow", | |||
".bmp": "application/x-bmp", | |||
".c4t": "application/x-c4t", | |||
".cal": "application/x-cals", | |||
".cdf": "application/x-netcdf", | |||
".cel": "application/x-cel", | |||
".cg4": "application/x-g4", | |||
".cit": "application/x-cit", | |||
".cml": "text/xml", | |||
".cmx": "application/x-cmx", | |||
".crl": "application/pkix-crl", | |||
".csi": "application/x-csi", | |||
".cut": "application/x-cut", | |||
".dbm": "application/x-dbm", | |||
".dcd": "text/xml", | |||
".der": "application/x-x509-ca-cert", | |||
".dib": "application/x-dib", | |||
".doc": "application/msword", | |||
".drw": "application/x-drw", | |||
".dwf": "Model/vnd.dwf", | |||
".dwg": "application/x-dwg", | |||
".dxf": "application/x-dxf", | |||
".emf": "application/x-emf", | |||
".ent": "text/xml", | |||
".eps": "application/x-ps", | |||
".etd": "application/x-ebx", | |||
".fax": "image/fax", | |||
".fif": "application/fractals", | |||
".frm": "application/x-frm", | |||
".gbr": "application/x-gbr", | |||
".gif": "image/gif", | |||
".gp4": "application/x-gp4", | |||
".hmr": "application/x-hmr", | |||
".hpl": "application/x-hpl", | |||
".hrf": "application/x-hrf", | |||
".htc": "text/x-component", | |||
".html": "text/html", | |||
".htx": "text/html", | |||
".ico": "image/x-icon", | |||
".iff": "application/x-iff", | |||
".igs": "application/x-igs", | |||
".img": "application/x-img", | |||
".isp": "application/x-internet-signup", | |||
".java": "java/*", | |||
".jpe": "image/jpeg", | |||
".jpeg": "image/jpeg", | |||
".jpg": "application/x-jpg", | |||
".jsp": "text/html", | |||
".lar": "application/x-laplayer-reg", | |||
".lavs": "audio/x-liquid-secure", | |||
".lmsff": "audio/x-la-lms", | |||
".ltr": "application/x-ltr", | |||
".m2v": "video/x-mpeg", | |||
".m4e": "video/mpeg4", | |||
".man": "application/x-troff-man", | |||
".mdb": "application/msaccess", | |||
".mfp": "application/x-shockwave-flash", | |||
".mhtml": "message/rfc822", | |||
".mid": "audio/mid", | |||
".mil": "application/x-mil", | |||
".mnd": "audio/x-musicnet-download", | |||
".mocha": "application/x-javascript", | |||
".mp1": "audio/mp1", | |||
".mp2v": "video/mpeg", | |||
".mp4": "video/mpeg4", | |||
".mpd": "application/vnd.ms-project", | |||
".mpeg": "video/mpg", | |||
".mpga": "audio/rn-mpeg", | |||
".mps": "video/x-mpeg", | |||
".mpv": "video/mpg", | |||
".mpw": "application/vnd.ms-project", | |||
".mtx": "text/xml", | |||
".net": "image/pnetvue", | |||
".nws": "message/rfc822", | |||
".out": "application/x-out", | |||
".p12": "application/x-pkcs12", | |||
".p7c": "application/pkcs7-mime", | |||
".p7r": "application/x-pkcs7-certreqresp", | |||
".pc5": "application/x-pc5", | |||
".pcl": "application/x-pcl", | |||
".pdf": "application/pdf", | |||
".pdx": "application/vnd.adobe.pdx", | |||
".pgl": "application/x-pgl", | |||
".pko": "application/vnd.ms-pki.pko", | |||
".plg": "text/html", | |||
".plt": "application/x-plt", | |||
".png": "application/x-png", | |||
".ppa": "application/vnd.ms-powerpoint", | |||
".pps": "application/vnd.ms-powerpoint", | |||
".ppt": "application/x-ppt", | |||
".prf": "application/pics-rules", | |||
".prt": "application/x-prt", | |||
".ps": "application/postscript", | |||
".pwz": "application/vnd.ms-powerpoint", | |||
".ra": "audio/vnd.rn-realaudio", | |||
".ras": "application/x-ras", | |||
".rdf": "text/xml", | |||
".red": "application/x-red", | |||
".rjs": "application/vnd.rn-realsystem-rjs", | |||
".rlc": "application/x-rlc", | |||
".rm": "application/vnd.rn-realmedia", | |||
".rmi": "audio/mid", | |||
".rmm": "audio/x-pn-realaudio", | |||
".rms": "application/vnd.rn-realmedia-secure", | |||
".rmx": "application/vnd.rn-realsystem-rmx", | |||
".rp": "image/vnd.rn-realpix", | |||
".rsml": "application/vnd.rn-rsml", | |||
".rtf": "application/msword", | |||
".rv": "video/vnd.rn-realvideo", | |||
".sat": "application/x-sat", | |||
".sdw": "application/x-sdw", | |||
".slb": "application/x-slb", | |||
".slk": "drawing/x-slk", | |||
".smil": "application/smil", | |||
".snd": "audio/basic", | |||
".sor": "text/plain", | |||
".spl": "application/futuresplash", | |||
".ssm": "application/streamingmedia", | |||
".stl": "application/vnd.ms-pki.stl", | |||
".sty": "application/x-sty", | |||
".swf": "application/x-shockwave-flash", | |||
".tg4": "application/x-tg4", | |||
".tif": "image/tiff", | |||
".tiff": "image/tiff", | |||
".top": "drawing/x-top", | |||
".tsd": "text/xml", | |||
".uin": "application/x-icq", | |||
".vcf": "text/x-vcard", | |||
".vdx": "application/vnd.visio", | |||
".vpg": "application/x-vpeg005", | |||
".vsd": "application/x-vsd", | |||
".vst": "application/vnd.visio", | |||
".vsw": "application/vnd.visio", | |||
".vtx": "application/vnd.visio", | |||
".wav": "audio/wav", | |||
".wb1": "application/x-wb1", | |||
".wb3": "application/x-wb3", | |||
".wiz": "application/msword", | |||
".wk4": "application/x-wk4", | |||
".wks": "application/x-wks", | |||
".wma": "audio/x-ms-wma", | |||
".wmf": "application/x-wmf", | |||
".wmv": "video/x-ms-wmv", | |||
".wmz": "application/x-ms-wmz", | |||
".wpd": "application/x-wpd", | |||
".wpl": "application/vnd.ms-wpl", | |||
".wr1": "application/x-wr1", | |||
".wrk": "application/x-wrk", | |||
".ws2": "application/x-ws", | |||
".wsdl": "text/xml", | |||
".xdp": "application/vnd.adobe.xdp", | |||
".xfd": "application/vnd.adobe.xfd", | |||
".xhtml": "text/html", | |||
".xls": "application/x-xls", | |||
".xml": "text/xml", | |||
".xq": "text/xml", | |||
".xquery": "text/xml", | |||
".xsl": "text/xml", | |||
".xwd": "application/x-xwd", | |||
".sis": "application/vnd.symbian.install", | |||
".x_t": "application/x-x_t", | |||
".apk": "application/vnd.android.package-archive", | |||
"0.301": "application/x-301", | |||
"0.906": "application/x-906", | |||
".a11": "application/x-a11", | |||
".ai": "application/postscript", | |||
".aifc": "audio/aiff", | |||
".anv": "application/x-anv", | |||
".asf": "video/x-ms-asf", | |||
".asx": "video/x-ms-asf", | |||
".avi": "video/avi", | |||
".biz": "text/xml", | |||
".bot": "application/x-bot", | |||
".c90": "application/x-c90", | |||
".cat": "application/vnd.ms-pki.seccat", | |||
".cdr": "application/x-cdr", | |||
".cer": "application/x-x509-ca-cert", | |||
".cgm": "application/x-cgm", | |||
".class": "java/*", | |||
".cmp": "application/x-cmp", | |||
".cot": "application/x-cot", | |||
".crt": "application/x-x509-ca-cert", | |||
".css": "text/css", | |||
".dbf": "application/x-dbf", | |||
".dbx": "application/x-dbx", | |||
".dcx": "application/x-dcx", | |||
".dgn": "application/x-dgn", | |||
".dll": "application/x-msdownload", | |||
".dot": "application/msword", | |||
".dtd": "text/xml", | |||
".dwf": "application/x-dwf", | |||
".dxb": "application/x-dxb", | |||
".edn": "application/vnd.adobe.edn", | |||
".eml": "message/rfc822", | |||
".epi": "application/x-epi", | |||
".eps": "application/postscript", | |||
".exe": "application/x-msdownload", | |||
".fdf": "application/vnd.fdf", | |||
".fo": "text/xml", | |||
".g4": "application/x-g4", | |||
".tif": "image/tiff", | |||
".gl2": "application/x-gl2", | |||
".hgl": "application/x-hgl", | |||
".hpg": "application/x-hpgl", | |||
".hqx": "application/mac-binhex40", | |||
".hta": "application/hta", | |||
".htm": "text/html", | |||
".htt": "text/webviewhtml", | |||
".icb": "application/x-icb", | |||
".ico": "application/x-ico", | |||
".ig4": "application/x-g4", | |||
".iii": "application/x-iphone", | |||
".ins": "application/x-internet-signup", | |||
".IVF": "video/x-ivf", | |||
".jfif": "image/jpeg", | |||
".jpe": "application/x-jpe", | |||
".jpg": "image/jpeg", | |||
".js": "application/x-javascript", | |||
".la1": "audio/x-liquid-file", | |||
".latex": "application/x-latex", | |||
".lbm": "application/x-lbm", | |||
".ls": "application/x-javascript", | |||
".m1v": "video/x-mpeg", | |||
".m3u": "audio/mpegurl", | |||
".mac": "application/x-mac", | |||
".math": "text/xml", | |||
".mdb": "application/x-mdb", | |||
".mht": "message/rfc822", | |||
".mi": "application/x-mi", | |||
".midi": "audio/mid", | |||
".mml": "text/xml", | |||
".mns": "audio/x-musicnet-stream", | |||
".movie": "video/x-sgi-movie", | |||
".mp2": "audio/mp2", | |||
".mp3": "audio/mp3", | |||
".mpa": "video/x-mpg", | |||
".mpe": "video/x-mpeg", | |||
".mpg": "video/mpg", | |||
".mpp": "application/vnd.ms-project", | |||
".mpt": "application/vnd.ms-project", | |||
".mpv2": "video/mpeg", | |||
".mpx": "application/vnd.ms-project", | |||
".mxp": "application/x-mmxp", | |||
".nrf": "application/x-nrf", | |||
".odc": "text/x-ms-odc", | |||
".p10": "application/pkcs10", | |||
".p7b": "application/x-pkcs7-certificates", | |||
".p7m": "application/pkcs7-mime", | |||
".p7s": "application/pkcs7-signature", | |||
".pci": "application/x-pci", | |||
".pcx": "application/x-pcx", | |||
".pdf": "application/pdf", | |||
".pfx": "application/x-pkcs12", | |||
".pic": "application/x-pic", | |||
".pl": "application/x-perl", | |||
".pls": "audio/scpls", | |||
".png": "image/png", | |||
".pot": "application/vnd.ms-powerpoint", | |||
".ppm": "application/x-ppm", | |||
".ppt": "application/vnd.ms-powerpoint", | |||
".pr": "application/x-pr", | |||
".prn": "application/x-prn", | |||
".ps": "application/x-ps", | |||
".ptn": "application/x-ptn", | |||
".r3t": "text/vnd.rn-realtext3d", | |||
".ram": "audio/x-pn-realaudio", | |||
".rat": "application/rat-file", | |||
".rec": "application/vnd.rn-recording", | |||
".rgb": "application/x-rgb", | |||
".rjt": "application/vnd.rn-realsystem-rjt", | |||
".rle": "application/x-rle", | |||
".rmf": "application/vnd.adobe.rmf", | |||
".rmj": "application/vnd.rn-realsystem-rmj", | |||
".rmp": "application/vnd.rn-rn_music_package", | |||
".rmvb": "application/vnd.rn-realmedia-vbr", | |||
".rnx": "application/vnd.rn-realplayer", | |||
".rpm": "audio/x-pn-realaudio-plugin", | |||
".rt": "text/vnd.rn-realtext", | |||
".rtf": "application/x-rtf", | |||
".sam": "application/x-sam", | |||
".sdp": "application/sdp", | |||
".sit": "application/x-stuffit", | |||
".sld": "application/x-sld", | |||
".smi": "application/smil", | |||
".smk": "application/x-smk", | |||
".sol": "text/plain", | |||
".spc": "application/x-pkcs7-certificates", | |||
".spp": "text/xml", | |||
".sst": "application/vnd.ms-pki.certstore", | |||
".stm": "text/html", | |||
".svg": "text/xml", | |||
".tdf": "application/x-tdf", | |||
".tga": "application/x-tga", | |||
".tif": "application/x-tif", | |||
".tld": "text/xml", | |||
".torrent": "application/x-bittorrent", | |||
".txt": "text/plain", | |||
".uls": "text/iuls", | |||
".vda": "application/x-vda", | |||
".vml": "text/xml", | |||
".vsd": "application/vnd.visio", | |||
".vss": "application/vnd.visio", | |||
".vst": "application/x-vst", | |||
".vsx": "application/vnd.visio", | |||
".vxml": "text/xml", | |||
".wax": "audio/x-ms-wax", | |||
".wb2": "application/x-wb2", | |||
".wbmp": "image/vnd.wap.wbmp", | |||
".wk3": "application/x-wk3", | |||
".wkq": "application/x-wkq", | |||
".wm": "video/x-ms-wm", | |||
".wmd": "application/x-ms-wmd", | |||
".wml": "text/vnd.wap.wml", | |||
".wmx": "video/x-ms-wmx", | |||
".wp6": "application/x-wp6", | |||
".wpg": "application/x-wpg", | |||
".wq1": "application/x-wq1", | |||
".wri": "application/x-wri", | |||
".ws": "application/x-ws", | |||
".wsc": "text/scriptlet", | |||
".wvx": "video/x-ms-wvx", | |||
".xdr": "text/xml", | |||
".xfdf": "application/vnd.adobe.xfdf", | |||
".xls": "application/vnd.ms-excel", | |||
".xlw": "application/x-xlw", | |||
".xpl": "audio/scpls", | |||
".xql": "text/xml", | |||
".xsd": "text/xml", | |||
".xslt": "text/xml", | |||
".x_b": "application/x-x_b", | |||
".sisx": "application/vnd.symbian.install", | |||
".ipa": "application/vnd.iphone", | |||
".xap": "application/x-silverlight-app", | |||
".zip": "application/x-zip-compressed", | |||
} |
@@ -1,126 +0,0 @@ | |||
import { mergeConfig, dispatchRequest, jsonpRequest} from "./utils.js"; | |||
export default class request { | |||
constructor(options) { | |||
//请求公共地址 | |||
this.baseUrl = options.baseUrl || ""; | |||
// 超时时间 | |||
this.timeout = options.timeout || 10000; | |||
//默认请求头 | |||
this.header = options.header || {}; | |||
//默认配置 | |||
this.config = options.config || { | |||
isPrompt: true, | |||
load: true, | |||
isFactory: true | |||
}; | |||
} | |||
//post请求 | |||
post(url = '', data = {}, options = {}) { | |||
return this.request({ | |||
method: "POST", | |||
data: data, | |||
url: url, | |||
...options | |||
}); | |||
} | |||
//get请求 | |||
get(url = '', data = {}, options = {}) { | |||
return this.request({ | |||
method: "GET", | |||
data: data, | |||
url: url, | |||
...options | |||
}); | |||
} | |||
//put请求 | |||
put(url = '', data = {}, options = {}) { | |||
return this.request({ | |||
method: "PUT", | |||
data: data, | |||
url: url, | |||
...options | |||
}); | |||
} | |||
//delete请求 | |||
delete(url = '', data = {}, options = {}) { | |||
return this.request({ | |||
method: "DELETE", | |||
data: data, | |||
url: url, | |||
...options | |||
}); | |||
} | |||
//jsonp请求(只限于H5使用) | |||
jsonp(url = '', data = {}, options = {}) { | |||
return this.request({ | |||
method: "JSONP", | |||
data: data, | |||
url: url, | |||
...options | |||
}); | |||
} | |||
//接口请求方法 | |||
async request(data) { | |||
// 请求数据 | |||
let requestInfo, | |||
// 是否运行过请求开始钩子 | |||
runRequestStart = false; | |||
try { | |||
if (!data.url) { | |||
throw { errMsg: "【request】缺失数据url", statusCode: 0} | |||
} | |||
// 数据合并 | |||
requestInfo = mergeConfig(this, data); | |||
// 代表之前运行到这里 | |||
runRequestStart = true; | |||
//请求前回调 | |||
if (this.requestStart) { | |||
let requestStart = this.requestStart(requestInfo); | |||
if (typeof requestStart == "object") { | |||
let changekeys = ["data", "header", "isPrompt", "load", "isFactory"]; | |||
changekeys.forEach(key => { | |||
requestInfo[key] = requestStart[key]; | |||
}); | |||
} else { | |||
throw { | |||
errMsg: "【request】请求开始拦截器未通过", | |||
statusCode: 0, | |||
data: requestInfo.data, | |||
method: requestInfo.method, | |||
header: requestInfo.header, | |||
url: requestInfo.url, | |||
} | |||
} | |||
} | |||
let requestResult = {}; | |||
if(requestInfo.method == "JSONP"){ | |||
requestResult = await jsonpRequest(requestInfo); | |||
} else { | |||
requestResult = await dispatchRequest(requestInfo); | |||
} | |||
//是否用外部的数据处理方法 | |||
if (requestInfo.isFactory && this.dataFactory) { | |||
//数据处理 | |||
let result = await this.dataFactory({ | |||
...requestInfo, | |||
response: requestResult | |||
}); | |||
return Promise.resolve(result); | |||
} else { | |||
return Promise.resolve(requestResult); | |||
} | |||
} catch (err){ | |||
this.requestError && this.requestError(err); | |||
return Promise.reject(err); | |||
} finally { | |||
// 如果请求开始未运行到,请求结束也不运行 | |||
if(runRequestStart){ | |||
this.requestEnd && this.requestEnd(requestInfo); | |||
} | |||
} | |||
} | |||
} |
@@ -1,101 +0,0 @@ | |||
// 获取合并的数据 | |||
export const mergeConfig = function(_this, options) { | |||
//判断url是不是链接 | |||
let urlType = /^(http|https):\/\//.test(options.url); | |||
let config = Object.assign({ | |||
timeout: _this.timeout | |||
}, _this.config, options); | |||
if (options.method == "FILE") { | |||
config.url = urlType ? options.url : _this.fileUrl + options.url; | |||
} else { | |||
config.url = urlType ? options.url : _this.baseUrl + options.url; | |||
} | |||
//请求头 | |||
if (options.header) { | |||
config.header = Object.assign({}, _this.header, options.header); | |||
} else { | |||
config.header = Object.assign({}, _this.header); | |||
} | |||
return config; | |||
} | |||
// 请求 | |||
export const dispatchRequest = function(requestInfo) { | |||
return new Promise((resolve, reject) => { | |||
let requestAbort = true; | |||
let requestData = { | |||
url: requestInfo.url, | |||
header: requestInfo.header, //加入请求头 | |||
success: (res) => { | |||
requestAbort = false; | |||
resolve(res); | |||
}, | |||
fail: (err) => { | |||
requestAbort = false; | |||
if(err.errMsg == "request:fail abort"){ | |||
reject({ | |||
errMsg: "请求超时,请重新尝试", | |||
statusCode: 0, | |||
}); | |||
} else { | |||
reject(err); | |||
} | |||
} | |||
}; | |||
//请求类型 | |||
if (requestInfo.method) { | |||
requestData.method = requestInfo.method; | |||
} | |||
if (requestInfo.data) { | |||
requestData.data = requestInfo.data; | |||
} | |||
// #ifdef MP-WEIXIN || MP-ALIPAY | |||
if (requestInfo.timeout) { | |||
requestData.timeout = requestInfo.timeout; | |||
} | |||
// #endif | |||
if (requestInfo.dataType) { | |||
requestData.dataType = requestInfo.dataType; | |||
} | |||
// #ifndef APP-PLUS || MP-ALIPAY | |||
if (requestInfo.responseType) { | |||
requestData.responseType = requestInfo.responseType; | |||
} | |||
// #endif | |||
// #ifdef H5 | |||
if (requestInfo.withCredentials) { | |||
requestData.withCredentials = requestInfo.withCredentials; | |||
} | |||
// #endif | |||
let requestTask = uni.request(requestData); | |||
setTimeout(() => { | |||
if(requestAbort){ | |||
requestTask.abort(); | |||
} | |||
}, requestInfo.timeout) | |||
}) | |||
} | |||
// jsonp请求 | |||
export const jsonpRequest = function(requestInfo) { | |||
return new Promise((resolve, reject) => { | |||
let dataStr = ''; | |||
Object.keys(requestInfo.data).forEach(key => { | |||
dataStr += key + '=' + requestInfo.data[key] + '&'; | |||
}); | |||
//匹配最后一个&并去除 | |||
if (dataStr !== '') { | |||
dataStr = dataStr.substr(0, dataStr.lastIndexOf('&')); | |||
} | |||
requestInfo.url = requestInfo.url + '?' + dataStr; | |||
let callbackName = "callback" + Math.ceil(Math.random() * 1000000); | |||
// #ifdef H5 | |||
window[callbackName] = function(data) { | |||
resolve(data); | |||
} | |||
let script = document.createElement("script"); | |||
script.src = requestInfo.url + "&callback=" + callbackName; | |||
document.head.appendChild(script); | |||
// 及时删除,防止加载过多的JS | |||
document.head.removeChild(script); | |||
// #endif | |||
}); | |||
} |
@@ -1,146 +0,0 @@ | |||
import request from "./core/request.js" | |||
import { | |||
getToken, | |||
removeToken | |||
} from "@/utils/auth.js" | |||
// TODO: 设置基础接口地址,可根据小程序体验版和线上版本区分 | |||
let baseUrl = "http://127.0.0.1"; | |||
//可以new多个request来支持多个域名请求 | |||
let $http = new request({ | |||
//接口请求地址 | |||
baseUrl: baseUrl, | |||
//设置请求头(如果使用报错跨域问题,可能是content-type请求类型和后台那边设置的不一致) | |||
header: { | |||
'content-type': 'application/json;charset=UTF-8' | |||
}, | |||
// 请求超时时间(默认6000) | |||
timeout: 10000, | |||
// 默认配置(可不写) | |||
config: { | |||
// 是否自动提示错误 | |||
isPrompt: true, | |||
// 是否显示加载动画 | |||
load: true, | |||
// 是否使用数据工厂 | |||
isFactory: true | |||
} | |||
}); | |||
//当前接口请求数 | |||
let requestNum = 0; | |||
// 当前失败接口数 | |||
let requestFailNum = 0; | |||
//请求开始拦截器 | |||
$http.requestStart = function(options) { | |||
if (options.load) { | |||
if (requestNum <= 0) { | |||
//打开加载动画 | |||
uni.showLoading({ | |||
title: '加载中', | |||
mask: true | |||
}); | |||
} | |||
requestNum += 1; | |||
} | |||
//请求前加入token,从缓存中读取token,请在登录后将token存储在本地缓存中 | |||
options.header['token'] = getToken(); | |||
return options; | |||
} | |||
//请求结束 | |||
$http.requestEnd = function(options) { | |||
//判断当前接口是否需要加载动画 | |||
if (options.load) { | |||
requestNum = requestNum - 1; | |||
if (requestNum <= 0) { | |||
uni.hideLoading(); | |||
} | |||
} | |||
} | |||
//所有接口数据处理(可在接口里设置不调用此方法) | |||
//此方法需要开发者根据各自的接口返回类型修改,以下只是模板 | |||
$http.dataFactory = async function(res) { | |||
if (res.response.statusCode && res.response.statusCode == 200) { | |||
let httpData = res.response.data; | |||
if (typeof(httpData) == "string") { | |||
httpData = JSON.parse(httpData); | |||
} | |||
/*********以下只是模板(及共参考),需要开发者根据各自的接口返回类型修改*********/ | |||
// TODO: 判断数据是否请求成功,根据后端返回的成功状态码修改 | |||
if (httpData.code == 200) { | |||
// 返回正确的结果(then接受数据) | |||
return Promise.resolve(httpData); | |||
} else { //其他错误提示 | |||
if (res.isPrompt) { | |||
// 自动提示错误 | |||
uni.showToast({ | |||
title: httpData.info || httpData.msg, | |||
icon: "none", | |||
duration: 3000 | |||
}); | |||
} | |||
// 返回错误的结果(catch接受数据) | |||
return Promise.reject({ | |||
statusCode: 500, | |||
errMsg: httpData.info || httpData.msg | |||
}); | |||
} | |||
/*********以上只是模板(及共参考),需要开发者根据各自的接口返回类型修改*********/ | |||
} else if (res.response.statusCode && res.response.statusCode == 401) { | |||
// 用户身份信息过期处理,清除token并返回登录页 | |||
if(requestFailNum <= 0) { | |||
removeToken(); | |||
uni.showModal({ | |||
title: '温馨提示', | |||
content: '登录状态过期,请重新登录!', | |||
confirmText: "确认", | |||
showCancel: false, | |||
success: function(result) { | |||
uni.reLaunch({ | |||
url: '/pages/login/index' | |||
}); | |||
} | |||
}); | |||
} | |||
requestFailNum++; | |||
return Promise.reject({ | |||
statusCode: res.response.statusCode, | |||
errMsg: "登录状态过期" | |||
}); | |||
} else if (res.response.statusCode && res.response.statusCode == 404) { | |||
// 接口地址不存在 | |||
return Promise.reject({ | |||
statusCode: res.response.statusCode, | |||
errMsg: "请求失败,请检查接口地址是否正确" | |||
}); | |||
} else { | |||
// 返回错误的结果(catch接受数据) | |||
return Promise.reject({ | |||
statusCode: res.response.statusCode, | |||
errMsg: "数据工厂验证不通过" | |||
}); | |||
} | |||
}; | |||
// 错误回调 | |||
$http.requestError = function(e) { | |||
if(!e.errMsg) { | |||
return; | |||
} | |||
// e.statusCode === 0 是参数校验错误抛出的 | |||
if (e.statusCode === 0 || e.statusCode === 401) { | |||
throw e; | |||
} else { | |||
// 解决hideLoading会隐藏Toast的bug,setTimeout让showToast在requestEnd回调之后再执行 | |||
setTimeout(() => { | |||
if(e.errMsg == "request:fail") { | |||
e.errMsg = "请求失败,请检查接口地址是否正确!" | |||
} | |||
uni.showToast({ | |||
title: e.errMsg || "网络错误,请检查一下网络", | |||
icon: "none", | |||
duration: 3000 | |||
}); | |||
}) | |||
} | |||
} | |||
export default $http; |