Compare commits
1 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
f21d98bc51 |
40
api/http.js
40
api/http.js
|
|
@ -10,12 +10,13 @@
|
||||||
// 导入全局属性
|
// 导入全局属性
|
||||||
import appConfig from '@/config/appConfig.js'
|
import appConfig from '@/config/appConfig.js'
|
||||||
import storageManage from '@/commons/utils/storageManage.js'
|
import storageManage from '@/commons/utils/storageManage.js'
|
||||||
import {
|
|
||||||
sm4DecryptByResData
|
// let baseUrl = '' //测试
|
||||||
} from '@/commons/utils/encryptUtil.js'
|
// let baseUrl = 'https://cashier-client.sxczgkj.cn/cashier-client' //测试环境
|
||||||
import infoBox from "@/commons/utils/infoBox.js"
|
// let baseUrl = 'https://pre-cashierclient.sxczgkj.cn/cashier-client' //预发布环境
|
||||||
// let baseUrl = ''
|
// let baseUrl = 'https://cashierclient.sxczgkj.cn/cashier-client' //线上环境
|
||||||
let baseUrl = 'https://cashier-client.sxczgkj.cn/cashier-client'
|
let baseUrl = appConfig.ENV_ENUM.VITE_API_URL
|
||||||
|
|
||||||
// 多少 ms 以内, 不提示loading
|
// 多少 ms 以内, 不提示loading
|
||||||
const loadingShowTime = 200
|
const loadingShowTime = 200
|
||||||
|
|
||||||
|
|
@ -45,7 +46,7 @@ function commonsProcess(showLoading, httpReqCallback) {
|
||||||
let reqFinishFunc = () => {
|
let reqFinishFunc = () => {
|
||||||
|
|
||||||
if (reqState == 'ingLoading') { // 关闭loading弹层
|
if (reqState == 'ingLoading') { // 关闭loading弹层
|
||||||
infoBox.hideLoading()
|
uni.hideLoading()
|
||||||
}
|
}
|
||||||
reqState = 'finish' // 请求完毕
|
reqState = 'finish' // 请求完毕
|
||||||
}
|
}
|
||||||
|
|
@ -56,7 +57,7 @@ function commonsProcess(showLoading, httpReqCallback) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (reqState == 'ing') {
|
if (reqState == 'ing') {
|
||||||
reqState = 'ingLoading'
|
reqState = 'ingLoading'
|
||||||
infoBox.showLoading()
|
uni.showLoading({ title: '请稍后', mask: true })
|
||||||
}
|
}
|
||||||
}, loadingShowTime)
|
}, loadingShowTime)
|
||||||
}
|
}
|
||||||
|
|
@ -87,7 +88,10 @@ function commonsProcess(showLoading, httpReqCallback) {
|
||||||
// http响应码不正确
|
// http响应码不正确
|
||||||
if (statusCode != 200 && statusCode != 204 && statusCode != 201) {
|
if (statusCode != 200 && statusCode != 204 && statusCode != 201) {
|
||||||
isShowErrorToast = true
|
isShowErrorToast = true
|
||||||
infoBox.showErrorToast(data.message || '服务器异常')
|
uni.showToast({
|
||||||
|
title: data.message || '服务器异常',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
return Promise.reject(bodyData) // 跳转到catch函数
|
return Promise.reject(bodyData) // 跳转到catch函数
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,19 +101,25 @@ function commonsProcess(showLoading, httpReqCallback) {
|
||||||
|
|
||||||
}).catch(res => {
|
}).catch(res => {
|
||||||
if(res.status==401){
|
if(res.status==401){
|
||||||
infoBox.showToast(`登录失效`)
|
uni.showToast({
|
||||||
|
title: '登录失效',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
}
|
}
|
||||||
if(res.status==500){
|
if(res.status==500){
|
||||||
infoBox.showToast(`网络异常`)
|
uni.showToast({
|
||||||
|
title: '网络异常',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
}
|
}
|
||||||
// if(res&&res.msg){
|
|
||||||
// infoBox.showErrorToast(res.msg)
|
|
||||||
// }
|
|
||||||
reqFinishFunc(); // 请求完毕的动作
|
reqFinishFunc(); // 请求完毕的动作
|
||||||
|
|
||||||
// 如果没有提示错误, 那么此处提示 异常。
|
// 如果没有提示错误, 那么此处提示 异常。
|
||||||
if (!isShowErrorToast) {
|
if (!isShowErrorToast) {
|
||||||
infoBox.showErrorToast(`请求网络异常`)
|
uni.showToast({
|
||||||
|
title: '请求网络异常',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.reject(res)
|
return Promise.reject(res)
|
||||||
|
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
/**
|
|
||||||
* 数字, 计算相关函数
|
|
||||||
*
|
|
||||||
* @author terrfly
|
|
||||||
* @site https://www.jeepay.vip
|
|
||||||
* @date 2022/11/22 10:38
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保留小数n位,不进行四舍五入
|
|
||||||
* num你传递过来的数字,
|
|
||||||
* decimal你保留的几位,默认保留小数后两位
|
|
||||||
*/
|
|
||||||
const formatDecimal = function(num, decimal = 2) {
|
|
||||||
num = num.toString()
|
|
||||||
const index = num.indexOf('.')
|
|
||||||
if (index !== -1) {
|
|
||||||
num = num.substring(0, decimal + index + 1)
|
|
||||||
} else {
|
|
||||||
num = num.substring(0)
|
|
||||||
}
|
|
||||||
//截取后保留两位小数
|
|
||||||
return parseFloat(num).toFixed(decimal)
|
|
||||||
}
|
|
||||||
|
|
||||||
const model = {
|
|
||||||
// 分转元
|
|
||||||
// amount - 金额 parseFloat - 是否转换为数字格式, 默认String
|
|
||||||
cert2Dollar(amount, needParseFloat = false) {
|
|
||||||
if (needParseFloat) { // parseFlot
|
|
||||||
return formatDecimal(amount / 100)
|
|
||||||
}
|
|
||||||
return formatDecimal(amount / 100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default model
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
/**
|
|
||||||
* 数据 工具类
|
|
||||||
*
|
|
||||||
* @author terrfly
|
|
||||||
* @site https://www.jeepay.vip
|
|
||||||
* @date 2022/11/30 14:18
|
|
||||||
*/
|
|
||||||
|
|
||||||
const model = {
|
|
||||||
|
|
||||||
// 递归遍历树状结构数据 matchFunc 匹配结果, true表示匹配成功, 否则继续匹配。
|
|
||||||
// pnode 可不传入
|
|
||||||
// 返回结构: [当前数据, 上级数据 ]
|
|
||||||
recursionTreeData: (treeData, matchFunc, childrenName = 'children', pnode = null ) => {
|
|
||||||
|
|
||||||
for (let i = 0; i < treeData.length; i++) {
|
|
||||||
|
|
||||||
const item = treeData[i]
|
|
||||||
|
|
||||||
// 匹配成功
|
|
||||||
if(matchFunc(item)){
|
|
||||||
return [item, pnode]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item[childrenName] && item[childrenName].length > 0) {
|
|
||||||
let res = model.recursionTreeData(item[childrenName], matchFunc, childrenName, item)
|
|
||||||
if(res){
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export default model
|
|
||||||
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
/**
|
|
||||||
* 加解密工具包
|
|
||||||
*
|
|
||||||
* @author terrfly
|
|
||||||
* @site https://www.jeepay.vip
|
|
||||||
* @date 2021/5/16 17:35
|
|
||||||
*/
|
|
||||||
import { SM4 } from 'gm-crypto'
|
|
||||||
import appConfig from '@/config/appConfig.js'
|
|
||||||
|
|
||||||
let HEX_KEY = null
|
|
||||||
|
|
||||||
// 字符串转16进制
|
|
||||||
function str2hex(str) {
|
|
||||||
var val = ''
|
|
||||||
for (var i = 0; i < str.length; i++) {
|
|
||||||
if (val == '')
|
|
||||||
val = str.charCodeAt(i).toString(16)
|
|
||||||
else
|
|
||||||
val += str.charCodeAt(i).toString(16)
|
|
||||||
}
|
|
||||||
val += ''
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取hex秘钥
|
|
||||||
function getHexKey(){
|
|
||||||
|
|
||||||
if(!HEX_KEY){
|
|
||||||
|
|
||||||
HEX_KEY = str2hex(appConfig.encryptKey)
|
|
||||||
|
|
||||||
}
|
|
||||||
return HEX_KEY
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 解密 (http响应数据, 做通用处理)
|
|
||||||
export function sm4DecryptByResData(data){
|
|
||||||
|
|
||||||
if(!data){
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
let res = SM4.decrypt(data, getHexKey(), {
|
|
||||||
inputEncoding: 'base64',
|
|
||||||
outputEncoding: 'utf8'
|
|
||||||
})
|
|
||||||
|
|
||||||
if(!res){
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
return JSON.parse(res)['originData']
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加密 (http响应数据, 做通用处理)
|
|
||||||
export function sm4EncryptByReqData(data){
|
|
||||||
|
|
||||||
if(!data){
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加密处理
|
|
||||||
let encryptData = SM4.encrypt(JSON.stringify(data), getHexKey(), {
|
|
||||||
inputEncoding: 'utf8',
|
|
||||||
outputEncoding: 'base64'
|
|
||||||
})
|
|
||||||
|
|
||||||
return {encryptData : encryptData}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,101 +0,0 @@
|
||||||
/**
|
|
||||||
* form 验证 工具类
|
|
||||||
*
|
|
||||||
* @author terrfly
|
|
||||||
* @site https://www.jeepay.vip
|
|
||||||
* @date 2022/11/25 10:58
|
|
||||||
*/
|
|
||||||
|
|
||||||
import infoBox from '@/commons/utils/infoBox.js'
|
|
||||||
|
|
||||||
const model = {
|
|
||||||
|
|
||||||
|
|
||||||
// 正则表达式
|
|
||||||
regexp: {
|
|
||||||
|
|
||||||
// 手机号验证规则
|
|
||||||
mobile: /^1\d{10}$/,
|
|
||||||
|
|
||||||
// 登录用户名: 字母开头 6 -18位。
|
|
||||||
loginUsername: /^[a-zA-Z][a-zA-Z0-9]{5,17}$/,
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
// 验证规则:
|
|
||||||
rules: {
|
|
||||||
|
|
||||||
// showText 为空, 说明是 input的placeHoloder 直接飘红,
|
|
||||||
// showText 有值: 在文本框下方提示。
|
|
||||||
// 只有input 才有这种特殊判断。
|
|
||||||
requiredInput: (showText, type = 'string') => {
|
|
||||||
return {format: type, required: true, errorMessage: showText ? ('请输入' + showText) : ' ' }
|
|
||||||
},
|
|
||||||
|
|
||||||
requiredSelect: (showText, type = 'string') => {
|
|
||||||
return {format: type, required: true, errorMessage: '请选择' + showText }
|
|
||||||
},
|
|
||||||
|
|
||||||
requiredUpload: (showText, type = 'string') => {
|
|
||||||
return {format: type, required: true, errorMessage: '请上传' + showText }
|
|
||||||
},
|
|
||||||
|
|
||||||
// 正则验证 , 请注意: 该规则需要在required后面, 此处不可包含required
|
|
||||||
patternRule: (showText, p) => {
|
|
||||||
return {pattern: p, errorMessage: '请输入正确的' + showText }
|
|
||||||
},
|
|
||||||
|
|
||||||
requiredInputShowToast: (showText, type = 'string') => {
|
|
||||||
return {format: type, required: true, errorMessage:' ', toastErrorMessage: '请输入' + showText }
|
|
||||||
},
|
|
||||||
|
|
||||||
requiredSelectShowToast: (showText, type = 'string') => {
|
|
||||||
return {format: type, required: true, errorMessage:' ', toastErrorMessage: '请选择' + showText }
|
|
||||||
},
|
|
||||||
|
|
||||||
requiredUploadShowToast: (showText, type = 'string') => {
|
|
||||||
return {format: type, required: true, errorMessage:' ', toastErrorMessage: '请上传' + showText }
|
|
||||||
},
|
|
||||||
|
|
||||||
patternRuleShowToast: (showText, p) => {
|
|
||||||
return {pattern: p, errorMessage:' ', toastErrorMessage: '请输入正确的' + showText }
|
|
||||||
},
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
// 支持 提示信息
|
|
||||||
// 类型如下:
|
|
||||||
// {
|
|
||||||
// required: true,
|
|
||||||
// toastErrorMessage: "请输入去去去去群",
|
|
||||||
// errorMessage: ' ', // 不会显示在下部, 需要空格占位
|
|
||||||
// }
|
|
||||||
validate: (form) => {
|
|
||||||
|
|
||||||
return form.validate().catch(e => {
|
|
||||||
|
|
||||||
if(!e || e.length <= 0){
|
|
||||||
return Promise.reject()
|
|
||||||
}
|
|
||||||
|
|
||||||
for(let i = 0; i < e.length; i++){
|
|
||||||
let k = e[i].key
|
|
||||||
let rules = form.rules[k].rules
|
|
||||||
for(let j = 0; j < rules.length; j++){
|
|
||||||
if(rules[j].toastErrorMessage && rules[j].required){
|
|
||||||
infoBox.showToast(rules[j].toastErrorMessage) // 仅提示一次即可
|
|
||||||
return Promise.reject(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Promise.reject(e)
|
|
||||||
})
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export default model
|
|
||||||
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
/**
|
|
||||||
* 格式化价格函数,将价格限定在指定的最小值和最大值范围内,并保留两位小数。
|
|
||||||
*
|
|
||||||
* @param {number} price - 需要格式化的价格。
|
|
||||||
* @param {number} min - 价格的最小值。
|
|
||||||
* @param {number} max - 价格的最大值,默认为100000000。
|
|
||||||
* @param {Boolean} returnIsArea - 是否返回值符合范围区间,默认为false。
|
|
||||||
* @returns {number} - 返回格式化后的价格,如果超出范围则返回最小值或最大值。
|
|
||||||
*/
|
|
||||||
export const formatPrice = (price,min=-Infinity, max = 100000000,returnIsArea=false ) => {
|
|
||||||
if(price === undefined || price === null||price===''){
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
// 将价格转换为浮点数并保留两位小数
|
|
||||||
const newval = parseFloat((Math.floor(price * 100) / 100).toFixed(2))
|
|
||||||
// 如果价格大于最大值,返回最大值
|
|
||||||
if (newval > max) {
|
|
||||||
return returnIsArea?{value:max,error:true}:max
|
|
||||||
}
|
|
||||||
// 如果价格小于最小值,返回最小值
|
|
||||||
if (newval < min) {
|
|
||||||
return returnIsArea?{value:min,error:true}:min
|
|
||||||
}
|
|
||||||
// 如果价格小于最小值,返回最小值
|
|
||||||
if (newval < min) {
|
|
||||||
return min
|
|
||||||
}
|
|
||||||
// 返回格式化后的价格
|
|
||||||
return newval
|
|
||||||
}
|
|
||||||
export function returnReverseVal(val, isReturnString = true) {
|
|
||||||
const isBol = typeof val === "boolean";
|
|
||||||
const isString = typeof val === "string";
|
|
||||||
let reverseNewval = "";
|
|
||||||
if (isBol) {
|
|
||||||
reverseNewval = !val;
|
|
||||||
}
|
|
||||||
if (isString) {
|
|
||||||
reverseNewval = val === "true" ? "false" : "true";
|
|
||||||
}
|
|
||||||
return reverseNewval;
|
|
||||||
}
|
|
||||||
export function returnBoolean(val) {
|
|
||||||
const isBol = typeof val === "boolean";
|
|
||||||
const isString = typeof val === "string";
|
|
||||||
let newval = "";
|
|
||||||
if (isBol) {
|
|
||||||
newval = val;
|
|
||||||
}
|
|
||||||
if (isString) {
|
|
||||||
newval = val === "true" ? true : false;
|
|
||||||
}
|
|
||||||
return newval;
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
function getDayArea(date = new Date(), type) {
|
|
||||||
const now = date
|
|
||||||
if (type === 'start') {
|
|
||||||
const startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
||||||
return startOfDay
|
|
||||||
}
|
|
||||||
if (type === 'end') {
|
|
||||||
const endOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999);
|
|
||||||
return endOfDay;
|
|
||||||
}
|
|
||||||
return `${startOfDay}-${endOfDay}`
|
|
||||||
}
|
|
||||||
function getMonthArea(date = new Date(), type) {
|
|
||||||
let now = date
|
|
||||||
let currentMonthStart = new Date(now.getFullYear(), now.getMonth(), 1);
|
|
||||||
let currentMonthEnd = new Date(now.getFullYear(), now.getMonth() + 1, 0 , 23, 59, 59, 999);
|
|
||||||
if (type === 'start') {
|
|
||||||
return currentMonthStart
|
|
||||||
}
|
|
||||||
if (type === 'end') {
|
|
||||||
return currentMonthEnd;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
start: currentMonthStart,
|
|
||||||
end: currentMonthEnd
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default {
|
|
||||||
getDayArea, getMonthArea
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
/**
|
|
||||||
* 获取url链接参数
|
|
||||||
* @param {Object} url
|
|
||||||
* @param {Object} name
|
|
||||||
*/
|
|
||||||
export function getQueryString(url, name) {
|
|
||||||
var reg = new RegExp('(^|&|/?)' + name + '=([^&|/?]*)(&|/?|$)', 'i')
|
|
||||||
var r = url.substr(1).match(reg)
|
|
||||||
if (r != null) {
|
|
||||||
return r[2]
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
/**
|
|
||||||
* 提示信息公共文件
|
|
||||||
*
|
|
||||||
* @author terrfly
|
|
||||||
* @site https://www.jeequan.com
|
|
||||||
* @date 2022/11/14 15:29
|
|
||||||
*/
|
|
||||||
|
|
||||||
const model = {
|
|
||||||
|
|
||||||
// uni.showToast的封装
|
|
||||||
// 参数: 标题、 显示时长(单位: 秒), 扩展参数
|
|
||||||
// 返回: promise对象, 当提示消失后调用 resolve()
|
|
||||||
showToast: (title, duration = 1.5, extObject) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
uni.showToast(Object.assign({ title: title, icon: 'none', mask: true, duration: (duration * 1000) }, extObject))
|
|
||||||
setTimeout(resolve, (duration * 1000));
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
// success类型的提示
|
|
||||||
showSuccessToast: (title, duration) => {
|
|
||||||
return model.showToast(title, duration, {icon: 'success'})
|
|
||||||
},
|
|
||||||
|
|
||||||
// error类型的提示
|
|
||||||
showErrorToast: (title, duration) => {
|
|
||||||
return model.showToast(title, duration, {icon: 'error'})
|
|
||||||
},
|
|
||||||
|
|
||||||
showLoading: (title = '请稍后' ) => {
|
|
||||||
return uni.showLoading({ title: title, mask: true })
|
|
||||||
},
|
|
||||||
|
|
||||||
hideLoading: () => {
|
|
||||||
return uni.hideLoading()
|
|
||||||
},
|
|
||||||
|
|
||||||
// 返回 Promise 点击确定和取消
|
|
||||||
// APP安卓原生提示(比较丑), APP 不推荐使用该函数 。
|
|
||||||
showModal: (title, confirmText = '确定', cancalText = '取消', extObject) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
uni.showModal( Object.assign({
|
|
||||||
title: title,
|
|
||||||
confirmText: confirmText,
|
|
||||||
showCancel: cancalText ? true : false,
|
|
||||||
cancelText: cancalText,
|
|
||||||
success: function(r) {
|
|
||||||
if (r.confirm) {
|
|
||||||
resolve()
|
|
||||||
}else if (r.cancel) {
|
|
||||||
reject()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, extObject ));
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export default model
|
|
||||||
|
|
@ -1,143 +0,0 @@
|
||||||
import { $getBaiduToken } from '@/http/apiManager.js';
|
|
||||||
const audioTeam = [];
|
|
||||||
let audioStartSwitch = false;
|
|
||||||
const getAudioUrl = 'https://tsn.baidu.com/text2audio';
|
|
||||||
|
|
||||||
export default function openVoice(objs) { // 传入需转为语音的文本内容
|
|
||||||
let lineUp = false;
|
|
||||||
let returnAudio = false;
|
|
||||||
if (typeof(objs) !== 'string') {
|
|
||||||
if (objs && objs.lineUp === true) {
|
|
||||||
lineUp = true;
|
|
||||||
}
|
|
||||||
if (objs && objs.returnAudio === true) {
|
|
||||||
returnAudio = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(returnAudio) {
|
|
||||||
return new Promise((resolve, reject)=>{
|
|
||||||
openVoiceFc(objs, returnAudio).then(res=>{
|
|
||||||
resolve(res);
|
|
||||||
}).catch(err=>{
|
|
||||||
reject(err)
|
|
||||||
});
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!audioStartSwitch || lineUp) {
|
|
||||||
audioStartSwitch = true;
|
|
||||||
openVoiceFc(objs);
|
|
||||||
} else {
|
|
||||||
audioTeam.push(objs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function openVoiceFc(objs, returnAudio) {
|
|
||||||
if(returnAudio) {
|
|
||||||
return new Promise((resolve, reject)=>{
|
|
||||||
$getBaiduToken().then(({bizData}) => {
|
|
||||||
if (bizData) {
|
|
||||||
resolve(tts(objs, bizData, returnAudio));
|
|
||||||
} else {
|
|
||||||
reject('获取语音tok接口为空');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}else{
|
|
||||||
$getBaiduToken().then(({bizData}) => {
|
|
||||||
if (bizData) {
|
|
||||||
tts(objs, bizData);
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function tts(objs, tok, returnAudio) {
|
|
||||||
if(typeof(objs)=='string')
|
|
||||||
objs = {voiceSet: {tex: objs}};
|
|
||||||
const data = {
|
|
||||||
tok,
|
|
||||||
cuid: tok,
|
|
||||||
ctp: 1,
|
|
||||||
lan: 'zh',
|
|
||||||
...objs.voiceSet
|
|
||||||
}
|
|
||||||
if(returnAudio)
|
|
||||||
return btts( data, objs.audioSet, objs.audioCallback, objs.lineUp, returnAudio);
|
|
||||||
btts( data, objs.audioSet, objs.audioCallback, objs.lineUp, returnAudio);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setAudioSet(options, audio) {
|
|
||||||
if (options) {
|
|
||||||
audio.volume = options.volume || 1;
|
|
||||||
audio.startTime = options.startTime || 0;
|
|
||||||
audio.loop = options.loop || false;
|
|
||||||
audio.obeyMuteSwitch = options.obeyMuteSwitch && typeof(options.obeyMuteSwitch) == 'boolean' ? options.obeyMuteSwitch :
|
|
||||||
true; //支持微信小程序、百度小程序、头条小程序
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function btts(param, options, audioCallback, lineUp, returnAudio) {
|
|
||||||
let audio = uni.createInnerAudioContext();
|
|
||||||
setAudioSet(options, audio);
|
|
||||||
// 序列化参数列表
|
|
||||||
let fd = [];
|
|
||||||
for (let k in param) {
|
|
||||||
fd.push(k + '=' + encodeURIComponent(encodeURIComponent(param[k])));
|
|
||||||
}
|
|
||||||
audio.src = `${getAudioUrl}?${fd.join('&')}`;
|
|
||||||
|
|
||||||
if(returnAudio) {
|
|
||||||
audio.onEnded(() => {
|
|
||||||
audio.destroy(); //销毁音频实例
|
|
||||||
audio = null;
|
|
||||||
})
|
|
||||||
audio.onError((e)=>{
|
|
||||||
if (audioCallback && audioCallback.onError && typeof(audioCallback.onError) == 'function') audioCallback.onError(e);
|
|
||||||
audio.destroy(); //销毁音频实例
|
|
||||||
audio = null;
|
|
||||||
})
|
|
||||||
return audio;
|
|
||||||
}
|
|
||||||
audio.onPlay(() => {
|
|
||||||
if (audioCallback && audioCallback.onPlay && typeof(audioCallback.onPlay) == 'function') audioCallback.onPlay();
|
|
||||||
})
|
|
||||||
audio.onPause(()=>{
|
|
||||||
if (audioCallback && audioCallback.onPause && typeof(audioCallback.onPause) == 'function') audioCallback.onPause();
|
|
||||||
})
|
|
||||||
audio.onWaiting(()=>{
|
|
||||||
if (audioCallback && audioCallback.onWaiting && typeof(audioCallback.onWaiting) == 'function') audioCallback.onWaiting();
|
|
||||||
})
|
|
||||||
audio.onStop(()=>{
|
|
||||||
if (audioCallback && audioCallback.onStop && typeof(audioCallback.onStop) == 'function') audioCallback.onStop();
|
|
||||||
})
|
|
||||||
audio.onTimeUpdate(()=>{
|
|
||||||
if (audioCallback && audioCallback.onTimeUpdate && typeof(audioCallback.onTimeUpdate) == 'function') audioCallback.onTimeUpdate();
|
|
||||||
})
|
|
||||||
audio.onSeeking(()=>{
|
|
||||||
if (audioCallback && audioCallback.onSeeking && typeof(audioCallback.onSeeking) == 'function') audioCallback.onSeeking();
|
|
||||||
})
|
|
||||||
audio.onSeeked(()=>{
|
|
||||||
if (audioCallback && audioCallback.onSeeked && typeof(audioCallback.onSeeked) == 'function') audioCallback.onSeeked();
|
|
||||||
})
|
|
||||||
audio.onEnded(() => {
|
|
||||||
audio.destroy(); //销毁音频实例
|
|
||||||
audio = null;
|
|
||||||
if (audioCallback && audioCallback.onEnded && typeof(audioCallback.onEnded) == 'function') audioCallback.onEnded();
|
|
||||||
if (lineUp !== false) {
|
|
||||||
if (audioTeam.length > 0) {
|
|
||||||
openVoiceFc(audioTeam[0]);
|
|
||||||
audioTeam.splice(0, 1);
|
|
||||||
} else {
|
|
||||||
audioStartSwitch = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
audio.onError((e)=>{
|
|
||||||
if (audioCallback && audioCallback.onError && typeof(audioCallback.onError) == 'function') audioCallback.onError(e);
|
|
||||||
audio.destroy(); //销毁音频实例
|
|
||||||
audio = null;
|
|
||||||
})
|
|
||||||
audio.play();
|
|
||||||
}
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
import storageManage from '@/commons/utils/storageManage.js'
|
|
||||||
import dayjs from 'dayjs'
|
|
||||||
import baiduyy from './QS-baiduyy.js'; // 百度语音合成
|
|
||||||
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
import wxTextToSpeach from './wxTextToSpeach.js'; // 微信小程序插件语音合成
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
|
|
||||||
const model = {
|
|
||||||
// 监听推送通知
|
|
||||||
addPushMsgEventListener: function(){
|
|
||||||
|
|
||||||
console.log("监听推送")
|
|
||||||
|
|
||||||
// #ifdef APP-PLUS
|
|
||||||
// unipush1.0监听消息
|
|
||||||
if(plus && plus.push) {
|
|
||||||
plus.push.addEventListener('receive', model.handlePush)
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
// unipush2.0监听消息
|
|
||||||
model.uniPushListener2()
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
// uniPush2.0 接收推送消息
|
|
||||||
uniPushListener2: function() {
|
|
||||||
uni.onPushMessage((res) => {
|
|
||||||
console.log("uniPush2.0 收到推送消息:", res.data) //监听推送消息
|
|
||||||
model.handlePush(res.data)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
// 语音播报
|
|
||||||
handlePush: function(message) {
|
|
||||||
|
|
||||||
// 没有token信息
|
|
||||||
if(!storageManage.token()){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 信息不存在
|
|
||||||
if(!message || !message.content) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const content = JSON.parse(message.content)
|
|
||||||
console.log("消息内容:", content)
|
|
||||||
|
|
||||||
// 支付成功
|
|
||||||
if (content && content.type == 'paySuccess') {
|
|
||||||
// 在过期时间之内, 则调起语音播报。
|
|
||||||
if( dayjs(content.expiredTime).isAfter(dayjs()) ){
|
|
||||||
console.log('执行消息播报');
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
wxTextToSpeach(content.msg)
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifndef MP-WEIXIN
|
|
||||||
baiduyy(content.msg)
|
|
||||||
// #endif
|
|
||||||
uni.vibrateLong({});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default model
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
import {
|
|
||||||
$pushInfoRegister
|
|
||||||
} from '@/http/apiManager.js'
|
|
||||||
import storageManage from '@/commons/utils/storageManage.js'
|
|
||||||
// 默认导出 方法 注册 push连接
|
|
||||||
export default async function() {
|
|
||||||
let cid1 = undefined // unipush1.0 客户端CID
|
|
||||||
let cid2 = undefined // unipush2.0 客户端CID
|
|
||||||
let orgCid = undefined // 原始cid如果获取的cid和新的cid不相同赋值原始cid后端会根据原始cid更新
|
|
||||||
let cidType = undefined //传递类型 是 app 还是 微信
|
|
||||||
// #ifdef APP-PLUS
|
|
||||||
cidType = 'app_plus'
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
cidType = 'mp_weixin'
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifdef APP-PLUS
|
|
||||||
if (!plus) {
|
|
||||||
cid1 = plus.push.getClientInfo().clientid
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
const data = await uni.getPushClientId()
|
|
||||||
console.log('客户端推送标识:', data.cid)
|
|
||||||
cid2 = data.cid
|
|
||||||
// 如果不存 cid 本地存储 写入 cid
|
|
||||||
if (!storageManage.uniPush2Cid()) {
|
|
||||||
storageManage.uniPush2Cid(data.cid)
|
|
||||||
} else if (cid2 !== storageManage.uniPush2Cid()) { // 否则进行 cid 对比 判断 是否相等 不相等 赋值 orgCid
|
|
||||||
orgCid = storageManage.uniPush2Cid() //赋值原始cid
|
|
||||||
storageManage.uniPush2Cid(data.cid) //重新写入 cid
|
|
||||||
}
|
|
||||||
if (cid1) {
|
|
||||||
pushInfoRegister(cid1)
|
|
||||||
} else {
|
|
||||||
pushInfoRegister(cid1, cid2, orgCid, cidType)
|
|
||||||
}
|
|
||||||
|
|
||||||
function pushInfoRegister(cid1 = '', cid2 = '', org = '', cidType = '') {
|
|
||||||
$pushInfoRegister({
|
|
||||||
cid1,
|
|
||||||
cid2,
|
|
||||||
orgCid: org,
|
|
||||||
cidType
|
|
||||||
}).then(res => {
|
|
||||||
orgCid = '' //重置 数据
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,87 +0,0 @@
|
||||||
import { $mchConfig } from "@/http/apiManager"
|
|
||||||
import storageManage from '@/commons/utils/storageManage.js'
|
|
||||||
let num = 0 //计算错误此时 超过5次错误 不在出触发
|
|
||||||
const plugin = requirePlugin("WechatSI")
|
|
||||||
const pushMsgArr = [] //维护一个消息队列
|
|
||||||
let backgroundAudioManager = undefined //获取背景音频实例
|
|
||||||
let audioMp3 = ''
|
|
||||||
console.log('执行创建 语音播报逻辑');
|
|
||||||
// 获取配置项 判断是否 开启 小程序 语音推送
|
|
||||||
export function getPushStatus () {
|
|
||||||
if (!storageManage.token()) return //未登录 不播放
|
|
||||||
$mchConfig('orderConfig').then(({ bizData = [] }) => {
|
|
||||||
const weChat = bizData.find(v => v.configKey == "weChatVoice")
|
|
||||||
if (weChat && weChat?.configVal == 1) {
|
|
||||||
createBgMusice()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// getPushStatus()
|
|
||||||
// 创建 背景音乐
|
|
||||||
function createBgMusice (file) {
|
|
||||||
backgroundAudioManager = wx.getBackgroundAudioManager()
|
|
||||||
backgroundAudioManager.title = '订单通知'
|
|
||||||
if (!audioMp3) {
|
|
||||||
createFile()
|
|
||||||
} else {
|
|
||||||
backgroundAudioManager.src = audioMp3
|
|
||||||
}
|
|
||||||
|
|
||||||
// 监听 音频播放失败事件
|
|
||||||
backgroundAudioManager.onError(function (res) {
|
|
||||||
console.log('音频播放失败', res, num);
|
|
||||||
if (num >= 5) return
|
|
||||||
createFile()
|
|
||||||
num++
|
|
||||||
})
|
|
||||||
// 监听 音频播放结束事件
|
|
||||||
onBgMusiceEnd()
|
|
||||||
}
|
|
||||||
// 监听bei背景音乐播放状态
|
|
||||||
export function onBgMusiceEnd () {
|
|
||||||
backgroundAudioManager.onEnded(() => {
|
|
||||||
if (pushMsgArr.length > 0) return broadcast(pushMsgArr.pop()) //如果有消息 则继续播放
|
|
||||||
backgroundAudioManager.src = audioMp3 //否则播放默认背景音乐
|
|
||||||
})
|
|
||||||
}
|
|
||||||
export function startOrEndMusice (flag) {
|
|
||||||
if (!flag && !!backgroundAudioManager) return backgroundAudioManager.stop() //关闭背景音乐 地址指向空即可
|
|
||||||
if (!backgroundAudioManager) return createBgMusice() // 如果一开始是关闭状态 则创建背景音乐实例
|
|
||||||
backgroundAudioManager.src = audioMp3 // 否则重新赋值背景音地址即可
|
|
||||||
}
|
|
||||||
export default function (message) {
|
|
||||||
if (!backgroundAudioManager) return
|
|
||||||
pushMsgArr.unshift(message) //将消息添加到消息队列头部 背景音乐播放结束后 会对消息队列 进行校验 如果消息队列有消息 会进行播放 否则继续循环背景音乐
|
|
||||||
}
|
|
||||||
// 播放订单
|
|
||||||
function broadcast (msg) {
|
|
||||||
plugin.textToSpeech({
|
|
||||||
lang: "zh_CN",
|
|
||||||
tts: true,
|
|
||||||
content: msg,
|
|
||||||
success: function (res) {
|
|
||||||
backgroundAudioManager.src = res.filename;
|
|
||||||
onBgMusiceEnd()
|
|
||||||
},
|
|
||||||
fail: function (res) {
|
|
||||||
console.log("fail tts", res)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建文件
|
|
||||||
export function createFile (file) {
|
|
||||||
const fs = wx.getFileSystemManager()
|
|
||||||
fs.copyFile({
|
|
||||||
srcPath: `static/noiseless.mp3`,
|
|
||||||
destPath: `${wx.env.USER_DATA_PATH}/noiseless.mp3`,
|
|
||||||
success (res) {
|
|
||||||
console.log(res, `${wx.env.USER_DATA_PATH}/noiseless.mp3`)
|
|
||||||
audioMp3 = `${wx.env.USER_DATA_PATH}/noiseless.mp3`
|
|
||||||
backgroundAudioManager.src = audioMp3
|
|
||||||
},
|
|
||||||
fail (res) {
|
|
||||||
console.error(res)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
创建 云空间 上传云函数 云函数 url化 运营平台 配置云函数地址
|
|
||||||
|
|
||||||
打包时 勾选云push 2.0 push1.0 仅支持 app 推送
|
|
||||||
|
|
||||||
注意配置 百度语音相关参数
|
|
||||||
|
|
||||||
使用push2.0 请将 static\noiseless.mp3 文件 配置到运营平台 系统 配置 通知配置 push2.0 uniPush语音播报音频文件(小程序播报必填) 下
|
|
||||||
|
|
||||||
注意:扩展库依赖3张opendb表:opendb-tempdata,opendb-device,uni-id-device。公测版uniCloud,执行扩展库会自动创建。如果你使用的是uniCloud正式版需要自己创建这3张表。
|
|
||||||
|
|
||||||
|
|
@ -15,7 +15,13 @@ const appConfig = {
|
||||||
DEVELOPMENT: 'development', // 本地调试地址
|
DEVELOPMENT: 'development', // 本地调试地址
|
||||||
TEST: 'test', // 测试地址
|
TEST: 'test', // 测试地址
|
||||||
DEMO: 'demo', // 演示环境
|
DEMO: 'demo', // 演示环境
|
||||||
PRODUCTION: 'production' // 生产环境
|
PRODUCTION: 'production' ,// 生产环境,
|
||||||
|
// # 测试
|
||||||
|
// VITE_API_URL: 'https://cashier-client.sxczgkj.cn/cashier-client',
|
||||||
|
// # 预发布
|
||||||
|
VITE_API_URL: 'https://pre-cashierclient.sxczgkj.cn/cashier-client',
|
||||||
|
// # 线上环境接口地址
|
||||||
|
// VITE_API_URL: 'https://cashierclient.sxczgkj.cn/cashier-client',
|
||||||
},
|
},
|
||||||
|
|
||||||
storeEnvEnumKey: 'currentEnvEnum', // 本地存储的envkey的值
|
storeEnvEnumKey: 'currentEnvEnum', // 本地存储的envkey的值
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@
|
||||||
},
|
},
|
||||||
"router" : {
|
"router" : {
|
||||||
"mode" : "history", //采用history模式URL的路径才跟配置的对应上,不然URL是先加/#再追加配置的地
|
"mode" : "history", //采用history模式URL的路径才跟配置的对应上,不然URL是先加/#再追加配置的地
|
||||||
"base" : "/pay" //在页面路由上加上该前缀
|
"base" : "/pay_pre" //在页面路由上加上该前缀
|
||||||
},
|
},
|
||||||
"devServer" : {
|
"devServer" : {
|
||||||
"port" : 80,
|
"port" : 80,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="content">
|
<view class="content">
|
||||||
<view class="info">
|
<view class="info">
|
||||||
<image class="shopImage" :src="shopImage"></image>
|
<image class="shopImage" :src="shopImage" mode="aspectFill"></image>
|
||||||
<view class="shopName">{{shopName}}</view>
|
<view class="shopName">{{shopName}}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="input">
|
<view class="input">
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue