chuangte_bike_newxcx/page_user/huanbike.vue
2025-04-11 18:23:16 +08:00

996 lines
20 KiB
Vue
Raw 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="tits">
<image src="https://lxnapi.ccttiot.com/bike/img/static/uByIrgaV23PDGZWReKHW" mode=""></image>
点击扫码或输入想换的车辆编号
</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="bikesn" placeholder="请扫描设备上的二维码" style="margin-left: 32rpx;"
placeholder-class="my-placeholder" />
</view>
<view class="conts_box">
<view class="cont_li">
<view class="left">
<view class="km">
可继续行驶{{orderobj.deviceRemainEndurance == null ? '--' : orderobj.deviceRemainEndurance}}公里
</view>
<view class="speed">
<view class="speeds" :style="{ width: orderobj.deviceRemainingPower + '%' }"></view>
</view>
<view class="NO">
SN{{orderobj.deviceSn}}
</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: 600;">
已骑行
</view>
<view class="right" style="font-size: 32rpx;font-weight: 600;">
{{timeRemaining}}
</view>
</view>
<view class="cont_li" style="margin-top: 10rpx;">
<view class="left" style="font-size: 32rpx;font-weight: 600;">
预估金额
</view>
<view class="right" style="font-size: 32rpx;font-weight: 600;">
{{feiyong}}元
</view>
</view>
<view class="txtss">
扫码开锁后将自动合并订单,骑行时间将继续计时
</view>
</view>
<view class="cont_box">
<view class="tit">
<image src="https://lxnapi.ccttiot.com/bike/img/static/uByIrgaV23PDGZWReKHW" mode=""></image>
请选择换车原因
</view>
<view class="choose_li">
<view class="li_cont" @click="checkIdx = 1">
<view class="img_box">
<image src="https://api.ccttiot.com/smartmeter/img/static/uGWN8B6dfaSc7ACKxb7r" mode=""
v-if="checkIdx == 1"></image>
</view>
电量不足
</view>
<view class="li_cont" @click="checkIdx = 2">
<view class="img_box">
<image src="https://api.ccttiot.com/smartmeter/img/static/uGWN8B6dfaSc7ACKxb7r" mode=""
v-if="checkIdx == 2"></image>
</view>
车辆损坏
</view>
</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>
<view class="input-container">
<view class="placeholder" v-if="!textValue">请输入故障原因</view>
<textarea class="custom-textarea" v-model="textValue" style="border: none;"></textarea>
</view>
</view>
<view class="cont_box" v-show="checkIdx == 2 || orderobj.orderAreaReturnVerify == true">
<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> -->
<view class="vadio_png1">
<image @click="recordVideo" class="backimg" src="https://api.ccttiot.com/smartmeter/img/static/uTwV4aH6HbxqmM1ssvTs" mode="" v-if="videoUrl==''"></image>
<video class="vad" :src="videoUrl" controls="controls" style="width: 100%;" v-if="videoUrl!=''"></video>
</view>
<view class="tip_txt" style="font-weight: 500;font-size: 32rpx;color: #3D3D3D;margin-top: 30rpx;">
保持车辆录像的完整清晰,不要随意拍摄确保视频中车辆出境并且出现车牌号
</view>
</view>
<view class="btns" @click="subs()">
提交
</view>
</view>
</template>
<script>
export default {
data() {
return {
bgc: {
backgroundColor: "#fff",
},
textValue: '',
currentCount: 0,
imglist: [],
token: '',
upurl: '',
checkIdx: 1,
videoUrl: '',
ordersn:'',
orderid:'',
bikesn:'',
orderobj:{},
feiyong:'',
timeRemaining: "",
latitude:'',
longitude:'',
videoPath:'',
}
},
onLoad(e) {
console.log(e);
this.ordersn = e.sn
this.orderid = e.orderid
this.getQiniuToken()
this.getdingdan()
this.getfeiyong()
},
onShow() {
uni.getLocation({
type: 'wgs84',
success: (res) => {
this.latitude = res.latitude
this.longitude = res.longitude
},
fail: (err) => {
console.error('获取位置失败:', err)
}
})
},
computed: {
},
methods: {
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 = 'https://api.ccttiot.com/' + str.key
// console.log(_this.userImgs)
// _this.imglist.push(_this.userImgs)
}
});
},
// 点击进行换车
subs(){
uni.showLoading({
title: '换车中...'
})
let reason = ''
let faultPicture = ''
if(this.checkIdx == 1){
reason = 'LOW_POWER'
}else{
reason = 'DEVICE_FAULT'
}
// if(this.imglist.length > 0){
// faultPicture = this.imglist.join(',')
// }
let data = {
orderId:this.orderid,
deviceSn:this.bikesn,
reason:reason,
faultDetail:this.textValue,
faultPicture:this.videoUrl,
lat:this.latitude,
lon:this.longitude
}
this.$u.put(`/app/order/changeDevice`,data).then(res =>{
if(res.code == 200){
uni.hideLoading()
uni.showToast({
title: '换车成功',
icon: 'success',
duration: 1000
})
setTimeout(()=>{
uni.navigateBack()
},1000)
}else{
uni.hideLoading()
uni.showToast({
title: res.msg,
icon: 'none',
duration: 1000
})
}
})
},
// 获取当前进行中订单 startTime
getdingdan(){
this.$u.get(`/app/orderDevice/mineUsing`).then(res =>{
if(res.code == 200){
if(res.data){
this.orderobj = res.data
if(res.data.startTime){
this.timeRemaining = this.calculateTimeRemaining()
}
}
}
})
},
calculateTimeRemaining() {
const targetDate = new Date(this.orderobj.startTime)
const now = new Date()
const diffMs = now - targetDate
const diffHours = Math.floor(diffMs / (1000 * 60 * 60))
const diffMinutes = Math.floor((diffMs % (1000 * 60 * 60)) / (1000 * 60))
return `${diffHours} 小时 ${diffMinutes} 分钟`
},
// 计算订单费用
getfeiyong(){
let data = {
orderId:this.orderid
}
this.$u.post(`/app/order/calcFee`,data).then(res =>{
if(res.code == 200){
this.feiyong = res.data.ridingFee
}
})
},
getQiniuToken() {
this.$u.get("/common/qiniuToken").then((res) => {
if (res.code == 200) {
this.token = res.data
}
})
},
btn() {
let _this = this
let math = 'static/' + _this.$u.guid(20)
uni.chooseImage({
count: 9,
type: 'all',
success(res) {
const tempFilePaths = res.tempFiles
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) {
let str = JSON.parse(res.data)
_this.userImgs = 'https://api.ccttiot.com/' + str.key
_this.imglist.push(_this.userImgs)
}
})
}
})
},
qrcode() {
uni.scanCode({
onlyFromCamera: true,
scanType: ['qrCode'],
success: res => {
console.log(res);
function getQueryParam(url, paramName) {
let regex = new RegExp(`[?&]${paramName}=([^&]*)`)
let results = regex.exec(url)
return results ? decodeURIComponent(results[1].replace(/\+/g, ' ')) : null
}
let sceneValue = res.result
let decodedValue = decodeURIComponent(sceneValue)
this.bikesn = getQueryParam(decodedValue, 's')
},
fail: err => {
console.error('扫描失败:', err)
uni.showToast({
title: '扫描失败',
icon: 'none'
})
}
})
},
}
}
</script>
<style lang="scss">
page {
background-color: #F7FAFE;
}
.page {
padding-bottom: 100rpx;
// width: 750rpx;
width: 750rpx;
// height: 530rpx;
// background: linear-gradient( 180deg, #4297F3 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: #4297F3;
}
.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: #4297F3;
}
}
.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: #4297F3;
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: #4297F3;
border-radius: 16rpx 16rpx 16rpx 16rpx;
}
}
.NO {
width: 100%;
font-weight: 400;
font-size: 24rpx;
color: #3D3D3D;
margin-top: 18rpx;
}
}
.right {
padding-right: 20rpx;
font-weight: 600;
font-size: 36rpx;
color: #3D3D3D;
image {
width: 244rpx;
height: 196rpx;
}
}
}
}
.tits {
width: 680rpx;
margin: 0 auto;
margin-top: 38rpx;
font-size: 36rpx;
color: #3D3D3D;
display: flex;
flex-wrap: nowrap;
align-items: center;
image {
margin-right: 12rpx;
width: 24rpx;
height: 24rpx;
}
}
.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;
.vadio_png1{
position: relative;
width: 100%;
height: 340rpx;
margin-top: 30rpx;
.backimg{
width: 100%;
height: 340rpx;
}
.tip_img{
position: absolute;
top: 72rpx;
left: 210rpx;
width: 252rpx;
height: 194rpx;
z-index: 11;
}
.vad{
width: 100%;
height: 370rpx;
border-radius: 40rpx;
z-index: 1;
}
.glass{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 340rpx;
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;
}
}
.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: #4297F3;
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>