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.

353 lines
8.8 KiB

2 years ago
<template>
<view class="main-container">
<view class="centerBody">
<view class="card">
<view class="title">升级文件</view>
<view class="titleflex">
<view class="titleInput">
<view class="checkInput" ref="input">{{textName}}</view>
</view>
<u-button type="primary" text="查找文件" @click="openFileSeletor"></u-button>
</view>
</view>
<view class="card">
<view class="title">软件版本</view>
<view class="titleflex">
<view class="uptitle">
<u-input v-model="version" disabled />
</view>
<u-button type="primary" text="读取" @click="readFileAsync"></u-button>
</view>
</view>
<view class="card">
<view class="titleflex">
<u-button type="primary" text="固件升级" @click="upgradeDevice"></u-button>
<!-- <u-button type="primary" text="重启"></u-button>
<u-button type="primary" text="取消"></u-button> -->
</view>
<view class="upgstyle">
升级进度:<span v-if="!uploadStatus">正在升级.. {{num+'%'}}</span>
<span v-else>升级成功! {{num+'%'}}</span>
</view>
<view class="upgProgress">
<u-line-progress :percentage="num" :showText="false" activeColor="#4BACC6"></u-line-progress>
</view>
</view>
</view>
<u-overlay class='u-mask' :show="commandmaskshow" :opacity="0.6">
<view>
<u-loading-icon size='40'></u-loading-icon>
</view>
</u-overlay>
<nk-select-file v-model="show" @confirm="getPath"></nk-select-file>
<u-toast ref="uToast"></u-toast>
</view>
</template>
<script>
// #ifdef APP
import ecUI from '@/utils/ecUI.js'
import ecBLE from '@/utils/ecBLE/ecBLE.js'
import { sendDeviceUpgrade, receivecommand, sendStartUpgtade, sendReadDevicestatus} from '@/common/network/protocol645.js'
// #endif
// #ifdef MP
const ecUI = require('@/utils/ecUI.js')
const ecBLE = require('@/utils/ecBLE/ecBLE.js')
// #endif
export default{
data(){
return{
value:'',
num:0,
fileName:null,
timecall:null,
textName:'请选择文件',
show:false,
commandmaskshow:false,
fullPath:'',
uploadStatus:false,
version:'',
}
},
onShow() {
this.uploadStatus=false
this.num=0
},
methods:{
openFileSeletor(){
this.show = true;
this.uploadStatus=false;
// 下面代码为h5环境下获取文件并解析;
// let list = []
// let that = this;
// h5获取上传文件以及
// var input = document.createElement('input');
// input.type = 'file';
// input.style.display="none";
// input.click();
// input.addEventListener('change', function(event) {
// var file = event.target.files[0]; // 获取文件对象
// that.textName = file.name
// // 将所取文件转为字节数组
// var reader = new FileReader();
// reader.onload = function(e) {
// var fileData = e.target.result;
// let size = Math.ceil(fileData.byteLength / 128);
// that.num = size;
// var uint8View = new Uint8Array(fileData);
// console.log(uint8View.slice(0, 128));
// console.log(Array.from(uint8View.slice(0, 128)).map(byte => byte.toString(16)));
// }
// reader.onerror = function(e) {
// console.error('文件读取错误');
// }
// reader.readAsArrayBuffer(file);
// });
},
decimalToHex(decimal) {
let dec = decimal % 205
var hex;
var nums;
var hex2;
if(decimal>204){
hex = dec.toString(16).padStart(2,'0');
}else{
hex = (decimal + 51).toString(16);
}
nums = Math.floor(decimal/256);
if(nums>204){
hex2 = nums.toString(16).padStart(2,'0');
}else{
hex2 = (nums+51).toString(16);
}
return hex2+hex;
},
readFileAsync() {
let that = this
let id = getApp().globalData.id;
if(!id){
this.$refs.uToast.show({
message: "未连接蓝牙设备!",
type: "warning",
icon: false,
});
return
};
let data={}
data.id = id;
this.commandmaskshow = true
let ans = ''
sendReadDevicestatus(data).then((res)=>{
let result = receivecommand(res,data)
if(result){
this.commandmaskshow = false
for(let i=0;i<res.data.length;i++){
let text = parseInt(res.data[i],16).toString()
ans+=text
}
that.version = ans;
that.$refs.uToast.show({
message: "读取成功!",
type: "success",
icon: false,
});
}
})
},
upgradeDevice(){
if(!getApp().globalData.id){
this.$refs.uToast.show({
message: "未连接蓝牙设备!",
type: "warning",
icon: false,
});
return
};
if(this.pathArr==undefined){
this.$refs.uToast.show({
message: "未选择升级文件!",
type: "warning",
icon: false,
});
return
}
let that = this
this.commandmaskshow=true;
this.uploadStatus=false;
var FileInputStream = plus.android.importClass("java.io.FileInputStream");
var File = plus.android.importClass("java.io.File");
var files = new File(this.pathArr.url);
var fileLength = files.length();
var size = Math.ceil(fileLength/128); //总上传数量
var value; //文件数据
let data2 = {} //上传数据
let maxUpload = 0; //上传序号
let str = that.pathArr.name
let textChecks = Number(str.substring(str.indexOf("-") + 1, str.indexOf(".")))//文件总校验和
console.log('文件校验和:'+textChecks);
data2.id = getApp().globalData.id;
const start =()=>{
var fileSize = new FileInputStream(this.pathArr.url);
let arrList = [] //单次上传字节数组
let max = 0;
fileSize.skip(maxUpload*128);
while(maxUpload<size && max<128){
value = fileSize.read();
if(value==-1){
break;
}
max++
arrList.push(value);
}
if(maxUpload<size){
that.num = Math.ceil((maxUpload * 100) / size);
data2.msg = arrList;
data2.len = arrList.length;
data2.number = that.decimalToHex(maxUpload);
sendDeviceUpgrade(data2).then((res)=>{
let result = receivecommand(res,data2)
if(result){
maxUpload++;
start();
fileSize.close();
if(that.num==100){
that.uploadStatus=true;
that.commandmaskshow=false;
}
}else{
that.uploadStatus=false;
fileSize.close();
let text = res.text.substring(16,18);
let errorText=""
if(text=="43"){
errorText="标识长度错误"
}else if(text=="3A"){
errorText="数据内容重复"
}else if(text=="35"){
errorText="标识报序号溢出"
}else{
errorText="标识总校验错误"
}
that.$refs.uToast.show({
message: errorText,
type: "error",
icon: false,
});
}
})
}
}
var data = {}
data.id = getApp().globalData.id;
data.msg={
textChecks:textChecks.toString().padStart(8,"0"),
lenChecks:fileLength.toString(16).padStart(8,"0"),
}
//启动升级命令
sendStartUpgtade(data).then((res)=>{
let result = receivecommand(res,data)
if(result){
start();
}
})
},
getPath(event){
this.pathArr = event[0];
this.textName = event[0].name;
}
}
}
</script>
<style scoped>
.main-container {
padding: 28rpx 0 1px;
background: linear-gradient(
180deg,
rgba(235, 241, 255, 0.5) 0%,
#e4ebff 100%
);
height: 100%;
}
.title{
margin-bottom: 24rpx;
font-size: 38rpx;
font-weight: bold;
line-height: 50rpx;
}
.card {
margin: 0 32rpx 28rpx;
padding: 28rpx;
background-color: #ffffff;
border-radius: 10rpx;
}
.titleflex{
display: flex;
height: 100rpx;
align-items: center;
}
.titleflex button{
width: 160rpx;
}
.titleInput{
margin-right: 30px;
}
.sliderModel >>> uni-slider .uni-slider-handle-wrapper{
height: 20rpx;
width: 400rpx;
}
.uptitle >>> .u-input--radius{
width: 400rpx;
}
.upgstyle{
font-size: 48rpx;
margin-top: 40rpx;
}
.upgstyle span{
color:red;
}
.upgProgress{
width: 95%;
margin-left: 2.5%;
}
.upgProgress >>> .u-line-progress__background{
height: 80rpx !important;
border-radius: 0;
}
.upgProgress >>> .u-line-progress__line{
height: 80rpx !important;
border-radius: 0;
}
.upgProgress >>> .u-line-progress__line span{
font-size: 40rpx;
}
.upgProgress >>> .u-line-progress{
border-radius: 0;
}
.checkInput{
width: 350rpx;
height: 70rpx;
border: 2rpx solid #ddd;
line-height: 70rpx;
padding-left: 40rpx;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.u-mask{
display: flex;
align-items: center;
justify-content: center;
}
.u-mask >>> .u-loading-icon__dot:before{
width: 3px;
}
.u-mask >>> .u-loading-icon__dot{
color: #fff;
}
</style>