代码提交

This commit is contained in:
黄少君
2023-11-14 17:21:03 +08:00
parent d0b337c596
commit dcab74274f
567 changed files with 22414 additions and 7375 deletions

4
utils/config.js Normal file
View File

@ -0,0 +1,4 @@
// 缓存key
export const CacheKey = {
PAY_INFO: 'pay_info', // 支付信息
}

View File

@ -1,59 +1,57 @@
const doc = null
const CACHE_KEY = 'clear_0.0.1'
// const doc = window.document;
function get(key) {
return uni.getStorageSync(key)
}
function all() {
return uni.getStorageInfoSync()
}
function set(key, data, time) {
console.log("--> % set % key:\n", key)
console.log("--> % set % data:\n", data)
if (!key) {
return
}
uni.setStorageSync(key, data)
}
function remove(key) {
if (!key || !_has(key)) {
return
}
uni.removeStorageSync(key)
}
function clearAll() {
const res = uni.getStorageInfoSync()
res.keys.map(item => {
if (item == 'redirect' || item == 'spread' || item == CACHE_KEY) {
return
}
remove(item)
})
}
function _has(key) {
if (!key) {
return
}
let value = uni.getStorageSync(key)
if (value) {
return true
}
return false
}
export default {
get,
all,
set,
remove,
clearAll,
has: _has,
CACHE_KEY,
}
const doc = null
const CACHE_KEY = 'clear_0.0.1'
// const doc = window.document;
function get(key) {
return uni.getStorageSync(key)
}
function all() {
return uni.getStorageInfoSync()
}
function set(key, data, time) {
if (!key) {
return
}
uni.setStorageSync(key, data)
}
function remove(key) {
if (!key || !_has(key)) {
return
}
uni.removeStorageSync(key)
}
function clearAll() {
const res = uni.getStorageInfoSync()
res.keys.map(item => {
if (item == 'redirect' || item == 'spread' || item == CACHE_KEY) {
return
}
remove(item)
})
}
function _has(key) {
if (!key) {
return
}
let value = uni.getStorageSync(key)
if (value) {
return true
}
return false
}
export default {
get,
all,
set,
remove,
clearAll,
has: _has,
CACHE_KEY,
}

View File

