初始化仓库

This commit is contained in:
wangxiaowei
2025-04-30 13:59:26 +08:00
commit f3990f76ef
1034 changed files with 133104 additions and 0 deletions

40
utils/cache.js Normal file
View File

@ -0,0 +1,40 @@
const Cache = {
//设置缓存(expire为缓存时效)
set(key, value, expire) {
let data = {
expire: expire ? (this.time() + expire) : "",
value
}
if (typeof data === 'object')
data = JSON.stringify(data);
try {
uni.setStorageSync(key, data)
} catch (e) {
return false;
}
},
get(key) {
try {
let data = uni.getStorageSync(key)
const {value, expire} = JSON.parse(data)
if(expire && expire < this.time()) {
uni.removeStorageSync(key)
return false;
}else {
return value
}
} catch (e) {
return false;
}
},
//获取当前时间
time() {
return Math.round(new Date() / 1000);
},
remove(key) {
if(key) uni.removeStorageSync(key)
}
}
export default Cache;

113
utils/login.js Normal file
View File

@ -0,0 +1,113 @@
import {
silentLogin
} from '@/api/app';
import {
isWeixinClient,
currentPage,
trottle,
tabbarList
} from './tools'
import store from '@/store'
import Cache from './cache'
import {
BACK_URL
} from '@/config/cachekey'
import wechath5 from './wechath5'
import {
inputInviteCode
} from '@/api/user'
// 获取登录凭证code
export function getWxCode() {
return new Promise((resolve, reject) => {
uni.login({
success(res) {
resolve(res.code);
},
fail(res) {
reject(res);
}
});
});
}
//小程序获取用户信息
export function getUserProfile() {
return new Promise((resolve, reject) => {
uni.getUserProfile({
desc: '获取用户信息,完善用户资料 ',
success: (res) => {
resolve(res);
},
fail(res) {}
})
})
}
//通用小程序获取用户信息
export function getUserInfo() {
return new Promise((resolve, reject) => {
uni.getUserInfo({
success: (res) => {
resolve(res);
},
fail(res) {}
})
})
}
export const wxMnpLogin = trottle(_wxMnpLogin, 1000)
//小程序静默授权
async function _wxMnpLogin() {
const code = await getWxCode()
const {code:loginCode, data: loginData} = await silentLogin({
code
})
const {
options,
onLoad,
onShow,
route
} = currentPage()
if(loginCode != 1) return
if (loginData.token && !loginData.is_new_user) {
store.commit('LOGIN', loginData)
onLoad && onLoad(options)
onShow && onShow()
const inviteCode = Cache.get("INVITE_CODE")
if (inviteCode) {
Cache.remove("INVITE_CODE")
inputInviteCode({
code: inviteCode
})
}
} else {
const loginRoute = '/pages/login/login'
if (!tabbarList.includes(route)) {
if(loginRoute.includes(route)) return
uni.navigateTo({
url: loginRoute
})
}
}
}
export const toLogin = trottle(_toLogin, 1000)
// 去登录
function _toLogin() {
uni.navigateTo({
url: '/pages/login/login'
});
//#ifdef H5
const pathLogin = 'pages/login/login'
let path = currentPage().route
if (path != pathLogin) {
uni.navigateTo({
url: '/pages/login/login'
})
}
// #endif
}

109
utils/request.js Normal file
View File

