jiuyiUniapp/jiuyi2/common/js/util.js

1611 lines
37 KiB
JavaScript
Raw Normal View History

2024-12-18 15:46:27 +08:00
// vuex
import store from '@/store'
// 配置
import config from '@/common/js/config.js'
// 接口
import api from '@/api/index.js'
// 工具库
const util = {
// 配置参数
config,
// 正则
reg: {
// 手机号
tel: /^1[3-9]\d{9}$/,
// 身份证
idCard: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/,
},
/**
* 弹窗
* @param {Object|String} obj String类型只是弹出文字 object如下
* @param {String} obj.title 弹窗的标题
* @param {String} obj.content 弹窗的内容
* @param {String} obj.confirmText 确定的文本
* @param {String} obj.showCancel 是否显示取消
* @param {String} obj.cancelText 取消的文本
* @param {Function} params.success 请求成功回调 可通过promise.then捕获
* @param {Function} params.fail 请求失败回调 可通过promise.catch捕获
* @param {Function} params.complete 请求结束回调 无论是否成功失败都会执行
* @return {Object} string返回null object返回返回promis对象 执行成功返回resolve 执行失败返回reject
*/
alert(obj) {
// 没值
if (obj == null || obj == undefined) return
// 这个地方说白了就是 如果只是想提示一句话一个文本的话 就只是弹个小tips
if (typeof obj == "string" || typeof obj == "number") {
uni.showToast({
'title': "" + obj + "",
'icon': 'none',
duration: 3000,
});
return null
}
// 标题
obj.title = obj.title ? obj.title : ""
// 提示内容
obj.content = obj.content ? obj.content : ""
// 确定文本
obj.confirmText = obj.confirmText ? obj.confirmText : "确定"
// 取消按钮
obj.showCancel = obj.showCancel === false ? false : true
// 取消文本
obj.cancelText = obj.cancelText ? obj.cancelText : "取消"
// 返回 Promise 对象
return new Promise((resolve, reject) => {
// 调起
uni.showModal({
title: obj.title,
content: obj.content,
confirmText: obj.confirmText,
showCancel: obj.showCancel,
cancelText: obj.cancelText,
success: res => {
obj.success ? obj.success(res) : () => {}
2024-12-18 15:46:27 +08:00
resolve(res)
},
fail: err => {
obj.fail ? obj.fail(err) : () => {}
2024-12-18 15:46:27 +08:00
reject(err)
},
complete: res => {}
2024-12-18 15:46:27 +08:00
})
})
},
/**
* 上传文件
* @param {Object} obj
* @param {String} obj.mode img图片 video视频
*/
upload(obj) {
// 使用promise写请求,一个函数两种回调
return new Promise((resolve, reject) => {
// 默认token
let token = uni.getStorageSync('token') || ''
// 接口地址
2024-12-31 17:07:01 +08:00
obj.url = obj.url ? obj.url : '/file/upload'
2024-12-18 15:46:27 +08:00
// 文件
obj.file = obj.file ? obj.file : ""
// 附加数据
obj.data = obj.data ? obj.data : {}
// 请求头
obj.header = {
// 'Content-Type': 'multipart/form-data; ',
2025-01-02 01:01:23 +08:00
// 'Content-Type': 'application/json;charset=UTF-8',
2024-12-27 15:03:48 +08:00
'Access-Control-Allow-Origin': '*',
2024-12-18 15:46:27 +08:00
...obj.header,
}
if (token) obj.header["Authorization"] = `Bearer ${token}`
// 打开loading效果
uni.showLoading({
title: "正在上传",
})
// 上传
uni.uploadFile({
url: util.config.host + obj.url,
filePath: obj.file,
header: obj.header,
formData: obj.data,
dataType: 'json',
name: 'file',
success: (res) => {
// 关闭loading效果
uni.hideLoading()
// 成功
obj.success ? obj.success(JSON.parse(res.data)) : ''
//
resolve(JSON.parse(res.data))
},
fail: (res) => {
// 关闭loading效果
uni.hideLoading()
// 错误
obj.fail ? obj.fail(res.data) : ''
//
reject(res)
},
2025-02-05 23:29:54 +08:00
complete(rs) {
2025-02-15 16:10:05 +08:00
console.log('upload complete', rs)
2025-02-05 23:29:54 +08:00
}
2024-12-18 15:46:27 +08:00
})
})
},
/**
* 发送网络请求
* @param {Object} params 传参
* @param {String} params.url 请求地址 一般用于后台请求接口
* @param {Array} params.query 请求地址拼接参数 用于后台请求地址拼接补全
* @param {String} params.fullurl 全请求地址 一般用于第三方请求地址
* @param {Boolean} params.load 是否显示加载动画 默认不显示
* @param {Object} params.data 请求入参 没有则不传
* @param {Object} params.header 请求头 默认不传
* @param {String} params.method 请求方式 默认值POST
* @param {Function} params.success 请求成功回调 可通过promise.then捕获
* @param {Function} params.fail 请求失败回调 可通过promise.catch捕获
* @param {Function} params.complete 请求结束回调 无论是否成功失败都会执行
* @return {Object} 返回promis对象 执行成功返回resolve 执行失败返回reject
*/
request(params) {
// 默认token
let token = uni.getStorageSync('token') || ''
// 返回方法
return new Promise((resolve, reject) => {
// 请求地址
let url = util.config.host + (params.url ? params.url : '/api/index/index')
// 是否path拼接参数
if (params.path && params.path instanceof Array) params.path.forEach(item => {
url += `/${item}`
})
// 是否query拼接参数
if (params.query) {
url = util.setUrl(url, params.query)
}
// 是否打开加载效果
if (params.load) {
uni.showLoading({
title: "加载中",
mask: true,
})
}
// 请求头
params.header = {
'Content-Type': 'application/json;charset=UTF-8',
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',
// token: uni.getStorageSync('token'),
'Access-Control-Allow-Origin': '*',
'IS_APP_REQ': 'APP_REQ',
...params.header,
}
if (token) params.header["Authorization"] = `Bearer ${token}`
2024-12-31 14:46:56 +08:00
// console.log('request url', url)
// console.log('request data', params.data)
// console.log('request header', params.header)
2024-12-18 15:46:27 +08:00
// console.log('params.responseType', url, params.responseType)
// 发起网络请求
uni.request({
// 请求地址
url: url,
// 请求方式 get/post
method: params.method ? params.method : "POST",
// 是否开启SSL验证
sslVerify: false,
// 请求参数
data: params.data,
// header请求头
header: params.header,
// 数据类型
dataType: 'json',
responseType: params.responseType || 'text',
// 请求成功返回
success: res => {
2025-02-23 13:32:05 +08:00
console.log('request success', url, res, params.data ? params.data : '')
2024-12-18 15:46:27 +08:00
// 关闭加载效果
if (params.load) {
uni.hideLoading()
}
// 401
if (res.data.code == 401) {
// 登出
util.logout(() => {
2025-02-28 13:09:49 +08:00
util.alert(res.data.msg)
2025-02-23 13:32:05 +08:00
reject(res.data)
2025-02-28 13:09:49 +08:00
uni.redirectTo({
url: '/pages/login/loginPhone',
})
2024-12-18 15:46:27 +08:00
})
}
// 嵌套式回调
params.success ? params.success(res.data) : ''
// 链式回调
resolve(res.data);
},
// 请求失败返回
fail: res => {
2025-01-12 22:17:52 +08:00
console.log('request fail', url, res, params.data ? params.data : '')
2024-12-18 15:46:27 +08:00
// 关闭加载效果
if (params.load) {
uni.hideLoading()
}
// 嵌套式回调
params.fail ? params.fail(res) : ''
// 链式回调
reject(res)
},
complete(res) {
2025-01-02 01:01:23 +08:00
// console.log('complete', url, res);
2024-12-18 15:46:27 +08:00
// 嵌套式回调
params.complete ? params.complete(res) : ''
},
})
})
},
2025-02-21 10:03:50 +08:00
/**
* 替换图片的宽度为最大宽度100% (移动端解析html富文本专用)
* @param {Object} value 富文本
*/
imgReplace(value) {
2024-12-18 15:46:27 +08:00
return value.replace(/<p([\s\w"=\/\.:;]+)((?:(style="[^"]+")))/ig, '<p')
.replace(/<p>/ig, '<p style="font-size: 15px; line-height: 25px;">')
.replace(/<img([\s\w"-=\/\.:;]+)((?:(height="[^"]+")))/ig, '<img$1')
.replace(/<img([\s\w"-=\/\.:;]+)((?:(width="[^"]+")))/ig, '<img$1')
.replace(/<img([\s\w"-=\/\.:;]+)((?:(style="[^"]+")))/ig, '<img$1')
.replace(/<img([\s\w"-=\/\.:;]+)((?:(alt="[^"]+")))/ig, '<img$1')
.replace(/<img([\s\w"-=\/\.:;]+)/ig, '<img style="width: 100%;" $1')
},
/**
* 路由跳转方法
* @param {string} url 跳转的目标页面路径
* @param {Object} params 要传递的参数对象
* @param {string} method 跳转方法默认为 navigateTo
*/
routeWithParams(url, params = {}, method = 'navigateTo') {
// const paramStr = Object.keys(params).length > 0 ? '?' + new URLSearchParams(params) : '';
// const fullUrl = `${url}${paramStr}`;
const fullUrl = util.setUrl('url', params)
switch (method) {
case 'navigateTo':
uni.navigateTo({
url: fullUrl
});
break;
case 'redirectTo':
uni.redirectTo({
url: fullUrl
});
break;
case 'reLaunch':
uni.reLaunch({
url: fullUrl
});
break;
case 'switchTab':
uni.switchTab({
url: fullUrl
});
break;
default:
throw new Error(`Unsupported method: ${method}`);
}
},
/**
* get参数拼接
* @param {Object} data 需要转化的对象
*/
set_param(data) {
// 初始路径
let url = ''
// 格式化
if (!data) data = []
// 遍历
for (let [key, value] of Object.entries(data)) {
url += `${key}=${value}&`
}
// 判断最后一个是不是& 是就删除& 不是就放回url
url = url.substring(url.length - 1) == '&' ? url.substring(0, url.length - 1) : url
return url ? url : url.substring(1)
},
/**
* get参数拼接url
* @param {String} url 需要处理的url
* @param {Object} data 需要转化的Object对象
*/
setUrl(url, data) {
let result = url += (url.indexOf('?') < 0 ? '?' : '&') + util.set_param(data)
return result
},
/**
* query字符串转对象
* @param {Object} str query字符串
*/
query_to_param(str) {
let obj = {}
decodeURIComponent(str).split('&').forEach(item => {
let [key, val] = item.split('=');
obj[key] = val
})
return obj
},
/**
* 倒计时
* @param {String} endtime 结束时间
*/
countDownd(endtime) {
if (!endtime) {
return
}
endtime = Number(endtime)
let timestamp = Date.parse(new Date()) / 1000
if (endtime > 100000) {
// 距离结束的秒数
let time = (endtime - timestamp)
} else {
let time = endtime
}
// 获取天、时、分、秒
let day = util.timeFormin(parseInt(time / (60 * 60 * 24)))
let hou = util.timeFormin(parseInt(time % (60 * 60 * 24) / 3600))
let min = util.timeFormin(parseInt(time % (60 * 60 * 24) % 3600 / 60))
let sec = util.timeFormin(parseInt(time % (60 * 60 * 24) % 3600 % 60))
let str = "";
if (day) {
str += day + "天"
}
if (hou || hou == 0) {
if (hou > 9) {
str += hou + ":"
} else {
str += "0" + hou + ":"
}
} else {
str += "00:"
}
if (min || min == 0) {
if (min > 9) {
str += min + ":"
} else {
str += "0" + min + ":"
}
} else {
str += "00:";
}
if (sec) {
if (sec > 9) {
str += sec;
} else {
str += "0" + sec
}
} else {
str += "00"
}
return str
},
// 格式化时间
timeFormin(param) {
return param < 0 ? 0 : param;
},
/**
* 对二补齐
* @param {String} str 数字或数字字符串
*/
toTwo(str) {
// 格式化字符
let num = String(Number(str));
// 判断时间
if (num.length < 2) {
num = '0' + num;
}
// 返回时间
return num;
},
/**
* 时间戳处理成时间
* @param {Object} str
* 时间格式 单个字母不补0
* yyyy
* MM
* dd
* WW
* HH 小时 24小时制
* hh 小时 12小时制
* mm 分钟
* ss
* a am/pm
* 比如 'yyyy-MM-dd HH:mm:ss 周w a' 返回2023-02-06 11:19:19 周一 pm
* @param {Number} timestamp 需要处理时间戳
*/
formatTime(str, timestamp) {
// 当前时间
const nowDate = new Date()
// 周列表 歪果仁把周日放在第一位
let weekList = ['日', '一', '二', '三', '四', '五', '六']
// 格式化字符串
if (!str || typeof str != 'string') {
str = 'yyyy-MM-dd HH:mm:ss'
}
// 格式化时间戳
if (!timestamp) {
timestamp = nowDate.valueOf()
} else if (String(timestamp).length <= 10) {
// 时间
timestamp = timestamp * 1000
}
// 时间
const date = new Date(timestamp)
// 获取对应时间
let year = date.getFullYear(),
moth = date.getMonth() + 1,
day = date.getDate(),
week = date.getDay(),
hour = date.getHours(),
minute = date.getMinutes(),
second = date.getSeconds()
// 处理年
str = str.replace('yyyy', year)
// 处理月份
str = str.replace('MM', this.toTwo(moth))
str = str.replace('M', moth)
// 处理日
str = str.replace('dd', this.toTwo(day))
str = str.replace('d', day)
// 处理周
str = str.replace('w', weekList[week])
// 处理小时
if (str.match('h')) {
// 12小时制
hour = hour > 12 ? hour - 12 : hour
// 12小时制
str = str.replace('hh', this.toTwo(hour))
str = str.replace('h', hour)
} else if (str.match('H')) {
// 24小时制
str = str.replace('HH', this.toTwo(hour))
str = str.replace('H', hour)
}
// 处理分钟
str = str.replace('mm', this.toTwo(minute))
str = str.replace('m', minute)
// 处理秒
str = str.replace('ss', this.toTwo(second))
str = str.replace('s', second)
// 处理是上午还是下午
let a = hour > 12 ? 'am' : 'pm'
str = str.replace('a', a)
return str
},
/**
* 时间计算
* @param {String} format 格式化 规则
* format '+1 month' 往后一个月
* @param {Number} value 需要处理的时间戳 单位秒
*/
strtotime(format, value) {
// 处理时间 精确到秒的函数
if (value && format.indexOf(" ") > -1) {
// 单位
let unit = format.split(" ")
let pre = unit[0]
let next = unit[1]
// 格式化时间戳
if (!value) value = nowDate.valueOf()
else if (String(value).length <= 10) value = value * 1000
//创建date变量
let nowDate = new Date(value)
switch (next) {
case "year":
nowDate.setYear(nowDate.getFullYear() + parseInt(pre))
break
case "month":
nowDate.setMonth(nowDate.getMonth() + parseInt(pre))
break
case "day":
nowDate.setDate(nowDate.getDate() + parseInt(pre))
break
case "week":
nowDate.setDate(nowDate.getDate() + (parseInt(pre) * 7));
break
case "hour":
nowDate.setHours(nowDate.getHours() + (parseInt(pre)));
break
case "minute":
nowDate.setMinutes(nowDate.getMinutes() + (parseInt(pre)));
break
}
return nowDate.getTime()
} else {
//创建date变量
var nowDate = new Date(value)
return nowDate.getTime()
}
},
/**
* 上传图片
* @param {Object} obj 对象类型
* @param {Array} obj.value 操作的对象
* @param {Boolean} obj.unlimited 不限制
* @param {Number} obj.count 图片计数
* @param {Number} obj.type 1单张 2多张
* @param {Array} obj.sourceType ['album', 'camera']
* @param {Function} obj.success 执行成功返回的方法return修改的对象
*/
2025-01-09 09:06:53 +08:00
upload_image(obj) { // 格式化默认值
2024-12-18 15:46:27 +08:00
// 图片计数
2025-01-09 09:06:53 +08:00
const count = obj.count ? obj.count : 8;
2025-01-06 14:04:49 +08:00
// 多张图片
2025-01-09 09:06:53 +08:00
if (!obj.type) obj.type = 2;
2024-12-18 15:46:27 +08:00
// 操作对象
2025-01-09 09:06:53 +08:00
// 修正逻辑判断
if (obj.value == '' || obj.value == undefined || obj.value == null) obj.value = obj.type == 1 ? '' : [];
2024-12-18 15:46:27 +08:00
// 判断剩余图片上传个数
if (obj.value.length >= count && obj.type == 2) {
// 弹窗提示
2025-01-09 09:06:53 +08:00
util.alert('上传图片已达上限');
return;
2024-12-18 15:46:27 +08:00
}
// 选择图片
uni.chooseImage({
// 限制图片
count: obj.type == 1 ? 1 : count - obj.value.length,
2025-01-09 09:06:53 +08:00
sourceType: obj.sourceType || ['album', 'camera'],
2024-12-18 15:46:27 +08:00
success: (rs) => {
// 遍历图片返回列表
rs.tempFiles.forEach(item => {
// 限制大小
2025-01-09 09:06:53 +08:00
let size = 1024 * 1024 * util.config.img_size;
2024-12-18 15:46:27 +08:00
if (item.size > size && !obj.unlimited) {
2025-01-09 09:06:53 +08:00
util.alert(`大小超过${util.config.img_size}m`);
return;
2024-12-18 15:46:27 +08:00
}
// 调用上传图片
util.upload({
file: item.path,
mode: 'img',
success(res) {
if (res.code === 200) {
uni.getImageInfo({
src: item.path,
success: imageInfo => {
const result = res.data.url;
obj.success && obj.success({
value: result,
width: imageInfo.width,
height: imageInfo.height,
});
},
})
2025-01-09 09:06:53 +08:00
return;
2024-12-18 15:46:27 +08:00
}
2025-01-09 09:06:53 +08:00
util.alert(rs.msg);
2024-12-18 15:46:27 +08:00
},
2025-01-09 09:06:53 +08:00
});
});
2024-12-18 15:46:27 +08:00
},
fail(rs) {
if (rs.errMsg == "chooseImage:fail cancel") {
// 取消选择
}
},
2025-01-09 09:06:53 +08:00
});
2024-12-18 15:46:27 +08:00
},
/**
* 上传视频
* @param {Object} obj 对象类型
* @param {Array} obj.value 操作的对象
* @param {Object} obj.unlimited 不限制
* @param {Object} obj.count 计数
* @param {Object} obj.success 执行成功返回的方法return修改的对象
*/
upload_video(obj) {
// 视频计数
const count = obj.count ? obj.count : 1
// 选择视频
uni.chooseVideo({
compressed: false,
success(rs) {
// 限制大小
// let size = 1024 * 1024 * util.config.video_size
// if (rs.size > size && !obj.unlimited) {
// util.alert(`大小超过${util.config.video_size}m`)
// return
// }
// 调用上传视频
util.upload({
file: rs.tempFilePath,
mode: 'video',
success(res) {
// 上传成功
if (res.code == 200) {
2025-01-02 01:01:23 +08:00
// const fullUrl = util.format_url(res.msg, 'video')
2024-12-18 15:46:27 +08:00
obj.success && obj.success({
2025-01-02 01:01:23 +08:00
value: res.data.url,
width: rs.width,
height: rs.height,
size: rs.size,
duration: rs.duration,
// value: fullUrl,
2024-12-18 15:46:27 +08:00
})
return
} else {
util.alert(res.msg)
}
},
})
},
fail(rs) {
if (rs.errMsg == "chooseImage:fail cancel") {
// 取消选择
}
},
})
},
/**
* 上传文件
* @param {Object} obj 对象类型
* @param {Array} obj.value 操作的对象
* @param {Object} obj.count 计数
* @param {Object} obj.success 执行成功返回的方法return修改的对象
*/
upload_files(obj) {
const value = obj.value
// 限制目录
const file_suffix = util.config.file_suffix
// 默认值
const count = obj.count ? obj.count : 1
// 判断剩余图片上传个数
if (value.length >= count) {
// 弹窗提示
util.alert('上传数量已达上限')
return
}
console.log('upload_files', obj)
/**
* 结算方法
* @param {Object} path
*/
function result_fn(path) {
// 上传文件的后缀名
let str = path.split('.').pop().toLowerCase()
// 结果
let reult = file_suffix.find(node => node.id == str)
// 验证
if (!reult) {
util.alert(`不能上传${str}格式文件`)
return
}
// 上传文件
util.upload({
file: path,
success(res) {
if (res.code == 200) {
value.push(res.data)
// 执行方法
obj.success && obj.success({
...res.data,
value,
})
} else {
util.alert(res.msg)
}
},
})
}
// #ifdef MP-WEIXIN
// 从微信聊天里面选择文件
wx.chooseMessageFile({
count: 1,
type: 'file',
// 文件过滤
extension: file_suffix.map(node => node.id),
success: (rs) => {
// 遍历数组
rs.tempFiles.forEach((e, i) => {
result_fn(e.path)
})
},
})
return
// #endif
// #ifdef APP-PLUS
if (uni.getSystemInfoSync().platform == "android") {
console.log('chooseFile')
chooseFile((rs) => {
console.log('rs', rs)
result_fn(rs)
})
} else {
util.alert('因权限问题暂不支持非android平台')
}
return
// #endif
util.alert('暂未开放')
},
/**
* 上传音频
* @param {Object} obj 对象类型
* @param {Array} obj.value 操作的对象
* @param {Object} obj.count 计数
* @param {Object} obj.success 执行成功返回的方法return修改的对象
*/
upload_audio(obj) {
const value = obj.value
// 限制目录
const audio_suffix = util.config.audio_suffix
// 默认值
const count = obj.count ? obj.count : 1
// 判断剩余图片上传个数
if (value.length >= count) {
// 弹窗提示
util.alert('上传数量已达上限')
return
}
/**
* 结算方法
* @param {Object} path
*/
function result_fn(path) {
// 上传文件的后缀名
let str = path.split('.').pop().toLowerCase()
// 结果
let reult = audio_suffix.find(node => node.id == str)
// 验证
if (!reult) {
util.alert(`不能上传${str}格式文件`)
return
}
// 上传文件
util.upload({
file: path,
success(res) {
if (res.code == 200) {
value.push(res.data)
// 执行方法
obj.success && obj.success({
...res.data,
value,
})
} else {
util.alert(res.msg)
}
},
})
}
// #ifdef MP-WEIXIN
// 从微信聊天里面选择文件
wx.chooseMessageFile({
count: 1,
type: 'file',
// 文件过滤
extension: audio_suffix.map(node => node.id),
success: (rs) => {
// 遍历数组
rs.tempFiles.forEach((e, i) => {
result_fn(e.path)
})
},
})
return
// #endif
// #ifdef APP-PLUS
if (uni.getSystemInfoSync().platform == "android") {
chooseFile((rs) => {
console.log('chooseFile', rs);
result_fn(rs)
})
} else {
util.alert('因权限问题暂不支持非android平台')
}
return
// #endif
util.alert('暂未开放')
},
/**
* 视频转封面 oss特有
* @param {Object} url 视频路径
*/
video_coverImage(url) {
let result = `${url}?x-oss-process=video/snapshot,t_1,m_fast`
return result
},
/**
* 预览图片
* @param {Array} urls 图片列表
* @param {Number} current 当前预览的下标
*/
view_imgs(urls, current) {
// 格式化
if (!urls || urls.length == 0) {
util.alert('暂无')
return
}
uni.previewImage({
urls,
current,
})
},
/**
* 通过路径获取文件后缀
* @param {Object} url 需要获取的文件路径
* @param {Object} type file文件 audio音频
* @return {Object} 返回后缀列表对象 util.config.file_suffix
*/
get_file_suffix(url, type) {
if (!type) type = 'file'
// 文件后缀
const file_suffix = util.config[{
'file': 'file_suffix',
'audio': 'audio_suffix',
} [type]]
2024-12-18 15:46:27 +08:00
let result = ''
if (url) result = file_suffix.find(item => item.id === url.split('.').pop().toLowerCase())
return result
},
2024-12-18 15:46:27 +08:00
/**
* 通过路径获取音频后缀
* @param {Object} url 需要获取的文件路径
* @return {Object} 返回后缀列表对象 util.config.file_suffix
*/
get_audio_suffix(url) {
// 文件后缀
const audio_suffix = util.config.audio_suffix
let result = ''
if (url) result = audio_suffix.find(item => item.id === url.split('.').pop().toLowerCase())
return result
},
/**
* 调起支付
* @param {Object} obj 操作对象
* @param {String} obj.payType 支付方式 WeChat微信 AliPay支付宝 4钱包
* @param {String} obj.method 支付环境 app手机应用 mp小程序
* @param {String} obj.debug 调试模式
* @param {Boolean|Object} obj.cb 支付结果跳转 false为不跳转 跳转需携带object定义对象
* @param {String} obj.cb.styles 风格 style1蓝色 style2绿色 style3橙色
* @param {String} obj.cb.result 结果 success成功 fail失败
* @param {String} obj.cb.price 价格
* @param {String} obj.cb.url 跳转的详情路径
* @param {Function} obj.fn 请求接口函数
* @param {Function} obj.success 成功方法
* @param {Function} obj.fail 失败方法
* @param {Function} obj.complete 结束方法
*/
payment(obj) {
// 参数必须是对象
obj = obj ? obj : {}
// 支付参数
obj.data = obj.data ? obj.data : {}
// 付款类型
// #ifdef APP
obj.method = 'app'
// 支付请求
util.payment_request(obj)
// #endif
// #ifdef MP-WEIXIN
obj.method = 'mp'
// 登录
uni.login({
success: (rs) => {
// code
obj.data.code = rs.code
// 支付请求
util.payment_request(obj)
}
})
// #endif
},
// 支付请求
payment_request(obj) {
obj.debug ? console.log('params', obj) : ""
if (!obj.fn) {
throw 'no function'
}
/**
* 结果跳转
* @param {Object} result success成功 fail失败
*/
function result_goto(result) {
const cb = obj.cb
if (!cb) return
// 跳转到订单结果
uni.redirectTo({
url: util.setUrl('/index/pay_result', {
orderNumber: cb.orderNumbers || '',
result,
styles: cb.styles || '',
price: cb.price || '',
url: cb.url || '',
}),
})
}
// 支付方法
obj.fn(obj.data).then(rs => {
// 调试模式
obj.debug ? console.log('request success result', rs) : ""
if (rs.code == 200) {
// 根据对应类型吊起支付
switch (obj.data.payType) {
// 微信支付
case "1":
switch (obj.method) {
// 小程序支付
case "mp":
if (rs.data && rs.data.paySign) {
uni.requestPayment({
provider: "wxpay",
timeStamp: rs.data.timeStamp,
package: rs.data.package,
nonceStr: rs.data.nonceStr,
paySign: rs.data.paySign,
signType: rs.data.signType,
success(result) {
obj.success ? obj.success(rs) : ''
result_goto('success')
},
fail(result) {
obj.fail ? obj.fail(result) : ''
result_goto('fail')
},
complete(result) {
obj.debug ? console.log('requestPayment complete',
result) : ""
obj.complete ? obj.complete(result) : ''
}
})
} else {
obj.fail ? obj.fail('no data') : ''
}
break
// app支付
2024-12-18 15:46:27 +08:00
case "app":
uni.requestPayment({
provider: "wxpay",
orderInfo: rs.data,
success(result) {
obj.success ? obj.success(rs) : ''
result_goto('success')
},
fail(result) {
obj.fail ? obj.fail(result) : ''
result_goto('fail')
},
complete(result) {
obj.debug ? console.log('requestPayment complete', result) :
""
obj.complete ? obj.complete(result) : ''
}
})
break
}
break
// 支付宝支付
2024-12-18 15:46:27 +08:00
case "2":
switch (obj.method) {
// app支付
case "app":
uni.requestPayment({
provider: "alipay",
orderInfo: rs.msg,
success(result) {
obj.success ? obj.success(rs) : ''
result_goto('success')
},
fail(result) {
obj.fail ? obj.fail(result) : ''
result_goto('fail')
},
complete(result) {
obj.debug ? console.log('requestPayment complete', result) :
""
obj.complete ? obj.complete(result) : ''
}
})
break
}
break
// 钱包支付
2024-12-18 15:46:27 +08:00
case "4":
obj.success ? obj.success(rs) : ''
result_goto('success')
break
}
} else {
util.alert(rs.msg)
// 失败
obj.fail ? obj.fail(rs) : ''
}
}).catch(rs => {
console.log('request catch result', rs);
})
},
// 微信小程序登录
weChatLogin(obj) {
// 格式化
obj = obj ? obj : {}
const parent_id = uni.getStorageSync('parent_id')
const admin_id = uni.getStorageSync('admin_id')
// 获取用户信息
uni.getUserProfile({
desc: "weixin",
success: e => {
// 用户信息
const userInfo = e.userInfo
// 定义用户数据
let data = {
nickName: userInfo.nickName,
avatarUrl: userInfo.avatarUrl,
}
// 调用登录
uni.login({
provider: "weixin",
success: rs => {
data.code = rs.code
data.platform = "wechatMini"
// 邀请人ID
if (parent_id) data.parent_id = parent_id
// 后台业务员的ID
if (admin_id) data.admin_id = admin_id
// 如果获得code
if (rs.errMsg == "login:ok") {
// 请求接口
util.request({
url: "/api/user/third",
data,
load: 1,
}).then(res => {
// 如果操作成功
if (res.code == 200) {
// 最终登录
// util.final_login()
// 成功
obj.success ? obj.success(res) : ''
}
})
}
},
})
},
fail(res) {
util.alert("您拒绝了授权");
// 失败
obj.fail ? obj.fail(res) : (res) => {};
2024-12-18 15:46:27 +08:00
},
complete() {
// 结束
obj.complete ? obj.complete() : ''
},
});
},
/**
* 最终登录 用于请求登录接口后统一调用的登录方法
* @param {Object} param 数据对象
* @param {Function} cb 回调函数
*/
finalLogin(param, cb) {
2025-02-23 13:32:05 +08:00
// 登录令牌
const token = param.data
// 缓存token
uni.setStorageSync('token', token)
// 开启加载
uni.showLoading({
mask: true
})
setTimeout(() => {
2025-02-17 19:26:33 +08:00
// 获取用户信息
util.getUserinfo((userinfo) => {
// 登录
uni.$emit('login')
setTimeout(() => {
2025-02-21 17:57:08 +08:00
util.loginTencent(userinfo)
2025-02-17 19:26:33 +08:00
uni.reLaunch({
url: '/pages/index/index'
})
}, 500)
//
cb ? cb() : ''
})
2025-02-23 13:32:05 +08:00
}, 500)
2024-12-18 15:46:27 +08:00
},
// 登录腾讯聊天
loginTencent(userinfo) {
2024-12-31 14:46:56 +08:00
api.login.getIMToken({}).then(rs => {
2025-01-06 09:45:10 +08:00
//
const imSig = rs.msg
// #ifdef APP
// 音视频登录
2024-12-18 15:46:27 +08:00
const loginParams = {
SDKAppID: util.config.TChat.SDKAppID,
userID: userinfo.id + '',
2025-01-06 09:45:10 +08:00
userSig: imSig,
2024-12-18 15:46:27 +08:00
}
uni.$TUICallKit.login(loginParams, res => {
if (res.code === 0) {
console.log('[TUICallKit] login success.');
} else {
console.error('[TUICallKit] login failed, failed message = ', res.msg, params);
}
})
// #endif
uni.$chat.login({
userID: userinfo.id + '',
2025-01-06 09:45:10 +08:00
userSig: imSig,
2024-12-18 15:46:27 +08:00
}).then(rs => {
2025-02-22 17:13:30 +08:00
util.updateMyProfile(userinfo)
2024-12-18 15:46:27 +08:00
console.log('im login success', rs)
})
})
},
2025-02-22 17:13:30 +08:00
// 更新im个人资料
updateMyProfile(userinfo) {
// 验证sdk是否准备完毕
let isReady = uni.$chat.isReady();
if (!isReady) {
setTimeout(function() {
2025-02-22 17:13:30 +08:00
util.updateMyProfile(userinfo);
}, 800);
return
}
let obj = {
nick: userinfo.userNickname,
avatar: userinfo.avatar
}
uni.$chat.updateMyProfile(obj).then(res => {
// console.log(res);
})
2025-02-22 17:13:30 +08:00
},
2024-12-18 15:46:27 +08:00
/**
* 获取用户信息
* @param {Function} cb 回调函数
*/
getUserinfo(cb) {
return new Promise(reslove => {
// 请求接口
api.mine.getUserinfo().then(rs => {
if (rs.code === 200) {
2025-01-05 20:06:22 +08:00
reslove(rs.data)
2025-01-06 09:45:10 +08:00
const userinfo = rs.data
2025-01-07 14:56:03 +08:00
// 如果开启了青少年模式
2025-02-04 13:45:10 +08:00
if (userinfo.teenTime) util.getTeenMode(userinfo.teenTime)
2024-12-18 15:46:27 +08:00
// 提交
store.commit('setState', {
key: 'userinfo',
value: userinfo
})
// 用户信息
uni.setStorageSync('userinfo', userinfo)
cb ? cb(userinfo) : ''
}
}).finally(() => {
// 关闭加载
uni.hideLoading()
})
})
},
2025-02-03 20:36:02 +08:00
// 青少年模式
getTeenMode(teenTime) {
// 当前时间
const currentDate = new Date()
// 当前小时
const currentHour = currentDate.getHours()
// 大于八点 小于22点 当前时间小于设定时间
2025-02-04 13:45:10 +08:00
const result = currentHour >= 6 && currentHour < 22 && currentDate.valueOf() < new Date(teenTime).valueOf()
2025-02-03 20:36:02 +08:00
// 锁定
function lock() {
2025-02-04 13:45:10 +08:00
console.log('lock')
2025-02-03 20:36:02 +08:00
uni.reLaunch({
url: '/pages/login/lock'
})
}
// 结果
if (result) {
2025-02-04 13:45:10 +08:00
console.log('time', new Date(teenTime).valueOf() - currentDate.valueOf())
2025-02-03 20:36:02 +08:00
// 设置定时器
setTimeout(() => {
lock()
}, parseInt(new Date(teenTime).valueOf() - currentDate.valueOf()))
} else lock()
},
2024-12-18 15:46:27 +08:00
/**
* 验证登录
* @param {Object} cb 回调函数
*/
isLogin(cb) {
// 验证
let userinfo = uni.$store.state.userinfo
return new Promise((resolve, reject) => {
// 登录
if (userinfo.id) {
2025-02-03 09:05:19 +08:00
// 成功
resolve()
// 回调
cb ? cb() : ''
} else reject()
2024-12-18 15:46:27 +08:00
})
},
/**
* 清除登录状态
* @param {Function} cb 回调函数
*/
logout(cb) {
// 用户信息
const userinfo = store.state.userinfo
// 用户id
2025-02-03 09:05:19 +08:00
if (userinfo.id) {
2024-12-18 15:46:27 +08:00
uni.$emit('logout') // 触发自定义事件监听
// tim登出
uni.$chat.logout().then(rs => {
console.log('tim logout rs'); // 登出成功
}).catch(rs => {
console.log('tim logout error:', rs);
});
}
// 把vuex的值改成未登录的状态
store.commit('setState', {
key: 'userinfo',
value: {},
})
uni.removeStorageSync('userinfo') // 删除缓存的用户信息
uni.removeStorageSync('token')
// 回调函数
cb ? cb() : ''
},
// 是否实名
isAuth(param) {
// 验证登录
util.isLogin(() => {
const userinfo = uni.$store.state.userinfo
2025-02-03 20:36:02 +08:00
if (userinfo.isRealName) {
2024-12-18 15:46:27 +08:00
param.success ? param.success(userinfo) : ''
return
}
// 去实名
if (!param.noLink) uni.navigateTo({
url: '/pages/mine/realname',
})
param.fail ? pararm.fail(userinfo) : ''
})
},
// 拨打电话
makePhone(phoneNumber) {
if (!phoneNumber) {
util.alert('暂无手机号')
}
uni.makePhoneCall({
phoneNumber,
fail(err) {
console.log('err', err);
},
})
},
/**
* 处理路径添加host或这默认图片地址
* @param {String} ev 需要处理的字符串
* @param {String} mode img图片 video视频
* @return {String} 返回的路径
*/
format_url(ev, mode) {
if (!ev) return ''
if (ev.match(/^http/)) return ev
return 'https://9yvideo.oss-cn-beijing.aliyuncs.com/' + ev
},
/**
* 去除路径里的host
* @param {Object} ev 需要处理的字符串
* @return {String} 处理之后的路径
*/
replace_url(ev) {
if (!ev || typeof ev != 'string') throw `${ev} is not String`
let result = ev.slice(ev.indexOf('/images') + 1)
return result
},
/**
* 格式化经纬度
* @param {String} num 数字或数字字符串
*/
formart_lnglat(num) {
// 结果
let result = ''
// 结果
if (!num) return num
num = parseFloat(Number(num).toFixed(6))
return num
},
/**
* 检查跳转
* @param {String} route 路径
* @param {String} type 跳转
*/
checkLink(route, type = 'navigateTo') {
// 当前页面栈
const currentPages = getCurrentPages()
// 寻找的页面
const find_route = route
// 寻找下标
const find_index = currentPages.findIndex(node => {
return node.route == find_route
})
// 是否存在
if (find_index < 0) {
uni[type]({
url: `/${find_route}`
})
} else {
uni.navigateBack({
delta: currentPages.length - find_index - 1
})
}
},
/**
* 数字转化
*/
rp(n) {
var cnum = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十'];
var s = '';
n = '' + n; // 数字转为字符串
for (var i = 0; i < n.length; i++) {
s += cnum[parseInt(n.charAt(i))];
}
if (s.length == 2) { // 两位数的时候
// 如果个位数是0的时候0改成十
if (s.charAt(1) == cnum[0]) {
s = s.charAt(0) + cnum[10];
// 如果是一十改成十
if (s == cnum[1] + cnum[10]) {
s = cnum[10]
}
} else if (s.charAt(0) == cnum[1]) {
// 如果十位数是一的话改成十
s = cnum[10] + s.charAt(1);
} else if (s.charAt(0) == cnum[2]) {
// 如果十位数是二的话改成十二
s = cnum[2] + cnum[10] + s.charAt(1);
} else if (s.charAt(0) == cnum[3]) {
s = cnum[3] + cnum[10] + s.charAt(1);
} else if (s.charAt(0) == cnum[4]) {
s = cnum[4] + cnum[10] + s.charAt(1);
} else if (s.charAt(0) == cnum[5]) {
s = cnum[5] + cnum[10] + s.charAt(1);
} else if (s.charAt(0) == cnum[6]) {
s = cnum[6] + cnum[10] + s.charAt(1);
} else if (s.charAt(0) == cnum[7]) {
s = cnum[7] + cnum[10] + s.charAt(1);
} else if (s.charAt(0) == cnum[8]) {
s = cnum[8] + cnum[10] + s.charAt(1);
} else if (s.charAt(0) == cnum[9]) {
s = cnum[9] + cnum[10] + s.charAt(1);
} else if (s.charAt(0) == cnum[10]) {
s = cnum[10] + cnum[10] + s.charAt(1);
}
}
return s;
},
/**
* 复制文本
* @param {String} text 需要复制的文本
*/
copyText(text) {
uni.setClipboardData({
data: text,
success: () => {
2025-01-05 15:43:14 +08:00
util.alert('文本已复制到剪贴板')
2024-12-18 15:46:27 +08:00
}
});
},
showToastAndRedirect(title, icon = 'none', fun = () => {}) {
2024-12-18 15:46:27 +08:00
uni.showToast({
title,
icon,
duration: 2000, // 显示两秒
complete: () => {
fun()
uni.hideLoading()
}
});
},
/**
* 去聊天
* @param {Object} option
* @param {Object} option.name 标题昵称
* @param {Object} option.msgId 聊天对象id
2025-01-08 21:01:16 +08:00
* @param {Object} option.type 聊天类型 C2C单聊 GROUP群聊
2024-12-18 15:46:27 +08:00
*/
toChat(option) {
uni.navigateTo({
2024-12-31 14:46:56 +08:00
url: util.setUrl('/pages/news/chat/chat', {
2024-12-18 15:46:27 +08:00
name: option.name,
msgId: option.msgId,
type: option.type,
2025-01-12 02:05:25 +08:00
num: option.num,
2024-12-18 15:46:27 +08:00
})
})
},
// 扫码
scan() {
uni.scanCode({
success: (res) => {
if (res && res.result) {
let result = JSON.parse(res.result)
2025-02-23 13:32:05 +08:00
if (result.type == 'ADDFRIEND') {
2025-02-18 18:09:05 +08:00
uni.navigateTo({
url: `/pages/news/addFriend?account=${result.account}`
});
return
}
2024-12-18 15:46:27 +08:00
if (result.key == 'user') {
// 跳转申请添加好友界面
uni.navigateTo({
url: util.setUrl('/pages/news/applyFriend', {
userId: result.userId,
nickname: result.userNickname,
})
})
}
}
//
},
fail: (err) => {
util.alert('二维码扫描失败')
}
});
2025-01-02 01:01:23 +08:00
},
// 获取我的钱包
getPurse() {
api.mine.selectPurse().then(rs => {
if (rs.code == 200) {
// 同步vuex
uni.$store.commit('setState', {
key: 'purse',
value: rs.data,
})
return
}
util.alert({
content: rs.msg,
showCancel: false,
})
})
},
2025-01-03 18:11:02 +08:00
// 获取我的任务
getMyTask() {
// 验证登录
util.isLogin().then(() => {
// 获取任务
api.intergral.viewingTasks({}).then(rs => {
if (rs.code == 200) {
uni.$store.commit('setState', {
key: 'task',
value: rs.data,
})
return
}
})
}).catch(() => {
// 修改为默认值
uni.$store.commit('setState', {
key: 'task',
value: {
//任务类型 0.任务读秒 1.流量点(种子)读秒
taskType: 0,
//有效时长
viewingDuration: 0,
},
})
})
},
2024-12-18 15:46:27 +08:00
}
export default util