jingshuiji/utils/util.js
liluo293254 11c5647ae5 feat: 统一环境配置并移除本地测试登录入口
新增 config/env.js 管理 local/test/prod 网关,清理调试登录与页面联调相关改动。
2026-08-07 08:47:52 +08:00

900 lines
27 KiB
JavaScript
Raw 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.

// const { XRShadow } = require("XrFrame/elements");
const app = getApp()
// API / CDN 基址统一由 config/env.js 管理(与社区 static CDN 约定一致)
const env = require('../config/env.js')
const server_url = env.server_url
const img_url = env.img_url
const static_url = env.static_url
const aliyun_oss_url = env.aliyun_oss_url
/** 公开静态资源完整 URL(path 可带或不带前导 /) */
function staticSrc(path) {
if (!path) return static_url
if (/^https?:\/\//i.test(path)) return processImageUrl(path)
return static_url.replace(/\/$/, '') + '/' + String(path).replace(/^\//, '')
}
/** 将历史 OSS 直链替换为当前环境 CDN(对齐社区 processImageUrl) */
function processImageUrl(url) {
if (!url || typeof url !== 'string') return url
const prodOss = 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com'
const devOss = 'https://wechat-img-file-dev.oss-cn-beijing.aliyuncs.com'
if (url.indexOf(prodOss) === 0) return static_url + url.slice(prodOss.length)
if (url.indexOf(devOss) === 0) return static_url + url.slice(devOss.length)
if (aliyun_oss_url && url.indexOf(aliyun_oss_url) === 0) {
return static_url + url.slice(aliyun_oss_url.length)
}
return url
}
const getGuid = function () {
var s = [];
var hexDigits = "0123456789abcdef";
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = "4";
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
s[8] = s[13] = s[18] = s[23] = "-";
var uuid = s.join("");
return uuid;
}
const goLogin = () => {
var pages = getCurrentPages() //获取加载的页面
var currentPage = pages[pages.length - 1] //获取当前页面的对象
var urlthis = currentPage.route //当前页面url
console.log('urlthisurlthis', urlthis);
let JumpUrl = '/pages/newLogin/newLogin';
if (urlthis.includes('packages/master')) {
JumpUrl = '/pages/newLogin/newLogin';
} else if (urlthis.includes('packages/partner')) {
JumpUrl = '/pages/newLogin/newLogin';
}
wx.showModal({
title: '提示',
content: '请登录后查看',
confirmText: "去登陆",
complete: (res) => {
if (res.cancel) { }
if (res.confirm) {
wx.reLaunch({
url: JumpUrl,
})
}
}
})
}
const formatTimeForChart = date => {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
var str = [month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
return str;
}
const formatTime = (time, option) => {
const date = new Date(time)
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const week = date.getDay()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
//获取 年月日
if (option == 'YY-MM-DD') return [year, month, day].map(formatNumber).join('-')
//获取 年月
if (option == 'YY-MM') return [year, month].map(formatNumber).join('-')
//获取 年
if (option == 'YY') return [year].map(formatNumber).toString()
//获取 月
if (option == 'MM') return [mont].map(formatNumber).toString()
//获取 日
if (option == 'DD') return [day].map(formatNumber).toString()
//获取 年月日 周一 至 周日
if (option == 'YY-MM-DD Week') return [year, month, day].map(formatNumber).join('-') + ' ' + getWeek(week)
//获取 月日 周一 至 周日
if (option == 'MM-DD Week') return [month, day].map(formatNumber).join('-') + ' ' + getWeek(week)
//获取 周一 至 周日
if (option == 'Week') return getWeek(week)
//获取 时分秒
if (option == 'hh-mm-ss') return [hour, minute, second].map(formatNumber).join(':')
//获取 时分
if (option == 'hh-mm') return [hour, minute].map(formatNumber).join(':')
//获取 分秒
if (option == 'mm-dd') return [minute, second].map(formatNumber).join(':')
//默认 时分秒 年月日
return [year, month, day].map(formatNumber).join('-')
}
const getCurrentTime = () => {
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
}
const formatNumber = n => {
n = n.toString()
return n[1] ? n : '0' + n
}
const getWeek = n => {
switch (n) {
case 1:
return '星期一'
case 2:
return '星期二'
case 3:
return '星期三'
case 4:
return '星期四'
case 5:
return '星期五'
case 6:
return '星期六'
case 7:
return '星期日'
}
}
const getUrl = function (url, data, successfn, disAuthRedirect, nocloseloading) {
if (data && !data.uid) {
data.uid = wx.getStorageSync('uid');
}
let paid = wx.getStorageSync('paid');
let said = wx.getStorageSync("said")
if (data && !data.paid) {
data._paid = paid;
}
// if (data && !data.said) {
data._said = said;
// }
var app1 = getApp();
wx.request({
url: server_url + url,
data: data,
method: 'GET',
success: f => {
if (!nocloseloading) {
//wx.hideLoading();
}
if (f.data.code == "-101" || f.data.code == "-102") {
if (!disAuthRedirect) {
successfn(f.data);
return;
}
} else {
successfn(f.data);
}
},
error: f => {
// wx.hideLoading();
wx.showToast({
title: '系统繁忙',
icon: 'none'
})
}
})
}
const getUrl2 = function (url, data, successfn, disAuthRedirect, nocloseloading) {
if (data && !data.uid) {
data.uid = wx.getStorageSync('uid');
}
var app1 = getApp();
let token = wx.getStorageSync('token')
console.log(token, 'token');
wx.request({
url: server_url + url,
data: data,
method: 'GET',
header: {
// 'Accept': 'application/json',
// 'Bearer token': token
"Authorization": "Bearer " + token
},
success: f => {
console.log(f, '成功');
if (!nocloseloading) {
//wx.hideLoading();
}
if (f.data.code == "-101" || f.data.code == "-102") {
if (!disAuthRedirect) {
return;
}
} else {
successfn(f.data);
}
},
error: f => {
console.log(f, '失败');
// wx.hideLoading();
wx.showToast({
title: '系统繁忙',
icon: 'none'
})
}
})
}
const postUrl = function (url, data, successfn, token, options) {
var pages = getCurrentPages() //获取加载的页面
let ctoken;
if (token) {
ctoken = token;
} else {
ctoken = wx.getStorageSync('ctoken'); // 后续接口强依赖强校验该字段
}
const opts = options || {}
var currentPage = pages[pages.length - 1] //获取当前页面的对象
var urlthis = currentPage.route //当前页面url
if (data && !data.uid) {
}
if (data && !data.paid) {
}
if (data.uid == "" && urlthis == "pages/login/login") {
} else if (data.uid == "" && urlthis == "/pages/mine/route/route") {
} else { }
let parmas
if (wx.getStorageSync('userId')) {
parmas = {
user_id: wx.getStorageSync('userId'),
...data
}
} else {
parmas = {
...data
}
}
try {
let traceId = ''
traceId = wx.getStorageSync('trace-id')
wx.request({
url: server_url + url,
data: JSON.stringify(parmas),
method: 'POST',
header: {
'content-type': 'application/json',
'Authorization': ctoken === undefined ? '' : ctoken,
'trace-id':traceId
},
success: f => {
const traceId = f.header['trace-id']
if(traceId){
wx.setStorageSync('traceId', traceId)
}
// TODO: 待验证是否可做判断依据
// 调用成功,返回200 等其他情况则表示接口失败
if (f.statusCode == 401 || f.data.msg === "效验令牌失败") {
// 可选接口(如转账确认轮询)勿强制跳登录,避免未登录进首页被误判为「登录401」
if (opts.skipAuthRedirect) {
if (typeof successfn === 'function') {
successfn({ unauthorized: true, msg: (f.data && f.data.msg) || '请登录后操作' })
}
return
}
console.log('走到这?')
goLogin();
return
}
if (f.data && f.statusCode === 200) {
const res = {
...f.data.data,
msg: f.data.msg
};
successfn(res);
return res;
} else {
wx.showToast({
title: f.data.msg,
icon: 'none'
})
}
},
error: f => {
console.log('error');
wx.showToast({
title: '系统繁忙',
icon: 'none'
})
}
})
} catch (e) {
wx.showToast({
title: e.message,
})
}
}
const postUrl2 = function (url, data, successfn, token) {
var pages = getCurrentPages() //获取加载的页面
let ctoken;
if (token) {
ctoken = token;
} else {
ctoken = wx.getStorageSync('ctoken'); // 后续接口强依赖强校验该字段
}
var currentPage = pages[pages.length - 1] //获取当前页面的对象
var urlthis = currentPage.route //当前页面url
if (data && !data.uid) {
// data.uid = wx.getStorageSync('uid');
}
if (data && !data.paid) {
// data._paid = wx.getStorageSync('paid');
}
// data._said = wx.getStorageSync("said")
if (data.uid == "" && urlthis == "pages/login/login") {
} else if (data.uid == "" && urlthis == "/pages/mine/route/route") {
} else { }
let parmas
if (wx.getStorageSync('userId')) {
parmas = {
user_id: wx.getStorageSync('userId'),
...data
}
} else {
parmas = {
...data
}
}
try {
let traceId = ''
traceId = wx.getStorageSync('trace-id')
wx.request({
url: server_url + url,
data: JSON.stringify(parmas),
method: 'POST',
header: {
// 'content-type': 'application/x-www-form-urlencoded',
'content-type': 'application/json',
'Authorization': ctoken === undefined ? '' : ctoken,
'trace-id':traceId
},
success: f => {
const traceId = f.header['trace-id']
if(traceId){
wx.setStorageSync('traceId', traceId)
}
// 支付查单等走 postUrl2:401 / 令牌失效 → 登录
if (f.statusCode == 401 || (f.data && f.data.msg === "效验令牌失败")) {
goLogin();
return;
}
if (typeof successfn === 'function') {
successfn(f);
}
},
error: f => {
wx.showToast({
title: '系统繁忙',
icon: 'none'
})
}
})
} catch (e) {
wx.showToast({
title: e.message,
})
}
}
const postUrl3 = function (url, data, version, successfn, token) {
var pages = getCurrentPages() //获取加载的页面
let ctoken;
if (token) {
ctoken = token;
} else {
ctoken = wx.getStorageSync('ctoken'); // 后续接口强依赖强校验该字段
}
var currentPage = pages[pages.length - 1] //获取当前页面的对象
var urlthis = currentPage.route //当前页面url
if (data && !data.uid) {
// data.uid = wx.getStorageSync('uid');
}
if (data && !data.paid) {
// data._paid = wx.getStorageSync('paid');
}
// data._said = wx.getStorageSync("said")
if (data.uid == "" && urlthis == "pages/login/login") {
} else if (data.uid == "" && urlthis == "/pages/mine/route/route") {
} else { }
let parmas
if (wx.getStorageSync('userId')) {
parmas = {
user_id: wx.getStorageSync('userId'),
...data
}
} else {
parmas = {
...data
}
}
try {
let traceId = ''
traceId = wx.getStorageSync('trace-id')
wx.request({
url: server_url + url,
data: JSON.stringify(parmas),
method: 'POST',
header: {
// 'content-type': 'application/x-www-form-urlencoded',
'content-type': 'application/json',
'version': version,
'trace-id':traceId
},
success: f => {
console.log('successddd', f);
const traceId = f.header['trace-id']
if(traceId){
wx.setStorageSync('traceId', traceId)
}
// TODO: 待验证是否可做判断依据
// 调用成功,返回200 等其他情况则表示接口失败
if (f.statusCode == 401 || f.data.msg === "效验令牌失败") {
goLogin();
return;
wx.showModal({
title: '提示',
content: '请登录后查看',
confirmText: "去登陆",
complete: (res) => {
if (res.cancel) {
}
if (res.confirm) {
wx.reLaunch({
url: '/pages/login/login',
})
// wx.navigateTo({
// url: '/pages/MasterLogin/MasterLogin',
// })
}
}
})
return
}
if (f.data && f.statusCode === 200) {
const res = {
...f.data.data,
msg: f.data.msg
};
successfn(res);
return res;
} else {
wx.showToast({
title: f.data.msg,
icon: 'none'
})
}
},
error: f => {
console.log('error');
wx.showToast({
title: '系统繁忙',
icon: 'none'
})
}
})
} catch (e) {
wx.showToast({
title: e.message,
})
}
}
const postUrl4 = function (url, data, successfn, token) {
var pages = getCurrentPages() //获取加载的页面
let ctoken;
if (token) {
ctoken = token;
} else {
ctoken = wx.getStorageSync('atoken'); // 后续接口强依赖强校验该字段
}
var currentPage = pages[pages.length - 1] //获取当前页面的对象
var urlthis = currentPage.route //当前页面url
if (data && !data.uid) {
// data.uid = wx.getStorageSync('uid');
}
if (data && !data.paid) {
// data._paid = wx.getStorageSync('paid');
}
// data._said = wx.getStorageSync("said")
if (data.uid == "" && urlthis == "pages/login/login") {
} else if (data.uid == "" && urlthis == "/pages/mine/route/route") {
} else { }
let parmas
if (wx.getStorageSync('userId')) {
parmas = {
// user_id: wx.getStorageSync('userId'),
...data
}
} else {
parmas = {
...data
}
}
try {
let traceId = ''
traceId = wx.getStorageSync('trace-id')
wx.request({
url: server_url + url,
data: JSON.stringify(parmas),
method: 'POST',
header: {
// 'content-type': 'application/x-www-form-urlencoded',
'content-type': 'application/json',
"Authorization": ctoken,
'trace-id':traceId
},
success: f => {
const traceId = f.header['trace-id']
if(traceId){
wx.setStorageSync('traceId', traceId)
}
// TODO: 待验证是否可做判断依据
// 调用成功,返回200 等其他情况则表示接口失败
if (f.statusCode == 401 || f.data.msg === "效验令牌失败") {
goLogin();
return;
wx.showModal({
title: '提示',
content: '请登录后查看',
confirmText: "去登陆",
complete: (res) => {
if (res.cancel) {
}
if (res.confirm) {
wx.reLaunch({
url: '/pages/login/login',
})
}
}
})
return
}
if (f.data && f.statusCode === 200) {
const res = {
...f.data.data,
msg: f.data.msg
};
successfn(res);
return res;
} else {
wx.showToast({
title: f.data.msg,
icon: 'none'
})
}
},
error: f => {
console.log('error');
wx.showToast({
title: '系统繁忙',
icon: 'none'
})
}
})
} catch (e) {
wx.showToast({
title: e.message,
})
}
}
const uploadFileUrl = function (filename, successfn) {
wx.uploadFile({
url: server_url + '/public/upload-image', // "https://qsmmcha.com/webapi/file.ashx",
filePath: filename,
name: 'image',
formData: {
'uid': wx.getStorageSync('uid'),
},
success: (f) => {
successfn(f.data);
},
fail: (res) => {
console.log(res);
wx.showToast({
title: '上传文件失败',
icon: 'none'
})
},
complete: () => { }
});
}
//打开小程序路径
const openUrl = function (url) {
var rooturls = ['pages/index/index', 'pages/category/category', 'pages/shoppingCart/shoppingCart', 'pages/mine/mine'];
if (url[0] == "p") {
url = '/' + url;
}
for (var i = 0; i < rooturls.length; i++) {
if (url.indexOf(rooturls[i]) > -1) {
wx.switchTab({
url: url,
});
return;
}
}
wx.navigateTo({
url: url,
})
}
//验证是否是邮箱
const isEmail = function (strEmail) {
if (strEmail.search(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/) != -1)
return true;
else
return false
}
//验证身份证号
const isIdcard = function isValidIdCard(idCard) {
var ret = false;
var w = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
if (idCard.length == 18) {
//身份证号码长度必须为18,只要校验位正确就算合法
var crc = idCard.substring(17);
var a = new Array();
var sum = 0;
for (var i = 0; i < 17; i++) {
a.push(idCard.substring(i, i + 1));
sum += parseInt(a[i], 10) * parseInt(w[i], 10);
//alert(a[i]);
}
sum %= 11;
var res = "-1";
switch (sum) {
case 0: {
res = "1";
break;
}
case 1: {
res = "0";
break;
}
case 2: {
res = "X";
break;
}
case 3: {
res = "9";
break;
}
case 4: {
res = "8";
break;
}
case 5: {
res = "7";
break;
}
case 6: {
res = "6";
break;
}
case 7: {
res = "5";
break;
}
case 8: {
res = "4";
break;
}
case 9: {
res = "3";
break;
}
case 10: {
res = "2";
break;
}
}
if (crc.toLowerCase() == res.toLowerCase()) {
ret = true;
}
//ret=true;
}
/*
else if(idCard.length == 15){
//15位的身份证号,只验证是否全为数字
var pattern = /\d/;
ret=pattern.test(idCard);
}*/
return ret;
}
const isPhone = function (e) {
var phone = e;
if (e.length != 11) {
return false
}
if (!(/^1(3\d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8\d|9[0-35-9])\d{8}$/.test(phone))) {
return false
} else {
return true
}
}
//数组去重
const uniqueByField = function (arr, field) {
const seen = {};
return arr.filter(item => {
const key = item[field];
return seen.hasOwnProperty(key) ? false : (seen[key] = true);
});
}
/**
* 精确的浮点数运算
* @param {number} num1 - 第一个数字
* @param {number} num2 - 第二个数字
* @param {string} operator - 运算符,支持 '+', '-', '*', '/', '+='
* @returns {number} - 运算结果
*/
function floatCalculate(num1, num2, operator) {
// 获取小数位数
function getPrecision(num) {
const str = num.toString();
const decimalIndex = str.indexOf('.');
return decimalIndex === -1 ? 0 : str.length - decimalIndex - 1;
}
// 计算放大倍数
const precision1 = getPrecision(num1);
const precision2 = getPrecision(num2);
const maxPrecision = Math.max(precision1, precision2);
const factor = Math.pow(10, maxPrecision);
// 将数字转换为整数
const intNum1 = Math.round(num1 * factor);
const intNum2 = Math.round(num2 * factor);
// 根据运算符进行计算
let result;
switch (operator) {
case '+':
result = (intNum1 + intNum2) / factor;
break;
case '-':
result = (intNum1 - intNum2) / factor;
break;
case '*':
result = (intNum1 * intNum2) / (factor * factor);
break;
case '/':
result = intNum1 / intNum2;
break;
case '+=':
result = (intNum1 + intNum2) / factor;
break;
default:
throw new Error('不支持的运算符');
}
return result;
}
/**
* @description 读取缓存并删除
* @method headerStorage
* @param {Object} that // this指向
* @param {String} key // 缓存键名
* @param {*} value // 存储页面data参数
*/
const headerStorage = (that, key, value) => {
if (key === '' || value === '') {
console.log('请输入缓存key 或 存储页面参数');
return;
}
const res = wx.getStorageSync(`${key}`);
console.log('缓存key de val', res);
// 获取到存储对象后另存到data数据中
that.setData({ [value]: res }, () => {
// 获取后异步删除 防止下次页面携带数据错误
wx.removeStorage({
key: `${key}`,
success: function () {
console.log('存储对象已成功删除');
},
fail: function (err) {
console.error('删除存储对象失败', err);
}
});
});
}
function debounce(func, wait) {
let timeout;
console.log('funcfuncfuncfunc', func, wait);
console.log('debouncedebouncedebounce', wait);
return function (...args) {
console.log('1231313123', ...args);
const context = this;
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(context, args), wait);
};
}
function preciseAdd(num1, num2) {
const precision = Math.pow(10, 10); // 根据需求调整精度
return (Math.round(num1 * precision) + Math.round(num2 * precision)) / precision;
}
module.exports = {
server_url: server_url,
img_url: img_url,
static_url: static_url,
aliyun_oss_url: aliyun_oss_url,
staticSrc: staticSrc,
processImageUrl: processImageUrl,
openUrl: openUrl,
getUrl: getUrl,
getUrl2: getUrl2,
postUrl: postUrl,
postUrl2: postUrl2,
postUrl3: postUrl3,
postUrl4: postUrl4,
uploadFileUrl: uploadFileUrl,
formatTime: formatTime,
formatTimeForChart: formatTimeForChart,
// socketUrl: socket_url,
headerStorage,
getGuid: getGuid,
isEmail: isEmail,
isIdcard: isIdcard,
debounce,
isPhone,
uniqueByField,
floatCalculate,
getCurrentTime
}