@ -0,0 +1,109 @@
import axios from "../js_sdk/xtshadow-axios/axios.min"
import store from "../store"
import {
paramsToStr,
currentPage,
tabbarList,
acountList
} from "./tools"
import Cache from "./cache"
import {
TOKEN,
BACK_URL
} from "../config/cachekey"
import {
baseURL
} from "../config/app"
import {
getWxCode,
toLogin,
wxMnpLogin
} from "./login"
let index = 0;
function checkParams(params) {
if (typeof params != "object") return params;
for (let key in params) {
const value = params[key];
if (value === null || value === undefined || value === "") {
delete params[key];
}
}
return params;
}
const service = axios.create({
baseURL: `${baseURL}/api/`,
timeout: 10000,
header: {
"content-type": "application/json",
},
});
// request拦截器
service.interceptors.request.use(
(config) => {
config.data = checkParams(config.data);
config.params = checkParams(config.params);
if (config.method == "GET") {
config.url += paramsToStr(config.params);
}
config.header.token = config.header.token || Cache.get(TOKEN);
return config;
},
(error) => {
// Do something with request error
console.log(error); // for debug
Promise.reject(error);
}
);
// response 拦截器
service.interceptors.response.use(
async (response) => {
if (response.data) {
const {
code,
show,
msg
} = response.data;
const {
route,
options
} = currentPage();
if (code == 0 && show && msg) {
uni.showToast({
title: msg,
icon: "none",
});
} else if (code == -1) {
store.commit("LOGOUT");
//#ifdef MP-WEIXIN || MP-ALIPAY
wxMnpLogin();
// #endif
//#ifdef H5 || APP-PLUS
if (route && !tabbarList.includes(route)) {
toLogin();
}
// #endif
//#ifdef H5
if (!acountList.includes(route)) {
Cache.set(BACK_URL, `/${route}${paramsToStr(options)}`);
}
// #endif
}
}
return Promise.resolve(response.data);
},
(error) => {
// tryHideFullScreenLoading()
console.log(error);
console.log("err" + error); // for debug
return Promise.reject(error);
}
);
export default service;

425
utils/tools.js Normal file
View File

