// 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) : () => {} resolve(res) }, fail: err => { obj.fail ? obj.fail(err) : () => {} reject(err) }, complete: res => {} }) }) }, /** * 上传文件 * @param {Object} obj * @param {String} obj.mode img图片 video视频 */ upload(obj) { // 使用promise写请求,一个函数两种回调 return new Promise((resolve, reject) => { // 默认token let token = uni.getStorageSync('token') || '' // 接口地址 obj.url = obj.url ? obj.url : '/file/upload' // 文件 obj.file = obj.file ? obj.file : "" // 附加数据 obj.data = obj.data ? obj.data : {} // 请求头 obj.header = { // 'Content-Type': 'multipart/form-data; ', // 'Content-Type': 'application/json;charset=UTF-8', 'Access-Control-Allow-Origin': '*', ...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) }, complete(rs) { console.log('upload complete', rs) } }) }) }, /** * 发送网络请求 * @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}` // console.log('request url', url) // console.log('request data', params.data) // console.log('request header', params.header) // 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 => { console.log('request success', url, res, params.data ? params.data : '') // 关闭加载效果 if (params.load) { uni.hideLoading() } // 401 if (res.data.code == 401) { // 登出 util.logout(() => { util.alert(res.data.msg) reject(res.data) uni.redirectTo({ url: '/pages/login/loginPhone', }) }) } // 嵌套式回调 params.success ? params.success(res.data) : '' // 链式回调 resolve(res.data); }, // 请求失败返回 fail: res => { console.log('request fail', url, res, params.data ? params.data : '') // 关闭加载效果 if (params.load) { uni.hideLoading() } // 嵌套式回调 params.fail ? params.fail(res) : '' // 链式回调 reject(res) }, complete(res) { // console.log('complete', url, res); // 嵌套式回调 params.complete ? params.complete(res) : '' }, }) }) }, /** * 替换图片的宽度为最大宽度100% (移动端解析html富文本专用) * @param {Object} value 富文本 */ imgReplace(value) { return value.replace(/
/ig, '
')
.replace(/ 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修改的对象
*/
upload_image(obj) { // 格式化默认值
// 图片计数
const count = obj.count ? obj.count : 8;
// 多张图片
if (!obj.type) obj.type = 2;
// 操作对象
// 修正逻辑判断
if (obj.value == '' || obj.value == undefined || obj.value == null) obj.value = obj.type == 1 ? '' : [];
// 判断剩余图片上传个数
if (obj.value.length >= count && obj.type == 2) {
// 弹窗提示
util.alert('上传图片已达上限');
return;
}
// 选择图片
uni.chooseImage({
// 限制图片
count: obj.type == 1 ? 1 : count - obj.value.length,
sourceType: obj.sourceType || ['album', 'camera'],
success: (rs) => {
// 遍历图片返回列表
rs.tempFiles.forEach(item => {
// 限制大小
let size = 1024 * 1024 * util.config.img_size;
if (item.size > size && !obj.unlimited) {
util.alert(`大小超过${util.config.img_size}m`);
return;
}
// 调用上传图片
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,
});
},
})
return;
}
util.alert(rs.msg);
},
});
});
},
fail(rs) {
if (rs.errMsg == "chooseImage:fail cancel") {
// 取消选择
}
},
});
},
/**
* 上传视频
* @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) {
// const fullUrl = util.format_url(res.msg, 'video')
obj.success && obj.success({
value: res.data.url,
width: rs.width,
height: rs.height,
size: rs.size,
duration: rs.duration,
// value: fullUrl,
})
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]]
let result = ''
if (url) result = file_suffix.find(item => item.id === url.split('.').pop().toLowerCase())
return result
},
/**
* 通过路径获取音频后缀
* @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支付
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
// 支付宝支付
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
// 钱包支付
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) => {};
},
complete() {
// 结束
obj.complete ? obj.complete() : ''
},
});
},
/**
* 最终登录 用于请求登录接口后统一调用的登录方法
* @param {Object} param 数据对象
* @param {Function} cb 回调函数
*/
finalLogin(param, cb) {
// 登录令牌
const token = param.data
// 缓存token
uni.setStorageSync('token', token)
// 开启加载
uni.showLoading({
mask: true
})
setTimeout(() => {
// 获取用户信息
util.getUserinfo((userinfo) => {
// 登录
uni.$emit('login')
setTimeout(() => {
util.loginTencent(userinfo)
uni.reLaunch({
url: '/pages/index/index'
})
}, 500)
//
cb ? cb() : ''
})
}, 500)
},
// 登录腾讯聊天
loginTencent(userinfo) {
api.login.getIMToken({}).then(rs => {
//
const imSig = rs.msg
// #ifdef APP
// 音视频登录
const loginParams = {
SDKAppID: util.config.TChat.SDKAppID,
userID: userinfo.id + '',
userSig: imSig,
}
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 + '',
userSig: imSig,
}).then(rs => {
util.updateMyProfile(userinfo)
console.log('im login success', rs)
})
})
},
// 更新im个人资料
updateMyProfile(userinfo) {
// 验证sdk是否准备完毕
let isReady = uni.$chat.isReady();
if (!isReady) {
setTimeout(function() {
util.updateMyProfile(userinfo);
}, 800);
return
}
let obj = {
nick: userinfo.userNickname,
avatar: userinfo.avatar
}
uni.$chat.updateMyProfile(obj).then(res => {
// console.log(res);
})
},
/**
* 获取用户信息
* @param {Function} cb 回调函数
*/
getUserinfo(cb) {
return new Promise(reslove => {
// 请求接口
api.mine.getUserinfo().then(rs => {
if (rs.code === 200) {
reslove(rs.data)
const userinfo = rs.data
// 如果开启了青少年模式
if (userinfo.teenTime) util.getTeenMode(userinfo.teenTime)
// 提交
store.commit('setState', {
key: 'userinfo',
value: userinfo
})
// 用户信息
uni.setStorageSync('userinfo', userinfo)
cb ? cb(userinfo) : ''
}
}).finally(() => {
// 关闭加载
uni.hideLoading()
})
})
},
// 青少年模式
getTeenMode(teenTime) {
// 当前时间
const currentDate = new Date()
// 当前小时
const currentHour = currentDate.getHours()
// 大于八点 小于22点 当前时间小于设定时间
const result = currentHour >= 6 && currentHour < 22 && currentDate.valueOf() < new Date(teenTime).valueOf()
// 锁定
function lock() {
console.log('lock')
uni.reLaunch({
url: '/pages/login/lock'
})
}
// 结果
if (result) {
console.log('time', new Date(teenTime).valueOf() - currentDate.valueOf())
// 设置定时器
setTimeout(() => {
lock()
}, parseInt(new Date(teenTime).valueOf() - currentDate.valueOf()))
} else lock()
},
/**
* 验证登录
* @param {Object} cb 回调函数
*/
isLogin(cb) {
// 验证
let userinfo = uni.$store.state.userinfo
return new Promise((resolve, reject) => {
// 登录
if (userinfo.id) {
// 成功
resolve()
// 回调
cb ? cb() : ''
} else reject()
})
},
/**
* 清除登录状态
* @param {Function} cb 回调函数
*/
logout(cb) {
// 用户信息
const userinfo = store.state.userinfo
// 用户id
if (userinfo.id) {
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
if (userinfo.isRealName) {
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: () => {
util.alert('文本已复制到剪贴板')
}
});
},
showToastAndRedirect(title, icon = 'none', fun = () => {}) {
uni.showToast({
title,
icon,
duration: 2000, // 显示两秒
complete: () => {
fun()
uni.hideLoading()
}
});
},
/**
* 去聊天
* @param {Object} option
* @param {Object} option.name 标题昵称
* @param {Object} option.msgId 聊天对象id
* @param {Object} option.type 聊天类型 C2C单聊 GROUP群聊
*/
toChat(option) {
uni.navigateTo({
url: util.setUrl('/pages/news/chat/chat', {
name: option.name,
msgId: option.msgId,
type: option.type,
num: option.num,
})
})
},
// 扫码
scan() {
uni.scanCode({
success: (res) => {
if (res && res.result) {
let result = JSON.parse(res.result)
if (result.type == 'ADDFRIEND') {
uni.navigateTo({
url: `/pages/news/addFriend?account=${result.account}`
});
return
}
if (result.key == 'user') {
// 跳转申请添加好友界面
uni.navigateTo({
url: util.setUrl('/pages/news/applyFriend', {
userId: result.userId,
nickname: result.userNickname,
})
})
}
}
//
},
fail: (err) => {
util.alert('二维码扫描失败')
}
});
},
// 获取我的钱包
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,
})
})
},
// 获取我的任务
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,
},
})
})
},
}
export default util