@ -1,60 +1,130 @@
import stringify from '@/utils/querystring'
import { timeFormat } from '@/uni_modules/uv-ui-tools/libs/function/index.js';
import router from './router'
import cookie from './cookie'
/**
* 未登录无权限
*/
export const handleLoginFailure = () => {
// router.replace({
// path: '/pages/login/login',
// })
uni.redirectTo({
url: '/pages/login/login',
})
// todo 添加记录参数逻辑
// router.replace({
// path: '/pages/login/login',
// })
const routes = getCurrentPages();
const curRoute = routes[routes.length - 1];
if (["pages/login/guid", "pages/login/index"].includes(curRoute.route)) {
return;
}
const data = curRoute?.$page?.fullPath;
uni.setStorage({
key: 'lastFullPath',
data
})
uni.redirectTo({
url: '/pages/login/guid',
})
}
export const afterLogin = () => {
const tabsList = [
'/pages/goodsCategory/goodsCategory',
'/pages/index/index',
'/pages/shoppingCart/shoppingCart',
'/pages/user/user'
]
const lastPath = uni.getStorageSync('lastFullPath');
if (lastPath) {
const str = lastPath.split("?")
if (tabsList.includes(str[0])) {
uni.switchTab({url: lastPath})
} else {
uni.redirectTo({url: lastPath})
}
uni.removeStorageSync('lastFullPath')
} else {
uni.switchTab({url: '/pages/index/index'})
}
}
export function parseUrl(location) {
if (typeof location === 'string') return location
const { url, query } = location
if (typeof location === 'string') return location
const {url, query} = location
const queryStr = stringify(query)
const queryStr = stringify(query)
if (!queryStr) {
return url
}
if (!queryStr) {
return url
}
return `${url}?${queryStr}`
return `${ url }?${ queryStr }`
}
export function objectURLToBlob(url) {
return new Promise(resolve => {
const http = new XMLHttpRequest()
http.open('GET', url, true)
http.responseType = 'blob'
http.onload = function (e) {
if (this.status == 200 || this.status === 0) {
resolve(this.response)
}
}
http.send()
})
}
/**
* 判断h5环境是否在微信浏览器内
* @returns {boolean}
*/
export function h5InWeChat() {
if (!navigator || (navigator && !navigator.userAgent)) return false
let ua = navigator.userAgent.toLowerCase();
return ua.match(/MicroMessenger/i) == "micromessenger"
}
export function createMessage(msg, data) {
return {
msg,
data
}
}
const toAuth = () => {
uni.showToast({
title: '暂未开放',
icon: 'none',
duration: 2000,
})
uni.showToast({
title: '暂未开放',
icon: 'none',
duration: 2000,
})
}
export default {
install: (app, options) => {
// 在这里编写插件代码
// 注入一个全局可用的 $translate() 方法
app.config.globalProperties.$yrouter = router
app.config.globalProperties.$cookie = cookie
app.config.globalProperties.$toAuth = toAuth
app.config.globalProperties.$onClickLeft = () => {
router.back()
}
install: (app, options) => {
// 在这里编写插件代码
// 注入一个全局可用的 $translate() 方法
app.config.globalProperties.$yrouter = router
app.config.globalProperties.$cookie = cookie
app.config.globalProperties.$toAuth = toAuth
app.config.globalProperties.$timeFormat = timeFormat
app.config.globalProperties.$onClickLeft = () => {
uni.navigateBack()
// router.back()
}
// #ifdef H5
app.config.globalProperties.$platform = 'h5'
// #endif
// #ifdef H5
app.config.globalProperties.$platform = 'h5'
// #endif
// #ifdef APP-PLUS
// app端
app.config.globalProperties.$platform = 'app'
// #endif
// #ifdef APP-PLUS
// app端
app.config.globalProperties.$platform = 'app'
// #endif
// #ifdef MP-WEIXIN
app.config.globalProperties.$platform = 'routine'
// #endif
},
// #ifdef MP-WEIXIN
app.config.globalProperties.$platform = 'routine'
// #endif
},
}

286
utils/paymentUtils.js Normal file
View File