@ -0,0 +1,425 @@
import {
loadingType
} from "./type";
import {
baseURL
} from "@/config/app.js";
import store from "@/store";
//所在环境
let client = null;
// #ifdef MP-WEIXIN
client = 1;
// #endif
// #ifdef H5
client = isWeixinClient() ? 2 : 6;
// #endif
// #ifdef APP-PLUS
client = 3;
uni.getSystemInfo({
success: (res) => {
client = res.platform == "ios" ? 3 : 4;
},
fail: (res) => {
client = 3;
},
});
// #endif
// #ifdef MP-ALIPAY
client = 7;
// #endif
export {
client
};
//节流
export const trottle = (func, time = 1000, context) => {
let previous = new Date(0).getTime();
return function(...args) {
let now = new Date().getTime();
if (now - previous > time) {
func.apply(context, args);
previous = now;
}
};
};
//判断是否为微信环境
export function isWeixinClient() {
var ua = navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == "micromessenger") {
//这是微信环境
return true;
} else {
//这是非微信环境
return false;
}
}
//判断是否为安卓环境
export function isAndroid() {
let u = navigator.userAgent;
return u.indexOf("Android") > -1 || u.indexOf("Adr") > -1;
}
//获取url后的参数 以对象返回
export function strToParams(str) {
var newparams = {};
for (let item of str.split("&")) {
newparams[item.split("=")[0]] = item.split("=")[1];
}
return newparams;
}
//重写encodeURL函数
export function urlencode(str) {
str = (str + "").toString();
return encodeURIComponent(str)
.replace(/!/g, "%21")
.replace(/'/g, "%27")
.replace(/\(/g, "%28")
.replace(/\)/g, "%29")
.replace(/\*/g, "%2A")
.replace(/%20/g, "+");
}
//一维数组截取为二维数组
export function arraySlice(data, array = [], optNum = 10) {
data = JSON.parse(JSON.stringify(data));
if (data.length <= optNum) {
data.length > 0 && array.push(data);
return array;
}
array.push(data.splice(0, optNum));
return arraySlice(data, array, optNum);
}
//对象参数转为以?&拼接的字符
export function paramsToStr(params) {
let p = "";
if (typeof params == "object") {
p = "?";
for (let props in params) {
p += `${props}=${params[props]}&`;
}
p = p.slice(0, -1);
}
return p;
}
//分页加载
export async function loadingFun(fun, page, dataList = [], status, params) {
// 拷贝对象
dataList = Object.assign([], dataList);
if (status == loadingType.FINISHED) return false;
const {
code,
data
} = await fun({
page_no: page,
...params,
});
uni.stopPullDownRefresh();
if (code == 1) {
if (page == 1) dataList = [];
let {
list,
more
} = data;
dataList.push(...list);
page = ++page;
if (!more) {
status = loadingType.FINISHED;
}
if (dataList.length <= 0) {
status = loadingType.EMPTY;
}
} else {
status = loadingType.ERROR;
}
return {
page,
dataList,
status,
};
}
// 获取wxml元素
export function getRect(selector, all, context) {
return new Promise(function(resolve) {
let qurey = uni.createSelectorQuery();
if (context) {
qurey = uni.createSelectorQuery().in(context);
}
qurey[all ? "selectAll" : "select"](selector)
.boundingClientRect(function(rect) {
if (all && Array.isArray(rect) && rect.length) {
resolve(rect);
}
if (!all && rect) {
resolve(rect);
}
})
.exec();
});
}
// 轻提示
export function toast(info = {}, navigateOpt) {
let title = info.title || "";
let icon = info.icon || "none";
let endtime = info.endtime || 2000;
if (title)
uni.showToast({
title: title,
icon: icon,
duration: endtime,
});
if (navigateOpt != undefined) {
if (typeof navigateOpt == "object") {
let tab = navigateOpt.tab || 1,
url = navigateOpt.url || "";
switch (tab) {
case 1:
//跳转至 table
setTimeout(function() {
uni.switchTab({
url: url,
});
}, endtime);
break;
case 2:
//跳转至非table页面
setTimeout(function() {
uni.navigateTo({
url: url,
});
}, endtime);
break;
case 3:
//返回上页面
setTimeout(function() {
uni.navigateBack({
delta: parseInt(url),
});
}, endtime);
break;
case 4:
//关闭当前所有页面跳转至非table页面
setTimeout(function() {
uni.reLaunch({
url: url,
});
}, endtime);
break;
case 5:
//关闭当前页面跳转至非table页面
setTimeout(function() {
uni.redirectTo({
url: url,
});
}, endtime);
break;
}
} else if (typeof navigateOpt == "function") {
setTimeout(function() {
navigateOpt && navigateOpt();
}, endtime);
}
}
}
//菜单跳转
export function menuJump(item) {
const {
is_tab,
link,
link_type
} = item;
switch (link_type) {
case 1:
// 本地跳转
if (is_tab) {
uni.switchTab({
url: link,
});
return;
}
uni.navigateTo({
url: link,
});
break;
case 2:
// webview
uni.navigateTo({
url: "/pages/webview/webview?url=" + link,
});
break;
case 3: // tabbar
}
}
export function uploadFile(path) {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: `${baseURL}/api/file/formimage`,
filePath: path,
name: "file",
header: {
token: store.getters.token,
},
fileType: "image",
cloudPath: "",
success: (res) => {
console.log("uploadFile res ==> ", res);
let data = JSON.parse(res.data);
if (data.code == 1) {
resolve(data.data);
} else {
reject();
}
},
fail: (err) => {
console.log(err);
reject();
},
});
});
}
//当前页面
export function currentPage() {
let pages = getCurrentPages();
let currentPage = pages[pages.length - 1];
return currentPage || {};
}
// H5复制方法
export function copy(str) {
// #ifdef H5
let aux = document.createElement("input");
aux.setAttribute("value", str);
document.body.appendChild(aux);
aux.select();
document.execCommand("copy");
document.body.removeChild(aux);
uni.showToast({
title: "复制成功",
});
// #endif
// #ifndef H5
uni.setClipboardData({
data: str.toString(),
});
// #endif
}
export function setTabbar() {
const config = store.getters.appConfig;
uni.setTabBarStyle({
color: config.navigation_setting.ust_color,
selectedColor: config.navigation_setting.st_color,
});
// #ifdef APP-PLUS
config.navigation_menu.forEach((item, index) => {
uni.downloadFile({
url: item.un_selected_icon,
success: (res) => {
uni.setTabBarItem({
index,
iconPath: res.tempFilePath,
});
},
});
uni.downloadFile({
url: item.un_selected_icon,
success: (res) => {
uni.setTabBarItem({
index,
iconPath: res.tempFilePath,
});
},
});
uni.downloadFile({
url: item.selected_icon,
success: (res) => {
uni.setTabBarItem({
index,
selectedIconPath: res.tempFilePath,
});
},
});
});
// #endif
// #ifndef APP-PLUS
config.navigation_menu.forEach((item, index) => {
uni.setTabBarItem({
index,
text: item.name,
iconPath: item.un_selected_icon,
selectedIconPath: item.selected_icon,
fail(res) {
console.log('setTabBarItem error=', res);
},
success(res) {
// console.log(res)
},
});
});
// #endif
uni.showTabBar();
}
// 忽略登录和tabbar页面路径
export const tabbarList = [
"pages/index/index",
"pages/order/order",
"pages/shop_cart/shop_cart",
"pages/my/my",
"pages/recharge/recharge",
"bundle/pages/setting/setting",
];
// 登录注册相关
export const acountList = [
"pages/login/login",
"pages/forget_pwd/forget_pwd",
"pages/register/register",
];
/**
* @description 获取当前微信小程序基础库版本号
*/
export function getBaseLibraryVersion() {
const {
SDKVersion
} = wx.getSystemInfoSync();
return SDKVersion;
}
/**
* @description 用于比较当前微信基础库版本与目标基础库版本
* 示例用法:比较小程序基础库版本是否大于等于 2.12.0 compareWeChatVersion("2.12.0")
* return 1 =>当前版本大于目标版本 return -1 =>当前版本小于目标版本 return 0 =>当前版本等于目标版本
* @param {string} targetVersion 目标微信版本号
*
*/
export function compareWeChatVersion(targetVersion) {
const currentVersion = getBaseLibraryVersion();
if (currentVersion === targetVersion) {
return 0; // 当前版本与目标版本相同
} else if (currentVersion > targetVersion) {
return 1; // 当前版本大于目标版本
} else {
return -1; // 当前版本小于目标版本
}
}

