You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
719 lines
18 KiB
719 lines
18 KiB
import { |
|
host |
|
} from "@/config/host"; |
|
|
|
import store from '@/store/index.js'; |
|
|
|
// #ifdef APP |
|
const sunmi_print = uni.requireNativePlugin('Sunmi-Print-Inner') |
|
const TTSSpeech = uni.requireNativePlugin('MT-TTS-Speech') |
|
// #endif |
|
const utils = { |
|
//一体机打印初始化 |
|
init: () => { |
|
// #ifdef APP |
|
return new Promise((relove, reject) => { |
|
sunmi_print.connect(res => { |
|
console.log(res) |
|
if (res.connect == 'hello') { |
|
console.log('打印机成功连接') |
|
relove(true) |
|
} else { |
|
relove(false) |
|
} |
|
}) |
|
}) |
|
// #endif |
|
}, |
|
//检查打印机状态 |
|
getstate: () => { |
|
// #ifdef APP |
|
return new Promise((relove, reject) => { |
|
sunmi_print.getPrinterStatus(result => { |
|
console.log('打印机当前状态是:' + result.status) |
|
if (result.status == 'running') { |
|
relove(true) |
|
} else { |
|
let title |
|
switch (result.status) { |
|
case 'offline': |
|
title = '打印机未连接' |
|
break |
|
case 'fault': |
|
title = '打印机故障' |
|
break |
|
case 'outpaper': |
|
title = '打印机缺纸' |
|
break |
|
case 'hot': |
|
title = '打印机过热' |
|
break |
|
case 'open': |
|
title = '打印机开盖' |
|
break |
|
case 'error': |
|
title = '未知错误' |
|
break |
|
} |
|
uni.showToast({ |
|
title, |
|
icon: 'error', |
|
}) |
|
relove(false) |
|
} |
|
}) |
|
}) |
|
// #endif |
|
}, |
|
//打印的内容 |
|
printxie: async obj => { |
|
// #ifdef APP |
|
let res = await sunmi_print.labelLocate() |
|
console.log(res) |
|
setTimeout(() => { |
|
sunmi_print.printText({ |
|
text: '日期:' + obj.rigthnumer + ' ', |
|
align: 2, |
|
size: 22, |
|
bold: true, |
|
underline: false, |
|
compact: false, |
|
skip: true, |
|
}) |
|
sunmi_print.printText({ |
|
text: obj.title, |
|
align: 1, |
|
size: 90, |
|
bold: true, |
|
underline: false, |
|
compact: true, |
|
skip: true, |
|
}) |
|
sunmi_print.printDividingline({ |
|
style: 0, |
|
height: '3', |
|
}), |
|
sunmi_print.printText({ |
|
text: `件数:${obj.number1}`, |
|
align: 0, |
|
size: 40, |
|
bold: true, |
|
underline: false, |
|
compact: true, |
|
skip: true, |
|
}) |
|
sunmi_print.printText({ |
|
text: obj.leftnumber, |
|
align: 0, |
|
size: 27, |
|
bold: true, |
|
underline: false, |
|
compact: true, |
|
skip: true, |
|
}) |
|
sunmi_print.labelOutput() |
|
}, 2000) |
|
// #endif |
|
}, |
|
// H5蓝牙打印初始化 |
|
initbl_App: () => { |
|
// #ifdef APP |
|
let deviceList = [] |
|
let main = plus.android.runtimeMainActivity() |
|
let Context = plus.android.importClass('android.content.Context') |
|
let BManager = main.getSystemService(Context.BLUETOOTH_SERVICE) |
|
plus.android.importClass(BManager) |
|
let BAdapter = BManager.getAdapter() |
|
plus.android.importClass(BAdapter) |
|
let lists = BAdapter.getBondedDevices() |
|
// let aaa = BAdapter.getProfileConnectionState() |
|
// console.log('aaa :>> ', aaa); |
|
// console.log('lists :>> ', lists); |
|
plus.android.importClass(lists) |
|
let iterator = lists.iterator() |
|
console.log('iterator :>> ', iterator) |
|
|
|
plus.android.importClass(iterator) |
|
while (iterator.hasNext()) { |
|
let d = iterator.next() |
|
plus.android.importClass(d) |
|
let temp = { |
|
name: d.getName(), |
|
address: d.getAddress(), |
|
status: d.getBondState(), |
|
uuids: d.getUuids(), |
|
op: d, |
|
} |
|
deviceList.push(temp) |
|
} |
|
|
|
// getProfileConnectionState |
|
return deviceList |
|
// #endif |
|
}, |
|
// 蓝牙打印初始化 |
|
initbl: () => { |
|
// #ifdef APP |
|
let deviceList = [] |
|
let main = plus.android.runtimeMainActivity() |
|
let Context = plus.android.importClass('android.content.Context') |
|
let BManager = main.getSystemService(Context.BLUETOOTH_SERVICE) |
|
plus.android.importClass(BManager) |
|
let BAdapter = BManager.getAdapter() |
|
plus.android.importClass(BAdapter) |
|
let lists = BAdapter.getBondedDevices() |
|
// let aaa = BAdapter.getProfileConnectionState() |
|
// console.log('aaa :>> ', aaa); |
|
// console.log('lists :>> ', lists); |
|
plus.android.importClass(lists) |
|
let iterator = lists.iterator() |
|
console.log('iterator :>> ', iterator) |
|
|
|
plus.android.importClass(iterator) |
|
while (iterator.hasNext()) { |
|
let d = iterator.next() |
|
plus.android.importClass(d) |
|
let temp = { |
|
name: d.getName(), |
|
address: d.getAddress(), |
|
status: d.getBondState(), |
|
uuids: d.getUuids(), |
|
op: d, |
|
} |
|
deviceList.push(temp) |
|
} |
|
|
|
// getProfileConnectionState |
|
return deviceList |
|
// #endif |
|
}, |
|
//给蓝牙打印机推送打印的内容 |
|
getbl: (dev, text) => { |
|
return new Promise((resolve, reject) => { |
|
try { |
|
// #ifdef APP |
|
uni.showLoading({ |
|
title: '打印中', |
|
mask: true, |
|
}) |
|
let main = plus.android.runtimeMainActivity() |
|
let BluetoothAdapter = plus.android.importClass('android.bluetooth.BluetoothAdapter') |
|
let UUID = plus.android.importClass('java.util.UUID') |
|
let uuid = UUID.fromString('00001101-0000-1000-8000-00805F9B34FB') |
|
let BAdapter = BluetoothAdapter.getDefaultAdapter() |
|
let device = BAdapter.getRemoteDevice(dev.address) |
|
plus.android.importClass(device) |
|
let bluetoothSocket = device.createInsecureRfcommSocketToServiceRecord(uuid) |
|
plus.android.importClass(bluetoothSocket) |
|
console.log('开始连接打印机:' + dev.name) |
|
if (!bluetoothSocket.isConnected()) { |
|
bluetoothSocket.connect() |
|
if (bluetoothSocket.isConnected()) { |
|
console.log('设备已连接,开始发送打印文件') |
|
let outputStream = bluetoothSocket.getOutputStream() |
|
plus.android.importClass(outputStream) |
|
// sb(outputStream); |
|
|
|
// text+='PRINT\r\n' |
|
console.log(text) |
|
let arrayBuffer = plus.android.invoke(text, 'getBytes', 'gbk') |
|
outputStream.write(arrayBuffer) |
|
// console.log(111111111); |
|
outputStream.flush() |
|
bluetoothSocket.close() |
|
if (!bluetoothSocket.isConnected()) { |
|
console.log('设备已关闭') |
|
} |
|
resolve(null) |
|
} else { |
|
uni.showToast({ |
|
title: '设备连接失败', |
|
icon: 'error', |
|
duration: 2000, |
|
}) |
|
reject(null) |
|
} |
|
} |
|
// #endif |
|
} catch (err) { |
|
reject(null) |
|
//TODO handle the exception |
|
} finally { |
|
uni.hideLoading() |
|
} |
|
}) |
|
}, |
|
//初始化tts语音引擎 |
|
inittts() { |
|
// #ifdef APP |
|
TTSSpeech.init(status => { |
|
if (status === 0) { |
|
console.log('引擎初始化成功') |
|
TTSSpeech.setSpeed(100) |
|
TTSSpeech.getInstallTTS(res => { |
|
console.log(JSON.stringify(res)) |
|
let flage = false |
|
res.forEach(v => { |
|
if (v.name == 'com.iflytek.speechcloud') { |
|
flage = true |
|
} |
|
console.log(v.label + ': ' + v.name) |
|
}) |
|
if (!flage) { |
|
// uni.showToast({ |
|
// title:'当前未安装语音引擎,前往安装中', |
|
// icon:'none' |
|
// }) |
|
uni.showModal({ |
|
title: '安装语音引擎', |
|
content: '请选择浏览器下载安装还是直接安装', |
|
cancelText: '浏览器安装', |
|
confirmText: '直接安装', |
|
success: function(res) { |
|
if (res.confirm) { |
|
var fileSaveUrl = plus.io.convertLocalFileSystemURL('static/TTS.apk') |
|
plus.runtime.install( |
|
//安装 |
|
fileSaveUrl, { |
|
force: true, |
|
}, |
|
function(res) { |
|
utils.showToast('更新成功,请重新打开APP') |
|
TTSSpeech.setEngine('com.iflytek.speechcloud') |
|
// plus.runtime.restart() |
|
plus.runtime.quit() |
|
} |
|
) |
|
} else if (res.cancel) { |
|
setTimeout(() => { |
|
plus.runtime.openURL( |
|
'http://htys.oss-cn-chengdu.aliyuncs.com/htys/5402c622c319fac17c50fe52581cb627.apk' |
|
) |
|
setTimeout(() => { |
|
plus.runtime.quit() |
|
}, 2500) |
|
}, 1500) |
|
} |
|
}, |
|
}) |
|
} else { |
|
// uni.showToast({ |
|
// title:'' |
|
// }) |
|
} |
|
}) |
|
} else { |
|
console.log('引擎初始化失败') |
|
} |
|
}, 'com.iflytek.speechcloud') |
|
// #endif |
|
}, |
|
//语音播报 |
|
ttsspke: text => { |
|
// #ifdef APP |
|
console.log('语音播报') |
|
if (!text) { |
|
return |
|
} |
|
return TTSSpeech.speak({ |
|
text, |
|
}) |
|
// #endif |
|
}, |
|
//设置扫描的广播 |
|
setting: () => { |
|
// #ifdef APP |
|
let main = plus.android.runtimeMainActivity() |
|
let deviceAction = 'com.android.server.scannerservice.broadcast' |
|
let strdata = 'scannerdata' |
|
let Intent = plus.android.importClass('android.content.Intent') |
|
let intentSetting = new Intent('com.android.scanner.service_settings') |
|
//设置条码发送方式 |
|
//"FOCUS":焦点录入 |
|
//"BROADCAST":广播 |
|
//"EMUKEY":模拟按键 |
|
//"CLIPBOARD":剪贴板 |
|
intentSetting.putExtra('barcode_send_mode', 'BROADCAST') |
|
//设置Action |
|
intentSetting.putExtra('action_barcode_broadcast', deviceAction) |
|
//设置返回状态: getstringExtra键值 |
|
intentSetting.putExtra('key_barcode_broadcast', strdata) |
|
// 提交设置 |
|
console.log('广播动作:' + deviceAction + ',接受的标签值:' + strdata) |
|
main.sendBroadcast(intentSetting) |
|
// #endif |
|
}, |
|
//获取当前APP的版本信息 |
|
getversion: () => { |
|
return new Promise((relove, reject) => { |
|
// #ifdef APP |
|
// console.log('123123123') |
|
//获取当前的包名 |
|
let main = plus.android.runtimeMainActivity() |
|
let pkName = main.getPackageName() |
|
// 获取当前应用版本号 |
|
plus.runtime.getProperty(plus.runtime.appid, info => { |
|
console.log(info.version, pkName) |
|
let obj = { |
|
version: info.version, |
|
pkName, |
|
} |
|
relove(obj) |
|
}) |
|
// #endif |
|
}) |
|
}, |
|
//执行下载更新(apk和wgt都可以) |
|
updatefile: file => { |
|
// #ifdef APP |
|
const downloadTask = uni.downloadFile({ |
|
//执行下载 |
|
url: file, //下载地址 |
|
success: downloadResult => { |
|
//下载成功 |
|
if (downloadResult.statusCode == 200) { |
|
// console.log('downloadResult','downloadResult'); |
|
plus.runtime.install( |
|
//安装 |
|
downloadResult.tempFilePath, { |
|
force: true, |
|
}, |
|
function(res) { |
|
uni.showToast({ |
|
title: '安装成功', |
|
icon: 2000, |
|
duration: 1000, |
|
}) |
|
setTimeout(function() { |
|
plus.runtime.restart() |
|
}, 1100) |
|
} |
|
) |
|
} |
|
}, |
|
}) |
|
var showLoading = plus.nativeUI.showWaiting('正在下载', { |
|
back: 'none', |
|
}) |
|
downloadTask.onProgressUpdate(res => { |
|
showLoading.setTitle(' 正在下载' + res.progress + '% ') |
|
if (res.progress == 100) { |
|
plus.nativeUI.closeWaiting() |
|
} |
|
}) |
|
// #endif |
|
}, |
|
//执行下载更新(无感)(wgt) |
|
updatefile1: file => { |
|
// #ifdef APP |
|
const downloadTask = uni.downloadFile({ |
|
//执行下载 |
|
url: file, //下载地址 |
|
success: downloadResult => { |
|
//下载成功 |
|
if (downloadResult.statusCode == 200) { |
|
// console.log('downloadResult','downloadResult'); |
|
plus.runtime.install( |
|
//安装 |
|
downloadResult.tempFilePath, { |
|
force: true, |
|
}, |
|
function(res) { |
|
setTimeout(function() { |
|
plus.runtime.restart() |
|
}, 1100) |
|
} |
|
) |
|
} |
|
}, |
|
}) |
|
// var showLoading = plus.nativeUI.showWaiting("正在下载", {back: "none"}); |
|
// downloadTask.onProgressUpdate((res) => { |
|
// showLoading.setTitle(" 正在下载" + res.progress + "% "); |
|
// if (res.progress == 100) { |
|
// plus.nativeUI.closeWaiting(); |
|
// } |
|
// }); |
|
// #endif |
|
}, |
|
/** |
|
* 异步获取元素距离视口顶部的距离 |
|
* @param {String} className |
|
@return {Promise} (string) => promise |
|
*/ |
|
getViewDistanceFormTop(className) { |
|
return new Promise((resolve, reject) => { |
|
uni.getSystemInfo({ |
|
success: resu => { |
|
let _height = '' |
|
const query = uni.createSelectorQuery() |
|
// 获取当前swiper距离顶部的位置 |
|
query.select(className).boundingClientRect() |
|
query.exec(res => { |
|
// 屏幕的高度减去当前swiper距离顶部的高度就是剩余屏幕的高度,然后动态赋值给swiperHeight |
|
_height = resu.windowHeight - res[0].top + 'px' |
|
console.log('页面的剩余高度', _height) |
|
|
|
resolve(_height) |
|
}) |
|
}, |
|
fail: res => { |
|
reject('') |
|
}, |
|
}) |
|
}) |
|
}, |
|
/** |
|
* 提示 |
|
* @param {String} content 提示的文字 |
|
*/ |
|
handleToast(content, icon = 'none', isShowMsg = true) { |
|
if (isShowMsg) |
|
uni.showToast({ |
|
title: content, |
|
icon: icon, |
|
duration: 1500, |
|
}) |
|
|
|
// #ifdef APP |
|
this.ttsspke(content) |
|
// #endif |
|
}, |
|
|
|
/** 防抖函数 */ |
|
debounce(func, delay) { |
|
let timer |
|
if (!delay) delay = 500 |
|
return (function() { |
|
const context = this |
|
const args = arguments |
|
clearTimeout(timer) |
|
timer = setTimeout(function() { |
|
func.apply(context, args) |
|
// func(); |
|
console.log('timer :>> ', timer) |
|
clearTimeout(timer) |
|
}, delay) |
|
})() |
|
}, |
|
/** 是否为数字 */ |
|
isNumber(content) { |
|
return !isNaN(parseFloat(content)) && isFinite(content) |
|
}, |
|
/** 获取类型 */ |
|
getObjType(obj) { |
|
var toString = Object.prototype.toString |
|
var map = { |
|
'[object Boolean]': 'boolean', |
|
'[object Number]': 'number', |
|
'[object String]': 'string', |
|
'[object Function]': 'function', |
|
'[object Array]': 'array', |
|
'[object Date]': 'date', |
|
'[object RegExp]': 'regExp', |
|
'[object Undefined]': 'undefined', |
|
'[object Null]': 'null', |
|
'[object Object]': 'object', |
|
} |
|
// if (obj instanceof Element) { |
|
// return 'element' |
|
// } |
|
return map[toString.call(obj)] |
|
}, |
|
/** 深拷贝 */ |
|
deepClone(data) { |
|
var type = this.getObjType(data) |
|
var obj |
|
if (type === 'array') { |
|
obj = [] |
|
} else if (type === 'object') { |
|
obj = {} |
|
} else { |
|
//不再具有下一层次 |
|
return data |
|
} |
|
if (type === 'array') { |
|
for (var i = 0, len = data.length; i < len; i++) { |
|
obj.push(this.deepClone(data[i])) |
|
} |
|
} else if (type === 'object') { |
|
for (var key in data) { |
|
obj[key] = this.deepClone(data[key]) |
|
} |
|
} |
|
return obj |
|
}, |
|
/** |
|
* 数字运算(主要用于小数点精度问题) |
|
* [see](https://juejin.im/post/6844904066418491406#heading-12) |
|
* @param {number} a 前面的值 |
|
* @param {"+"|"-"|"*"|"/"} type 计算方式 |
|
* @param {number} b 后面的值 |
|
* @example |
|
* ```js |
|
* // 可链式调用 |
|
* const res = computeNumber(1.3, "-", 1.2).next("+", 1.5).next("*", 2.3).next("/", 0.2).result; |
|
* console.log(res); |
|
* ``` |
|
*/ |
|
computeNumber(a, type, b) { |
|
/** |
|
* 获取数字小数点的长度 |
|
* @param {number} n 数字 |
|
*/ |
|
function getDecimalLength(n) { |
|
const decimal = n.toString().split('.')[1]; |
|
return decimal ? decimal.length : 0; |
|
} |
|
/** |
|
* 修正小数点 |
|
* @description 防止出现 `33.33333*100000 = 3333332.9999999995` && `33.33*10 = 333.29999999999995` 这类情况做的处理 |
|
* @param {number} n |
|
*/ |
|
const amend = (n, precision = 15) => parseFloat(Number(n).toPrecision(precision)); |
|
const power = Math.pow(10, Math.max(getDecimalLength(a), getDecimalLength(b))); |
|
let result = 0; |
|
|
|
a = amend(a * power); |
|
b = amend(b * power); |
|
|
|
switch (type) { |
|
case '+': |
|
result = (a + b) / power; |
|
break; |
|
case '-': |
|
result = (a - b) / power; |
|
break; |
|
case '*': |
|
result = (a * b) / (power * power); |
|
break; |
|
case '/': |
|
result = a / b; |
|
break; |
|
} |
|
|
|
result = amend(result); |
|
|
|
return { |
|
/** 计算结果 */ |
|
result, |
|
/** |
|
* 继续计算 |
|
* @param {"+"|"-"|"*"|"/"} nextType 继续计算方式 |
|
* @param {number} nextValue 继续计算的值 |
|
*/ |
|
next(nextType, nextValue) { |
|
return computeNumber(result, nextType, nextValue); |
|
}, |
|
}; |
|
}, |
|
handleUpload(fileList, index, option) { |
|
wx.uploadFile({ |
|
url: host + 'api/common/upload ', //仅为示例,非真实的接口地址 |
|
filePath: fileList[index], |
|
name: 'file', |
|
header: { |
|
Authorization: `Bearer ${uni.getStorageSync('token')}` |
|
}, |
|
formData: { |
|
'user': 'test' |
|
}, |
|
success: (res) => { |
|
const data = res.data |
|
|
|
console.log('data :>> ', data); |
|
|
|
const response = JSON.parse(data) |
|
|
|
if (response.code === 1001) { |
|
store.commit('HANDLE_UPDATA_TOKEN', response.data) |
|
return this.handleUpload(fileList, index, option) |
|
} else if (response.code === 1002) { |
|
uni.reLaunch({ |
|
url: '/pages/login/login' |
|
}) |
|
return |
|
} else if (response.code !== 200) return |
|
|
|
option.successByUpload && option.successByUpload(res) |
|
|
|
this.handleWhileUpload(fileList, index + 1, option) |
|
} |
|
}) |
|
}, |
|
handleWhileUpload(fileList, startIndex = 0, option) { |
|
if (startIndex >= fileList.length) return option.allSuccess && option.allSuccess() |
|
|
|
this.handleUpload(fileList, startIndex, option) |
|
}, |
|
/** |
|
* 选择图片上传 |
|
* @param {Object} 配置 |
|
* successByUpload 每项文件上传成功后执行回调 |
|
* closeByUpload 每项文件上传失败后执行回调 |
|
* allSuccess 所有上传执行完毕后执行函数 |
|
* beforeUpload 上传前执行函数 |
|
*/ |
|
handleUploadFile(option) { |
|
// #ifdef MP-WEIXIN |
|
wx.chooseImage({ |
|
success: (res) => { |
|
if (option.beforeUpload) { |
|
const _flag = option.beforeUpload(res) |
|
if (_flag === false) return |
|
} |
|
|
|
const tempFilePaths = res.tempFilePaths |
|
|
|
console.log('this :>> ', this); |
|
|
|
this.handleWhileUpload(tempFilePaths, 0, option) |
|
|
|
// wx.uploadFile({ |
|
// url: 'http://192.168.5.34:9922/api/common/upload', //仅为示例,非真实的接口地址 |
|
// filePath: tempFilePaths[0], |
|
// name: 'file', |
|
// header: { |
|
// Authorization: `Bearer ${token}` |
|
// }, |
|
// formData: { |
|
// 'user': 'test' |
|
// }, |
|
// success(res) { |
|
// const data = res.data |
|
// //do something |
|
// } |
|
// }) |
|
} |
|
}) |
|
// #endif |
|
|
|
// uni.chooseImage({ |
|
// count: 10, |
|
// success(files) { |
|
// console.log('files :>> ', files); |
|
// let token = uni.getStorageSync('token') |
|
// // uni.uploadFile({ url: 'http://192.168.5.34:9922/api/common/upload', filePath: files.tempFilePaths[0], header: { Authorization: `Bearer ${token}` } }) |
|
|
|
// // const formData = new FormData(); |
|
|
|
// // formData.append("id", uuidv4()); |
|
// // formData.append( |
|
// // "file", |
|
// // new Blob([files.tempFiles[0]]) |
|
// // ); |
|
|
|
// // console.log('formData :>> ', formData); |
|
|
|
// // postUpload({ file: new Blob([files.tempFiles[0]]) }).then((res) => { |
|
// // console.log("res", res); |
|
// // }); |
|
|
|
// // const blob = dataURLtoBlob(JSON.stringify(files.tempFiles[0])) |
|
|
|
// // postUpload({ file: blob }) |
|
// } |
|
// }) |
|
} |
|
} |
|
export default utils |