@ -0,0 +1,286 @@
/**
* @name: 支付工具方法
* @author: kahu4
* @date: 2023-11-07 11:42
* @description支付工具方法 请使用try catch抓取异常或者.catch抓取异常
* @update: 2023-11-07 11:42
* */
import { useInterface } from "@/hooks/useInterface";
import { createMessage, h5InWeChat } from "@/utils/index";
import { wechatPay } from "@/api/order";
import { CacheKey } from "@/utils/config";
const {loading, hideLoading} = useInterface()
// 微信支付的provider
export const WechatProvider = 'wxpay'
// 支付类型(后端用)
export const ServicePayType = {
0: 'weixin_h5', // H5微信内h5、微信外H5
1: 'weixin_applet', // 微信小程序
2: 'weixin_app' // 微信APP
}
// 支付类型(前端用)
export const PayType = {
0: 'wechat', // 微信支付
1: 'balance', // 余额支付
2: 'alipay', // 支付宝支付
}
// 微信支付环境类型(前端用)
export const WechatPayEnvType = {
0: 'app', // APP
1: 'miniProgram', // 小程序
2: 'h5InWechat', // 微信内H5
3: 'h5OutWechat' // 微信外H5
}
/**
* 获取当前环境
* @returns {*} WechatPayEnvType
*/
export function getEnvType() {
let envType; // 0.APP 1.微信小程序 2.微信内H5 3.微信外H5 WechatPayEnvType
// #ifdef APP-PLUS
envType = WechatPayEnvType["0"]
// #endif
// #ifdef MP-WEIXIN
envType = WechatPayEnvType["1"]
// #endif
// #ifdef H5
if (h5InWeChat()) {
envType = WechatPayEnvType["2"]
} else {
envType = WechatPayEnvType["3"]
}
// #endif
return envType
}
/**
* @name: 支付
* @param options {{ type:any, payInfo:any }}
* type PayType
* payInfo 结算信息
*/
export async function doPayment(options) {
loading({title: '支付中...'})
const res = await _chooseEnvToPayment(options)
hideLoading()
return res
}
/**
* 区别环境调用支付
* @param options
* @returns {Promise<{msg: *, data: *}>}
* @private
*/
async function _chooseEnvToPayment(options) {
const {type, payInfo} = options
let res;
if (type === PayType[0]) {
// 微信支付
switch (getEnvType()) {
case WechatPayEnvType["0"]:
res = await _appWechatPay(payInfo)
break;
case WechatPayEnvType["1"]:
res = await _miniProgramPay(payInfo)
break;
case WechatPayEnvType["2"]:
res = await _h5InWechatPay(payInfo)
break;
case WechatPayEnvType["3"]:
res = await _h5OutWechatPay(payInfo)
break;
}
}
if (type === PayType["1"]) {
// 余额支付
}
if (type === PayType["2"]) {
// 支付宝
res = await _aliPay(payInfo)
}
return res
}
/**
* APP微信支付
* @param payInfo
* @private
* @docs https://pay.weixin.qq.com/docs/merchant/apis/in-app-payment/app-transfer-payment.html
*/
function _appWechatPay(payInfo) {
return new Promise(async (resolve, reject) => {
// 请求线上获取 res:{ appId,timeStamp,nonceStr,paySign,package,signType,mwebUrl,codeUrl,merchant_id,out_trade_no }
const res = await _doWechatPayRequest({
from: ServicePayType['2'],
paytype: ServicePayType['2'],
uni: payInfo.orderId
})
const orderInfo = {
appid: res.appId, // 微信开放平台审核通过的移动应用AppID 。
prepayid: res.merchant_id, // 请填写商户号mchid对应的值。
timestamp: res.timeStamp, // 时间
sign: res.paySign, // 签名使用字段AppID、timeStamp、nonceStr、prepayid计算得出的签名值 注意取值RSA格式
partnerid: res.out_trade_no, // 微信返回的支付交易会话ID该值有效期为2小时。
noncestr: res.nonceStr, // 随机字符串不长于32位。推荐随机数生成算法。
package: 'Sign=WXPay', // 暂填写固定值Sign=WXPay
}
uni.requestPayment({
provider: WechatProvider,
orderInfo,
success: (res) => resolve(createMessage('用户支付成功', res)),
fail: (error) => reject(createMessage('用户支付失败', error))
})
})
}
/**
* 微信小程序支付
* @param payInfo
* @private
* @docs https://pay.weixin.qq.com/docs/merchant/apis/h5-payment/h5-transfer-payment.html
*/
function _miniProgramPay(payInfo) {
return new Promise(async (resolve, reject) => {
// 请求线上获取 res:{ appId,timeStamp,nonceStr,paySign,package,signType,mwebUrl,codeUrl,merchant_id,out_trade_no }
const res = await _doWechatPayRequest({
from: ServicePayType['1'],
paytype: ServicePayType['1'],
uni: payInfo.orderId
})
uni.requestPayment({
timeStamp: res.timeStamp,
nonceStr: res.nonceStr,
signType: res.signType,
paySign: res.paySign,
package: res.package,
provider: WechatProvider,
success: (res) => resolve(createMessage('用户支付成功', res)),
fail: (error) => reject(createMessage('用户支付失败', error))
})
})
}
/**
* 微信内H5支付
* @param payInfo
* @private
* @docs https://pay.weixin.qq.com/docs/merchant/apis/h5-payment/h5-transfer-payment.html
*/
async function _h5InWechatPay(payInfo) {
return new Promise(async (resolve, reject) => {
// 请求线上获取 res:{ appId,timeStamp,nonceStr,paySign,package,signType,mwebUrl,codeUrl,merchant_id,out_trade_no }
const res = await _doWechatPayRequest({
from: 'h5',
paytype: ServicePayType['0'],
uni: payInfo.orderId
})
/** 注册JS SDK */
jweixin.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来若要查看传入的参数可以在pc端打开参数信息会通过log打出仅在pc端时才会打印。
appId: res.appId, // 必填,公众号的唯一标识
timestamp: res.timeStamp, // 必填,生成签名的时间戳
nonceStr: res.nonceStr, // 必填,生成签名的随机串
signature: res.paySign, // 必填签名见附录1
jsApiList: ['chooseWXPay'] // 必填需要使用的JS接口列表所有JS接口列表见附录2
});
/** JS SDK 可使用状态 */
jweixin.ready(() => {
/** 检查JS SDK API是否可用 */
jweixin.checkJsApi({
jsApiList: ['chooseWXPay'], // 需要检测的JS接口列表所有JS接口列表见附录2,
success: () => {
},
fail: (error) => {
return reject(createMessage('微信版本过低,请升级微信版本', error))
}
});
/** 去拉起微信支付 */
jweixin.chooseWXPay({
timestamp: res.timeStamp, // 支付签名时间戳注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
nonceStr: res.nonceStr, // 支付签名随机串,不长于 32 位
package: res.package, // 统一支付接口返回的prepay_id参数值提交格式如prepay_id=***
signType: res.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
paySign: res.paySign, // 支付签名
success: (res) => {
// 支付成功后的回调函数
uni.setStorageSync(CacheKey.PAY_INFO, JSON.stringify(
{
from: 'h5',
paytype: ServicePayType['0'],
uni: payInfo.orderId
}
))
setTimeout(() => {
uni.redirectTo({url: '/pages/payStatus/index'})
}, 3000)
return resolve(createMessage('用户支付成功', res))
},
cancel: (r) => {
return reject(createMessage('用户取消支付', {}))
},
fail: (error) => {
return reject(createMessage('跳转微信支付失败', error))
}
});
});
/** JS SDK发生错误 */
jweixin.error((error) => {
return reject(createMessage('JS-SDK加载错误', error))
});
})
}
/**
* 微信外H5支付
* @param payInfo
* @private
*/
async function _h5OutWechatPay(payInfo) {
const res = await _doWechatPayRequest({
from: 'h5',
paytype: ServicePayType['0'],
uni: payInfo.orderId
})
if (res && res.mwebUrl) {
// 缓存支付订单数据
uni.setStorageSync(CacheKey.PAY_INFO, JSON.stringify(
{
from: 'h5',
paytype: ServicePayType['0'],
uni: payInfo.orderId
}
))
location.replace(res.mwebUrl)
return Promise.resolve(createMessage('用户支付成功', {type: 'h5'}))
} else {
return Promise.reject(createMessage('服务端拉起支付失败', {type: 'h5', error: res}))
}
}
/**
* 支付宝支付
* @param payInfo
*/
function _aliPay(payInfo) {
return Promise.reject("暂不支持支付宝支付")
}
/**
* 请求服务端获取支付信息
* @param data {{from:string, paytype: string, uni: string }}
* @returns {Promise<*>}
* @private
*/
async function _doWechatPayRequest(data) {
return await wechatPay(data)
}