113
utils/type.js Normal file
View File

@ -0,0 +1,113 @@
//分页状态
export const loadingType = {
LOADING: 'loading',
FINISHED: 'finished',
ERROR: 'error',
EMPTY: 'empty'
};
// 收藏状态
export const CollectType = {
COLLECTION: 1,
CANCEL_COLLECTION: 0
}
//支付方式
export const payWay = {
WECHAT: 1,
ALIPAY: 2,
BALANCE: 3
}
export const orderType = {
// 全部
ALL: 'all',
// 待付款
WAIT_PAY: 'wait_pay',
// 未制作
NOT_MADE: 'not_made',
// 已完成
FINISH: 'finish',
// 退款
REFUND: 'refund'
};
// 售后状态
export const AfterSaleType = {
// 售后申请
NORMAL: 'normal',
// 处理中
HANDLING: 'apply',
// 已处理
FINISH: 'finish'
}
// 售后退款操作
export const refundOptType = {
// 仅退款
ONLY_REFUND: 0,
// 退货退款
REFUNDS: 1
}
// 短信发送
export const SMSType = {
// 注册
REGISTER: 'ZCYZ',
// 找回密码
FINDPWD: 'ZHMM',
// 登陆
LOGIN: 'YZMDL',
// 更换手机号
CHANGE_MOBILE: 'BGSJHM',
// 绑定手机号
BIND: 'BDSJHM'
}
// 分销订单状态
export const userOrderPromoteOrder = {
ALL: 0,
WAIT_RETURN: 1,
HANDLED: 2,
INVALED: 3
}
// 排序类型
export const SortType = {
NONE: '',
ASC: 'asc',
DESC: 'desc'
}
// 粉丝类型
export const FansType = {
ALL: 'all',
FIRST: 'first',
SECOND: 'second'
}
export const groupType = {
ALL: -1,
PROGESS: 0,
SUCCESS: 1,
FAIL: 2
};
export const bargainType = {
ALL: -1,
BARGINNING: 0,
SUCCESS: 1,
FAIL: 2
}
export const withdrawType = {
// 账户余额
ACCOUNT: 1,
// 微信零钱
WECHAT: 2,
// 微信收款码
PAY_WECHAT: 3,
// 支付宝收款码
PAY_ALIPAY: 4,
BANK: 5
}

