diff --git a/api/login.js b/api/login.js index 39a87c7..6c14f86 100644 --- a/api/login.js +++ b/api/login.js @@ -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) -} \ No newline at end of file +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, +}; diff --git a/main.js b/main.js index 6334c26..23cdcbc 100644 --- a/main.js +++ b/main.js @@ -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 = () => { diff --git a/uni.promisify.adaptor.js b/uni.promisify.adaptor.js new file mode 100644 index 0000000..47fbce1 --- /dev/null +++ b/uni.promisify.adaptor.js @@ -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])); + }); + }, +}); \ No newline at end of file diff --git a/utils/formData.js b/utils/formData.js new file mode 100644 index 0000000..4404199 --- /dev/null +++ b/utils/formData.js @@ -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; + diff --git a/utils/index.js b/utils/index.js new file mode 100644 index 0000000..7f50546 --- /dev/null +++ b/utils/index.js @@ -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 diff --git a/utils/mimeMap.js b/utils/mimeMap.js new file mode 100644 index 0000000..fea9b28 --- /dev/null +++ b/utils/mimeMap.js @@ -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", +} \ No newline at end of file diff --git a/utils/request/core/request.js b/utils/request/core/request.js deleted file mode 100644 index f6b5776..0000000 --- a/utils/request/core/request.js +++ /dev/null @@ -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); - } - } - } -} diff --git a/utils/request/core/utils.js b/utils/request/core/utils.js deleted file mode 100644 index 65e4a70..0000000 --- a/utils/request/core/utils.js +++ /dev/null @@ -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 - }); -} \ No newline at end of file diff --git a/utils/request/index.js b/utils/request/index.js deleted file mode 100644 index 0afc4fc..0000000 --- a/utils/request/index.js +++ /dev/null @@ -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; \ No newline at end of file