View File

@ -1,63 +1,63 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var stringifyPrimitive = function (v) {
switch (typeof v) {
case 'string':
return v
case 'boolean':
return v ? 'true' : 'false'
case 'number':
return isFinite(v) ? v : ''
default:
return ''
}
}
function stringify(obj, sep, eq, name) {
sep = sep || '&'
eq = eq || '='
if (obj === null) {
obj = undefined
}
if (typeof obj === 'object') {
return Object.keys(obj).map(function (k) {
var ks = stringifyPrimitive(k) + eq
if (Array.isArray(obj[k])) {
return obj[k].map(function (v) {
return ks + stringifyPrimitive(v)
}).join(sep)
} else {
return ks + stringifyPrimitive(obj[k])
}
}).filter(Boolean).join(sep)
}
if (!name) return ''
return stringifyPrimitive(name) + eq + stringifyPrimitive(obj)
}
export default stringify
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var stringifyPrimitive = function (v) {
switch (typeof v) {
case 'string':
return v
case 'boolean':
return v ? 'true' : 'false'
case 'number':
return isFinite(v) ? v : ''
default:
return ''
}
}
function stringify(obj, sep, eq, name) {
sep = sep || '&'
eq = eq || '='
if (obj === null) {
obj = undefined
}
if (typeof obj === 'object') {
return Object.keys(obj).map(function (k) {
var ks = stringifyPrimitive(k) + eq
if (Array.isArray(obj[k])) {
return obj[k].map(function (v) {
return ks + stringifyPrimitive(v)
}).join(sep)
} else {
return ks + stringifyPrimitive(obj[k])
}
}).filter(Boolean).join(sep)
}
if (!name) return ''
return stringifyPrimitive(name) + eq + stringifyPrimitive(obj)
}
export default stringify