158
utils/wechath5.js Normal file
View File

@ -0,0 +1,158 @@
// #ifdef H5
import weixin from "@/js_sdk/jweixin-module";
import {
isAndroid
} from "./tools"
import {
getJsconfig,
getCodeUrl,
wechatLogin
} from '@/api/app'
import store from '../store'
import Cache from './cache'
import {inputInviteCode} from "@/api/user"
class Wechath5 {
//获取微信配置url
signLink() {
if (typeof window.entryUrl === 'undefined' || window.entryUrl === '') {
window.entryUrl = location.href.split('#')[0]
}
return isAndroid() ? location.href.split('#')[0] : window.entryUrl;
}
//微信sdk配置
config() {
return new Promise((resolve) => {
getJsconfig().then(res => {
if (res.code == 1) {
let config = res.data.config
weixin.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来若要查看传入的参数可以在pc端打开参数信息会通过log打出仅在pc端时才会打印。
appId: config.appId, // 必填,公众号的唯一标识
timestamp: config.timestamp, // 必填,生成签名的时间戳
nonceStr: config.nonceStr, // 必填,生成签名的随机串
signature: config.signature, // 必填,签名
jsApiList: config.jsApiList // 必填需要使用的JS接口列表
});
resolve()
}
})
})
}
//获取微信登录url
getWxUrl() {
getCodeUrl().then(res => {
if (res.code == 1) {
location.href = res.data.url
}
})
}
//微信授权
authLogin(code) {
return new Promise((resolve, reject) => {
wechatLogin({
code
})
.then(res => {
if(res.code == 1) {
store.commit("LOGIN", {
token: res.data.token
});
resolve(res.data);
}
})
});
}
//微信分享
share(option) {
weixin.ready(() => {
const {
shareTitle,
shareLink,
shareImage,
shareDesc
} = option
weixin.updateTimelineShareData({
title: shareTitle, // 分享标题
link: shareLink, // 分享链接该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: shareImage, // 分享图标
success: function(res) {
// 设置成功
}
});
// 发送给好友
weixin.updateAppMessageShareData({
title: shareTitle, // 分享标题
link: shareLink, // 分享链接该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: shareImage, // 分享图标
desc: shareDesc,
success: function(res) {
// 设置成功
}
});
// 发送到tx微博
weixin.onMenuShareWeibo({
title: shareTitle, // 分享标题
link: shareLink, // 分享链接该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: shareImage, // 分享图标
desc: shareDesc,
success: function(res) {
// 设置成功
}
})
})
}
wxPay(opt) {
return new Promise((reslove, reject) => {
weixin.ready(() => {
weixin.chooseWXPay({
timestamp: opt.timeStamp, // 支付签名时间戳注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
nonceStr: opt.nonceStr, // 支付签名随机串,不长于 32 位
package: opt.package, // 统一支付接口返回的prepay_id参数值提交格式如prepay_id=***
signType: opt.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
paySign: opt.paySign, // 支付签名
success: (res) => {
reslove('success')
},
cancel: (res) => {
reslove('fail')
},
fail: (res) => {
reslove('fail')
},
});
});
})
}
getWxAddress() {
return new Promise((reslove, reject) => {
weixin.ready(() => {
weixin.openAddress({
success: (res) => {
reslove(res)
},
})
})
})
}
scanQRCode() {
return new Promise((reslove, reject) => {
weixin.ready(() => {
weixin.scanQRCode({
needResult: 1, // 默认为0扫描结果由微信处理1则直接返回扫描结果
scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有
success: function(res) {
reslove(res.resultStr)
}
});
})
})
}
}
export default new Wechath5()
// #endif