diff --git a/pages_store/Operator/device_set.vue b/pages_store/Operator/device_set.vue
index 2f195a3..9bb1273 100644
--- a/pages_store/Operator/device_set.vue
+++ b/pages_store/Operator/device_set.vue
@@ -5,48 +5,59 @@
-
分享二维码,邀请朋友使用车辆
-
- 保存
-
-
+ 保存
+
-
- 车辆编号
-
+ 车辆编号
+ {{ deviceInfos.sn }}
+
+
+ 备注
- {{ deviceInfos.sn }}
+ {{ deviceInfos.remark || '未设置' }}
+
+
+
+ 满电电压
+
+ {{ deviceInfos.fullVoltage || '未设置' }} V
+
+
+
+ 亏电电压
+
+ {{ deviceInfos.lowVoltage || '未设置' }} V
+
+
+
+ 满电续航
+
+ {{ deviceInfos.fullEndurance || '未设置' }} KM
-
- 车辆型号
-
+ 车辆型号
- {{ deviceInfos.model }}
+ {{ deviceInfos.model || '未设置' }}
-
-
- 车牌号
-
+
+ 车牌号
- {{ deviceInfos.vehicleNum }}
+ {{ deviceInfos.vehicleNum || '未设置' }}
-
- 车辆解绑
-
+ 车辆解绑
@@ -56,14 +67,14 @@
- 车牌号
- {{currentEditTitle}}
+
@@ -81,13 +92,15 @@ export default {
},
sn: '',
deviceInfos: {},
- qrSize: 220, // 338rpx 转换为 px (338/2)
+ qrSize: 220,
logoUrl: 'https://lxnapi.ccttiot.com/bike/img/static/u3giTY4VkWYpnGWRuFHF',
- tempFilePath: '', // 保存生成的二维码临时文件路径
+ tempFilePath: '',
showadd: false,
list: [],
showPlateModal: false,
- tempPlateNumber: '', // 临时存储修改的车牌号
+ currentEditField: '', // 当前编辑的字段
+ currentEditTitle: '', // 当前编辑项的标题
+ tempValue: '', // 临时存储修改的值
}
},
onLoad(e) {
@@ -98,246 +111,312 @@ export default {
this.getModelList();
},
methods: {
- confirm(e) {
+ confirm(e) {
+ this.showadd = false;
+ this.putDeviceModel(e[0].value);
+ },
- this.showadd = false
- this.putDeviceModel(e[0].value)
+ // 打开编辑弹窗
+ openPlateModal(field, title) {
+ this.currentEditField = field;
+ this.currentEditTitle = title;
+ this.tempValue = this.deviceInfos[field] || '';
+ this.showPlateModal = true;
+
+ // 根据字段类型设置输入框类型
+ const numericFields = ['fullVoltage', 'lowVoltage', 'fullEndurance'];
+ if (numericFields.includes(field)) {
+ // 找到输入框并设置为数字类型
+ // this.$nextTick(() => {
+ // const input = document.querySelector('.plate-input');
+ // if (input) {
+ // input.type = 'number';
+ // input.step = '0.1'; // 允许输入小数
+ // }
+ // });
+ }
+ },
- },
- // 打开车牌号修改弹窗
- openPlateModal() {
- this.tempPlateNumber = this.deviceInfos.vehicleNum; // 初始化为当前车牌号
- this.showPlateModal = true;
- },
+ // 关闭弹窗
+ closePlateModal() {
+ this.showPlateModal = false;
+ // 重新生成二维码
+ this.generateQRCode();
+ },
- // 关闭弹窗
- 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);
+ // 确认编辑
+ confirmEdit() {
+ if (!this.tempValue) {
+ uni.showToast({
+ title: '请输入' + this.currentEditTitle,
+ icon: 'none'
+ });
+ return;
+ }
- // 先清空画布并填充白色背景
- context.setFillStyle('#ffffff');
- context.fillRect(0, 0, this.qrSize, this.qrSize);
- context.draw(true);
+ // 数字类型字段的验证
+ const numericFields = ['fullVoltage', 'lowVoltage', 'fullEndurance'];
+ if (numericFields.includes(this.currentEditField)) {
+ const value = parseFloat(this.tempValue);
+
+ // 验证是否为有效数字
+ if (isNaN(value)) {
+ uni.showToast({
+ title: '请输入有效的数字',
+ icon: 'none'
+ });
+ return;
+ }
- // 创建二维码实例
- const qr = new UQRCode();
- qr.data = qrUrl;
- qr.size = this.qrSize;
- qr.margin = 10;
- qr.backgroundColor = '#ffffff';
- qr.foregroundColor = '#000000';
- qr.canvasContext = context;
+ // 验证范围
+ switch (this.currentEditField) {
+ case 'fullVoltage':
+ case 'lowVoltage':
+ if (value < 0 || value > 100) {
+ uni.showToast({
+ title: '电压值应在0-100之间',
+ icon: 'none'
+ });
+ return;
+ }
+ break;
+ case 'fullEndurance':
+ if (value < 0 || value > 1000) {
+ uni.showToast({
+ title: '续航里程应在0-1000之间',
+ icon: 'none'
+ });
+ return;
+ }
+ break;
+ }
- // 生成二维码
- qr.make();
- qr.drawCanvas();
+ // 转换为数字类型
+ this.tempValue = value;
+ }
- // 加载并绘制logo
- const logoSize = this.qrSize / 4; // logo大小为二维码的1/4
- const logoX = (this.qrSize - logoSize) / 2;
- const logoY = (this.qrSize - logoSize) / 2;
+ this.updateDeviceField();
+ this.closePlateModal();
+ },
- 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);
- }
- });
+ // 统一的设备字段更新方法
+ updateDeviceField() {
+ const params = {
+ sn: this.sn,
+ [this.currentEditField]: this.tempValue
+ };
- } 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);
- }
- },
+ // 对数字类型字段进行特殊处理
+ const numericFields = ['fullVoltage', 'lowVoltage', 'fullEndurance'];
+ if (numericFields.includes(this.currentEditField)) {
+ params[this.currentEditField] = parseFloat(this.tempValue);
+ }
+
+ this.$u.put('/appVerify/device/edit', params).then((res) => {
+ if (res.code === 200) {
+ this.deviceInfo();
+ uni.showToast({
+ title: '修改成功',
+ icon: 'success'
+ });
+ } else {
+ uni.showToast({
+ title: res.msg,
+ icon: 'none',
+ duration: 2000
+ });
+ }
+ });
+ },
+
+ unBind() {
+ this.$u.post('/appVerify/untie/' + this.deviceInfos.deviceId).then((res) => {
+ if (res.code === 200) {
+ uni.redirectTo({
+ url: '/pages_store/merchant'
+ });
+ } else {
+ uni.showToast({
+ title: res.msg,
+ icon: 'none',
+ duration: 2000
+ });
+ }
+ })
+ },
+
+ putDeviceModel(modelId) {
+ const params = {
+ sn: this.sn,
+ modelId: modelId
+ };
+
+ this.$u.put('/appVerify/device/edit', params).then((res) => {
+ if (res.code === 200) {
+ this.deviceInfo();
+ } else {
+ uni.showToast({
+ title: res.msg,
+ icon: 'none',
+ duration: 2000
+ });
+ }
+ })
+ },
+
+ changeModel() {
+ this.showadd = true;
+ },
+
+ deviceInfo() {
+ this.$u.get('app/getDeviceBySn?sn=' + this.sn).then((res) => {
+ 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) => {
+ 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();
+
+ const logoSize = this.qrSize / 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);
+ 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参数
+ path: `/pages/index/index?sn=${this.sn}`
}
},
-
- // 修改分享到朋友圈的配置
onShareTimeline() {
return {
title: '设备分享',
imageUrl: 'https://lxnapi.ccttiot.com/bike/img/static/uNRujJOme6J0bIxiN1TF',
- query: `sn=${this.sn}` // 这里的参数会自动拼接到pages/index/index后面
+ query: `sn=${this.sn}`
}
}
}
@@ -348,17 +427,13 @@ 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 {
+ padding-bottom: 100rpx;
.mask {
position: fixed;
top: 0;
@@ -366,7 +441,7 @@ page {
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
- z-index: 999;
+ z-index: 100;
}
.plate-modal {
@@ -378,95 +453,121 @@ page {
background: #FFFFFF;
border-radius: 24rpx;
z-index: 1000;
+ box-shadow: 0 4rpx 24rpx rgba(0, 0, 0, 0.1);
+ animation: modalFadeIn 0.3s ease-out;
.modal-title {
display: flex;
flex-direction: column;
align-items: center;
- padding: 40rpx 0;
+ padding: 48rpx 0 32rpx;
+ border-bottom: 2rpx solid #F5F5F5;
.logo {
- width: 80rpx;
- height: 80rpx;
+ width: 88rpx;
+ height: 88rpx;
border-radius: 50%;
- margin-bottom: 20rpx;
+ margin-bottom: 24rpx;
+ box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
}
text {
- font-size: 32rpx;
- font-weight: 500;
- color: #333;
- }
+ font-size: 36rpx;
+ font-weight: 600;
+ color: #333333;
+ line-height: 1.4;
- .sub-title {
- font-size: 24rpx;
- color: #999;
- margin-top: 8rpx;
+ &.sub-title {
+ margin-top: 8rpx;
+ font-size: 24rpx;
+ color: #999999;
+ font-weight: 400;
+ letter-spacing: 2rpx;
+ }
}
}
.modal-content {
- padding: 0 40rpx;
+ padding: 32rpx 40rpx;
.label {
+ display: block;
font-size: 28rpx;
- color: #333;
- margin-bottom: 20rpx;
+ color: #333333;
+ margin-bottom: 16rpx;
+ font-weight: 500;
}
.plate-input {
width: 100%;
- height: 80rpx;
- border: 2rpx dashed #CCCCCC;
- border-radius: 8rpx;
- padding: 0 20rpx;
+ height: 88rpx;
+ background: #F8F8F8;
+ border-radius: 12rpx;
+ padding: 0 24rpx;
+ font-size: 30rpx;
+ color: #333333;
+ box-sizing: border-box;
+ border: 2rpx solid #EEEEEE;
+ transition: all 0.3s ease;
+
+ &:focus {
+ border-color: #4297F3;
+ background: #FFFFFF;
+ }
+ }
+
+ .input-placeholder {
+ color: #999999;
font-size: 28rpx;
- margin-bottom: 40rpx;
}
}
.modal-footer {
display: flex;
- border-top: 2rpx solid #EEEEEE;
+ height: 100rpx;
+ border-top: 2rpx solid #F5F5F5;
.btn {
flex: 1;
- height: 100rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
+ font-weight: 500;
+ transition: all 0.3s ease;
&.cancel {
- color: #999;
- border-right: 2rpx solid #EEEEEE;
+ color: #666666;
+ background: #FFFFFF;
+ border-radius: 0 0 0 24rpx;
+
+ &:active {
+ background: #F5F5F5;
+ }
}
&.confirm {
- color: #4297F3;
+ color: #FFFFFF;
+ background: #4297F3;
+ border-radius: 0 0 24rpx 0;
+
+ &:active {
+ background: darken(#4297F3, 5%);
+ }
}
}
}
}
- .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;
+ @keyframes modalFadeIn {
+ from {
+ opacity: 0;
+ transform: translate(-50%, -48%);
+ }
+ to {
+ opacity: 1;
+ transform: translate(-50%, -50%);
+ }
}
.device_info {
@@ -477,44 +578,35 @@ page {
padding-bottom: 24rpx;
background: #FFFFFF;
box-shadow: 0rpx 2rpx 18rpx 0rpx rgba(0, 0, 0, 0.1);
- border-radius: 20rpx 20rpx 20rpx 20rpx;
+ border-radius: 20rpx;
.device_info_item {
margin-bottom: 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
+ padding: 24rpx 0;
+ transition: all 0.3s ease;
+ border-bottom: 2rpx dashed #dddddd;
+ &:active {
+ background: #F8F8F8;
+ }
.device_info_item_title {
- font-weight: 400;
font-size: 28rpx;
- color: #6F6F6F;
+ color: #666666;
}
.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颜色
- }
+ color: #333333;
.iconfont {
- margin-left: 10rpx; // 图标和输入框之间的间距
+ margin-left: 8rpx;
+ color: #999999;
+ font-size: 24rpx;
}
}
}
@@ -540,26 +632,23 @@ page {
justify-content: center;
align-items: center;
padding: 40rpx;
- z-index: 1;
canvas {
- background: #ffffff;
+ background: #FFFFFF;
padding: 20rpx;
border-radius: 16rpx;
- box-shadow: 0 0 10rpx rgba(0, 0, 0, 0.1);
+ box-shadow: 0 4rpx 24rpx rgba(0, 0, 0, 0.1);
}
}
.tips {
position: absolute;
- width: 660rpx;
+ width: 100%;
text-align: center;
top: 678rpx;
- left: 0;
- right: 0;
- font-weight: 700;
+ font-weight: 600;
font-size: 32rpx;
- color: #3D3D3D;
+ color: #333333;
}
.btn_box {
@@ -581,7 +670,12 @@ page {
border: 2rpx solid #808080;
font-weight: 500;
font-size: 32rpx;
- color: #3D3D3D;
+ color: #333333;
+ transition: all 0.3s ease;
+
+ &:active {
+ background: #F5F5F5;
+ }
}
.btn1 {
@@ -598,6 +692,11 @@ page {
padding: 0;
margin: 0;
line-height: 82rpx;
+ transition: all 0.3s ease;
+
+ &:active {
+ background: darken(#4297F3, 5%);
+ }
&::after {
border: none;
@@ -605,5 +704,27 @@ page {
}
}
}
+
+ .unBind {
+ margin: 0 auto;
+ margin-top: 90rpx;
+ margin-bottom: 40rpx;
+ 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;
+ font-weight: 500;
+ font-size: 40rpx;
+ color: #FFFFFF;
+ transition: all 0.3s ease;
+
+ &:active {
+ background: darken(#3D3D3D, 5%);
+ }
+ }
}
\ No newline at end of file