bike/page_user/changeCar.vue
2024-12-30 14:31:59 +08:00

2039 lines
47 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="page">
<u-navbar title="换车骑行" :border-bottom="false" :background="bgc" title-color='#000' title-size='36' height='45'
back-icon-color='#000'></u-navbar>
<view class="cont_box">
<view class="tit">
<image src="https://lxnapi.ccttiot.com/bike/img/static/uByIrgaV23PDGZWReKHW" mode=""></image>
请选择换车原因
</view>
<!-- https://lxnapi.ccttiot.com/bike/img/static/uZQYJi6D7tPy4CszHtau -->
<view class="choose_li">
<view class="li_cont" @click="checkIdx = 1">
<view class="img_box">
<image src="https://lxnapi.ccttiot.com/bike/img/static/uZQYJi6D7tPy4CszHtau" mode=""
v-if="checkIdx == 1"></image>
</view>
电量不足
</view>
<view class="li_cont" @click="checkIdx = 2">
<view class="img_box">
<image src="https://lxnapi.ccttiot.com/bike/img/static/uZQYJi6D7tPy4CszHtau" mode=""
v-if="checkIdx == 2"></image>
</view>
车辆损坏
</view>
</view>
<view class="tit" style="margin-top: 20rpx;">
SN{{ orderinfo.sn }}
</view>
</view>
<view class="cont_box" v-show="checkIdx == 2">
<view class="tit">
<image src="https://lxnapi.ccttiot.com/bike/img/static/uByIrgaV23PDGZWReKHW" mode=""></image>
请选择车辆故障部位
</view>
<!-- https://lxnapi.ccttiot.com/bike/img/static/uZQYJi6D7tPy4CszHtau -->
<view class="txt">
车头故障
</view>
<view class="checkbox">
<view v-for="(item, index) in cbgz" :key="index" class="check_li"
:class="item.checked === true ? 'act1' : ''" @click="toggleCheckbox(index)">
{{ item.dictLabel }}
<image src="https://lxnapi.ccttiot.com/bike/img/static/ufYwbVclwhX64u4eGu6u" mode=""
v-if="item.checked === true"></image>
</view>
</view>
<view class="txt">
车身故障
</view>
<view class="checkbox">
<view v-for="(item, index) in csgz" :key="index" class="check_li"
:class="item.checked === true ? 'act1' : ''" @click="csCheckbox(index)">
{{ item.dictLabel }}
<image src="https://lxnapi.ccttiot.com/bike/img/static/ufYwbVclwhX64u4eGu6u" mode=""
v-if="item.checked === true"></image>
</view>
</view>
<view class="txt">
特殊故障
</view>
<view class="checkbox">
<view v-for="(item, index) in tsgz" :key="index" class="check_li"
:class="item.checked === true ? 'act1' : ''" @click="tsCheckbox(index)">
{{ item.dictLabel }}
<image src="https://lxnapi.ccttiot.com/bike/img/static/ufYwbVclwhX64u4eGu6u" mode=""
v-if="item.checked === true"></image>
</view>
</view>
<view class="input-container">
<view class="placeholder" v-if="!textValue">如选项未涵盖,请输入故障问题</view>
<textarea class="custom-textarea" v-model="textValue" @focus="hidePlaceholder" style="border: none;"
@input="updateWordCount" @blur="showPlaceholder"></textarea>
<text class="word-count">{{ currentCount }}/500</text>
</view>
</view>
<view class="cont_box" v-if="checkIdx == 2 && areainfo.returnVerify == 0">
<view class="tit">
<image src="https://lxnapi.ccttiot.com/bike/img/static/uByIrgaV23PDGZWReKHW" mode=""></image>
请对故障部位拍照
</view>
<view class="icon">
<view class="imgbox" v-for="(item, index) in imglist " :key="index">
<image :src="item" mode=""></image>
</view>
<view class="imgbox" @click="btn">
<image src="https://api.ccttiot.com/smartmeter/img/static/uY8CPw9YE6JxPzcHUaqf" mode=""></image>
</view>
</view>
<!-- https://lxnapi.ccttiot.com/bike/img/static/uZQYJi6D7tPy4CszHtau -->
</view>
<view class="cont" v-if="areainfo.returnVerify == 1">
<view class="tip_txt" style="font-weight: 500;font-size: 32rpx;color: #3D3D3D;">
保持车辆录像的完整清晰,不要随意拍摄,确保视频中车辆出境,并且出现车牌号
</view>
<view class="vadio_png1" @click="recordVideo">
<image class="backimg" src="https://lxnapi.ccttiot.com/bike/img/static/uEP0UPJw6a1WuxA7ZlMo" mode=""
v-if="videoUrl == ''">
<image class="tip_img" src="https://lxnapi.ccttiot.com/bike/img/static/uXFG7Vee8MWx5y7pha2U"
mode=""></image>
</image>
<video class="vad" :src="videoUrl" controls="controls" style="width: 100%;" v-if="videoUrl != ''"></video>
<view class="glass" v-if="videoUrl != ''"></view>
<image class="tip_img" src="https://lxnapi.ccttiot.com/bike/img/static/uXFG7Vee8MWx5y7pha2U" mode=""
v-if="videoUrl != ''"></image>
</view>
</view>
<view class="tits">
点击扫码或输入车辆编号
</view>
<view class="iptbox">
<view class="qrcode" @click="qrcode()">
<image src="https://api.ccttiot.com/smartmeter/img/static/uy7BNwAMIKwvstqFnRhs" mode=""></image>
</view>
<input type="text" class="ips" v-model="sncode" placeholder="请扫描设备上的二维码" style="margin-left: 32rpx;"
placeholder-class="my-placeholder" />
</view>
<view class="conts_box" v-if="deviceinfo.sn">
<view class="cont_li">
<view class="left">
<view class="km">
可继续行驶{{ deviceinfo.remainingMileage }}公里
</view>
<view class="speed">
<view class="speeds" :style="{ width: deviceinfo.remainingPower + '%' }">
</view>
</view>
<view class="NO">
NO.{{ deviceinfo.sn }}
</view>
</view>
<view class="right">
<image src="https://lxnapi.ccttiot.com/bike/img/static/uqKmFMF9YHTX8lAQARSd" mode=""></image>
</view>
</view>
<view class="cont_li" style="margin-top: 10rpx;">
<view class="left" style="font-size: 32rpx;font-weight: 400;">
已骑行
</view>
<view class="right" style="font-size: 32rpx;font-weight: 400;">
{{ timeString }}
</view>
</view>
<view class="cont_li" style="margin-top: 10rpx;">
<view class="left" style="font-size: 32rpx;font-weight: 400;">
预估金额
</view>
<view class="right" style="font-size: 32rpx;font-weight: 400;">
{{ parseFloat(money).toFixed(2) }}元
</view>
</view>
<view class="txtss">
扫码开锁后将自动合并订单,骑行时间将继续计时
</view>
</view>
<!-- <view class="conts_box">
<view class="left">
已骑行
</view>
<view class="right">
{{timeString}}
</view>
</view>
<view class="conts_box">
<view class="left">
预估金额
</view>
<view class="right">
{{money}}元
</view>
</view> -->
<view class="btns" @click="subs(0)">
提交
</view>
<view class="maskloadpage" v-if="maskloading">
<view class="maskpage0" v-if="maskepage == 0">
<view class="top_info">
<image :src="loadimg" mode=""></image>
<view class="masktxt">
{{ toploadtxt }}
</view>
</view>
<view class="masktips">
{{ tiptxt }}
</view>
<view class="tipsimg">
<image src="https://lxnapi.ccttiot.com/bike/img/static/ugvqmfB3QYujZ6SnfTia" mode=""></image>
</view>
</view>
<view class="maskpage1" v-if="maskepage == 4">
<view class="top_info">
<image :src="loadimg" mode=""></image>
<view class="masktxt">
{{ buletxt }}
</view>
</view>
<view class="masktips" style="width: 100%;">
请确保与车辆的距离小于3米
</view>
<view class="tipsimg">
<image src="https://lxnapi.ccttiot.com/bike/img/static/ugvqmfB3QYujZ6SnfTia" mode=""></image>
</view>
</view>
<!-- 不允许停车点外还车 -->
<view class="maskpage1" v-if="maskepage == 5">
<view class="top_info">
<image src="https://lxnapi.ccttiot.com/bike/img/static/uG3cbPgvPDzwlq6IHHxK" mode=""></image>
<view class="masktxt" v-if="orderinfo.sn">
蓝牙连接失败
</view>
</view>
<view class="masktips" style="width: 100%;">
请确保手机蓝牙已经打开
</view>
<view class="masktips" @click="totxtpage()"
style="width: 100%;color: #4C97E7;text-decoration-line: underline;margin-top: 0; font-size: 28rpx;">
点击查看教程
</view>
<view class="tipsimg">
<image src="https://lxnapi.ccttiot.com/bike/img/static/ugvqmfB3QYujZ6SnfTia" mode=""></image>
</view>
<view class="btn_box">
<view class="btn4" @click="closemask()">
返回
</view>
<view class="btn3" @click="subs(1)">
重新尝试
</view>
</view>
</view>
</view>
</view>
</template>
<script>
const app = getApp();
var xBlufi = require("@/utils/blufi/xBlufi.js");
let _this = null;
export default {
data() {
return {
bgc: {
backgroundColor: "#fff",
},
cbgz: [],
csgz: [],
tsgz: [
],
textValue: '',
currentCount: 0,
imglist: [],
token: '',
sn: '',
upurl: '',
checkIdx: 1,
maskloading: false,
maskepage: 0,
sn: 0,
mac: 0,
orderinfo: {},
sncode: '',
money: '',
timer: null,
timeString: '',
deviceinfo: {},
issend: false,
isback: false,
isopen: false,
upvideo: false,
maskloading: false,
toploadtxt: "开锁中0%",
loadimg: 'https://lxnapi.ccttiot.com/bike/img/static/urJQJnOI1DEjWatFqHYh',
tiptxt: '请定点停放,规范用车',
maskepage: 0,
backgps: {},
buletxt: '',
buleclose: false,
buleopen: false,
bulering: false,
bulerebort: false,
getnum: 0,
showvehicle: false,
vehicleNum: '',
gps: {},
areainfo: {},
areaId: '',
videoUrl: ''
}
},
onLoad(e) {
this.getlist()
},
watch: {
sncode: {
handler(newValue) {
if (newValue && newValue.length === 7) {
// 等待 orderinfo 加载完成后再获取设备信息
if (this.orderinfo && this.orderinfo.areaId) {
this.getdevice();
} else {
// 如果 orderinfo 还未加载完成,等待后再调用
setTimeout(() => {
this.getdevice();
}, 500);
}
}
},
immediate: false
}
},
onHide() {
clearInterval(this.timer);
// 页面隐藏时清除定时器
if (this.timers) {
clearInterval(this.timers);
this.timers = null;
console.log('定时器已清除');
}
xBlufi.listenDeviceMsgEvent(false, this.funListenDeviceMsgEvent);
xBlufi.notifyStartDiscoverBle({
'isStart': false
});
},
onUnload() {
clearInterval(this.timer);
// 页面卸载时清除定时器
if (this.timers) {
clearInterval(this.timers);
this.timers = null;
console.log('定时器已清除');
}
xBlufi.listenDeviceMsgEvent(false, this.funListenDeviceMsgEvent);
xBlufi.notifyStartDiscoverBle({
'isStart': false
});
},
onBeforeUnmount() {
clearInterval(this.timer);
if (this.timers) {
clearInterval(this.timers);
this.timers = null;
console.log('定时器已清除');
}
xBlufi.listenDeviceMsgEvent(false, this.funListenDeviceMsgEvent);
xBlufi.notifyStartDiscoverBle({
'isStart': false
});
},
onShow() {
// if (uni.getStorageSync('adminAreaid')) {
// }
this.$store.dispatch('userInfo', this.$u).then(() => {
this.getQiniuToken()
this.getisInOrder()
// 执行其他操作...
});
let that = this
uni.getLocation({
type: 'gcj02',
success: function (lb) {
that.gps.latitude = lb.latitude;
that.gps.longitude = lb.longitude;
},
fail: function (error) {
uni.showToast({
title: '未获取到定位信息,请点击设置勾选允许位置信息,即可使用全部功能',
icon: 'none',
duration: 2000
});
// that.getmarks()
// 在这里处理获取位置信息失败的情况
}
})
},
computed: {
userId() {
return this.$store.getters.userId;
},
},
methods: {
totxtpage() {
// this.seeDetail = true
uni.navigateTo({
url: '/page_user/bulelink'
})
},
getQiniuToken() {
console.log('diaou');
this.$u.get("/common/qiniu/uploadInfo").then((res) => {
if (res.code == 200) {
this.token = res.token
console.log(res, 'resres');
this.upurl = res.domain
}
});
// this.$u.get('https://v2.ielts.langsi.online/file/getToken').then(res => {
// console.log(res.data);
// this.token = res.data.token
// }).catch(err => {
// console.log(err)
// })
},
btn() {
let _this = this
let math = 'static/' + _this.$u.guid(20)
uni.chooseImage({
count: 9,
type: 'all',
success(res) {
// tempFilePath可以作为img标签的src属性显示图片
const tempFilePaths = res.tempFiles
// let tempFilePaths = chooseImageRes.tempFilePaths;
// console.log(tempFilePaths)
// tempFilePaths.forEach(item=>{
// // 上传图片到七牛云
// })
wx.uploadFile({
url: 'https://up-z2.qiniup.com',
name: 'file',
filePath: tempFilePaths[0].path,
formData: {
token: _this.token, //后端返回的token
key: 'smartmeter/img/' + math
},
success: function (res) {
console.log(res, 'resres');
let str = JSON.parse(res.data)
console.log(str.key)
_this.userImgs = _this.upurl + '/' + str.key
console.log(_this.userImgs)
_this.imglist.push(_this.userImgs)
}
});
}
})
},
getArea() {
let id = this.areaId
this.$u.get("/app/area/" + id).then((res) => {
if (res.code == 200) {
this.areainfo = res.data
// this.areainfo.returnVerify = 0
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
});
}
});
},
closemask() {
this.maskloading = false
},
sub() {
let data = {
userId: this.orderinfo.userId,
detail: this.textValue,
sn: this.orderinfo.sn,
orderNo: this.orderinfo.orderNo,
types: [] // Initialize the type array
};
if (this.areainfo.returnVerify == 0) {
data.picture = this.imglist.join(',')
} else {
data.picture = this.videoUrl
}
// Check for checked items in cbgz
this.cbgz.forEach(item => {
if (item.checked) {
data.types.push(item.dictValue);
}
});
// Check for checked items in csgz
this.csgz.forEach(item => {
if (item.checked) {
data.types.push(item.dictValue);
}
});
// Check for checked items in tsgz
this.tsgz.forEach(item => {
if (item.checked) {
data.types.push(item.dictValue);
}
});
console.log(data, 'dadadad');
this.$u.post("/appVerify/fault", data).then((res) => {
if (res.code == 200) {
this.issend = true
uni.showToast({
title: '提交成功',
icon: 'none',
duration: 1000
});
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 1000
});
}
});
},
subvadio() {
let data = {
orderNo: this.orderinfo.orderNo,
}
if (!this.orderinfo.videoUrl) {
data.videoUrl = this.videoUrl
}
if (this.orderinfo.videoUrl) {
data.videoUrl = this.orderinfo.videoUrl + ',' + this.videoUrl
}
this.$u.put('/appVerify/order/saveVideoUrl', data).then((res) => {
// uni.hideLoading()·
if (res.code === 200) {
this.upvideo = true
} else {
}
})
},
recordVideo() {
// 调用录像API
uni.chooseVideo({
sourceType: ['camera'], // 指定使用相机录像
camera: 'back', // 指定使用后置摄像头可选值有front、back
maxDuration: 15, // 最大录制时长(秒)
success: (res) => {
// 获取视频录制文件的临时路径
this.videoPath = res.tempFilePath;
console.log(res.tempFilePath);
this.upload()
},
fail: (err) => {
console.log('录像失败:', err);
}
});
},
upload() {
uni.showLoading({
title: '上传中'
})
let _this = this
let math = 'static/' + _this.$u.guid(20)
wx.uploadFile({
url: 'https://up-z2.qiniup.com',
name: 'file',
filePath: this.videoPath,
formData: {
token: _this.token, //后端返回的token
key: 'bike/video/' + math
},
success: function (res) {
uni.hideLoading()
console.log(res, 'resres');
let str = JSON.parse(res.data)
console.log(str.key)
_this.videoUrl = _this.upurl + '/' + str.key
console.log(_this.userImgs)
// _this.imglist.push(_this.userImgs)
}
});
},
subs(num) {
if (this.deviceinfo.onlineStatus == 0) {
uni.showToast({
title: '当前设备离线中,请使用其他车辆',
icon: 'none',
duration: 1000
});
return
}
if (this.orderinfo.sn === this.sncode) {
uni.showToast({
title: '换车设备不能和当前设备相同',
icon: 'none',
duration: 1000
});
} else if (this.areainfo.returnVerify == 1 && this.videoUrl == '') {
uni.showToast({
title: '请拍摄还车视频',
icon: 'none',
duration: 1000
});
} else if (this.areainfo.returnVerify === 0 && this.checkIdx === 2) {
if (this.imglist.length < 1) {
uni.showToast({
title: '请对损坏部位拍照',
icon: 'none',
duration: 1000
});
} else {
uni.showToast({
title: '请选择损坏部位',
icon: 'none',
duration: 1000
});
}
} else if (!this.deviceinfo.sn) {
uni.showToast({
title: '请扫码或者输入车辆编号',
icon: 'none',
duration: 1000
});
} else {
// if(this.)
if (num === 0) {
this.maskloading = true;
this.maskepage = 0;
this.loadimg = 'https://lxnapi.ccttiot.com/bike/img/static/uRxPPoVoqmnmng6wKlij';
let percentage = 0;
const interval = setInterval(() => {
if (percentage < 98) {
percentage += 2; // 每次增加的百分比,可以调整
this.toploadtxt = `换车中${percentage}%`;
} else {
clearInterval(interval);
this.toploadtxt = "换车中98%";
}
}, 40); // 每40毫秒更新一次可以调整
}
if (!this.upvideo && this.orderinfo.returnVerify === 1) {
this.subvadio();
}
if (this.checkIdx === 2 && !this.issend) {
this.sub();
}
if (!this.isback) {
this.changeback();
} else if (!this.isopen) {
setTimeout(() => {
this.changeOpne();
}, 300)
}
setTimeout(() => {
if (this.isback && this.isopen) {
this.loadimg = 'https://lxnapi.ccttiot.com/bike/img/static/ukD735zCS1yQXw2aGun8';
this.toploadtxt = '换车成功';
setTimeout(() => {
this.resetState();
this.getisInOrder();
uni.navigateBack({
delta: 1 // delta值为1时表示返回的页面层数
});
}, 1000);
}
}, 2000);
}
},
resetState() {
this.isback = false;
this.isopen = false;
this.issend = false;
this.upvideo = false;
this.deviceinfo = {};
this.maskloading = false;
this.sncode = '';
},
changeback() {
// this.mac=this.orderinfo.mac
// this.buleclose=true
// this.Binddevice()
this.$u.post('/appVerify/changeVehicle/lock?orderNo=' + this.orderinfo.orderNo + '&changeReason=' + this.checkIdx + "&newSn=" + this
.deviceinfo.sn).then((res) => {
if (res.code == 200) {
this.isback = true
this.subs(1)
} else {
uni.showToast({
title: '换车关锁失败',
icon: 'none',
duration: 1000
});
// 处理接口返回错误的情况
this.mac = this.orderinfo.mac
this.buleclose = true
this.Binddevice()
}
}).catch(error => {
// 处理接口请求失败的情况
});
},
buleback() {
this.$u.post('/appVerify/changeVehicle/lock?orderNo=' + this.orderinfo.orderNo + '&changeReason=' + this
.checkIdx + '&isBluetooth=true' + '&lon=' + lb.longitude +
'&lat=' + lb.latitude).then((res) => {
if (res.code == 200) {
this.isback = true
this.subs(1)
}
}).catch(error => {
// 处理接口请求失败的情况
});
},
changeOpne() {
this.$u.post('/appVerify/changeVehicle/unlocking?orderNo=' + this.orderinfo.orderNo + '&newSn=' + this
.deviceinfo.sn).then((res) => {
if (res.code == 200) {
this.isopen = true
this.subs(1)
} else {
uni.showToast({
title: '换车开锁失败',
icon: 'none',
duration: 1000
});
this.mac = this.deviceinfo.mac
this.buleopen = true
this.Binddevice()
// 处理接口返回错误的情况
}
}).catch(error => {
// 处理接口请求失败的情况
});
},
changebuleOpne() {
this.$u.post('/appVerify/changeVehicle/unlocking?orderNo=' + this.orderinfo.orderNo + '&newSn=' + this
.deviceinfo.sn + '&isBluetooth=true' + '&lon=' + this.gps.longitude + '&lat=' + this.gps.latitude)
.then((res) => {
if (res.code == 200) {
this.isopen = true
this.subs(1)
}
}).catch(error => {
// 处理接口请求失败的情况
});
},
getdevice() {
if (!this.sncode) {
return;
}
// 清空当前设备信息
this.deviceinfo = {};
this.$u.get('/app/device/info?sn=' + this.sncode).then((res) => {
if (res.code === 200 && res.data) {
console.log('当前区域ID:', this.orderinfo.areaId);
console.log('设备区域ID:', res.data.areaId);
// 确保两个值都存在且为数字类型进行比较
const currentAreaId = Number(this.orderinfo.areaId);
const deviceAreaId = Number(res.data.areaId);
if (!isNaN(currentAreaId) && !isNaN(deviceAreaId) && currentAreaId === deviceAreaId) {
this.deviceinfo = res.data;
} else {
uni.showToast({
title: '换车设备和当前运营区不同,请使用其他车辆换车',
icon: 'none',
duration: 2000
});
this.sncode = ''; // 清空输入的 sn
}
} else {
uni.showToast({
title: res.msg || '获取设备信息失败',
icon: 'none',
duration: 2000
});
}
}).catch(error => {
console.error('获取设备信息错误:', error);
uni.showToast({
title: '获取设备信息失败',
icon: 'none',
duration: 2000
});
});
},
qrcode() {
uni.scanCode({
onlyFromCamera: true,
scanType: ['qrCode'],
success: res => {
try {
let sn = null;
let queryParams = res.result.split('?')[1];
if (queryParams) {
let params = queryParams.split('&');
params.forEach(param => {
let [key, value] = param.split('=');
if (key === 'sn') {
sn = value;
}
});
}
if (!sn) {
uni.showToast({
title: '无效的二维码',
icon: 'none',
duration: 2000
});
return;
}
this.sncode = sn;
if (this.sncode) {
// 等待 orderinfo 加载完成后再获取设备信息
if (this.orderinfo && this.orderinfo.areaId) {
this.getdevice();
} else {
// 如果 orderinfo 还未加载完成,等待后再调用
setTimeout(() => {
this.getdevice();
}, 500);
}
}
} catch (error) {
console.error('二维码解析错误:', error);
uni.showToast({
title: '二维码格式错误',
icon: 'none',
duration: 2000
});
}
},
fail: err => {
console.error('扫描失败:', err);
uni.showToast({
title: '扫描失败',
icon: 'none',
duration: 2000
});
}
});
},
Binddevice() {
uni.getBluetoothAdapterState({
success: function (res) {
console.log('蓝牙状态:', res.available)
},
fail: function (res) {
console.log('获取蓝牙状态失败')
}
})
this.maskloading = true
this.devicesList = []
this.maskepage = 4
this.buletxt = '蓝牙连接中'
// uni.showLoading({
// title: '蓝牙扫描中..'
// })
xBlufi.initXBlufi(1);
console.log("xBlufi", xBlufi.XMQTT_SYSTEM);
xBlufi.listenDeviceMsgEvent(true, this.funListenDeviceMsgEvent);
xBlufi.notifyStartDiscoverBle({
'isStart': true
});
// 两秒后停止蓝牙搜索
setTimeout(() => {
xBlufi.notifyStartDiscoverBle({
'isStart': false
});
setTimeout(() => {
// uni.hideLoading()
if (this.devicesList.length == 0) {
// uni.showToast({
// title: '暂无发现对应设备,请靠近设备',
// icon: 'none',
// duration: 1500
// });
this.maskepage = 5
} else {
let uniqueDevicesList = Array.from(new Set(this.devicesList));
// 将去重后的数组重新赋值给 this.devicesList
this.devicesList = uniqueDevicesList;
console.log(this.devicesList, 'this.devicesListthis.devicesList');
let istrue = false
this.devicesList.forEach(device => {
// 从设备名称中提取 MAC 地址(假设 MAC 地址是设备名称的后6个字符
let macFromName = device.name.substring(device.name.length - 12);
console.log(macFromName, 'macFromNamemacFromName');
// 与 this.mac 进行比较
if (macFromName == this.mac) {
// 如果相同,则将 this.ishave 设置为 true
console.log(device);
this.deviceInfoss = device
// this.ishave = true;
istrue = true
this.createBLEConnection(device)
console.log('对比正确1111111111');
} else {
console.log('对比错误');
}
});
setTimeout(() => {
if (!istrue) {
this.buletxt = '蓝牙连接失败'
setTimeout(() => {
this.maskepage = 5
}, 500)
}
}, 500)
}
}, 200)
// 判断是否存在浇花器设备
// this.status = true
}, 5000)
},
reboot() {
let vm = this; // 将外部的 this 绑定到 vm 上
uni.getNetworkType({
success(res) {
if (res.networkType !== 'none') {
uni.getConnectedBluetoothDevices({
success(res) {
console.log('已连接的蓝牙设备信息:', res);
// vm.dl = (vm.orderinfo.deviceAmount / vm.orderinfo.unitPrice).toFixed(2); // 使用 vm 访问 Vue 实例的属性
xBlufi.notifySendCustomData({
customData: "11reboot"
});
// vm.maskloading=false
// uni.hideLoading()
// vm.remakr()
},
fail(err) {
uni.hideLoading()
console.error('获取已连接蓝牙设备信息失败:', err);
}
});
} else {
console.log('手机未连接网络');
}
}
});
},
open() {
let vm = this; // 将外部的 this 绑定到 vm 上
uni.getNetworkType({
success(res) {
if (res.networkType !== 'none') {
uni.getConnectedBluetoothDevices({
success(res) {
console.log('已连接的蓝牙设备信息:', res);
// vm.dl = (vm.orderinfo.deviceAmount / vm.orderinfo.unitPrice).toFixed(2); // 使用 vm 访问 Vue 实例的属性
xBlufi.notifySendCustomData({
customData: "11open"
});
vm.maskepage = 0
vm.toploadtxt = '换车中';
vm.changebuleOpne()
// uni.hideLoading()
// vm.remakr()
},
fail(err) {
// uni.hideLoading()
console.error('获取已连接蓝牙设备信息失败:', err);
}
});
} else {
console.log('手机未连接网络');
}
}
});
},
close() {
let vm = this; // 将外部的 this 绑定到 vm 上
uni.getNetworkType({
success(res) {
if (res.networkType !== 'none') {
uni.getConnectedBluetoothDevices({
success(res) {
console.log('已连接的蓝牙设备信息:', res);
// vm.dl = (vm.orderinfo.deviceAmount / vm.orderinfo.unitPrice).toFixed(2); // 使用 vm 访问 Vue 实例的属性
xBlufi.notifySendCustomData({
customData: "11close"
});
// vm.maskloading=false
vm.buleback()
vm.maskepage = 0
vm.toploadtxt = '换车中';
// uni.hideLoading()
// vm.remakr()
},
fail(err) {
// uni.hideLoading()
console.error('获取已连接蓝牙设备信息失败:', err);
}
});
} else {
console.log('手机未连接网络');
}
}
});
},
funListenDeviceMsgEvent: function (options) {
switch (options.type) {
case xBlufi.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS:
if (options.result) {
let devicesarr = options.data
// this.devicesList = options.data
devicesarr.forEach(device => {
// this.$u.get(`/app/device/${mac}/isBind`, data).then((res) => {
// if (res.data == false) {
this.devicesList.push(device);
let uniqueDevicesList = Array.from(new Set(this.devicesList));
// 将去重后的数组重新赋值给 this.devicesList
this.devicesList = uniqueDevicesList;
});
}
break;
case xBlufi.XBLUFI_TYPE.TYPE_CONNECTED:
console.log("连接回调:" + JSON.stringify(options));
if (options.result) {
// uni.hideLoading();
xBlufi.notifyInitBleEsp32({
deviceId: options.data.deviceId
});
// xBlufi.listenDeviceMsgEvent(true, this.funListenDeviceMsgEvents);
// this.deviceIds = options.data.deviceId
// this.name = options.data.name
// 连接成功绑定设备
// let params = {
// mac: this.Bluetoothmac,
// userId: this.$store.state.user.userId
// }
let systemInfo = uni.getSystemInfoSync();
if (systemInfo.platform === 'android') {
// 当前设备是 Android
} else if (systemInfo.platform === 'ios') {
// 当前设备是 iOS
// uni.navigateTo({
// url: '/pages/wifilist/index?deviceId=' + options
// .data.deviceId + '&name=' + options.data.name
// })
}
}
if (options.result == false) {
// this.loadingmask=false
this.carstause = false
if (this.maskepage == 4) {
this.buletxt = '设备连接失败'
setTimeout(() => {
this.maskepage = 5
}, 800)
}
// uni.showModal({
// title: '很抱歉提醒你!',
// content: '小程序与设备异常断开',
// showCancel: false,
// success: function(res) {
// // uni.navigateBack({
// // url: '../search/search'
// // });
// }
// });
// this.statusflag = false
// uni.hideLoading();
}
break;
case xBlufi.XBLUFI_TYPE.TYPE_RECIEVE_CUSTON_DATA:
// this.ver_data = this.parseCustomData(options.data)
if (options.data) {
this.carstause = true
if (this.maskloading && this.maskepage == 4) {
// setTimeout(() => {
// this.maskloading = false
// }, 700)
if (this.buleclose == false && this.buleopen == false && this.bulerebort == false &&
this
.bulering == false) {
if (this.buletxt == '蓝牙连接中') {
this.buletxt = '蓝牙连接成功!'
}
}
if (this.buleclose) {
this.buleclose = false
this.close()
}
if (this.buleopen) {
this.buleopen = false
this.open()
}
if (this.bulerebort) {
this.buleopen = false
this.reboot()
}
if (this.bulering) {
this.bulering = false
this.ring()
}
}
} else {
this.carstause = false
if (this.maskepage == 4) {
this.buletxt = '设备连接失败'
setTimeout(() => {
this.maskepage = 5
}, 800)
}
}
console.log("1收到设备发来的自定义数据结果", options.data);
break;
case xBlufi.XBLUFI_TYPE.TYPE_STATUS_CONNECTED: {
console.log('状态', options.result)
if (options.result == false) {
this.carstause = false
if (this.maskepage == 4) {
this.buletxt = '设备连接失败'
setTimeout(() => {
this.maskepage = 5
}, 800)
}
// uni.showToast({
// title: '设备断开链接,请重新点击蓝牙链接',
// icon: 'none'
// });
// uni.showModal({
// title: '很抱歉提醒你!',
// content: '小程序与设备异常断开',
// showCancel: false,
// success: function(res) {
// // uni.navigateBack({
// // url: '../search/search'
// // });
// }
// });
// this.statusflag = false
// uni.hideLoading();
}
}
break;
case xBlufi.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_STOP:
if (options.result) {
let uniqueDevicesList = Array.from(new Set(this.devicesList));
// 过滤出名称字段的前五个字母为 "CTPOW" 的项
let filteredDevices = uniqueDevicesList.filter(device => device.name.substring(0,
4) ===
"BBLE");
// 将过滤后的数组重新赋值给 this.devicesList
this.devicesList = filteredDevices;
// console.log('蓝牙停止搜索ok',this.devicesList);
} else {
//蓝牙停止搜索失败
// console.log('蓝牙停止搜索失败');
}
this.searching = false
// _this.setData({
// searching: false
// });
break;
}
},
// 解析自定义数据
//4、建立连接
createBLEConnection(e) {
console.log('调用了');
xBlufi.notifyStartDiscoverBle({
'isStart': false
});
console.log(e, '蓝牙信息')
const deviceId = e.deviceId
this.Bluetoothmac = e.localName.substring(5) //从第七位开始截取 只取后面的mac号
console.log(this.Bluetoothmac, '11111');
let name = e.name;
console.log('点击了蓝牙准备连接的deviceId:' + e.deviceId);
xBlufi.notifyConnectBle({
isStart: true,
deviceId: e.deviceId,
name
});
// for (var i = 0; i < this.devicesList.length; i++) {
// if (e.deviceId === this.devicesList[i].deviceId) {
// uni.showLoading({
// title: '连接蓝牙设备中...'
// });
// }
// }
},
getisInOrder() {
// uni.showLoading({
// })
this.orderinfo = {}
if (this.userId) {
this.$u.post('/app/user/isInOrder?userId=' + this.userId,).then((res) => {
// uni.hideLoading()
if (res.code === 200) {
// this.freList=res.rows
this.orderinfo = res.data[0]
this.areaId = this.orderinfo.areaId
this.getArea()
const createTimeTimestamp = new Date(this.orderinfo.unlockTime).getTime();
this.$u.get('/app/device/info?sn=' + this.orderinfo.sn).then((res) => {
if (res.code == 200) {
this.orderinfo.mac = res.data.mac
} else {
// 处理接口返回错误的情况
}
}).catch(error => {
// 处理接口请求失败的情况
});
// 定义定时器
this.timer = setInterval(() => {
const currentTime = Date.now();
const timePassed = currentTime - createTimeTimestamp;
const secondsPassed = Math.floor(timePassed / 1000);
// 转换为时分秒格式
const hours = Math.floor(secondsPassed / 3600);
const minutes = Math.floor((secondsPassed % 3600) / 60);
const seconds = secondsPassed % 60;
const timeString =
`${hours < 10 ? '0' : ''}${hours}:${minutes < 10 ? '0' : ''}${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
let totalMinutes = hours * 60 + minutes;
let totalTime;
if (this.orderinfo.rule.rentalUnit === 'minutes') {
totalTime = totalMinutes;
} else if (this.orderinfo.rule.rentalUnit === 'hours') {
totalTime = hours + minutes / 60;
} else if (this.orderinfo.rule.rentalUnit === 'day') {
totalTime = hours / 24 + minutes / 1440;
}
// 计费规则计算
if (this.orderinfo.rule.ridingRule == 1) {
const ridingRuleJson = JSON.parse(this.orderinfo.rule.ridingRuleJson);
const timeoutTime = parseFloat(ridingRuleJson.timeoutTime);
const startingPrice = parseFloat(ridingRuleJson.startingPrice);
const startingTime = parseFloat(ridingRuleJson.startingTime);
const timeoutPrice = parseFloat(ridingRuleJson.timeoutPrice);
let totalCharge;
if (totalTime <= startingTime) {
totalCharge = startingPrice;
} else {
const extraTime = totalTime - startingTime;
const extraCharge = Math.ceil(extraTime / timeoutTime) *
timeoutPrice;
totalCharge = startingPrice + extraCharge;
}
// 更新money值
this.money = totalCharge + this.orderinfo.appointmentFee
} else if (this.orderinfo.rule.ridingRule == 2) {
const ridingRuleJson = JSON.parse(this.orderinfo.rule.ridingRuleJson);
const rules = ridingRuleJson.rule;
let totalCharge = 0;
for (let rule of rules) {
const start = parseFloat(rule.start);
const end = parseFloat(rule.end);
const eachUnit = parseFloat(rule.eachUnit);
const fee = parseFloat(rule.fee);
if (totalTime > start && (end === 9999 || totalTime <= end)) {
// 所有时间都按照该区间的费率来计算
totalCharge = Math.ceil(totalTime / eachUnit) * fee;
break;
}
}
// 更新money值
this.money = totalCharge + this.orderinfo.appointmentFee
}
// 更新时间字符串
this.timeString = timeString;
}, 1000);
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
});
}
})
}
},
toggleCheckbox(index) {
this.cbgz[index].checked = !this.cbgz[index].checked;
this.$forceUpdate()
},
csCheckbox(index) {
this.csgz[index].checked = !this.csgz[index].checked;
},
tsCheckbox(index) {
this.tsgz[index].checked = !this.tsgz[index].checked;
},
hidePlaceholder() {
this.placeholderVisible = false;
},
showPlaceholder() {
if (!this.textValue) {
this.placeholderVisible = true;
}
},
getlist() {
// checked
this.$u.get("/appVerify/fault/allList?dictType=et_fault_type").then((res) => {
if (res.code == 200) {
this.cbgz = res.data.headstock.map(item => ({
...item,
checked: false
}));
this.csgz = res.data.body.map(item => ({
...item,
checked: false
}));
this.tsgz = res.data.special.map(item => ({
...item,
checked: false
}));
} else {
uni.showToast({
title: '未登录,请登录后尝试',
icon: 'none',
duration: 2000
});
}
});
},
}
}
</script>
<style lang="scss">
page {
background-color: #F7FAFE;
}
.page {
padding-bottom: 100rpx;
// width: 750rpx;
width: 750rpx;
// height: 530rpx;
// background: linear-gradient( 180deg, #64B6A7 0%, rgba(255,255,255,0) 100%), #FFFFFF;
border-radius: 0rpx 0rpx 0rpx 0rpx;
padding-bottom: 200rpx;
.tip_box {
padding: 44rpx 36rpx;
font-weight: 400;
font-size: 32rpx;
color: #FFFFFF;
background: #64B6A7;
}
.vadio_png1 {
position: relative;
width: 672rpx;
height: 370rpx;
.backimg {
width: 672rpx;
height: 370rpx;
}
.tip_img {
position: absolute;
top: 72rpx;
left: 210rpx;
width: 252rpx;
height: 194rpx;
z-index: 11;
}
.vad {
width: 672rpx;
height: 370rpx;
border-radius: 40rpx;
z-index: 1;
}
.glass {
position: absolute;
top: 0;
left: 0;
width: 672rpx;
height: 370rpx;
background: rgba(255, 255, 255, 0.2);
border-radius: 40rpx;
// box-shadow: 0 rgba(0, 0, 0, 0.1);
backdrop-filter: blur(10rpx);
-webkit-backdrop-filter: blur(10rpx);
/* For Safari */
// border: 1rpx solid rgba(255, 255, 255, 0.3);
z-index: 10;
}
}
.cont {
width: 100%;
padding: 0 39rpx;
.tip_txt {
margin-top: 38rpx;
width: 100%;
font-weight: 400;
font-size: 28rpx;
color: #3D3D3D;
}
.vadio_png {
margin-top: 52rpx;
image {
width: 672rpx;
height: 370rpx;
}
}
.btn {
position: fixed;
bottom: 100rpx;
left: 38rpx;
// margin-top: 128rpx;
display: flex;
align-items: center;
justify-content: center;
width: 680rpx;
height: 90rpx;
background: rgba(100, 182, 167, 0.5);
border-radius: 54rpx 54rpx 54rpx 54rpx;
z-index: 10;
font-weight: 500;
font-size: 40rpx;
color: #FFFFFF;
}
.act1 {
background: #64B6A7;
}
}
.maskloadpage {
position: fixed;
padding: 46rpx;
bottom: 0;
width: 752rpx;
height: 780rpx;
background: #FFFFFF;
border-radius: 40rpx 40rpx 0rpx 0rpx;
z-index: 101;
box-shadow: 0rpx 0rpx 8rpx 0rpx rgba(0, 0, 0, 0.15);
.maskpage0 {
.top_info {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
image {
margin-right: 16rpx;
width: 50rpx;
height: 50rpx;
}
.masktxt {
font-weight: 500;
font-size: 44rpx;
color: #3D3D3D;
}
}
.masktips {
margin-top: 20rpx;
width: 100%;
text-align: center;
font-weight: 400;
font-size: 32rpx;
color: #3D3D3D;
}
.tipsimg {
margin-top: 60rpx;
display: flex;
// align-items: center;
justify-content: center;
width: 100%;
image {
width: 554rpx;
height: 262rpx;
}
}
}
.maskpage1 {
.top_info {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
image {
margin-right: 16rpx;
width: 50rpx;
height: 50rpx;
}
.masktxt {
font-weight: 500;
font-size: 44rpx;
color: #3D3D3D;
}
}
.masktips {
margin-top: 20rpx;
width: 100%;
text-align: center;
font-weight: 400;
font-size: 32rpx;
color: #3D3D3D;
}
.tipsimg {
margin-top: 60rpx;
display: flex;
// align-items: center;
justify-content: center;
width: 100%;
image {
width: 554rpx;
height: 262rpx;
}
}
.btn_box {
width: 750rpx;
padding: 0 36rpx;
position: absolute;
bottom: 60rpx;
left: 0;
display: flex;
justify-content: space-between;
align-items: center;
.btn3 {
// margin-right: 16rpx;
display: flex;
align-items: center;
justify-content: center;
width: 300rpx;
height: 90rpx;
background: #4C97E7;
border-radius: 45rpx 45rpx 45rpx 45rpx;
font-weight: 500;
font-size: 40rpx;
color: #FFFFFF;
}
.btn4 {
display: flex;
align-items: center;
justify-content: center;
width: 300rpx;
height: 90rpx;
border-radius: 45rpx 45rpx 45rpx 45rpx;
border: 2rpx solid #808080;
font-weight: 500;
font-size: 40rpx;
color: #808080;
}
}
}
}
.btns {
position: fixed;
bottom: 70rpx;
left: 34rpx;
display: flex;
align-items: center;
justify-content: center;
font-weight: 500;
font-size: 40rpx;
color: #FFFFFF;
width: 680rpx;
height: 90rpx;
background: #64B6A7;
border-radius: 54rpx 54rpx 54rpx 54rpx;
z-index: 100;
}
.iptbox {
display: flex;
align-items: center;
flex-wrap: nowrap;
padding: 22rpx;
margin: 28rpx auto 0;
width: 680rpx;
height: 88rpx;
background: #FFFFFF;
box-shadow: 0rpx 0rpx 8rpx 0rpx rgba(0, 0, 0, 0.15);
border-radius: 20rpx 20rpx 20rpx 20rpx;
.qrcode {
padding-right: 20rpx;
border-right: 2rpx solid #D8D8D8;
image {
width: 54rpx;
height: 54rpx;
}
}
.ips {
width: 630rpx;
}
image {
width: 18rpx;
height: 32rpx;
}
.my-placeholder {
font-weight: 400;
font-size: 32rpx;
color: #808080;
}
}
.conts_box {
width: 680rpx;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
margin-top: 38rpx;
background: #FFFFFF;
box-shadow: 0rpx 10rpx 64rpx 0rpx rgba(0, 0, 0, 0.08);
border-radius: 20rpx 20rpx 20rpx 20rpx;
padding-bottom: 20rpx;
.txtss {
margin-top: 18rpx;
padding-left: 20rpx;
width: 100%;
font-weight: 500;
font-size: 28rpx;
color: #808080;
}
.cont_li {
width: 100%;
display: flex;
flex-wrap: nowrap;
align-items: center;
justify-content: space-between;
.left {
padding-left: 20rpx;
display: flex;
flex-wrap: wrap;
font-weight: 600;
font-size: 36rpx;
color: #3D3D3D;
.km {
font-weight: 400;
font-size: 28rpx;
color: #3D3D3D;
}
.speed {
margin-top: 18rpx;
width: 226rpx;
height: 22rpx;
background: #ccc;
border-radius: 16rpx 16rpx 16rpx 16rpx;
.speeds {
// width: 90%;
height: 100%;
background: #64B6A7;
border-radius: 16rpx 16rpx 16rpx 16rpx;
}
}
.NO {
width: 100%;
font-weight: 400;
font-size: 24rpx;
color: #3D3D3D;
}
}
.right {
padding-right: 20rpx;
font-weight: 600;
font-size: 36rpx;
color: #3D3D3D;
image {
width: 244rpx;
height: 196rpx;
}
}
}
}
.tits {
width: 680rpx;
margin: 0 auto;
font-weight: 400;
margin-top: 38rpx;
font-size: 36rpx;
color: #3D3D3D;
}
.cont_box {
margin: 0 auto;
padding: 24rpx 32rpx;
width: 680rpx;
margin-top: 38rpx;
background: #FFFFFF;
box-shadow: 0rpx 10rpx 64rpx 0rpx rgba(0, 0, 0, 0.08);
border-radius: 20rpx 20rpx 20rpx 20rpx;
.tit {
width: 100%;
display: flex;
flex-wrap: nowrap;
align-items: center;
image {
margin-right: 12rpx;
width: 24rpx;
height: 24rpx;
}
}
.choose_li {
margin-top: 34rpx;
width: 100%;
display: flex;
flex-wrap: nowrap;
align-items: center;
// justify-content: space-between;
.li_cont {
width: 50%;
display: flex;
flex-wrap: nowrap;
.img_box {
margin-right: 30rpx;
width: 38rpx;
height: 38rpx;
border-radius: 50%;
border: 2rpx solid #3D3D3D;
}
}
}
.tip {
display: flex;
flex-wrap: nowrap;
// align-items: center;
font-weight: 700;
font-size: 32rpx;
color: #3D3D3D;
line-height: 44rpx;
.ipnt {
margin-top: 10rpx;
margin-right: 12rpx;
color: #FF4444;
font-size: 48rpx;
}
}
.iptbox {
display: flex;
align-items: center;
margin-top: 30rpx;
width: 592rpx;
height: 80rpx;
border-radius: 20rpx 20rpx 20rpx 20rpx;
border: 2rpx solid #979797;
.ips {
margin-left: 30rpx;
width: 80%;
}
.iptbtn {
display: flex;
align-items: center;
justify-content: center;
width: 112rpx;
height: 80rpx;
background: #64B6A7;
border-radius: 20rpx 20rpx 20rpx 20rpx;
image {
width: 37rpx;
height: 37rpx;
}
}
}
.txt {
margin-top: 18rpx;
font-weight: 400;
font-size: 28rpx;
color: #3D3D3D;
}
.icon {
display: flex;
flex-wrap: wrap;
align-items: center;
margin-top: 40rpx;
.imgbox {
width: 33%;
image {
width: 142rpx;
height: 142rpx;
}
}
}
.checkbox {
display: flex;
flex-wrap: wrap;
.check_li {
position: relative;
margin-right: 10rpx;
margin-top: 18rpx;
display: flex;
align-items: center;
justify-content: center;
width: 142rpx;
height: 65rpx;
border-radius: 20rpx 20rpx 20rpx 20rpx;
border: 2rpx solid #C7C7C7;
image {
position: absolute;
right: 0;
bottom: 0;
width: 40rpx;
height: 20rpx;
}
}
.check_li:nth-child(4n) {
margin-right: 0;
}
.act1 {
// background-image: url(https://api.ccttiot.com/smartmeter/img/static/uaqN5qdoGNCs7Dumzr3F);
width: 142rpx;
height: 65rpx;
// background-size: cover;
border: 2rpx solid #1E807A;
// background: #4C97E7;
}
}
.input-container {
position: relative;
width: 612rpx;
height: 248rpx;
background: #FFFFFF;
box-shadow: 0rpx 16rpx 40rpx 0rpx rgba(42, 130, 228, 0.1);
border-radius: 20rpx;
margin-top: 40rpx;
overflow: hidden;
padding-right: 38rpx;
box-sizing: border-box;
border: 2rpx solid #C7C7C7;
}
.placeholder {
position: absolute;
top: 18rpx;
left: 38rpx;
color: #999;
/* placeholder颜色 */
pointer-events: none;
/* 确保点击事件可以穿透到textarea上 */
}
.custom-textarea {
width: 100%;
height: 100%;
/* 设置一个合适高度 */
padding-top: 18rpx;
/* 为placeholder留出空间 */
padding-left: 38rpx;
box-sizing: border-box;
border: 1px solid #ccc;
}
.word-count {
position: absolute;
right: 10px;
bottom: 10px;
font-size: 12px;
color: #999;
}
}
}
</style>