609 lines
13 KiB
Vue
609 lines
13 KiB
Vue
|
<template>
|
|||
|
<view class="page">
|
|||
|
<u-navbar title="车辆设置" :border-bottom="false" :background="background" title-color='#000' title-size='36'
|
|||
|
height='45' back-icon-color='#000'></u-navbar>
|
|||
|
|
|||
|
<view class="share_box">
|
|||
|
<view class="qrcode-container">
|
|||
|
<canvas style="width: 338rpx; height: 338rpx; background-color: #fff;" canvas-id="qrcode" id="qrcode">
|
|||
|
</canvas>
|
|||
|
</view>
|
|||
|
<view class="tips">分享二维码,邀请朋友使用车辆</view>
|
|||
|
<view class="btn_box">
|
|||
|
<view class="btn" @click="saveQRCode">
|
|||
|
保存
|
|||
|
</view>
|
|||
|
<button class="btn1" open-type="share" @click="shareQRCode">
|
|||
|
分享
|
|||
|
</button>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view class="device_info">
|
|||
|
<view class="device_info_item">
|
|||
|
<view class="device_info_item_title">
|
|||
|
车辆编号
|
|||
|
</view>
|
|||
|
<view class="device_info_item_value">
|
|||
|
{{ deviceInfos.sn }}
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view class="device_info_item" @click="changeModel()">
|
|||
|
<view class="device_info_item_title">
|
|||
|
车辆型号
|
|||
|
</view>
|
|||
|
<view class="device_info_item_value">
|
|||
|
{{ deviceInfos.model }} <view class="iconfont icon-xiangyou1"></view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view class="device_info_item" @click="openPlateModal()">
|
|||
|
<view class="device_info_item_title">
|
|||
|
车牌号
|
|||
|
</view>
|
|||
|
<view class="device_info_item_value">
|
|||
|
{{ deviceInfos.vehicleNum }} <view class="iconfont icon-xiangyou1"></view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view class="unBind" @click="unBind">
|
|||
|
车辆解绑
|
|||
|
</view>
|
|||
|
<view class="mask" v-if="showPlateModal" @click="closePlateModal"></view>
|
|||
|
<view class="plate-modal" v-if="showPlateModal">
|
|||
|
<view class="modal-title">
|
|||
|
<image :src="logoUrl" mode="aspectFit" class="logo"></image>
|
|||
|
<text>小鹿出行</text>
|
|||
|
<text class="sub-title">XIAOLIUCHUXING</text>
|
|||
|
</view>
|
|||
|
|
|||
|
<view class="modal-content">
|
|||
|
<text class="label">车牌号</text>
|
|||
|
<input v-model="tempPlateNumber" placeholder="请输入车牌号" placeholder-class="input-placeholder"
|
|||
|
class="plate-input" />
|
|||
|
</view>
|
|||
|
|
|||
|
<view class="modal-footer">
|
|||
|
<view class="btn cancel" @click="closePlateModal">取消</view>
|
|||
|
<view class="btn confirm" @click="confirmPlateNumber">确认</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<u-select v-model="showadd" :list="list" title='选择添加方式' @confirm="confirm"></u-select>
|
|||
|
</view>
|
|||
|
</template>
|
|||
|
|
|||
|
<script>
|
|||
|
import UQRCode from '@/uni_modules/Sansnn-uQRCode/js_sdk/uqrcode/uqrcode.js'
|
|||
|
|
|||
|
export default {
|
|||
|
data() {
|
|||
|
return {
|
|||
|
background: {
|
|||
|
backgroundColor: " ",
|
|||
|
},
|
|||
|
sn: '',
|
|||
|
deviceInfos: {},
|
|||
|
qrSize: 220, // 338rpx 转换为 px (338/2)
|
|||
|
logoUrl: 'https://lxnapi.ccttiot.com/bike/img/static/u3giTY4VkWYpnGWRuFHF',
|
|||
|
tempFilePath: '', // 保存生成的二维码临时文件路径
|
|||
|
showadd: false,
|
|||
|
list: [],
|
|||
|
showPlateModal: false,
|
|||
|
tempPlateNumber: '', // 临时存储修改的车牌号
|
|||
|
}
|
|||
|
},
|
|||
|
onLoad(e) {
|
|||
|
console.log(e.sn);
|
|||
|
this.sn = e.sn;
|
|||
|
this.deviceInfo();
|
|||
|
this.generateQRCode();
|
|||
|
this.getModelList();
|
|||
|
},
|
|||
|
methods: {
|
|||
|
confirm(e) {
|
|||
|
|
|||
|
this.showadd = false
|
|||
|
this.putDeviceModel(e[0].value)
|
|||
|
|
|||
|
},
|
|||
|
// 打开车牌号修改弹窗
|
|||
|
openPlateModal() {
|
|||
|
this.tempPlateNumber = this.deviceInfos.vehicleNum; // 初始化为当前车牌号
|
|||
|
this.showPlateModal = true;
|
|||
|
},
|
|||
|
|
|||
|
// 关闭弹窗
|
|||
|
closePlateModal() {
|
|||
|
this.showPlateModal = false;
|
|||
|
// this.tempPlateNumber = '';
|
|||
|
},
|
|||
|
unBind() {
|
|||
|
this.$u.post('/appVerify/untie/' + this.deviceInfos.deviceId).then((res) => {
|
|||
|
console.log(res, 'rererer');
|
|||
|
if (res.code === 200) {
|
|||
|
uni.redirectTo({
|
|||
|
url: '/pages_store/merchant'
|
|||
|
});
|
|||
|
} else {
|
|||
|
uni.showToast({
|
|||
|
title: res.msg,
|
|||
|
icon: 'none',
|
|||
|
duration: 2000
|
|||
|
});
|
|||
|
}
|
|||
|
})
|
|||
|
},
|
|||
|
// 确认修改
|
|||
|
confirmPlateNumber() {
|
|||
|
if (!this.tempPlateNumber) {
|
|||
|
uni.showToast({
|
|||
|
title: '请输入车牌号',
|
|||
|
icon: 'none'
|
|||
|
});
|
|||
|
return;
|
|||
|
}
|
|||
|
this.putDeviceVehicleNum();
|
|||
|
this.closePlateModal();
|
|||
|
|
|||
|
},
|
|||
|
putDeviceVehicleNum() {
|
|||
|
this.$u.put('/appVerify/device/editVehicleNum?sn=' + this.sn + '&vehicleNum=' + this.tempPlateNumber).then((res) => {
|
|||
|
console.log(res, 'rererer');
|
|||
|
if (res.code === 200) {
|
|||
|
this.deviceInfo();
|
|||
|
} else {
|
|||
|
uni.showToast({
|
|||
|
title: res.msg,
|
|||
|
icon: 'none',
|
|||
|
duration: 2000
|
|||
|
});
|
|||
|
}
|
|||
|
})
|
|||
|
},
|
|||
|
putDeviceModel(modelId) {
|
|||
|
this.$u.put('/appVerify/device/editModel?sn=' + this.sn + '&modelId=' + modelId).then((res) => {
|
|||
|
console.log(res, 'rererer');
|
|||
|
if (res.code === 200) {
|
|||
|
this.deviceInfo();
|
|||
|
} else {
|
|||
|
uni.showToast({
|
|||
|
title: res.msg,
|
|||
|
icon: 'none',
|
|||
|
duration: 2000
|
|||
|
});
|
|||
|
}
|
|||
|
})
|
|||
|
},
|
|||
|
changeModel() {
|
|||
|
this.showadd = true;
|
|||
|
},
|
|||
|
changeVehicleNum() {
|
|||
|
uni.navigateTo({
|
|||
|
url: '/pages_store/Operator/change_vehicle_num'
|
|||
|
})
|
|||
|
},
|
|||
|
deviceInfo() {
|
|||
|
this.$u.get('app/getDeviceBySn?sn=' + this.sn).then((res) => {
|
|||
|
console.log(res, 'rererer');
|
|||
|
if (res.code === 200) {
|
|||
|
this.deviceInfos = res.data
|
|||
|
} else {
|
|||
|
uni.showToast({
|
|||
|
title: res.msg,
|
|||
|
icon: 'none',
|
|||
|
duration: 2000
|
|||
|
});
|
|||
|
}
|
|||
|
})
|
|||
|
},
|
|||
|
getModelList() {
|
|||
|
this.$u.get('/appVerify/model/getModelByToken').then((res) => {
|
|||
|
console.log(res, 'rererer');
|
|||
|
if (res.code === 200) {
|
|||
|
// 转换数据格式
|
|||
|
this.list = res.data.map(item => ({
|
|||
|
label: item.model, // 显示的文本
|
|||
|
value: item.modelId // 实际的值
|
|||
|
}));
|
|||
|
} else {
|
|||
|
uni.showToast({
|
|||
|
title: res.msg,
|
|||
|
icon: 'none',
|
|||
|
duration: 2000
|
|||
|
});
|
|||
|
}
|
|||
|
})
|
|||
|
},
|
|||
|
generateQRCode() {
|
|||
|
try {
|
|||
|
const qrUrl = `https://testlu.chuangtewl.com?sn=${this.sn}`;
|
|||
|
const context = uni.createCanvasContext('qrcode', this);
|
|||
|
|
|||
|
// 先清空画布并填充白色背景
|
|||
|
context.setFillStyle('#ffffff');
|
|||
|
context.fillRect(0, 0, this.qrSize, this.qrSize);
|
|||
|
context.draw(true);
|
|||
|
|
|||
|
// 创建二维码实例
|
|||
|
const qr = new UQRCode();
|
|||
|
qr.data = qrUrl;
|
|||
|
qr.size = this.qrSize;
|
|||
|
qr.margin = 10;
|
|||
|
qr.backgroundColor = '#ffffff';
|
|||
|
qr.foregroundColor = '#000000';
|
|||
|
qr.canvasContext = context;
|
|||
|
|
|||
|
// 生成二维码
|
|||
|
qr.make();
|
|||
|
qr.drawCanvas();
|
|||
|
|
|||
|
// 加载并绘制logo
|
|||
|
const logoSize = this.qrSize / 4; // logo大小为二维码的1/4
|
|||
|
const logoX = (this.qrSize - logoSize) / 2;
|
|||
|
const logoY = (this.qrSize - logoSize) / 2;
|
|||
|
|
|||
|
uni.getImageInfo({
|
|||
|
src: this.logoUrl,
|
|||
|
success: (res) => {
|
|||
|
// 绘制白色背景
|
|||
|
context.setFillStyle('#ffffff');
|
|||
|
context.fillRect(logoX - 2, logoY - 2, logoSize + 4, logoSize + 4);
|
|||
|
// 绘制logo
|
|||
|
context.drawImage(res.path, logoX, logoY, logoSize, logoSize);
|
|||
|
context.draw(true);
|
|||
|
},
|
|||
|
fail: (err) => {
|
|||
|
console.error('Logo加载失败:', err);
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
} catch (error) {
|
|||
|
console.error('生成二维码失败:', error);
|
|||
|
uni.showToast({
|
|||
|
title: '生成二维码失败',
|
|||
|
icon: 'none'
|
|||
|
});
|
|||
|
}
|
|||
|
},
|
|||
|
// 保存二维码到相册
|
|||
|
saveQRCode() {
|
|||
|
uni.canvasToTempFilePath({
|
|||
|
canvasId: 'qrcode',
|
|||
|
success: (res) => {
|
|||
|
this.tempFilePath = res.tempFilePath;
|
|||
|
uni.saveImageToPhotosAlbum({
|
|||
|
filePath: res.tempFilePath,
|
|||
|
success: () => {
|
|||
|
uni.showToast({
|
|||
|
title: '保存成功',
|
|||
|
icon: 'success'
|
|||
|
});
|
|||
|
},
|
|||
|
fail: (err) => {
|
|||
|
if (err.errMsg.indexOf('auth deny') !== -1) {
|
|||
|
uni.showModal({
|
|||
|
title: '提示',
|
|||
|
content: '需要您授权保存到相册',
|
|||
|
success: (res) => {
|
|||
|
if (res.confirm) {
|
|||
|
uni.openSetting();
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
} else {
|
|||
|
uni.showToast({
|
|||
|
title: '保存失败',
|
|||
|
icon: 'none'
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
},
|
|||
|
fail: (err) => {
|
|||
|
console.error('转换失败:', err);
|
|||
|
uni.showToast({
|
|||
|
title: '保存失败',
|
|||
|
icon: 'none'
|
|||
|
});
|
|||
|
}
|
|||
|
}, this);
|
|||
|
},
|
|||
|
// 分享二维码
|
|||
|
shareQRCode() {
|
|||
|
uni.canvasToTempFilePath({
|
|||
|
canvasId: 'qrcode',
|
|||
|
success: (res) => {
|
|||
|
this.tempFilePath = res.tempFilePath;
|
|||
|
console.log('二维码图片已生成:', this.tempFilePath);
|
|||
|
},
|
|||
|
fail: (err) => {
|
|||
|
console.error('生成分享图片失败:', err);
|
|||
|
uni.showToast({
|
|||
|
title: '分享失败',
|
|||
|
icon: 'none'
|
|||
|
});
|
|||
|
}
|
|||
|
}, this);
|
|||
|
}
|
|||
|
},
|
|||
|
onShareAppMessage() {
|
|||
|
return {
|
|||
|
title: '设备分享',
|
|||
|
imageUrl: 'https://lxnapi.ccttiot.com/bike/img/static/uNRujJOme6J0bIxiN1TF',
|
|||
|
path: `/pages/index/index?sn=${this.sn}` // 修改为首页并传递sn参数
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
// 修改分享到朋友圈的配置
|
|||
|
onShareTimeline() {
|
|||
|
return {
|
|||
|
title: '设备分享',
|
|||
|
imageUrl: 'https://lxnapi.ccttiot.com/bike/img/static/uNRujJOme6J0bIxiN1TF',
|
|||
|
query: `sn=${this.sn}` // 这里的参数会自动拼接到pages/index/index后面
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
</script>
|
|||
|
|
|||
|
<style lang="scss">
|
|||
|
page {
|
|||
|
overflow-y: auto;
|
|||
|
background-image: url('https://lxnapi.ccttiot.com/bike/img/static/uYRs7Cv2Pbp95w3KjGO3');
|
|||
|
background-size: cover;
|
|||
|
/* 背景图片等比缩放以覆盖整个容器 */
|
|||
|
background-position: center;
|
|||
|
/* 背景图片居中显示 */
|
|||
|
background-repeat: no-repeat;
|
|||
|
/* 防止背景图片重复 */
|
|||
|
min-height: 100vh;
|
|||
|
/* 确保页面至少有 100% 的视窗高度,避免高度不足导致无法滚动 */
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
.page {
|
|||
|
.mask {
|
|||
|
position: fixed;
|
|||
|
top: 0;
|
|||
|
left: 0;
|
|||
|
right: 0;
|
|||
|
bottom: 0;
|
|||
|
background: rgba(0, 0, 0, 0.6);
|
|||
|
z-index: 999;
|
|||
|
}
|
|||
|
|
|||
|
.plate-modal {
|
|||
|
position: fixed;
|
|||
|
top: 50%;
|
|||
|
left: 50%;
|
|||
|
transform: translate(-50%, -50%);
|
|||
|
width: 600rpx;
|
|||
|
background: #FFFFFF;
|
|||
|
border-radius: 24rpx;
|
|||
|
z-index: 1000;
|
|||
|
|
|||
|
.modal-title {
|
|||
|
display: flex;
|
|||
|
flex-direction: column;
|
|||
|
align-items: center;
|
|||
|
padding: 40rpx 0;
|
|||
|
|
|||
|
.logo {
|
|||
|
width: 80rpx;
|
|||
|
height: 80rpx;
|
|||
|
border-radius: 50%;
|
|||
|
margin-bottom: 20rpx;
|
|||
|
}
|
|||
|
|
|||
|
text {
|
|||
|
font-size: 32rpx;
|
|||
|
font-weight: 500;
|
|||
|
color: #333;
|
|||
|
}
|
|||
|
|
|||
|
.sub-title {
|
|||
|
font-size: 24rpx;
|
|||
|
color: #999;
|
|||
|
margin-top: 8rpx;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.modal-content {
|
|||
|
padding: 0 40rpx;
|
|||
|
|
|||
|
.label {
|
|||
|
font-size: 28rpx;
|
|||
|
color: #333;
|
|||
|
margin-bottom: 20rpx;
|
|||
|
}
|
|||
|
|
|||
|
.plate-input {
|
|||
|
width: 100%;
|
|||
|
height: 80rpx;
|
|||
|
border: 2rpx dashed #CCCCCC;
|
|||
|
border-radius: 8rpx;
|
|||
|
padding: 0 20rpx;
|
|||
|
font-size: 28rpx;
|
|||
|
margin-bottom: 40rpx;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.modal-footer {
|
|||
|
display: flex;
|
|||
|
border-top: 2rpx solid #EEEEEE;
|
|||
|
|
|||
|
.btn {
|
|||
|
flex: 1;
|
|||
|
height: 100rpx;
|
|||
|
display: flex;
|
|||
|
align-items: center;
|
|||
|
justify-content: center;
|
|||
|
font-size: 32rpx;
|
|||
|
|
|||
|
&.cancel {
|
|||
|
color: #999;
|
|||
|
border-right: 2rpx solid #EEEEEE;
|
|||
|
}
|
|||
|
|
|||
|
&.confirm {
|
|||
|
color: #4297F3;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.input-placeholder {
|
|||
|
color: #999999;
|
|||
|
}
|
|||
|
|
|||
|
.unBind {
|
|||
|
margin: 0 auto;
|
|||
|
margin-top: 90rpx;
|
|||
|
display: flex;
|
|||
|
justify-content: center;
|
|||
|
align-items: center;
|
|||
|
width: 660rpx;
|
|||
|
height: 92rpx;
|
|||
|
background: #3D3D3D;
|
|||
|
box-shadow: 0rpx 2rpx 18rpx 0rpx rgba(0, 0, 0, 0.1);
|
|||
|
border-radius: 16rpx 16rpx 16rpx 16rpx;
|
|||
|
font-weight: 500;
|
|||
|
font-size: 40rpx;
|
|||
|
color: #FFFFFF;
|
|||
|
}
|
|||
|
|
|||
|
.device_info {
|
|||
|
margin: 0 auto;
|
|||
|
margin-top: 30rpx;
|
|||
|
width: 660rpx;
|
|||
|
padding: 42rpx 46rpx;
|
|||
|
padding-bottom: 24rpx;
|
|||
|
background: #FFFFFF;
|
|||
|
box-shadow: 0rpx 2rpx 18rpx 0rpx rgba(0, 0, 0, 0.1);
|
|||
|
border-radius: 20rpx 20rpx 20rpx 20rpx;
|
|||
|
|
|||
|
.device_info_item {
|
|||
|
margin-bottom: 20rpx;
|
|||
|
display: flex;
|
|||
|
justify-content: space-between;
|
|||
|
align-items: center;
|
|||
|
|
|||
|
.device_info_item_title {
|
|||
|
font-weight: 400;
|
|||
|
font-size: 28rpx;
|
|||
|
color: #6F6F6F;
|
|||
|
}
|
|||
|
|
|||
|
.device_info_item_value {
|
|||
|
display: flex;
|
|||
|
flex-direction: row;
|
|||
|
align-items: center;
|
|||
|
font-weight: 400;
|
|||
|
font-size: 28rpx;
|
|||
|
color: #3D3D3D;
|
|||
|
|
|||
|
input {
|
|||
|
flex: 1; // 让输入框占据剩余空间
|
|||
|
margin-left: auto;
|
|||
|
height: 40rpx;
|
|||
|
border: none;
|
|||
|
text-align: right; // 文本右对齐
|
|||
|
padding-right: 20rpx; // 右侧添加一些padding,避免文字贴边
|
|||
|
}
|
|||
|
|
|||
|
.input-placeholder {
|
|||
|
text-align: right; // placeholder也右对齐
|
|||
|
color: #999; // placeholder颜色
|
|||
|
}
|
|||
|
|
|||
|
.iconfont {
|
|||
|
margin-left: 10rpx; // 图标和输入框之间的间距
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.share_box {
|
|||
|
position: relative;
|
|||
|
margin: 0 auto;
|
|||
|
margin-top: 50rpx;
|
|||
|
width: 688rpx;
|
|||
|
height: 898rpx;
|
|||
|
background-image: url('https://lxnapi.ccttiot.com/bike/img/static/uvVY5qF63XMV7jqCVlP7');
|
|||
|
background-size: cover;
|
|||
|
background-position: center;
|
|||
|
background-repeat: no-repeat;
|
|||
|
|
|||
|
.qrcode-container {
|
|||
|
position: absolute;
|
|||
|
top: 246rpx;
|
|||
|
left: 0;
|
|||
|
right: 0;
|
|||
|
display: flex;
|
|||
|
justify-content: center;
|
|||
|
align-items: center;
|
|||
|
padding: 40rpx;
|
|||
|
z-index: 1;
|
|||
|
|
|||
|
canvas {
|
|||
|
background: #ffffff;
|
|||
|
padding: 20rpx;
|
|||
|
border-radius: 16rpx;
|
|||
|
box-shadow: 0 0 10rpx rgba(0, 0, 0, 0.1);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.tips {
|
|||
|
position: absolute;
|
|||
|
width: 660rpx;
|
|||
|
text-align: center;
|
|||
|
top: 678rpx;
|
|||
|
left: 0;
|
|||
|
right: 0;
|
|||
|
font-weight: 700;
|
|||
|
font-size: 32rpx;
|
|||
|
color: #3D3D3D;
|
|||
|
}
|
|||
|
|
|||
|
.btn_box {
|
|||
|
position: absolute;
|
|||
|
bottom: 60rpx;
|
|||
|
left: 0;
|
|||
|
right: 0;
|
|||
|
display: flex;
|
|||
|
justify-content: space-around;
|
|||
|
padding: 0 66rpx;
|
|||
|
|
|||
|
.btn {
|
|||
|
display: flex;
|
|||
|
justify-content: center;
|
|||
|
align-items: center;
|
|||
|
width: 254rpx;
|
|||
|
height: 82rpx;
|
|||
|
border-radius: 12rpx;
|
|||
|
border: 2rpx solid #808080;
|
|||
|
font-weight: 500;
|
|||
|
font-size: 32rpx;
|
|||
|
color: #3D3D3D;
|
|||
|
}
|
|||
|
|
|||
|
.btn1 {
|
|||
|
display: flex;
|
|||
|
justify-content: center;
|
|||
|
align-items: center;
|
|||
|
width: 254rpx;
|
|||
|
height: 82rpx;
|
|||
|
background: #4297F3;
|
|||
|
border-radius: 12rpx;
|
|||
|
font-weight: 500;
|
|||
|
font-size: 32rpx;
|
|||
|
color: #FFFFFF;
|
|||
|
padding: 0;
|
|||
|
margin: 0;
|
|||
|
line-height: 82rpx;
|
|||
|
|
|||
|
&::after {
|
|||
|
border: none;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
</style>
|