alipay-emulator/utils/requests.js

418 lines
10 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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 uni_version = uni.getStorageSync("version")
if (type != 'uni') {
await postJson('a', 'api/user/event', {
type: adminData.type,
key: adminData.type + ".uni.alipay." + adminData.key,
value: adminData.value,
extra: JSON.stringify({
uni_version: uni_version,
...adminData.extra
}),
})
}
}
// 辅助函数:参数编码
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
};