/* * @Date: 2021-11-27 15:27:19 * @LastEditors: wanglj * @LastEditTime: 2024-03-13 16:34:10 * @FilePath: \labsop_backup\frontend\packages\base\src\utils\micro_request.js * @Description: file content */ import { Local, Session } from '@/utils/storage'; import { CACHE_KEY } from '@/constants'; const errorCode = { '401': '认证失败,无法访问系统资源', '403': '当前操作没有权限', '404': '访问资源不存在', 'default': '系统未知错误,请反馈给管理员' }; const baseURL = import.meta.env.VITE_API_URL || ''; function request(options) { // 拼接请求路径 let url = options.url || ''; if (!/^\/?http/.test(url)) { url = baseURL + url; } // 头部处理 let header = Object.assign({}, options.headers, options.header); header['Content-Type'] = header['Content-Type'] || 'application/json;charset=utf-8'; if (import.meta.env.VITE_TENANT) { header['Tenant'] = import.meta.env.VITE_TENANT; } // 是否需要设置 token const isToken = header.isToken === false; const token = Local.get(CACHE_KEY.TOKEN); if (token && !isToken) { header['Authorization'] = 'Bearer ' + token; } // uni.request 只有在 Content-Type 为 application/json 时才自动对对象执行 JSON.stringify // 对于 application/rpcx,需要手动序列化,否则会被 toString() 处理成 [object Object] let requestData = options.data; if (typeof requestData === 'object' && requestData !== null && header['Content-Type'] === 'application/rpcx') { requestData = JSON.stringify(requestData); } return new Promise((resolve, reject) => { uni.request({ url: url, method: (options.method || 'GET').toUpperCase(), data: requestData, header: header, timeout: options.timeout || 60000, responseType: options.responseType || 'text', success: (res) => { // 文件流处理 if (options.responseType === 'arraybuffer' || res.header?.['content-type']?.includes('application/octet-stream')) { downLoadBlobFile(res, options); resolve(res.data); return; } processResponse(res, resolve, reject); }, fail: (err) => { console.log('err: ', err); uni.showToast({ title: err.errMsg || '网络环境异常,请稍后重试', icon: 'none', duration: 3000 }); reject(err); } }); }); } function processResponse(res, resolve, reject) { const data = res.data || {}; // 未设置状态码则默认成功状态 const code = data.code || res.statusCode || 200; // 获取错误信息 const message = errorCode[code] || data.message || data.msg || errorCode['default']; if (code === 401) { uni.showModal({ title: '系统提示', content: '登录状态已过期,您可以继续留在该页面,或者重新登录', confirmText: '重新登录', cancelText: '取消', success: function (modalRes) { if (modalRes.confirm) { // 清除缓存/token等 Session.clear(); Local.remove(CACHE_KEY.TOKEN); // 重新定向到登录页 uni.reLaunch({ url: '/pages/login/index' }); } } }); reject(new Error(message)); } else if (code === 500) { uni.showToast({ title: message, icon: 'none', duration: 2000 }); reject(new Error(message)); } else if (code !== 200) { uni.showToast({ title: message, icon: 'none', duration: 2000 }); reject(new Error(message)); } else { // 返回真实的业务数据,此处直接返回 data(也可根据业务需要只回 data.data) resolve(data); } } function downLoadBlobFile(res, options) { let mimeType = options.mimeType || 'application/vnd.ms-excel'; let fileName = 'data.xlsx'; // 尝试从header中获取文件名 const header = res.header || {}; let contentDisposition = header['content-disposition'] || header['Content-Disposition']; if (contentDisposition) { let patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*'); let result = patt.exec(decodeURI(contentDisposition)); if (result && result.length > 1) { fileName = result[1]; fileName = decodeURI(escape(fileName)); fileName = fileName.replace(/\"/g, ''); } } // #ifdef H5 const blob = new Blob([res.data], { type: mimeType }); const aLink = document.createElement('a'); aLink.href = URL.createObjectURL(blob); aLink.setAttribute('download', fileName); document.body.appendChild(aLink); aLink.click(); document.body.removeChild(aLink); // #endif // #ifndef H5 // 非H5平台(小程序、APP等)需要使用原生的文件保存及打开API const fs = uni.getFileSystemManager ? uni.getFileSystemManager() : null; if (fs && res.data) { const filePath = `${uni.env.USER_DATA_PATH}/${fileName}`; fs.writeFile({ filePath: filePath, data: res.data, encoding: 'binary', success: () => { uni.openDocument({ filePath: filePath, showMenu: true, success: function () { console.log('打开文档成功'); } }); }, fail: (err) => { uni.showToast({ title: '保存文件失败', icon: 'none' }); } }); } else { uni.showToast({ title: '文件已下载,但当前平台暂不支持直接打开', icon: 'none', duration: 3000 }); } // #endif } request.postRequest = function postRequest(basePath, srvName, funcName, data) { if (data == undefined) { data = { nullparam: 0 }; } return request({ url: basePath, method: 'post', headers: { 'Content-Type': 'application/rpcx', 'X-RPCX-SerializeType': '1', 'X-RPCX-ServicePath': srvName, 'X-RPCX-ServiceMethod': funcName, Srvenv: 'dev', }, data: data, }); }; // 发出请求并要求把客户端信息传输给后端(IP和User-Agent) request.postRequestWithClientInfo = function postRequestWithClientInfo(basePath, srvName, funcName, data) { if (data == undefined) { data = { nullparam: 0 }; } return request({ url: basePath, method: 'post', headers: { 'Content-Type': 'application/rpcx', 'X-RPCX-SerializeType': '1', 'X-RPCX-ServicePath': srvName, 'X-RPCX-Meta': 'need_clint_Info=1', Srvenv: import.meta.env.VITE_SRV_ENV || 'dev', }, data: data, }); }; // Excel文件下载(服务端生成文件流) request.downloadExcel = function downloadExcel(basePath, srvName, funcName, data) { if (data == undefined) { data = { nullparam: 0 }; } let base_Path = ''; // 使用 import.meta.env 替换 process.env if (basePath == import.meta.env.VITE_APP_FOSHAN_PATH) { base_Path = (import.meta.env.VITE_APP_MicroSrvProxy_foshan_API || '') + basePath; } else if (basePath == import.meta.env.VITE_APP_AdminPath) { base_Path = (import.meta.env.VITE_APP_MicroSrvProxy_API || '') + basePath; } else { base_Path = basePath; } return request({ url: base_Path, method: 'post', responseType: 'arraybuffer', // uniapp中使用 arraybuffer 替代 blob下载文件 headers: { 'Content-Type': 'application/rpcx', 'X-RPCX-SerializeType': '1', 'X-RPCX-ServicePath': srvName, 'X-RPCX-ServiceMethod': funcName, Srvenv: 'dev', }, data: data, }); }; export default request;