View File

@ -1,12 +1,6 @@
import { parseUrl } from '@/utils'
export function navigateTo(location, complete, fail, success) {
console.log({
url: parseUrl(location),
complete,
fail,
success,
})
uni.navigateTo({
url: parseUrl(location),
complete,

148
utils/utils.js Normal file
View File

@ -0,0 +1,148 @@
export function formatDate(date, format) {
const year = date.getFullYear().toString();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
const hours = date.getHours().toString().padStart(2, '0');
const minutes = date.getMinutes().toString().padStart(2, '0');
const seconds = date.getSeconds().toString().padStart(2, '0');
return format
.replace(/yyyy/g, year)
.replace(/MM/g, month)
.replace(/dd/g, day)
.replace(/HH/g, hours)
.replace(/mm/g, minutes)
.replace(/ss/g, seconds);
}
/**
* 正则检测大陆手机号
* @param phone
*/
export function checkPhone(phone) {
return /^1[3456789]\d{9}$/.test(phone);
}
/**
* 创建一个滚动动画
* @param scrollStart 动画开始滚动位置
* @param scrollEnd 动画结束滚动位置
* @param valueStart 动画值开始值
* @param valueEnd 动画值结束值
*/
export function createAnimation(scrollStart, scrollEnd, valueStart, valueEnd) {
return function (nowScroll) {
if (nowScroll <= scrollStart) {
return valueStart
}
if (nowScroll >= scrollEnd) {
return valueEnd
}
// (nowScroll - scrollStart) / (scrollEnd - scrollStart) 当前滚动在咕哝的那个起始值中的比例
// 用value的总值 * 比例 = value的值
// 由于valueStart可能不是0 所以需要加上valueStart
return ((valueEnd - valueStart) * (nowScroll - scrollStart) / (scrollEnd - scrollStart)) + valueStart
}
}
/**
* 从数组中找到比较项并且删除
* @param originalList 原数组
* @param compareItem 比较项目
* @param field 比较字段
*/
export function compareToDelListItem(originalList, compareItem, field) {
const delIndex = originalList.findIndex((item) => item[field] === compareItem[field]);
if (delIndex >= 0) {
originalList.splice(delIndex, 1);
return true
}
return false
}
/**
* 过滤File类型
* @param file
* @param excludeTypeArr 需要排除的类型
*/
export function filterFileType(file, excludeTypeArr) {
let suffix, name
// #ifndef MP-WEIXIN
name = file.name
suffix = name.slice(name.lastIndexOf('.') + 1)
// #endif
// #ifdef MP-WEIXIN
name = file.url
suffix = name.slice(name.lastIndexOf('.') + 1)
// #endif
return excludeTypeArr.includes(suffix)
}
/**
* 阿拉伯数字转换中文数字
* @param number
*/
export function arabicToChinese(number) {
const chineseNumberMap = {
0: '零',
1: '一',
2: '二',
3: '三',
4: '四',
5: '五',
6: '六',
7: '七',
8: '八',
9: '九',
10: '十'
};
const chineseUnitMap = {
10: '十',
100: '百',
1000: '千',
10000: '万',
100000: '十万',
1000000: '百万',
10000000: '千万',
100000000: '亿',
1000000000: '十亿',
10000000000: '百亿',
100000000000: '千亿',
1000000000000: '兆'
};
if (number <= 10) {
return chineseNumberMap[number]
}
let chineseNumber = '';
let num = number;
for (let unit of [1000000000000, 100000000000, 10000000000, 1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1]) {
if (num >= unit) {
let count = Math.floor(num / unit);
chineseNumber += chineseNumberMap[count] + (chineseUnitMap[unit] ? chineseUnitMap[unit] : '');
num %= unit; // 取余
} else if (chineseNumber !== '') {
chineseNumber += chineseNumberMap[0]; // 添加零,保持位数对齐
}
}
return chineseNumber;
}
export function hasNetWork() {
return new Promise < boolean > ((resolve, reject) => {
wx.getNetworkType({
success(res) {
console.log(res);
if (res.networkType === 'none') {
resolve(false)
} else {
resolve(true)
}
}
})
})
}