From 2c86a8bd60deed0dd0e044bad6fb83f75d19a332 Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期日, 26 十月 2025 15:05:50 +0800
Subject: [PATCH] Merge branch 'feature-task'

---
 app/pages/bind-vehicle.vue |  335 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 335 insertions(+), 0 deletions(-)

diff --git a/app/pages/bind-vehicle.vue b/app/pages/bind-vehicle.vue
new file mode 100644
index 0000000..417e3a4
--- /dev/null
+++ b/app/pages/bind-vehicle.vue
@@ -0,0 +1,335 @@
+<template>
+  <view class="bind-vehicle-container">
+    <view class="header">
+      <text class="title">缁戝畾杞﹁締</text>
+    </view>
+    
+    <!-- 鎵爜缁戝畾 - 宸查殣钘� -->
+    <!-- <view class="scan-section">
+      <view class="section-title">鎵竴鎵粦瀹�</view>
+      <view class="scan-content">
+        <view class="scan-icon" @click="scanQRCode">
+          <uni-icons type="scan" size="40" color="#007AFF"></uni-icons>
+          <text class="scan-text">鐐瑰嚮鎵爜缁戝畾杞﹁締</text>
+        </view>
+      </view>
+    </view> -->
+    
+    <!-- 涓嬫媺閫夋嫨缁戝畾 -->
+    <view class="form-section">
+      <view class="section-title">閫夋嫨杞︾墝鍙风粦瀹�</view>
+      <view class="form-item">
+        <view class="form-label">杞︾墝鍙�</view>
+        <picker mode="selector" :range="vehiclePlates" @change="onVehiclePlateChange">
+          <view class="form-input picker-input">
+            {{ selectedVehiclePlate || '璇烽�夋嫨杞︾墝鍙�' }}
+            <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+          </view>
+        </picker>
+      </view>
+      
+      <view class="form-actions">
+        <button class="submit-btn" @click="bindVehicle" :disabled="!selectedVehiclePlate">纭缁戝畾</button>
+        <button class="cancel-btn" @click="goBack">鍙栨秷</button>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+  import { mapState } from 'vuex'
+  import { listAvailableVehicles, bindVehicleToUser, getUserBoundVehicle } from '@/api/vehicle'
+  
+  export default {
+    data() {
+      return {
+        selectedVehiclePlate: '',
+        selectedVehicleId: null,
+        // 杞﹁締鍒楄〃鏁版嵁
+        vehiclePlates: [],
+        vehicleOptions: [],
+        loading: false,
+        // 褰撳墠缁戝畾鐨勮溅杈嗕俊鎭�
+        currentBoundVehicle: null
+      }
+    },
+    computed: {
+      ...mapState({
+        currentUser: state => state.user
+      })
+    },
+    onLoad() {
+      // 鍔犺浇杞﹁締鍒楄〃
+      this.loadVehicleList()
+      // 鍔犺浇褰撳墠鐢ㄦ埛缁戝畾鐨勮溅杈�
+      this.loadCurrentBoundVehicle()
+    },
+    methods: {
+      // 鍔犺浇褰撳墠鐢ㄦ埛缁戝畾鐨勮溅杈�
+      loadCurrentBoundVehicle() {
+        const userId = this.currentUser.userId
+        getUserBoundVehicle(userId).then(response => {
+          if (response.code === 200 && response.data) {
+            this.currentBoundVehicle = response.data
+            console.log('褰撳墠缁戝畾杞﹁締:', this.currentBoundVehicle)
+          } else {
+            this.currentBoundVehicle = null
+          }
+        }).catch(error => {
+          console.error('鑾峰彇缁戝畾杞﹁締澶辫触:', error)
+          this.currentBoundVehicle = null
+        })
+      },
+      
+      // 鍔犺浇杞﹁締鍒楄〃锛堝彧鍔犺浇鍚屼竴鍒嗗叕鍙哥殑杞﹁締锛�
+      loadVehicleList() {
+        this.loading = true
+        // 鑾峰彇褰撳墠鐢ㄦ埛鐨勯儴闂↖D
+        const deptId = this.currentUser.deptId
+        
+        if (!deptId) {
+          this.loading = false
+          console.error('鏃犳硶鑾峰彇鐢ㄦ埛閮ㄩ棬淇℃伅')
+          this.$modal.showToast('鏃犳硶鑾峰彇鐢ㄦ埛閮ㄩ棬淇℃伅')
+          return
+        }
+        
+        // 浣跨敤鐢ㄦ埛鎵�鍦ㄧ殑閮ㄩ棬ID鍔犺浇杞﹁締鍒楄〃
+        listAvailableVehicles(deptId, 'GENERAL').then(response => {
+          this.loading = false
+          const vehicleList = response.data || response.rows || []
+          
+          if (vehicleList.length === 0) {
+            console.log('褰撳墠鍒嗗叕鍙告殏鏃犲彲鐢ㄨ溅杈�')
+            this.$modal.showToast('褰撳墠鍒嗗叕鍙告殏鏃犲彲鐢ㄨ溅杈�')
+          }
+          
+          this.vehicleOptions = vehicleList.map(vehicle => ({
+            id: vehicle.vehicleId,
+            name: vehicle.vehicleNo,
+            type: vehicle.vehicleType,
+            brand: vehicle.vehicleBrand,
+            model: vehicle.vehicleModel
+          }))
+          this.vehiclePlates = this.vehicleOptions.map(v => v.name)
+          
+          console.log(`鍔犺浇浜� ${vehicleList.length} 杈嗚溅杈嗭紙閮ㄩ棬ID: ${deptId}锛塦)
+        }).catch(error => {
+          this.loading = false
+          console.error('鍔犺浇杞﹁締鍒楄〃澶辫触:', error)
+          this.$modal.showToast('鍔犺浇杞﹁締鍒楄〃澶辫触')
+        })
+      },
+      
+      // 鎵爜缁戝畾杞﹁締
+      scanQRCode() {
+        // #ifdef H5
+        this.$modal.showToast('H5鐜鏆備笉鏀寔鎵爜鍔熻兘')
+        // #endif
+        
+        // #ifndef H5
+        uni.scanCode({
+          success: (res) => {
+            console.log('鎵爜缁撴灉锛�', res)
+            // 瑙f瀽鎵爜缁撴灉锛岃繖閲屽亣璁炬壂鐮佺粨鏋滄槸杞︾墝鍙�
+            this.selectedVehiclePlate = res.result
+            this.$modal.showToast('鎵爜鎴愬姛锛屾鍦ㄧ粦瀹氳溅杈�...')
+            // 鎵爜鎴愬姛鍚庤嚜鍔ㄧ粦瀹�
+            this.bindVehicle()
+          },
+          fail: (err) => {
+            console.log('鎵爜澶辫触锛�', err)
+            this.$modal.showToast('鎵爜澶辫触锛岃閲嶈瘯')
+          }
+        })
+        // #endif
+      },
+      
+      // 杞︾墝鍙烽�夋嫨
+      onVehiclePlateChange(e) {
+        const index = e.detail.value
+        this.selectedVehiclePlate = this.vehiclePlates[index]
+        this.selectedVehicleId = this.vehicleOptions[index]?.id
+      },
+      
+      // 缁戝畾杞﹁締
+      bindVehicle() {
+        if (!this.selectedVehiclePlate || !this.selectedVehicleId) {
+          this.$modal.showToast('璇烽�夋嫨杞︾墝鍙�')
+          return
+        }
+        
+        // 妫�鏌ユ槸鍚﹂�夋嫨鐨勬槸褰撳墠宸茬粦瀹氱殑杞﹁締
+        if (this.currentBoundVehicle && this.currentBoundVehicle.vehicleId === this.selectedVehicleId) {
+          this.$modal.showToast('褰撳墠宸茬粦瀹氭杞﹁締锛屾棤闇�閲嶅缁戝畾')
+          return
+        }
+        
+        // 濡傛灉宸茬粡缁戝畾浜嗗叾浠栬溅杈嗭紝鎻愮ず鏄惁寮哄埗缁戝畾
+        if (this.currentBoundVehicle) {
+          const currentVehicleNo = this.currentBoundVehicle.vehicleNumber || '鏈煡杞︾墝'
+          const confirmMsg = `鎮ㄥ綋鍓嶅凡缁戝畾杞﹁締锛�${currentVehicleNo}\n\n纭瑕佽В缁戞棫杞﹁締骞剁粦瀹氭柊杞﹁締锛�${this.selectedVehiclePlate} 鍚楋紵`
+          
+          this.$modal.confirm(confirmMsg).then(() => {
+            this.performBind()
+          }).catch(() => {
+            // 鐢ㄦ埛鍙栨秷寮哄埗缁戝畾
+            console.log('鐢ㄦ埛鍙栨秷寮哄埗缁戝畾')
+          })
+        } else {
+          // 娌℃湁缁戝畾杞﹁締锛岀洿鎺ョ粦瀹�
+          this.$modal.confirm('纭缁戝畾杞﹁締 ' + this.selectedVehiclePlate + ' 鍚楋紵').then(() => {
+            this.performBind()
+          }).catch(() => {
+            // 鐢ㄦ埛鍙栨秷鎿嶄綔
+          })
+        }
+      },
+      
+      // 鎵ц缁戝畾鎿嶄綔
+      performBind() {
+        this.loading = true
+        const userId = this.currentUser.userId
+        
+        bindVehicleToUser(userId, this.selectedVehicleId).then(response => {
+          this.loading = false
+          
+          if (response.code === 200) {
+            this.$modal.showToast('杞﹁締缁戝畾鎴愬姛')
+            // 鏇存柊Vuex涓殑鐢ㄦ埛淇℃伅
+            this.$store.dispatch('GetInfo')
+            // 杩斿洖涓婁竴椤�
+            setTimeout(() => {
+              this.$tab.navigateBack()
+            }, 1500)
+          } else {
+            this.$modal.showToast(response.msg || '缁戝畾澶辫触')
+          }
+        }).catch(error => {
+          this.loading = false
+          console.error('缁戝畾杞﹁締澶辫触:', error)
+          const errorMsg = error.msg || error.message || '缁戝畾杞﹁締澶辫触锛岃閲嶈瘯'
+          this.$modal.showToast(errorMsg)
+        })
+      },
+      
+      goBack() {
+        this.$tab.navigateBack()
+      }
+    }
+  }
+</script>
+
+<style lang="scss">
+  .bind-vehicle-container {
+    padding: 20rpx;
+    background-color: #f5f5f5;
+    min-height: 100vh;
+  }
+  
+  .header {
+    text-align: center;
+    padding: 40rpx 0;
+    
+    .title {
+      font-size: 40rpx;
+      font-weight: bold;
+      color: #333;
+    }
+  }
+  
+  .section-title {
+    font-size: 32rpx;
+    font-weight: bold;
+    margin: 30rpx 0 20rpx 0;
+    color: #333;
+  }
+  
+  .scan-section {
+    background-color: white;
+    border-radius: 15rpx;
+    padding: 30rpx;
+    margin-bottom: 20rpx;
+    box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+    
+    .scan-content {
+      text-align: center;
+      padding: 40rpx 0;
+      
+      .scan-icon {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        
+        .scan-text {
+          margin-top: 20rpx;
+          font-size: 28rpx;
+          color: #007AFF;
+        }
+      }
+    }
+  }
+  
+  .form-section {
+    background-color: white;
+    border-radius: 15rpx;
+    padding: 30rpx;
+    box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+    
+    .form-item {
+      margin-bottom: 40rpx;
+      
+      &:last-child {
+        margin-bottom: 0;
+      }
+      
+      .form-label {
+        font-size: 28rpx;
+        margin-bottom: 15rpx;
+        color: #333;
+      }
+      
+      .form-input {
+        height: 70rpx;
+        padding: 0 20rpx;
+        border: 1rpx solid #eee;
+        border-radius: 10rpx;
+        font-size: 28rpx;
+        
+        &.picker-input {
+          display: flex;
+          align-items: center;
+          justify-content: space-between;
+        }
+      }
+    }
+    
+    .form-actions {
+      display: flex;
+      margin-top: 50rpx;
+      
+      .submit-btn, .cancel-btn {
+        flex: 1;
+        height: 80rpx;
+        border-radius: 10rpx;
+        font-size: 32rpx;
+        margin: 0 10rpx;
+      }
+      
+      .submit-btn {
+        background-color: #007AFF;
+        color: white;
+        
+        &[disabled] {
+          background-color: #cccccc;
+        }
+      }
+      
+      .cancel-btn {
+        background-color: #f0f0f0;
+        color: #333;
+      }
+    }
+  }
+</style>
\ No newline at end of file

--
Gitblit v1.9.1