83 コミット f1743f3b4c ... 72ab8cfc9b

作者 SHA1 メッセージ 日付
  xxq 72ab8cfc9b 0402_xxq 1 週間 前
  郭宇琦 62e34298cc bug修复 1 週間 前
  郭宇琦 0af3bf0ca6 Merge branch 'lw_test' into gyq_test 1 週間 前
  郭宇琦 72546f9554 Merge branch 'gyq_test' of http://git.bms16.com/liuwei/zx_flk_app into gyq_test 1 週間 前
  郭宇琦 a27cbb47c7 bug修改 1 週間 前
  liuwei 9b7b9d1373 首页 1 週間 前
  xiongyi 09a712f6d9 1 1 週間 前
  郭宇琦 b3360776bc Merge branch 'gyq_test' of http://git.bms16.com/liuwei/zx_flk_app into gyq_test 1 週間 前
  郭宇琦 05e56f2da9 bug修改 1 週間 前
  xiongyi f3f85ab054 Merge branch 'gyq_test' of http://git.bms16.com/liuwei/zx_flk_app into gyq_test 1 週間 前
  xiongyi 255a39b092 提交代码 1 週間 前
  郭宇琦 1727797c17 全局修改图片的mode 1 週間 前
  郭宇琦 fe1d7de570 bug修改 1 週間 前
  郭宇琦 bd1492bff9 Merge branch 'lw_test' into gyq_test 1 週間 前
  郭宇琦 7ca61315b7 Merge branch 'gyq_test' of http://git.bms16.com/liuwei/zx_flk_app into gyq_test 1 週間 前
  郭宇琦 e41e3d4012 bug修改 1 週間 前
  liuwei abdbbd4022 首页 1 週間 前
  liuwei f9fd73aed2 首页 1 週間 前
  liuwei 498c6d8cd5 0401 1 週間 前
  xiongyi 382121d92a 提交代码 1 週間 前
  郭宇琦 c941b4bf79 地图优化 1 週間 前
  郭宇琦 e32bb4b050 Merge branch 'lw_test' into gyq_test 1 週間 前
  郭宇琦 6d216bf862 bug修改 1 週間 前
  liuwei e5ce4d3698 蓝牙test 1 週間 前
  郭宇琦 60d10fc4fa Merge branch 'lw_test' into gyq_test 1 週間 前
  liuwei 11f594de30 首页 1 週間 前
  郭宇琦 beb50631fb Merge branch 'gyq_test' of http://git.bms16.com/liuwei/zx_flk_app into gyq_test 1 週間 前
  郭宇琦 437410e4fc bug修改 1 週間 前
  xiongyi 94d4a91371 提交代码 1 週間 前
  郭宇琦 644e374c86 bug修复 1 週間 前
  xiongyi 271a9c855a 去掉多余文件 1 週間 前
  xiongyi 6a7f9197a4 适配详情Img标签变形问题 1 週間 前
  xiongyi f4352e4a83 提交代码 1 週間 前
  郭宇琦 343dd7805a bug修改 1 週間 前
  郭宇琦 5efa032a1f Merge branch 'lw_test' into gyq_test 1 週間 前
  郭宇琦 07c62e289f Merge branch 'gyq_test' of http://git.bms16.com/liuwei/zx_flk_app into gyq_test 1 週間 前
  郭宇琦 17d3990200 bug修复 1 週間 前
  liuwei b5a67da94a 系统消息 1 週間 前
  liuwei 1eafb47074 3_31_BUG_蓝牙去除登录写 1 週間 前
  xiongyi 28c0dfa765 修改bug 1 週間 前
  xiongyi 8104c27806 注册去ctime 1 週間 前
  xiongyi a530ceff17 修改bug 1 週間 前
  xiongyi 208d5839a9 提交消息详情,修改bug 1 週間 前
  郭宇琦 9467f88006 bug修复 1 週間 前
  郭宇琦 0b86379aa6 Merge branch 'lw_test' into gyq_test 1 週間 前
  郭宇琦 363c821b1a Merge branch 'gyq_test' of http://git.bms16.com/liuwei/zx_flk_app into gyq_test 1 週間 前
  郭宇琦 589e0092c1 bug修复 1 週間 前
  liuwei 329afde896 开机传参数 1 週間 前
  xiongyi b8fb641cb7 修改Bug 1 週間 前
  郭宇琦 3f8ff8e471 bug修复 1 週間 前
  郭宇琦 06887ef2bb Merge branch 'lw_test' into gyq_test 1 週間 前
  郭宇琦 b56fcd0368 bug修复 1 週間 前
  liuwei b44e6c4dc8 蓝牙 1 週間 前
  郭宇琦 f7b80d2f8d Merge branch 'gyq_test' of http://git.bms16.com/liuwei/zx_flk_app into gyq_test 1 週間 前
  郭宇琦 3cbcdb29c4 bug修复 1 週間 前
  liuwei 3640056e40 蓝牙调试 1 週間 前
  xiongyi b2ae8f4db6 提交代码 1 週間 前
  郭宇琦 ad23529020 Merge branch 'gyq_test' of http://git.bms16.com/liuwei/zx_flk_app into gyq_test 1 週間 前
  郭宇琦 4b2d9239ac bug修改 1 週間 前
  xiongyi eedc7358d2 修改Bug. 1 週間 前
  郭宇琦 e99ae8955c Merge branch 'lw_test' into gyq_test 1 週間 前
  郭宇琦 2a54f2b90d bug修复 1 週間 前
  liuwei 86c9afef85 蓝牙调整 1 週間 前
  liuwei 1abf39b355 首页 1 週間 前
  郭宇琦 ed63f7fc85 Merge branch 'lw_test' into gyq_test 1 週間 前
  郭宇琦 e209ecd840 bug修复 1 週間 前
  郭宇琦 d15c006ff2 bug修复 1 週間 前
  郭宇琦 4630d6b0c8 bug修复 1 週間 前
  liuwei c0e556c565 订单列表头部样式 1 週間 前
  郭宇琦 c112196afe bug修改 1 週間 前
  郭宇琦 0e25c262e8 bug修复 1 週間 前
  郭宇琦 1717a7ee19 全局定位问题处理 1 週間 前
  郭宇琦 4d35d7fd0a bug修复 1 週間 前
  郭宇琦 c8c0cb0169 bug 1 週間 前
  郭宇琦 1d7f4b4dc7 bug修复 1 週間 前
  郭宇琦 c83a2c82f0 bug修改 1 週間 前
  郭宇琦 59c7c3d6ab Merge branch 'lw_test' into gyq_test 1 週間 前
  郭宇琦 5ac4588a27 bug 1 週間 前
  郭宇琦 cd813de76e bug修改 1 週間 前
  liuwei 1cf929a9a9 蓝牙 1 週間 前
  郭宇琦 029059039d 首页没有数据处理方案 1 週間 前
  郭宇琦 545c9ce9dd Merge branch 'lw_test' into gyq_test 1 週間 前
  郭宇琦 70e37caa2f 扫码换电bug 1 週間 前
90 ファイル変更4266 行追加1584 行削除
  1. 1 1
      .hbuilderx/launch.json
  2. 96 38
      common/bluetooth.js
  3. 700 0
      common/bluetooth/ZXCar - 副本.js
  4. 81 69
      common/bluetooth/ZXCar.js
  5. 48 11
      common/common.js
  6. 1 1
      common/config.js
  7. 2 1
      common/config_gyq.js
  8. 5 2
      common/http.js
  9. 16 15
      common/storage.js
  10. 2 1
      component/allPrice/allPrice.css
  11. 1 1
      component/allPrice/allPrice.vue
  12. 6 2
      component/carPlan/carPlan.css
  13. 6 2
      component/carPlan/carPlan.vue
  14. 5 3
      component/comPopup/Notice.vue
  15. 196 0
      component/customSwitch.vue
  16. 7 2
      component/customTabbar/index.vue
  17. 14 11
      component/googleMap/googleMap.vue
  18. 58 0
      component/googleMap/googleMaps.vue
  19. 11 3
      component/returnCar/returnCar.vue
  20. 4 5
      component/scanBtn/scanBtn.vue
  21. 4 0
      component/scanCabBtn/scanBtn.css
  22. 30 26
      component/scanCabBtn/scanBtn.vue
  23. 6 6
      component/uploader/uploader.css
  24. 3 4
      component/uploaders/uploaders.vue
  25. 152 0
      components/navBar/navigation.vue
  26. 185 0
      components/toggle-switch/toggle-switch.vue
  27. 16 16
      js_sdk/wa-permission/permission.js
  28. 1 1
      locale/zh.json
  29. 4 0
      main.js
  30. 16 11
      manifest.json
  31. 95 106
      mixin/index.js
  32. 1 0
      package.json
  33. 1 1
      pages.json
  34. 1 1
      pages/aboutMy/aboutMy.vue
  35. 0 1
      pages/activation/activation.css
  36. 163 23
      pages/activation/activation.vue
  37. 22 29
      pages/batteryDetail/batteryDetail.vue
  38. 2 1
      pages/batteryPackage/batteryPackage.css
  39. 12 7
      pages/batteryPackage/batteryPackage.vue
  40. 22 10
      pages/batteryRecord/batteryRecord.vue
  41. 64 82
      pages/bluetoothUnlock/bluetoothPair.vue
  42. 5 3
      pages/bluetoothUnlock/unlockSet.vue
  43. 163 115
      pages/cabinetDetail/cabinetDetail.vue
  44. 17 10
      pages/carDetail/carDetail.vue
  45. 8 2
      pages/carFunctionSet/more.vue
  46. 53 47
      pages/carFunctionSet/unbind.vue
  47. 14 9
      pages/carList/carList.vue
  48. 29 29
      pages/carLocation/carLocation.vue
  49. 3 1
      pages/contract/contract.vue
  50. 58 14
      pages/dashboard/dashboard.vue
  51. 1 1
      pages/deviceInfo/deviceInfo.vue
  52. 1 1
      pages/index/components/AndroidUnlockAuth.vue
  53. 53 1
      pages/index/components/control/control.css
  54. 232 4
      pages/index/components/control/control.vue
  55. 4 4
      pages/index/components/mapCard/mapCard.vue
  56. 9 2
      pages/index/components/unleasedPages/unleasedPages.vue
  57. 24 4
      pages/index/index.css
  58. 115 80
      pages/index/index.vue
  59. 1 1
      pages/login/login.vue
  60. 2 2
      pages/loginRegister/changePassword.vue
  61. 1 1
      pages/loginRegister/forgetPassword.vue
  62. 10 10
      pages/loginRegister/login.vue
  63. 1 1
      pages/loginRegister/register.vue
  64. 83 0
      pages/message/carLocation.css
  65. 84 0
      pages/message/detail.vue
  66. 0 120
      pages/message/deviceInfo.vue
  67. 344 233
      pages/message/index.vue
  68. 219 0
      pages/message/location.vue
  69. 11 6
      pages/my/my.vue
  70. 31 15
      pages/my/set.vue
  71. 6 1
      pages/openCabinet/openCabinet.css
  72. 13 11
      pages/openCabinet/openCabinet.vue
  73. 1 1
      pages/order/order.css
  74. 48 25
      pages/order/order.vue
  75. 37 2
      pages/orderStatus/orderStatus.css
  76. 164 71
      pages/orderStatus/orderStatus.vue
  77. 4 10
      pages/package/package.css
  78. 45 67
      pages/package/package.vue
  79. 1 1
      pages/phoneLogin/phoneLogin.vue
  80. 2 2
      pages/powerSetting/powerSetting.vue
  81. 7 1
      pages/purchaseOrder/purchaseOrder.vue
  82. 2 1
      pages/service/components/carRentalList/carRentalList.css
  83. 61 32
      pages/service/components/carRentalList/carRentalList.vue
  84. 54 19
      pages/service/components/leaseType/leaseType.vue
  85. 127 76
      pages/service/service.vue
  86. 6 0
      pages/storeDetails/storeDetails.css
  87. 20 20
      pages/storeDetails/storeDetails.vue
  88. 1 1
      pages/travelingTrack/travelingTrack.css
  89. 25 34
      pages/travelingTrack/travelingTrack.vue
  90. 6 0
      utils/gyq_utils.js

+ 1 - 1
.hbuilderx/launch.json

@@ -25,7 +25,7 @@
         },
         {
             "openVueDevtools" : false,
-            "playground" : "standard",
+            "playground" : "custom",
             "type" : "uni-app:app-ios"
         }
     ]

+ 96 - 38
common/bluetooth.js

@@ -4,7 +4,7 @@ import SystemInfoUtil from './SystemInfoUtil.js';
 // 蓝牙对应的权限名称
 // 蓝牙权限对应的中文名称
 
-const app = getApp();
+// var app = null;
 const bluetoothDevices = {
     ZX16D: require('./bluetooth/ZX16D.js'),
     FMBMS: require('./bluetooth/FMBMS.js'),
@@ -18,14 +18,16 @@ const bluetoothDevices = {
     AD3BTS: require('./bluetooth/AD3BTS.js'),
     BWJT: require('./bluetooth/ZXBT_JL.js'),
     JTBMS: require('./bluetooth/ZXBT_JL.js'),
-	ZXCAR: require('./bluetooth/ZXCar.js')
+	ZXZK: require('./bluetooth/ZXCar.js') //flk中控
+	// ZXCAR: require('./bluetooth/ZXCar.js') //flk中控
 };
 //初始化蓝牙
 function initBluetooth() {
 	console.log('initBluetooth');
+	const app = getApp();
     //监听蓝牙适配器状态变化事件
     uni.onBluetoothAdapterStateChange((res) => {
-        console.log(res,'onBluetoothAdapterStateChange');
+        console.log(app,res,'onBluetoothAdapterStateChange');
         Object.keys(app.globalData.adapterStateChangeFunc).forEach((n) => app.globalData.adapterStateChangeFunc[n](res));
     });
     //监听低功耗蓝牙连接状态的改变事件。包括开发者主动连接或断开连接,设备丢失,连接异常断开等等
@@ -45,27 +47,30 @@ function initBluetooth() {
 	// uni.onBLEMTUChange((res) => {
 	//   console.log("MTU 变更:", res.mtu); // 实际生效的 MTU 大小
 	// });
-	console.log("监听值")
+	console.log(app,"监听值")
     //监听低功耗蓝牙设备的特征值变化事件。必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification
     uni.onBLECharacteristicValueChange((res) => {
 		console.log(res,'restest1111');
-        if (app.globalData.connectionState[res.deviceId]) {
-            const device = app.globalData.connectionState[res.deviceId].device;
+		const car_sn=uni.getStorageSync('car_info').car_sn;
+        if (app.globalData.connectionState[car_sn]) {
+            const device = app.globalData.connectionState[car_sn].device;
 			console.log(res.serviceId.toUpperCase() == bluetoothDeviceConfig(device).readServiceID.toUpperCase(),'00000');
 			if (
                 res.serviceId.toUpperCase() == bluetoothDeviceConfig(device).readServiceID.toUpperCase() &&
                 res.characteristicId.toUpperCase() == bluetoothDeviceConfig(device).readID.toUpperCase()
             ) {
-                var data = bluetoothDeviceConfig(device).readData(device, res.value, app.globalData.connectionState[res.deviceId].data);
-				// console.log(data,'data--------');
+				console.log(app.globalData.connectionState[car_sn],bluetoothDeviceConfig(device),'data--------');
+                var data = bluetoothDeviceConfig(device).readData(device, res.value, app.globalData.connectionState[car_sn].data);
+				
 				if (data) {
-                    app.globalData.connectionState[res.deviceId].data = data;
+					const app = getApp();
+                    app.globalData.connectionState[car_sn].data = data;
                     if (app.globalData.characteristicStateChangeFunc[device.mac_id]) {
                         Object.keys(app.globalData.characteristicStateChangeFunc[device.mac_id]).forEach((p) =>
                             app.globalData.characteristicStateChangeFunc[device.mac_id][p](data)
                         );
-						// common.simpleToast(app.globalData.connectionState[res.deviceId].data)
-                        console.log(app.globalData.connectionState[res.deviceId].data);
+						// common.simpleToast(app.globalData.connectionState[car_sn].data)
+                        console.log(app.globalData.connectionState[car_sn].data);
                     }
                 }
             }
@@ -74,14 +79,17 @@ function initBluetooth() {
 }
 // 监听蓝牙适配器状态变化事件
 function onAdapterStateChange(name, callback) {
+	const app = getApp();
     app.globalData.adapterStateChangeFunc[name] = callback;
 }
 // 移除蓝牙适配器状态变化事件的监听
 function offAdapterStateChange(name) {
+	const app = getApp();
     delete app.globalData.adapterStateChangeFunc[name];
 }
 // 监听蓝牙设备连接状态变化事件
 function onConnectionStateChange(macid, name, callback) {
+	const app = getApp();
     if (!app.globalData.connectionStateChangeFunc[macid]) {
         app.globalData.connectionStateChangeFunc[macid] = {};
     }
@@ -89,12 +97,14 @@ function onConnectionStateChange(macid, name, callback) {
 }
 // 移除蓝牙设备连接状态变化事件的监听
 function offConnectionStateChange(macid, name) {
+	const app = getApp();
     if (app.globalData.connectionStateChangeFunc[macid]) {
         delete app.globalData.connectionStateChangeFunc[macid][name];
     }
 }
 // 监听蓝牙特征值状态变化事件
 function onCharacteristicStateChange(macid, name, callback) {
+	const app = getApp();
     if (!app.globalData.characteristicStateChangeFunc[macid]) {
         app.globalData.characteristicStateChangeFunc[macid] = {};
     }
@@ -102,6 +112,7 @@ function onCharacteristicStateChange(macid, name, callback) {
 }
 // 移除蓝牙特征值状态变化事件的监听
 function offCharacteristicStateChange(macid, name) {
+	const app = getApp();
     if (app.globalData.characteristicStateChangeFunc[macid]) {
         delete app.globalData.characteristicStateChangeFunc[macid][name];
     }
@@ -136,6 +147,7 @@ function openBluetoothAdapter(callback = () => {}, fail = () => {}) {
 function closeBluetoothAdapter(callback = () => {}, fail = () => {}) {
     uni.closeBluetoothAdapter({
         success: (res) => {
+			const app = getApp();
             app.globalData.adapterStateChangeFunc = {};
             app.globalData.connectionStateChangeFunc = {};
             app.globalData.characteristicStateChangeFunc = {};
@@ -189,6 +201,7 @@ function isVoltageToEle(device) {
 }
 // 根据macid判断是否是单蓝牙设备
 function isSginleBtByMacid(macid) {
+	const app = getApp();
     // 根据macid查找设备id
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
     // 打印全局连接状态
@@ -233,17 +246,22 @@ function findDevice(device, callback = () => {}, fail = () => {}) {
 						res.devices.forEach((data) => {
 							// console.log(data,'data***************');
 							// 判断设备是否为指定设备
+							console.log('------',bluetoothDeviceConfig(device).isDevice(device, data));
 							if (bluetoothDeviceConfig(device).isDevice(device, data)) {
+								const app = getApp();
 								// uni.offBluetoothDeviceFound();
 								uni.stopBluetoothDevicesDiscovery(); //查找到蓝牙设备停止搜索
-								deviceId = data.deviceId;
+								const car_info= uni.getStorageSync('car_info')
+								const deviceIds = data.deviceId;
+								console.log(deviceIds,'deviceIds123');
+								const deviceId = car_info.car_sn;
 								if (app.globalData.connectionState[deviceId]) {
 									app.globalData.connectionState[deviceId].device = device;
 								} else {
 									app.globalData.connectionState[deviceId] = {
 										device: device,
 										deviceName:data.name,
-										deviceId: deviceId,
+										deviceId: deviceIds,
 										connected: false,
 										data: {}
 									};
@@ -283,7 +301,11 @@ function findDevice(device, callback = () => {}, fail = () => {}) {
                         // uni.offBluetoothDeviceFound();
                         // 停止蓝牙设备搜索
                         uni.stopBluetoothDevicesDiscovery();
-                        deviceId = data.deviceId;
+						const car_info= uni.getStorageSync('car_info')
+                        const deviceIds = data.deviceId;
+						console.log(deviceIds,'deviceIds456');
+						const deviceId = car_info.car_sn;
+						const app = getApp();
                          // 检查全局状态中是否已经存在该设备
                         if (app.globalData.connectionState[deviceId]) {
                             app.globalData.connectionState[deviceId].device = device;
@@ -293,7 +315,7 @@ function findDevice(device, callback = () => {}, fail = () => {}) {
                             app.globalData.connectionState[deviceId] = {
                                 device: device,
 								deviceName:data.name,
-                                deviceId: deviceId,
+                                deviceId: deviceIds,
                                 connected: false,
                                 data: {}
                             };
@@ -321,6 +343,8 @@ function connectDevice(device, callback = () => {}, fail = () => {}) {
     if (!bluetoothDeviceConfig(device) || !bluetoothDeviceConfig(device).acceptDevice(device)) {
         return;
     }
+	const app = getApp();
+	console.log(app,'连接函数connectDevice deviceId111111');
     // 获取设备ID
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == device.mac_id);
 	console.log(deviceId,'连接函数connectDevice deviceId');
@@ -346,24 +370,28 @@ function connectDevice(device, callback = () => {}, fail = () => {}) {
             return;
         }
     }
-	const device_name=app.globalData.connectionState[deviceId].deviceName
+	const car_sn=uni.getStorageSync('car_info').car_sn
+	const deviceIds = app.globalData.connectionState[car_sn].deviceId
+	console.log(deviceIds,'deviceIds');
+	const device_name=app.globalData.connectionState[car_sn].deviceName
     // 创建蓝牙连接
     uni.createBLEConnection({
-        deviceId: deviceId,
+        deviceId: deviceIds,
         success: (res) => {
 			console.log(res,'蓝牙连接成功');
+			const app = getApp();
             // 更新连接状态
             app.globalData.connectionState[deviceId] = {
                 device: device,
 				deviceName: device_name,
-                deviceId: deviceId,
+                deviceId: deviceIds,
                 connected: true,
                 data: {}
             };
             // 调用连接成功回调
             alterConnect(
                 device,
-                deviceId,
+                deviceIds,
                 (res) => {
                     console.log('uni.createBLEConnection');
                     callback(res);
@@ -406,6 +434,12 @@ function alterConnect(device, deviceId, callback = () => {}, fail = () => {}) {
     }
 	console.log("xxxx2")
 	console.log(deviceId)
+	// var data = bluetoothDeviceConfig(device).alterConnect(device, deviceId);
+	//蓝牙不使用登录指令
+	// var data = bluetoothDeviceConfig(device).nearUnlock(device, deviceId);
+	// setTimeout(()=>{
+	// 	writeData(device, deviceId, data, callback, fail);
+	// },1000)
     // 获取蓝牙设备的服务列表
 	setTimeout(()=>{
     uni.getBLEDeviceServices({
@@ -443,15 +477,15 @@ function alterConnect(device, deviceId, callback = () => {}, fail = () => {}) {
                                             success: (res) => {
                                                 console.log('setBLEMTU success>>', res);
                                                 // 判断设备是否有alterConnect方法
-                                                if (bluetoothDeviceConfig(device).alterConnect) {
-                                                    var data = bluetoothDeviceConfig(device).alterConnect(device, deviceId);
+                                                if (bluetoothDeviceConfig(device).getNearUnlockSet) {
+                                                    var data = bluetoothDeviceConfig(device).getNearUnlockSet(device, deviceId);
 													console.log(data[0],'data111111');
                                                     // 判断alterConnect方法是否返回数据
                                                     if (data) {
                                                         // 写入数据
 														setTimeout(()=>{
 															writeData(device, deviceId, data, callback, fail);
-														},500)
+														},3000)
                                                         
                                                     } else {
                                                         // 调用回调函数
@@ -465,8 +499,8 @@ function alterConnect(device, deviceId, callback = () => {}, fail = () => {}) {
                                             fail: (res) => {
                                                 console.log('setBLEMTU fail>>', res);
                                                 // 判断设备是否有alterConnect方法
-                                                if (bluetoothDeviceConfig(device).alterConnect) {
-                                                    var data = bluetoothDeviceConfig(device).alterConnect(device, deviceId);
+                                                if (bluetoothDeviceConfig(device).getNearUnlockSet) {
+                                                    var data = bluetoothDeviceConfig(device).getNearUnlockSet(device, deviceId);
                                                     // 判断alterConnect方法是否返回数据
                                                     if (data) {
                                                         // 写入数据
@@ -483,8 +517,8 @@ function alterConnect(device, deviceId, callback = () => {}, fail = () => {}) {
                                         });
                                     } else {
                                         // 判断设备是否有alterConnect方法
-                                        if (bluetoothDeviceConfig(device).alterConnect) {
-                                            var data = bluetoothDeviceConfig(device).alterConnect(device, deviceId);
+                                        if (bluetoothDeviceConfig(device).getNearUnlockSet) {
+                                            var data = bluetoothDeviceConfig(device).getNearUnlockSet(device, deviceId);
                                             // 判断alterConnect方法是否返回数据
                                             if (data) {
                                                 // 写入数据
@@ -510,14 +544,14 @@ function alterConnect(device, deviceId, callback = () => {}, fail = () => {}) {
                             fail(res);
                         }
                     });
-                },
+				},
                 fail(res) {
 					console.log('getBLEDeviceServices fail',res);
                     // 调用失败回调函数
                     fail(res);
                 }
             });	
-			},800)
+			},500)
             
         },
         fail(res) {
@@ -530,7 +564,8 @@ function alterConnect(device, deviceId, callback = () => {}, fail = () => {}) {
 }
 // 关闭设备连接
 function closeDevice(macid, callback = () => {}, fail = () => {}) {
-    // 获取设备ID
+    const app=getApp()
+	// 获取设备ID
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
     // 如果设备ID不存在,则调用fail函数
     if (deviceId == undefined) {
@@ -550,6 +585,7 @@ function closeDevice(macid, callback = () => {}, fail = () => {}) {
         deviceId: deviceId,
         success: (res) => {
             console.log(res);
+			const app = getApp();
             // 如果设备连接状态存在,则将连接状态设置为false
             if (app.globalData.connectionState[deviceId]) {
                 app.globalData.connectionState[deviceId].connected = false;
@@ -608,7 +644,6 @@ function writeData(device, deviceId, data, callback = () => {}, fail = () => {})
     // buffer = common.toArrayBuffer(data.shift());
 	
     //buffer = common.toArrayBuffer(data.shift());
-	console.log()
 	var byteArray = data.shift()
 	const buffer = new ArrayBuffer(byteArray.length);
 	const dataView = new DataView(buffer);
@@ -621,7 +656,8 @@ function writeData(device, deviceId, data, callback = () => {}, fail = () => {})
 	// console.log(buffer,'buffer111');
     // 调用uni.writeBLECharacteristicValue方法,向蓝牙设备写入数据
 	// setTimeout(() => {
-    uni.writeBLECharacteristicValue({
+		plus.bluetooth.writeBLECharacteristicValue({
+    // uni.writeBLECharacteristicValue({
         deviceId: deviceId,
         serviceId: bluetoothDeviceConfig(device).writeServiceID,
         characteristicId: bluetoothDeviceConfig(device).writeID,
@@ -639,7 +675,7 @@ function writeData(device, deviceId, data, callback = () => {}, fail = () => {})
                 // // 否则,延时500毫秒后再次调用writeData函数
                 setTimeout(() => {
                     writeData(device, deviceId, data, callback, fail);
-                }, 50);
+                }, 150);
             }
         },
         // 失败回调函数
@@ -652,6 +688,7 @@ function writeData(device, deviceId, data, callback = () => {}, fail = () => {})
 	// }, 200);
 }
 function stateUpdate(macid, callback = () => {}, fail = () => {}) {
+	const app = getApp();
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
     if (deviceId == undefined) {
         fail();
@@ -671,6 +708,7 @@ function stateUpdate(macid, callback = () => {}, fail = () => {}) {
     return false;
 }
 function voltageToEle(macid, value, callback = () => {}, fail = () => {}) {
+	const app = getApp();
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
     if (deviceId == undefined) {
         fail();
@@ -690,6 +728,7 @@ function voltageToEle(macid, value, callback = () => {}, fail = () => {}) {
     return false;
 }
 function turnOn(macid, callback = () => {}, fail = () => {}) {
+	const app = getApp();
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
     if (deviceId == undefined) {
         fail();
@@ -709,6 +748,7 @@ function turnOn(macid, callback = () => {}, fail = () => {}) {
     return false;
 }
 function turnOnBuzzer(macid, callback = () => {}, fail = () => {}) {
+	const app = getApp();
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
     if (deviceId == undefined) {
         fail();
@@ -728,6 +768,7 @@ function turnOnBuzzer(macid, callback = () => {}, fail = () => {}) {
     return false;
 }
 function turnOffBuzzer(macid, callback = () => {}, fail = () => {}) {
+	const app = getApp();
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
     if (deviceId == undefined) {
         fail();
@@ -747,6 +788,7 @@ function turnOffBuzzer(macid, callback = () => {}, fail = () => {}) {
     return false;
 }
 function turnOff(macid, callback = () => {}, fail = () => {}) {
+	const app = getApp();
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
     if (deviceId == undefined) {
         fail();
@@ -766,6 +808,7 @@ function turnOff(macid, callback = () => {}, fail = () => {}) {
     return false;
 }
 function bmsChargingMOS(macid, value, callback = () => {}, fail = () => {}) {
+	const app = getApp();
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
     if (deviceId == undefined) {
         fail();
@@ -785,6 +828,7 @@ function bmsChargingMOS(macid, value, callback = () => {}, fail = () => {}) {
     return false;
 }
 function bmsDischargeMOS(macid, value, callback = () => {}, fail = () => {}) {
+	const app = getApp();
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
     if (deviceId == undefined) {
         fail();
@@ -804,6 +848,7 @@ function bmsDischargeMOS(macid, value, callback = () => {}, fail = () => {}) {
     return false;
 }
 function isConnected(macid) {
+	const app = getApp();
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
     if (deviceId == undefined) {
         return false;
@@ -811,6 +856,7 @@ function isConnected(macid) {
     return app.globalData.connectionState[deviceId].connected;
 }
 function getData(macid) {
+	const app = getApp();
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
     if (deviceId == undefined) {
         return false;
@@ -818,6 +864,7 @@ function getData(macid) {
     return app.globalData.connectionState[deviceId].data;
 }
 function getConnectionState(macid) {
+	const app = getApp();
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
     if (deviceId == undefined) {
         return false;
@@ -841,6 +888,7 @@ function isUniversalBluetoothPlugin(device) {
     }
 }
 function sendHireCommand(macid, info, callback = () => {}, fail = () => {}) {
+	const app = getApp();
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
     if (deviceId == undefined) {
         fail();
@@ -860,6 +908,7 @@ function sendHireCommand(macid, info, callback = () => {}, fail = () => {}) {
     return false;
 }
 function sendBackCommand(macid, info, callback = () => {}, fail = () => {}) {
+	const app = getApp();
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
     if (deviceId == undefined) {
         fail();
@@ -879,6 +928,7 @@ function sendBackCommand(macid, info, callback = () => {}, fail = () => {}) {
     return false;
 }
 function sendExchangeCommand(macid, info, callback = () => {}, fail = () => {}) {
+	const app = getApp();
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
     if (deviceId == undefined) {
         fail();
@@ -899,6 +949,7 @@ function sendExchangeCommand(macid, info, callback = () => {}, fail = () => {})
 }
 // 定义一个函数,用于发送获取柜子信息的命令
 function sendGetCabinetInfoCommand(macid, info, callback = () => {}, fail = () => {}) {
+	const app = getApp();
     // 获取设备ID
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
     console.log(deviceId,'deviceId0000');
@@ -929,6 +980,7 @@ function sendGetCabinetInfoCommand(macid, info, callback = () => {}, fail = () =
     return false;
 }
 function sendConfirmCommand(macid, value, serialNum, callback = () => {}, fail = () => {}) {
+	const app = getApp();
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
     if (deviceId == undefined) {
         fail();
@@ -948,6 +1000,7 @@ function sendConfirmCommand(macid, value, serialNum, callback = () => {}, fail =
     return false;
 }
 function sendCancelCommand(macid, serialNum, callback = () => {}, fail = () => {}) {
+	const app = getApp();
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
     if (deviceId == undefined) {
         fail();
@@ -969,6 +1022,7 @@ function sendCancelCommand(macid, serialNum, callback = () => {}, fail = () => {
 
 //切换正常工厂模式
 function sendSwitchNormalCommand(macid, callback = () => {}, fail = () => {}) {
+	const app = getApp();
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
     if (deviceId == undefined) {
         fail();
@@ -990,7 +1044,7 @@ function sendSwitchNormalCommand(macid, callback = () => {}, fail = () => {}) {
 }
 
 function sendOTACommand(macid, callback = () => {}, fail = () => {}) {
-	
+	const app = getApp();
     const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
     if (deviceId == undefined) {
         fail();
@@ -1027,19 +1081,22 @@ function sendOTACommand(macid, callback = () => {}, fail = () => {}) {
 }
 function executeDeviceCommand(macid, commandName, callback = () => {}, fail = () => {}) {
     console.log('test');
-	const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
+	const app = getApp();
+	const deviceId =  app.globalData.connectionState[macid].deviceId
     if (deviceId == undefined) {
         fail();
         return false;
     }
-    const device = app.globalData.connectionState[deviceId].device;
+    const device = app.globalData.connectionState[macid].device;
     if (!bluetoothDeviceConfig(device)[commandName]) {
         fail();
         return false;
     }
     var data = bluetoothDeviceConfig(device)[commandName](device, deviceId);
     if (data) {
-        writeData(device, deviceId, data, callback, fail);
+		setTimeout(()=>{
+			writeData(device, deviceId, data, callback, fail);
+		},200)
         return true;
     }
     fail();
@@ -1083,12 +1140,13 @@ function getSensitivity(macid, callback = () => {}, fail = () => {}) {
 }
 //设置灵敏度
 function setSensitivity(macid,type, callback = () => {}, fail = () => {}) {
-	const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
+	const app = getApp();
+	const deviceId = app.globalData.connectionState[macid].deviceId
 	if (deviceId == undefined) {
 	    fail();
 	    return false;
 	}
-	const device = app.globalData.connectionState[deviceId].device;
+	const device = app.globalData.connectionState[macid].device;
 	if (!bluetoothDeviceConfig(device)[setSensitivity]) {
 	    fail();
 	    return false;

+ 700 - 0
common/bluetooth/ZXCar - 副本.js

@@ -0,0 +1,700 @@
+const common = require('../common.js');
+
+const FMBMS = require('./FMBMS.js');
+var bluetooth = require('@/common/bluetooth.js');
+import permision from "@/js_sdk/wa-permission/permission.js"
+
+const readServiceID = '0000FEE7-0000-1000-8000-00805F9B34FB';
+const readID = '000036F6-0000-1000-8000-00805F9B34FB';
+const writeServiceID = '0000FEE7-0000-1000-8000-00805F9B34FB';
+const writeID = '000036F5-0000-1000-8000-00805F9B34FB';
+const MTU = 115;
+let subIndex = -1
+let commands = []; // 升级包指令数组,每个指令是一个 ArrayBuffer
+let currentCommandIndex = 1;
+var totalLength = 0 //总包长度
+var joinPack = []//接收到的数据包
+var readRepeatTime = 0 //读到完整数据包的时间戳
+var readRepeatTime = 0 //读到完整数据包的时间戳
+
+
+function acceptDevice(device) {
+	return device.btid ? true : false;
+}
+
+function isSingleBt() {
+	console.log('是单蓝牙');
+	return true;
+}
+
+function haveBms() {
+	console.log('是单蓝牙并且带bms');
+	return true;
+}
+
+function isDevice(device, data) {
+	// console.log(device,data,'device111');
+	const advertisData = new Uint8Array(data.advertisData);
+	// console.log(advertisData,'判断返回第几个字段是正常模式还是升级模式');
+	//打印返回广播 判断返回字段是正常模式还是升级模式
+	// console.log(advertisData.slice(4, 10).toString(),'device2222');
+	const mac = device.btid
+		.split('')
+		.map((p, i) => parseInt(p + device.btid[i + 1], 16))
+		.filter((p, i) => i % 2 == 0);
+
+	// if ( advertisData.slice(4, 10).toString() == "095A5832") {
+	//     return true;
+	// }
+	//判断是否是智寻的蓝牙
+	const result = data.name.startsWith("ZX");
+	// const result = data.name.startsWith("ZN");
+	// if (data.name === "865416038002201") {
+	// if (data.name === "ZX2503150000000") {
+	if (result) {
+		return true
+	}
+
+	return false;
+}
+
+//连接蓝牙后 发送登录指令
+function alterConnect(device, deviceId) {
+	const app = getApp();
+	readRepeatTime=0
+	// console.log(device,app.globalData.connectionState[deviceId],'deviceliuwei');
+	//登录 crc[0x1F,0x0F,0x5A,0x58,0x32,0x32,0x30,0x32,0x32,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x08,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x67,0xAC,0x53,0xE7,0x08,0x00]
+	//登录 [[0x22,0x22,0x01,0x1F,0x0F,0x5A,0x58,0x32,0x32,0x30,0x32,0x32,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x08,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x67,0xAC,0x53,0xE7,0x08,0x00,crc_data,0xAA,0xAA]]
+	//时间戳 0x67AC53E7 0x65,0xB3,0xED,0x6F 16:00:05
+	//切换正常,工厂下发指令 [[0x22,0x22,0x54,0x01,0x01,0x12,0xAA,0xAA]]
+	//OTA 升级指令 [[0x22,0x22,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,n,0xCB,0xAA,0xAA]]
+
+	// const data = [0x1F, 0x0F, ,0x5A,0x58, 0x35, 0x32, 0x30, 0x32, 0x32, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+	console.log("校检---》")
+	let data=[ 0x1F, 0x0F]
+	// const device_name=app.globalData.connectionState[device.mac_id].deviceName
+	const device_sn=stringToHexArray(device.mac_id)
+	
+	// const car_info = uni.getStorageSync('car_info')
+	// const device_sn=stringToHexArray(car_info.car_sn)
+	// const device_sn=stringToHexArray('865416038001109')
+	data.push(...device_sn)
+	data.push(0x08, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x67, 0xAC, 0x53, 0xE7, 0x08, 0x00)
+	// const data=[ 0x1F, 0x0F,0x38, 0x36, 0x35, 0x34, 0x31, 0x36, 0x30, 0x33, 0x38, 0x30, 0x30, 0x32, 0x32, 0x30, 0x31,0x08, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x67, 0xAC, 0x53, 0xE7, 0x08, 0x00]
+	// console.log(data,'datatest');
+	console.log(crc8IEEE8023(data).toString(16).toUpperCase(),'crc---------');
+	const crc_data = parseInt(crc8IEEE8023(data).toString(16).toUpperCase(),16) 
+	// const crc_data =crc8IEEE8023(data).toString(16).toUpperCase()
+	data.push(crc_data,0xAA,0xAA)
+	data.unshift(0x22,0x22,0x01)
+	// // 从索引 0 开始,删除 3 个元素
+	const firstPart = data.splice(0, 20);
+	
+	// // 剩余的元素
+	const secondPart = data;
+	// const threePart = data;
+	// return [data]
+	return [firstPart,secondPart]
+	// return [[0x22]]
+}
+
+function crc8IEEE8023(data) {
+    const poly = 0x07; // IEEE 802.3 polynomial x^8 + x^2 + x + 1
+    let crc = 0x00;
+
+    for (let i = 0; i < data.length; i++) {
+        crc ^= data[i];
+        for (let j = 0; j < 8; j++) {
+            if (crc & 0x80) {
+                crc = ((crc << 1) ^ poly) & 0xFF;
+            } else {
+                crc = (crc << 1) & 0xFF;
+            }
+        }
+    }
+    return crc;
+}
+
+function stringToHexArray(str) {
+  const result = [];
+  for (let i = 0; i < str.length; i++) {
+    const charCode = str.charCodeAt(i); // 获取字符的 ASCII 码值
+	const hexValue=`0x${charCode.toString(16).toUpperCase()}`
+	const hexDataValue=parseInt(hexValue,16)
+    result.push(hexDataValue);
+  }
+  return result;
+}
+
+
+
+
+//收到硬件方向软件方发送的数据
+function readData(device, value, data) {
+	console.log('***********************test');
+	var test = new Uint8Array(value);
+	// const bmsData=Array.from(test);
+	const normalArray=Array.from(test);
+	// console.log(bmsData,'bmsData-------------');
+	// const normalArray =packBmsData(bmsData) 
+	
+	if(normalArray){
+		console.log(normalArray[2],'normalArray---------------');
+		switch(normalArray[2]){
+			case 0x60:
+			//登陆指令
+			loginCmd(device.mac_id,normalArray)
+			break;
+			
+			case 0x61||0x62||0x65:
+			//开机指令 关机  寻车 //设置灵敏度回复
+			trunCarCommand(device.mac_id,normalArray)
+			break;
+			
+			case 0x66:
+			//升级指令
+			checkSendNextCommand(device.mac_id,normalArray)
+			break;
+			
+			case 0x7C:
+			//接近解锁指令 
+			nearCarCmd(device.mac_id,normalArray)
+			break;
+			
+			case 0x7E:
+			
+			//获取车辆接近解锁 是否配对 灵敏度信息
+			getNearCarCmdInfo(device.mac_id,normalArray)
+			break;
+			
+		}
+	}
+		
+	// console.log(normalArray,currentCommandIndex-1,commands[currentCommandIndex],commands[currentCommandIndex-1], 'value**************************');
+	// if((normalArray[0]==0x00) && (normalArray[1]==0x01) && normalArray.length==2){
+	// 	switch (normalArray[1]) {
+	// 		case 0x01:
+	// 			uni.showModal({
+	// 				title: '提示',
+	// 				confirmText: '开始升级',
+	// 				content: '登陆成功,当前处于升级模式是否开始升级',
+	// 				success: function(res) {
+	// 					if (res.confirm) {
+	// 						currentCommandIndex=0
+	// 						otaUpgrade().then(()=>{
+	// 							//登陆成功  且当前为升级模式可以发送升级文件
+	// 							sendNextCommand(device.mac_id)
+	// 						})
+	// 					} else {}
+	// 				}
+	// 			});
+	// 			return [1,1,2,3]
+	// 			break;
+	// 	}
+	// }else if(normalArray[0]==0x00&&normalArray.length==1){
+	// 	// common.simpleToast('开机成功', 2000)
+	// 	return '操作成功'
+	// }else{
+	// 	switch(normalArray[3]){
+	// 		case 0x00:
+	// 		sendNextCommand(device.mac_id)
+	// 		break;
+			
+			
+	// 		case 0x01:
+	// 		uni.hideLoading();
+	// 		console.log(normalArray,commands.length,currentCommandIndex-1,commands[currentCommandIndex-3],commands[currentCommandIndex-2],commands[currentCommandIndex-1], 'value**************************');
+	// 		common.simpleToast('升级文件回复失败', 2000)
+	// 		// test() 升级文件回复失败
+	// 		break;
+	// 	}
+	// }
+	
+
+
+	
+	
+		
+
+
+	return data;
+}
+
+function loginCmd(mac_id,data){
+	const len=data.length-4
+	if(data[len-1]==0x00 && data[len]==0x01){
+		uni.showModal({
+			title: '提示',
+			confirmText: '开始升级',
+			content: '登陆成功,当前处于升级模式是否开始升级',
+			success: function(res) {
+				if (res.confirm) {
+					currentCommandIndex=0
+					otaUpgrade().then(()=>{
+						//登陆成功  且当前为升级模式可以发送升级文件
+						sendNextCommand(device.mac_id)
+					})
+				} else {}
+			}
+		});
+	}else if(data[4]==0x00 && data[4]==0x00){
+		// uni.hideLoading();
+		//正常模式
+		console.log('登陆成功');
+		// if('lockType' in app.globalData.nearLockInfo ){
+		// 	if(app.globalData.nearLockInfo.lockType==0){
+		// 		console.log('获取接近解锁指令为关闭');
+				
+		// 	}else{
+		// 		uni.hideLoading();
+		// 		console.log('获取接近解锁指令为成功');
+		// 	}
+		// }else{
+		// 	const getNearUnlockSetCmd=getNearUnlockSet()
+		// 	console.log(getNearUnlockSetCmd,'getNearUnlockSetCmd');
+		// 	writeData(mac_id,getNearUnlockSetCmd)
+		// }
+		checkUnlock(mac_id,'login')
+	
+	}
+}
+function checkSendNextCommand(mac_id,data){
+	const len=data.length-4
+	if(data[len]==0x00){
+		sendNextCommand(device.mac_id)
+	}else if(data[len]==0x01){
+		uni.hideLoading();
+		// console.log(normalArray,commands.length,currentCommandIndex-1,commands[currentCommandIndex-3],commands[currentCommandIndex-2],commands[currentCommandIndex-1], 'value**************************');
+		common.simpleToast('升级文件回复失败')
+	}
+}
+function trunCarCommand(mac_id,data){
+	uni.hideLoading();
+	const len=data.length-4
+	if(data[len]==0x00){
+		common.simpleToast('操作成功')
+	}else if(data[len]==0x01){
+		common.simpleToast('操作失败')
+	}
+}
+function nearCarCmd(mac_id,data){
+	const app = getApp();
+	uni.hideLoading();
+	//测试
+	const len=data.length-4
+	const pData={
+		lockType:data[4],//接近解锁配置
+	}
+	console.log(pData,data,pData.status,'pData');
+	app.globalData.nearLockInfo=pData
+	
+	if(data[len]==0x00){
+		common.simpleToast('操作成功')
+		// common.simpleToast(`请在系统通知中同意与${mac_id}配对`)
+		
+	}else if(data[len]==0x01){
+		common.simpleToast('操作失败')
+		// common.simpleToast('配对失败,请重新开始配对')
+	}
+}
+
+
+
+
+//处理蓝牙三段回复 综合成一个数组
+function packBmsData(value) {
+  if (value.length!=0) {
+	  console.log(endTime - readRepeatTime);
+    if (endTime - readRepeatTime > 8000) {//超过8秒,说明数据有问题,数据清空
+      readRepeatTime = endTime
+      joinPack = []
+    }
+	// console.log((value[0] == 0x22) && (value[1]== 0x22),joinPack,'000000');
+    if((value[0] == 0x22) && (value[1]== 0x22)){//当开始符为标志符 代表接收包开始
+      var endTime = new Date().getTime()
+		  totalLength = value[3]//包长度
+		  joinPack=value
+      // console.log(joinPack,value,'111111');
+    }else if(joinPack.length!=0 && (joinPack[0] == 0x22) && (joinPack[1]== 0x22)){
+		const len=joinPack.length-1
+		const diffJoinLength =joinPack.length-4
+		readRepeatTime = endTime
+		// console.log(totalLength,diffJoinLength,value,'2222222');
+		if(totalLength > diffJoinLength){//内容长度符合为完整包
+			joinPack.push(...value)
+			return joinPack
+		}else if(totalLength <= diffJoinLength){
+			joinPack = []
+		}
+	}
+    else{
+		readRepeatTime = endTime
+		joinPack = []
+		return joinPack
+    }
+  }
+}
+
+function mergeUint8Array(arr1, arr2) {
+    let len1 = arr1 ? arr1.length : 0;
+    let len2 = arr2.length;
+    let arr = new Uint8Array(len1 + len2);
+
+    for (let i = 0; i < len1; i++) {
+        arr[i] = arr1[i];
+    }
+
+    for (let i = 0; i < len2; i++) {
+        arr[len1 + i] = arr2[i];
+    }
+
+    return arr;
+}
+
+//发送指令封装
+function sendCommand(cmd, data = []) {
+	readRepeatTime=0
+	let cmdData = [0x22, 0x22]
+	// cmdData.push(cmd)
+	//协议号 cmd
+	//包长度 data.length
+	const dataLen=parseInt(data.length.toString(16).toUpperCase(), 16)
+	//信息内容 cmd
+	//crc校验
+	const pData=[dataLen,...data]
+	const crcData=parseInt(crc8IEEE8023(pData).toString(16).toUpperCase(), 16)
+	cmdData.push(cmd,dataLen,...data,crcData,0xAA, 0xAA)
+	// console.log(cmdData,'cmdDatacmdData');
+	return cmdData
+}
+
+
+function turnOnCar(device, deviceId) {
+	return [sendCommand(0x02,[0x02])];
+}
+
+function turnOffCar(device, deviceId) {
+	return [sendCommand(0x03,[0x03])];
+}
+function findCarCmd(device, deviceId) {
+	return [sendCommand(0x06,[0x06])];
+}
+function openCarSeat(device, deviceId) {
+	return [sendCommand(0x07,[0x07])];
+}
+function openCarTrunk(device, deviceId) {
+	return [sendCommand(0x08,[0x08])];
+}
+function getCarPressure(device, deviceId) {
+	return [sendCommand(0x4A,[0x4A])];
+}
+function nearUnlock(device, deviceId) {
+	return [sendCommand(0x4B,[0x02])];
+}
+function nearCloseUnlock(device, deviceId) {
+	return [sendCommand(0x4B,[0x00])];
+}
+function getSensitivity(device, deviceId) {
+	return [sendCommand(0x4F,[0x4F])];
+}
+function setSensitivity(device, deviceId,type) {
+	return [sendCommand(0x4E,['0x4'+type])];
+}
+function setNearUnlock(device, deviceId,type) {
+	return [sendCommand(0x4D,[0x4D])];
+}
+function getNearUnlockSet(device, deviceId,type) {
+	return [sendCommand(0x4D,[0x4D])];
+}
+
+function getNearCarCmdInfo(macid,data){
+	console.log('getNearCarCmdInfo',macid,data);
+	
+	
+	if(data[5]==0x02||data[5]==0x01){
+		uni.hideLoading();
+		const pData={
+				lockType:data[4],//接近解锁配置
+				level:data[5],//感应等级
+			}
+		const app = getApp();
+		app.globalData.nearLockInfo=pData
+		
+		console.log('已开启配对');
+		// common.simpleToast('已开启配对',2000)
+		// common.simpleToast('感应解锁已开启,前往设置灵敏度页面')
+		// uni.navigateTo({ url: '/pages/bluetoothUnlock/unlockset' })
+		
+		// if( pData.status == 0x01){
+		// 	common.simpleToast('配对成功')
+		// 	return 
+		// }else if(pData.status==0x00){
+		// 	common.simpleToast('未配对')
+		// }
+		setTimeout(()=>{
+			checkUnlock(macid)
+		},300)
+	}else if(data[5]==0x00){
+		console.log('未开启配对')
+		const nearUnlockCmd=nearUnlock()
+		console.log(nearUnlockCmd,'nearUnlockCmd');
+		writeData(mac_id,nearUnlockCmd)
+	}
+		
+}
+function checkUnlock(macid,type='get'){
+	
+	const res=permision.getBondedDevices()
+	console.log(res,'test0000000000000');
+	let app=getApp()
+	if(res){
+			app.globalData.nearLockCheck=true
+			common.simpleToast('感应解锁已开启,前往设置灵敏度页面')
+			uni.redirectTo({ url: '/pages/bluetoothUnlock/unlockSet' })
+			console.log('test');
+			//redirectTo 关闭当前页面 防止用户重复操作
+		}else{
+			if(type==='login'){
+						//下发接近解锁指令
+						// const nearUnlockCmd=nearUnlock()
+						// console.log(nearUnlockCmd,'nearUnlockCmd');
+						// setTimeout(() => {
+						//     writeData(macid,nearUnlockCmd)
+						// }, 500);
+						
+						// 获取接近解锁指令信息
+						const getNearUnlockSetCmd=getNearUnlockSet()
+						console.log(getNearUnlockSetCmd,'getNearUnlockSetCmd');
+						setTimeout(() => {
+							writeData(macid,getNearUnlockSetCmd)
+						}, 200);
+			}else{
+				uni.showModal({
+					title: '蓝牙配对确认',
+					content: '请在系统通知栏前往同意与'+macid+'设备配对',
+					cancelText: '取消',
+					confirmText: '已同意',
+					success: function(res) {
+						if (res.confirm) {
+							checkUnlock(macid)
+						}else{
+							// uni.switchTab({ url: '/pages/index/index' })
+						}
+					},
+					fail: function(res) {},
+					complete: function(res) {},
+				})
+			}
+	}
+}
+
+
+
+function switchFactory(device, deviceId) {
+	//切换正常,工厂模式指令
+	//切换工厂模式 [[0x22,0x22,0x54,0x01,0x01,0x12,0xAA,0xAA]]
+	//切换正常模式 [[0x22,0x22,0x54,0x01,0x00,0x15,0xAA,0xAA]]
+	return [[0x22,0x22,0x54,0x01,0x01,0x12,0xAA,0xAA]]
+	// return [sendCommand([0x54, 0x01, 0x01, 0x12])];
+}
+//升级按钮
+function otaUpgrade(device){
+	
+	const data = readBinBinarayToCommand()
+	data.then(result=>{commands=result})
+	
+	// console.log(data,'datatest111');
+	return data
+}
+async function readBinBinarayToCommand() {
+	let res =await uni.request({
+	  url: 'https://opt.bms16.com/ota.BIN', // 文件的网络地址
+	  method: 'GET',
+	  responseType: 'arraybuffer', // 指定响应类型为 arraybuffer
+	});
+	const arrayBuffer=res[1].data
+	const uint8Array = new Uint8Array(arrayBuffer); // 转换为 Uint8Array
+	const test = splitArrayIntoChunks(uint8Array, 80); // 分割成长度为 80 的数组
+	const data =makeArr(test)
+	return data
+}
+
+function sendNextCommand(mac_id) {
+	const app = getApp();
+	readRepeatTime=0
+	// console.log(currentCommandIndex,commands.length,'开始发送指令');
+	// console.log(commands[currentCommandIndex],'command');
+    if (currentCommandIndex >= commands.length) {
+		uni.hideLoading();
+		common.simpleToast('所有指令发送完成', 2000)
+        return;
+    }
+	const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == mac_id);
+    if (deviceId == undefined) {
+		console.log('deviceId == undefined');
+        return ;
+    }
+    const command = [commands[currentCommandIndex]];
+	if(command.length==0){
+		return
+	}
+	// // 将数据转换为ArrayBuffer类型
+	var buffer;
+	buffer = common.toArrayBuffer(command.shift());
+	// console.log(command,'command');
+    uni.writeBLECharacteristicValue({
+        deviceId: deviceId, // 替换为实际的设备 ID
+        serviceId: writeServiceID, // 替换为实际的服务 ID
+        characteristicId: writeID, // 替换为可写入的特征值 ID
+        value: buffer,
+        success() {
+            // console.log('指令发送成功,等待设备响应',currentCommandIndex,commands[currentCommandIndex]);
+        },
+        fail(err) {
+            console.error('指令发送失败', err);
+        }
+    });
+    currentCommandIndex++;
+}
+
+function splitArrayIntoChunks(array, chunkSize) {
+	const newArr=array.slice(16383)
+    const numChunks = Math.ceil(newArr.length / chunkSize);
+	
+    return Array.from({ length: numChunks }, (_, i) => {
+        return newArr.slice(i * chunkSize, (i + 1) * chunkSize);
+    });
+}
+
+
+// 处理分割后的数组
+function makeArr(array) {
+    const result = [];
+	let endPackage;
+    for (let i = 0; i < array.length; i ++) {
+			endPackage = 0x00
+		if((i + 1) >= array.length){
+			//当前是最后一次循环
+			endPackage = 0x01
+		}
+		// if(i==2) return
+		//协议号 30 包长度未固定array.length+8 转16进制  固件类型0x00 升级包大小(总包大小) 125396字节-》0x00,0x01,0xE9,0xD4
+		let startArray = []
+		const packageLen=parseInt((array[i].length+8).toString(16).toUpperCase(), 16)
+		
+		// const totalPackageSize=[0x00,0x00,0x01,0xE9,0xD4]
+		// const totalPackageSize=[0x00,0x00,0x01,0xeb,0xfc]
+		const totalPackageSize=[0x00,0x00,0x01,0xAB,0xFC]
+		startArray.push(packageLen,...totalPackageSize)
+		 //软件包id
+		const ids=splitNumber(i)  // 0x00,0x01
+		startArray.push(...ids)
+		 //是否为最后一个包
+		startArray.push(endPackage)
+		 //软件数据包
+		const formattedChunk = array[i].map(byte => `0x${byte.toString(16).toUpperCase()}`); // 转换为 0xXX 格式 
+		startArray.push(...formattedChunk)
+		// if(i>95&& i<105){
+		// 	console.log(startArray,'startArray-------');
+		// }
+		//crc检验
+		const crcStr='0x'+crc8IEEE8023(startArray).toString(16).toUpperCase()
+		const testCrc=parseInt(crcStr,16)
+		
+		startArray.push(crcStr)
+		startArray.push(0xAA,0xAA)
+		startArray.unshift(0x22,0x22,0x30)
+        result.push(startArray);
+    }
+	// result.push([0x22,0x22,0x30,0x58,0x00,0x00,0x00,0xE9,0xD4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2C,0xAA,0xAA])
+    return result;
+}
+
+
+
+function splitNumber(num) {
+	let highByte = (num >> 8) & 0xFF; // 对于0-255的数字,结果总是0
+	// 低字节
+	let lowByte = num & 0xFF;
+  
+	// 将每个字节转换为两位的十六进制字符串,并添加'0x'前缀
+	let highHex = highByte.toString(16).toUpperCase().padStart(2, '0'); // 确保是两位十六进制数
+	let lowHex = lowByte.toString(16).toUpperCase().padStart(2, '0');  // 确保是两位十六进制数
+  
+	// 返回结果数组(这里实际上可以返回一个对象或字符串,根据需求调整)
+	return ['0x' + highHex, '0x' + lowHex];
+}
+
+// 定义一个函数,用于向蓝牙设备写入数据
+function writeData(mac_id, data, callback = () => {}, fail = () => {}) {
+	const app = getApp();
+	const deviceIds = app.globalData.connectionState[mac_id].deviceId
+	console.log(deviceIds,'deviceIds');
+    if (deviceIds == undefined) {
+        return ;
+    }
+	// 如果数据长度为0,则直接返回
+	if (data.length == 0) {
+        return;
+    }
+    // 将数据转换为ArrayBuffer类型
+    var buffer;
+    buffer = common.toArrayBuffer(data.shift());
+    // 调用uni.writeBLECharacteristicValue方法,向蓝牙设备写入数据
+    uni.writeBLECharacteristicValue({
+        deviceId: deviceIds,
+        serviceId: writeServiceID,
+        characteristicId: writeID,
+        value: buffer,
+        // 成功回调函数
+        success(res) {
+            // 如果数据长度为0,则调用回调函数
+            if (data.length == 0) {
+                callback(res);
+            } else {
+                // 否则,延时500毫秒后再次调用writeData函数
+                setTimeout(() => {
+                    writeData(device,  data, callback, fail);
+                }, 500);
+            }
+        },
+        // 失败回调函数
+        fail(res) {
+            console.log(res);
+            // 调用失败回调函数
+            fail(res);
+        }
+    });
+}
+
+
+
+
+module.exports = {
+	readServiceID: readServiceID,
+	readID: readID,
+	writeServiceID: writeServiceID,
+	writeID: writeID,
+	MTU: MTU,
+	acceptDevice: acceptDevice,
+	isDevice: isDevice,
+	alterConnect: alterConnect,
+	readData: readData,
+	turnOffCar: turnOffCar,
+	isSingleBt: isSingleBt,
+	haveBms: haveBms,
+	switchFactory: switchFactory,
+	otaUpgrade,
+	findCarCmd,
+	turnOffCar,
+	turnOnCar,
+	getCarPressure,
+	nearUnlock,
+	nearCloseUnlock,
+	getSensitivity,
+	setSensitivity,
+	getNearUnlockSet,
+	setNearUnlock,
+	
+
+};

+ 81 - 69
common/bluetooth/ZXCar.js

@@ -9,7 +9,6 @@ const readID = '000036F6-0000-1000-8000-00805F9B34FB';
 const writeServiceID = '0000FEE7-0000-1000-8000-00805F9B34FB';
 const writeID = '000036F5-0000-1000-8000-00805F9B34FB';
 const MTU = 115;
-const app = getApp();
 let subIndex = -1
 let commands = []; // 升级包指令数组,每个指令是一个 ArrayBuffer
 let currentCommandIndex = 1;
@@ -34,7 +33,7 @@ function haveBms() {
 }
 
 function isDevice(device, data) {
-	// console.log(device,data,'device111');
+	console.log(device,data,'device111');
 	const advertisData = new Uint8Array(data.advertisData);
 	// console.log(advertisData,'判断返回第几个字段是正常模式还是升级模式');
 	//打印返回广播 判断返回字段是正常模式还是升级模式
@@ -47,8 +46,9 @@ function isDevice(device, data) {
 	// if ( advertisData.slice(4, 10).toString() == "095A5832") {
 	//     return true;
 	// }
-		//判断是否是智寻的蓝牙
-	const result = data.name.startsWith("ZX");
+	//判断是否是智寻的蓝牙
+	// const result = data.name.startsWith("ZX");
+	const result = (data.name==device.mac_id);
 	// const result = data.name.startsWith("ZN");
 	// if (data.name === "865416038002201") {
 	// if (data.name === "ZX2503150000000") {
@@ -61,6 +61,7 @@ function isDevice(device, data) {
 
 //连接蓝牙后 发送登录指令
 function alterConnect(device, deviceId) {
+	const app = getApp();
 	readRepeatTime=0
 	// console.log(device,app.globalData.connectionState[deviceId],'deviceliuwei');
 	//登录 crc[0x1F,0x0F,0x5A,0x58,0x32,0x32,0x30,0x32,0x32,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x08,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x67,0xAC,0x53,0xE7,0x08,0x00]
@@ -72,8 +73,8 @@ function alterConnect(device, deviceId) {
 	// const data = [0x1F, 0x0F, ,0x5A,0x58, 0x35, 0x32, 0x30, 0x32, 0x32, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
 	console.log("校检---》")
 	let data=[ 0x1F, 0x0F]
-	const device_name=app.globalData.connectionState[deviceId].deviceName
-	const device_sn=stringToHexArray(device_name)
+	// const device_name=app.globalData.connectionState[device.mac_id].deviceName
+	const device_sn=stringToHexArray(device.mac_id)
 	
 	// const car_info = uni.getStorageSync('car_info')
 	// const device_sn=stringToHexArray(car_info.car_sn)
@@ -95,7 +96,7 @@ function alterConnect(device, deviceId) {
 	// const threePart = data;
 	// return [data]
 	return [firstPart,secondPart]
-	// return [[0x22,0x22,0x02,0x01,0x02,0x1B,0xAA,0xAA]]
+	// return [[0x22]]
 }
 
 function crc8IEEE8023(data) {
@@ -137,9 +138,10 @@ function readData(device, value, data) {
 	const normalArray=Array.from(test);
 	// console.log(bmsData,'bmsData-------------');
 	// const normalArray =packBmsData(bmsData) 
-	
+	console.log('normalArray---------------',normalArray);
+	if(normalArray[2]!=0x7E) return
 	if(normalArray){
-		console.log(normalArray[2],'normalArray---------------');
+		
 		switch(normalArray[2]){
 			case 0x60:
 			//登陆指令
@@ -223,20 +225,20 @@ function readData(device, value, data) {
 function loginCmd(mac_id,data){
 	const len=data.length-4
 	if(data[len-1]==0x00 && data[len]==0x01){
-		uni.showModal({
-			title: '提示',
-			confirmText: '开始升级',
-			content: '登陆成功,当前处于升级模式是否开始升级',
-			success: function(res) {
-				if (res.confirm) {
-					currentCommandIndex=0
-					otaUpgrade().then(()=>{
-						//登陆成功  且当前为升级模式可以发送升级文件
-						sendNextCommand(device.mac_id)
-					})
-				} else {}
-			}
-		});
+		// uni.showModal({
+		// 	title: '提示',
+		// 	confirmText: '开始升级',
+		// 	content: '登陆成功,当前处于升级模式是否开始升级',
+		// 	success: function(res) {
+		// 		if (res.confirm) {
+		// 			currentCommandIndex=0
+		// 			otaUpgrade().then(()=>{
+		// 				//登陆成功  且当前为升级模式可以发送升级文件
+		// 				sendNextCommand(device.mac_id)
+		// 			})
+		// 		} else {}
+		// 	}
+		// });
 	}else if(data[4]==0x00 && data[4]==0x00){
 		// uni.hideLoading();
 		//正常模式
@@ -278,6 +280,7 @@ function trunCarCommand(mac_id,data){
 	}
 }
 function nearCarCmd(mac_id,data){
+	const app = getApp();
 	uni.hideLoading();
 	//测试
 	const len=data.length-4
@@ -288,10 +291,12 @@ function nearCarCmd(mac_id,data){
 	app.globalData.nearLockInfo=pData
 	
 	if(data[len]==0x00){
-		common.simpleToast(`请在系统通知中同意与${mac_id}配对`)
+		common.simpleToast('操作成功')
+		// common.simpleToast(`请在系统通知中同意与${mac_id}配对`)
 		
 	}else if(data[len]==0x01){
-		common.simpleToast('配对失败,请重新开始配对')
+		common.simpleToast('操作失败')
+		// common.simpleToast('配对失败,请重新开始配对')
 	}
 }
 
@@ -397,10 +402,11 @@ function getSensitivity(device, deviceId) {
 function setSensitivity(device, deviceId,type) {
 	return [sendCommand(0x4E,['0x4'+type])];
 }
-function setNearUnlock(device, deviceId,type) {
+function setNearUnlock(device, deviceId) {
 	return [sendCommand(0x4D,[0x4D])];
 }
-function getNearUnlockSet(device, deviceId,type) {
+//
+function getNearUnlockSet(device, deviceId) {
 	return [sendCommand(0x4D,[0x4D])];
 }
 
@@ -414,6 +420,7 @@ function getNearCarCmdInfo(macid,data){
 				lockType:data[4],//接近解锁配置
 				level:data[5],//感应等级
 			}
+		const app = getApp();
 		app.globalData.nearLockInfo=pData
 		
 		console.log('已开启配对');
@@ -430,7 +437,7 @@ function getNearCarCmdInfo(macid,data){
 		setTimeout(()=>{
 			checkUnlock(macid)
 		},300)
-	}else if(pData.lockType==0x00){
+	}else if(data[5]==0x00){
 		console.log('未开启配对')
 		const nearUnlockCmd=nearUnlock()
 		console.log(nearUnlockCmd,'nearUnlockCmd');
@@ -439,47 +446,49 @@ function getNearCarCmdInfo(macid,data){
 		
 }
 function checkUnlock(macid,type='get'){
-	let deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == macid);
-	let device = app.globalData.connectionState[deviceId].device
-	permision.getBondedDevices(deviceId).then(res=>{
-		if(res){
+	
+	const res=permision.getBondedDevices()
+	console.log(res,'test0000000000000');
+	let app=getApp()
+	if(res){
 			app.globalData.nearLockCheck=true
 			common.simpleToast('感应解锁已开启,前往设置灵敏度页面')
+			uni.redirectTo({ url: '/pages/bluetoothUnlock/unlockSet' })
+			console.log('test');
 			//redirectTo 关闭当前页面 防止用户重复操作
-			uni.redirectTo({ url: '/pages/bluetoothUnlock/unlockset' })
 		}else{
-				if(type==='login'){
-							//下发接近解锁指令
-							// const nearUnlockCmd=nearUnlock()
-							// 		console.log(nearUnlockCmd,'nearUnlockCmd');
-							// 		writeData(mac_id,nearUnlockCmd)
-							
-							// 获取接近解锁指令信息
-							const getNearUnlockSetCmd=getNearUnlockSet()
-							console.log(getNearUnlockSetCmd,'getNearUnlockSetCmd');
-							setTimeout(() => {
-							    writeData(macid,getNearUnlockSetCmd)
-							}, 500);
-				}else{
-					uni.showModal({
-						title: '蓝牙配对确认',
-						content: '请在系统通知栏前往同意与'+device.name+'设备配对',
-						cancelText: '取消',
-						confirmText: '已同意',
-						success: function(res) {
-							if (res.confirm) {
-								checkUnlock(macid)
-							}else{
-								uni.redirectTo({ url: '/pages/index/index' })
-							}
-						},
-						fail: function(res) {},
-						complete: function(res) {},
-					})
-				}
-				
-		}
-	})
+			if(type==='login'){
+						//下发接近解锁指令
+						// const nearUnlockCmd=nearUnlock()
+						// console.log(nearUnlockCmd,'nearUnlockCmd');
+						// setTimeout(() => {
+						//     writeData(macid,nearUnlockCmd)
+						// }, 500);
+						
+						// 获取接近解锁指令信息
+						const getNearUnlockSetCmd=getNearUnlockSet()
+						console.log(getNearUnlockSetCmd,'getNearUnlockSetCmd');
+						setTimeout(() => {
+							writeData(macid,getNearUnlockSetCmd)
+						}, 200);
+			}else{
+				uni.showModal({
+					title: '蓝牙配对确认',
+					content: '请在系统通知栏前往同意与'+macid+'设备配对',
+					cancelText: '取消',
+					confirmText: '已同意',
+					success: function(res) {
+						if (res.confirm) {
+							checkUnlock(macid)
+						}else{
+							// uni.switchTab({ url: '/pages/index/index' })
+						}
+					},
+					fail: function(res) {},
+					complete: function(res) {},
+				})
+			}
+	}
 }
 
 
@@ -514,6 +523,7 @@ async function readBinBinarayToCommand() {
 }
 
 function sendNextCommand(mac_id) {
+	const app = getApp();
 	readRepeatTime=0
 	// console.log(currentCommandIndex,commands.length,'开始发送指令');
 	// console.log(commands[currentCommandIndex],'command');
@@ -620,8 +630,10 @@ function splitNumber(num) {
 
 // 定义一个函数,用于向蓝牙设备写入数据
 function writeData(mac_id, data, callback = () => {}, fail = () => {}) {
-    const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == mac_id);
-    if (deviceId == undefined) {
+	const app = getApp();
+	const deviceIds = app.globalData.connectionState[mac_id].deviceId
+	console.log(deviceIds,'deviceIds');
+    if (deviceIds == undefined) {
         return ;
     }
 	// 如果数据长度为0,则直接返回
@@ -633,7 +645,7 @@ function writeData(mac_id, data, callback = () => {}, fail = () => {}) {
     buffer = common.toArrayBuffer(data.shift());
     // 调用uni.writeBLECharacteristicValue方法,向蓝牙设备写入数据
     uni.writeBLECharacteristicValue({
-        deviceId: deviceId,
+        deviceId: deviceIds,
         serviceId: writeServiceID,
         characteristicId: writeID,
         value: buffer,
@@ -645,7 +657,7 @@ function writeData(mac_id, data, callback = () => {}, fail = () => {}) {
             } else {
                 // 否则,延时500毫秒后再次调用writeData函数
                 setTimeout(() => {
-                    writeData(device, deviceId, data, callback, fail);
+                    writeData(device,  data, callback, fail);
                 }, 500);
             }
         },

+ 48 - 11
common/common.js

@@ -847,7 +847,7 @@ async function callPhone(phone) {
 		content: text,
 		confirmText: '确定',
 	})
-	if(res[1].confirm){
+	if (res[1].confirm) {
 		uni.makePhoneCall({
 			phoneNumber: phone,
 		})
@@ -855,17 +855,53 @@ async function callPhone(phone) {
 }
 
 function timestampToDays(timestamp) {
-	if(!timestamp) return
-    // 1秒 = 1000毫秒,1分钟 = 60秒,1小时 = 60分钟,1天 = 24小时
-    const millisecondsInADay = 24 * 60 * 60 * 1000;
-
-    // 计算天数
-    const days = timestamp / millisecondsInADay;
-
-    // 保留一位小数
-    return days.toFixed(1);
+	if (!timestamp) return
+	// 1秒 = 1000毫秒,1分钟 = 60秒,1小时 = 60分钟,1天 = 24小时
+	const millisecondsInADay = 24 * 60 * 60 * 1000;
+
+	// 计算天数
+	const days = timestamp / millisecondsInADay;
+
+	// 保留一位小数
+	return days.toFixed(1);
+}
+
+//计算相差时间
+function formatTimeDifference(timestamp) {
+	const current = Date.now();
+	const diff = Math.abs(current - timestamp);
+	const totalHours = diff / (1000 * 60 * 60)
+	let days = 0;
+	let hours;
+	
+	if (totalHours >= 24) {
+		days = Math.floor(totalHours / 24); // 计算完整天数
+		hours = Math.round(totalHours % 24); // 剩余小时四舍五入
+		
+		const result = [];
+		if (days > 0) result.push(`${days}天`);
+		if (hours > 0 || result.length === 0) result.push(`${hours}小时`);
+		return result.join("");
+		
+	} else {
+		// 提取整数小时部分
+		hours = Math.floor(totalHours);
+		// 计算剩余的小数小时并转换为分钟
+		let remaining = totalHours - hours;
+		let minutes = Math.round(remaining * 60);
+
+		// 处理分钟进位(例如 59.6分钟 → 60分钟 → 进位到小时)
+		if (minutes >= 60) {
+			hours += 1;
+			minutes = 0;
+		}
+		days = 0;
+		return `${hours}小时 ${minutes}分钟`;
+	}
+	
 }
 
+
 module.exports = {
 	formatTime: formatTime,
 	obj2UrlQuery: obj2UrlQuery,
@@ -914,5 +950,6 @@ module.exports = {
 	countToDay: countToDay,
 	getFormattedTime: getFormattedTime,
 	callPhone: callPhone,
-	timestampToDays: timestampToDays
+	timestampToDays: timestampToDays,
+	formatTimeDifference: formatTimeDifference
 };

+ 1 - 1
common/config.js

@@ -49,7 +49,7 @@ var config = {
 	API_DAYHIRE_HIRE_HIRE: api_web_url + '?r=dayhire/hire/hire', // 扫码下单租车
 	API_DAYHIRE_HIRE_ORDER_LIST: api_web_url + '?r=dayhire/hire/order-list', // 订单列表
 	API_DAYHIRE_HIRE_ORDER_INFO: api_web_url + '?r=dayhire/hire/order-info', //订单详情
-	API_DAYHIRE_HIRE_CANCEL_ORDER: api_web_url + '?r=dayhire/hire/cancel-order', //取消订单
+	API_DAYHIRE_HIRE_CANCEL_ORDER: api_web_url + '?r=flk/order/cancel-pay', //取消订单
 	API_DAYHIRE_HIRE_CONTINUE_PAY: api_web_url + '?r=dayhire/hire/continue-pay', //重新调起支付
 	API_DAYHIRE_USER_SHOP_MODEL_LIST: api_web_url + '?r=dayhire/user/shop-model-list', //门店列表
 	API_DAYHIRE_USER_SHOP_INFO: api_web_url + '?r=dayhire/user/shop-info', //门店详情

+ 2 - 1
common/config_gyq.js

@@ -54,7 +54,8 @@ var config = {
 	API_FLK_CABINET_NEAR_LIST: api_web_url +'?r=flk/cabinet/near-list',
 	//忘记密码
 	API_FLK_CABINET_RESET_PASSWORD: api_web_url +'?r=flk/account/reset-password',
-	
+	//车辆电池列表
+	API_CAR_BATTERY_LIST: api_web_url +'?r=flk/car/battery-list',
 	//取消订单
 	API_FLK_ORDER_CANCEL_PAY: api_web_url +'?r=flk/order/cancel-pay',
 	//激活车辆(绑定设备): 

+ 5 - 2
common/http.js

@@ -124,7 +124,11 @@ function postRequest(url, data, successCallBack, failCallBack) {
 			} else if(res.data.code === 503){
 				return
 			} else {
-				uni.showToast({ title: res.data.msg, icon: 'none' })
+				successCallBack(res);
+				if(res.data.msg){
+					uni.showToast({ title: res.data.msg, icon: 'none' })
+				}
+				
 				return
 			}
 			if (_checkTokenValid(res)) {
@@ -141,7 +145,6 @@ function postRequest(url, data, successCallBack, failCallBack) {
 					showCancel: false
 				});
 			}
-
 			failCallBack(res);
 		}
 	});

+ 16 - 15
common/storage.js

@@ -33,14 +33,15 @@ const ICONS = {
 	add: `${QINIU_URL}FqLEWbMe8DcnQtNz6GdDDD87ObZK`,
 	placeholder: `${QINIU_URL}FpKvfFNSDbx0d9RDwyGAQdFb7Kt6`
 }
-const activeTabs = [{
-		name: i18n.t('开机'),
-		type:'turnOnOrOff',
-		iconUrl: `${QINIU_URL}Fp5T9lSNakoiioji6S7W4DmFQ_ys`,
-		offUrl: `${QINIU_URL}FqxGx0H169EOJN0__Ym2Ls8x2i03`,
-		isLock: true,
-		isTurnOn:1
-	},
+// {
+// 		name: i18n.t('开机'),
+// 		type:'turnOnOrOff',
+// 		iconUrl: `${QINIU_URL}Fp5T9lSNakoiioji6S7W4DmFQ_ys`,
+// 		offUrl: `${QINIU_URL}FqxGx0H169EOJN0__Ym2Ls8x2i03`,
+// 		isLock: true,
+// 		isTurnOn:1
+// 	},
+const activeTabs = [
 	{
 		name: i18n.t('闪灯鸣笛'),
 		type:'findCar',
@@ -55,15 +56,15 @@ const activeTabs = [{
 		name: i18n.t('打开尾箱'),
 		type:'openTailBox',
 		iconUrl: `${QINIU_URL}Fv3KLuYWEeV5IM4_2sMbmur7yZtz`
-	}
-]
-const toBeSelectTabs = [{
+	},
+	{
 		name:i18n.t('胎压'),
 		type:'tirePressure',
 		url:'',
 		iconUrl: `${QINIU_URL}FmbcjmvoB4J3CT1hrbjNX4kxv9Zq`
-	},
-	{
+	}
+]
+const toBeSelectTabs = [{
 		name: i18n.t('电池信息'),
 		type:'batteryInfo',
 		url:'/pages/batteryDetail/batteryDetail',
@@ -199,8 +200,8 @@ function setUserCurrentLocation(
 
 function getUserCurrentLocation() {
 	return uni.getStorageSync(USER_CURRENT_LOCATION) || {
-		longitude: 115.853024,
-		latitude: 28.686280
+		longitude: "115.853024",
+		latitude: "28.686280"
 	};
 }
 

+ 2 - 1
component/allPrice/allPrice.css

@@ -6,5 +6,6 @@
 }
 
 .integer-part {
-	font-size: 40rpx;
+	font-size: 54rpx;
+	font-family: DIN, DIN;	
 }

+ 1 - 1
component/allPrice/allPrice.vue

@@ -2,7 +2,7 @@
 	<view class="container flex-row">
 		<view>¥</view>
 		<view class="integer-part">{{integerPart}}</view>
-		<view>{{decimalPart}}</view>
+		<view style="font-size: 32rpx;">{{decimalPart}}</view>
 	</view>
 </template>
 

+ 6 - 2
component/carPlan/carPlan.css

@@ -66,9 +66,10 @@
 	justify-content: center;
 	background: #F3F8FF;
 	border-radius: 16rpx;
-	min-width: 158rpx;
 	border: 4rpx solid transparent;
 	margin-right: 18rpx;
+	box-sizing: border-box;
+	min-width: 158rpx;
 }
 .car-plan-list-i{
 	height: 158rpx;
@@ -76,9 +77,10 @@
 	justify-content: center;
 	background: #FFF;
 	border-radius: 16rpx;
-	min-width: 158rpx;
 	border: 4rpx solid #0A59F7;
 	margin-right: 18rpx;
+	box-sizing: border-box;
+	min-width: 158rpx;
 }
 .car-plan-unit{
 	font-weight: 400;
@@ -89,11 +91,13 @@
 	font-weight: 600;
 	font-size: 32rpx;
 	color: #060809;
+
 }
 .car-plan-unit-i{
 	font-weight: 400;
 	font-size: 32rpx;
 	color: #0A59F7;
+
 }
 .car-plan-price-i{
 	font-weight: 600;

+ 6 - 2
component/carPlan/carPlan.vue

@@ -3,7 +3,7 @@
 		<view class="more-info">
 			<view class="flex-row model-title">
 				<view style="margin-right: 24rpx;">
-					<image style="width: 160rpx;height: 160rpx;border-radius: 16rpx;" :src="image" mode="aspectFill"></image>
+					<image style="width: 160rpx;height: 160rpx;border-radius: 16rpx;" :src="image" mode="aspectFit"</image>
 					</view>
 				<view class="car-model-detail flex-row">
 					<!-- <priceTool :price="58" :font_size="40"/> -->
@@ -46,7 +46,7 @@
 						<view :class="(type == item.hire_duration_unit ? 'car-plan-price-i' : 'car-plan-price') ">$<text style="font-size: 48rpx;margin-left: 6rpx;">{{item.hire_price/100}}</text></view>
 					</view>
 					
-					<view v-if="params.sell_price != 0"  @click="tapSelectType({hire_duration_unit:100,hire_price:params.sell_price})" :class="['flex-row' , (type == 100 ? 'car-plan-list-i' : 'car-plan-list') ]" >
+					<view v-if="params.sell_price != 0 && isBuy"  @click="tapSelectType({hire_duration_unit:100,hire_price:params.sell_price})" :class="['flex-row' , (type == 100 ? 'car-plan-list-i' : 'car-plan-list') ]" style="padding:  0rpx 20rpx; min-width: auto; "  >
 						<view :class="(type == 100 ? 'car-plan-unit-i' : 'car-plan-unit') ">购买</view>
 						<view :class="(type == 100 ? 'car-plan-price-i' : 'car-plan-price') ">$<text style="font-size: 48rpx;margin-left: 6rpx;">{{params.sell_price/100}}</text></view>
 					</view>
@@ -138,6 +138,10 @@
 		 * 组件的属性列表
 		 */
 		props: {
+			isBuy:{
+				type: Boolean,
+				default: true
+			},
 			params:{
 				type:Object,
 				default:{}

+ 5 - 3
component/comPopup/Notice.vue

@@ -5,8 +5,8 @@
             <view class="title">{{ title }}</view>
             <view class="tips">
                 <text v-if="type=='bluetoothPail'">{{text}}</text>
-                <text v-else-if="type=='register'">我们向 <span style="color: #0A59F7;">{{email}}</span> 注册邮件,请您登录邮箱点击链接完成注册。</text>
-                <text v-else-if="type=='forgetPassword'">我们向 <span style="color: #0A59F7;">{{email}}</span> 发送了一封密码重置邮件,请您登录邮箱操作处理。</text>
+                <text v-else-if="type=='register'">我们向 <span style="color: #0A59F7;">{{email}}</span> 发送注册邮件,请您登录邮箱点击链接完成注册。</text>
+                <text v-else-if="type=='forgetPassword'">我们向 <span style="color: #0A59F7;">{{email}}</span> 发送了一封密码重置邮件,请您登录邮箱操作处理。</text>
             </view>
             <view class="btn" @tap="close">{{ btnText }}</view>
         </view>
@@ -55,7 +55,9 @@ export default {
     },
     methods: {
         close() {
-            this.$emit('input', false)
+            uni.navigateTo({
+            	url: '/pages/loginRegister/login',
+            })
         }
     }
 }

+ 196 - 0
component/customSwitch.vue

@@ -0,0 +1,196 @@
+<template>
+	<view class="switch-container" :style="{ width: width, height: height }" @touchstart="onTouchStart"
+		@touchmove="onTouchMove" @touchend="onTouchEnd" @click="handleClick">
+		<view class="switch" :class="{ active: isValue }">
+			<!-- 额外包裹一层 -->
+			<view class="indicator-wrapper" :class="{ shaking: isShaking }">
+				<image class="indicator" :src="imageSrc" />
+			</view>
+			<view v-if="isShowSwitchText&&isValue" class="switch_text_off">滑动关机</view>
+			<view v-if="isShowSwitchText&&!isValue" class="switch_text_on">滑动开机</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			modelValue: String,
+			imageSrc: {
+				type: String,
+				default: "https://qiniu.bms16.com/Fkovrpq1bexe-Unal_VJREbLUhdu" // 默认滑块图片
+			},
+			width: {
+				type: String,
+				default: "400rpx" // 默认宽度
+			},
+			height: {
+				type: String,
+				default: "96rpx" // 默认高度
+			},
+			defaultPosition: {
+				type: String,
+				default: "right" // 默认在左边
+			},
+			fetchData: Function // 后台请求函数
+		},
+		data() {
+			return {
+				isValue:false,
+				isShowSwitchText: true,
+				isSwiping: false, // 是否滑动
+				isShaking: false, // 是否抖动
+				startX: 0, // 触摸起始位置
+				position: 2, // 滑块初始位置 (左侧)
+				containerWidth: 400, // 容器宽度(px)
+				indicatorSize: 36 // 滑块大小(px)
+			};
+		},
+		computed: {
+			maxPosition() {
+				return this.containerWidth - this.indicatorSize - 4; // 计算滑块最右边的位移
+			}
+		},
+		watch: {
+			modelValue(newValue) {
+				// console.log(newValue,"值变动")
+				// this.isValue = JSON.parse(newValue).state
+				this.position = this.isValue ? this.maxPosition : 2;
+			}
+		},
+		mounted() {
+		},
+		methods: {
+			async triggerRequest() {
+				if (this.isShaking) return; // 避免重复触发
+				this.isShaking = true; // 开始抖动
+				try {
+					let data = await this.fetchData(this.isValue); // 触发后台请求
+					this.isValue = JSON.parse(data).state
+					this.$emit('changEnd',data)
+				} catch (error) {
+					console.error("请求失败:", error);
+				} finally {
+					this.isShowSwitchText = true;
+					this.isShaking = false; // 停止抖动
+					// this.isValue = !this.isValue
+				}
+			},
+			handleClick() {
+				if (this.isSwiping) return;
+				this.isShowSwitchText = false;
+				this.triggerRequest();
+			},
+			onTouchStart(e) {
+				this.isShowSwitchText = false;
+				this.isSwiping = false;
+				this.startX = e.touches[0].clientX;
+			},
+			onTouchMove(e) {
+				let moveX = e.touches[0].clientX - this.startX;
+				if (Math.abs(moveX) > 10) {
+					this.isSwiping = true;
+				}
+			},
+			onTouchEnd() {
+				if (!this.isSwiping) return;
+				this.triggerRequest();
+				this.isSwiping = false;
+			}
+		}
+	};
+</script>
+
+<style scoped>
+	.switch-container {
+		/* 	width: 400rpx;
+		height: 96rpx; */
+		background: #FFFFFF;
+		border-radius: 48rpx;
+		border: 4rpx solid #F1F3F4;
+		display: flex;
+		align-items: center;
+		padding: 2px;
+		position: relative;
+	}
+
+	.switch {
+		width: 100%;
+		height: 100%;
+		border-radius: 15px;
+		position: relative;
+		transition: background 0.3s;
+	}
+
+	.switch.active {
+		background: #ffffff;
+	}
+
+	/* 外层比滑块大 5px */
+	.indicator-wrapper {
+		width: 144rpx;
+		height: 80rpx;
+		background: rgba(0, 0, 0, 1);
+		border-radius: 42rpx;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		position: absolute;
+		/* top: 6rpx; */
+		left: 6rpx;
+	}
+
+	.indicator {
+		width: 26px;
+		height: 26px;
+		border-radius: 50%;
+		position: relative;
+		transition: transform 0.3s;
+	}
+
+	.switch.active .indicator-wrapper {
+		transform: translateX(244rpx);
+	}
+
+	.indicator-wrapper.shaking {
+		animation: shake 0.2s infinite alternate;
+	}
+
+	.switch_text_on {
+		position: relative;
+		width: 158rpx;
+		height: 80rpx;
+		font-family: PingFangSC, PingFang SC;
+		font-weight: 500;
+		font-size: 32rpx;
+		color: #060809;
+		line-height: 80rpx;
+		text-align: left;
+		font-style: normal;
+		margin-left: 200rpx;
+	}
+
+	.switch_text_off {
+		position: relative;
+		width: 158rpx;
+		height: 80rpx;
+		font-family: PingFangSC, PingFang SC;
+		font-weight: 500;
+		font-size: 32rpx;
+		color: #060809;
+		line-height: 80rpx;
+		text-align: left;
+		font-style: normal;
+		margin-left: 50rpx;
+	}
+
+	@keyframes shake {
+		0% {
+			transform: translateX(110rpx);
+		}
+
+		100% {
+			transform: translateX(120rpx);
+		}
+	}
+</style>

+ 7 - 2
component/customTabbar/index.vue

@@ -25,7 +25,6 @@
 </template>
 
 <script>
-	var app = getApp();
 	const storage = require('@/common/storage.js');
 	const http = require('@/common/http.js');
 	const config = require('@/common/config.js');
@@ -88,7 +87,7 @@
 		// },
 
 		mounted() {
-			console.log(uni.getSystemInfoSync().safeArea)
+			// console.log(uni.getSystemInfoSync().safeArea)
 		},
 		methods: {
 			routerPush(url) {
@@ -103,13 +102,19 @@
 				const me = this
 				if (!this.loadIsLogin()) return
 				uni.scanCode({
+					scanType:['qrCode'],
 					success(res) {
 						me.loadGeneralQRData(res.result)
+					},
+					fail() {
+						me.$msg('扫码失败,请重新扫码')
 					}
 				})
 			},
 			loadGeneralQRData(options) {
+				console.log(options)
 				let objOpt = this.$paramsObj(options)
+				
 				if (objOpt.d) {
 					console.log('扫码的是机柜')
 					uni.navigateTo({

+ 14 - 11
component/googleMap/googleMap.vue

@@ -2,7 +2,7 @@
 	<view class="content">
 		<view id="container">
 			<view :style="{width:width,height:height}" :keyId='keyId' :change:keyId='keyId' :id="`mapModule` + keyId"
-				:prop="mapData" :change:prop="mapModule.update" :lngLat="myLocation"
+				:prop="mapData" :change:prop="mapModule.update" :lngLat="myLocations"
 				:change:lngLat="mapModule.initAmap"></view>
 
 		</view>
@@ -11,8 +11,6 @@
 <script module="mapModule" lang="renderjs">
 	var common = require("@/common/common.js");
 	var transform = require('../../common/transform.js');
-	var meMarker = []
-	var polylinePath = null
 	export default {
 		data() {
 			return {
@@ -45,11 +43,14 @@
 				let _this = this
 				const script = document.createElement('script')
 				script.src =
-					'https://map.gpsall.cc/maps/api/js?key=AIzaSyA70JUgslynjmVv0NPz3hcvkTbPZpr2i_c&callback=initMap&v=weekly&loading=async';
+					'https://map.gpsall.cc/maps/api/js?key=AIzaSyCWxFJPWgJP8hb2cTbvfZb13tbm2rlhxgs&callback=initMap&v=weekly&loading=async';
 				script.async = true; // 异步加载
 				script.defer = true; // 延迟执行
 				document.head.appendChild(script)
 				window.initMap = function() {
+					 // 延迟执行以确保元素已加载
+					  // const elements = document.querySelectorAll(".gm-style-cc, .gmnoprint[role='menubar']");
+					  // elements.forEach(el => el.style.display = "none");
 					_this.loadAmap(lngLat)
 				};
 
@@ -60,9 +61,7 @@
 					lat: lngLat.latitude,
 					lng: lngLat.longitude
 				}
-				console.log("lngLat", lngLat)
 				lngLat = transform.wgs_gcj_encrypts(lngLat)
-				console.log("lngLat", lngLat)
 
 				this.map.panTo(new google.maps.LatLng(lngLat.latitude, lngLat.longitude))
 			},
@@ -78,6 +77,7 @@
 					fullscreenControl: false,
 					draggable: true, // 显式启用拖拽
 					zoom: _this.zoom,
+					 keyboardShortcuts: false, // 禁用键盘快捷键
 					panControl: false,
 					zoomControl: false,
 					scaleControl: false,
@@ -94,10 +94,9 @@
 				new google.maps.event.addListener(_this.map, "click", function(event) {
 					_this.$ownerInstance.callMethod('bindTapMap')
 				});
+				
 				//如果有polylines则添加
 				if (_this.polylines?.points?.length > 0) {
-					console.log('添加轨迹')
-					console.log(_this.polylines.points)
 					let path = _this.polylines.points.map(item => {
 						return {
 							lng: item.lng,
@@ -130,6 +129,7 @@
 			//添加标记
 			addMarkers() {
 				if (this.markersArray.length > 0) this.clearMarkers() //添加前先删除所有标记
+				console.log(this.Markers)
 				this.Markers.map((item, index) => {
 					this.AddMarker(item)
 				})
@@ -174,6 +174,8 @@
 			},
 
 			update(newValue, _, ownerInstance) {
+				console.log('过来了')
+				console.log(newValue)
 				if (newValue.zoom) this.zoom = newValue.zoom || 14
 				if (newValue.polylines && newValue.polylines.points && newValue.polylines.points.length > 0) this
 					.polylines = newValue.polylines
@@ -227,7 +229,7 @@
 					size: new google.maps.Size(item.width, item.height),
 					scaledSize: new google.maps.Size(item.width, item.height)
 				});
-				let distance = common.getFlatternDistance(this.myLocation.longitude, this.myLocation
+				let distance = common.getFlatternDistance(this.myLocations.longitude, this.myLocations
 					.latitude, item.longitude, item.latitude)
 				let time = Math.ceil(Number(((distance - 0) / 1000).toFixed(2)) * 25 / 10)
 				let content = `${common.formatDistance(Number(distance))} 骑行${time}分钟`
@@ -277,7 +279,7 @@
 				type: Object,
 				required: true //必填项
 			},
-			myLocation: {
+			myLocations: {
 				type: Object,
 				required: true //必填项
 			},
@@ -288,7 +290,8 @@
 
 			};
 		},
-		mounted() {},
+		mounted() {
+		},
 		methods: {
 			onMarkertap(marker) {
 				this.$emit('changMarkertap', marker)

+ 58 - 0
component/googleMap/googleMaps.vue

@@ -0,0 +1,58 @@
+<template>
+	<view :style="{width:width,height:height}">
+		<view :style="{width:width,height:height}" id='map111'></view>
+	</view>
+</template>
+
+<script>
+	import { Loader } from "@googlemaps/js-api-loader"
+	export default {
+		props:{
+			width: {
+				type: String,
+				default: '100%'
+			},
+			height: {
+				type: String,
+				default: '100%'
+			},
+		},
+		data() {
+			return {
+				maps: null,
+				loader:null
+			}
+		},
+		mounted() {
+			console.log('哈哈哈')
+			let loader = new Loader({
+				apiKey: "AIzaSyCWxFJPWgJP8hb2cTbvfZb13tbm2rlhxgs",
+				version: "weekly",
+			});
+			this.init(loader)
+		},
+		methods: {
+			async init(loader) {
+				loader.load().then(async res => {
+					const {
+						Map
+					} = await google.maps.importLibrary("maps");
+
+					this.map = new Map(document.getElementById("map111"), {
+						center: {
+							lat: -34.397,
+							lng: 150.644
+						},
+						zoom: 8,
+					});
+				}).catch(err=>{
+					console.log(err)
+				});
+			}
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 11 - 3
component/returnCar/returnCar.vue

@@ -10,6 +10,7 @@
 					<view @tap="navStore">导航到店</view>
 					<view @tap="immediatelyReturn">我已到店</view>
 				</view>
+				<view v-if="typePage=='index'" style="height: 110rpx;"></view>
 			</view>
 		</view>
 </template>
@@ -28,6 +29,10 @@ export default {
 			type: Boolean,
 			default: false
 		},
+		typePage: {
+			type: String,
+			default: 'order'
+		},
     },
     /**
      * 组件的方法列表
@@ -50,7 +55,7 @@ export default {
 	position: fixed;
 	top: 0;
 	left: 0;
-	z-index: 10;
+	z-index: 1000;
 	width: 100%;
 	height: 100vh;
 	background-color: rgba(0, 0, 0, 0.4);
@@ -60,7 +65,7 @@ export default {
 	border-radius: 32rpx 32rpx 0rpx 0rpx;
 	background-color: #ffffff;
 	padding: 40rpx 32rpx 74rpx;
-	z-index: 100;
+	z-index: 1100;
 	position: fixed;
 	bottom: 0;
 	width: 100%;
@@ -117,9 +122,12 @@ export default {
 .close-view{
 	width: 60rpx;
 	height: 60rpx;
-	line-height: 60rpx;
+	/* line-height: 60rpx; */
 	background: #F4F5F6;
 	border-radius: 50%;
 	text-align: center;
+	display: flex;
+	align-items: center;
+	justify-content: center;
 }
 </style>

+ 4 - 5
component/scanBtn/scanBtn.vue

@@ -119,7 +119,7 @@
 				isShowToBuy:false,
 				wallet_money:0,
 				payResp:{},
-				myLocation:{},
+				myLocations:{},
 				orderInfo:{},
 				carInfo:{}
 			}
@@ -129,7 +129,6 @@
 		 */
 		,
 		mounted: function(options) {
-			console.log(454444)
 			const car_list = uni.getStorageSync('user_car_list') || null
 			const storedLocation = uni.getStorageSync('user_current_location');
 			if (car_list){
@@ -140,7 +139,7 @@
 			if (storedLocation && storedLocation.longitude && storedLocation.latitude) {
 				// 如果本地有存储的定位信息,则直接使用
 				this.setData({
-					myLocation: storedLocation,
+					myLocations: storedLocation,
 					license_plate_number:car_list.plate_number
 				});
 			}
@@ -237,8 +236,8 @@
 				//扫码机柜信息
 				const me=this
 				const pData={
-					longitude:this.myLocation.longitude,
-					latitude:this.myLocation.latitude,
+					longitude:this.myLocations.longitude,
+					latitude:this.myLocations.latitude,
 					dev_id:dev_id||'',
 					time:timeNow
 				}

+ 4 - 0
component/scanCabBtn/scanBtn.css

@@ -462,4 +462,8 @@
 	color: #fff;
 	text-align: center;
 	line-height: 80rpx;
+	position: fixed;
+	right: 0;
+	left: 0;
+	bottom: 60rpx;
 }

+ 30 - 26
component/scanCabBtn/scanBtn.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="container-view">
+		<view style="height: 160rpx;"></view>
 		<view @tap="sacnBtn" class="refund-btn"><text>扫码换电</text></view>
 		<view v-if="isModelCenter" class="model_center">
 			<image class="pack_model" src="https://zxappfile.bms16.com/zx_client/buy_pack_model.png" />
@@ -8,7 +9,7 @@
 			<view v-if="packType==0" class="look_package" @tap="clickLookPackage">查看套餐</view>
 			<view v-if="packType==2" class="look_package" @tap="clickMyPackage">去押金认证</view>
 			<view class="line_view"></view>
-			<image @tap="clickClosePackage" class="close_package"
+			<image @tap="isModelCenter = false" class="close_package"
 				src="https://zxappfile.bms16.com/zx_client/close_package.png"></image>
 		</view>
 	</view>
@@ -26,7 +27,7 @@
 	// var IndexImpl = require('../../pages/index/model/indexImpl.js');
 	const DF_CAB_INFO_DONE = 10000; //机柜信息传输完成
 	var subscribeTimer = null;
-	var app = getApp();
+	
 	export default {
 		props: {
 			listData:{
@@ -109,6 +110,7 @@
 				// this.license_plate_number = car_list.plate_number
 				this.carInfo = car_list
 			}
+			let app = getApp();
 			if (app.globalData.showScanBtn) {
 				this.showScanBtn = true
 			} else {
@@ -140,8 +142,8 @@
 		},
 		methods: {
 			clickLookPackage() {
-				wx.switchTab({
-					url: '/pages/packageCenter/packageCenter'
+				wx.navigateTo({
+					url: '/pages/batteryPackage/batteryPackage'
 				})
 			},
 			clickMyPackage() {
@@ -224,6 +226,7 @@
 				})
 			},
 			async sacnBtn() {
+				
 				const user_token = storage.getUserToken()
 				if (!user_token) {
 					this.loadIsLogin()
@@ -231,41 +234,42 @@
 				}
 				await this.loadBatteryInfo()
 				
-				if(this.listData.can_exchange_num == 0){
-					this.isModelCenter = true
-					this.packType = 2
-					return
-				}
-				if((this.listData.user_battery_list.length - this.listData.can_exchange_num) >= 0 && this.listData.can_exchange_num != -1){
-					common.simpleToast('您的次数不足无法换电!')
+				if(this.isTagCodeFn().length < 1){
+					common.simpleToast('未找到可更换的电池!')
 					return
 				}
-				if(this.isTagCodeFn().length < 1){
-					common.simpleToast('未找到和您匹配的电源!')
+				if((this.listData.user_battery_list.length - this.listData.can_exchange_num) <= 0 && this.listData.can_exchange_num === 0 && this.listData.can_exchange_num != -1){
+					this.packType = 0
+					this.isModelCenter = true
 					return
 				}
+				uni.showLoading({
+					title:' 加载中...'
+				})
+				uni.hideLoading()
 				let res = await uni.scanCode({
 					onlyFromCamera: true,
 					scanType: ['qrCode'],
 				});
+				
 				var cabinet_dev_id = '';
 				if(res[0]) return
 				res = res[1]
 				this.loadGeneralQRData(res)
 				
-				if ('path' in res && res.path) {
-					if (res.path.split('%26devid%3D').length > 1) {
-						cabinet_dev_id = res.path.split('%26devid%3D')[1].split('%26')[0];
-					} else if (res.path.split('&devid=').length > 1) {
-						cabinet_dev_id = res.path.split('&devid=')[1].split('&')[0];
-					}
-				}
-				if (cabinet_dev_id != '') {
-					this.scan_dev_id = cabinet_dev_id
-					this.loadNowCabinetDetail(cabinet_dev_id)
-				} else {
-					common.simpleToast("未找到相应的机柜")
-				}
+				// if ('path' in res && res.path) {
+				// 	if (res.path.split('%26devid%3D').length > 1) {
+				// 		cabinet_dev_id = res.path.split('%26devid%3D')[1].split('%26')[0];
+				// 	} else if (res.path.split('&devid=').length > 1) {
+				// 		cabinet_dev_id = res.path.split('&devid=')[1].split('&')[0];
+				// 	}
+				// }
+				// if (cabinet_dev_id != '') {
+				// 	this.scan_dev_id = cabinet_dev_id
+				// 	this.loadNowCabinetDetail(cabinet_dev_id)
+				// } else {
+				// 	common.simpleToast("未找到相应的机柜")
+				// }
 				
 			},
 			sacnBtnReturn() {

+ 6 - 6
component/uploader/uploader.css

@@ -10,8 +10,8 @@
 }
 
 .list-item {
-	width: 206rpx;
-	height: 206rpx;
+	width: 200rpx;
+	height: 200rpx;
 	background-color: #F4F5F6;
 	border-radius: 16rpx;
 	display: flex;
@@ -23,14 +23,14 @@
 }
 
 .img-item {
-    width: 206rpx;
-    height: 206rpx;
+    width: 200rpx;
+    height: 200rpx;
     background-color: #fff;
 	border-radius: 16rpx;
 }
 .img-item-demo {
-    width: 206rpx;
-    height: 206rpx;
+    width: 200rpx;
+    height: 200rpx;
     background-color: #fff;
 	border-radius: 16rpx;
 	/* 翻转图片的颜色 */

+ 3 - 4
component/uploaders/uploaders.vue

@@ -1,10 +1,10 @@
 <template>
-	<view class="container">
+	<view >
 		<view class="list-group">
 			<view class="list-item" @longpress="bindDelImage" :data-idx="index"
 				v-for="(item, index) in imgList" :key="item.unique">
 				<!-- <image  class="img-item-demo" :src="item.url"></image> -->
-				<image  class="img-item" :src="item.url" mode="aspectFill"></image>
+				<image  class="img-item" :src="item.url" mode="aspectFit"></image>
 				<!-- <view class="img_text">{{ item.title? item.title : '车辆照片'}}</view> -->
 			</view>
 			<view v-if="imgList.length < max" class="list-item" @tap="bindUpImg">
@@ -12,7 +12,6 @@
 				<view class="empity-item">+</view>
 			</view>
 		</view>
-
 	</view>
 </template>
 
@@ -57,7 +56,7 @@ import upload from './upload.js';
 					const imgList = res[1].tempFilePaths
 					let data = await upload.uploadFile(imgList)
 					this.imgList = this.imgList.concat(data)
-					this.updateImages(data)
+					this.updateImages(this.imgList)
 				}
 			},	
 			

+ 152 - 0
components/navBar/navigation.vue

@@ -0,0 +1,152 @@
+<template>
+		<view class="top-view flex-row"
+			:style="{'padding-top':`${statusBarHeight1}px`,background:`rgba(255,255,255,${opacity})`}">
+			<view class="navHei" :style="{'height':`calc(${navabarHeight}rpx)`,'width':'100%',}">
+				<view v-if="isback" class="left" @tap="bindReturnView">
+					<view class="pos">
+						<view   class="car-detail-style">
+							<image  class="return-view"
+								src="https://qiniu.bms16.com/FnHXbzly7aXi8zLghrTU5BZdwH5_" mode="aspectFit"></image>
+						</view>
+						<view :style="{opacity:1 - opacity,background:`rgba(0,0,0,0.4)`}" class="car-detail-style">
+							<image  class="return-view"
+								src="https://qiniu.bms16.com/Fjpnr3cH9ZqTQrGlw3Ywp3qbJGIG" mode="aspectFit"></image>
+						</view>
+					</view>
+				</view>
+				<text class="top-text">{{name}}</text>
+			</view>
+		</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			isback:{
+				type: Boolean,
+				default: true
+			},
+			name: {
+				type: String,
+				default: ''
+			},
+			scroll: {
+				default: 0,
+				type: Number
+			}
+		},
+		watch: {
+			scroll(n) {
+				this.opacity = n / 160
+			}
+		},
+		data() {
+			return {
+				opacity: 0,
+				statusBarHeight1: 0,
+				navabarHeight: 0,
+			}
+		},
+		mounted() {
+			this._getCustomBar()
+			this.opacity = this.scroll
+		},
+		methods: {
+			_getCustomBar() {
+				const sysinfo = uni.getSystemInfoSync()
+				// let GAP = 8
+				// // #ifdef MP-ALIPAY
+				// GAP = 0
+				// // #endif
+				// // #ifdef APP-PLUS
+
+				// // #endif
+				// // #ifdef MP-WEIXIN
+				// const clientRect = uni.getMenuButtonBoundingClientRect()
+				// const navabarHeight = (clientRect.bottom - sysinfo.statusBarHeight) + (clientRect.top - sysinfo.statusBarHeight) + GAP
+				// this.navabarHeight = navabarHeight
+				// // #endif
+
+				this.statusBarHeight1 = sysinfo.statusBarHeight
+				this.navabarHeight = 100
+			},
+
+			bindReturnView() {
+				uni.navigateBack({
+					delta: 1,
+				}) // 返回上一页
+			},
+		}
+	}
+</script>
+
+<style scoped>
+	.navHei {
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		position: relative;
+	}
+
+	.left {
+		width: 40rpx;
+		height: 40rpx;
+		position: absolute;
+		left: 0;
+	}
+
+	.top-view {
+		width: 100%;
+		position: fixed;
+		z-index: 99999;
+		left: 0;
+		top: 0;
+		align-items: center;
+		padding: 0 26rpx;
+		text-align: center;
+
+	}
+
+	.navHei {
+		position: relative;
+		width: 56rpx;
+		height: 56rpx;
+	}
+
+	.return-view {
+		width: 40rpx;
+		height: 40rpx;
+		
+		/* margin-top: 24rpx; */
+		/* 		margin-left: 32rpx; */
+	}
+
+	.top-text {
+		color: #060809;
+		font-size: 36rpx;
+		font-weight: 600;
+		line-height: 36rpx;
+		text-align: center;
+		font-style: normal;
+		font-family: PingFangSC, PingFang SC;
+	}
+
+	.view-height {
+		/* border-bottom:2rpx solid #060809 ; */
+		/* margin-bottom: 32rpx; */
+	}
+
+	.car-detail-style {
+		width: 56rpx;
+		height: 56rpx;
+		
+		border-radius: 16rpx 0rpx 16rpx 0rpx;
+		padding-left: 6rpx;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		position: absolute;
+		left: 0;
+		top: 0;
+	}
+</style>

+ 185 - 0
components/toggle-switch/toggle-switch.vue

@@ -0,0 +1,185 @@
+<template>
+	<view class="switch-container" :style="containerStyle" @click="handleClick">
+		<!-- 状态文字 -->
+		<text class="status-text" :style="[statusTextStyle, leftTextStyle]">{{ activeText }}</text>
+		<text class="status-text" :style="[statusTextStyle, rightTextStyle]">{{ inactiveText }}</text>
+		<!-- 图片滑块 -->
+		<image class="switch-thumb" :src="currentThumb" :style="thumbStyle" @touchstart="onTouchStart"
+			@touchmove="onTouchMove" @touchend="onTouchEnd" />
+	</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			value: Boolean,
+			containerWidth: {
+				type: Number,
+				default: 120
+			},
+			thumbSize: {
+				type: Number,
+				default: 32
+			},
+			// 新增图片相关props
+			activeThumb: {
+				type: String,
+				default: '' // 建议使用绝对路径
+			},
+			inactiveThumb: {
+				type: String,
+				default: ''
+			},
+			// 状态文字配置
+			activeText: {
+				type: String,
+				default: 'ON'
+			},
+			inactiveText: {
+				type: String,
+				default: 'OFF'
+			},
+			activeColor: {
+				type: String,
+				default: 'ffffff'
+			},
+			inactiveColor: {
+				type: String,
+				default: 'ffffff'
+			},
+			textColor: {
+				type: String,
+				default: '#000000'
+			}
+		},
+		data() {
+			return {
+				isDragging: false,
+				startX: 0,
+				currentX: 0,
+				maxOffset: 0
+			};
+		},
+		computed: {
+			currentThumb() {
+				// return this.value ? this.activeThumb : this.inactiveThumb;
+				return 'https://qiniu.bms16.com/Fkovrpq1bexe-Unal_VJREbLUhdu';
+			},
+			containerStyle() {
+				return {
+					width: this.containerWidth + 'px',
+					backgroundColor: this.value ? this.activeColor : this.inactiveColor,
+					height: this.thumbSize + 8 + 'px',
+					borderRadius: (this.thumbSize + 8) / 2 + 'px'
+				}
+			},
+			thumbStyle() {
+				const baseStyle = {
+					width: this.thumbSize + 'px',
+					height: this.thumbSize + 'px',
+					borderRadius: this.thumbSize / 2 + 'px'
+				};
+
+				if (this.isDragging) {
+					return {
+						...baseStyle,
+						transform: `translateX(${this.currentX}px)`,
+						transition: 'none'
+					};
+				}
+
+				return {
+					...baseStyle,
+					transform: `translateX(${this.value ? this.maxOffset : 0}px)`,
+					transition: 'transform 0.3s cubic-bezier(0.3, 1, 0.3, 1)'
+				};
+			},
+			statusTextStyle() {
+				return {
+					color: this.textColor,
+					fontSize: this.thumbSize * 0.5 + 'px',
+					opacity: this.isDragging ? 0.6 : 1
+				}
+			},
+			leftTextStyle() {
+				return {
+					right: (this.thumbSize + 20) + 'px',
+					opacity: this.value ? 1 : 0
+				}
+			},
+			rightTextStyle() {
+				return {
+					left: (this.thumbSize + 20) + 'px',
+					opacity: this.value ? 0 : 1
+				}
+			}
+		},
+		mounted() {
+			//计算滑块(thumb)在滑动轨道(container)上的最大偏移量。
+			this.maxOffset = this.containerWidth - this.thumbSize - 4;
+		},
+		methods: {
+			handleClick() {
+				//点击立即切换状态
+				if (!this.isDragging) {
+					this.toggleState();
+				}
+			},
+			onTouchStart(e) {
+				this.isDragging = true;
+				this.startX = e.touches[0].pageX;
+				this.currentX = this.value ? this.maxOffset : 0;
+			},
+			onTouchMove(e) {
+				if (!this.isDragging) return;
+				const deltaX = e.touches[0].pageX - this.startX;
+				let newX = this.value ? this.maxOffset + deltaX : deltaX;
+
+				// 限制滑动范围
+				newX = Math.max(0, Math.min(newX, this.maxOffset));
+				this.currentX = newX;
+			},
+			toggleState() {
+				this.$emit('input', !this.value);
+				this.$emit('change', !this.value);
+			},
+			onTouchEnd() {
+				this.isDragging = false;
+				// 判断滑动是否超过50%
+				const threshold = this.containerWidth * 0.5;
+				const newState = this.currentX > threshold - this.thumbSize / 2;
+				if (newState !== this.value) {
+					this.toggleState();
+				} else {
+					this.currentX = this.value ? this.maxOffset : 0;
+				}
+			}
+		}
+	};
+</script>
+
+<style scoped>
+	.switch-container {
+		position: relative;
+		display: flex;
+		align-items: center;
+		transition: background-color 0.3s;
+		box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
+	}
+
+	.switch-thumb {
+		position: absolute;
+		top: 4px;
+		left: 4px;
+		z-index: 2;
+		box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
+	}
+
+	.status-text {
+		position: absolute;
+		z-index: 1;
+		font-weight: bold;
+		transition: opacity 0.3s;
+		pointer-events: none;
+	}
+</style>

+ 16 - 16
js_sdk/wa-permission/permission.js

@@ -444,9 +444,9 @@ function openGeneralSettings() {
     main.startActivity(intent);
 }
 
-async function getBondedDevices() {
+function getBondedDevices() {
   // #ifdef APP-PLUS
-  try {
+
 	// 检查蓝牙是否可用
 	const BluetoothAdapter = plus.android.importClass('android.bluetooth.BluetoothAdapter');
 	const bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
@@ -470,10 +470,9 @@ async function getBondedDevices() {
 	//   address: plus.android.invoke(device, 'getAddress'),
 	//   type: getDeviceType(plus.android.invoke(device, 'getBluetoothClass'))
 	// }));
-	const app = getApp()
-	const car_info = uni.getStorageSync('car_info') ||{}
-	const car_sn=car_info.car_sn
-	let deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == car_sn);
+	const app = getApp();
+	const car_sn=  uni.getStorageSync('car_info').car_sn
+	const deviceId =app.globalData.connectionState[car_sn].deviceId
 	if(!deviceId) return false
 	//配对配对蓝牙设备是否在蓝牙列表里面
 	deviceArray.map(device => {
@@ -482,16 +481,7 @@ async function getBondedDevices() {
 		}
 	});
 	return isPaired
-  } catch (e) {
-	console.error('获取蓝牙设备失败:', e);
-	// uni.showToast({ title: '获取设备列表失败', icon: 'none' });
-	return false;
-  }
-  // #endif
-  
-  // #ifndef APP-PLUS
-  console.warn('此方法仅支持APP平台');
-  return false;
+
   // #endif
 }
 
@@ -505,6 +495,14 @@ function getDeviceType(bluetoothClass) {
 //设备蓝牙权限是否开启
 function checkBluetoothPermission() {
     // #ifdef APP-PLUS
+	if (isIos) {
+        // iOS 平台蓝牙权限检查
+        // iOS 平台没有独立的蓝牙权限,但需要检查定位权限是否开启
+        // 因为在 iOS 上,蓝牙扫描需要定位权限
+        return judgeIosPermissionLocation();
+    } else {
+        // 安卓平台蓝牙权限检查
+        // #ifdef APP-PLUS
         // 检查蓝牙是否可用
         const BluetoothAdapter = plus.android.importClass('android.bluetooth.BluetoothAdapter');
         const bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
@@ -522,6 +520,8 @@ function checkBluetoothPermission() {
 
         console.log('蓝牙已启用');
         return true;
+        // #endif
+    }
     // #endif
 }
 

+ 1 - 1
locale/zh.json

@@ -54,7 +54,7 @@
 	"重置密码邮件已发送":"重置密码邮件已发送",
 	"我知道了":"我知道了",
 	"请输入有效的邮箱地址":"请输入有效的邮箱地址",
-	"欢迎来到智寻出行":"欢迎来到智寻出行",
+	"欢迎来到FRANCO MORINI":"欢迎来到FRANCO MORINI",
 	"请输入邮箱账号":"请输入邮箱账号",
 	"请输入密码":"请输入密码",
 	"已阅读并同意":"已阅读并同意",

+ 4 - 0
main.js

@@ -15,6 +15,9 @@ Vue.use(uView)
 import gyq_utils from '@/utils/gyq_utils'
 Vue.use(gyq_utils)
 
+import Navigation from '@/components/navBar/navigation.vue'
+Vue.component('Navigation', Navigation);
+
 uni.addInterceptor('request', {
 	fail: (err) => {
 		uni.hideLoading()
@@ -22,6 +25,7 @@ uni.addInterceptor('request', {
 	}
 });
 import Vue from 'vue';
+
 Vue.mixin(Mixin);
 Vue.mixin(mixins);
 Vue.config.productionTip = false;

+ 16 - 11
manifest.json

@@ -2,8 +2,8 @@
     "name" : "FRANCO MORINI",
     "appid" : "__UNI__111A022",
     "description" : "",
-    "versionName" : "1.3.7",
-    "versionCode" : 137,
+    "versionName" : "1.3.8",
+    "versionCode" : 138,
     "transformPx" : false,
     "loadnativePlugins" : false,
     "sassImplementationName" : "node-sass",
@@ -23,12 +23,12 @@
         "modules" : {
             "Bluetooth" : {},
             "Geolocation" : {},
-            "Maps" : {},
             "Barcode" : {},
             "Camera" : {},
             "OAuth" : {},
             "Contacts" : {},
-            "iBeacon" : {}
+            "iBeacon" : {},
+            "Maps" : {}
         },
         "distribute" : {
             "android" : {
@@ -61,7 +61,10 @@
                 "minSdkVersion" : 21
             },
             "ios" : {
-                "dSYMs" : false
+                "dSYMs" : false,
+                "privacyDescription" : {
+                    "NSPhotoLibraryUsageDescription" : ""
+                }
             },
             "sdkConfigs" : {
                 "ad" : {},
@@ -77,16 +80,18 @@
                 },
                 "maps" : {
                     "google" : {
-                        "APIKey_ios" : "AIzaSyAyfZx9Stm7rx5KbOGH5e1mgT-84EWvb7Q",
+                        "APIKey_ios" : "AIzaSyCaQ8pXdHqsgQmUbKNyGOTyyRMhN0cgoTI",
                         "APIKey_android" : "AIzaSyAyfZx9Stm7rx5KbOGH5e1mgT-84EWvb7Q"
                     }
                 },
-                "oauth" : {},
+                "oauth" : {
+                    "google" : {
+                        "clientid" : "994756703987-u1eq1bun35uifcp2sbh9mjc9bb59gu2v.apps.googleusercontent.com"
+                    }
+                },
                 "geolocation" : {
-                    "amap" : {
-                        "__platform__" : [ "ios", "android" ],
-                        "appkey_ios" : "unknown",
-                        "appkey_android" : "255bc0dfb27a04f9c4aaacf0fd80cff8"
+                    "system" : {
+                        "__platform__" : [ "ios", "android" ]
                     }
                 },
                 "share" : {

+ 95 - 106
mixin/index.js

@@ -1,126 +1,113 @@
 // mixins/countdownMixin.js
 var bluetooth = require('@/common/bluetooth.js');
-import {
-	getFunctionTag,
-	setFunctionTag,
-	getUserCurrentLocation
-} from '@/common/storage.js';
-var app = getApp();
+import {getFunctionTag,setFunctionTag,getUserCurrentLocation} from '@/common/storage.js';
+
 var config = require('@/common/config.js');
 var common = require('@/common/common.js');
 var http = require('@/common/http.js');
 import i18n from '@/locale/index.js'
 export default {
-	data() {
-		return {
-			myLocation:{},
-			carOnline: false,
-			statusBarHeight: 0,
-			popText: '',
-			cmdType: '',
-			popupControlShow: false
-		};
-	},
-	onLoad(){
-		this.myLocation = getUserCurrentLocation()
-		this.locationMixin()
-		this.checkLocationPermission()
-	},
-	mounted() {
-		this.statusBarHeight = uni.getSystemInfoSync().statusBarHeight || 0
-	},
-	methods: {
-		async locationMixin(){
-			let data = await this.$location()
-			this.myLocation = {
-				longitude: data.longitude,
-				latitude: data.latitude
-			}
-		},
-		async checkLocationPermission() {
-			let data = await this.$checkLocationPermission()
-			console.log('权限获取')
-			console.log(data)
-		},
-		tapOpenControl(e) {
-			const _carOnline = uni.getStorageSync('car_info').online != 0 //在线
+  data() {
+    return {
+		scrollTop: 0,
+      carOnline: false, 
+	  statusBarHeight:0,
+	  popText:'',
+	  cmdType:'',
+	  myLocation:{},
+	  popupControlShow:false
+    };
+  },
+  onLoad(){
+	 this.myLocation = getUserCurrentLocation()
+	 this.locationMiXin()
+  },
+   mounted(){
+  	  this.statusBarHeight = uni.getSystemInfoSync().statusBarHeight || 0
+  },
+  methods: {
+	  async locationMiXin(){
+		  let myLocation = await this.$location()
+		   this.myLocation = {
+			   latitude:`${myLocation.latitude}`,
+			   longitude:`${myLocation.longitude}`,
+		   }
+	  },
+		tapOpenControl(e){
+			const _carOnline= uni.getStorageSync('car_info').online != 0 //在线
 			console.log(this.popupControlShow);
-			const {
-				name,
-				type
-			} = e
+			const {name,type}=e
 			this.setData({
-				carOnline: _carOnline,
-				popText: name,
-				cmdType: type,
-				popupControlShow: true
+				carOnline:_carOnline,
+				popText:name,
+				cmdType:type,
+				popupControlShow:true
 			})
 			console.log(this.popupControlShow);
 		},
-		changClick(tab) {
-			const typeArr = ['tirePressure', 'batteryInfo', 'navigation']
-			const isOther = typeArr.findIndex(t => t === tab.type) !== -1
-			console.log('isOther', isOther);
-			if (isOther) {
-				const {
-					name,
-					type
-				} = tab
+		changClick(tab){
+			const typeArr=['tirePressure','batteryInfo','navigation']
+			const isOther=typeArr.findIndex(t => t === tab.type)!==-1
+			console.log('isOther',isOther);
+			if(isOther){
+				const {name,type}=tab
 				this.setData({
-					popText: name,
-					cmdType: type,
+					popText:name,
+					cmdType:type,
 				})
 				this.tapBlueToothCmd()
-			} else {
+			}else{
 				this.tapOpenControl(tab)
 			}
 		},
-		closePopup() {
-			this.popupControlShow = false
+		closePopup(){
+			this.popupControlShow=false
 		},
-		tapBlueToothCmd(_,type){
+		tapBlueToothCmd(cmd,type){
 			const car_info= uni.getStorageSync('car_info');
-			const isCarLocation = type
+			const isCarLocation = (cmd=='more')?true:type
 			if(this.cmdType=='batteryInfo'){
 				uni.navigateTo({
-					url: `/pages/batteryDetail/batteryDetail`
+					url:`/pages/batteryDetail/batteryDetail`
 				})
-			} else if (this.cmdType == 'navigation') {
+			}else if(this.cmdType=='navigation'){
 				const {
 					address,
 					latitude,
 					longitude,
 					car_name
-				} = car_info
+				} =car_info
 				uni.openLocation({
 					latitude: latitude - 0,
 					longitude: longitude - 0,
 					scale: 15,
 					name: car_name,
 					address: address,
-					success: function(res) {},
+					success: function (res) {},
 				})
 				//获取胎压
-			} else if (this.cmdType == 'tirePressure') {
+			}else if(this.cmdType=='tirePressure'){
 				this.bluetoothCmd()
-			} else {
+			}else{
 				// 判断车辆是否在线状态 true 在线调用接口 不在线提示连接蓝牙
 				if (this.carOnline) {
 					if (this.cmdType == 'turnOnOrOff') {
-						const switchType = this.contrilList.find(item => item.isTurnOn)
+						const switchType = this.contrilList.find(item => item.isTurnOn).isTurnOn
 						const pData = {
 							car_sn: car_info.car_sn,
 							switch: switchType
 						}
-						const me = this
+						const me=this
 						common.loading();
 						http.postApi(config.API_FLK_CAR_SWITCH, pData, (resp) => {
 							uni.hideLoading();
 							if (resp.data.code === 200) {
 								common.simpleToast(me.popText + '成功');
 								const activeTag = me.contrilList.map(item => {
-									item.isTurnOn = (item.isTurnOn == 1) ? 0 : 1
-									item.name = i18n.t((item.isTurnOn == 1) ? '关机' : '开机')
+									if('isLock' in item){
+										item.isTurnOn = (item.isTurnOn == 1) ? 0 : 1
+										item.name = i18n.t((item.isTurnOn == 1) ? '关机' : '开机')
+									}
 									return item
 								})
 								const tag = getFunctionTag().tag
@@ -128,29 +115,21 @@ export default {
 									activeTag,
 									tag
 								})
-
+								me.$emit('loadCarDetail',pData,car_sn)
 							} else {
 								common.simpleToast(resp.data.msg);
 							}
 						});
-					} else {
-						const testArr = [{
-								type: 'findCar',
-								opt_type: 1
-							},
-							{
-								type: 'openSeatBag',
-								opt_type: 0
-							},
-							{
-								type: 'openTailBox',
-								opt_type: 2
-							},
-						]
-						const pData = testArr.find(i => i.type === this.cmdType)
-						const me = this
+					}else{
+						const testArr=[
+							{type:'findCar',opt_type:1},
+							{type:'openSeatBag',opt_type:0},
+							{type:'openTailBox',opt_type:2},
+							]
+						const pData = testArr.find(i=>i.type===this.cmdType)
+						const me=this
 						common.loading();
-						http.postApi(config.API_FLK_CAR_REMOTE_CONTROL, pData, (resp) => {
+						http.postApi(config.API_FLK_CAR_REMOTE_CONTROL, {...pData,car_sn: car_info.car_sn}, (resp) => {
 							uni.hideLoading();
 							if (resp.data.code === 200) {
 								common.simpleToast(me.popText + '成功');
@@ -163,18 +142,19 @@ export default {
 					this.bluetoothCmd(isCarLocation)
 				}
 			}
-			this.popupControlShow = false
+			this.popupControlShow=false
 		},
-		bluetoothCmd(isCarLocation) {
-			const me = this
-			const car_info = uni.getStorageSync('car_info');
+		bluetoothCmd(isCarLocation){
+			const me=this
+			const car_info= uni.getStorageSync('car_info');
+			const app = getApp();
 			//蓝牙是否已经连接 未连接提示去连接 已连接下发对应指令
 			const isBluetoothConnect = app.globalData.nearLockCheck
 			if(isBluetoothConnect){
+				//改成判断开关锁
 				const isTurnOn=this.contrilList.find(item => item.isTurnOn).isTurnOn==1
-				console.log(isTurnOn,this.cmdType,this.contrilList);
 				const bluetoothCommands = {
-					'turnOnOrOff': isTurnOn ? bluetooth.turnOnCar : bluetooth.turnOffCar,
+					'turnOnOrOff': isTurnOn?bluetooth.turnOnCar:bluetooth.turnOffCar,
 					'findCar': bluetooth.findCarCmd,
 					'openSeatBag': bluetooth.openCarSeat,
 					'openTailBox': bluetooth.openCarTrunk,
@@ -186,13 +166,13 @@ export default {
 				if (command) {
 					command(car_sn, () => {
 						uni.hideLoading();
-						if (this.cmdType == 'openSeatBag' || this.cmdType == 'openTailBox') {
+						if(this.cmdType=='openSeatBag'||this.cmdType=='openTailBox'){
 							common.simpleToast('操作成功');
 						}
 						console.log(`发送${this.popText}指令结束`);
 					});
 				}
-			} else {
+			}else{
 				uni.showModal({
 					title: '提示',
 					content: '当前车辆处于离线,是否前往开启蓝牙配对操作车辆?',
@@ -201,22 +181,31 @@ export default {
 					confirmText: '确定',
 					success: function(res) {
 						if (res.confirm) {
-							console.log(isCarLocation,'test111');
 							if(isCarLocation){
 								uni.switchTab({
-									url: '/pages/index/index'
+									url:'/pages/index/index'
 								})
-							} else {
+							}else{
 								me.$emit('toBluetooth')
 							}
-
+							
 						}
 					},
 					fail: function(res) {},
 					complete: function(res) {},
 				})
 			}
-		}
+		},
+		// async loadData() {
+		// 				return new Promise((resolve) => {
+		// 					// setTimeout(resolve, 1000); // 模拟 5 秒请求时间
+		// 					// this.trunOn(resolve)
+		// 				});
+		// 			},
+
 	},
-	beforeDestroy() {},
-};
+
+ 
+  beforeDestroy() {
+  },
+};

+ 1 - 0
package.json

@@ -30,6 +30,7 @@
     },
     "dependencies": {
         "@amap/amap-jsapi-loader": "^1.0.1",
+        "@googlemaps/js-api-loader": "^1.16.8",
         "crypto-js": "^4.2.0",
         "dayjs": "^1.11.13",
         "echarts": "^5.6.0",

+ 1 - 1
pages.json

@@ -67,7 +67,7 @@
 			}
 		},
 		{
-			"path": "pages/message/deviceInfo",
+			"path": "pages/message/detail",
 			"style": {
 			}
 		},

+ 1 - 1
pages/aboutMy/aboutMy.vue

@@ -2,7 +2,7 @@
 	<view class="container">
 		<navBar name="关于我们"></navBar>
 		<view class="header_view flex-row flex-column">
-			<image class="header_img" :src="app_logo" mode="aspectFill"></image>
+			<image class="header_img" :src="app_logo" mode="aspectFit"></image>
 			<view class="header_title">{{appName}}</view>
 			<view class="version">{{"V " + app_version}}</view>
 		</view>

+ 0 - 1
pages/activation/activation.css

@@ -36,7 +36,6 @@
 	border-radius: 40rpx;
 	padding-top: 12rpx;
 	padding-bottom: 12rpx;
-	width: 208rpx;
 	text-align: center;
 }
 

+ 163 - 23
pages/activation/activation.vue

@@ -1,10 +1,9 @@
 <template>
 	<view class="">
-		<navBar name="我的订单" left="0"></navBar>
+		<navBar :name="typePage=='index'?'归还车辆':'车辆激活'" left="0"></navBar>
 		<view class="container-view">
 			<view class="return-info">
 				<view class="h5">车辆信息</view>
-		
 				<view v-if="overdueMoney" class="return-top  flex-row flex-between">
 					<view style="align-items: baseline;" class="flex-row">逾期费用:
 						<allPrice :amount="(overdueMoney/100)" />
@@ -13,6 +12,15 @@
 				<view class="return-top  flex-row flex-between">
 					<view>车辆编号:{{car_sn}}</view>
 				</view>
+				<view class="return-top  flex-row flex-between">
+					<view>车辆品牌:{{carInfoData.brand_name}}</view>
+				</view>
+				<view class="return-top  flex-row flex-between">
+					<view>车辆颜色:{{carInfoData.color_name}}</view>
+				</view>
+				<view v-if="carInfoData.license_plate_number" class="return-top  flex-row flex-between">
+					<view>车牌号:{{carInfoData.license_plate_number}}</view>
+				</view>
 				<view class="return-top  flex-row flex-between">
 					<view>车辆名称:{{carInfoData.car_name}}</view>
 				</view>
@@ -20,14 +28,18 @@
 					<view>车型:{{carInfoData.model_name}}</view>
 				</view>
 				<view class="return-top  flex-row flex-between">
-					<view>续航:{{carInfoData.endurance}}m</view>
+					<view>续航:{{(carInfoData.endurance / 1000).toFixed(2)}}km</view>
 				</view>
 				<view class="return-top  flex-row flex-between">
-					<view>重量:{{carInfoData.weight}}kg</view>
+					<view>重量:{{(carInfoData.weight / 1000).toFixed(2)}}kg</view>
 				</view>
+				
 				<view class="return-top  flex-row ">
 					<view>照片:</view>
-					<image class="img" :src="carInfoData.model_images" mode="aspectFill"></image>
+					<view style="display: flex;align-items: center;" class="">
+						<image style="margin-right: 10rpx;" v-for="(item,index) of carInfoData.model_images"
+							:key="index" class="img" :src="item" mode="aspectFit"></image>
+					</view>
 				</view>
 			</view>
 			<view v-if="shopInfo.shop_name" class="return-info">
@@ -40,23 +52,27 @@
 				</view>
 			</view>
 			<view class="pictures-info">
-				<view>车辆照片</view>
+				<view>上传照片</view>
 				<!-- <view>这里是关于激活车辆照片的文案描述,这里是关于激活车辆照片的文案描述</view> -->
-				<uploaders :max="Number(shopList.flk_hire_car_img_num)" :car_info="car_imgs"
-					@update-car-images="handleCarImagesUpdate"></uploaders>
+				<!-- <uploaders :max="Number(shopList.flk_hire_car_img_num)" :car_info="car_imgs"
+					@update-car-images="handleCarImagesUpdate"></uploaders> -->
+				<view class="list-group">
+					<view class="list-item" @click="bindUpImg(index)" @longpress="bindDelImage(index)" :data-idx="index" v-for="(item, index) in shopList.flk_hire_return_car_img"
+						:key="item.unique">
+						<image v-if="!item.imgUrl"  class="img-item-demo" :src="item.url"></image>
+						<image v-else class="img-item" :src="item.imgUrl" mode="aspectFit"></image>
+						<view class="img_text">{{ item.title? item.title : '车辆照片'}}</view>
+						<view v-if="!item.imgUrl" class="empity-item">+</view>
+					</view>
+				</view>
 				<view v-if="isReturnCar" @tap="submitReturn" class="pictures-btn">归还车辆</view>
 				<view v-else @tap="submitEnabled" class="pictures-btn">激活车辆</view>
 			</view>
-		
 			<PayTypeModel @closeShow="()=>isShowToBuy=false" @payToOrder="payToOrder" :free_price="totalPrice"
 				:isShowToBuy="isShowToBuy" />
 		</view>
-		
 	</view>
-	
-
 </template>
-
 <script>
 	import uploaders from '@/component/uploaders/uploaders';
 	const http = require('@/common/http.js');
@@ -66,6 +82,7 @@
 	const common = require('@/common/common.js');
 	import PayTypeModel from '@/component/payTypeModel/payTypeModel';
 	import allPrice from '@/component/allPrice/allPrice';
+	import upload from '@//component/uploaders/upload.js.js';
 	export default {
 		components: {
 			uploaders,
@@ -74,6 +91,7 @@
 		},
 		data() {
 			return {
+				imgList:[],
 				totalPrice: 0,
 				isShowToBuy: false,
 				myLocation: {},
@@ -93,7 +111,8 @@
 				return_imgs: [],
 				car_imgs: [],
 				model_image_list: '',
-				_image_list: []
+				_image_list: [],
+				typePage:''
 			};
 		},
 		/**
@@ -101,7 +120,6 @@
 		 */
 		onLoad: function(options) {
 			this.locationFn()
-			console.log(options, 'options');
 			this.isReturnCar = options.isReturnCar
 			if (options.isReturnCar) {
 				uni.setNavigationBarTitle({
@@ -112,6 +130,7 @@
 			this.sub_sn = options.sub_sn || ''
 			this.model_id = options.model_id || ''
 			this.car_sn = options.car_sn || ''
+			this.typePage = options.type || ''
 			if (options.overdueMoney == 'undefined' || !options.overdueMoney) {
 				this.overdueMoney = 0
 			} else {
@@ -136,6 +155,33 @@
 		onShow: function() {},
 		onUnload: function() {},
 		methods: {
+			async bindDelImage(index){
+				let res = await uni.showModal({
+					title: '提示',
+					content: '你确定要删除吗?',
+					showCancel: true,
+				})
+				if (res[1].confirm) {
+					this.shopList.flk_hire_return_car_img[index].imgUrl = ''
+					this.$forceUpdate()
+				}
+			},
+			async bindUpImg(index) {
+				let res = await uni.chooseImage({
+					count: 1,
+				})
+				if(res[1]){
+					const imgList = res[1].tempFilePaths
+					let data = await upload.uploadFile(imgList)
+					this.shopList.flk_hire_return_car_img[index].imgUrl = data[0].url
+					this.$forceUpdate()
+					// this.imgList = this.imgList.concat(data)
+					// this.updateImages(this.imgList)
+				}
+			},	
+			
+			
+			
 			async payToOrder(pay_type) {
 				let milliseconds = new Date().getTime();
 				const current_time = this.overdueTime ? this.overdueTime : parseInt(milliseconds / 1000);
@@ -177,17 +223,20 @@
 			},
 			//还车
 			async submitReturn() {
-				this._image_list = this.car_imgs.map(item => {
-					return item.url
+				this._image_list = this.shopList.flk_hire_return_car_img.map(item => {
+					return item.imgUrl
 				})
-				if (this._image_list.length < 1) return common.simpleToast('请上传车辆照片')
+				 this._image_list = this._image_list.filter(item=> {
+					if(item){
+						return item
+					}
+				})
+				if (this._image_list.length < this.shopList.flk_hire_return_car_img.length) return common.simpleToast('请上传车辆照片')
 				if (this.totalPrice > 0) {
 					this.isShowToBuy = true
 				} else {
 					this.payToOrder(1)
 				}
-
-
 			},
 			async shopInfoFn() {
 				let res = await uni.getLocation()
@@ -216,6 +265,24 @@
 				})
 				if (data.code == 200) {
 					this.shopList = data.data
+					if(this.shopList.flk_hire_return_car_img.length < this.shopList.share_car_max_user_num){
+						let num = this.shopList.share_car_max_user_num - this.shopList.flk_hire_return_car_img.length
+						for (let i = 0; i < num; i++) {
+							this.shopList.flk_hire_return_car_img.push({
+								url:"",
+								imgUrl:'',
+								title:''
+							})
+							
+						}
+					}
+					if(this.shopList.flk_hire_return_car_img.length > this.shopList.share_car_max_user_num){
+						let flk_hire_return_car_img = []
+						for (let i = 0; i < this.shopList.share_car_max_user_num; i++) {
+							let item = this.shopList.flk_hire_return_car_img[i]
+							this.shopList.flk_hire_return_car_img.push(item)
+						}
+					}
 				} else {
 					common.simpleToast(data.msg)
 				}
@@ -227,6 +294,7 @@
 					car_sn: this.car_sn
 				})
 				if (data.code == 200) {
+					data.data.model_images = data.data.model_images.split(',') || []
 					this.carInfoData = data.data
 				} else {
 					common.simpleToast(data.msg)
@@ -239,8 +307,13 @@
 
 			submitEnabled() {
 				const me = this
-				const _image_list = this.car_imgs.map(item => item.url)
-				if (_image_list.length < 1) return common.simpleToast('请上传车辆照片')
+				let _image_list =this.shopList.flk_hire_return_car_img.map(item => item.imgUrl)
+				_image_list = _image_list.filter(item=> {
+					if(item){
+						return item
+					}
+				})
+				if (_image_list.length < this.shopList.flk_hire_return_car_img.length) return common.simpleToast('请上传车辆照片')
 				const pData = {
 					car_sn: this.car_sn,
 					sub_sn: this.sub_sn,
@@ -263,6 +336,73 @@
 	};
 </script>
 
-<style>
+<style scoped>
 	@import './activation.css';
+	.list-group {
+	    display: flex;
+	    flex-direction: row;
+	    justify-content: flex-start;
+	    flex-wrap: wrap;
+	}
+	
+	.list-item {
+		width: 200rpx;
+		height: 200rpx;
+		background-color: #F4F5F6;
+		border-radius: 16rpx;
+		display: flex;
+		flex-direction: column;
+	    margin-right: 9rpx;
+	    margin-bottom: 10rpx;
+		position: relative;
+		align-items: center;
+	}
+	
+	.img-item {
+	    width: 200rpx;
+	    height: 200rpx;
+	    background-color: #fff;
+		border-radius: 16rpx;
+	}
+	.img-item-demo {
+	    width: 200rpx;
+	    height: 200rpx;
+	    background-color: #fff;
+		border-radius: 16rpx;
+		/* 翻转图片的颜色 */
+		filter: invert(30%); 
+		opacity: 0.8;
+	}
+	
+	
+	
+	.empity-item {
+		position: absolute;
+		/* #ifdef MP-ALIPAY */
+		top: 0.7rem;
+		left: 0.5rem;
+		/* #endif */
+		/* #ifdef MP-WEIXIN */
+		top: 10rpx;
+		left: 48rpx;
+		/* #endif */
+	
+	    color: #e6e6e6;
+	    font-size: 120rpx;
+	    text-align: center;
+	}
+	
+	.img_text {
+	    font-family: PingFangSC, PingFang SC;
+	    font-weight: 500;
+	    font-size: 24rpx;
+	    color: #fff;
+	    line-height: 24rpx;
+	    /* text-align: center; */
+	    font-style: normal;
+	    /* text-align: center; */
+	    position: absolute;
+	    bottom: 17rpx;
+	    /* left: 73rpx; */
+	}
 </style>

+ 22 - 29
pages/batteryDetail/batteryDetail.vue

@@ -1,56 +1,37 @@
 <template>
 	<view class="battery-detail-main">
 		<navBar name="电池信息"  bgColor="#CFD1DE"></navBar>
-		<view class=" quantity-count">65<text class="quantity-text">%</text></view>
-		<view class="battery-list-view">
+		<view class=" quantity-count">{{electricQuantity || 0}}<text class="quantity-text">%</text></view>
+		<view v-for="(item,index) of list" :key="index" class="battery-list-view">
 			<view class="battery-list flex-row flex-between">
-				<view class="battery-name">No.1电池</view>
-				<view class="battery-id">MAC ID:0168802221</view>
+				<view class="battery-name">No.{{index + 1}}电池</view>
+				<view class="battery-id">MAC ID:{{item.battery_sn}}</view>
 			</view>
 			<view class="flex-row flex-around">
 				<view class="battery-device-info">
-					<view class="quantity-info">44 <text class="quantity-text-1">%</text></view>
+					<view class="quantity-info">{{item.electric_quantity || 0}} <text class="quantity-text-1">%</text></view>
 					<view class="battery-info-text">剩余电量</view>
 				</view>
 				<view class="battery-device-info">
-					<view class="quantity-info">44 <text class="quantity-text-1">%</text></view>
+					<view class="quantity-info">{{(item.voltage).toFixed(2) || 0}}<text class="quantity-text-1"></text></view>
 					<view class="battery-info-text">电压</view>
 				</view>
 				<view class="battery-device-info">
-					<view class="quantity-info">44 <text class="quantity-text-1">%</text></view>
-					<view class="battery-info-text">温度</view>
-				</view>
-			</view>
-		</view>
-		<view class="battery-list-view">
-			<view class="battery-list flex-row flex-between">
-				<view class="battery-name">No.1电池</view>
-				<view class="battery-id">MAC ID:0168802221</view>
-			</view>
-			<view class="flex-row flex-around">
-				<view class="battery-device-info">
-					<view class="quantity-info">44 <text class="quantity-text-1">%</text></view>
-					<view class="battery-info-text">剩余电量</view>
-				</view>
-				<view class="battery-device-info">
-					<view class="quantity-info">44 <text class="quantity-text-1">%</text></view>
-					<view class="battery-info-text">电压</view>
-				</view>
-				<view class="battery-device-info">
-					<view class="quantity-info">44 <text class="quantity-text-1">%</text></view>
+					<view class="quantity-info">{{item.battery_temp[0] || 0}} <text class="quantity-text-1">℃</text></view>
 					<view class="battery-info-text">温度</view>
 				</view>
 			</view>
 		</view>
 	</view>
 </template>
-
 <script>
 	const http = require('../../common/request.js');
 	const config = require('../../common/config_gyq.js');
 	export default {
 		data() {
 			return {
+				electricQuantity:0,
+				car_sn:'',
 				list:[]
 			};
 		}
@@ -59,9 +40,21 @@
 		 */
 		,
 		onLoad: function(options) {
+			this.car_sn = uni.getStorageSync('car_info').car_sn || '';
+			this.batteryListFn()
 		},
 		methods: {
-
+			async batteryListFn(){
+				let {data} = await http.postApi(config.API_CAR_BATTERY_LIST,{car_sn:this.car_sn})
+				let electric_quantity = 0
+				data.data.list.map(item=>{
+					electric_quantity += Number(item.electric_quantity)
+				})
+				console.log((electric_quantity / data.data.list.length).toFixed(0))
+				this.electricQuantity = (electric_quantity / data.data.list.length).toFixed(0) || 0
+				this.electricQuantity = this.electricQuantity != 'NaN' ? this.electricQuantity : 0
+				this.list = data.data.list
+			}
 		}
 	};
 </script>

+ 2 - 1
pages/batteryPackage/batteryPackage.css

@@ -37,8 +37,9 @@
 	
 }
 .package-num{
-	font-size: 46rpx;
+	font-size: 40rpx;
 	margin-right: 2rpx;
+	margin-left: 6rpx;
 }
 .align-center{
 	align-items: center;

+ 12 - 7
pages/batteryPackage/batteryPackage.vue

@@ -1,19 +1,20 @@
 <template>
 	<view class="battery-package-main">
-		<navBar bgColor="transparent" name="换电套餐" />
+		<navBar bgColor="#fff" name="换电套餐" />
+		
 		<view class="package-icon-view flex-row">
 			<img src="https://qiniu.bms16.com/FqF7erLOB8OutmFnre7-mbTkwpZr" alt="">
 			<view class="package-icon-text flex-row">5秒换电,瞬间满电,畅享骑行新体验!</view>
 		</view>
 		<view v-for="(item,index) of list" @click="selectItem(item)" :key="index" class="package-list-view" :class="{'active' : item.package_code == form.package_code }">
 			<view class="package-num-view flex-row"><text class="package-num">{{item.total_day || 0}}</text> 天 <text
-					class="package-num">{{item.total_num || 0}}</text></view>
+					class="package-num">{{(item.total_num || 0)=== 0 ? '不限次数' : item.total_num + '次'}}</text></view>
 			<view class="flex-row flex-between align-baseline">
 				<view v-if="item.tag.child_tag_name" class="apply-battery">适用电池:<text class="apply-battery-num">{{ !!Number(item.tag.main_tag_name) ? item.tag.main_tag_name + "V" : item.tag.main_tag_name}}{{!!Number(item.tag.child_tag_name) ? item.tag.child_tag_name + "Ah" : item.tag.child_tag_name }}</text></view>
 				
 				<view v-else class="apply-battery">适用电池:<text class="apply-battery-num">{{ item.tag.main_tag_name }}</text></view>
 				<view class="flex-row align-baseline">
-					<text class="package-price">${{item.viewShowMoney || '0.00'}}</text>
+					<!-- <text class="package-price">${{item.viewShowMoney || '0.00'}}</text> -->
 					<text class="symbol-style">
 						<text>$</text>
 						<text style="font-size: 48rpx;">{{item.viewMoney || '0.00'}}</text>
@@ -46,7 +47,7 @@
 		<view style="height: 200rpx;">
 			
 		</view>
-		<view @click="isShowToBuy = true"  class="pay-btn">立即购买</view>
+		<view v-if="form.package_code" @click="isShowToBuy = true"  class="pay-btn">立即购买</view>
 		<payTypeModel @closeShow='isShowToBuy = false' :free_price='form.price' :isShowToBuy='isShowToBuy' @payToOrder='submit'></payTypeModel>
 	</view>
 </template>
@@ -94,14 +95,14 @@ import { fenToYuan, msg } from '../../utils/util.js';
 					data
 				} = await http.postApi(config.API_FLK_EXCHANGE_PACKAGE_PAY, this.form)
 				uni.hideLoading()
-				console.log(data)
 				if(data.code == 200){
 					uni.navigateTo({
-						url:`/pages/order/order`
+						url:`/pages/order/order?selectOrderType=0`
 					})
 				}else{
-					msg(res.data.msg)
+					msg(data.msg)
 				}
+				this.isShowToBuy = false
 			},
 			selectItem(item){
 				this.form.package_code = item.package_code
@@ -120,6 +121,10 @@ import { fenToYuan, msg } from '../../utils/util.js';
 						item.viewShowMoney = (item.show_money / 100).toFixed(2)
 						item.viewMoney = (item.money / 100).toFixed(2)
 					})
+					if(data.data.list.length > 0){
+						this.form.package_code = data.data.list[0].package_code
+						this.form.price = data.data.list[0].money
+					}
 					this.list = data.data.list
 					
 				}

+ 22 - 10
pages/batteryRecord/batteryRecord.vue

@@ -1,20 +1,19 @@
 <template>
 	<view class="container-view">
 		<navBar name="换电记录" type="noBottom"></navBar>
-		
 		<view class="order-type-view flex-row flex-between">
-			<view @click="srcFn(`/pages/carList/carList`)" class="car-model-list flex-row">
+			<view v-if="car_info.car_sn" @click="srcFn(`/pages/carList/carList`)" class="car-model-list flex-row">
 				<view class="car-model-text">{{car_info.car_name}}</view><img class="right-corner-icon"
 					src="https://qiniu.bms16.com/Fqs6TrEmcdT7QNEdKWs9Hir2cacO" alt="">
 			</view>
 		</view>
-		
 		<view v-for="(item,index) of list" :key="index" class="batteryList">
 			<view class="header">
 				<view v-if="item.status == 1" class="h5">开始换电</view>
 				<view v-if="item.status == 2" class="h5">换电中</view>
 				<view v-if="item.status == 3" class="h5">换电成功</view>
 				<view v-if="item.status == 4" class="h5">换电失败</view>
+				<view v-if="item.status == 5" class="h5">部分成功</view>
 				<view v-if="item.status == 0" class="h5">未知</view>
 				<view class="time">{{item.ctime}}</view>
 			</view>
@@ -39,15 +38,13 @@
 				<view class="dt">电柜名称</view>
 				<view class="dd">{{item.dev_name}}</view>
 			</view>
-			<image class="top" src="https://qiniu.bms16.com/FpVjOP5pZY1gXcCcS3TwI0GkywEe" mode=""></image>
+			<!-- <image class="top" src="https://qiniu.bms16.com/FpVjOP5pZY1gXcCcS3TwI0GkywEe" mode=""></image> -->
 		</view>
 	</view>
 </template>
 
 <script>
 	import dayjs from 'dayjs'
-	import duration from 'dayjs/plugin/duration'
-	dayjs.extend(duration);
 	var config_gyq = require('../../common/config_gyq.js');
 	var request = require('../../common/request');
 	var common = require('../../common/common.js');
@@ -64,6 +61,10 @@
 			this.listFn()
 		},
 		methods: {
+			dayjsFn(time){
+				console.log(time)
+				return dayjs(time * 1000).format('YYYY-MM-DD HH:mm:ss')
+			},
 			srcFn(url){
 				uni.navigateTo({
 					url
@@ -78,9 +79,20 @@
 				if (data.code == 200) {
 					this.list = data.data.list
 					this.list.map(item=>{
-						item.btn_battery = item.btn_battery ? item.btn_battery.join(',') : ''
-						item.bor_battery = item.bor_battery ? item.bor_battery.join(',') : ''
-						item.ctime = common.formatTime(item.ctime)
+						item.btn_battery = item.btn_battery.filter(item=>{
+							if(item){
+								return item
+							}
+						})
+						item.bor_battery = item.bor_battery.filter(item=>{
+							if(item){
+								return item
+							}
+						})
+						item.btn_battery = item.btn_battery ? item.btn_battery.join(',') : []
+						item.bor_battery = item.bor_battery ? item.bor_battery.join(',') : []
+						
+						item.ctime = dayjs(item.ctime * 1000).format('YYYY-MM-DD HH:mm:ss')
 					})
 				}
 
@@ -91,7 +103,7 @@
 
 <style scoped lang="scss">
 	.car-model-text{
-		width: 260rpx;
+		max-width: 260rpx;
 		text-overflow: ellipsis;
 		overflow: hidden;
 		white-space: nowrap;

+ 64 - 82
pages/bluetoothUnlock/bluetoothPair.vue

@@ -2,7 +2,7 @@
 	<view class="bluetoothPair-page">
 		<navBar name="开启感应解锁"></navBar>
 		<view class="car-wrap">
-			<view class="name">{{model_name}}</view>
+			<view class="name">{{car_info.model_name}}</view>
 			<image :src="QINIU_URL + 'Fi6CPKj4-raA86oizhL3PiXD4DkH'" class="car-img" />
 			<view>
 				<viwe class="pair-title">是否配对改设备</viwe>
@@ -21,7 +21,8 @@
 		</view>
 
 		<!-- 测试指令!!!别删除 -->
-		<view class="pair-btn" style="bottom: 340rpx;" @tap="nearCloseUnlockBtn">关闭靠近解锁</view>
+		<view class="pair-btn" style="bottom: 240rpx;" @tap="nearCloseUnlockBtn">关闭靠近解锁</view>
+		<!-- <view class="pair-btn" style="bottom: 240rpx;" @tap="nearTest">跳转解绑配对</view> -->
 		<!-- <view class="pair-btn" style="bottom: 240rpx;" @tap="nearUnlockBtn">靠近解锁</view> -->
 		<!-- <view class="pair-btn" style="bottom: 140rpx;" @tap="otaUpgrade">OTA升级</view> -->
 		<view class="pair-btn" @tap="initiateBluetoothPairing">开始配对</view>
@@ -39,11 +40,11 @@
 	var bluetooth = require('@/common/bluetooth.js');
 	import permision from "@/js_sdk/wa-permission/permission.js"
 	const DF_CAB_INFO_DONE = 10000; //机柜信息传输完成
-	var app = getApp();
 	var config = require('../../common/config.js');
 	var common = require('../../common/common.js');
 	var http = require('../../common/http.js');
 	var storage = require('../../common/storage.js');
+	// const app = getApp({allowDefault: true})
 	export default {
 		components: {
 			CenterDialog,
@@ -53,24 +54,32 @@
 			return {
 				QINIU_URL,
 				showNotice: false,
-				model_name:'',
+				// model_name:'',
 				car_sn:'',
+				car_info:{},
+				isReconnecting: false // 新增标志位
 			}
 		},
 		onLoad(){
-			const { car_sn , model_name } = uni.getStorageSync('car_info')
-			this.setData({
-				model_name,
-				car_sn
-			})
+			
+			this.car_info= uni.getStorageSync('car_info')
+			this.car_sn=this.car_info.car_sn
+			// this.setData({
+			// 	model_name,
+			// 	car_sn
+			// })
+			 // console.log(app,'app');
+			 // return
+			 // bluetooth.initBluetooth()
+			 // this.bluetoothClose()
 			const isOpenBluetoothPermission=permision.checkBluetoothPermission()
 			if(isOpenBluetoothPermission){
-				bluetooth.initBluetooth()
 				//初始化 连接蓝牙  -下发配对指令 -会断开连接-直接再次连接 记得不要提示可以蓝牙断开连接
 				//点击配对-连接蓝牙-调用配对-确认配对  取消 断开蓝牙 不走逻辑
+				bluetooth.initBluetooth()
 				this.bluetoothClose()
 			}else{
-				common.showContent('蓝牙未启用,请先打开蓝牙')
+				common.simpleToast('蓝牙未启用,请先打开蓝牙')
 			}
 			
 		},
@@ -144,6 +153,7 @@
 			},
 			switchNormal(){
 				const me=this
+				const app=getApp()
 				app.globalData.connectionState={}
 				bluetooth.sendSwitchNormalCommand(this.car_sn, (res) => {
 						// uni.hideLoading();
@@ -180,13 +190,18 @@
 			},
 			loadBluetooth() {
 				const me = this;
+				const third_device_type = this.car_info.third_device_type
+				console.log(third_device_type,'third_device_type');
 				var device = {
 					mac_id: this.car_sn,
 					btid: this.car_sn,
 					btkey: this.car_sn,
-					bt_type: "ZXCAR",
-					device_type: "ZXCAR"
+					bt_type: third_device_type,
+					device_type: third_device_type,
+					// bt_type: 'ZXCAR',
+					// device_type: 'ZXCAR'
 				};
+				const app=getApp()
 				app.globalData.connectionState={}
 				//bluetooth.acceptDevice(device) 是否是蓝牙类型列表里面的
 				if (bluetooth.acceptDevice(device)) {
@@ -200,11 +215,16 @@
 							//监听蓝牙设备连接状态变化事件
 							bluetooth.onConnectionStateChange(device.mac_id, 'index', (res) => {
 								
-								if (!res.connected &&('lockType' in app.globalData.nearLockInfo &&app.globalData.nearLockInfo.lockType==0)) {
+								if (!res.connected &&!('lockType' in app.globalData.nearLockInfo)) {
 									// 蓝牙连接断开
 									console.log('蓝牙连接断开');
-									me.loadBluetooth()
-									// common.simpleToast('蓝牙连接断开')
+									if (!me.isReconnecting) { // 检查标志位
+										me.isReconnecting = true; // 设置标志位
+										setTimeout(() => {
+											me.loadBluetooth();
+											me.isReconnecting = false; // 重置标志位
+										}, 100);
+									}
 								} else {
 									console.log('蓝牙连接成功');
 									// uni.hideLoading();
@@ -212,76 +232,33 @@
 									
 								}
 							});
-							// uni.hideLoading()
-							// await bluetooth.sendOTACommand(device.mac_id, 'index', (res) => {
-							// 		uni.hideLoading();
-							// 		if (!res.connected) {
-							// 			// 蓝牙未连接
-							// 			common.simpleToast('蓝牙连接断开1111', 2000)
-							// 		} else {
-							// 			common.simpleToast('蓝牙连接成功2222', 2000)
-							// 		}
-							// 	});
-							// console.log('test');
-							// console.log(app.globalData.connectionStateChangeFunc,'app.globalData.connectionStateChangeFunc');
-							//监听蓝牙特征值状态变化事件
-							// 	bluetooth.onCharacteristicStateChange(device.mac_id, 'index', (data) => {
-							// 		console.log(data,'datatest');
-							// 		if (JSON.stringify(data) != '{}') {
-							// 			if (data.state === DF_CAB_INFO_DONE) {
-							// 				me.reportCabintInfo(device.mac_id, data.commandList);
-							// 				uni.hideLoading();
-							// 				common.simpleToast('蓝牙连接成功0000')
-							// 				// 进行机柜蓝牙换电 API_DAYHIRE_CABINRT_BLUETOOTH_CHANGE_BATTERY
-							// 			}
-							// 		}
-							// 	});
-								
-							// 	bluetooth.sendGetCabinetInfoCommand(
-							// 		device.mac_id,
-							// 		device,
-							// 		(res) => {
-							// 			common.loading();
-							// 		},
-							// 		(res) => {
-							// 			uni.showModal({
-							// 				title: '提示',
-							// 				confirmText: '重新连接',
-							// 				content: '连接失败,请尝试重新连接3333',
-							// 				success: function(res) {
-							// 					if (res.confirm) {
-							// 						me.loadBluetooth();
-							// 					} else {}
-							// 				}
-							// 			});
-							// 		}
-							// 	);
-							
+
 							},
 							(res) => {
 								console.log('观察周围是否有其他骑手连接,请等待对方完成 或 微信是否开启了蓝牙权限',res,res.errCode);
 								uni.hideLoading();
-								var showContent = ""
-								if (res && ("errCode" in res)) {
-									if (res.errCode == 9000001) {
-										var showContent = "观察周围是否有其他骑手连接,请等待对方完成 或 微信是否开启了蓝牙权限!!"
-									} else {
-										var showContent = "连接失败,请尝试重新连接44444"+res.errCode
-									}
-								} else {
-									var showContent = "连接失败,请尝试重新连接55555"
-								}
-								uni.showModal({
-									title: '提示',
-									confirmText: '重新连接',
-									content: showContent,
-									success: function(res) {
-										if (res.confirm) {
-											
-											me.loadBluetooth();
-										} else {}
-									}
-								});
+								// var showContent = ""
+								// if (res && ("errCode" in res)) {
+								// 	if (res.errCode == 9000001) {
+								// 		var showContent = "观察周围是否有其他骑手连接,请等待对方完成 或 微信是否开启了蓝牙权限!!"
+								// 	} else {
+								// 		var showContent = "连接失败,请尝试重新连接44444"+res.errCode
+								// 	}
+								// } else {
+								// 	var showContent = "连接失败,请尝试重新连接55555"
+								// }
+								// uni.showModal({
+								// 	title: '提示',
+								// 	confirmText: '重新连接',
+								// 	content: showContent,
+								// 	success: function(res) {
+								// 		if (res.confirm) {
+								// 			setTimeout(()=>{
+								// 				me.loadBluetooth();
+								// 			},100)
+								// 		} else {}
+								// 	}
+								// });
 							}, 
 							(res) => {
 								// console.log('蓝牙未打开或请在右上角设置授权小程序使用蓝牙66666');
@@ -312,6 +289,11 @@
 					// });
 				}
 			},
+			nearTest(){
+				uni.navigateTo({
+					url:'/pages/bluetoothUnlock/unlockSet'
+				})
+			}
 			
 		}
 	}

+ 5 - 3
pages/bluetoothUnlock/unlockSet.vue

@@ -43,14 +43,14 @@
 
 <script>
 	var bluetooth = require('@/common/bluetooth.js');
-	var app = getApp();
+	var common = require('@/common/common.js');
 	export default {
 		data() {
 			return {
 				stepIndex:1,
 				start:0,
 				end:0,
-				showSensitivityDialog: true,
+				showSensitivityDialog: false,
 				sensitivityValue: 1
 			}
 		},
@@ -103,7 +103,9 @@
 				})
 			},
 			closeNeerUnlock(){
-				nearCloseUnlock(car_sn,()=>{
+				const car_sn = uni.getStorageSync('car_info').car_sn
+				common.loading();
+				bluetooth.nearCloseUnlock(car_sn,()=>{
 					console.log('关闭接近解锁成功');
 				})
 			}

+ 163 - 115
pages/cabinetDetail/cabinetDetail.vue

@@ -1,21 +1,22 @@
 <template>
-	<view v-if="cabinetInfo.dev_id" class="main-view">
-			<view class="content">
-				<swiper v-if="shop_image.length!=0" class="swiper" :indicator-dots="true" :autoplay="true" :interval="2000"
-					indicator-color="rgba(0, 0, 0, 0.3)" indicator-active-color="#000000" :duration="1000" circular>
-					<swiper-item class="swiper-item" v-for="(item,index) in shop_image" :key="index">
-						<img class="swiper-item-img" :src="item" />
-					</swiper-item>
-				</swiper>
-				<img v-else class="bg-img" src="https://qiniu.bms16.com/FhRnr7rADHHsOFfpWO4duD15SgIt" alt="">
+	<view class="main-view">
+		<Navigation :scroll='scrollTop'></Navigation>
+		<view class="content">
+			<swiper v-if="shop_image.length!=0" class="swiper" :indicator-dots="true" :autoplay="true" :interval="2000"
+				indicator-color="rgba(0, 0, 0, 0.3)" indicator-active-color="#000000" :duration="1000" circular>
+				<swiper-item class="swiper-item" v-for="(item,index) in shop_image" :key="index">
+					<image class="swiper-item-img" :src="item" mode="aspectFit"></image>
+				</swiper-item>
+			</swiper>
+			<img v-else class="bg-img" src="https://qiniu.bms16.com/FhRnr7rADHHsOFfpWO4duD15SgIt" alt="">
+		</view>
+		<view class="cabinet-detail">
+			<view class="cabinet-name-view flex-row flex-between">
+				<view class="cabinet-name">{{cabinetInfo.cabinet_name}}</view>
+				<!-- <view class="distance">{{cabinetInfo.distance}}km</view> -->
 			</view>
-			<view class="cabinet-detail">
-				<view class="cabinet-name-view flex-row flex-between">
-					<view class="cabinet-name">{{cabinetInfo.cabinet_name}}</view>
-					<!-- <view class="distance">{{cabinetInfo.distance}}km</view> -->
-				</view>
-	
-				<!-- <view v-if="tagList.length==0" class="no_battery">
+
+			<view v-if="tagList.length==0" class="no_battery">
 					无可用电池
 				</view>
 				<view class="flex-row" style="justify-content: center;">
@@ -27,42 +28,42 @@
 							<text class="tag_num">{{'x' + item.num}}</text>
 						</view>
 					</view>
-				</view> -->
-	
-				<view class="flex-row flex-between">
-					<view :class="isWorkTimer ? 'left_grid_2' : 'left_grid_1'">
-						<view class="flex-row">
-							<img class="icon_grid"
-								:src="!isWorkTimer ? 'https://zxappfile.bms16.com/zx_admin/cab_timer.png' : 'https://zxappfile.bms16.com/zx_admin/cab_timer_work.png'">
-							<view :class="isWorkTimer ? 'grid_text_1' : 'grid_text_rest' ">{{isWorkTimer ? '营业中' : '已休息'}}
-							</view>
-						</view>
-						<view class="grid_text_2">
-							{{cabinetInfo.work_begin_time!=null?cabinetInfo.work_begin_time:'00:00'}}-{{cabinetInfo.work_end_time!=null?cabinetInfo.work_end_time:'23:59'}}
+				</view>
+
+			<view class="flex-row flex-between">
+				<view :class="isWorkTimer ? 'left_grid_2' : 'left_grid_1'">
+					<view class="flex-row">
+						<img class="icon_grid"
+							:src="!isWorkTimer ? 'https://zxappfile.bms16.com/zx_admin/cab_timer.png' : 'https://zxappfile.bms16.com/zx_admin/cab_timer_work.png'">
+						<view :class="isWorkTimer ? 'grid_text_1' : 'grid_text_rest' ">{{isWorkTimer ? '营业中' : '已休息'}}
 						</view>
 					</view>
-					<view  @tap="navToCabinet" class="right_grid flex-between">
-						<view>
-							<view class="cab_distance">
-								直线距您{{cabinetInfo.distance>1?(cabinetInfo.distance+'千米'):(cabinetInfo.distance*1000+'米')}}
-							</view>
-							<view class="cab_address">{{cabinetInfo.address}}</view>
-						</view>
-						<view>
-							<img class="icon_grid_1" src="https://zxappfile.bms16.com/zx_admin/cab_nav.png">
-							<view class="grid_nav">导航</view>
+					<view class="grid_text_2">
+						{{cabinetInfo.work_begin_time!=null?cabinetInfo.work_begin_time:'00:00'}}-{{cabinetInfo.work_end_time!=null?cabinetInfo.work_end_time:'23:59'}}
+					</view>
+				</view>
+				<view @tap="navToCabinet" class="right_grid flex-between">
+					<view>
+						<view class="cab_distance">
+							直线距您{{cabinetInfo.distance>1?(cabinetInfo.distance+'千米'):(cabinetInfo.distance*1000+'米')}}
 						</view>
+						<view class="cab_address">{{cabinetInfo.address}}</view>
+					</view>
+					<view>
+						<img class="icon_grid_1" src="https://zxappfile.bms16.com/zx_admin/cab_nav.png">
+						<view class="grid_nav">导航</view>
 					</view>
 				</view>
 			</view>
-			<view class="battery-list-view">
-				<view class="battery-title flex-row flex-between">
-					<text class="blod-text">格口详情</text>
-					<text class="cabinet-ref">电柜编号:<text class="cabinet-ref-text"> {{cabinetInfo.dev_id}}</text></text>
-				</view>
-				<view class="battery-list-main flex-row flex-start">
-					<view class="battery-list" v-for="(item, index) in batteryList" :key="item.unique">
-						<!-- <block v-if="item.isReservation">
+		</view>
+		<view class="battery-list-view">
+			<view class="battery-title flex-row flex-between">
+				<text class="blod-text">格口详情</text>
+				<text class="cabinet-ref">电柜编号:<text class="cabinet-ref-text"> {{cabinetInfo.dev_id}}</text></text>
+			</view>
+			<view class="battery-list-main flex-row flex-start">
+				<view class="battery-list" v-for="(item, index) in batteryList" :key="item.unique">
+					<!-- <block v-if="item.isReservation">
 							<view class="battery-list-g">
 								<view class="namber-view flex-row">
 									<view class="namber namber-g">
@@ -77,76 +78,79 @@
 								<view class="tip-text tip-text-g1">已预约</view>
 							</view>
 						</block> -->
-						<!-- 没有预约-->
-						<!-- <block v-else> -->
-							<!-- 空仓或者仓门不可用-->
-							<view v-if="!item.cabinet_battery_sn||(item.fault_reason&&item.fault_reason.length>0)"
-								:class="(item.fault_reason&&item.fault_reason.length>0)?'battery-list-s':'battery-list-g'">
-								<!-- <view class="namber-view flex-row">
+					<!-- 没有预约-->
+					<!-- <block v-else> -->
+					<!-- 空仓或者仓门不可用-->
+					<view v-if="!item.cabinet_battery_sn||(item.fault_reason&&item.fault_reason.length>0)"
+						:class="(item.fault_reason&&item.fault_reason.length>0)?'battery-list-s':'battery-list-g'">
+						<!-- <view class="namber-view flex-row">
 									<view
 										:class="(item.fault_reason&&item.fault_reason.length>0)?'namber namber-s':'namber namber-g'">
 										{{item.box_sn}}
 									</view>
 								</view> -->
-	
-								<view class="namber-view flex-row flex-between">
-									<view
-										:class="(item.fault_reason&&item.fault_reason.length>0)?'namber namber-s':'namber namber-g'">
-										{{item.box_sn}}
-									</view>
-									<view v-if="item.tag_info" class="tag_type_n">
-										{{item.tag_info.main_tag_name ? (item.tag_info.main_tag_name) : ''}}{{item.tag_info.child_tag_name ? '/' + item.tag_info.child_tag_name : ''}}
-									</view>
-								</view>
-	
-								<view class="status-img-view flex-row">
-									<img v-if="!item.cabinet_battery_sn&&!(item.fault_reason&&item.fault_reason.length>0)"
-										class="status-img" src="https://qiniu.bms16.com/FtOgmvwtoUCVzEyxIau6-6i0hjLt"
-										alt="">
-									<img v-if="item.fault_reason&&item.fault_reason.length>0" class="status-img"
-										src="https://qiniu.bms16.com/FmMGYfe7eRSQvM8zeKEVeSmzbArd" alt="">
-								</view>
-								<!-- <view class="battery-ref">124513215</view> -->
-								<view v-if="!item.cabinet_battery_sn&&!(item.fault_reason&&item.fault_reason.length>0)"
-									class="tip-text tip-text-g">空仓</view>
-								<view v-if="item.fault_reason&&item.fault_reason.length>0" class="tip-text tip-text-u">
-									{{item.fault_reason[0]}}
-								</view>
+
+						<view class="namber-view flex-row flex-between">
+							<view
+								:class="(item.fault_reason&&item.fault_reason.length>0)?'namber namber-s':'namber namber-g'">
+								{{item.box_sn}}
 							</view>
-							<!-- 满电或者电量未满 -->
-							<view v-else :class="(item.is_full_soc==1)?'battery-list-b':'battery-list-o'">
-								<view class="namber-view flex-row flex-between">
-									<view :class="(item.is_full_soc==1)?'namber namber-b':'namber namber-o'">{{item.box_sn}}
-									</view>
-									<view v-if="item.tag_info" class="tag_type">
-										{{item.tag_info.main_tag_name ? (item.tag_info.main_tag_name) : ''}}{{item.tag_info.child_tag_name ? '/' + item.tag_info.child_tag_name : ''}}
-									</view>
-								</view>
-								<view class="status-img-view flex-row">
-									<view v-if="item.cabinet_battery_sn" class="progress-bar-view">
-										<progressView :soc="item.soc" :status="item.is_full_soc"></progressView>
-									</view>
-									<view v-if="item.cabinet_battery_sn" class="battery-number">
-										{{item.battery_sn}}
-										<!-- 0168 8256 9608 -->
-									</view>
-								</view>
-								<view v-if="item.is_full_soc==1" class="tip-text tip-text-b">电池可用</view>
-								<view v-else class="tip-text tip-text-o">待充满</view>
+							<view v-if="item.tag_info" class="tag_type_n">
+								{{item.tag_info.main_tag_name ? (item.tag_info.main_tag_name) : ''}}{{item.tag_info.child_tag_name ? '/' + item.tag_info.child_tag_name : ''}}
+							</view>
+						</view>
+
+						<view class="status-img-view flex-row">
+							<img v-if="!item.cabinet_battery_sn&&!(item.fault_reason&&item.fault_reason.length>0)"
+								class="status-img" src="https://qiniu.bms16.com/FtOgmvwtoUCVzEyxIau6-6i0hjLt" alt="">
+							<img v-if="item.fault_reason&&item.fault_reason.length>0" class="status-img"
+								src="https://qiniu.bms16.com/FmMGYfe7eRSQvM8zeKEVeSmzbArd" alt="">
+						</view>
+						<!-- <view class="battery-ref">124513215</view> -->
+						<view v-if="!item.cabinet_battery_sn&&!(item.fault_reason&&item.fault_reason.length>0)"
+							class="tip-text tip-text-g">空仓</view>
+						<view v-if="item.fault_reason&&item.fault_reason.length>0" class="tip-text tip-text-u">
+							{{item.fault_reason[0]}}
+						</view>
+					</view>
+					<!-- 满电或者电量未满 -->
+					<view v-else :class="(item.is_full_soc==1)?'battery-list-b':'battery-list-o'">
+						<view class="namber-view flex-row flex-between">
+							<view :class="(item.is_full_soc==1)?'namber namber-b':'namber namber-o'">{{item.box_sn}}
+							</view>
+							<view v-if="item.tag_info" class="tag_type">
+								{{item.tag_info.main_tag_name ? (item.tag_info.main_tag_name) : ''}}{{item.tag_info.child_tag_name ? '/' + item.tag_info.child_tag_name : ''}}
+							</view>
+						</view>
+						<view class="status-img-view flex-row">
+							<view v-if="item.cabinet_battery_sn" class="progress-bar-view">
+								<progressView :soc="item.soc" :status="item.is_full_soc"></progressView>
+							</view>
+							<view v-if="item.cabinet_battery_sn" class="battery-number">
+								{{item.battery_sn}}
+								<!-- 0168 8256 9608 -->
 							</view>
-						<!-- </block> -->
+						</view>
+						<view v-if="item.is_full_soc==1" class="tip-text tip-text-b">电池可用</view>
+						<view v-else class="tip-text tip-text-o">待充满</view>
 					</view>
+					<!-- </block> -->
 				</view>
-				<scanBtn :dev_id="dev_id" :listData='listData' :cab_info="cabinetInfo" @refreshCabinet="refreshCabinet"
-					@popPackageModel="clickPopPackageModel" ref="scanRef"></scanBtn>
 			</view>
-		
+			<scanBtn :dev_id="dev_id" :listData='listData' :cab_info="cabinetInfo" @refreshCabinet="refreshCabinet"
+				@popPackageModel="clickPopPackageModel" ref="scanRef"></scanBtn>
 		</view>
+
+	</view>
 </template>
 
 <script>
-	import { getLocation, msg,strJoin } from '../../utils/util.js';
-import progressView from '@/component/progressView/progressView';
+	import {
+		getLocation,
+		msg,
+		strJoin
+	} from '../../utils/util.js';
+	import progressView from '@/component/progressView/progressView';
 	const http = require('../../common/request.js');
 	const config = require('../../common/config_gyq.js');
 	const common = require('../../common/common.js');
@@ -161,10 +165,13 @@ import progressView from '@/component/progressView/progressView';
 			progressView,
 			scanBtn
 		},
+		onPageScroll(e) {
+			this.scrollTop = e.scrollTop
+		},
 		data() {
 			return {
 				dev_id: '',
-				listData:{},
+				listData: {},
 				isWorkTimer: true,
 				tagList: [],
 				batteryList: [], //电池列表
@@ -189,17 +196,17 @@ import progressView from '@/component/progressView/progressView';
 				isShowAppoint: false,
 				packType: 0,
 				notShow: 0,
-				car_info:{}
+				car_info: {}
 			};
 		},
 		/**
 		 * 生命周期函数--监听页面加载
 		 */
 		onLoad: function(options) {
-			this.notShow = options.notShow?options.notShow:1
+			this.notShow = options.notShow ? options.notShow : 1
 			this.dev_id = options.dev_id
 			const storedLocation = uni.getStorageSync('user_current_location');
-			this.car_info =  uni.getStorageSync('car_info') || {};
+			this.car_info = uni.getStorageSync('car_info') || {};
 			const car_list = uni.getStorageSync('user_car_list') || null
 			this.license_plate_number = car_list ? car_list.plate_number : ''
 			const me = this
@@ -220,7 +227,7 @@ import progressView from '@/component/progressView/progressView';
 				// this.getLocationAndSave();
 			}
 			// bluetooth.initBluetooth()
-			
+
 		},
 		/**
 		 * 生命周期函数--监听页面显示
@@ -234,9 +241,9 @@ import progressView from '@/component/progressView/progressView';
 					isModelCenter: false
 				})
 			},
-			clickPopPackageModel(e,notShow) {
+			clickPopPackageModel(e, notShow) {
 				// console.log(e.packType,notShow,'sadasd');
-				
+
 				// this.notShow = notShow?notShow:this.notShow
 				// if ((e.packType === 0&&this.notShow==1) || e.packType === 2) {
 				// 	this.setData({
@@ -278,13 +285,46 @@ import progressView from '@/component/progressView/progressView';
 				})
 			},
 
+			//计算电池数量
+			deduplicateAndCountByMainAndChild(data) {
+				// 1. 统计次数:根据 main_tag_code 和 child_tag_code(如果存在)
+				const countMap = {};
+
+				data.forEach(item => {
+					// 如果 child_tag_code 为空,则只根据 main_tag_code 统计
+					const key = item.child_tag_code ?
+						`${item.main_tag_code}_${item.child_tag_code}` :
+						item.main_tag_code;
+
+					countMap[key] = (countMap[key] || 0) + 1;
+				});
+
+				// 2. 去重并添加 num 字段
+				const seen = new Set();
+				return data.filter(item => {
+					// 生成去重键(与统计时逻辑一致)
+					const key = item.child_tag_code ?
+						`${item.main_tag_code}_${item.child_tag_code}` :
+						item.main_tag_code;
+
+					// 如果是第一次出现,添加 num 并保留
+					if (!seen.has(key)) {
+						seen.add(key);
+						item.num = countMap[key]; // 直接修改原对象(如需要深拷贝可改用 { ...item, num })
+						return true;
+					}
+					// 否则过滤掉
+					return false;
+				});
+			},
+
 			async loadCabinetDetail() {
 				//获取机柜信息
 				const that = this
 				var _can_num = 0
 				let resp = await http.postApi(config.API_CABINET_INFO, {
-					car_sn:this.car_info.car_sn,
-					dev_id:this.dev_id,
+					car_sn: this.car_info.car_sn,
+					dev_id: this.dev_id,
 					longitude: this.myLocation.longitude,
 					latitude: this.myLocation.latitude,
 				})
@@ -297,7 +337,7 @@ import progressView from '@/component/progressView/progressView';
 					// 		_can_num = _can_num + 1
 					// 	}
 					// }
-				
+
 					var cabinetInfo = resp.data.data.cabinetInfo
 					cabinetInfo.work_begin_time = cabinetInfo.work_begin_time == null ? '00:00' : cabinetInfo
 						.work_begin_time
@@ -309,13 +349,21 @@ import progressView from '@/component/progressView/progressView';
 					var box_list = resp.data.data.boxList
 					// box_list = cabinetDetailImpl.getBoxReservation(box_list, reservation_List)
 					console.log(box_list, "box_list")
+					let tagList = []
+					box_list.map(item => {
+						if (item.tag_info) {
+							tagList.push(item.tag_info)
+						}
+
+					})
+					tagList = this.deduplicateAndCountByMainAndChild(tagList)
 					that.setData({
 						reservation_info: reservation_List,
 						isWorkTimer: isWorkTimer,
-						tagList: resp.data.data.tagList,
+						tagList,
 						cabinetInfo: cabinetInfo,
 						batteryList: box_list,
-						listData:resp.data.data,
+						listData: resp.data.data,
 						online_status: cabinetInfo.online_status,
 						can_battery_num: resp.data.data.can_exchange_num,
 						shop_image: JSON.parse(cabinetInfo.imgs.split(',')) || []
@@ -415,6 +463,6 @@ import progressView from '@/component/progressView/progressView';
 	};
 </script>
 
-<style  >
+<style>
 	@import './cabinetDetail.css';
 </style>

+ 17 - 10
pages/carDetail/carDetail.vue

@@ -1,19 +1,15 @@
 <template>
 	<view>
 	<view class="car-detail-main">
-		<navBar type="carDetail"/>
-		<!-- <view v-if="car_detail.image" class="flex-row">
-			<img style="width: 600rpx;height: 406rpx; margin: auto; margin-bottom: 20rpx;" :src="car_detail.image"
-				alt="">
-		</view> -->
+		<Navigation :scroll='scrollTop'></Navigation>
 		<view class="store-img-view">
 			<swiper v-if="car_detail.model_images && car_detail.model_images.length!=0" class="swiper" :indicator-dots="true" :autoplay="true" :interval="2000"
 				indicator-color="rgba(0, 0, 0, 0.3)" indicator-active-color="#000000" :duration="1000" circular>
 				<swiper-item class="swiper-item" v-for="(item,index) in car_detail.model_images" :key="index">
-					<image class="swiper-item-img" :src="item" mode="aspectFill"></image>
+					<image style="width: 100%;height: 100%;" class="swiper-item-img" :src="item" mode="aspectFit"></image>
 				</swiper-item>
 			</swiper>
-			<image v-else class="bg-img" src="https://qiniu.bms16.com/FhRnr7rADHHsOFfpWO4duD15SgIt" mode="aspectFill">
+			<image v-else class="bg-img" src="https://qiniu.bms16.com/FhRnr7rADHHsOFfpWO4duD15SgIt" mode="aspectFit">
 			</image>
 		</view>
 		
@@ -107,7 +103,6 @@
 	import {
 		LEASE_TYPE_ARR
 	} from '@/common/constant.js'
-	var app = getApp();
 	var config = require('@/common/config.js');
 	var common = require('@/common/common.js');
 	var http = require('@/common/http.js');
@@ -134,9 +129,19 @@
 				this.model_id = options.model_id
 				this.locationFn()
 			}
+			if (options.shop_type) {
+				const d = {
+					hire_duration_unit:options.shop_type,
+					hire_price:Number(options.hire_price)
+				}
+				this.tapSelectType(d)
+			}
 			// this.loadCarInfo()
 			// getFlatternDistance 获取直线距离
 		},
+		onPageScroll(e) {
+			this.scrollTop = e.scrollTop
+		},
 		methods: {
 			locationFn() {
 				this.loadCarInfo(this.myLocation.longitude, this.myLocation.latitude)
@@ -150,11 +155,13 @@
 				}, (resp) => {
 					if (resp.data.code === 200) {
 						// resp.data.data.desc = resp.data.data.desc.replaceAll('/<img\b/gi, '$& style="1"'')
-						me.tapSelectType(resp.data.data.rental_setting[0])
+						
+						// me.tapSelectType(resp.data.data.rental_setting[0])
 						resp.data.data.distance = common.formatDistance(Number(resp.data.data.distance))
+						resp.data.data.desc = this.$htmlData(resp.data.data.desc)
 						me.setData({
 							car_detail: resp.data.data,
-							price: ((resp.data.data.rental_setting[0]?.hire_price || 0) / 100).toFixed(2)
+							// price: ((resp.data.data.rental_setting[0]?.hire_price || 0) / 100).toFixed(2)
 						})
 					} else {
 						common.simpleToast(resp.data.msg);

+ 8 - 2
pages/carFunctionSet/more.vue

@@ -1,7 +1,7 @@
 <template>
 	<view class="zx-container car-function-set-more">
 		<navBar name="更多功能" left="0"></navBar>
-		<view class="fn-wrap">
+		<view style='margin-top: 20rpx;' class="fn-wrap">
 			<view class="title">
 				{{ $t('固定导航栏') }}
 				<text class="sort-num">{{ realActiveTabs.length }} / {{ MAX_TAB_LEN }}</text>
@@ -31,7 +31,7 @@
 			</view>
 		</view>
 		<view class="tips">{{ $t('长按拖动可调整顺序,可增减固定导航栏内容') }}</view>
-		<view class="un-bind-btn" @tap="toUnbind">{{ $t('解除绑定') }}</view>
+		<view v-if="showUnBind" class="un-bind-btn" @tap="toUnbind">{{ $t('解除绑定') }}</view>
 		<view v-if="popupControlShow" class="show-modal">
 			<view class="modal-info">
 				<view class="popup-title">{{($t(popText)==$t('开机'))?$t('开启车辆'):($t(popText)==$t('关机')?$t('关闭车辆'):$t(popText))}}</view>
@@ -77,6 +77,8 @@
 				isActiveEdit: false,
 				activeTabs: [],
 				toBeSelectTabs: [],
+				car_info :{},
+				showUnBind:true
 			}
 		},
 		computed: {
@@ -87,6 +89,10 @@
 				return this.isActiveEdit && this.realActiveTabs.length < this.MAX_TAB_LEN
 			}
 		},
+		onLoad(){
+			this.car_info =  uni.getStorageSync('car_info') || {};
+			this.showUnBind = !!this.car_info.sold_time
+		},
 		created() {
 			this.initializeTabs()
 		},

+ 53 - 47
pages/carFunctionSet/unbind.vue

@@ -1,51 +1,55 @@
 <template>
-    <view class="zx-container unbind-page">
-		<navBar name="解除绑定" bgColor="#F1F3F4"></navBar>
-      <view class="zx-wrap car-info-wrap">
-        <image :src="carInfo.model_images" class="car-img" />
-        <view class="car-name">
-          {{ carInfo.car_name }}
-        </view>
-      </view>
-      <view class="zx-wrap input-wrap">
-        <view class="title">{{ $t('输入注册账号的密码即可解绑') }}</view>
-        <ZxInput
-          v-model="passwd"
-          :placeholder="$t('请输入密码')"
-          background="#F3F8FF"
-          is-password
-        />
-      </view>
-      <view class="tips-wrap">
-        <view class="title">{{ $t('提示信息') }}</view>
-        <view class="text">
-          <text>1、</text>
-          解绑后,您将失去当前设备的控制权,其他人可以连接绑定您的设备。
-        </view>
-        <view class="text">
-          <text>2、</text>
-          解绑后将立即删除家庭账号,感应解锁等数据。
-        </view>
-      </view>
-      <view
-        style="margin-top: 40rpx;"
-        :class="[
-          'zx-form-btn',
-          passwd && 'is-submit'
-        ]"
-        @tap="unbindTap"
-      >
-        {{ $t('完成并解绑') }}
-      </view>
-      <Confirm
-        v-model="showConfirm"
-        :dialog-info="{
-          text: $t('是否确定解除绑定'),
-          showCancelButton: true
-        }"
-        @confirm="unbindSubmit"
-      />
-    </view>
+	<view>
+		<navBar name="解除绑定" bgColor="#fff"></navBar>
+		<view class="zx-container unbind-page">
+		  <view class="zx-wrap car-info-wrap">
+		    <image :src="carInfo.model_images" class="car-img" />
+		    <view class="car-name">
+		      {{ carInfo.car_name }}
+		    </view>
+		  </view>
+		  <view class="zx-wrap input-wrap">
+		    <view class="title">{{ $t('输入注册账号的密码即可解绑') }}</view>
+		    <ZxInput
+		      v-model="passwd"
+		      :placeholder="$t('请输入密码')"
+		      background="#F3F8FF"
+		      is-password
+		    />
+		  </view>
+		  <view class="tips-wrap">
+		    <view class="title">{{ $t('提示信息') }}</view>
+		    <view class="text">
+		      <text>1、</text>
+		      解绑后,您将失去当前设备的控制权,其他人可以连接绑定您的设备。
+		    </view>
+		    <view class="text">
+		      <text>2、</text>
+		      解绑后将立即删除家庭账号,感应解锁等数据。
+		    </view>
+		  </view>
+		  <view
+		    style="margin-top: 40rpx;"
+		    :class="[
+		      'zx-form-btn',
+		      passwd && 'is-submit'
+		    ]"
+		    @tap="unbindTap"
+		  >
+		    {{ $t('完成并解绑') }}
+		  </view>
+		  <Confirm
+		    v-model="showConfirm"
+		    :dialog-info="{
+		      text: $t('是否确定解除绑定'),
+		      showCancelButton: true
+		    }"
+		    @confirm="unbindSubmit"
+		  />
+		</view>
+		  
+	</view>
+  
   </template>
   
   <script>
@@ -79,6 +83,7 @@
     },
     onLoad() {
 			this.carInfo = uni.getStorageSync('car_info')
+			this.carInfo.model_images = this.carInfo.model_images.split(',')[0]
 		},
     methods: {
       unbindTap() {
@@ -114,6 +119,7 @@
   .unbind-page {
     .car-info-wrap {
         padding: 0 32rpx 40rpx;
+		padding-top: 20rpx;
         .car-img {
             width: 100%;
             height: 492rpx;

+ 14 - 9
pages/carList/carList.vue

@@ -3,7 +3,10 @@
 	<navBar name="请选择设备" type="select"/>
 	<view class="car-list">
 		<view v-for="(item,index) of carList" :key="index" @click="clickItem(item)"  :class="['car-list-card',  car_info.car_sn == item.car_sn?'car-list-card-i' :'']">
-		    <view class="car-name" :class="{ 'car-name-i' : car_info.car_sn == item.car_sn}">{{item.car_name}}</view>
+		    <view class="flex-row">
+		    	<view class="car-name" :class="{ 'car-name-i' : car_info.car_sn == item.car_sn}">{{item.car_name}}</view>
+		    	<!-- <view class="car-name1">{{item.car_sn}}</view> -->
+		    </view>
 			<image v-if="car_info.car_sn == item.car_sn && isNearLockCheck" class="icon" src="/static/resource/images/gyq_ly.png" mode=""></image>
 			<!-- https://qiniu.bms16.com/Fg8_p7083jpsy8BXG4bR6yMs7jQX -->
 			<image class="img" :src="item.model_images" mode="aspectFit"></image>
@@ -16,14 +19,14 @@
 			<view @click="navCarDetail" class="btn btn-left">{{ $t('租赁设备') }}</view>
 			<view class="btn btn-right">{{ $t('绑定设备') }}</view>
 		</view> -->
-		<Confirm
+		<!-- <Confirm
         v-model="showConfirm"
         :dialog-info="{
-          text: $t('是否确定'),
+          text: $t('是否切换到车辆' + clickItemData.car_name ),
           showCancelButton: true
         }"
         @confirm="unbindSubmit"
-      />
+      /> -->
 	</view>
 </view>
 </template>
@@ -31,11 +34,12 @@
 <script>
  import Confirm from '@/component/comPopup/Confirm'
 	var config = require('../../common/config.js');
-	var app = getApp();
+	
 	var config = require('../../common/config.js');
 	var common = require('../../common/common.js');
 	var http = require('../../common/http.js');
 	var storage = require('../../common/storage.js');
+		var bluetooth = require('@/common/bluetooth.js');
 	export default {
 		components: {
 			Confirm,
@@ -55,6 +59,7 @@
 		 */
 		,
 		onLoad: function(options) {
+			const app = getApp();
 			this.isNearLockCheck=app.globalData.nearLockCheck
 			this.loadUserCarList()
 		},
@@ -72,6 +77,7 @@
 				this.showConfirm = true
 				// uni.setStorageSync('car_info',item)
 				// this.car_info = item
+				this.unbindSubmit()
 			},
 			unbindSubmit(){
 				let car_sn = this.clickItemData.car_sn
@@ -84,6 +90,7 @@
 						resp.data.data.car_sn = car_sn
 						uni.setStorageSync('car_info', resp.data.data);
 						me.car_info = resp.data.data
+						const app = getApp();
 						//清空当前设备蓝牙相关
 						app.globalData.nearLockCheck=false
 						app.globalData.nearLockInfo={}
@@ -106,9 +113,7 @@
 			loadUserCarList(){
 				this.car_info = uni.getStorageSync('car_info') || {};
 				const me = this
-				common.loading()
 				http.postApi(config.API_FLK_CAR_DEVICE_LIST, {}, (resp) => {
-					uni.hideLoading();
 					if (resp.data.code === 200) {
 						const carList=resp.data.data.list
 						resp.data.data.list.map(item=>{
@@ -201,9 +206,9 @@
 .car-name{
     font-family: PingFangSC, PingFang SC;
     font-weight: 600;
-    font-size: 48rpx;
+    font-size: 36rpx;
     color: #828DA2;
-	width: 500rpx;
+	width: 460rpx;
 	text-overflow: ellipsis;
 	overflow: hidden;
 	white-space: nowrap;

+ 29 - 29
pages/carLocation/carLocation.vue

@@ -7,7 +7,10 @@
 		</map>
 		<!-- #endif -->
 		<!-- #ifdef APP -->
-		<googleMap keyId="1" width='100%' height='calc(100vh - 506rpx)' v-if="myLocation.latitude"  :mapData="{type:3,markers,zoom:13}" :myLocation='myLocation'></googleMap>
+		<googleMap keyId="1" width='100%' height='calc(100vh - 506rpx)' v-if="car_info.latitude"  :mapData="{type:3,markers,zoom:13}" :myLocations='{
+			latitude:car_info.latitude,
+			longitude:car_info.longitude,
+		}'></googleMap>
 		<!-- #endif -->
 		<!-- 由于cover-view一些样式及点击事件不支持 -->
 		<!-- 气泡内容 -->
@@ -58,7 +61,10 @@ import googleMap from "@/component/googleMap/googleMap";
 		 */
 		onLoad: function(options) {
 			
-			this.car_info = uni.getStorageSync('car_info') || {}
+			let car_info = uni.getStorageSync('car_info') || {}
+			car_info.latitude = `${car_info.latitude}`
+			car_info.longitude = `${car_info.longitude}`
+			this.car_info = car_info
 			this.car_info.heart_time = this.car_info.heart_time ?  dayjs(this.car_info.heart_time*1000).format('YYYY-MM-DD hh:mm:ss') : '未知时间'
 			this.init()
 			// this.longitude = {
@@ -91,36 +97,30 @@ import googleMap from "@/component/googleMap/googleMap";
 		},
 		methods: {
 			init(){
-				this.latitude = this.car_info.latitude || 39.909
-				this.longitude = this.car_info.longitude || 116.39742
+				this.latitude = this.car_info.latitude 
+				this.longitude = this.car_info.longitude
 				this.getAddressName(this.latitude,this.longitude)
 				let _this = this
-				uni.getLocation({
-					success(res) {
-						_this.myLocation.latitude = res.latitude
-						_this.myLocation.longitude = res.longitude
-						_this.markers = [
-							{
-								width: 80 / 2,
-								height: 108 / 2,
-								id: _this.car_info.car_sn,
-								longitude: _this.longitude,
-								latitude: _this.latitude,
-								iconPath: 'https://qiniu.bms16.com/Fim2CWvIaWVoqPwQsJbNn-fcS-Ku',
-								iconPathActive: 'https://qiniu.bms16.com/Fim2CWvIaWVoqPwQsJbNn-fcS-Ku',
-								content:''
-							},
-							{
-								width: 22,
-								height: 40,
-								id: 50000,
-								iconPath: "https://zxappfile.bms16.com/zx_client/location_n.png",
-								longitude: res.longitude,
-								latitude: res.latitude,
-							}
-						]
+				_this.markers = [
+					{
+						width: 80 / 2,
+						height: 108 / 2,
+						id: _this.car_info.car_sn,
+						longitude: `${_this.longitude}`,
+						latitude: `${_this.latitude}`,
+						iconPath: 'https://qiniu.bms16.com/Fim2CWvIaWVoqPwQsJbNn-fcS-Ku',
+						iconPathActive: 'https://qiniu.bms16.com/Fim2CWvIaWVoqPwQsJbNn-fcS-Ku',
+						content:''
+					},
+					{
+						width: 22,
+						height: 40,
+						id: 50000,
+						iconPath: "https://zxappfile.bms16.com/zx_client/location_n.png",
+						longitude: _this.myLocation.longitude,
+						latitude: _this.myLocation.latitude,
 					}
-				})
+				]
 			},
 			navAddress() {
 				const that = this;

+ 3 - 1
pages/contract/contract.vue

@@ -21,7 +21,7 @@
 	const config = require('../../common/config.js');
 	var common = require('../../common/common.js');
 	var http = require('../../common/http.js');
-	var app = getApp();
+
 	export default {
 		data() {
 			return {
@@ -57,6 +57,7 @@
 		 * 生命周期函数--监听页面显示
 		 */
 		onShow: function() {
+			const app = getApp();
 			this.setData({
 				orderSign:app.globalData.orderSign,
 			    orderSignUrl:app.globalData.orderSignUrl
@@ -74,6 +75,7 @@
 				const accountInfo = wx.getAccountInfoSync() // 上报小程序账号信息
 				http.postApi(config.API_USER_INFO, { appid: accountInfo.miniProgram.appId }, function (resp) {
 					if (resp.data.code === 200) {
+						const app = getApp();
 						app.globalData.orderSign = resp.data.data.userInfo.order_sign
 						app.globalData.orderSignUrl = resp.data.data.userInfo.order_sign_url
 						me.setData({

+ 58 - 14
pages/dashboard/dashboard.vue

@@ -2,7 +2,7 @@
 	<view class="dashboard-page zx-page-linear">
 		<navBar bgColor="transparent"></navBar>
 		<view class="dashboard">
-			<view class="shadow" :style="{ '--progress': progress || 0 + '%' }"></view>
+			<view class="shadow" :style="{ '--progress': `${progress || 0}%` }"></view>
 			<view class="spe-wrap">
 				<view class="spe-num">
 					{{ infoList.speed || 0 }}
@@ -11,17 +11,24 @@
 			</view>
 			<view class="power-wrap">
 				<u-count-to :startVal="0" bold :endVal="progress || 0" fontSize="48rpx" />
+				<view class="em">W</view>
 			</view>
 		</view>
-
 		<view class="battery_life_progress">
-			<view :style="{width:((infoList.remain_mail || 0 / infoList.endurance || 0) * 100) + '%'}" class="is_progress"></view>
-			<view class="text ">
-				<text>续航</text>
-				<text> {{(infoList.remain_mail || 0/1000).toFixed(0) || 0}}km </text>
+			<view>
+				<view :style="{width:(((infoList.remain_mail || 0) / (infoList.endurance /1000) || 0) * 100) + '%'}"
+					class="is_progress"></view>
+				<view class="text">
+					<text style="margin-left: 20rpx;">续航</text>
+					<!-- <text style="margin-left: 16rpx;"> {{(infoList.remain_mail || 0/1000).toFixed(0) || 0}}km </text> -->
+					<text style="margin-left: 16rpx;"> {{ infoList.remain_mail > 0 ? infoList.remain_mail : 0 }}km </text>
+					
+				</view>
+			</view>
+			<view style="font-weight: 600;font-size: 36rpx;position: relative;z-index: 99;">
+				{{ (((infoList.remain_mail || 0) / (infoList.endurance /1000) || 0) * 100).toFixed(0) + '%' }}
 			</view>
 		</view>
-
 		<view class="info-container">
 			<view class="info-wrap" v-for="(item, index) in infoList.list" :key="index">
 				<view class="label">{{ item.label }}</view>
@@ -40,6 +47,7 @@
 		data() {
 			return {
 				speed: 50,
+				time:null,
 				infoList: {}
 			}
 		},
@@ -49,14 +57,24 @@
 				return this.infoList.speed / MAX_SPEED * 100
 			}
 		},
-		created() {
+		onLoad() {
 			let car_sn = uni.getStorageSync('car_info').car_sn
-			if(car_sn){
+			if (car_sn) {
 				this._initInfoList()
+				this.time = setInterval(()=>{
+					this._initInfoList()
+				},3000)
 			}
-			
+		},
+		onUnload() {
+			this.clearIntervalTimer()
 		},
 		methods: {
+			clearIntervalTimer() {
+				if (this.time == null) return
+				clearInterval(this.time)
+				this.time = null
+			},
 			async _initInfoList() {
 				let car_sn = uni.getStorageSync('car_info').car_sn
 				let {
@@ -73,7 +91,7 @@
 						},
 						{
 							label: '骑行时长',
-							prop: this.infoList.current_time || 0,
+							prop: (this.infoList.current_time / 60 /60).toFixed(2) || 0,
 							unit: 'h'
 						},
 						{
@@ -163,7 +181,7 @@
 				background: #D6E7FF;
 				border-radius: 64rpx;
 				position: absolute;
-				bottom: 22rpx;
+				bottom: 72rpx;
 				left: 50%;
 				transform: translateX(-50%);
 				display: flex;
@@ -173,17 +191,40 @@
 				font-weight: bold;
 				font-size: 48rpx;
 				color: #060809;
+				position: relative;
+				.em{
+					position: absolute;
+					right: -10rpx;
+					top: 0;
+					width: 54rpx;
+					height: 32rpx;
+					background: #0A59F7;
+					border-radius: 16rpx;
+					font-size: 22rpx;
+					line-height: 1;
+					color: #fff;
+					display: flex;
+					align-items: center;
+					justify-content: center;
+				}
 			}
 		}
 
 		.battery_life_progress {
+
+			display: flex;
+			justify-content: space-between;
+			align-items: center;
+
 			width: 100%;
 			margin-bottom: 40rpx;
+			padding-right: 40rpx;
 			background: #FFFFFF;
 			border-radius: 40rpx;
 			overflow: hidden;
 			position: relative;
 			height: 92rpx;
+
 			.is_progress {
 				min-width: 30%;
 				height: 100%;
@@ -194,7 +235,8 @@
 				left: 0;
 				top: 0;
 			}
-			.text{
+
+			.text {
 				position: relative;
 				z-index: 1;
 				font-size: 32rpx;
@@ -203,7 +245,8 @@
 				align-items: center;
 				height: 92rpx;
 				padding-left: 10rpx;
-				text{
+
+				text {
 					line-height: 1;
 				}
 			}
@@ -213,6 +256,7 @@
 			display: flex;
 			flex-wrap: wrap;
 			justify-content: space-between;
+
 			.info-wrap {
 				width: 336rpx;
 				margin-bottom: 14rpx;

+ 1 - 1
pages/deviceInfo/deviceInfo.vue

@@ -13,7 +13,7 @@
 			</view>
 			<view class="info-view">
 				<view class="info-title">车辆总里程</view>
-				<view class="info-value">{{(list.total_mil / 1000).toFixed(0)}}km</view>
+				<view class="info-value">{{(Number(list.total_mil) / 1000).toFixed(2)}}km</view>
 			</view>
 		</view>
 		<view class="flex-row">

+ 1 - 1
pages/index/components/AndroidUnlockAuth.vue

@@ -28,7 +28,6 @@
 </template>
 
 <script>
-	var app = getApp();
 	var common = require('@/common/common.js');
 	import permision from "@/js_sdk/wa-permission/permission.js"
 	// import mixin from '@/mixin/index.js'; // 引入 mixin
@@ -108,6 +107,7 @@ export default {
       }
     },
     linkTo() {
+      // const app = getApp();
 		// let isOpenAllPermission=false
 		// app.globalData.permissionArr.map(item=>{
 		// 	if(!item.state) isOpenAllPermission=true

+ 53 - 1
pages/index/components/control/control.css

@@ -150,4 +150,56 @@
 .ok-btn-pop{
 	color: #FFFFFF;
 	background: #060809;
-}
+}
+.power-view{
+	padding: 0 32rpx;
+	margin-bottom: 40rpx;
+}
+.power-on-off{
+	align-items: center;
+	flex-grow: 1;
+	margin-right: 14rpx;
+	height: 96rpx;
+	background: #FFFFFF;
+	border-radius: 48rpx;
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 600;
+	font-size: 32rpx;
+	color: #060809;
+	border: 4rpx solid #F1F3F4;
+}
+.power-on-btn{
+	height: 96rpx;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	width: 144rpx;
+	background: #060809;
+	border-radius: 52rpx;
+	border: 6rpx solid #FFF;
+}
+.power-on-text{
+	display:flex;
+	flex-grow: 1;
+	margin-left: 40rpx;
+	translateX:('-135px');
+}
+.car-change-battery{
+	align-items: center;
+	width: 272rpx;
+	height: 96rpx;
+	background: #FFFFFF;
+	border-radius: 48rpx;
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 500;
+	font-size: 32rpx;
+	color: #060809;
+	margin-left: 20rpx;
+	padding-left: 20rpx;
+}
+.car-change-text{
+	margin-left: 8rpx;
+	display: flex;
+	flex-grow: 1;
+}
+

+ 232 - 4
pages/index/components/control/control.vue

@@ -10,6 +10,22 @@
 				<text>{{$t("更多功能")}}</text>
 			</view>
 		</scroll-view>
+		<view class="flex-row power-view">
+			<!-- <view class="power-on-off flex-row" >
+				<view :style="sliderStyle" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" class="power-on-btn"><image style="width: 52rpx;height: 52rpx;" src="https://qiniu.bms16.com/Fkovrpq1bexe-Unal_VJREbLUhdu" mode=""></image></view>
+				<view class="power-on-text" >滑动启动</view>
+			</view> -->
+			<custom-switch @changEnd='changEnd'  :width="'400rpx'"
+				:height="'96rpx'"  :modelValue="switchValue" :fetchData="loadData"></custom-switch>
+				
+				
+			<!-- <custom-switch :defaultPosition="'right'" :width="'400rpx'" 
+			    :height="'96rpx'"  v-model="switchValue" :fetchData="loadData"></custom-switch> -->
+			<view @tap="navToInputPages" class="car-change-battery flex-row">
+				<view class="car-change-btn"><image style="width: 80rpx;height: 80rpx;" src="https://qiniu.bms16.com/FgvnT-msLbL5RHjl6fvNlM0kab5N" mode=""></image></view>
+				<view class="car-change-text">车辆换电</view>
+			</view>
+		</view>
 		<view v-if="popupControlShow" class="show-modal">
 			<view class="modal-info">
 				<view class="popup-title">{{($t(popText)==$t('开机'))?$t('开启车辆'):($t(popText)==$t('关机')?$t('关闭车辆'):$t(popText))}}</view>
@@ -57,16 +73,16 @@
 			</view>
 		</view>
    -->
-   
 	</view>
 </template>
 
 <script>
-	var app = getApp();
 	var bluetooth = require('@/common/bluetooth.js');
 	var config = require('@/common/config.js');
 	var common = require('@/common/common.js');
 	var http = require('@/common/http.js');
+	import CustomSwitch from '@/component/customSwitch.vue'; // 引入组件
+	
 	import controlMixin from '@/mixin/index';
 	import i18n from '@/locale/index.js'
 	import {
@@ -75,6 +91,7 @@
 		} from '@/common/storage.js';
 export default {
 	mixins: [controlMixin],
+	components:{CustomSwitch},
 	props:{
 		contrilList: {
 			type: Array,
@@ -85,24 +102,53 @@ export default {
 			default: false
 		},
 	},
-	
+
     data() {
         return {
 			// popText:'',
 			// popupControlShow:false,
 			// controlType:null,//选择的车辆控制
+			switchValue: {state:false,time:0},
 			isShowMore:false,
-			car_line:false
+			car_line:false,
+			// startX: 0, // 滑块开始滑动的初始位置
+			// moveX: 0, // 滑块滑动的距离
+			// unlocked: false, // 是否解锁成功的标志
+			
 		};
     },
+	computed: {
+	    // 计算滑块的样式
+	    sliderStyle() {
+	      return {
+	        transform: `translateX(${this.moveX}px)`
+	      };
+	    }
+	},
 	mounted() {
 		// this.contrilList = getFunctionTag().activeTag
+		// setTimeout(()=>{
+			this.switchValue.state=uni.getStorageSync('car_info').acc_state==1
+		// },50)
+		
+		// setTimeout(()=>{
+		// 	console.log(this.switchValue)
+		// },5000)
+		
 	},
  
     /**
      * 组件的方法列表
      */
     methods: {
+		changEnd(e){
+			this.switchValue = JSON.parse(e)
+			if(this.switchValue.type==1){
+				const car_sn= uni.getStorageSync('car_info').car_sn
+				this.$emit('loadCarDetail',car_sn)
+			}
+			console.log(this.switchValue)
+		},
 		tapOpen(e){
 				const item = e.currentTarget.dataset.item;
 				this.changClick(item)
@@ -111,6 +157,188 @@ export default {
 			uni.navigateTo({
 				url: '/pages/carFunctionSet/more?online='+this.online
 			})
+		},
+		trunOn(type){
+			
+			if (this.carOnline) {
+				//开机1 关机0
+				const car_sn= uni.getStorageSync('car_info').car_sn;
+				const pData = {
+					car_sn,
+					switch: switchType
+				}
+				const me=this
+				common.loading();
+				http.postApi(config.API_FLK_CAR_SWITCH, pData, (resp) => {
+					uni.hideLoading();
+					if (resp.data.code === 200) {
+						common.simpleToast(me.popText + '成功');
+						const activeTag = me.contrilList.map(item => {
+							if('isLock' in item){
+								item.isTurnOn = (item.isTurnOn == 1) ? 0 : 1
+								item.name = i18n.t((item.isTurnOn == 1) ? '关机' : '开机')
+							}
+							return item
+						})
+						const tag = getFunctionTag().tag
+						setFunctionTag({
+							activeTag,
+							tag
+						})
+						me.$emit('loadCarDetail',pData,car_sn)
+					} else {
+						common.simpleToast(resp.data.msg);
+					}
+				});
+			}else{
+				//车辆离线
+				const car_sn= uni.getStorageSync('car_info').car_sn;
+				common.loading();
+				if (type==1) {
+					bluetooth.turnOnCar(car_sn, () => {
+						uni.hideLoading();
+					});
+				}else{
+					bluetooth.turnOffCar(car_sn, () => {
+						uni.hideLoading();
+					});
+				}
+			}
+		},
+		async navToInputPages() {
+			const me = this
+			const exchange_need_package=uni.getStorageSync('car_info').exchange_need_package;
+			if(exchange_need_package==0){
+				uni.scanCode({
+					scanType:['qrCode'],
+					success(res) {
+						me.loadGeneralQRData(res.result)
+					},
+					fail() {
+						me.$msg('扫码失败,请重新扫码')
+					}
+				})
+			}else if(exchange_need_package==1){
+				uni.showModal({
+					title: '温馨提示',
+					content: '您还未购买换电套餐,是否前往购买换电套餐?',
+					showCancel: true,
+					cancelText: '取消',
+					confirmText: '前往购买',
+					success: function(res) {
+						if (res.confirm) {
+							uni.navigateTo({
+								url: `/pages/batteryPackage/batteryPackage`
+							})
+							
+						}
+					},
+					fail: function(res) {},
+					complete: function(res) {},
+				})
+			}else if(exchange_need_package==-1){
+				this.$msg('当前车辆暂未绑定电池')
+			}
+			
+		},
+		loadGeneralQRData(options) {
+			console.log(options)
+			let objOpt = this.$paramsObj(options)
+			
+			if (objOpt.d) {
+				console.log('扫码的是机柜')
+				uni.navigateTo({
+					url: `/pages/cabinetDetail/cabinetDetail?dev_id=${objOpt.d}`,
+				})
+				return
+			} else {
+				console.log('扫码的是车辆')
+				this.$msg('请扫描机柜二维码')
+				return
+			}
+		},
+		
+		async loadData(state) {
+			// console.log(state,'state');
+			return new Promise((resolve,reject) => {
+				if (uni.getStorageSync('car_info').online==1) {
+								//开机1 关机0
+								const car_sn= uni.getStorageSync('car_info').car_sn;
+								const switchType= state?0:1;
+								const pData = {
+									car_sn,
+									switch: switchType
+								}
+								const me=this
+								http.postApi(config.API_FLK_CAR_SWITCH, pData, (resp) => {
+									if (resp.data.code === 200) {
+										//const textStr = (this.switchValue==0)?'开机':'关机'
+	
+										// const activeTag = me.contrilList.map(item => {
+										// 	if('isLock' in item){
+										// 		item.isTurnOn = (item.isTurnOn == 1) ? 0 : 1
+										// 		item.name = i18n.t((item.isTurnOn == 1) ? '关机' : '开机')
+										// 	}
+										// 	return item
+										// })
+										// const tag = getFunctionTag().tag
+										// setFunctionTag({
+										// 	activeTag,
+										// 	tag
+										// })
+										
+										setTimeout(() => {
+										
+											resolve(JSON.stringify({
+												state:!state,
+												type:1,
+												time: Math.floor(Date.now() / 1000)
+											}))
+											console.log(132);
+											
+											// me.switchValue = JSON.stringify({
+											// 	state:!state,
+											// 	time: Math.floor(Date.now() / 1000)
+											// })
+										}, 1000)
+										
+									} else {
+										 setTimeout(() => {
+										 	resolve(JSON.stringify({
+										 		state:state,
+												type:2,
+										 		time:Math.floor(Date.now() / 1000)
+										 	}))
+										 	//this.switchValue=!this.switchValue
+										 	// this.switchValue = JSON.stringify({
+										 	// 	state:this.switchValue.state,
+										 	// 	time:Math.floor(Date.now() / 1000)
+										 	// })
+											// common.simpleToast(resp.data.msg);
+										 }, 1000)
+										//setTimeout(resolve, 1000);
+										
+									}
+								});
+							}else{
+								//车辆离线
+								const car_sn= uni.getStorageSync('car_info').car_sn;
+								const switchType= state;
+								common.loading();
+								if (!switchType) {
+									bluetooth.turnOnCar(car_sn, () => {
+										uni.hideLoading();
+									});
+								}else{
+									bluetooth.turnOffCar(car_sn, () => {
+										uni.hideLoading();
+									});
+								}
+							}
+				// console.log(me.switchValue,'this.switchValue');
+				// // this.trunOn()
+				// setTimeout(resolve, 1000); // 模拟 5 秒请求时间
+			});
 		}
 		// tapOpen(e){
 		// 	this.carOnline=this.online

+ 4 - 4
pages/index/components/mapCard/mapCard.vue

@@ -6,7 +6,7 @@
 				<cover-image class='img' style="width: 36rpx;height: 36rpx;" src="https://qiniu.bms16.com/FrKY7Ex5za22plr39ddIsJcjFVpi" ></cover-image>
 				<cover-view class="text">车辆位置</cover-view>
 			</cover-view>
-			<googleMap keyId="1" width='100%' :height="height?'258rpx':'140rpx'" v-if="car_info.latitude"  :mapData="{type:3}" :myLocation='{
+			<googleMap keyId="1" width='100%' :height="height?'258rpx':'140rpx'" v-if="car_info.latitude"  :mapData="{type:3}" :myLocations='{
 				longitude:car_info.longitude,
 				latitude:car_info.latitude
 			}'></googleMap>
@@ -15,14 +15,14 @@
 		<!-- #endif -->
 		<!-- #ifndef APP -->
 		<map class="map"  :longitude="car_info.longitude"
-			:latitude="car_info.latitude" scale="16" show-location :style="{width:'300rpx',height: height?'258rpx':'140rpx'}" :markers="carLocation">
+			:latitude="car_info.latitude" scale="16" show-location :style="{width:'100%',height: height?'258rpx':'140rpx'}" :markers="carLocation">
 			<view class="top-car-location flex-row">
 				<img style="width: 36rpx;height: 36rpx;" src="https://qiniu.bms16.com/FrKY7Ex5za22plr39ddIsJcjFVpi" alt="">
 				<text>车辆位置</text>
 			</view>
 		</map>
 		<!-- #endif -->
-		<view  class="car-address">{{carAddress}}</view>
+		<view class="car-address">{{carAddress}}</view>
 	</view>
 </template>
 
@@ -144,7 +144,7 @@
 	height: 80rpx;
 	line-height: 80rpx;
 	text-align: center;
-	width: 300rpx;
+	width: 324rpx;
 	white-space: nowrap;
 	overflow: hidden;
 	text-overflow: ellipsis;

+ 9 - 2
pages/index/components/unleasedPages/unleasedPages.vue

@@ -62,15 +62,17 @@
 						<view class="car-speed">52 <text class="company">km/h</text></view>
 						<text>极速可达</text>
 					</view> -->
+					
 				</view>
-				<view class="flex-row" @tap="navCarDetail" style="justify-content: center;">
+				<view class="flex-row" @tap="navCarDetail1" style="justify-content: center;">
 					<view class="more-btn flex-row">
 						<view class="more-btn-text">了解更多</view>
 						<img class="more-btn-img" src="https://qiniu.bms16.com/Fi2Lg800Mc1MhCnvHT1DkvOEdJB1" alt="">
 					</view>
 				</view>
+				<view style="height: 160rpx;"></view>
 				<view class="flex-row flex-around">
-					<view @tap="navCarDetail" class="lease-btn">租赁设备</view>
+					<view @tap="navCarDetail1" class="lease-btn">租赁设备</view>
 					<view class="binding-btn">绑定设备</view>
 				</view>
 			</view>
@@ -137,6 +139,11 @@
 					model_id: this.model_list[e].model_id
 				})
 			},
+			navCarDetail1(){
+				uni.switchTab({
+					url:"/pages/service/service"
+				});
+			},
 			navCarDetail() {
 				const me = this
 				uni.navigateTo({

+ 24 - 4
pages/index/index.css

@@ -5,7 +5,7 @@
 	align-items: center;
 }
 .padding_about_40{
-	padding: 26rpx 0rpx 44rpx 40rpx;
+	padding: 26rpx 0rpx 20rpx 40rpx;
 }
 .car-img-view{
 	padding: 0 40rpx;
@@ -18,7 +18,8 @@
 	flex-direction: column;
 	line-height: 1;
 	align-items: flex-start;
-	position: absolute;
+	/* position: absolute;
+	z-index: 100; */
 }
 .car-name-view{
 	font-weight: 600;
@@ -32,7 +33,7 @@
 	align-items: baseline;
 }
 .car-name-view .text{
-	width: 200rpx;
+	max-width: 200rpx;
 	white-space: nowrap;
 	text-overflow: ellipsis;
 	overflow: hidden;
@@ -51,7 +52,7 @@
 	text-align:center;
 	display: flex;
 	align-items: baseline;
-	margin-top: 20rpx;
+	margin-top: 14rpx;
 }
 .update-time-view{
 	justify-content: center;
@@ -76,6 +77,8 @@
 	flex-grow: 1;
 	height: 100%;
 	margin-left:20rpx;
+	display: flex;
+	flex-direction: column;
 }
 .card-top-title{
 	margin-bottom: 20rpx;
@@ -184,4 +187,21 @@
 	color: #FFFFFF;
 	text-align: center;
 	width: 148rpx;
+}
+.return-car-btn{
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 600;
+	font-size: 28rpx;
+	color: #060809;
+	width: 220rpx;
+	height: 62rpx;
+	justify-content: center;
+	align-items: center;
+	background: rgba(255,255,255,0.32);
+	border-radius: 40rpx;
+}
+.custom-swiper-view{
+	width: 100%;
+	height: 480rpx;
+	margin: 10rpx 0;
 }

+ 115 - 80
pages/index/index.vue

@@ -1,7 +1,7 @@
 <template>
 	<view>
 		<!-- #ifdef APP -->
-		<u-no-network zIndex='9999' @retry='retry'></u-no-network>
+		<u-no-network zIndex='9' @retry='retry'></u-no-network>
 		<!-- #endif -->
 		<view v-if="isConnected">
 			<block v-if="isLogin && car_info.car_sn">
@@ -19,9 +19,9 @@
 							<img src="https://qiniu.bms16.com/FoSXDpVGvbdmwbX3CMUBvR7X4IzI"
 								style="width: 14rpx;height: 14rpx;" alt="">
 						</view>
-						<view @click="routerLink('/pages/message/index')" class="news">
-							<view v-if="(newsList.plate_count + newsList.device_count) > 0" class="num">
-								{{newsList.plate_count + newsList.device_count}}
+						<view @click="routerLink('/pages/message/index?isSys=0')" class="news">
+							<view v-if="newsList.device_count > 0" class="num">
+								{{ newsList.device_count}}
 							</view>
 							<image src="https://qiniu.bms16.com/FtlfBtBE5-TeTI5EdrciX_u8u_Sx"
 								style="width: 48rpx;height: 48rpx;" mode=""></image>
@@ -43,33 +43,46 @@
 						</view>
 						<view @click="routerLink('/pages/order/order')" class="renew-btn">去续费</view>
 					</view>
-					<view class="car-img-view" @tap="toMoreInfoPage">
-						<view class="quantity-view flex-row">
+					<view class="car-img-view" >
+						<view v-if="!car_info.sold_time" class="flex-row flex-between" style="align-items: center;">
 							<text class="quantity flex-row">{{car_info.soc}} <text
 									style="font-size: 28rpx;font-weight: 500;">%</text></text>
+							<view @tap.stop="tapReturnCar" class="return-car-btn flex-row">
+								<image style="width: 46rpx;height: 46rpx;" src="https://qiniu.bms16.com/FtyG7Gq2QBaVVrZmTnmZFzXhE5nN" mode=""></image>
+								<view style="margin-left: 12rpx;">我要还车</view>
+							</view>
+						</view>
+						<view class="quantity-view flex-row">
 							<u-line-progress style="width: 100rpx;" active-color="#2ADA62" height="10"
 								:show-percent="false" :percent="car_info.soc"></u-line-progress>
 							<view class="quantity-text flex-row">
 								<view style="font-weight:400;font-size: 22rpx;width: 44rpx;">{{$t("续航")}}</view>
-								<view style="font-size: 36rpx;">{{formatDistance(car_info.endurance) }}<text
-										style="font-size: 30rpx;">{{car_info.endurance>1000?'km':'m'}}</text></view>
+								<view style="font-size: 36rpx;">{{formatDistance(car_info.remain_mail) }}<text style="font-size: 30rpx;">{{car_info.remain_mail ? car_info.remain_mail>1000?'km':'m' :'km'}}</text></view>
 							</view>
 						</view>
 						<!-- <img :src="car_info.model_images||'https://qiniu.bms16.com/Fg8_p7083jpsy8BXG4bR6yMs7jQX'" style="width: 100%;height: 526rpx;" alt=""> -->
-						<img :src="'https://qiniu.bms16.com/Fg8_p7083jpsy8BXG4bR6yMs7jQX'"
-							style="width: 100%;height: 526rpx;" alt="">
+						<!-- <img :src="'https://qiniu.bms16.com/Fg8_p7083jpsy8BXG4bR6yMs7jQX'"
+							style="width: 100%;height: 526rpx;" alt=""> -->
+							<view class="custom-swiper-view">
+								<u-swiper @click="toMoreInfoPage" v-if="car_image.length!=0" :list="car_image"  :autoplay="false" mode="none"
+									 :height="480" bgColor="transparent" class="custom-swiper">
+								</u-swiper>
+								<image @click="toMoreInfoPage" v-else style="width: 100%;height: 480rpx;" src="https://qiniu.bms16.com/Fg8_p7083jpsy8BXG4bR6yMs7jQX" mode="">
+								</image>
+							</view>
+							
 						<view class="flex-row align-center update-time-view">
-							<text  style="margin-right: 10rpx;">{{car_info.acc_state==1?$t("车辆已开机"): $t("车辆已关机")}} </text>
+							<text  style="margin-right: 10rpx;">{{car_info.online==1&&car_info.acc_state==1?$t("车辆已开机"): $t("车辆已关机")}} </text>
 							<text v-if="car_info.heart_time != 0" style="margin-right: 10rpx;">{{$t("更新于")}} {{tools.formatTime( car_info.heart_time|| '')}}</text>
 							<img :src="'https://qiniu.bms16.com/'+(isBluethConnect?'Fk3f9H_o-1Wq2xXx7I_xo7bxK1xJ':'FsL6XWGoIhfsVB7jRg6EGFVsuaTZ')"
 								:style="{width: (isBluethConnect?32:24)+'rpx',height: '32rpx'}" alt="">
 						</view>
 					</view>
-					<Control :contrilList="contrilList" @toBluetooth="inductiveUnlockHandle"/>
-			
+					<Control :contrilList="contrilList" @toBluetooth="inductiveUnlockHandle" @loadCarDetail="loadCarDetail"/>
+					
 			
 					<view :class="['flex-row', 'flex-between', 'map-card-view',car_info.exchange_package_info && car_info.exchange_package_info.activity_time?'height_362':'height_260']">
-						<MapCard :car_info="car_info" :height="car_info.exchange_package_info && car_info.exchange_package_info.activity_time"/>
+						<MapCard :car_info="car_info" :height="!!(car_info.exchange_package_info && car_info.exchange_package_info.activity_time)"/>
 			
 						<view class="card-right">
 							<view class="card-bg" @tap="navTravelingTrack">
@@ -106,6 +119,8 @@
 							</view>
 						</view>
 					</view>
+					<!-- <custom-switch :defaultPosition="'right'" :width="'400rpx'"
+					    :height="'96rpx'"  v-model="switchValue" :fetchData="loadData"></custom-switch> -->
 					<view class="config-view">
 						<view @tap="navToPage" class="flex-row config-car-view">
 							<view class="margin_r_20"><img class="icon_style_64"
@@ -153,12 +168,13 @@
 			<IosUnlockAuth :authStepList="authStepList" :value="isShowPermission" @closePermission="closePermission"
 				v-else-if="isShowPermission && (platform === 'ios')" />
 		</view>
+		<returnCar :isShowReturnCar="isShowReturnCar" typePage="index" @closeShowReturnCarBtn="()=>isShowReturnCar=false"
+			@navStoreBtn="navStoreBtn" @immediatelyReturnBtn="immediatelyReturnBtn" />
 	</view>
 </template>
 <script module="tools" lang="wxs" src="@/pages/common/wxs/tools.wxs"></script>
 <script module="tools" lang="sjs" src="@/pages/common/wxs/tools.sjs"></script>
 <script>
-	var app = getApp();
 	var config = require('@/common/config.js');
 	var config_gyq = require('@/common/config_gyq.js');
 	var common = require('@/common/common.js');
@@ -172,15 +188,18 @@
 	import BluetoothUnlockAuth from '../bluetoothUnlock/bluetoothUnlockAuth.vue'
 	import AndroidUnlockAuth from './components/AndroidUnlockAuth.vue'
 	import IosUnlockAuth from './components/IosUnlockAuth.vue'
+	import ReturnCar from '@/component/returnCar/returnCar';
+	
 	import {
 		getFunctionTag,
 	} from '@/common/storage.js';
 	import permision from "@/js_sdk/wa-permission/permission.js"
-	var bluetooth = require('@/common/bluetooth.js');
+	let bluetooth = require('@/common/bluetooth.js');
 
 	export default {
 		data() {
 			return {
+				time:null,
 				isModel: false,
 				isConnected: false,
 				statusBarHeight: 0,
@@ -204,6 +223,9 @@
 				statusBarHeight: 0,
 				isBluethConnect: false, //当前是否蓝牙连接或者配对
 				isOpenAllPermission: false, //所有蓝牙配对所需权限是否已开启
+				isShowReturnCar:false,
+				overdueData:{},
+				car_image:[]
 			};
 		},
 		computed: {},
@@ -214,14 +236,14 @@
 			UnleasedPages,
 			BluetoothUnlockAuth,
 			AndroidUnlockAuth,
-			IosUnlockAuth
+			IosUnlockAuth,
+			ReturnCar
 		},
 
 		/**
 		 * 生命周期函数--监听页面加载
 		 */
 		onLoad: function(options) {
-			this.locationFn()
 			this.statusBarHeight = uni.getSystemInfoSync().statusBarHeight || 0
 			let _this = this
 			// #ifdef APP
@@ -274,14 +296,23 @@
 				path: 'pages/index/index',
 			}
 		},
+		onUnload() {
+			this.clearIntervalTimer()
+		},
 		methods: {
+			clearIntervalTimer() {
+				if (this.time == null) return
+				clearInterval(this.time)
+				this.time = null
+			},
 			init() {
+				
 				this.loadModelList()
 				this.contrilList = getFunctionTag().activeTag
 				const user_token = storage.getUserToken()
 				this.car_info = uni.getStorageSync('car_info') || {};
-				this.isBluethConnect = app.globalData.connectionState[this.car_sn] && app.globalData.connectionState[this
-					.car_sn].connected && app.globalData.nearLockCheck
+				const app = getApp();
+				this.isBluethConnect =  app.globalData.nearLockCheck
 				if (!user_token) return
 				this.newsNumFn()
 				this.isLogin = true
@@ -305,7 +336,7 @@
 				// }
 			},
 			retry() {
-				console.log('115555')
+				
 			},
 			async newsNumFn() {
 				let {
@@ -315,17 +346,7 @@
 					this.newsList = data.data
 				}
 			},
-			locationFn() {
-				uni.getLocation({
-					success(res) {
-						let myLocation = {
-							latitude: res.latitude,
-							longitude: res.longitude,
-						}
-						storage.setUserCurrentLocation(myLocation)
-					}
-				})
-			},
+	
 			changCar(e) {
 				this.car_info = e
 			},
@@ -411,49 +432,6 @@
 				uni.navigateTo({
 					url: url
 				});
-				// if (me.userInfo.is_auth - 0 == 1 && me.userInfo.status - 0 == 2) {
-				// 	uni.navigateTo({
-				// 		url: url
-				// 	});
-				// } else if (me.userInfo.is_auth - 0 == 1 && me.userInfo.status - 0 != 2) {
-				// 	uni.showModal({
-				// 		title: '身份认证提示',
-				// 		content: '尚未完成身份认证,是否进行身份认证?',
-				// 		cancelText: '取消',
-				// 		confirmText: '确定',
-				// 		success: function(res) {
-				// 			if (res.confirm) {
-				// 				me.loadFaceToken()
-				// 			}
-				// 		},
-				// 		fail: function(res) {},
-				// 		complete: function(res) {},
-				// 	})
-				// } else {
-				// 	uni.showModal({
-				// 		title: '提示',
-				// 		content: '您还未登录,请先登录',
-				// 		showCancel: true,
-				// 		cancelText: '取消',
-				// 		confirmText: '确定',
-				// 		success: function(res) {
-				// 			if (res.confirm) {
-				// 				//#ifdef MP-ALIPAY
-				// 				uni.navigateTo({
-				// 					url: '/pages/phoneLogin/phoneLogin',
-				// 				})
-				// 				//#endif
-				// 				//#ifdef MP-WEIXIN
-				// 				uni.navigateTo({
-				// 					url: '/pages/login/login',
-				// 				})
-				// 				//#endif
-				// 			}
-				// 		},
-				// 		fail: function(res) {},
-				// 		complete: function(res) {},
-				// 	})
-				// }
 			},
 			loadUserCarList() {
 				const me = this
@@ -496,13 +474,15 @@
 					car_sn
 				}, (resp) => {
 					uni.hideLoading();
+					console.log(resp.data)
 					if (resp.data.code === 200) {
 						resp.data.data.car_sn = car_sn
+						const _car_image=resp.data.data.model_images?resp.data.data.model_images.split(','):[]
 						me.setData({
 							car_info: resp.data.data,
+							car_image:_car_image
 						})
 						uni.setStorageSync('car_info', this.car_info);
-						console.log(this.car_info, 'this.car_info------------------');
 						//判断逾期
 						if (!resp.data.data.sold_time) return
 						let time = Math.ceil(resp.data.data.hire_end_time - Math.floor(new Date()) / 1000) / 60
@@ -512,9 +492,13 @@
 						} else {
 							this.isOverdueShow = false
 						}
-
+						if(!this.time){
+							this.time = setInterval(()=>{
+								this.loadCarDetail(car_sn)
+							},5000)
+						}
 					} else {
-						common.simpleToast(resp.data.msg);
+						// common.simpleToast(resp.data.msg);
 					}
 				})
 			},
@@ -526,6 +510,7 @@
 				})
 			},
 			formatDistance(distanceMeters) {
+				console.log(distanceMeters,'distanceMeters');
 				// 判断距离是否超过1000米  
 				// let distanceMeters=Number(_distanceMeters)
 				if (distanceMeters >= 1000) {
@@ -533,10 +518,59 @@
 					return (distanceMeters / 1000).toFixed(1);
 				} else {
 					// 否则直接返回米  
-					return distanceMeters.toFixed(0);
+					try {
+						return distanceMeters;
+					} catch (error) {
+						return 0;
+					}
+					
 				}
 			},
-
+			navStoreBtn() {
+				const {
+					latitude,
+					longitude,
+					address,
+					model_name
+				} = this.car_info
+				uni.openLocation({
+					latitude: latitude - 0,
+					longitude: longitude - 0,
+					scale: 15,
+					name: model_name,
+					address: address,
+					success: function(res) {}
+				});
+			},
+			tapReturnCar() {
+				this.overdueMoneyFn(this.car_info.car_sn)
+				this.setData({
+					isShowReturnCar: true
+				})
+			},
+			//逾期费用计算
+			async overdueMoneyFn(car_sn) {
+				let {
+					data
+				} = await request.postApi(config_gyq.API_FLK_CAR_OVERDUE_MONEY, {
+					car_sn
+				})
+				if (data.code == 200) {
+					this.overdueData = data.data
+				} else {
+					common.simpleToast(data.msg)
+				}
+			},
+			immediatelyReturnBtn() {
+				const {
+					car_sn,
+					model_id
+				} = this.car_info
+				//提交还车图片
+				uni.navigateTo({
+					url: `/pages/activation/activation?isReturnCar=${true}&model_id=${model_id}&car_sn=${car_sn}&isOverdue=${this.isOverdueShow}&overdueMoney=${this.overdueData.money}&overdueTime=${this.overdueData.time}&type=index`
+				});
+			},
 
 		}
 	};
@@ -563,6 +597,7 @@
 			line-height: 1;
 			background-color: #FA2918;
 			border-radius: 50%;
+			z-index: 99;
 		}
 	}
 </style>

+ 1 - 1
pages/login/login.vue

@@ -44,7 +44,6 @@
 	var http = require('../../common/http.js');
 	var storage = require('../../common/storage.js');
 	var encryption = require('../../common/encryption.js')
-	var app = getApp()
 	export default {
 		data() {
 			return {
@@ -186,6 +185,7 @@
 								uni.reLaunch({
 									url: '/pages/index/index',
 								})
+								const app = getApp();
 								let accounts = app.globalData.accountManagement
 								accounts.push(accountsData2)
 								if (accounts.length > 0) {

+ 2 - 2
pages/loginRegister/changePassword.vue

@@ -62,10 +62,10 @@ export default {
 			if(res[1].confirm){
 				let {data} = await http.postApi(config.API_FLK_ACCOUNT_IMODIFY_PASSWD,this.form)
 				if(data.code == 200){
-					common.simpleToast(this.$t('修改成功'))
+					common.simpleToast(this.$t('修改成功,请重新登录'))
 					storage.removeUserToken()
 					uni.removeStorageSync('USER_INFO_DATA')
-					uni.redirectTo({
+					uni.reLaunch({
 						url:'/pages/loginRegister/login'
 					})
 				}else{

+ 1 - 1
pages/loginRegister/forgetPassword.vue

@@ -40,7 +40,7 @@ export default {
     },
     computed: {
         noticeText({ email }) {
-            return `我们向 <span style="color: #0A59F7;">${email}</span> 发送了一封密码重置邮件,请您登录邮箱操作处理。`
+            return `我们向 <span style="color: #0A59F7;">${email}</span> 发送了一封密码重置邮件,请您登录邮箱操作处理。`
         }
     },
     methods: {

+ 10 - 10
pages/loginRegister/login.vue

@@ -2,7 +2,7 @@
     <view class="zx-page-linear login-page">
 		<navBar type="login" left="0" bgColor="transparent"></navBar>
       <view class="title-wrap">
-        <view class="title">{{ $t('欢迎来到智寻出行') }}</view>
+        <view class="title">{{ $t('欢迎来到FRANCO MORINI') }}</view>
         <view class="sub-title">{{ $t('邮箱密码登录') }}</view>
       </view>
       <view class="main">
@@ -40,13 +40,13 @@
             {{ $t('没有账号 立即注册') }}
           </view>
         </view>
-        <view class="other-type-login">
+<!--        <view class="other-type-login">
           <view class="title">{{ $t('其他方式登录') }}</view>
           <view class="types">
             <image :src="QINIU_URL + 'Fg14B6UDuR6pLD1uR10mBE_y2vbf'" class="icon" />
             <image :src="QINIU_URL + 'FlZRWQZ301H8rP2_LwUdjnSUTQop'" class="icon" />
           </view>
-        </view>
+        </view> -->
       </view>
     </view>
   </template>
@@ -215,13 +215,13 @@
             .forget {
                 display: flex;
                 align-items: center;
-                &::after {
-                    content: "";
-                    width: 28rpx;
-                    height: 28rpx;
-                    background: url('https://qiniu.bms16.com/FrQ-eKUnkECvMImnNgd4w3p5-NLd');
-                    background-size: 100%;
-                }
+                // &::after {
+                //     content: "";
+                //     width: 28rpx;
+                //     height: 28rpx;
+                //     background: url('https://qiniu.bms16.com/FrQ-eKUnkECvMImnNgd4w3p5-NLd');
+                //     background-size: 100%;
+                // }
             }
   
             .register {

+ 1 - 1
pages/loginRegister/register.vue

@@ -34,7 +34,7 @@
             type="register"
 			@close='close'
             :email="form.email"
-            :text="$t(`我们已向 <span>${this.form.email}</span> 发送注册邮件,请您登录邮箱点击链接完成注册。`)"
+            :text="`我们已向 <span>${this.form.email}</span> 发送注册邮件,请您登录邮箱点击链接完成注册。`"
             v-model="isSendSucceed"
         />
     </view>

+ 83 - 0
pages/message/carLocation.css

@@ -0,0 +1,83 @@
+.container {
+	
+}
+
+.custom-bubble {
+	font-size: 28rpx;
+	position: absolute;
+}
+
+.custom-bubble-name {
+	font-weight: 600;
+	font-size: 36rpx;
+	color: #060809;
+	margin-bottom: 16rpx;
+}
+
+.custom-bubble-btn {
+	color: #ffffff;
+	background-color: #2A3A5A;
+	padding: 20rpx 32rpx;
+	border-radius: 0 34rpx 34rpx 0;
+}
+.block-view{
+	border-radius: 40rpx 40rpx 0rpx 0rpx;
+	overflow: hidden;
+	z-index: 100;
+	position: fixed;
+	bottom: 0;
+	width: 100%;
+	background-color: #FFFFFF;
+	height: 506rpx;
+	padding: 32rpx
+}
+	
+.block-car-time{
+	border-radius: 16rpx;
+	border: 3rpx solid #E7EAEE;
+	padding: 6rpx 24rpx 6rpx 6rpx;
+	
+	font-weight: 400;
+	font-size: 28rpx;
+	color: #353738;
+}
+.align-center{
+	align-items: center;
+}
+.car-time-text{
+	font-weight: 400;
+	font-size: 28rpx;
+	color: #353738;
+}
+.car-time-text-b{
+	font-family: DIN, DIN;
+	font-weight: 600;
+	font-size: 34rpx;
+	color: #0A59F7;
+	margin: 0 4rpx;
+}
+.car-nav-btn{
+	width: 112rpx;
+	height: 64rpx;
+	background: #060809;
+	border-radius: 32rpx;
+}
+.updata-time{
+	width: 100%;
+	text-align: center;
+	font-weight: 400;
+	font-size: 28rpx;
+	color: #060809;
+	margin: 80rpx 0 24rpx;
+}
+.car-config-btn{
+	height: 80rpx;
+	line-height: 80rpx;
+	width: 100%;
+	background: #060809;
+	border-radius: 40rpx;
+	text-align: center;
+	font-weight: 600;
+	font-size: 32rpx;
+	color: #FFFFFF;
+}

+ 84 - 0
pages/message/detail.vue

@@ -0,0 +1,84 @@
+<template>
+	<view class="container">
+		<navBar name="信息详情"></navBar>
+		<view class="title">{{info.title}}</view>
+		<view>{{info.overview}}</view>
+		<image v-if="info.cover" :src="info.cover" class="img" mode="aspectFit" />
+		<rich-text :nodes="info.content"></rich-text>
+		<location v-if="latlng.latitude && latlng.longitude" :latlng="latlng" />
+	</view>
+</template>
+
+<script>
+	const config = require('@/common/config.js');
+	const http = require('@/common/http.js');
+	const request = require('@/common/request.js');
+	const common = require('@/common/common.js');
+	import location from './location.vue'
+	export default {
+		data() {
+			return {
+				id: '',
+				info: {},
+				latlng: {
+					
+				}
+			}
+		},
+		components: {
+			location
+		},
+		onLoad(options) {
+			this.id = options.id
+			this.queryMsgDetail()
+		},
+		methods: {
+			queryMsgDetail() {
+				const req = {
+					type: 'PLAT',
+					id: Number(this.id)
+				}
+				http.postApi(config.API_MESSAGE_DTL, req, res => {
+					if (res.succeed) {
+						this.info = res.data.data
+						console.log(this.info)
+						// 正则匹配所有<img>标签并插入自适应属性
+						this.info.content = (this.info.content || '').replace(/<img/g,
+							'<img style="max-width: 100%; height: auto;"')
+
+
+						// this.info.latitude = 28.909
+						// this.info.longitude = 115.39742
+
+						if (this.info.latitude && this.info.longitude) {
+
+							this.latlng = {
+								latitude: this.info.latitude,
+								longitude: this.info.longitude
+							}
+						}
+					}
+				})
+
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.container {
+		display: flex;
+		flex-direction: column;
+		padding: 20rpx;
+
+		.title {
+			font-size: 36rpx;
+			font-weight: bold;
+			margin: 20rpx;
+		}
+
+		.img {
+			width: 750rpx;
+		}
+	}
+</style>

+ 0 - 120
pages/message/deviceInfo.vue

@@ -1,120 +0,0 @@
-<template>
-    <view class="zx-container deviceInfo-container">
-        <!-- <map style="width: 100%; height: 500px;" :latitude="latitude"
-			:longitude="longitude" :markers="markers" show-location>
-		</map> -->
-        <view v-for="(item, index) in msgList" :key="index" class="list-item">
-            <view class="time">{{ item.ctime }}</view>
-            <view class="msg-wrap">
-                <view v-if="item.latitude" class="map">
-					<!-- #ifdef APP -->
-					<googleMap :keyId="index" width="100%" height='100%'   :mapData='{type:1}' :myLocation='{
-					latitude:item.latitude,	
-					longitude:item.longitude,	
-					}'  ></googleMap>
-					<!-- #endif -->
-				</view>
-                <view class="msg-text">
-                    <view class="title">{{ item.title }}</view>
-                    <view class="dtl-txt">{{ item.overview }}</view>
-                </view>
-            </view>
-        </view>
-    </view>
-</template>
-
-<script>
-const config = require('@/common/config.js');
-const http = require('@/common/http.js');
-var common = require('../../common/common.js');
-import googleMap from "@/component/googleMap/googleMap";
-export default {
-	components:{
-		googleMap
-	},
-    data() {
-        return {
-            // latitude: 23.090994,
-			// longitude: 113.314004,
-            // markers: [{
-            //     id: 1345,
-            //     latitude: 23.090994,
-            //     longitude: 113.314004,
-            //     iconPath: 'https://qiniu.bms16.com/Fim2CWvIaWVoqPwQsJbNn-fcS-Ku',
-            //     width: 30,
-            //     height: 30,
-            //     customCallout: {
-            //         anchorY: -45, // Y轴偏移量
-            //         anchorX: -100, // X轴偏移量
-            //         display: 'ALWAYS', // 'BYCLICK':点击显示; 'ALWAYS':常显
-            //     },
-            // }], // 标记点
-            msgList: [
-                // { time: '今天 13:14', title: '车辆推动报警', overview: '车辆正在被人推送,请及时查看' },
-                // { time: '今天 13:14', title: '车辆推动报警', overview: '车辆正在被人推送,请及时查看' },
-                // { time: '今天 13:14', title: '车辆推动报警', overview: '车辆正在被人推送,请及时查看' },
-            ]
-        }
-    },
-    onLoad(option) {
-        this.queryList(option.car_id)
-    },
-    methods: {
-        queryList(car_id) {
-            http.postApi(config.API_MESSAGE_LIST, { car_id, msg_type: 'DEVICE' }, res => {
-                if (res.succeed) {
-                    this.msgList = res.body.data.list
-                    this.msgList.map(item => {
-                        item.ctime = common.formatTime(item.ctime)
-                    })
-                }
-            })
-        }
-    }
-}
-</script>
-
-<style lang="scss" scoped>
-@import "@/libs/css/layout.scss";
-.deviceInfo-container {
-    padding: 24rpx 24rpx 150rpx;
-    .list-item {
-        width: 100%;
-        .time {
-            font-family: Roboto, Roboto;
-            font-weight: 400;
-            font-size: 28rpx;
-            color: #060809;
-            text-align: center;
-            margin: 40rpx 24rpx;
-        }
-        .msg-wrap {
-            width: 100%;
-            background: #FFFFFF;
-            border-radius: 40rpx;
-            padding: 8rpx;
-            .map {
-                width: 100%;
-                height: 384rpx;
-                background: url('https://qiniu.bms16.com/FufXj_x1qGs3iy7itHZ9oJ3FqG_Q');
-                background-size: 100%;
-            }
-            .msg-text {
-                padding: 32rpx 24rpx 40rpx;
-                .title {
-                    font-family: PingFangSC, PingFang SC;
-                    font-weight: bold;
-                    font-size: 36rpx;
-                    color: #060809;
-                    margin-bottom: 16rpx;
-                }
-                .dtl-tet {
-                    font-family: PingFangSC, PingFang SC;
-                    font-size: 24rpx;
-                    color: #060809;
-                }
-            }
-        }
-    }
-}
-</style>

+ 344 - 233
pages/message/index.vue

@@ -1,242 +1,353 @@
 <template>
-    <view class="message-page">
-		<navBar name="我的消息"></navBar>
-        <view class="device-msg-wrap base-wrap" v-for="(item, index) in deviceList" :key="index"  @tap="toDeviceMsgPage(item)">
-            <view class="row">
-                <view class="title">
-                    <view>{{ $t('设备消息') }}</view>
-                    <view v-if="item.unread > 0" class="bage">{{ item.unread }}</view>
-                </view>
-                <view class="time">{{item.message_date}}</view>
-            </view>
-            <view class="device-info">
-                <image class="img" :src="item.image" />
-                <view class="info">
-                    <view class="name">{{ item.car_name }}</view>
-                    <view class="status">{{item.message_overview}}</view>
-                </view>
-            </view>
-        </view>
-        
-        <view style="margin-top: 20rpx;" class="sys-msg-wrap base-wrap">
-            <view class="title">{{ $t('系统消息') }}</view>
-            <view class="msg-item" v-for="(item, index) in sysMsgList" :key="index">
-                <view class="msg">
-                    {{ item.title }}
-                    <view v-if="item.type === 1" class="btn">绑定设备</view>
-                </view>
-                <view class="time">{{ item.ctime }}</view>
-                <view class="dtl">{{ item.overview }}</view>
-            </view>
-        </view>
-    </view>
+	<view class="message-page">
+		<navBar :name="isSys === '0' ? '设备信息' : '我的消息'"></navBar>
+		<view v-if="isSys==='0' && deviceList.length>0">
+			<view class="device-msg-wrap base-wrap" v-for="(item, index) in deviceList" :key="index"
+				@tap="toDeviceMsgPage(item)">
+				<view class="row">
+					<view class="title">
+						<view>{{ $t('设备消息') }}</view>
+						<view v-if="item.unread > 0" class="bage">{{ item.unread }}</view>
+					</view>
+					<view class="time">{{item.message_date}}</view>
+				</view>
+				<view class="device-info">
+					<image class="img" :src="item.image" />
+					<view class="info">
+						<view class="name">{{ item.car_name }}</view>
+						<view v-if="item.message_overview!==''" class="status">{{item.message_overview}}</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view v-if="isSys==='0' && deviceList.length === 0"
+			style="display: flex;align-items: center;justify-content: center;height: 80vh;">
+			您还没有设备消息
+		</view>
+
+		<view v-if="isSys==='1' && sysMsgList.length > 0 " style="margin-top: 20rpx;" class="sys-msg-wrap base-wrap">
+
+			<view class="row">
+				<view class="title" style="display: flex;">
+					<view>{{ $t('系统消息') }}</view>
+					<view v-if="unreadCount > 0" class="bage">{{ unreadCount }}</view>
+				</view>
+			</view>
+			<view @click="gotoDetail(item)" class="msg-item" v-for="(item, index) in sysMsgList" :key="index">
+				<view class="msg">
+					<view class="flex">
+						<view v-if="item.read == 0" class="dot"></view>
+						{{ item.title }}
+					</view>
+					<view v-if="item.type === 1" class="btn">绑定设备</view>
+				</view>
+				<view class="time">{{ formatTimestamp(item.ctime)}}</view>
+				<view class="dtl">{{ item.overview }}</view>
+			</view>
+		</view>
+
+		<view v-if="isSys==='1' && sysMsgList.length === 0 "
+			style="display: flex;align-items: center;justify-content: center;height: 80vh;">
+			您还没有系统消息
+		</view>
+	</view>
 </template>
 
 <script>
-const config = require('@/common/config.js');
-const http = require('@/common/http.js');
-const request = require('@/common/request.js');
-const common = require('@/common/common.js');
-export default {
-    data() {
-        return {
-            value: 10,
-            sysMsgList: [],
-            deviceList: [],
-            deviceInfo: {}
-        }
-    },
-    created() {
-        this.querySysMsgList()
-        this.queryDeviceMsg()
-		this.readMessage()
-    },
-    methods: {
-		async readMessage(){
-			await request.postApi(config.API_MESSAGE_READ_MESSAGE,{msg_type:2,car_id:0})
+	const config = require('@/common/config.js');
+	const http = require('@/common/http.js');
+	const request = require('@/common/request.js');
+	const common = require('@/common/common.js');
+	export default {
+		data() {
+			return {
+				value: 10,
+				sysMsgList: [],
+				deviceList: [],
+				deviceInfo: {},
+				isSys: '1',
+				unreadCount: 0
+			}
+		},
+		onLoad(options) {
+			this.isSys = options.isSys
+			
+		},
+		onShow(){
+			this.querySysMsgList()
+			this.queryDeviceMsg()
 		},
-        toDeviceMsgPage(itemData) {
-            const { car_id } = itemData
-            uni.navigateTo({ url: `/pages/message/deviceInfo?car_id=${car_id}` })
-        },
-        queryDeviceMsg() {
-            http.postApi(config.API_DEVICE_MSG, {}, res => {
-                if (res.succeed) {
-                    this.deviceList = res.body.data
-                    this.deviceList.map(item => {
-                        item.message_date = common.formatTime(item.message_date)
-                    })
-                }
-            })
-        },
-        querySysMsgList() {
-            http.postApi(config.API_MESSAGE_LIST, { msg_type: 'PLAT' }, res => {
-                if (res.succeed) {
-                    this.sysMsgList= res.body.data.list
-                    this.sysMsgList.map(item => {
-                        item.ctime = common.formatTime(item.ctime)
-                    })
-                }
-            })
-        }
-    }
-}
+		methods: {
+			formatTimestamp(timestamp, isUTC = false) {
+			  const isSeconds = timestamp.toString().length === 10;
+			  const date = isSeconds ? new Date(timestamp * 1000) : new Date(timestamp);
+			
+			  const pad = (num) => num.toString().padStart(2, '0');
+			
+			  if (isUTC) {
+			    return `${date.getUTCFullYear()}-${pad(date.getUTCMonth() + 1)}-${pad(date.getUTCDate())} ${pad(date.getUTCHours())}:${pad(date.getUTCMinutes())}:${pad(date.getUTCSeconds())}`;
+			  } else {
+			    return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
+			  }
+			},
+			async readMessage() {
+				await request.postApi(config.API_MESSAGE_READ_MESSAGE, {
+					msg_type: 2,
+					car_id: 0
+				})
+			},
+			gotoDetail(item) {
+				request.postApi(config.API_MESSAGE_READ_MESSAGE, {
+					msg_type: 2,
+					msg_id: item.plat_msg_id,
+					car_id: ''
+				})
+
+				uni.navigateTo({
+					url: `/pages/message/detail?id=${item.plat_msg_id}`
+				})
+			},
+			toDeviceMsgPage(item) {
+				request.postApi(config.API_MESSAGE_READ_MESSAGE, {
+					msg_type: 1,
+					car_id: item.car_id,
+					msg_id: item.id
+				})
+
+				uni.navigateTo({
+					url: `/pages/message/detail?id=${item.car_id}`
+				})
+			},
+			queryDeviceMsg() {
+				http.postApi(config.API_DEVICE_MSG, {}, res => {
+					if (res.succeed) {
+						this.deviceList = res.body.data
+						this.deviceList.map(item => {
+							item.message_date = common.formatTime(item.message_date)
+						})
+					}
+				})
+			},
+			querySysMsgList() {
+				http.postApi(config.API_MESSAGE_LIST, {
+					msg_type: 'PLAT'
+				}, res => {
+					if (res.succeed) {
+						this.sysMsgList = res.body.data.list
+						this.sysMsgList.map(item => {
+							item.ctime = common.formatTime(item.ctime)
+						})
+						this.unreadCount = this.sysMsgList.filter(item => item.read === "0").length;
+					}
+				})
+			}
+		}
+	}
 </script>
 
 <style lang="scss" scoped>
-.message-page {
-    width: 100%;
-    min-height: 100vh;
-    overflow: auto;
-    background: #F1F3F4;
-    padding: 0 24rpx;
-
-    .base-wrap {
-        background: #FFFFFF;
-        border-radius: 40rpx;
-        padding: 40rpx 32rpx 32rpx 32rpx;
-        width: 100%;
-    }
-
-    .device-msg-wrap {
-        margin: 24rpx 0;
-
-        .row {
-            margin-bottom: 40rpx;
-            display: flex;
-            justify-content: space-between;
-
-            .title {
-                font-family: PingFangSC, PingFang SC;
-                font-weight: 400;
-                font-size: 36rpx;
-                color: #060809;
-                position: relative;
-
-                .bage {
-                    position: absolute;
-                    left: 96%;
-                    top: -12rpx;
-                    background: #FA2918;
-                    font-family: Futura, Futura;
-                    font-weight: 500;
-                    font-size: 24rpx;
-                    color: #FFFFFF;
-                    display: inline-flex;
-                    justify-content: center;
-                    align-items: center;
-                    line-height: 16px;
-                    padding: 0 5px;
-                    border-radius: 68rpx;
-                    z-index: 9;
-                }
-            }
-
-            .time {
-                font-family: Futura, Futura;
-                font-weight: 500;
-                font-size: 32rpx;
-                color: #060809;
-            }
-        }
-
-        .device-info {
-            display: flex;
-            align-items: center;
-
-            .img {
-                width: 128rpx;
-                height: 128rpx;
-                background: #f2f2f2;
-                margin-right: 24rpx;
-            }
-
-            .info {
-                .name {
-                    font-family: PingFangSC, PingFang SC;
-                    font-weight: bold;
-                    font-size: 40rpx;
-                    color: #060809;
-                    margin-bottom: 32rpx;
-                }
-
-                .status {
-                    font-family: PingFangSC, PingFang SC;
-                    font-size: 32rpx;
-                    color: #426BF2;
-                    display: flex;
-
-                    &::before {
-                        content: "";
-                        width: 40rpx;
-                        height: 40rpx;
-                        margin-right: 16rpx;
-                        border-radius: 50%;
-                        background: url('https://qiniu.bms16.com/Foxu2x1lQKqT5K4LqrUtWIA6Lbw8');
-                        background-size: 100%;
-                    }
-                }
-            }
-        }
-    }
-
-    .sys-msg-wrap {
-        .title {
-            font-family: PingFangSC, PingFang SC;
-            font-weight: 400;
-            font-size: 36rpx;
-            color: #060809;
-        }
-
-        .msg-item {
-            padding: 40rpx 0;
-            border-bottom: 1px solid #F1F4F5;
-            &:last-child {
-                border-bottom: none;
-            }
-
-            .msg {
-                font-family: PingFangSC, PingFang SC;
-                font-weight: bold;
-                font-size: 36rpx;
-                color: #060809;
-                display: flex;
-                align-items: center;
-                justify-content: space-between;
-
-                .btn {
-                    width: 192rpx;
-                    height: 64rpx;
-                    background: #060809;
-                    border-radius: 32rpx;
-                    color: #fff;
-                    display: flex;
-                    align-items: center;
-                    justify-content: center;
-                    font-family: AlibabaPuHuiTiM;
-                    font-size: 32rpx;
-
-                    &:active {
-                        opacity: 0.8;
-                    }
-                }
-            }
-
-            .time {
-                font-family: Futura, Futura;
-                font-weight: 500;
-                font-size: 24rpx;
-                color: #060809;
-                margin: 16rpx 0 24rpx;
-            }
-
-            .dtl {
-                font-family: PingFangSC, PingFang SC;
-                font-weight: 400;
-                font-size: 24rpx;
-                color: #060809;
-            }
-        }
-    }
-}
+	.message-page {
+		width: 100%;
+		min-height: 100vh;
+		overflow: auto;
+		background: #F1F3F4;
+		padding: 0 24rpx;
+
+		.base-wrap {
+			background: #FFFFFF;
+			border-radius: 40rpx;
+			padding: 40rpx 32rpx 32rpx 32rpx;
+			width: 100%;
+		}
+
+		.device-msg-wrap {
+			margin: 24rpx 0;
+
+			.row {
+				margin-bottom: 40rpx;
+				display: flex;
+				justify-content: space-between;
+
+				.title {
+					font-family: PingFangSC, PingFang SC;
+					font-weight: 400;
+					font-size: 36rpx;
+					color: #060809;
+					position: relative;
+
+					.bage {
+						position: absolute;
+						left: 96%;
+						top: -12rpx;
+						background: #FA2918;
+						font-family: Futura, Futura;
+						font-weight: 500;
+						font-size: 24rpx;
+						color: #FFFFFF;
+						display: inline-flex;
+						justify-content: center;
+						align-items: center;
+						line-height: 16px;
+						padding: 0 5px;
+						border-radius: 68rpx;
+						z-index: 9;
+					}
+				}
+
+				.time {
+					font-family: Futura, Futura;
+					font-weight: 500;
+					font-size: 32rpx;
+					color: #060809;
+				}
+			}
+
+			.device-info {
+				display: flex;
+				align-items: center;
+
+				.img {
+					width: 128rpx;
+					height: 128rpx;
+					background: #f2f2f2;
+					margin-right: 24rpx;
+				}
+
+				.info {
+					.name {
+						font-family: PingFangSC, PingFang SC;
+						font-weight: bold;
+						font-size: 40rpx;
+						color: #060809;
+						margin-bottom: 32rpx;
+					}
+
+					.status {
+						font-family: PingFangSC, PingFang SC;
+						font-size: 32rpx;
+						color: #426BF2;
+						display: flex;
+
+						&::before {
+							content: "";
+							width: 40rpx;
+							height: 40rpx;
+							margin-right: 16rpx;
+							border-radius: 50%;
+							background: url('https://qiniu.bms16.com/Foxu2x1lQKqT5K4LqrUtWIA6Lbw8');
+							background-size: 100%;
+						}
+					}
+				}
+			}
+		}
+
+		.sys-msg-wrap {
+
+			.row {
+				margin-bottom: 40rpx;
+				display: flex;
+				justify-content: space-between;
+
+				.title {
+					font-family: PingFangSC, PingFang SC;
+					font-weight: 400;
+					font-size: 36rpx;
+					color: #060809;
+					position: relative;
+
+
+				}
+
+				.time {
+					font-family: Futura, Futura;
+					font-weight: 500;
+					font-size: 32rpx;
+					color: #060809;
+				}
+			}
+
+			.bage {
+				position: absolute;
+				left: 96%;
+				top: -12rpx;
+				background: #FA2918;
+				font-family: Futura, Futura;
+				font-weight: 500;
+				font-size: 24rpx;
+				color: #FFFFFF;
+				display: inline-flex;
+				justify-content: center;
+				align-items: center;
+				line-height: 16px;
+				padding: 0 5px;
+				border-radius: 68rpx;
+				z-index: 9;
+			}
+
+			.msg-item {
+				padding: 40rpx 0;
+				border-bottom: 1px solid #F1F4F5;
+
+				&:last-child {
+					border-bottom: none;
+				}
+
+				.flex {
+					display: flex;
+				}
+
+				.dot {
+					background: #FA2918;
+					width: 20rpx;
+					height: 20rpx;
+					border-radius: 50%;
+					margin-right: 5rpx;
+					margin-top: 10rpx;
+				}
+
+				.msg {
+					font-family: PingFangSC, PingFang SC;
+					font-weight: bold;
+					font-size: 36rpx;
+					color: #060809;
+					display: flex;
+					align-items: center;
+					justify-content: space-between;
+
+					.btn {
+						width: 192rpx;
+						height: 64rpx;
+						background: #060809;
+						border-radius: 32rpx;
+						color: #fff;
+						display: flex;
+						align-items: center;
+						justify-content: center;
+						font-family: AlibabaPuHuiTiM;
+						font-size: 32rpx;
+
+						&:active {
+							opacity: 0.8;
+						}
+					}
+				}
+
+				.time {
+					font-family: Futura, Futura;
+					font-weight: 500;
+					font-size: 24rpx;
+					color: #060809;
+					margin: 16rpx 0 24rpx;
+				}
+
+				.dtl {
+					font-family: PingFangSC, PingFang SC;
+					font-weight: 400;
+					font-size: 24rpx;
+					color: #060809;
+				}
+			}
+		}
+	}
 </style>

+ 219 - 0
pages/message/location.vue

@@ -0,0 +1,219 @@
+<template>
+	<view class="">
+
+		<!-- #ifndef APP -->
+		<map @touchmove="hiddenNav" @markertap="showNav" style="width: 100%; height: calc(100vh - 506rpx);"
+			:latitude="latitude" :longitude="longitude" :markers="markers" show-location>
+		</map>
+		<!-- #endif -->
+		<!-- #ifdef APP-PLUS -->
+		<googleMap width="100%" height="600rpx" :mapData="{type:3,markers,zoom:13}" :myLocations='myLocation'>
+		</googleMap>
+		<!-- #endif -->
+
+	</view>
+	</view>
+</template>
+
+<script>
+	import dayjs from "dayjs";
+	import googleMap from "@/component/googleMap/googleMap";
+	const http = require('../../common/request.js');
+	const config = require('../../common/config.js');
+	const common = require('../../common/common.js');
+	import controlMixin from '@/mixin/index';
+	export default {
+		mixins: [controlMixin],
+		components: {
+			googleMap
+		},
+		props: {
+			latlng: {
+				type: Object,
+				default: () => {
+
+				}
+			}
+		},
+		watch: {
+			latlng: {
+				handler: function(newVal) {
+					if (newVal) {
+						this.init()
+					}
+				},
+				immediate: true
+			}
+		},
+		data() {
+			return {
+				id: 0, // 使用 marker点击事件 需要填写id
+				address: '',
+				city_name: '',
+				is_show_nav: true,
+				myLocation: {
+					// latitude:39.909,
+					// longitude: 116.39742,
+				},
+				markers: [], // 标记点
+				plate_number: '',
+				carLocationTimer: null, // 定时器变量,用于清除定时器
+			}
+		},
+		/**
+		 * 生命周期函数--监听页面加载
+		 */
+		mounted() {},
+		/**
+		 * 生命周期函数--监听页面显示
+		 */
+		onShow: function() {},
+
+		/**
+		 * 生命周期函数--监听页面卸载
+		 */
+		onUnload() {
+
+		},
+		methods: {
+			init() {
+				this.myLocation.latitude = this.latlng.latitude || 28.909
+				this.myLocation.longitude = this.latlng.longitude || 115.39742
+				// this.getAddressName(this.myLocation.latitude, this.myLocation.longitude)
+				let _this = this
+				uni.getLocation({
+					success(res) {
+						_this.myLocation.latitude = res.latitude
+						_this.myLocation.longitude = res.longitude
+						_this.markers = [{
+								width: 80 / 2,
+								height: 108 / 2,
+								longitude: _this.myLocation.longitude,
+								latitude: _this.myLocation.latitude,
+								iconPath: 'https://qiniu.bms16.com/Fim2CWvIaWVoqPwQsJbNn-fcS-Ku',
+								iconPathActive: 'https://qiniu.bms16.com/Fim2CWvIaWVoqPwQsJbNn-fcS-Ku',
+								content: ''
+							},
+							{
+								width: 22,
+								height: 40,
+								id: 50000,
+								iconPath: "https://zxappfile.bms16.com/zx_client/location_n.png",
+								longitude: res.longitude,
+								latitude: res.latitude,
+							}
+						]
+					}
+				})
+			},
+			navAddress() {
+				const that = this;
+				uni.openLocation({
+					latitude: that.latitude - 0,
+					longitude: that.longitude - 0,
+					scale: 15,
+					name: that.city_name,
+					address: that.address_name,
+					success: function(res) {}
+				});
+			},
+
+			async loadCarAddress() {
+				const that = this
+				http.postApi(config.API_DAYHIRE_CAR_LOCATION, {
+					plate_number: this.plate_number
+				}, (resp) => {
+					if (resp.data.code === 200) {
+						this.latitude = resp.data.data.latitude
+						this.longitude = resp.data.data.longitude
+						this.markers[0].latitude = resp.data.data.latitude
+						this.markers[0].longitude = resp.data.data.longitude
+
+					} else {
+						// 默认返回上一个页面再提示报错
+						uni.navigateBack({
+							delta: 1
+						})
+						common.simpleToast(resp.data.msg)
+					}
+				})
+			},
+
+			async getAddressName(latitude, longitude) {
+				const that = this
+				//#ifdef MP-ALIPAY
+				var _pi = "ali_index"
+				//#endif
+				//#ifdef MP-WEIXIN
+				var _pi = "wx_index"
+				//#endif
+				//#ifdef APP
+				var _pi = "APP"
+				//#endif
+				const location = {
+					lat: that.latitude,
+					lng: that.longitude,
+					pi: _pi
+				}
+				let {
+					data
+				} = await http.postApi(config.API_MAP_REGEO, location)
+				console.log(data.data.data)
+				if (data.code == 200) {
+					this.address = data.data.data.address
+				}
+			},
+
+			hiddenNav() {
+				this.is_show_nav = false
+			},
+
+			showNav() {
+				this.is_show_nav = true
+			},
+
+			findCar() {
+				const me = this
+				uni.showModal({
+					title: '提示',
+					content: '您确认开启闪灯鸣笛吗',
+					showCancel: true,
+					cancelText: '取消',
+					confirmText: '确定',
+					success: function(res) {
+						if (res.confirm) {
+							me.setData({
+								popText: '闪灯鸣笛',
+								cmdType: 'findCar',
+							})
+							me.tapBlueToothCmd('', true)
+						}
+					},
+					fail: function(res) {},
+					complete: function(res) {},
+				})
+			},
+			navAddress() {
+				const {
+					latitude,
+					longitude,
+					cityname,
+					address,
+					model_name
+				} = this.car_info
+				uni.openLocation({
+					latitude: latitude - 0,
+					longitude: longitude - 0,
+					scale: 15,
+					name: model_name,
+					address: address,
+					success: function(res) {}
+				});
+			}
+		}
+	};
+</script>
+
+<style>
+	@import './carLocation.css';
+</style>

+ 11 - 6
pages/my/my.vue

@@ -6,9 +6,9 @@
 		<!-- #ifdef APP -->
 		<view :style="{height: `${statusBarHeight}px`}"></view>
 		<!-- #endif -->
-		<view  class="user-switch-row">
-			<view  @click="routerLink({ url: '/pages/message/index',isLogin:1 })" class="news">
-				<view v-if="(newsList.plate_count + newsList.device_count) > 0" class="num">{{newsList.plate_count + newsList.device_count}}</view>
+		<view style="position: relative;z-index: 999999;"  class="user-switch-row">
+			<view  @click="routerLink({ url: '/pages/message/index?isSys=1',isLogin:1 })" class="news">
+				<view v-if="newsList.plate_count> 0" class="num">{{newsList.plate_count}}</view>
 				<image :src="QINIU_URL + 'FlL5BtEdMES2-mntjR9D3CX_LWYv'" class="message"
 					 />
 			</view>
@@ -23,10 +23,10 @@
 		
 		
 		<view  class="common-tabs">
-			<view class="item" @click="routerLink({url:'/pages/dashboard/dashboard',isLogin:1})">
+			<!-- <view class="item" @click="routerLink({url:'/pages/dashboard/dashboard',isLogin:1})">
 				<image :src="QINIU_URL + 'Fp6G-Kzb-YUGkP2WR-kjTlIbbTj1'" class="icon" />
 				<view class="name">{{ $t('我的车辆') }}</view>
-			</view>
+			</view> -->
 			<view class="item" @click="routerLink({url:'/pages/userManagement/userManagement',isLogin:1})">
 				<image :src="QINIU_URL + 'FnxGW52BCkTkK9HxsTdVrghU7B4D'" class="icon" />
 				<view class="name">{{ $t('用车人') }}</view>
@@ -109,7 +109,7 @@ var request = require('@/common/request.js');
 					{
 						name: `${lang('意见反馈')}`,
 						url: '/pages/feedback/index',
-						icon: 'FnSjwcN7Mcpa-WA7Cqx2cGTvX2V1'
+						icon: 'Fh1tuCqkBQ1A20WTsiizSR9w4tQ4'
 					},
 					//   { name: `${lang('关于我们')}`, url: '/pages/bluetoothUnlock/unlockSet', icon: 'Fmin1_DG6ZkENCdsI1qJZJpDNkhQ' },
 					{
@@ -177,10 +177,15 @@ var request = require('@/common/request.js');
 				}
 			},
 			checkHandle_combo() {
+				
 				if(!this.car_info.sold_time){
 					this.$msg('您还未购买车辆,购买车辆才可享受换电套餐')
 					return
 				}
+				if(!this.car_info.battery_tag_info.tag_code){
+					this.$msg('当前没有可更换的电池,购买车辆绑定电池后才可享受换电套餐')
+					return
+				}
 				if(!this.car_info.car_sn){
 					this.$msg('您还未绑定车辆!')
 					return

+ 31 - 15
pages/my/set.vue

@@ -9,8 +9,12 @@
 					<view v-if="item.textProp == 'registrationTime' && userInfo.ctime">
 						{{ formatTimestamp(userInfo.ctime) }}
 					</view>
+					<view v-if="item.textProp == 'version'">
+						{{"V " + app_version}}
+					</view>
 					<input class="inp" @input="handleInput" @blur="inpfn" maxlength="22"
 						v-if="item.textProp == 'nickname'" v-model="userInfo[item.textProp]" type="text" />
+						
 					<block v-else>
 						{{ userInfo[item.textProp] || '' }}
 					</block>
@@ -30,6 +34,8 @@
 	var config = require('../../common/config_gyq.js');
 	var http = require('../../common/request');
 	const common = require('../../common/common.js');
+	import dayjs from 'dayjs'
+	import 'dayjs/locale/zh-cn';
 	export default {
 		data() {
 			return {
@@ -37,6 +43,7 @@
 				QINIU_URL,
 				defaultHeadImg,
 				userInfo: {},
+				app_version: '',
 				list: [{
 						title: '昵称',
 						url: '',
@@ -54,7 +61,8 @@
 					{
 						title: '关于我们',
 						url: '/pages/aboutMy/aboutMy',
-						textProp: 'version'
+						textProp: 'version',
+						hideArrow: true
 					},
 					{
 						title: '隐私协议',
@@ -67,23 +75,31 @@
 				]
 			}
 		},
+		onLoad() {
+			let getAppBaseInfo = uni.getAppBaseInfo()
+			this.setData({
+				// app_logo: appConfig.app_logo,
+				app_version: getAppBaseInfo.appVersion || '',
+				appName: getAppBaseInfo.appName || ''
+			})
+		},
 		onShow() {
 			const user_token = storage.getUserToken()
 			user_token && this.loadUserInfo()
 		},
 		methods: {
-		 // 输入处理
-		    handleInput(e) {
-		      // 延迟处理输入法组合输入
-		      setTimeout(() => {
-		        const value = e.detail.value;
-		        const truncated = this.truncateToMaxBytes(value, 22);
-		        // 更新值(避免无限触发,需判断)
-		        if (truncated !== value) {
-		         this.userInfo.nickname = truncated;
-		        }
-		      }, 0);
-		    },
+			// 输入处理
+			handleInput(e) {
+				// 延迟处理输入法组合输入
+				setTimeout(() => {
+					const value = e.detail.value;
+					const truncated = this.truncateToMaxBytes(value, 22);
+					// 更新值(避免无限触发,需判断)
+					if (truncated !== value) {
+						this.userInfo.nickname = truncated;
+					}
+				}, 0);
+			},
 			// 截断字符串至指定字节
 			truncateToMaxBytes(str, maxBytes) {
 				let totalBytes = 0;
@@ -102,8 +118,8 @@
 			},
 
 			formatTimestamp(timestamp) {
-				const date = new Date(timestamp * 1000);
-				return date.toLocaleDateString('zh-CN'); // 本地化格式(如:2021/5/3)
+				dayjs.locale('zh-cn');
+				return dayjs.unix(timestamp).format('YYYY/M/D'); // 严格中文格式
 			},
 			inpfn(e) {
 				console.log(e.detail.value)

+ 6 - 1
pages/openCabinet/openCabinet.css

@@ -96,14 +96,19 @@
 .over-btn-view{
 	padding: 0 32rpx;
 	margin-bottom: 74rpx;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
 }
 .over-btn{
+	margin: 0 20rpx;
 	height: 80rpx;
-	background: #0074FF;
+	background: #060809;
 	border-radius: 40rpx;
 	justify-content: center;
 	font-family: PingFangSC, PingFang SC;
 	font-weight: 500;
 	font-size: 32rpx;
 	color: #FFFFFF;
+	width: 100%;
 }

+ 13 - 11
pages/openCabinet/openCabinet.vue

@@ -6,15 +6,12 @@
 		<view class="explain-view">
 			<view class="explain-num-view flex-row">
 				<!-- <text><text class="explain-num">{{empty_door_id}} </text>号仓门已打开</text> -->
-				<text v-if="list.status == 1">仓门已打开</text>
-				<text v-if="list.status == 2">换电中</text>
+				<text>仓门已打开</text>
+				<!-- <text v-if="list.status == 2">换电中</text>
 				<text v-if="list.status == 3">换电成功</text>
-				<text v-if="list.status == 4">换电失败</text>
+				<text v-if="list.status == 4">换电失败</text> -->
 			</view>
-			<view v-if="list.status == 1" class="explain-text">请存入更换电池,取走满电电池,并关好仓门</view>
-			<view v-if="list.status == 2" class="explain-text">换电中</view>
-			<view v-if="list.status == 3" class="explain-text">换电成功</view>
-			<view v-if="list.status == 4" class="explain-text-grap">{{list.fail_reason}}</view>
+			<view class="explain-text">请存入更换电池,取走满电电池,并关好仓门</view>
 			<!-- <view class="explain-text">请 归还 / 取出 电池并关上仓门</view> -->
 			<!-- <view class="explain-text">请取出电池并关上仓门</view> -->
 			<!-- <view class="explain-text-grap">归还完成后电柜会自动打开可租仓门</view> -->
@@ -30,7 +27,7 @@
 				</view>
 				<view v-if="list.status==3" class="open-result-view">
 					<view class="open-result flex-row">换电成功</view>
-					<view class="open-result-tip flex-row">即将跳转至首页,祝您骑行愉快</view>
+					<view class="open-result-tip flex-row">祝您骑行愉快</view>
 				</view>
 				<view v-if="list.status==4" class="open-result-view">
 					<view class="open-result flex-row">换电失败</view>
@@ -39,6 +36,7 @@
 				<view class="over-btn-view">
 					<view v-if="list.status==3" @tap="tapToIndex" class="over-btn flex-row">回到首页</view>
 					<view v-if="list.status==4" @tap="connectStore" class="over-btn flex-row">联系门店</view>
+					<view v-if="list.status==4" @click="srcFn(`/pages/index/index`)" class="over-btn flex-row">确认</view>
 				</view>
 			</view>
 		</view>
@@ -51,7 +49,6 @@
 	const common = require('../../common/common.js');
 	var bluetooth = require('../../common/bluetooth.js');
 	const DF_CAB_INFO_DONE = 10000; //机柜信息传输完成
-	const app = getApp();
 	export default {
 		data() {
 			return {
@@ -69,7 +66,7 @@
 			this.exchangeStatusFn()
 			this.time = setInterval(() => {
 				this.exchangeStatusFn()
-			}, 3000)
+			}, 1200)
 		},
 		/**
 		 * 生命周期函数--监听页面显示
@@ -81,6 +78,11 @@
 			this.clearIntervalTimer()
 		},
 		methods: {
+			srcFn(url){
+				uni.reLaunch({
+					url: '/pages/index/index',
+				})
+			},
 			tapToIndex() {
 				this.isOverModal = false
 				uni.reLaunch({
@@ -105,7 +107,7 @@
 				})
 				if (data.code == 200) {
 					this.list = data.data.statusInfo
-					if (data.data.statusInfo.status == 3 || data.data.statusInfo.status == 4) {
+					if (data.data.statusInfo.status == 3 || data.data.statusInfo.status == 4 || data.data.statusInfo.status == 5) {
 						this.clearIntervalTimer()
 						this.isOverModal = true
 					}

+ 1 - 1
pages/order/order.css

@@ -16,7 +16,7 @@
 	color: #060809;
 }
 .car-model-text{
-	width: 260rpx;
+	max-width: 260rpx;
 	text-overflow: ellipsis;
 	overflow: hidden;
 	white-space: nowrap;

+ 48 - 25
pages/order/order.vue

@@ -1,8 +1,8 @@
 <template>
 	<view class="container-view">
-		<navBar name="我的订单" left="0" ></navBar>
-		<view class="order-type-view flex-row flex-between">
-			<view v-if="car_info.car_sn" @click="srcFn(`/pages/carList/carList`)" class="car-model-list flex-row">
+		<navBar name="我的订单" ></navBar>
+		<!-- <view v-if="selectOrderType == 0" class="order-type-view flex-row flex-between">
+			<view v-if="car_info.car_sn && selectOrderType == 0" @click="srcFn(`/pages/carList/carList`)" class="car-model-list flex-row">
 				<view class="car-model-text">{{car_info.car_name}}</view><img class="right-corner-icon"
 					src="https://qiniu.bms16.com/Fqs6TrEmcdT7QNEdKWs9Hir2cacO" alt="">
 			</view>
@@ -16,8 +16,19 @@
 						src="https://qiniu.bms16.com/FmcoAVgWvyK44iPjK0phkDRU21i0" alt="">
 				</view>
 			</view>
+		</view> -->
+		<view  class="order-type-view flex-row flex-between">
+			<view style="justify-content: space-around;width: 100%;" class="order-package-type-view flex-row">
+				<view style="width: 128rpx;" v-for="(type, index) in orderTypes" :key="index" @tap="checkOrderType" :data-type="type.value"
+					:class="['package-type-list', 'flex-row', {'package-type-list-i': selectOrderType === type.value}]"
+					>
+					<view class="package-type-text">{{ type.text }}</view>
+					<img v-if="selectOrderType === type.value" class="right-button-icon"
+						src="https://qiniu.bms16.com/FmcoAVgWvyK44iPjK0phkDRU21i0" alt="">
+				</view>
+			</view>
 		</view>
-		<view v-for="(item, index) in hireOrderList" :key="index" @tap="loadToNav" :data-sub_sn="item.sub_sn"
+		<view v-for="(item, index) of hireOrderList" :key="index" @tap="loadToNav" :data-sub_sn="item.sub_sn"
 			class="order-card">
 			<view class="card-top flex-row">
 				<view v-if="selectOrderType == 1">{{ item.car_name }}</view>
@@ -35,7 +46,8 @@
 					</view>
 				</block>
 
-				<view v-if="item.pay_status==2 && selectOrderType == 1">
+				<view v-if="item.finally == 1 && selectOrderType == 1">
+					<view class="card card-k" v-if="item.order_status == 0">待支付</view>
 					<view class="card card-k" v-if="item.order_status == 1">待取车</view>
 					<view class="card card-k" v-else-if="item.order_status == 2">待激活</view>
 					<view class="card card-b" v-else-if="item.order_status == 3">使用中</view>
@@ -45,11 +57,13 @@
 					<view class="card card-k" v-else-if="item.order_status == 7">车辆已归还</view>
 					<view class="card card-k" v-else-if="item.order_status == 8 ">订单已支付,已取消</view>
 					<view class="card card-k" v-else-if=" item.order_status == 9">订单未支付,已取消</view>
+					<view class="card card-k" v-else-if=" item.order_status == 10">已完结</view>
 				</view>
 
-				<view v-if="item.pay_status!=2 && selectOrderType == 1">
+				<view v-if="item.finally != 1 && selectOrderType == 1">
 					<view class="card card-k" v-if="item.pay_status == 0">待支付</view>
 					<view class="card card-k" v-else-if="item.pay_status == 1">支付中</view>
+					<view class="card card-k" v-else-if="item.pay_status == 2">支付成功</view>
 					<view class="card card-r" v-else-if="item.pay_status == 3">支付失败</view>
 					<view class="card card-k" v-else-if="item.pay_status == 4">支付取消</view>
 					<view class="card card-b" v-else-if="item.pay_status == 5">线下待审核</view>
@@ -71,16 +85,20 @@
 			<view class="card-bottom">
 				<view class="bottom-item">
 					<block v-if="selectOrderType == 1">
+						<view class="item-label-view flex-row">
+							<view class="item-label">订单编号</view>
+							<view class="item-value">{{ item.sub_sn }}</view>
+						</view>
 						<view class="item-label-view flex-row">
 							<view class="item-label">下单时间</view>
 							<view class="item-value">{{ tools.formatTime(item.ctime) }}</view>
 						</view>
-						<view v-if="item.hire_end_time" class="item-label-view flex-row">
+						<view v-if="item.hire_end_time && item.order_type != 3" class="item-label-view flex-row">
 							<view class="item-label">有效期至</view>
 							<view class="item-value">{{ tools.formatTime(item.hire_end_time) }}</view>
 						</view>
 
-						<view v-if="item.hire_duration_time" class="item-label-view flex-row">
+						<view v-if="item.hire_duration_time && item.order_type != 3" class="item-label-view flex-row">
 							<view class="item-label">有效时长</view>
 							<view class="item-value">
 								{{ item.hire_duration_time.day > 0 ? item.hire_duration_time.day : '' }}<text
@@ -108,7 +126,8 @@
 						</view>
 						<view v-if="item.package_type == 1" class="item-label-view flex-row">
 							<view class="item-label">免费换电数</view>
-							<view class="item-value">{{item.last_num}}次</view>
+							<!-- <view class="item-value">{{item.last_num}}次</view> -->
+							<view class="item-value">不限次数</view>
 						</view>
 						<view v-if="item.package_type == 2" class="item-label-view flex-row">
 							<view class="item-label">免费换电数</view>
@@ -172,6 +191,7 @@
 						text: '租车购车'
 					}
 				],
+				start_id:0,
 				page: 1,
 				limit: 10,
 				status: '-1',
@@ -191,6 +211,7 @@
 		 * 生命周期函数--监听页面加载
 		 */
 		onLoad: function(options) {
+			this.selectOrderType = options.selectOrderType == 0 ? 0 : 1
 			const locationStr = uni.getStorageSync('user_current_location');
 			if (locationStr) {
 				this.myLocation = locationStr;
@@ -204,12 +225,15 @@
 		onShow: function() {
 			this.car_info = uni.getStorageSync('car_info') || {};
 			this.page = 1
+			this.start_id = 0
 			this.hireOrderList = []
-			if(this.selectOrderType == 1){
-				this.bindHireOrderList()
-			}else{
-				this.bindExchangeOrderFn()
-			}
+			setTimeout(()=> {
+				if(this.selectOrderType == 1){
+					this.bindHireOrderList()
+				}else{
+					this.bindExchangeOrderFn()
+				}
+			}, 300);
 		},
 
 		// 分享给好友
@@ -235,7 +259,7 @@
 		 * 页面下拉触底事件的处理函数
 		 */
 		onPullDownRefresh() {
-			this.page = 1
+			this.start_id
 			if (this.selectOrderType == 0) {
 				this.bindExchangeOrderFn()
 			} else if (this.selectOrderType == 1) {
@@ -252,29 +276,28 @@
 				// 获取当前时间
 				const now = dayjs();
 				// 解析到期时间
-				const endDate = dayjs(expirationDate);
+				const endDate = dayjs(expirationDate * 1000);
 				// 计算剩余天数
 				const remainingDays = endDate.diff(now, 'day');
-				return remainingDays || 0;
+				return remainingDays || 1;
 			},
 			//dayjs
 			validDurationFn(start, end) {
 				return getRemainingTime(start, end)
 			},
 			async bindExchangeOrderFn() {
-				if(!this.car_info.car_sn){
-					this.hireOrderList = []
-					return 
-				}
+				let me = this
 				let {
 					data
 				} = await request.postApi(config_gyq.API_FLK_EXCHANGE_PACKAGE_ORDER_LIST, {
 					pay_status: -1,
-					car_sn: this.car_info.car_sn,
+					car_sn: '',
+					start_id:me.start_id,
 					page: this.page,
 					limit: this.limit,
 				})
 				if (data.code == 200) {
+					me.start_id = data.data.start_id
 					this.hireOrderList.push.apply(this.hireOrderList, data.data.list)
 					this.is_next = data.data.is_next
 				} else {
@@ -286,11 +309,13 @@
 				http.postApi(config.API_FLK_ORDER_LIST, {
 					page: me.page,
 					limit: me.limit,
+					start_id:me.start_id,
 					// status: me.status,
 					// sort_time: me.sort_time,
 					// sort_num: me.sort_num
 				}, (resp) => {
 					if (resp.data.code === 200) {
+						me.start_id = resp.data.data.start_id
 						me.hireOrderList.push.apply(me.hireOrderList, resp.data.data.list)
 						me.is_next = resp.data.data.is_next
 						if (me.hireOrderList.length > 0) {
@@ -310,6 +335,7 @@
 				})
 			},
 			checkOrderType(e) {
+				this.start_id = 0
 				const type = e.currentTarget.dataset.type;
 				this.setData({
 					selectOrderType: type
@@ -341,9 +367,6 @@
 				const isJumpReturn = false
 				uni.navigateTo({
 					url: '/pages/orderStatus/orderStatus?sub_sn=' + sub_sn,
-					success: function(res) {},
-					fail: function(res) {},
-					complete: function(res) {},
 				})
 			},
 			async activateCar(e) {

+ 37 - 2
pages/orderStatus/orderStatus.css

@@ -495,6 +495,10 @@
 	padding-bottom: 24rpx; */
 	text-align: center;
 	margin-left: 10rpx;
+	display: flex;
+	flex-grow: 1;
+	justify-content: center;
+	align-items: center;
 }
 .sesame-btn-s {
 	color: #ffffff;
@@ -583,12 +587,12 @@
 
 .payment-info {
 	background-color: #ffffff;
-	padding: 24rpx 32rpx 28rpx;
+	padding: 24rpx 32rpx 30rpx;
 	width: 100%;
 	position: fixed;
 	left: 0;
 	bottom: 0;
-	padding-bottom: env(safe-area-inset-bottom);
+	padding-bottom: calc(env(safe-area-inset-bottom) + 20rpx);
 }
 .inset-bottom{
 	height: calc(150rpx + env(safe-area-inset-bottom));
@@ -918,6 +922,9 @@
 	font-size: 28rpx;
 	color: #9FA7B7;
 	margin: 16rpx 0;
+	text-overflow: ellipsis;
+	overflow: hidden;
+	white-space: nowrap;
 }
 .store-name{
 	font-weight: 600;
@@ -952,6 +959,11 @@
 .get-time-view{
 	font-weight: 400;
 	align-items: center;
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 600;
+	font-size: 48rpx;
+	color: #060809;
+	margin-bottom: 48rpx;
 }
 .serviceList{
 	display: flex;
@@ -975,4 +987,27 @@
 	text-align: center;
 	font-style: normal;
 	margin-right: 10rpx;
+}
+.link-phone-btn {
+	color: #ffffff;
+	font-size: 28rpx;
+	height: 60rpx;
+	line-height: 60rpx;
+	background-color: #060809;
+	border-radius: 40rpx;
+	padding: 0 20rpx;
+	display: flex;
+	flex-grow: 1;
+	justify-content: center;
+	align-items: center;
+	/* padding-top: 24rpx;
+	padding-bottom: 24rpx; */
+	text-align: center;
+	margin-left: 20rpx;
+}
+.grow_1{
+	display: flex;
+	flex-grow: 1;
+	justify-content: center;
+	align-items: center;
 }

+ 164 - 71
pages/orderStatus/orderStatus.vue

@@ -1,51 +1,63 @@
 <template>
+	
+	
 	<view class="container-view">
 		<view class="time-info">
 			<navBar bgColor="transparent" left="0"></navBar>
 			<view>
 				<view v-if="orderInfo.pay_status!=2">
-					<view v-if="orderInfo.pay_status == 0">待支付</view>
-					<view v-else-if="orderInfo.pay_status == 1">支付中</view>
-					<view v-else-if="orderInfo.pay_status == 3">支付失败</view>
-					<view v-else-if="orderInfo.pay_status == 4">支付取消</view>
-					<view v-else-if="orderInfo.pay_status == 5">线下待审核</view>
-					<view v-else-if="orderInfo.pay_status == 6">线下审核拒绝</view>
+					<view class="get-time-view flex-row" v-if="orderInfo.pay_status == 0">待支付</view>
+					<view class="get-time-view flex-row" v-else-if="orderInfo.pay_status == 1">支付中</view>
+					<view class="get-time-view flex-row" v-else-if="orderInfo.pay_status == 3">支付失败</view>
+					<view class="get-time-view flex-row" v-else-if="orderInfo.pay_status == 4">支付取消</view>
+					<view class="get-time-view flex-row" v-else-if="orderInfo.pay_status == 5">线下待审核</view>
+					<view class="get-time-view flex-row" v-else-if="orderInfo.pay_status == 6">线下审核拒绝</view>
 				</view>
-				<view class="get-time-view flex-row" v-if="orderInfo.order_status == 1 "><text>请于</text><text class="get-car-time">{{tools.formatTimeSecond( orderInfo.pick_up_time)}}</text><text>到门店取车</text>
-				</view>
-				<view v-if="orderInfo.order_status == 2">请上传车辆图片激活车辆</view>
 				<block v-if="orderInfo.pay_status == 2">
-					<view v-if="orderInfo.order_status == 3" class="blue-text">使用中...</view>
-					<view v-if="orderInfo.order_status == 4" class="red-text">已逾期</view>
-					<view v-if="orderInfo.order_status == 5">待门店确认</view>
-					<view v-if="orderInfo.order_status == 6">还车中,等待门店取车</view>
-					<view v-if="orderInfo.order_status == 7">已完成</view>
+					<view :class="['get-time-view', 'flex-row', 'blue-text']" v-if="orderInfo.order_status == 3">使用中...
+					</view>
+					<view :class="['get-time-view', 'flex-row', 'red-text']" v-if="orderInfo.order_status == 4">已逾期
+					</view>
+					<view class="get-time-view flex-row" v-if="orderInfo.order_status == 2">请上传车辆图片激活车辆</view>
+					<view class="get-time-view flex-row" v-if="orderInfo.order_status == 5">待门店确认</view>
+					<view class="get-time-view flex-row" v-if="orderInfo.order_status == 6">还车中,等待门店取车</view>
+					<view class="get-time-view flex-row" v-if="orderInfo.order_status == 7">已完成</view>
+					<view class="get-time-view flex-row"
+						v-if="orderInfo.order_status == 8||orderInfo.order_status == 9">已取消</view>
+					<view class="get-time-view flex-row" v-if="orderInfo.order_status == 1 "><text>请于</text><text
+						class="get-car-time">{{tools.formatTimeSecond( orderInfo.pick_up_time)}}</text><text>到门店取车</text>
+					</view>
+					<view v-if="orderInfo.order_status == 10">已完结</view>
 				</block>
-				<view v-if="orderInfo.order_status == 8||orderInfo.order_status == 9">已取消</view>
+
 			</view>
 
 			<view class="time-money">
 				<view v-if="orderInfo.order_type != 3" class="flex-row flex-between">
 					<view class="money-item">
 						<view :class="orderInfo.order_status == 4?'red-status':''">
-							<block v-if="orderInfo.hire_duration_time">{{orderInfo.hire_duration_time}}</block>
+							<block v-if="orderInfo.hire_duration_time&&orderInfo.hire_duration_time>0">{{orderInfo.hire_duration_time}}</block>
+							<block v-else>{{Number(orderInfo.hire_cycle) * (orderInfo.hire_duration)}}</block>
 						</view>
-						<view>{{((orderInfo.order_status == 2&&orderInfo.hire_type==2) || orderInfo.order_status == 3)?'租期剩余':(orderInfo.order_status == 4 ? '逾期时长':'租借周期')}}·<text style="opacity: 0.4;">天</text></view>
+						
+						<view>{{(orderInfo.order_status == 2 || orderInfo.order_status == 3)?'租期剩余':(orderInfo.order_status == 4 ? '逾期时长':'租借周期')}}·<text style="opacity: 0.4;">{{leaseUnits(orderInfo.hire_duration_unit)}}</text></view>
+						
 						<!-- <view v-if="(orderInfo.order_status == 2&&orderInfo.hire_type==2) || orderInfo.order_status == 3">
 							租期剩余·天</view>
 						<view v-else-if="orderInfo.order_status == 4 " class="red-status">逾期时长·天</view>
 						<view v-else>租借周期·天</view> -->
 					</view>
-					<view v-if="orderInfo.order_status != 4" class="money-item">
+					<view v-if="orderInfo.order_status != 4||orderInfo.overdue_money==0" class="money-item">
 						<view>
-							{{tools.toFix(orderInfo.hire_money / 100)}}
+							{{((orderInfo.hire_money + orderInfo.deposit) / 100).toFixed(2)}}
 						</view>
 						<view>订单金额<text style="opacity: 0.4;">·$</text></view>
 					</view>
 
-					<view v-if="orderInfo.order_status == 4" class="money-item">
+					<view v-if="orderInfo.order_status == 4&&orderInfo.overdue_money!=0" class="money-item">
 						<view style="color:#F95151" class="red-status">
-							{{tools.toFix(overdueData.money / 100)}}
+							{{(orderInfo.money / 100).toFixed(2)}}
+							<!-- {{(orderInfo.overdue_money / 100).toFixed(2)}} -->
 						</view>
 						<view style="color:#F95151">逾期金额·$</view>
 					</view>
@@ -56,6 +68,7 @@
 							:src="isExpanded?'https://qiniu.bms16.com/FvRah8ro91B_TUVEmInBq6n69W2f':'https://qiniu.bms16.com/FtbxPP0aXYG8hyJTEJfNTXa_Puuc'" />
 					</view>
 				</view>
+				
 				<view v-if="orderInfo.order_type == 3" class="flex-row flex-between">
 					<view class="money-item">
 						<view></view>
@@ -75,6 +88,7 @@
 				</view>
 
 				<view v-if="isExpanded" class="dashed-border"></view>
+				
 				<view v-if="isExpanded">
 					<view class="big-text">订单信息</view>
 					<view class="sn-content flex-row flex-between">
@@ -98,12 +112,12 @@
 					</view>
 					<view v-if="orderInfo.order_type != 3" class="sn-content flex-row flex-between">
 						<view class="sn-title">租车金额</view>
-						<view class="sn-text">$ {{tools.toFix(orderInfo.hire_money/1000)}}</view>
+						<view class="sn-text">$ {{tools.toFix(orderInfo.hire_money/100)}}</view>
 					</view>
 					<view v-if="orderInfo.order_type != 3" class="sn-content flex-row flex-between">
 						<view class="sn-title">租车押金</view>
-						<view class="sn-text"><text class="grey-text">订单结束后随时退</text> $
-							{{tools.toFix(orderInfo.deposit/1000)}}
+						<view class="sn-text"><text class="grey-text"></text> $
+							{{tools.toFix(orderInfo.deposit/100)}}
 						</view>
 					</view>
 				</view>
@@ -139,7 +153,9 @@
 				<view>
 					<view class="top-flex">
 						<view>{{orderInfo.model_name}}</view>
-						<view>续航{{(orderInfo.endurance /100).toFixed(0)}}km|重量{{(orderInfo.weight / 1000).toFixed(0)}}kg</view>
+						<view>
+							续航{{(orderInfo.endurance /1000).toFixed(0)}}km|重量{{(orderInfo.weight / 1000).toFixed(0)}}kg
+						</view>
 					</view>
 					<!-- //配套服务 -->
 					<view class="serviceList">
@@ -148,7 +164,7 @@
 						</view>
 					</view>
 				</view>
-				<image mode="aspectFill" v-if="orderInfo.model_images" :src="orderInfo.model_images"></image>
+				<image mode="aspectFit" v-if="orderInfo.model_images" :src="orderInfo.model_images"></image>
 				<image v-else src="https://qiniu.bms16.com/FhEvnKUckAHPtWaC04mi2s53IEVj" mode=""></image>
 			</view>
 			<!-- <view class="exchange-info">
@@ -178,7 +194,7 @@
 						v-if="orderInfo.hire_return_time.day>0">日</text>{{orderInfo.hire_return_time.hour > 0 ? orderInfo.hire_return_time.hour :'' }}<text
 						v-if="orderInfo.hire_return_time.hour>0">小时</text>{{orderInfo.hire_return_time.minute > 0 ? orderInfo.hire_return_time.minute :'' }}<text
 						v-if="orderInfo.hire_return_time.minute>0">分</text> -->
-					共{{hireDurationUnitsFn(orderInfo.total_hire_time,orderInfo.hire_duration_unit)}}
+					共{{hireDurationUnitsFn(orderInfo.total_hire_time,orderInfo.hire_duration_unit)}}{{leaseUnits(orderInfo.hire_duration_unit)}}
 				</view>
 			</view>
 			<view class="return-bottom flex-row">
@@ -209,19 +225,36 @@
 			</view>
 		</view>
 		<view class="inset-bottom"></view>
-		<view class="payment-info flex-row flex-between">
-			<view>
-				<view v-if="(orderInfo.order_status == 1 || orderInfo.pay_status == 5) && orderInfo.order_type != 3" class="cancel" @tap="clickCancel">结束订单</view>
+		<block v-if="orderInfo.pay_status != 2">
+			<view class="payment-info flex-row">
+				<view
+					v-if="(orderInfo.order_status == 0 ||orderInfo.order_status == 1 || orderInfo.pay_status == 5 || orderInfo.pay_status == 0) && orderInfo.order_type != 3"
+					class="cancel" @tap="clickCancel">结束订单</view>
+				<view @tap="callStorePhone" class="link-phone-btn">联系门店</view>
 			</view>
-			<view class="flex-row">
-				<view v-if="orderInfo.order_status == 1" @tap="navToScan" class="sesame-btn ">扫码绑定</view>
-				<view v-if="orderInfo.order_status == 2" @tap="navToScan" class="sesame-btn ">去上传</view>
-				<view v-if="(orderInfo.order_status == 3||orderInfo.order_status == 4) && orderInfo.order_type != 3 && orderInfo.pay_status != 5" @tap="tapReturnCar" class="deposit-btn">到店还车</view>
-				<view v-if="(orderInfo.order_status == 3||orderInfo.order_status == 4) && orderInfo.order_type != 3 && orderInfo.pay_status != 5"  @tap="bindRenew" class="sesame-btn">续租</view>
-				<view @tap="callStorePhone" class="deposit-btn ">联系门店</view>
+		</block>
+		<block v-if="orderInfo.pay_status == 2">
+			<view class="payment-info flex-row">
+					<!-- 待激活 -->
+					<view class="grow_1" v-if="orderInfo.order_status == 0 ||orderInfo.order_status == 1">
+						<view
+							v-if="(orderInfo.order_status == 0 ||orderInfo.order_status == 1 || orderInfo.pay_status == 5 || orderInfo.pay_status == 0) && orderInfo.order_type != 3"
+							class="cancel" @tap="clickCancel">结束订单</view>
+							<view v-if="orderInfo.order_status == 1" @tap="navToScan" class="sesame-btn ">扫码绑定</view>
+							<view v-if="orderInfo.order_status == 2" @tap="navToScan" class="sesame-btn ">去上传</view>
+					</view>
+					<!-- 使用中、已逾期 -->
+					<view class="grow_1" v-if="(orderInfo.order_status == 3||orderInfo.order_status == 4) && orderInfo.order_type != 3 && orderInfo.pay_status != 5">
+						<view  @tap="callStorePhone" class="cancel">联系门店</view>
+						<view @tap="tapReturnCar" class="deposit-btn">到店还车</view>
+						<view  @tap="bindRenew" class="sesame-btn">续租</view>
+					</view>
+					<!-- 待门店确认、已取消、已完成 -->
+					<view class="grow_1" v-if="(orderInfo.order_status == 5||orderInfo.order_status == 6||orderInfo.order_status == 7||orderInfo.order_status == 8||orderInfo.order_status == 9)">
+						<view  @tap="callStorePhone" class="link-phone-btn">联系门店</view>
+					</view>	
 			</view>
-		</view>
-		
+		</block>
 		<!-- <view class="payment-info flex-row flex-between">
 			<view v-if="orderInfo.order_status == 1 || orderInfo.pay_status == 5" class="flex-row"> 
 				<view v-if="orderInfo.order_type != 3"
@@ -285,7 +318,7 @@
 		<returnCar :isShowReturnCar="isShowReturnCar" @closeShowReturnCarBtn="()=>isShowReturnCar=false"
 			@navStoreBtn="navStoreBtn" @immediatelyReturnBtn="immediatelyReturnBtn" />
 
-		<carPlan @payToOrder='payReturn' v-if="showCarPlan" @changeSelectType="changeSelectType"
+		<carPlan :isBuy='false' @payToOrder='payReturn' v-if="showCarPlan" @changeSelectType="changeSelectType"
 			@closeShowMore="showCarPlan = false" :params="params" :selectType="selectType" />
 
 		<PayTypeModel @closeShow="()=>isShowToBuy=false" @payToOrder="payToOrder" :free_price="totalPrice"
@@ -306,6 +339,9 @@
 	import {
 		getRemainingTime
 	} from '@/utils/util';
+	import {
+		MAX_LIMITS,LEASE_TYPE_ARR
+	} from '@/common/constant.js'
 	var appWhiteListFilter = require('../../common/appWhiteListFilter.js');
 	import allPrice from '@/component/allPrice/allPrice';
 	import ReturnCar from '@/component/returnCar/returnCar';
@@ -314,6 +350,7 @@
 	import dayjs from 'dayjs'
 	import duration from 'dayjs/plugin/duration'
 	dayjs.extend(duration);
+	
 	export default {
 		components: {
 			allPrice,
@@ -364,12 +401,35 @@
 				this.bindOrderInfo()
 			}
 		},
-		
+
 		onUnload: function() {},
 
 		computed: {},
 
 		methods: {
+			getAddressName(latitude, longitude) {
+				const pData = {
+					lng: longitude,
+					lat: latitude,
+					pi: "wx_index"
+				}
+				const that = this
+				http.postApi(config.API_MAP_REGEO, pData, (resp) => {
+					if (resp.data.code === 200) {
+						that.orderInfo.address = resp.data.data.data.address
+					} else {
+						common.simpleToast(resp.data.msg)
+					}
+				})
+			},
+			leaseUnits(type){
+				const result = LEASE_TYPE_ARR.find(v => v.value == type);
+				return result ? result.unit : '';
+			},
+			leaseUnitsResult(type) {
+				const result = LEASE_TYPE_ARR.find(v => v.value == type);
+				return result ? result.label : '';
+			},
 			payReturn() {},
 			//逾期费用计算
 			async overdueMoneyFn(car_sn) {
@@ -395,7 +455,7 @@
 							...this.car_detail,
 							price: this.price
 						}
-						
+
 						me.setData({
 							car_detail: resp.data.data,
 							params: {
@@ -404,6 +464,7 @@
 								price: (resp.data.data.rental_setting[0].hire_price / 100).toFixed(2)
 							}
 						})
+						
 					} else {
 						common.simpleToast(resp.data.msg);
 					}
@@ -416,13 +477,30 @@
 					price: (price / 100).toFixed(2)
 				})
 			},
-			
-			async carDetFn(car_sn){
-				let {data} = await request.postApi(config.API_FLK_CAR_DETAIL, {car_sn})
+
+			async carDetFn(car_sn) {
+				let {
+					data
+				} = await request.postApi(config.API_FLK_CAR_DETAIL, {
+					car_sn
+				})
 				if (data.code === 200) {
-					if(data.data.is_display == 1){
+					if (data.data.model_id == this.orderInfo.model_id) {
+						return true
+					} else {
+						common.simpleToast('车型不匹配!')
+						return false
+					}
+
+					if (data.data.is_hire == 1) {
 						return true
-					}else{
+					} else {
+						common.simpleToast('车辆已被租售!')
+						return false
+					}
+					if (data.data.is_display == 1) {
+						return true
+					} else {
 						common.simpleToast('车辆未展示!')
 						return false
 					}
@@ -437,23 +515,23 @@
 				if (!car_sn) {
 					let res = await uni.scanCode({
 						onlyFromCamera: true,
-						scanType: [],
+						scanType: ['qrCode'],
 					});
 					if (res[0]) return
 					car_sn = res[1].result
-					if(!await this.carDetFn(car_sn)) return
+					if (!await this.carDetFn(car_sn)) return
 				}
 				uni.showLoading({
 					title: '识别中....',
 					mask: true
 				})
-				setTimeout(()=> {
+				setTimeout(() => {
 					uni.hideLoading();
 					uni.navigateTo({
 						url: `/pages/activation/activation?model_id=${this.orderInfo.model_id}&sub_sn=${this.sub_sn}&car_sn=${car_sn}`
 					})
 				}, 1000);
-				
+
 			},
 
 			navToCabinet() {
@@ -494,19 +572,19 @@
 			hireDurationUnitsFn(time, type) {
 
 				if (type == 1) {
-					return Math.ceil(time / 60 / 60 / 24) + '天'
+					return Math.ceil(time / 60 / 60 / 24) 
 				} else if (type == 2) {
-					return Math.ceil(time / 60 / 60 / 24 / 30) + '月'
+					return Math.ceil(time / 60 / 60 / 24 / 30)
 				} else if (type == 3) {
-					return Math.ceil(time / 60 / 60 / 24 / 30 / 365) + '年'
+					return Math.ceil(time / 60 / 60 / 24 / 30 / 365) 
 				} else if (type == 4) {
-					return Math.ceil(time / 60 / 60) + '小时'
+					return Math.ceil(time / 60 / 60) 
 				} else if (type == 5) {
-					return Math.ceil(time / 60) + '分钟'
+					return Math.ceil(time / 60)
 				} else if (type == 6) {
-					return Math.ceil(time / 60 / 60 / 24 / 7) + '周'
+					return Math.ceil(time / 60 / 60 / 24 / 7)
 				} else if (type == 7) {
-					return Math.ceil(time / 60 / 60 / 24 / 30 / 3) + '季'
+					return Math.ceil(time / 60 / 60 / 24 / 30 / 3)
 				}
 			},
 
@@ -523,18 +601,20 @@
 				}, (resp) => {
 					if (resp.data.code === 200) {
 						me.orderInfo = resp.data.data.order_info
-				me.orderInfo.model_images = me.orderInfo.model_images.split(',')[0]
+						me.orderInfo.model_images = me.orderInfo.model_images.split(',')[0]
+						me.getAddressName(this.orderInfo.latitude,this.orderInfo.longitude)
 						// 
 						if (resp.data.data.order_info.model_id) {
 							me.loadCarInfo(resp.data.data.order_info.model_id)
 						}
-						let distance = common.getFlatternDistance(locationStr.longitude, locationStr.latitude, me
+						let distance = common.getFlatternDistance(locationStr.longitude, locationStr.latitude,
+							me
 							.orderInfo.longitude, me.orderInfo.latitude)
 						resp.data.data.order_info.distance = distance
 						// 取还时间展示
 						// me.orderInfo.hire_return_time = common.getTimeToDay(Math.ceil(me.orderInfo
 						// 	.hire_end_time - me.orderInfo.hire_begin_time) / 60)
-				
+
 						me.orderInfo.hire_return_time = getRemainingTime(me.orderInfo
 							.hire_begin_time, me
 							.orderInfo.hire_end_time)
@@ -546,21 +626,33 @@
 							.orderInfo
 							.hire_end_time * 1000).format(
 							'YY-MM-DD') : 0
-							console.log(me.orderInfo.order_status == 1);
-							let other_time=0
+						console.log(me.orderInfo.order_status == 1);
+						let other_time = 0
 						// 剩余租期判断
-						if (me.orderInfo.order_status == 1){
-							me.orderInfo.hire_duration_time=common.countToDay(me.orderInfo.hire_cycle*me.orderInfo.hire_duration,me.orderInfo.hire_duration_unit)
-							console.log(me.orderInfo.hire_duration_time,'me.orderInfo.hire_duration_time');
-						}else if((me.orderInfo.hire_type == 2 && me.orderInfo.order_status == 2) ||me.orderInfo.order_status == 3) {
-							me.orderInfo.hire_duration_time = common.timestampToDays(Math.ceil(me.orderInfo.hire_end_time - Math.floor(new Date()) /1000))
+						//订单状态 0 默认 1 待取车 2 待激活 3 使用中 4 已逾期 5 还车申请中 6 还车中 7 车辆已归还 8 订单已支付,已取消 9 订单未支付已取消
+						if (me.orderInfo.order_status == 1) {
+							me.orderInfo.hire_duration_time = common.countToDay(me.orderInfo.hire_cycle * me
+								.orderInfo.hire_duration, me.orderInfo.hire_duration_unit)
+							console.log(me.orderInfo.hire_duration_time, 'me.orderInfo.hire_duration_time');
+						} else if ((me.orderInfo.hire_type == 2 && me.orderInfo.order_status == 2) || me
+							.orderInfo.order_status == 3) {
+							// me.orderInfo.hire_duration_time = common.timestampToDays(Math.ceil(me.orderInfo
+							// 	.hire_end_time - Math.floor(new Date()) / 1000))
+							
+							me.orderInfo.hire_duration_time = common.formatTimeDifference(me.orderInfo
+									.hire_end_time * 1000)
 						} else {
 							if (me.orderInfo.order_status == 4) {
 								me.overdueMoneyFn(me.orderInfo.car_sn)
-								
-								me.orderInfo.hire_duration_time = common.timestampToDays(Math.ceil(Math.floor(new Date()) / 1000 - me.orderInfo.hire_end_time))
+
+								// me.orderInfo.hire_duration_time = common.timestampToDays(Math.ceil(Math.floor(
+								// 	new Date()) / 1000 - me.orderInfo.hire_end_time))
+								me.orderInfo.hire_duration_time = common.formatTimeDifference(me.orderInfo
+									.hire_end_time * 1000)
+
 							} else {
-								me.orderInfo.hire_duration_time = common.timestampToDays(Math.ceil(me.orderInfo.hire_begin_time - me.orderInfo.hire_end_time))
+								me.orderInfo.hire_duration_time = common.timestampToDays(Math.ceil(me.orderInfo
+									.hire_begin_time - me.orderInfo.hire_end_time))
 							}
 						}
 					} else {
@@ -610,7 +702,7 @@
 				}
 				//提交还车图片
 				uni.navigateTo({
-					url: `/pages/activation/activation?isReturnCar=true,model_id=${this.orderInfo.model_id}&sub_sn=${this.sub_sn}&car_sn=${this.orderInfo.car_sn}&isOverdue=${isOverdue}&overdueMoney=${this.overdueData.money}&overdueTime=${this.overdueData.time}`
+					url: `/pages/activation/activation?isReturnCar=true&model_id=${this.orderInfo.model_id}&sub_sn=${this.sub_sn}&car_sn=${this.orderInfo.car_sn}&isOverdue=${isOverdue}&overdueMoney=${this.overdueData.money}&overdueTime=${this.overdueData.time}&type=index`
 				});
 				// if (isOverdue) {
 				// 	this.setData({
@@ -651,6 +743,7 @@
 					})
 					if (data.code == 200) {
 						common.simpleToast(data.msg)
+						this.isShowCancel = false
 						this.bindOrderInfo()
 					} else {
 						common.simpleToast(data.msg)

+ 4 - 10
pages/package/package.css

@@ -8,11 +8,6 @@
 	background-size: cover;
 }
 
-.return-view {
-	width: 40rpx;
-	height: 40rpx;
-	margin-left: 32rpx;
-}
 
 .top-text {
 	margin-left: 230rpx;
@@ -94,7 +89,7 @@
 .box-view {
 	padding-left: 24rpx;
 	padding-right: 24rpx;
-	margin-top: 68rpx;
+	margin-top: 210rpx;
 }
 
 .package-view {
@@ -104,12 +99,11 @@
 	margin-bottom: 20rpx;
 }
 
-.top-view {
-	margin-bottom: 32rpx;
-	padding-bottom: 28rpx;
-	border-bottom: 2rpx solid #F4F5F6;
+.top-view{
+	margin-bottom: 30rpx;
 }
 
+
 .top-title {
 	color: #060809;
 	font-size: 42rpx;

+ 45 - 67
pages/package/package.vue

@@ -1,20 +1,16 @@
 <template>
 	<view class="container-view">
-		<view class="top-bg" >
-			<navBar name="我的套餐" bgColor="transparent"></navBar>
-			<!-- <view class="flex-row" :style="'height:'+navabarHeight+'px;'">
-				<view class="flex-row" @tap="bindReturnView"><img class="return-view" src="https://qiniu.bms16.com/FnHXbzly7aXi8zLghrTU5BZdwH5_" /></view>
-				<text class="top-text">我的套餐</text>
-			</view> -->
-			
+		<view class="top-bg">
+			<Navigation :scroll='scrollTop'></Navigation>
+			<view :style="{height: `calc(${statusBarHeight}px + 100px)`}"></view>
 			<view class="package-card flex-row flex-between">
 				<view class="flex-row flex-column" style="align-items: flex-start;">
-					<view class="left-first flex-row">
+					<view @click="$srcFn(`/pages/carList/carList`)" class="left-first flex-row">
 						<view>{{car_info.car_name}}</view>
 						<img class="left-img" src="https://qiniu.bms16.com/Fpf25Lkkrx05pvLw08mksVQKAQWf" />
 					</view>
 					<view class="left-second flex-row">
-						<view style="margin-right: 32rpx;">适用电池:<text>48v20Ah</text></view>
+						<view style="margin-right: 32rpx;">适用电池:<text>{{car_info.battery_tag_info.main_tag_name ? (car_info.battery_tag_info.main_tag_name) : ''}}{{car_info.battery_tag_info.child_tag_name ? '/' + car_info.battery_tag_info.child_tag_name : ''}}</text></view>
 						<!-- <view>押金:<text>$5.0</text></view> -->
 					</view>
 					<view class="left-third">
@@ -25,22 +21,6 @@
 			</view>
 		</view>
 		<view class="box-view">
-			<!-- <view class="package-card flex-row flex-between">
-				<view class="flex-row flex-column" style="align-items: flex-start;">
-					<view class="left-first flex-row">
-						<view>小米 Su7</view>
-						<img class="left-img" src="https://qiniu.bms16.com/Fpf25Lkkrx05pvLw08mksVQKAQWf" />
-					</view>
-					<view class="left-second flex-row">
-						<view style="margin-right: 32rpx;">适用电池:<text>48v20Ah</text></view>
-						<view>押金:<text>$5.0</text></view>
-					</view>
-					<view class="left-third">
-						<view>卡号:<text>2024110202578</text></view>
-					</view>
-				</view>
-				<img class="card-right" src="https://qiniu.bms16.com/FuOJQxzypa-NginyHGdsWlzwnB8z" />
-			</view> -->
 			<view class="package-view" v-for="item in hireOrderList">
 				<view class="top-view flex-row flex-between">
 					<view class="top-title" v-if="item.package_type == 1">
@@ -57,18 +37,20 @@
 					<view v-if="item.package_status==2" class="card-text card-o">已结束</view>
 				</view>
 				<view class="package-item" style="margin-bottom: 32rpx;">
-					<view class="item-title">有效期至</view>
+					<view v-if="item.expire_time != 0" class="item-title">有效期至</view>
 					<view class="item-info">{{tools.formatTime(item.expire_time)}}</view>
 				</view>
 				<view v-if="item.package_type != 2" class="package-item" style="margin-bottom: 32rpx;">
 					<view class="item-title">有效时长</view>
 					<view class="item-info">
-						{{calculateRemainingDays(item.expire_time)}}<text style="color: #9FA7B7;">/{{item.total_day}}天</text>
+						{{ item.expire_time != 0 ? calculateRemainingDays(item.expire_time) : item.total_day }}<text
+							style="color: #9FA7B7;">/{{item.total_day}}天</text>
 					</view>
 				</view>
 				<view v-if="item.package_type == 1" class="package-item">
 					<view class="item-title">免费换电数</view>
-					<view style="color: #060809;" class="item-info">{{item.last_num}}次</view>
+					<!-- <view style="color: #060809;" class="item-info">{{item.last_num}}次</view> -->
+					<view style="color: #060809;" class="item-info">不限次数</view>
 				</view>
 				<view v-if="item.package_type == 2" class="package-item">
 					<view class="item-title">免费换电数</view>
@@ -85,84 +67,79 @@
 	</view>
 </template>
 <script module="tools" lang="wxs" src="@/pages/common/wxs/tools.wxs"></script>
-	<script module="tools" lang="sjs" src="@/pages/common/wxs/tools.sjs"></script>
+<script module="tools" lang="sjs" src="@/pages/common/wxs/tools.sjs"></script>
 <script>
 	var config = require('../../common/config_gyq.js');
 	var common = require('../../common/common.js');
 	var http = require('../../common/request.js');
 	var storage = require('../../common/storage.js');
 	const dayjs = require('dayjs');
-	import { getRemainingTime } from '../../utils/util.js';
+	import {
+		getRemainingTime
+	} from '../../utils/util.js';
 	export default {
 		components: {
-			
+
+		},
+		onPageScroll(e) {
+			this.scrollTop = e.scrollTop
 		},
 		data() {
 			return {
-				hireOrderList:[],
+				hireOrderList: [],
 				page: 1,
-				limit: 10,
-				car_info:{},
+				limit: 100,
+				car_info: {},
 				// statusBarHeight: 0,
 				// navabarHeight: 0,
-				packageList: [
-					{ctime: '2024-04-04 16:15',total_duration: 30,efficient_day: 24,change_rate: 6,total_times: 10,status:1},
-					{ctime: '2024-04-04 16:15',total_duration: 30,efficient_day: 24,change_rate: 6,total_times: 10,status:2},
-				]
+				packageList: []
 			};
 		},
 		/**
 		 * 生命周期函数--监听页面加载
 		 */
 		onLoad: function(options) {
-			this.car_info = uni.getStorageSync('car_info') || {};
-			// const clientRect = uni.getMenuButtonBoundingClientRect()
-			// const sysinfo = uni.getSystemInfoSync()
-			// let GAP = 8
-			// // #ifdef MP-ALIPAY
-			// GAP = 0
-			// // #endif
-			// const navabarHeight = (clientRect.bottom - sysinfo.statusBarHeight) + (clientRect.top - sysinfo.statusBarHeight) + GAP
-			// this.navabarHeight = navabarHeight
-			// this.statusBarHeight = sysinfo.statusBarHeight
-			this.mapCtx = uni.createMapContext('myMap');
-			this.listFn()
+			
 		},
 		/**
 		 * 生命周期函数--监听页面显示
 		 */
 		onShow: function() {
-			
+			this.car_info = uni.getStorageSync('car_info') || {};
+			this.listFn()
 		},
 		methods: {
-			 calculateRemainingDays(expirationDate) {
-			  // 获取当前时间
-			  const now = dayjs();
-			  // 解析到期时间
-			  const endDate = dayjs(expirationDate);
-			  // 计算剩余天数
-			  const remainingDays = endDate.diff(now, 'day');
-			  return remainingDays || 0;
+			calculateRemainingDays(expirationDate) {
+				
+				// // 获取当前时间
+				// const now = dayjs();
+				// // 解析到期时间
+				// const endDate = dayjs(expirationDate * 1000);
+				// // 计算剩余天数
+				// const remainingDays = endDate.diff(now, 'day');
+				// return remainingDays || 1;
+				
+				return  common.formatTimeDifference(expirationDate * 1000)
 			},
-			srcFn(){
+			srcFn() {
 				uni.navigateTo({
 					url: `/pages/batteryPackage/batteryPackage`
 				})
 			},
-			validDurationFn(start,end){
-				return getRemainingTime(start,end)
+			validDurationFn(start, end) {
+				return getRemainingTime(start, end)
 			},
-			async listFn(){
+			async listFn() {
 				let {
 					data
 				} = await http.postApi(config.API_FLK_EXCHANGE_PACKAGE_ORDER_LIST, {
 					page: this.page,
-					pay_status:2,
-					car_sn:this.car_info.car_sn,
+					pay_status: 2,
+					car_sn: this.car_info.car_sn,
 					limit: this.limit,
 				})
 				if (data.code == 200) {
-					this.hireOrderList.push.apply(this.hireOrderList, data.data.list)
+					this.hireOrderList = data.data.list
 				} else {
 					common.simpleToast(resp.data.msg)
 				}
@@ -178,7 +155,8 @@
 
 <style>
 	@import './package.css';
-	.packageBtn{
+
+	.packageBtn {
 		width: 686rpx;
 		height: 80rpx;
 		background: #060809;

+ 1 - 1
pages/phoneLogin/phoneLogin.vue

@@ -34,7 +34,6 @@
 	var common = require('../../common/common.js');
 	var http = require('../../common/http.js');
 	var storage = require('../../common/storage.js');
-	var app = getApp()
 	export default {
 		data() {
 			return {
@@ -201,6 +200,7 @@
 								uni.reLaunch({
 									url: '/pages/index/index',
 								})
+								const app = getApp();
 								let accounts = app.globalData.accountManagement
 								accounts.push(accountsData2)
 								if (accounts.length >0) {

+ 2 - 2
pages/powerSetting/powerSetting.vue

@@ -2,7 +2,7 @@
 		<view class="power-setting-main">
 			<navBar name="权限设置" bgColor="transparent"></navBar>
 			<view class="flex-row power-setting-head">
-				<img class="head-img" :src="headimg" alt="">
+				<image class="head-img" :src="headimg" mode="aspectFit"></image>
 				<view class="head-name">{{nickname}}</view>
 				<text class="head-email">{{form.email}}</text>
 			</view>
@@ -83,7 +83,7 @@
 				return
 			}
 			this.form.email = options.email;
-			this.form.headimg = options.headimg;
+			this.headimg = options.headimg;
 			this.form.nickname = options.nickname;
 		},
 		methods: {

+ 7 - 1
pages/purchaseOrder/purchaseOrder.vue

@@ -11,7 +11,7 @@
 		</view>
 		<view class="car-info-view">
 			<view class="flex-row align-center">
-				<image style="width: 160rpx;height: 160rpx;border-radius: 16rpx;" :src="modelInfo.model_images" mode="aspectFill"></image>
+				<image style="width: 160rpx;height: 160rpx;border-radius: 16rpx;" :src="modelInfo.model_images" mode="aspectFit"></image>
 				<view class="flex-row car-info-grow">
 					<view class="flex-row align-center">
 						<view class="car-name">{{modelInfo.car_model_name}}</view>
@@ -177,6 +177,7 @@
 		},
 		data() {
 			return {
+				takeCar:'',
 				isShowReturnCar:false,
 				isShowCheckOrder:false,
 				sub_sn: "",
@@ -197,7 +198,12 @@
 		,
 		onLoad: function(options) {
 			if (options && options.params) {
+				// #ifdef APP
+				const model_info = JSON.parse(options.params) || {}
+				// #endif
+				// #ifndef APP
 				const model_info = JSON.parse(decodeURIComponent(options.params)) || {}
+				// #endif
 				console.log(model_info, 'model_info');
 				model_info.model_images = model_info.model_images ? model_info.model_images[0] : ''
 				this.setData({

+ 2 - 1
pages/service/components/carRentalList/carRentalList.css

@@ -117,11 +117,12 @@
 .bottom-text>text:nth-of-type(1) {
 	color: #F95151;
 	font-weight: bold;
+	font-size: 22rpx;
 }
 
 .bottom-text>text:nth-of-type(2) {
 	color: #F95151;
-	font-size: 40rpx;
+	font-size: 28rpx;
 	font-weight: bold;
 }
 

+ 61 - 32
pages/service/components/carRentalList/carRentalList.vue

@@ -1,14 +1,16 @@
 <template>
 	<view>
 		<block>
-			<view :class='{"active" : activeMarkersId == item.id}' class="store-card" v-if="item.admin_id"  @click="navToStore(item.admin_id)" v-for="(item, index) in near_store_list" :key="index">
+			<view :class='{"active" : activeMarkersId == item.id}' class="store-card" v-if="item.admin_id"
+				@click="navToStore(item.admin_id)" v-for="(item, index) in near_store_list" :key="index">
 				<view>
 					<view class="card-top-style flex-row flex-between">
 						<view class="shop_name">{{item.shop_name}}</view>
 						<view>{{item.distance}}</view>
 					</view>
 					<view class="card-center-ren flex-row">
-						<view style="color: #0A59F7;border-color: #0A59F7;" v-for="(items,indexs) of item.business_list" :key="indexs" class=" tag align-c">
+						<view style="color: #0A59F7;border-color: #0A59F7;" v-for="(items,indexs) of item.business_list"
+							:key="indexs" class=" tag align-c">
 							{{items.title}}
 						</view>
 						<view class="align-c tag">
@@ -18,11 +20,14 @@
 					</view>
 				</view>
 				<view v-if="item.model_list.length===1">
-					<view @click.stop="$srcFn(`/pages/carDetail/carDetail?model_id=${item.model_list[0].model_id}`)" class="card-bottom card-first flex-row">
+					<view @click.stop="$srcFn(`/pages/carDetail/carDetail?model_id=${item.model_list[0].model_id}&shop_type=${shopType}&hire_price=${item.model_list[0].hire_price}`)"
+						class="card-bottom card-first flex-row">
 						<view class="second-view flex-row">
 							<view>
-								<image :src="item.model_list[0]!=''?item.model_list[0].model_images:'https://qiniu.bms16.com/FhEvnKUckAHPtWaC04mi2s53IEVj'" mode="aspectFill"></image>
-								</view>
+								<image
+									:src="item.model_list[0]!=''?item.model_list[0].model_images:'https://qiniu.bms16.com/FhEvnKUckAHPtWaC04mi2s53IEVj'"
+									mode="aspectFit"></image>
+							</view>
 							<view class="bottom-item">
 								<view>{{item.model_list[0].model_name}}</view>
 								<view>
@@ -30,22 +35,25 @@
 								</view>
 								<view class="flex-row flex-between">
 									<view class="bottom-text">
-										{{ curType() }} <text style="margin-left: 10rpx;">¥</text><text>{{60 }}</text>
+										{{ leaseUnitsResult }} <text
+											style="margin-left: 10rpx;">¥</text><text>{{item.model_list[0].hire_price}}</text>
 									</view>
 								</view>
 							</view>
 						</view>
 					</view>
 				</view>
-				
-				<scroll-view v-if="item.model_list.length>1" :scroll-into-view="'into'+into" scroll-x="true" enable-flex class="scrollview-box"
-					scroll-with-animation @scroll="onScroll">
-					<view @click.stop="$srcFn(`/pages/carDetail/carDetail?model_id=${items.model_id}`)" v-for="(items,index) in item.model_list" :key="index"
-						:style="{ marginLeft: index > 0 ? '32rpx' : '0' }" class="form-item" :data-item="items"
-						>
+
+				<scroll-view v-if="item.model_list.length>1" :scroll-into-view="'into'+into" scroll-x="true" enable-flex
+					class="scrollview-box" scroll-with-animation @scroll="onScroll">
+					<view @click.stop="$srcFn(`/pages/carDetail/carDetail?model_id=${items.model_id}&shop_type=${shopType}&hire_price=${items.hire_price}`)"
+						v-for="(items,index) in item.model_list" :key="index"
+						:style="{ marginLeft: index > 0 ? '32rpx' : '0' }" class="form-item" :data-item="items">
 						<view class="second-view flex-row">
 							<view>
-									<image :src="items.model_images || 'https://qiniu.bms16.com/FhEvnKUckAHPtWaC04mi2s53IEVj'" mode="aspectFill"></image>
+								<image
+									:src="items.model_images || 'https://qiniu.bms16.com/FhEvnKUckAHPtWaC04mi2s53IEVj'"
+									mode="aspectFit"></image>
 							</view>
 							<view class="bottom-item">
 								<view>{{ items.model_name }}</view>
@@ -54,7 +62,12 @@
 								</view>
 								<view class="flex-row flex-between">
 									<view class="bottom-text">
-										{{ curType() }} <text style="margin-left: 10rpx;">¥</text><text>{{ 60}}</text>
+										{{ leaseUnitsResult }}<text
+											style="margin-left: 10rpx;">¥</text><text>{{(items.hire_price /100).toFixed(2)}}</text>
+									</view>
+									<view v-if="items.sell_price && isBuy" class="bottom-text">
+										购买<text
+											style="margin-left: 10rpx;">¥</text><text>{{(items.sell_price /100).toFixed(2)}}</text>
 									</view>
 								</view>
 							</view>
@@ -69,13 +82,13 @@
 					</view>
 					<view class="flex-row align-center">
 						<view>
-								<image @click.stop="callFn(item.link_phone)" style="width: 84rpx;height: 64rpx;"
-								src="https://qiniu.bms16.com/Ft0YA1JYmq66hdoeEN-PgBHy5vLa"  mode=""></image>
+							<image @click.stop="callFn(item.link_phone)" style="width: 84rpx;height: 64rpx;"
+								src="https://qiniu.bms16.com/Ft0YA1JYmq66hdoeEN-PgBHy5vLa" mode=""></image>
 						</view>
 						<view style="margin-left: 20rpx;">
 							<image @click.stop="bindToNav(item)" style="width: 112rpx;height: 64rpx;"
 								src="https://qiniu.bms16.com/Fts38M35doVjK09GfOza5qD-wwkK" mode=""></image>
-								
+
 						</view>
 					</view>
 				</view>
@@ -98,17 +111,35 @@
 		loginToast
 	} from '@/utils'
 	export default {
+		computed: {
+			leaseUnitsResult() {
+				const result = LEASE_TYPE_ARR.find(v => v.value == this.shopType);
+				return result ? result.label : '';
+			},
+			leaseUnits() {
+				const result = LEASE_TYPE_ARR.find(v => v.value == this.shopType);
+				return result ? result.unit : '';
+			}
+		},
 		props: {
+			isBuy: {
+				type: Boolean,
+				defult: true
+			},
+			shopType: {
+				type: Number,
+				defult: 1
+			},
 			params: {
 				type: Object
 			},
-			near_store_list:{
-				type:Array,
-				defult:[]
+			near_store_list: {
+				type: Array,
+				defult: []
 			},
-			activeMarkersId:{
-				type:Number,
-				defult:0
+			activeMarkersId: {
+				type: Number,
+				defult: 0
 			}
 		},
 		data() {
@@ -140,9 +171,6 @@
 				model_list: [],
 				shopModelListView: []
 			};
-		},
-		computed: {
-			
 		},
 		watch: {
 			// params: {
@@ -166,7 +194,7 @@
 					name: shop_name,
 				})
 			},
-			callFn(tel){
+			callFn(tel) {
 				uni.showModal({
 					content: `您是否要拨打电话${tel}?`,
 					confirmText: '确定',
@@ -185,7 +213,7 @@
 				return '租'
 			},
 			async navToStore(admin_id) {
-				const url = '/pages/storeDetails/storeDetails?admin_id=' + admin_id 
+				const url = '/pages/storeDetails/storeDetails?admin_id=' + admin_id
 				uni.navigateTo({
 					url
 				})
@@ -240,7 +268,7 @@
 						let all_num = 0
 						let distance = ''
 						for (let i = 0; item.model_list.length > i; i++) {
-							
+
 							let model_item = item.model_list[i]
 							all_num += item.model_list[i].car_num - 0
 							distance = common.formatDistance(item.distance)
@@ -248,8 +276,9 @@
 						item.all_num = all_num
 						item.distance = distance
 						item.model_list.map(items => {
-							items.model_images =  items.model_images
-							items.total_price = (me.leaseTime * (items.price_setting[0].hire_price - 0)) /100
+							items.model_images = items.model_images
+							items.total_price = (me.leaseTime * (items.price_setting[0].hire_price - 0)) /
+								100
 							return item
 						})
 					}
@@ -339,4 +368,4 @@
 
 <style scoped>
 	@import url("./carRentalList.css");
-</style>
+</style>

+ 54 - 19
pages/service/components/leaseType/leaseType.vue

@@ -2,35 +2,38 @@
     <view class="container-view-contril">
 		<u-popup zIndex='9999' v-model="showLeaseType" :mask-close-able='false' :closeable="false" mode="bottom" border-radius="32">
 		    <view class="bottom-popup">
-		        <view class="title">{{ selectType == 'cabinet' ? '车辆类型' : '用车方案' }}</view>
+		        <view class="title">{{ selectType == 'cabinet' ? '车辆类型' : '租借类型' }}</view>
 		        <scroll-view style="max-height: 700rpx;" scroll-y>
 		        	<view class="item-wrap">
-		        		<view
-		        		    :class="['item', leaseType == 100 && 'checked']"
-		        		    @click="leaseType = 100"
-		        		>
-		        		    全部
-		        		</view>
 		        	    <template v-if="selectType == 'cabinet'">
 		        	        <view 
 		        	            v-for="(item, index) in modelTypeList" 
-		        	            :class="['item', leaseType == item.id && 'checked']"
+		        	            :class="['item', leaseType == item.name && 'checked']"
 		        	            :key="index"
-		        	            @click="leaseType = item.id"
+		        	            @click="leaseType = item.name"
 		        	        >
 		        	            {{ item.name }}
 		        	        </view>
 		        	    </template>
 		        	    <template v-if="selectType == 'store'" >
-		        	        <view 
-		        	            v-for="(item, index) in LEASE_TYPE_ARR" 
-		        	            :class="['item', leaseType == item.value && 'checked']"
-		        	            :key="index"
-		        	            @click="leaseType = item.value"
-		        	        >
-		        	            {{ item.label }}
+		        	        <view class="">
+		        	        	<view class="flexs">
+		        	        		<view
+		        	        		    v-for="(item, index) in LEASE_TYPE_ARR" 
+		        	        		    :class="['item', leaseType == item.value && 'checked']"
+		        	        		    :key="index"
+		        	        		    @click="leaseType = item.value"
+		        	        			v-if="item.value != 100"
+		        	        		>
+		        	        		    {{ item.label }}
+		        	        		</view>
+		        	        	</view>
+		        	        	<view class="bugFlex">
+		        	        		  <view class="title">购买</view>
+		        	        		  <u-switch v-model="buy"></u-switch>
+		        	        	</view>
 		        	        </view>
-		        	        <view class="item" style="opacity: 0;"></view>
+							
 		        	    </template>
 		        	</view>
 		        </scroll-view>
@@ -53,7 +56,8 @@ export default {
         return {
 			// showLeaseType: false,
 			LEASE_TYPE_ARR,
-			leaseType:100
+			leaseType:100,
+			buy:true
 		};
     },
     /**
@@ -67,12 +71,25 @@ export default {
 			type: Boolean,
 			default: false
 		},
+		isBuy:{
+			type: Boolean,
+			default: true
+		},
+		shopType:{
+			type: Number,
+			default: 1
+		},
         selectType: {
 			type: String,
 			default: ''
 		},
 
     },
+	mounted() {
+		
+		this.leaseType = this.shopType
+		this.buy = this.isBuy
+	},
     /**
      * 组件的方法列表
      */
@@ -81,12 +98,26 @@ export default {
             this.$emit('closeSelectType')
 		},
         chooseLeaseType() {
-            this.$emit('checkCabinetType', this.leaseType)
+			console.log(this.buy)
+            this.$emit('checkCabinetType', {
+				selectType:this.selectType,
+				leaseType:this.leaseType,
+				isBuy:this.buy
+			})
 		}
 	}
 };
 </script>
 <style lang="scss" scoped>
+	.bugFlex{
+		display: flex;
+		justify-content: space-between;
+		margin-top: 30rpx;
+	}
+	.flexs{
+		display: flex;
+		flex-wrap: wrap;
+	}
 .bottom-popup {
         padding: 40rpx 32rpx 32rpx 32rpx;
         padding-bottom: env(safe-area-inset-bottom);
@@ -121,6 +152,10 @@ export default {
                 color: #060809;
                 text-align: center;
                 font-style: normal;
+				margin-right: 16rpx;
+				&:nth-child(3n+3){
+					margin-right: 0;
+				}
             }
             .checked {
                 background: #FFFFFF;

+ 127 - 76
pages/service/service.vue

@@ -15,8 +15,10 @@
 		<!-- #endif -->
 
 		<!-- #ifdef APP -->
-		<googleMap keyId="1" width="100%" height='calc(50vh - 0rpx)' @changMarkertap="changMarkertap"
-			v-if="myLocation.latitude" :mapData='markers' :myLocation='myLocation'></googleMap>
+		<view style="width: 100%;height: calc(50vh - 0rpx);">
+			<googleMap keyId="1" width="100%" height='calc(50vh - 0rpx)' @changMarkertap="changMarkertap"
+				v-if="myLocation.latitude" :mapData='markers' :myLocations='myLocation'></googleMap>
+		</view>
 		<!-- #endif -->
 
 		<!-- 地图控件 -->
@@ -55,17 +57,24 @@
             ]">换电柜</view>
 				</view>
 				<view class="config-view flex-row">
+					<view @click='openSelectType' class="flex-row selectFlex">
+						<text v-if="selectType === 'store'" class="text">{{leaseUnitsResult}}{{isBuy ? "+购买" : ''}}</text>
+						<text v-if="selectType === 'cabinet'" class="text">{{cabinetType ? cabinetType : '全部'}}</text>
+						<u-icon v-if="showLeaseType" name="arrow-down" color="#9FA7B7" size="26"></u-icon>
+						<u-icon v-else name="arrow-up" color="#9FA7B7" size="26"></u-icon>
+					</view>
 					<view class="seach-img" @tap="openSearch"><img
 							src="https://qiniu.bms16.com/FiWnFuZm5vWQ_Si3CEYLGJnVhSal" alt="搜索" /></view>
-					<view @tap="openSelectType" class="screen-img"><img
+					<!-- <view @tap="openSelectType" class="screen-img"><img
 							:src="'https://qiniu.bms16.com/'+(shop_type!=''?'FikPWd13ENc2SWnC3q1n5F22uUDs':'FpElQHM5NbxHDjz1LrwaHYN668LR')"
-							alt="筛选" /></view>
+							alt="筛选" /></view> -->
 				</view>
 			</view>
-			<CarRentalList :activeMarkersId='activeMarkersId' v-if="selectType === 'store'" :near_store_list="nearCabinetList" />
+			<CarRentalList :isBuy='isBuy' :shopType='shopType' :activeMarkersId='activeMarkersId' v-if="selectType === 'store'" :near_store_list="nearCabinetList" />
+			
 			<CabinetList v-if="selectType === 'cabinet'" :near_cabinet_list="nearCabinetList" />
 		</view>
-		<leaseType :showLeaseType="showLeaseType" :selectType="selectType" :modelTypeList="modelTypeList"
+		<leaseType :isBuy='isBuy' :shopType='shopType' :showLeaseType="showLeaseType" :selectType="selectType" :modelTypeList="modelTypeList"
 			@closeSelectType="closeSelectType" @checkCabinetType="checkCabinetType" />
 			
 		<CustomTabbar curt-tab="service" />
@@ -73,7 +82,6 @@
 </template>
 
 <script>
-	var app = getApp();
 	var config = require("@/common/config.js");
 	var config_gyq = require("@/common/config_gyq.js");
 	var common = require("@/common/common.js");
@@ -97,6 +105,9 @@
 	export default {
 		data() {
 			return {
+				cabinetType:0,
+				shopType:1,
+				isBuy:true,
 				activeMarkersId: 0,
 				selectType: "store",
 				type: 1,
@@ -113,6 +124,16 @@
 				shop_type: ''
 			};
 		},
+		computed: {
+			leaseUnitsResult() {
+				const result = LEASE_TYPE_ARR.find(v => v.value == this.shopType);
+				return result ? result.label : '';
+			},
+			leaseUnits(){
+				const result = LEASE_TYPE_ARR.find(v => v.value == this.shopType);
+				return result ? result.unit : '';
+			}
+		},
 		components: {
 			googleMap,
 			LeaseType,
@@ -125,9 +146,7 @@
 		 */
 		onLoad: function(options) {
 			this.loadModelType();
-			
 		},
-		
 		onShow() {
 			this.locationFn()
 		},
@@ -146,42 +165,7 @@
 				}
 				this.nearCabinetList.unshift(this.nearCabinetList.splice(index, 1)[0])
 			},
-
-			markertapFn(e) {
-				let markerId = e.markerId
-				if (markerId == 5000) return
-				if (this.selectType == 'store') {
-					this.markers.map(item => {
-						if (markerId == item.id) {
-							item.iconPath = SHOPSELECTIMG
-							let distance = common.getFlatternDistance(this.myLocation.longitude, this.myLocation
-								.latitude, item.longitude, item.latitude)
-							let time = Math.ceil(Number(((distance - 0) / 1000).toFixed(2)) * 25 / 10)
-							let content = `${common.formatDistance(Number(distance))} 骑行${time}分钟`
-							item.label = {
-								content,
-								color: "#0074FF",
-								fontSize: 10,
-								bgColor: "#fff",
-								borderRadius: 10,
-								padding: 5,
-								anchorX: -45,
-								anchorY: -6
-							}
-							this.activeMarkersId = item.id
-						} else {
-							item.iconPath = CABINET_ICON_URL
-							item.label = {}
-						}
-					})
-				} else if (this.selectType == 'cabinet') {
-
-				}
-
-			},
-
-
-			async locationFn() {
+			locationFn() {
 				let _this = this
 				if (this.selectType === "store") {
 					this.loadCarRentalList();
@@ -189,7 +173,6 @@
 					this.loadNearCabinetList();
 				}
 			},
-
 			tapSelectType(e) {
 				const {
 					type
@@ -207,33 +190,48 @@
 
 			},
 			//附近门店列表
-			loadCarRentalList(name = '', shop_type = '') {
+			loadCarRentalList(name = '') {
 				const pData = {
 					limit: 50,
 					longitude: this.myLocation.longitude,
 					latitude: this.myLocation.latitude,
 					name,
-					shop_type
+					shop_type:'',
+					duration_unit:this.shopType
 				};
 				const me = this;
-				var nearCabinetList = [];
+				let nearCabinetList = [];
 				http.postApi(config.API_NEAR_SHOP_LIST, pData, (resp) => {
 					if (resp.data.code == 200) {
 						me.markers = {}
 						let markers = {
 							markers: []
 						}
-						nearCabinetList = resp.data.data.list.map(item => {
-							item.model_list.map(items=>{
-								items.model_images = items.model_images.split(',')[0] || ''
-							})
-							return {
-								...item,
-								distance: common.formatDistance(common.getFlatternDistance(this.myLocation
+						for (let index = 0; index < resp.data.data.list.length; index++) {
+								let element = resp.data.data.list[index];
+								element.distance = common.formatDistance(common.getFlatternDistance(this.myLocation
 									.longitude, this
-									.myLocation.latitude, item.longitude, item.latitude))
-							}
-						})
+									.myLocation.latitude, element.longitude, element.latitude))
+								let model_list = []
+								
+								for (let y = 0; y < element.model_list.length; y++) {
+									let item = element.model_list[y];
+										item.model_images = item.model_images.split(',')[0] || ''
+										let price_setting = []
+										for (let i = 0; i < item.price_setting.length; i++) {
+											let items1 = item.price_setting[i];
+											if(items1.hire_duration_unit == this.shopType){
+												item.hire_price = items1.hire_price
+												model_list.push(item)
+											}
+										}
+								}
+								nearCabinetList.push({
+									...element,
+									model_list
+								})
+						}
+						
 						markers.markers = nearCabinetList.map(item => {
 							return {
 								width: 50,
@@ -248,31 +246,43 @@
 						})
 
 						this.getLocationPostion(this.myLocation, markers);
-						// console.log(nearCabinetList, "nearCabinetList");
-						me.setData({
-							nearCabinetList: nearCabinetList,
-						});
+						this.nearCabinetList = nearCabinetList
 					} else {
 						common.simpleToast(resp.data.msg);
 					}
 				});
 			},
 			//附近机柜列表
-			async loadNearCabinetList(name = '') {
+			async loadNearCabinetList(cabinet_name = '') {
 				const pData = {
 					limit: 50,
 					longitude: this.myLocation.longitude,
 					latitude: this.myLocation.latitude,
-					name
+					cabinet_name
 				};
 				const me = this;
-				var nearCabinetList = [];
+				let nearCabinetList = [];
 				let {
 					data
 				} = await http_gyq.postApi(config_gyq.API_FLK_CABINET_NEAR_LIST, pData)
 				if (data.code === 200) {
 					this.markers = {}
-					nearCabinetList = data.data.cabinetList || [];
+					// nearCabinetList = data.data.cabinetList || [];
+					for (let i = 0; i < data.data.cabinetList.length; i++) {
+						let item = data.data.cabinetList[i];
+						if(this.cabinetType){
+							for (let i = 0; i < item.tag_code.length; i++) {
+								let items = item.tag_code[i];
+								if(items.main_tag_name == this.cabinetType || items.child_tag_name == this.cabinetType){
+									nearCabinetList.push(item)
+								}
+								
+							}
+						}else{
+							nearCabinetList.push(item)
+						}
+						
+					}
 					let markers = {}
 					markers.markers = nearCabinetList.map(item => {
 						return {
@@ -327,7 +337,7 @@
 				this.isFocused = true;
 			},
 			handleBlur() {
-				this.isFocused = false;
+				// this.isFocused = false;
 			},
 			clearSearch() {
 				this.setData({
@@ -336,6 +346,9 @@
 			},
 			openSearch() {
 				this.isSearch = !this.isSearch;
+				if(this.isSearch == false){
+					this.inputSearchValue = ''
+				}
 				this.isFocused = true;
 			},
 			openSelectType() {
@@ -356,14 +369,41 @@
 				}
 			},
 			checkCabinetType(e) {
-				console.log(e, "e");
-				const obj = LEASE_TYPE_ARR.find(v => v.value == e)
-				const shop_type = (e == 100) ? '' : obj.type
-				this.setData({
-					showLeaseType: false,
-					shop_type
-				});
-				this.loadCarRentalList('', shop_type)
+				if(e.selectType == "store"){
+					this.isBuy = e.isBuy
+					this.shopType = e.leaseType
+					this.showLeaseType = false
+					this.loadCarRentalList()
+				}else{
+					this.cabinetType = e.leaseType
+					this.showLeaseType = false
+					this.loadNearCabinetList()
+				}
+				// console.log(e, "e");
+				// const obj = LEASE_TYPE_ARR.find(v => v.value == e)
+				// const shop_type = (e == 100) ? '' : obj.type
+				// this.setData({
+				// 	showLeaseType: false,
+				// 	shop_type
+				// });
+				// this.loadCarRentalList('', shop_type)
+			},
+			shopList(list){
+				let nearCabinetList = []
+				for (let i = 0; i < list.length; i++) {
+					let item = list[i];
+					for (var index = 0; index < item.model_list.length; index++) {
+						var items = item.model_list[index];
+							for (var s = 0; s < items.price_setting.length; s++) {
+								var element = items.price_setting[s];
+								if(element.hire_duration_unit == this.shopType){
+									items.hire_price = element.hire_price
+								}
+							}
+					}
+					nearCabinetList.push(item)
+				}
+				this.nearCabinetList = nearCabinetList
 			},
 			loadModelType() {
 				const me = this
@@ -382,4 +422,15 @@
 </script>
 <style>
 	@import "./service.css";
+	.selectFlex{
+		align-items: center;
+		margin-right: 20rpx;
+	}
+	.selectFlex .text{
+		font-family: PingFangSC, PingFang SC;
+		font-weight: 500;
+		font-size: 32rpx;
+		color: #060809;
+		margin-right: 10rpx;
+	}
 </style>

+ 6 - 0
pages/storeDetails/storeDetails.css

@@ -37,6 +37,10 @@
 	font-size: 40rpx;
 	color: #060809;
 	margin-bottom: 24rpx;
+	width: 600rpx;
+	text-overflow: ellipsis;
+	overflow: hidden;
+	white-space: nowrap;
 }
 .store-type{
 	border-radius: 8rpx;
@@ -341,6 +345,8 @@
 		left: 20rpx;
 		top: 100rpx;
 		z-index: 1000;
+		display: flex;
+		align-items: center;
 	}
 	.return-view {
 		width: 40rpx;

+ 20 - 20
pages/storeDetails/storeDetails.vue

@@ -1,22 +1,18 @@
 <template>
 	<view class="container-view">
-		<!-- <navBar></navBar> -->
-		<!-- <view class="store-img-view" style="background-image: url('https://qiniu.bms16.com/FhG-xwyMdxPVjYNrxXnq5enGFT-2');background-repeat: no-repeat;background-size: 100% 500rpx;">
-			
-		</view> -->
+		<Navigation :scroll='scrollTop'></Navigation>
+		
 		<view class="store-img-view">
-			<view  :class="['car-detail-style']" @tap="bindReturnView">
-				<img  class="return-view" :src="'https://qiniu.bms16.com/Fjpnr3cH9ZqTQrGlw3Ywp3qbJGIG'" />
-			</view>
-			<swiper v-if="shop_image && shop_image.length!=0" class="swiper" :indicator-dots="true" :autoplay="true" :interval="2000"
-				indicator-color="rgba(0, 0, 0, 0.3)" indicator-active-color="#000000" :duration="1000" circular>
+			<swiper v-if="shop_image && shop_image.length!=0" class="swiper" :indicator-dots="true" :autoplay="true"
+				:interval="2000" indicator-color="rgba(0, 0, 0, 0.3)" indicator-active-color="#000000" :duration="1000"
+				circular>
 				<swiper-item class="swiper-item" v-for="(item,index) in shop_image" :key="index">
-					<image class="swiper-item-img" :src="item" mode="aspectFill"></image>
+					<image class="swiper-item-img" :src="item" mode="aspectFit"></image>
 				</swiper-item>
 			</swiper>
-			<image v-else class="bg-img" src="https://qiniu.bms16.com/FhRnr7rADHHsOFfpWO4duD15SgIt" mode="aspectFill">
+			<image v-else class="bg-img" src="https://qiniu.bms16.com/FhRnr7rADHHsOFfpWO4duD15SgIt" mode="aspectFit">
 			</image>
-			
+
 		</view>
 
 		<view class="p-bg">
@@ -124,9 +120,11 @@
 				</view>
 			</view>
 			<view class="car-info-list-view">
-				<view v-for="(item,index) of modelListsFn()"  @click="srcFn(`/pages/carDetail/carDetail?model_id=${item.model_id}`)" :key="index" class="car-info-view align-center flex-row">
+				<view v-for="(item,index) of modelListsFn()"
+					@click="srcFn(`/pages/carDetail/carDetail?model_id=${item.model_id}&shop_type=${tagId}&hire_price=${item.money * 100}`)" :key="index"
+					class="car-info-view align-center flex-row">
 					<!-- <img class="car-img" src="https://qiniu.bms16.com/FsxOysJT2V3KNYev2YWadvjyKn2j" alt=""> -->
-					<image class="car-img" :src="item.model_images[0]" mode="aspectFill"></image>
+					<image class="car-img" :src="item.model_images[0]" mode="aspectFit"></image>
 					<view class="car-info">
 						<view class="car-name flex-row">{{item.model_name}}</view>
 						<view class="car-model-info">续航{{item.endurance}}km|重量{{item.weight}}kg</view>
@@ -135,8 +133,7 @@
 								<text style="margin-right: 8rpx;">{{typeArrFn(tagId)}}</text>
 								<priceTool :price="Number(item.money)" :font_size="40" />
 							</view>
-							<view
-								class="lease-btn">购/租</view>
+							<view class="lease-btn">购/租</view>
 						</view>
 					</view>
 				</view>
@@ -176,6 +173,9 @@
 				isWorkTimer: null
 			};
 		},
+		onPageScroll(e) {
+			this.scrollTop = e.scrollTop
+		},
 		computed: {},
 		/**
 		 * 生命周期函数--监听页面加载
@@ -263,14 +263,14 @@
 
 						let arrSet = Array.from(new Set(arr));
 						let tagListArr = []
-						arrSet.map(item=>{
-							LEASE_TYPE_ARR.map(items=>{
-								if(item == items.value){
+						arrSet.map(item => {
+							LEASE_TYPE_ARR.map(items => {
+								if (item == items.value) {
 									tagListArr.push(items)
 								}
 							})
 						})
-						tagListArr.sort((x,y)=>{
+						tagListArr.sort((x, y) => {
 							return x.sort - y.sort
 						})
 						this.tagList = tagListArr

+ 1 - 1
pages/travelingTrack/travelingTrack.css

@@ -37,9 +37,9 @@
 	color: #5E6F90;
 	background-color: #F3F8FF;
 	border-radius: 40rpx;
+	padding: 0 20rpx;
 	padding-top: 12rpx;
 	padding-bottom: 12rpx;
-	width: 208rpx;
 	text-align: center;
 }
 

+ 25 - 34
pages/travelingTrack/travelingTrack.vue

@@ -10,23 +10,24 @@
 		<!-- #endif -->
 
 		<!-- #ifdef APP -->
-		<googleMap keyId="1" width="100%" height='calc(50vh - 0rpx)' v-if="myLocation.latitude" :mapData='{
+		<googleMap keyId="1" width="100%" height='calc(50vh - 0rpx)' v-if="myLocation.latitude  && mapShow" :mapData='{
 			markers,
+			zoom:17,
 			type:3,
 			polylines
-		}' :myLocation='myLocation'></googleMap>
+		}' :myLocations='myLocation'></googleMap>
 		<!-- #endif -->
 
 		<view class="car-info">
 			<view class="info-top flex-row flex-between">
-				<view class="top-left">
+				<view class="top-left f">
 					<view>{{carInfo.car_name}}</view>
-					<view>{{carInfo.license_plate_number}}</view>
+					<view>车牌号:{{carInfo.license_plate_number}}</view>
 				</view>
 				<view>
 					<image class="img"
 						:src="carInfo.model_images || 'https://qiniu.bms16.com/FguJzvAGtd4AdhDKXVLUo7XiMxWQ'"
-						mode="aspectFill"></image>
+						mode="aspectFit"></image>
 				</view>
 			</view>
 			<view class="ctime">{{time}}</view>
@@ -47,7 +48,7 @@
 					<view>行驶里程</view>
 				</view>
 				<view class="bottom-item">
-					<view>{{tools.toFix((trackInfo.using_time || 0) /3600)}}<text>h</text></view>
+					<view>{{tools.toFix((trackInfo.total_time || 0) / 60 / 60)}}<text>h</text></view>
 					<view>骑行时长</view>
 				</view>
 				<view class="bottom-item">
@@ -79,6 +80,7 @@
 		},
 		data() {
 			return {
+				mapShow:false,
 				time:'未知',
 				carInfo: {},
 				id: 0, // 使用 marker点击事件 需要填写id
@@ -90,10 +92,6 @@
 					enableTraffic: false // 是否开启实时路况
 				},
 				myInfo: {},
-				myLocation: {
-					latitude: 39.910925,
-					longitude: 116.413384,
-				},
 				star_address: '',
 				end_address: '',
 				address: {},
@@ -114,22 +112,22 @@
 		 * 生命周期函数--监听页面加载
 		 */
 		onLoad(options) {
-			console.log(uni.getStorageSync('car_info'))
+			
 			this.carInfo = uni.getStorageSync('car_info')
 			this.plate_number = options.plate_number
 			const me = this
 			// common.loading();
-			const storedLocation = uni.getStorageSync('user_current_location');
-			if (storedLocation.longitude && storedLocation.latitude) {
-				// 如果本地有存储的定位信息,则直接使用
-				this.setData({
-					myLocation: storedLocation
-				})
-				// this.loadTrackInfo()
-			} else {
-				this.getLocationAndSave();
-			}
-			// this.init()
+			// const storedLocation = uni.getStorageSync('user_current_location');
+			// if (storedLocation.longitude && storedLocation.latitude) {
+			// 	// 如果本地有存储的定位信息,则直接使用
+			// 	this.setData({
+			// 		myLocation: storedLocation
+			// 	})
+			// 	// this.loadTrackInfo()
+			// } else {
+			// 	this.getLocationAndSave();
+			// }
+			this.init()
 		},
 		/**
 		 * 生命周期函数--监听页面显示
@@ -144,6 +142,7 @@
 				} = await request.postApi(config_gyq.API_CAR_TRACK_INFO, {
 					car_sn: this.carInfo.car_sn,
 				})
+				
 				if (data.code == 200) {
 					this.trackInfo = data.data
 					this.pointsList = data.data.points.map(item => {
@@ -153,7 +152,7 @@
 							lat: item.latitude,
 						}
 					})
-
+					
 					if(this.pointsList.length < 1){
 						common.simpleToast('暂无骑行数据!')
 						setTimeout(function() {
@@ -163,25 +162,17 @@
 						}, 800);
 						return 
 					}
+					
 					//接口返回描绘线段
-					// #ifdef APP
+					
 					this.polylines = {
 						points: this.pointsList,
 						color: "#0BD28E",
 						width: 6
 					}
-					// #endif
-
-					// #ifdef MP-WEIXIN
-					this.polylines = [{
-						points: this.pointsList,
-						color: "#0BD28E",
-						width: 6
-					}]
 					if(this.pointsList.length > 0){
 						this.time = this.pointsList[0].time
 					}
-					// #endif
 					if (this.pointsList.length >= 2) {
 						const len = this.pointsList.length - 1
 						//点收尾标记
@@ -217,8 +208,8 @@
 						this.getAddressName(this.markers[0].latitude, this.markers[0].longitude, 1)
 					}
 
+					this.mapShow = true
 				}
-				console.log(data)
 			},
 			getAddressName(latitude, longitude, type) {
 				const pData = {

+ 6 - 0
utils/gyq_utils.js

@@ -25,6 +25,11 @@ async function location() {
 	}
 }
 
+function htmlData(str){
+	return str.replace(/\<img/gi, '<img style="width:100%;height:auto;display:block" ')
+}
+
+
 function locationAsync() {
 	return new Promise((resolve, reject) => {
 		uni.getLocation({
@@ -124,5 +129,6 @@ export default {
 		vm.prototype.$msg = msg;
 		vm.prototype.$location = location;
 		vm.prototype.$checkLocationPermission = checkLocationPermission;
+		vm.prototype.$htmlData = htmlData;
 	},
 };