// import InnerApp from "./InnerApp.js"; import { deepClone } from "../uni_modules/uv-ui-tools/libs/function/index.js"; import CryptoJS from "crypto-js"; // import pageData from "@/static/json/page.json" async function apiUserEvent(type, adminData, uniData) { let orderData = uni.getStorageSync("UserEventOrder") let uni_version = uni.getStorageSync("uni_version") let AppUser = uni.getStorageSync('AppUser') if (type != 'uni') { await postJson('a', 'api/user/event', { type: adminData.type, key: adminData.type + ".uni." + adminData.key, value: adminData.value, extra: JSON.stringify({ uni_version: uni_version, ...adminData.extra }), }) } if (type != 'admin') { // 公共 let ggData = { app_id: AppUser.app_id, user_name: AppUser.name, //宿主用户id uni_version: uni_version, //uni版本号 app_version: plus.runtime.version, //宿主版本号 } uni.report(uniData.type, { ...ggData, ...uniData.data, ...orderData }) } } // 辅助函数:参数编码 function encodeParam(data) { let params = deepClone(data); let url = ''; let keys = Object.keys(params); keys.forEach(res => { if ((params[res] && params[res] != "") || params[res] === 0) { if (typeof (params[res]) != 'string' && typeof (params[res]) != 'number') { params[res] = 'Object'; } url += "&"; url += res; url += "="; url += encodeURIComponent(params[res]); } }); url = url ? url.substring(1) : ''; return url; } // 辅助函数:参数解码 function decodeParam(zipStr) { var route = ''; for (var i = 0; i < zipStr.length; i += 1) { var chr = zipStr.charAt(i); if (chr === '+') { route += ' '; } else if (chr === '%') { var asc = zipStr.substring(i + 1, i + 3); if (parseInt('0x' + asc) > 0x7f) { route += decodeURI('%' + asc.toString() + zipStr.substring(i + 3, i + 9).toString()); i += 8; } else { route += String.fromCharCode(parseInt('0x' + asc)); i += 2; } } else { route += chr; } } let data = route.split('?'); let params = {}; let data2; try { if (data.length >= 2) { data2 = data[1].split('&'); } else if (data.length == 1) { data2 = data[0].split('&'); } else { return {}; } } catch (e) { return {}; } data2.forEach(res => { let parts = res.split('='); if (parts.length >= 2) { params[parts[0]] = decodeURIComponent(parts.slice(1).join('=')); } }); return params; } // AES解密函数 const deCode = (str) => { try { var key = CryptoJS.enc.Utf8.parse(uni.getStorageSync('decrypt')); let iv = key.clone(); iv.sigBytes = 16; iv.clamp(); let res = CryptoJS.AES.decrypt(str, key, { iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7, }).toString(CryptoJS.enc.Utf8); return JSON.parse(res); } catch (error) { console.error('Decryption error:', error); throw new Error('Failed to decrypt data'); } }; // 生成UUID function generateUUID() { var d = new Date().getTime(); var uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace( /[xy]/g, function (c) { var r = (d + Math.random() * 16) % 16 | 0; d = Math.floor(d / 16); return (c === "x" ? r : (r & 0x3) | 0x8).toString(16); } ); return uuid; } // 主请求函数 const request = (method = 'GET', serverUrl, domainUrl, params, dataType = "json") => { let currentUrl // try { // let pages = getCurrentPages(); // let currentPage = pages[pages.length - 2]; // currentUrl = currentPage.route; // currentUrl = pageData[currentUrl] // } catch (e) { // } let q = serverUrl // 头部header let header = uni.getStorageSync('header') || {}; // 请求地址 serverUrl = uni.getStorageSync('host') || serverUrl; if (q == 'test') { serverUrl = "http://10.3.0.24:9209/" header['x-token'] = "bdf87a98-eef0-47df-9faf-41d547b0457e" } let url = domianUrl(serverUrl, domainUrl); if (q != 'test') { params = deepClone(params); } var key = uni.getStorageSync('encrypt') || "default_encrypt_key"; let data = {}; console.log("传参", method === "GET" || method === "DELETE" || q == 'q') if (method === "GET" || method === "DELETE" || q == 'q') { params.timestamp = Math.floor(new Date().getTime() / 1000); params.nonce = generateUUID(); let keys = Object.keys(params); keys.sort(); for (let i in keys) { keys[i] = keys[i] + "=" + encodeURIComponent(params[keys[i]]); } let temp = keys.join("&") + "&" + CryptoJS.MD5(key).toString(); params.signature = CryptoJS.MD5(temp).toString(); data = { url: url + "?" + encodeParam(params), method, header: header // setheader(dataType, header), }; } else if (method === "POST" || method === "PUT") { let temp = decodeParam(url); temp.timestamp = Math.floor(new Date().getTime() / 1000); temp.nonce = generateUUID(); let keys = Object.keys(temp); keys.sort(); for (let i in keys) { keys[i] = keys[i] + "=" + encodeURIComponent(temp[keys[i]]); } let s = keys.join("&"); s += "&" + JSON.stringify(params); s += "&" + CryptoJS.MD5(key).toString(); temp.signature = CryptoJS.MD5(s).toString(); url = url.split("?")[0] + "?" + encodeParam(temp); data = { url, method, header: header, data: params, }; } console.log("传参详情", data) return new Promise((resolve, reject) => { uni.request(data).then(res => { if (res.statusCode == 200) { if (res.data.encrypt) { if (q != 'test') { res.data = deCode(res.data.data); } else { res.data = res.data.data } } if (res.data.code == 1001003 || res.data.code == 1001004 || res.data.code == 1001005) { uni.hideLoading(); uni.showToast({ icon: 'none', title: '登录失效,请重新登录' }) return reject(res); } else if (res.data.code != 0) { if (data.method == 'POST' && domainUrl == 'api/order') { apiUserEvent('all', { type: "event", key: "order_fail", value: "下单失败", extra: { from: currentUrl, data: data, res: res } }, { type: 'order_fail', data: { from: currentUrl, res: res } }) } uni.hideLoading(); uni.showToast({ icon: 'none', title: res.data.message }) return reject(res); } if (data.method == 'POST' && domainUrl == 'api/order') { apiUserEvent('all', { type: "event", key: "order_success", value: "下单成功", extra: { from: currentUrl, data: data, res: res } }, { type: 'order_success', data: { from: currentUrl } }) } resolve(res.data); } else { // InnerApp.addRequestLog(url, data, res) reject(res); } }).catch(err => { if (err.errMsg == 'request:fail timeout') { uniToast('请求超时,请重试!'); } else if (err.errMsg == 'request:fail') { uniToast('无网络!'); } else { apiUserEvent('uni', { type: "event", key: "err", value: "下单成功", extra: {} }, { type: 'request_err', data: { err: JSON.stringify(err) } }) // uni.showModal({ // title: '提示', // content: JSON.stringify(err), // success: function (res) { // if (res.confirm) { // console.log('用户点击确定'); // } else if (res.cancel) { // console.log('用户点击取消'); // } // } // }); // uniToast('服务器繁忙'); } // InnerApp.addRequestLog(url, data, err) reject(err); }); }); }; /** * 处理请求头 * @param dataType 是否json格式 * @param baseHeader 基础header */ const setheader = (dataType, baseHeader = {}) => { let header = { ...baseHeader }; if (dataType == 'json') { header['Content-Type'] = 'application/json;charset=UTF-8'; } else { header['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'; } // 获取系统信息 - 需要实际实现 var systeminfo = { appChannel: "wx-mp", brand: "", model: "", deviceId: "", platform: "wx-mp" }; header['x-version'] = "2.3.0"; header['x-channel'] = systeminfo.appChannel || "wx-mp"; header['x-mobile-brand'] = systeminfo.brand || ""; header['x-mobile-model'] = systeminfo.model || ""; header['x-device-id'] = systeminfo.deviceId || ""; header['x-base-version'] = "2.3.0"; header['x-platform'] = systeminfo.platform || "wx-mp"; // 以下需要实际实现 // const shop = InnerApp.getShop(); // if (shop) { // header['x-member-store'] = shop; // } // header['x-package'] = InnerApp.packageName; // var token = InnerApp.getToken(); // if (token) { // header['x-token'] = token; // } return header; }; /** * 处理接口URL * @param serveUrl 请求服务器地址 * @param domainUrl 接口路径 */ const domianUrl = (serveUrl, domainUrl) => { // #ifdef H5 // H5环境下使用相对路径,走 vite 代理,避免 CORS 跨域问题 const finalUrl = domainUrl.startsWith('/') ? domainUrl : '/' + domainUrl; console.log('[H5代理] 原始URL:', domainUrl, '→ 代理URL:', finalUrl); return finalUrl; // #endif // #ifndef H5 // 非H5环境(APP、小程序等)使用完整URL let finalUrl; if (serveUrl.endsWith('/') && domainUrl.startsWith('/')) { finalUrl = serveUrl + domainUrl.substring(1); } else if (!serveUrl.endsWith('/') && !domainUrl.startsWith('/')) { finalUrl = serveUrl + '/' + domainUrl; } else { finalUrl = serveUrl + domainUrl; } console.log('[非H5] 完整URL:', finalUrl); return finalUrl; // #endif }; /** * 处理吐司 * @param msg 吐司内容 * @param duration 吐司时间 */ const uniToast = (msg, duration = 2000) => { uni.showToast({ title: msg, duration: duration, icon: 'none' }); }; // HTTP方法封装 const get = (serverUrl, url, params = {}) => { return request('GET', serverUrl, url, params); }; const post = (serverUrl, url, params = {}) => { return request('POST', serverUrl, url, params); }; const postJson = (serverUrl, url, params = {}) => { return request('POST', serverUrl, url, params, 'json'); }; const put = (serverUrl, url, params = {}) => { return request('PUT', serverUrl, url, params); }; const putJson = (serverUrl, url, params = {}) => { return request('PUT', serverUrl, url, params, 'json'); }; const del = (serverUrl, url, params = {}) => { return request('DELETE', serverUrl, url, params); }; const delJson = (serverUrl, url, params = {}) => { return request('DELETE', serverUrl, url, params, 'json'); }; export { get, post, postJson, put, putJson, del, delJson, encodeParam, decodeParam };