From 37de2f4b0f732ca5c19582d4a340ad7c987925b5 Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期三, 05 十一月 2025 22:40:47 +0800
Subject: [PATCH] feat: 部门管理多个车辆

---
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/HospDataController.java     |   38 +
 ruoyi-ui/src/views/system/vehicle/index.vue                                           |   47 +
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java                 |    9 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java      |   93 ++++
 ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml                       |    6 
 ruoyi-ui/src/views/system/user/index.vue                                              |  105 ++++
 app/api/system/dept.js                                                                |    7 
 app/pages/task/create-emergency.vue                                                   |  200 ++++++++-
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/HospDataMapper.java                |   25 +
 ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml                       |   13 
 ruoyi-system/src/main/java/com/ruoyi/system/domain/UserSyncDTO.java                   |   14 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java     |   21 +
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleInfoMapper.java             |   17 
 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java           |   14 
 ruoyi-system/src/main/resources/mapper/system/UserSyncMapper.xml                      |    4 
 ruoyi-ui/src/api/system/dept.js                                                       |   18 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleSyncServiceImpl.java  |  139 ++++--
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserSyncServiceImpl.java     |    8 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java              |   13 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskController.java        |    6 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleInfoServiceImpl.java  |  101 +++++
 ruoyi-system/src/main/resources/mapper/system/HospDataMapper.xml                      |   43 ++
 ruoyi-system/src/main/java/com/ruoyi/system/domain/VehicleDept.java                   |   67 +++
 ruoyi-system/src/main/java/com/ruoyi/system/service/IVehicleInfoService.java          |    9 
 ruoyi-system/src/main/java/com/ruoyi/system/domain/VehicleInfo.java                   |   24 +
 app/api/hospital.js                                                                   |   32 +
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java      |   29 +
 sql/vehicle_dept_relation.sql                                                         |   17 
 ruoyi-system/src/main/resources/mapper/system/VehicleInfoMapper.xml                   |   59 ++
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskVehicleController.java |   21 
 30 files changed, 1,073 insertions(+), 126 deletions(-)

diff --git a/app/api/hospital.js b/app/api/hospital.js
index d962fe7..7823405 100644
--- a/app/api/hospital.js
+++ b/app/api/hospital.js
@@ -29,3 +29,35 @@
     }
   })
 }
+
+/**
+ * 鑾峰彇甯哥敤杞嚭鍖婚櫌鍒楄〃
+ * @param {string} serviceOrdClass 鍒嗗叕鍙哥紪鐮侊紙service_order_class锛�
+ * @param {string} region 鍦板煙鍏抽敭璇嶏紙鍙�夛級
+ */
+export function getFrequentOutHospitals(serviceOrdClass, region) {
+  return request({
+    url: '/system/hospital/frequent/out',
+    method: 'get',
+    params: {
+      serviceOrdClass: serviceOrdClass,
+      region: region
+    }
+  })
+}
+
+/**
+ * 鑾峰彇甯哥敤杞叆鍖婚櫌鍒楄〃
+ * @param {string} serviceOrdClass 鍒嗗叕鍙哥紪鐮侊紙service_order_class锛�
+ * @param {string} region 鍦板煙鍏抽敭璇嶏紙鍙�夛級
+ */
+export function getFrequentInHospitals(serviceOrdClass, region) {
+  return request({
+    url: '/system/hospital/frequent/in',
+    method: 'get',
+    params: {
+      serviceOrdClass: serviceOrdClass,
+      region: region
+    }
+  })
+}
diff --git a/app/api/system/dept.js b/app/api/system/dept.js
index 0c63430..fd4b2b4 100644
--- a/app/api/system/dept.js
+++ b/app/api/system/dept.js
@@ -17,11 +17,8 @@
  */
 export function listBranchCompany() {
   return request({
-    url: '/system/dept/list',
-    method: 'get',
-    params: {
-      parentId: 100
-    }
+    url: '/system/dept/branch/by-oa',
+    method: 'get'
   })
 }
 
diff --git a/app/pages/task/create-emergency.vue b/app/pages/task/create-emergency.vue
index 21fa1c0..99fe82d 100644
--- a/app/pages/task/create-emergency.vue
+++ b/app/pages/task/create-emergency.vue
@@ -18,7 +18,7 @@
         </picker>
       </view>
         <view class="form-item">
-        <view class="form-label">褰掑睘鏈烘瀯</view>
+        <view class="form-label required">褰掑睘鏈烘瀯</view>
         <picker mode="selector" :range="organizations" @change="onOrganizationChange">
           <view class="form-input picker-input">
             {{ selectedOrganization || '璇烽�夋嫨褰掑睘鏈烘瀯' }}
@@ -274,7 +274,7 @@
       </view>
       
       <view class="form-item">
-        <view class="form-label">杞繍鍏噷鏁�</view>
+        <view class="form-label required">杞繍鍏噷鏁�</view>
         <input 
           class="form-input" 
           type="digit" 
@@ -284,7 +284,7 @@
       </view>
       
       <view class="form-item">
-        <view class="form-label">鎴愪氦浠�</view>
+        <view class="form-label required">鎴愪氦浠�</view>
         <input 
           class="form-input" 
           type="digit" 
@@ -444,13 +444,13 @@
 import { addTask } from "@/api/task"
 import { listAvailableVehicles, getUserBoundVehicle } from "@/api/vehicle"
 import { calculateDistance, baiduDistanceByAddress } from "@/api/map"
-import { searchHospitals } from "@/api/hospital"
+import { searchHospitals, getFrequentOutHospitals, getFrequentInHospitals } from "@/api/hospital"
 import { listUser } from "@/api/system/user"
 import { searchIcd10 } from "@/api/icd10"
 
 import { getDicts } from "@/api/dict"
 import { getServiceOrdAreaTypes, getServiceOrderTypes, getHospitalDepartments } from "@/api/dictionary"
-import { listBranchCompany } from "@/api/system/dept"
+import { listBranchCompany, getDept } from "@/api/system/dept"
 import MapSelector from '@/components/map-selector.vue'
 
 export default {
@@ -465,6 +465,7 @@
       selectedVehicleId: null,
       selectedOrganization: '',
       selectedOrganizationId: null, // 褰掑睘鏈烘瀯ID锛堥儴闂↖D锛�
+      selectedOrganizationServiceOrderClass: '', // 褰掑睘鏈烘瀯鐨勬湇鍔″崟缂栫爜
       selectedRegion: '', // 浠庡綊灞炴満鏋勪腑鎻愬彇鐨勫湴鍩熶俊鎭紙濡傦細骞垮窞銆佹繁鍦崇瓑锛�
       selectedEmergencyTaskType: '', // 閫変腑鐨勪换鍔$被鍨嬫枃鏈�
       selectedEmergencyTaskTypeId: null, // 閫変腑鐨勪换鍔$被鍨婭D
@@ -618,17 +619,26 @@
     },
     
     getAvailableVehicles() {
-      const deptId = this.currentUser.deptId
-      return listAvailableVehicles(deptId, 'EMERGENCY').then(response => {
-        const vehicleList = response.data || response.rows || []
+      // 鏍规嵁鐢ㄦ埛鏈夋潈闄愮鐞嗙殑鍒嗗叕鍙革紝鏌ヨ鎵�鏈夊彲鐢ㄨ溅杈�
+      listAvailableVehicles(null, 'EMERGENCY').then(response => {
+        const vehicleList = response.data || []
         this.vehicleOptions = vehicleList.map(vehicle => ({
           id: vehicle.vehicleId,
           name: vehicle.vehicleNo,
           type: vehicle.vehicleType,
-          status: vehicle.status
+          status: vehicle.status,
+          deptNames: vehicle.deptNames || [] // 杞﹁締褰掑睘鐨勫涓垎鍏徃
         }))
-        this.vehicles = this.vehicleOptions.map(v => v.name)
-      }).catch(() => {
+        this.vehicles = this.vehicleOptions.map(v => {
+          // 濡傛灉杞﹁締褰掑睘澶氫釜鍒嗗叕鍙革紝鍦ㄨ溅鐗屽彿鍚庨潰鏄剧ず
+          if (v.deptNames && v.deptNames.length > 0) {
+            return `${v.name} (${v.deptNames.join('銆�')})`
+          }
+          return v.name
+        })
+        console.log('鍔犺浇鍙敤杞﹁締鏁伴噺:', this.vehicles.length)
+      }).catch(error => {
+        console.error('鍔犺浇杞﹁締鍒楄〃澶辫触:', error)
         this.vehicles = []
       })
     },
@@ -644,8 +654,9 @@
       const selected = this.organizationOptions[index]
       this.selectedOrganization = selected.deptName
       this.selectedOrganizationId = selected.deptId // 淇濆瓨閮ㄩ棬ID
-      // 浠庡綊灞炴満鏋勪腑鎻愬彇鍦板煙鍏抽敭璇嶏紙鍘婚櫎"鍒嗗叕鍙�"鍚庣紑锛�
-      // 渚嬪锛�"骞垮窞鍒嗗叕鍙�" -> "骞垮窞"
+      this.selectedOrganizationServiceOrderClass = selected.serviceOrderClass || '' // 淇濆瓨鏈嶅姟鍗曠紪鐮�
+      // 浠庡綊灞炴満鏋勪腑鎻愬彇鍦板煙鍏抽敭璇嶏紙鍘婚櫎鈥滃垎鍏徃鈥濆悗缂�锛�
+      // 渚嬪锛氣�滃箍宸炲垎鍏徃鈥� -> 鈥滃箍宸炩��
       this.selectedRegion = selected.deptName.replace(/鍒嗗叕鍙�$/g, '').trim()
       // 閲嶆柊鍔犺浇鍖婚櫌鍒楄〃锛堝甫鍦板煙杩囨护锛�
       this.loadDefaultHospitals()
@@ -668,9 +679,10 @@
           if (index !== -1) {
             this.selectedOrganization = this.currentUser.branchCompanyName
             this.selectedOrganizationId = this.organizationOptions[index].deptId // 淇濆瓨閮ㄩ棬ID
+            this.selectedOrganizationServiceOrderClass = this.organizationOptions[index].serviceOrderClass || '' // 淇濆瓨鏈嶅姟鍗曠紪鐮�
             // 鎻愬彇鍦板煙鍏抽敭璇�
             this.selectedRegion = this.selectedOrganization.replace(/鍒嗗叕鍙�$/g, '').trim()
-            console.log('榛樿閫変腑褰掑睘鏈烘瀯:', this.selectedOrganization, '閮ㄩ棬ID:', this.selectedOrganizationId, '鍦板煙:', this.selectedRegion)
+            console.log('榛樿閫変腑褰掑睘鏈烘瀯:', this.selectedOrganization, '閮ㄩ棬ID:', this.selectedOrganizationId, '鏈嶅姟鍗曠紪鐮�:', this.selectedOrganizationServiceOrderClass, '鍦板煙:', this.selectedRegion)
             // 鍔犺浇鍖婚櫌鍒楄〃锛堝甫鍦板煙杩囨护锛�
             this.loadDefaultHospitals()
           }
@@ -788,8 +800,63 @@
       this.taskForm.hospitalIn.departmentId = selected.id  // 淇濆瓨绉戝ID
     },
     
-    // 鍔犺浇榛樿鍖婚櫌鍒楄〃锛堝墠100鏉★級
+    // 鍔犺浇榛樿鍖婚櫌鍒楄〃锛堝父鐢ㄥ尰闄級
     loadDefaultHospitals() {
+      // 妫�鏌ユ槸鍚︽湁鏈嶅姟鍗曠紪鐮�
+      if (!this.selectedOrganizationServiceOrderClass) {
+        console.warn('鏈壘鍒版湇鍔″崟缂栫爜锛屾棤娉曞姞杞藉父鐢ㄥ尰闄�')
+        // 濡傛灉娌℃湁鏈嶅姟鍗曠紪鐮侊紝闄嶇骇涓烘櫘閫氭悳绱紙鎸夊湴鍩熻繃婊わ級
+        this.loadDefaultHospitalsByRegion()
+        return
+      }
+      
+      // 杞嚭鍖婚櫌锛氬姞杞藉綋鍓嶅垎鍏徃鐨勫父鐢ㄨ浆鍑哄尰闄�
+      getFrequentOutHospitals(this.selectedOrganizationServiceOrderClass, this.selectedRegion).then(response => {
+        this.hospitalOutResults = response.data || []
+        console.log('鍔犺浇甯哥敤杞嚭鍖婚櫌锛�', this.selectedOrganizationServiceOrderClass, '鍦板煙:', this.selectedRegion, '鏁伴噺:', this.hospitalOutResults.length)
+        
+        // 濡傛灉娌℃湁甯哥敤鍖婚櫌锛岄檷绾т负鏅�氭悳绱�
+        if (this.hospitalOutResults.length === 0) {
+          console.log('鏈壘鍒板父鐢ㄨ浆鍑哄尰闄紝闄嶇骇涓哄湴鍩熸悳绱�')
+          searchHospitals('', this.selectedRegion).then(res => {
+            this.hospitalOutResults = res.data || []
+          })
+        }
+      }).catch(error => {
+        console.error('鍔犺浇甯哥敤杞嚭鍖婚櫌澶辫触:', error)
+        // 澶辫触鍚庨檷绾т负鏅�氭悳绱�
+        searchHospitals('', this.selectedRegion).then(res => {
+          this.hospitalOutResults = res.data || []
+        })
+      })
+      
+      // 杞叆鍖婚櫌锛氬姞杞藉綋鍓嶅垎鍏徃鐨勫父鐢ㄨ浆鍏ュ尰闄紙鏈湴鍖哄煙浼樺厛锛�
+      getFrequentInHospitals(this.selectedOrganizationServiceOrderClass, '').then(response => {
+        const allHospitals = response.data || []
+        // 灏嗗尰闄㈡寜鍦板煙鎺掑簭锛氭湰鍦板尯鍩熶紭鍏�
+        this.hospitalInResults = this.sortHospitalsByRegion(allHospitals)
+        console.log('鍔犺浇甯哥敤杞叆鍖婚櫌锛�', this.selectedOrganizationServiceOrderClass, '鏁伴噺:', this.hospitalInResults.length)
+        
+        // 濡傛灉娌℃湁甯哥敤鍖婚櫌锛岄檷绾т负鏅�氭悳绱�
+        if (this.hospitalInResults.length === 0) {
+          console.log('鏈壘鍒板父鐢ㄨ浆鍏ュ尰闄紝闄嶇骇涓哄叏閮ㄥ尰闄�')
+          searchHospitals('', '').then(res => {
+            const allHospitals = res.data || []
+            this.hospitalInResults = this.sortHospitalsByRegion(allHospitals)
+          })
+        }
+      }).catch(error => {
+        console.error('鍔犺浇甯哥敤杞叆鍖婚櫌澶辫触:', error)
+        // 澶辫触鍚庨檷绾т负鏅�氭悳绱�
+        searchHospitals('', '').then(res => {
+          const allHospitals = res.data || []
+          this.hospitalInResults = this.sortHospitalsByRegion(allHospitals)
+        })
+      })
+    },
+    
+    // 闄嶇骇鍔犺浇鍖婚櫌锛堟寜鍦板煙杩囨护锛�
+    loadDefaultHospitalsByRegion() {
       // 杞嚭鍖婚櫌锛氬彧鍔犺浇褰撳墠鍖哄煙鐨勫尰闄紙甯﹀湴鍩熻繃婊わ級
       searchHospitals('', this.selectedRegion).then(response => {
         this.hospitalOutResults = response.data || []
@@ -800,7 +867,7 @@
       })
       
       // 杞叆鍖婚櫌锛氬姞杞芥墍鏈夊尰闄紙涓嶅甫鍦板煙杩囨护锛屽悗缁細鎸夊湴鍩熸帓搴忥級
-      searchHospitals('', this.selectedRegion).then(response => {
+      searchHospitals('', '').then(response => {
         const allHospitals = response.data || []
         // 灏嗗尰闄㈡寜鍦板煙鎺掑簭锛氭湰鍦板尯鍩熶紭鍏�
         this.hospitalInResults = this.sortHospitalsByRegion(allHospitals)
@@ -841,14 +908,39 @@
     
     // 杞嚭鍖婚櫌杈撳叆妗嗚幏寰楃劍鐐�
     onHospitalOutFocus() {
-      // 濡傛灉娌℃湁鎼滅储鍏抽敭璇嶏紝鍙樉绀哄綋鍓嶅尯鍩熺殑鍖婚櫌
+      // 濡傛灉娌℃湁鎼滅储鍏抽敭璇嶏紝鏄剧ず甯哥敤杞嚭鍖婚櫌
       if (!this.hospitalOutSearchKeyword || this.hospitalOutSearchKeyword.trim() === '') {
-        searchHospitals('', this.selectedRegion).then(response => {
-          this.hospitalOutResults = response.data || []
-        }).catch(error => {
-          console.error('鍔犺浇杞嚭鍖婚櫌澶辫触:', error)
-          this.hospitalOutResults = []
-        })
+        // 濡傛灉宸茬粡鍔犺浇杩囧父鐢ㄥ尰闄紝鐩存帴鏄剧ず
+        if (this.hospitalOutResults.length > 0) {
+          this.showHospitalOutResults = true
+          return
+        }
+        
+        // 鍚﹀垯閲嶆柊鍔犺浇甯哥敤鍖婚櫌
+        if (this.selectedOrganizationServiceOrderClass) {
+          getFrequentOutHospitals(this.selectedOrganizationServiceOrderClass, this.selectedRegion).then(response => {
+            this.hospitalOutResults = response.data || []
+            // 濡傛灉娌℃湁甯哥敤鍖婚櫌锛岄檷绾т负鏅�氭悳绱�
+            if (this.hospitalOutResults.length === 0) {
+              searchHospitals('', this.selectedRegion).then(res => {
+                this.hospitalOutResults = res.data || []
+              })
+            }
+          }).catch(error => {
+            console.error('鍔犺浇甯哥敤杞嚭鍖婚櫌澶辫触:', error)
+            searchHospitals('', this.selectedRegion).then(res => {
+              this.hospitalOutResults = res.data || []
+            })
+          })
+        } else {
+          // 娌℃湁鏈嶅姟鍗曠紪鐮侊紝浣跨敤鏅�氭悳绱�
+          searchHospitals('', this.selectedRegion).then(response => {
+            this.hospitalOutResults = response.data || []
+          }).catch(error => {
+            console.error('鍔犺浇杞嚭鍖婚櫌澶辫触:', error)
+            this.hospitalOutResults = []
+          })
+        }
       }
       this.showHospitalOutResults = true
     },
@@ -916,16 +1008,45 @@
     
     // 杞叆鍖婚櫌杈撳叆妗嗚幏寰楃劍鐐�
     onHospitalInFocus() {
-      // 濡傛灉娌℃湁鎼滅储鍏抽敭璇嶏紝鏄剧ず鎵�鏈夊尰闄紙鏈湴鍖哄煙浼樺厛锛�
+      // 濡傛灉娌℃湁鎼滅储鍏抽敭璇嶏紝鏄剧ず甯哥敤杞叆鍖婚櫌
       if (!this.hospitalInSearchKeyword || this.hospitalInSearchKeyword.trim() === '') {
-        searchHospitals('', '').then(response => {
-          const allHospitals = response.data || []
-          // 鎸夊湴鍩熸帓搴忥細鏈湴鍖哄煙浼樺厛
-          this.hospitalInResults = this.sortHospitalsByRegion(allHospitals)
-        }).catch(error => {
-          console.error('鍔犺浇杞叆鍖婚櫌澶辫触:', error)
-          this.hospitalInResults = []
-        })
+        // 濡傛灉宸茬粡鍔犺浇杩囧父鐢ㄥ尰闄紝鐩存帴鏄剧ず
+        if (this.hospitalInResults.length > 0) {
+          this.showHospitalInResults = true
+          return
+        }
+        
+        // 鍚﹀垯閲嶆柊鍔犺浇甯哥敤鍖婚櫌
+        if (this.selectedOrganizationServiceOrderClass) {
+          getFrequentInHospitals(this.selectedOrganizationServiceOrderClass, '').then(response => {
+            const allHospitals = response.data || []
+            // 鎸夊湴鍩熸帓搴忥細鏈湴鍖哄煙浼樺厛
+            this.hospitalInResults = this.sortHospitalsByRegion(allHospitals)
+            // 濡傛灉娌℃湁甯哥敤鍖婚櫌锛岄檷绾т负鏅�氭悳绱�
+            if (this.hospitalInResults.length === 0) {
+              searchHospitals('', '').then(res => {
+                const allHospitals = res.data || []
+                this.hospitalInResults = this.sortHospitalsByRegion(allHospitals)
+              })
+            }
+          }).catch(error => {
+            console.error('鍔犺浇甯哥敤杞叆鍖婚櫌澶辫触:', error)
+            searchHospitals('', '').then(res => {
+              const allHospitals = res.data || []
+              this.hospitalInResults = this.sortHospitalsByRegion(allHospitals)
+            })
+          })
+        } else {
+          // 娌℃湁鏈嶅姟鍗曠紪鐮侊紝浣跨敤鏅�氭悳绱�
+          searchHospitals('', '').then(response => {
+            const allHospitals = response.data || []
+            // 鎸夊湴鍩熸帓搴忥細鏈湴鍖哄煙浼樺厛
+            this.hospitalInResults = this.sortHospitalsByRegion(allHospitals)
+          }).catch(error => {
+            console.error('鍔犺浇杞叆鍖婚櫌澶辫触:', error)
+            this.hospitalInResults = []
+          })
+        }
       }
       this.showHospitalInResults = true
     },
@@ -1290,6 +1411,11 @@
         return false
       }
       
+      if (!this.selectedOrganizationId) {
+        this.$modal.showToast('璇烽�夋嫨褰掑睘鏈烘瀯')
+        return false
+      }
+      
       if (!this.selectedEmergencyTaskType) {
         this.$modal.showToast('璇烽�夋嫨浠诲姟绫诲瀷')
         return false
@@ -1340,6 +1466,16 @@
         return false
       }
       
+      if (!this.taskForm.transferDistance) {
+        this.$modal.showToast('璇疯緭鍏ヨ浆杩愬叕閲屾暟')
+        return false
+      }
+      
+      if (!this.taskForm.price) {
+        this.$modal.showToast('璇疯緭鍏ユ垚浜や环')
+        return false
+      }
+      
       return true
     },
     
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/HospDataController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/HospDataController.java
index e498a51..80a6869 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/HospDataController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/HospDataController.java
@@ -47,4 +47,42 @@
         HospData hospital = hospDataMapper.selectHospDataById(hospId);
         return success(hospital);
     }
+    
+    /**
+     * 鑾峰彇甯哥敤杞嚭鍖婚櫌鍒楄〃
+     * @param serviceOrdClass 鍒嗗叕鍙哥紪鐮侊紙service_order_class锛�
+     * @param region 鍦板煙鍏抽敭璇嶏紙鍙�夛級
+     */
+    @GetMapping("/frequent/out")
+    public AjaxResult getFrequentOutHospitals(
+            @RequestParam("serviceOrdClass") String serviceOrdClass,
+            @RequestParam(value = "region", required = false) String region) {
+        // 鏌ヨ甯哥敤杞嚭鍖婚櫌ID鍒楄〃
+        List<Integer> hospIds = hospDataMapper.selectFrequentOutHospitalIds(serviceOrdClass);
+        if (hospIds == null || hospIds.isEmpty()) {
+            return success();
+        }
+        // 鏍规嵁ID鍒楄〃鏌ヨ鍖婚櫌璇︽儏
+        List<HospData> hospitals = hospDataMapper.selectHospDataByIds(hospIds, region);
+        return success(hospitals);
+    }
+    
+    /**
+     * 鑾峰彇甯哥敤杞叆鍖婚櫌鍒楄〃
+     * @param serviceOrdClass 鍒嗗叕鍙哥紪鐮侊紙service_order_class锛�
+     * @param region 鍦板煙鍏抽敭璇嶏紙鍙�夛級
+     */
+    @GetMapping("/frequent/in")
+    public AjaxResult getFrequentInHospitals(
+            @RequestParam("serviceOrdClass") String serviceOrdClass,
+            @RequestParam(value = "region", required = false) String region) {
+        // 鏌ヨ甯哥敤杞叆鍖婚櫌ID鍒楄〃
+        List<Integer> hospIds = hospDataMapper.selectFrequentInHospitalIds(serviceOrdClass);
+        if (hospIds == null || hospIds.isEmpty()) {
+            return success();
+        }
+        // 鏍规嵁ID鍒楄〃鏌ヨ鍖婚櫌璇︽儏
+        List<HospData> hospitals = hospDataMapper.selectHospDataByIds(hospIds, region);
+        return success(hospitals);
+    }
 }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java
index 86ad7a6..eef87e6 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java
@@ -1,6 +1,8 @@
 package com.ruoyi.web.controller.system;
 
 import java.util.List;
+
+import com.ruoyi.common.core.domain.entity.SysUser;
 import org.apache.commons.lang3.ArrayUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -21,6 +23,7 @@
 import com.ruoyi.common.enums.BusinessType;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.system.service.ISysDeptService;
+import com.ruoyi.system.service.ISysUserService;
 
 /**
  * 閮ㄩ棬淇℃伅
@@ -34,6 +37,9 @@
     @Autowired
     private ISysDeptService deptService;
 
+    @Autowired
+    private ISysUserService userService;
+
     /**
      * 鑾峰彇閮ㄩ棬鍒楄〃
      */
@@ -45,6 +51,29 @@
     }
 
     /**
+     * 鍩轰簬褰撳墠鐢ㄦ埛鐨� OA_OrderClass 杩斿洖鍒嗗叕鍙稿垪琛�
+     */
+    @GetMapping("/branch/by-oa")
+    public AjaxResult listBranchByOaOrderClass()
+    {
+        com.ruoyi.common.core.domain.model.LoginUser loginUser = com.ruoyi.common.utils.SecurityUtils.getLoginUser();
+        com.ruoyi.common.core.domain.entity.SysUser user = loginUser.getUser();
+        java.util.List<com.ruoyi.common.core.domain.entity.SysDept> result = deptService.computeBranchCompaniesForUser(user);
+        return success(result);
+    }
+
+    /**
+     * 鍩轰簬鎸囧畾鐢ㄦ埛ID鐨� OA_OrderClass 杩斿洖鍒嗗叕鍙稿垪琛紝骞堕檮鍔犺鐢ㄦ埛鎵�灞炲垎鍏徃
+     */
+    @GetMapping("/branch/by-user/{userId}")
+    public AjaxResult listBranchByUser(@PathVariable("userId") Long userId)
+    {
+        SysUser user = userService.selectUserById(userId);
+        List<SysDept> result = deptService.computeBranchCompaniesForUser(user);
+        return success(result);
+    }
+
+    /**
      * 鏌ヨ閮ㄩ棬鍒楄〃锛堟帓闄よ妭鐐癸級
      */
     @GetMapping("/list/exclude/{deptId}")
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
index 629f442..f989b8b 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
@@ -71,6 +71,26 @@
     {
         LoginUser loginUser = SecurityUtils.getLoginUser();
         SysUser user = loginUser.getUser();
+        // 璁$畻鍙鐞嗗垎鍏徃鍒楄〃锛堝熀浜� OA_OrderClass 涓� sys_dept.service/dispatch_order_class锛�
+        java.util.List<SysDept> branchCompanies = new java.util.ArrayList<>();
+        java.util.Set<Long> seen = new java.util.HashSet<>();
+        if (com.ruoyi.common.utils.StringUtils.isNotEmpty(user.getOaOrderClass())) {
+            String[] codes = user.getOaOrderClass().split(",");
+            for (String raw : codes) {
+                String code = raw.trim();
+                if (code.isEmpty()) continue;
+                SysDept cond1 = new SysDept();
+                cond1.setParentId(100L);
+                cond1.setServiceOrderClass(code);
+                java.util.List<SysDept> list1 = deptService.selectDeptList(cond1);
+                for (SysDept d : list1) { if (seen.add(d.getDeptId())) branchCompanies.add(d); }
+                SysDept cond2 = new SysDept();
+                cond2.setParentId(100L);
+                cond2.setDispatchOrderClass(code);
+                java.util.List<SysDept> list2 = deptService.selectDeptList(cond2);
+                for (SysDept d : list2) { if (seen.add(d.getDeptId())) branchCompanies.add(d); }
+            }
+        }
         // 瑙掕壊闆嗗悎
         Set<String> roles = permissionService.getRolePermission(user);
         // 鏉冮檺闆嗗悎
@@ -132,6 +152,7 @@
         ajax.put("permissions", permissions);
         ajax.put("branchCompanyId", branchCompanyId);
         ajax.put("branchCompanyName", branchCompanyName);
+        ajax.put("branchCompanies", branchCompanies);
         ajax.put("oaUserId", user.getOaUserId());
         return ajax;
     }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskController.java
index b4bc326..e9b439b 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskController.java
@@ -11,6 +11,7 @@
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 import com.ruoyi.common.annotation.Log;
 import com.ruoyi.common.core.controller.BaseController;
@@ -18,12 +19,14 @@
 import com.ruoyi.common.enums.BusinessType;
 import com.ruoyi.system.domain.SysTask;
 import com.ruoyi.system.domain.SysTaskLog;
+import com.ruoyi.system.domain.VehicleInfo;
 import com.ruoyi.system.domain.vo.TaskQueryVO;
 import com.ruoyi.system.domain.vo.TaskCreateVO;
 import com.ruoyi.system.domain.vo.TaskUpdateVO;
 import com.ruoyi.system.domain.vo.TaskStatisticsVO;
 import com.ruoyi.system.domain.enums.TaskStatus;
 import com.ruoyi.system.service.ISysTaskService;
+import com.ruoyi.system.service.IVehicleInfoService;
 import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.common.core.page.TableDataInfo;
 
@@ -39,6 +42,9 @@
     
     @Autowired
     private ISysTaskService sysTaskService;
+    
+    @Autowired
+    private IVehicleInfoService vehicleInfoService;
 
     /**
      * 鏌ヨ浠诲姟绠$悊鍒楄〃锛堝悗鍙扮鐞嗙锛�
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskVehicleController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskVehicleController.java
index 120be7a..6560bd5 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskVehicleController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskVehicleController.java
@@ -16,7 +16,9 @@
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.enums.BusinessType;
 import com.ruoyi.system.domain.SysTaskVehicle;
+import com.ruoyi.system.domain.VehicleInfo;
 import com.ruoyi.system.service.ISysTaskService;
+import com.ruoyi.system.service.IVehicleInfoService;
 
 /**
  * 浠诲姟杞﹁締鍏宠仈Controller
@@ -30,6 +32,9 @@
     
     @Autowired
     private ISysTaskService sysTaskService;
+    
+    @Autowired
+    private IVehicleInfoService vehicleInfoService;
 
     /**
      * 鏌ヨ浠诲姟鍏宠仈鐨勮溅杈嗗垪琛�
@@ -41,12 +46,20 @@
     }
 
     /**
-     * 鏌ヨ鍙敤杞﹁締鍒楄〃
+     * 鏌ヨ鍙敤杞﹁締鍒楄〃锛堟牴鎹敤鎴锋潈闄愶級
+     * 鏍规嵁鐢ㄦ埛鎵�鍦ㄧ殑鍒嗗叕鍙革紝閫氳繃杞﹁締-鍒嗗叕鍙稿叧鑱旇〃鏌ヨ鎵�鏈夊彲鐢ㄨ溅杈�
+     * 
+     * @param deptId 閮ㄩ棬ID锛堝彲閫夛紝濡傛灉涓嶄紶鍒欎娇鐢ㄥ綋鍓嶇敤鎴风殑deptId锛�
+     * @param taskType 浠诲姟绫诲瀷锛堝彲閫夛級
+     * @return 杞﹁締鍒楄〃
      */
     @GetMapping("/available")
-    public AjaxResult getAvailableVehicles(@RequestParam Long deptId, @RequestParam(required = false) String taskType) {
-        List<SysTaskVehicle> list = sysTaskService.getAvailableVehicles(deptId, taskType);
-        return success(list);
+    public AjaxResult getAvailableVehicles(
+            @RequestParam(required = false) Long deptId, 
+            @RequestParam(required = false) String taskType) {
+        // 濡傛灉娌℃湁浼燿eptId锛屼娇鐢ㄥ綋鍓嶇敤鎴风殑userId鏌ヨ
+        List<VehicleInfo> vehicles = vehicleInfoService.selectAvailableVehiclesByUser(getUserId());
+        return success(vehicles);
     }
 
     /**
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java
index 8cf153e..a8e12cd 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java
@@ -92,6 +92,9 @@
     /** SQL Server涓殑OA鐢ㄦ埛ID */
     private Integer oaUserId;
 
+    /** OA绯荤粺鐨勮鍗曠紪鐮佸垪琛紙濡傦細BF,AB,SA锛� */
+    private String oaOrderClass;
+
     public SysUser()
     {
 
@@ -310,6 +313,16 @@
         this.oaUserId = oaUserId;
     }
 
+    public String getOaOrderClass()
+    {
+        return oaOrderClass;
+    }
+
+    public void setOaOrderClass(String oaOrderClass)
+    {
+        this.oaOrderClass = oaOrderClass;
+    }
+
     @Override
     public String toString() {
         return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
@@ -333,6 +346,7 @@
             .append("remark", getRemark())
             .append("dept", getDept())
             .append("oaUserId", getOaUserId())
+            .append("oaOrderClass", getOaOrderClass())
             .toString();
     }
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/UserSyncDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/UserSyncDTO.java
index 49345c1..79db005 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/UserSyncDTO.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/UserSyncDTO.java
@@ -20,6 +20,9 @@
     /** SQL Server涓殑閮ㄩ棬ID */
     private Integer departmentId;
 
+    /** 鐢ㄦ埛鍙敤鍒嗗叕鍙哥紪鐮佸垪琛紙鏉ユ簮浜嶰A_User.OA_OrderClass锛� */
+    private String oaOrderClass;
+
     /** 鐢ㄦ埛鎬у埆锛�0=鐢�,1=濂�,2=鏈煡锛� */
     private String sex;
 
@@ -99,6 +102,16 @@
         this.phonenumber = phonenumber;
     }
 
+    public String getOaOrderClass()
+    {
+        return oaOrderClass;
+    }
+
+    public void setOaOrderClass(String oaOrderClass)
+    {
+        this.oaOrderClass = oaOrderClass;
+    }
+
     @Override
     public String toString()
     {
@@ -110,6 +123,7 @@
                 ", sex='" + sex + '\'' +
                 ", email='" + email + '\'' +
                 ", phonenumber='" + phonenumber + '\'' +
+                ", oaOrderClass='" + oaOrderClass + '\'' +
                 '}';
     }
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/VehicleDept.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/VehicleDept.java
new file mode 100644
index 0000000..abcc73b
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/VehicleDept.java
@@ -0,0 +1,67 @@
+package com.ruoyi.system.domain;
+
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 杞﹁締-鍒嗗叕鍙稿叧鑱斿璞� tb_vehicle_dept
+ * 
+ * @author ruoyi
+ * @date 2025-01-16
+ */
+public class VehicleDept extends BaseEntity {
+    private static final long serialVersionUID = 1L;
+
+    /** 鍏宠仈ID */
+    private Long id;
+
+    /** 杞﹁締ID */
+    private Long vehicleId;
+
+    /** 鍒嗗叕鍙窱D */
+    private Long deptId;
+
+    /** 瀵瑰簲鐨勫垎鍏徃缂栫爜 */
+    private String orderClass;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getVehicleId() {
+        return vehicleId;
+    }
+
+    public void setVehicleId(Long vehicleId) {
+        this.vehicleId = vehicleId;
+    }
+
+    public Long getDeptId() {
+        return deptId;
+    }
+
+    public void setDeptId(Long deptId) {
+        this.deptId = deptId;
+    }
+
+    public String getOrderClass() {
+        return orderClass;
+    }
+
+    public void setOrderClass(String orderClass) {
+        this.orderClass = orderClass;
+    }
+
+    @Override
+    public String toString() {
+        return "VehicleDept{" +
+                "id=" + id +
+                ", vehicleId=" + vehicleId +
+                ", deptId=" + deptId +
+                ", orderClass='" + orderClass + '\'' +
+                '}';
+    }
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/VehicleInfo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/VehicleInfo.java
index 506de81..5871080 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/VehicleInfo.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/VehicleInfo.java
@@ -5,6 +5,8 @@
 import com.ruoyi.common.annotation.Excel;
 import com.ruoyi.common.core.domain.BaseEntity;
 
+import java.util.List;
+
 /**
  * 杞﹁締淇℃伅瀵硅薄 tb_vehicle_info
  */
@@ -53,6 +55,12 @@
     /** 褰掑睘閮ㄩ棬鍚嶇О */
     @Excel(name = "褰掑睘閮ㄩ棬")
     private String deptName;
+    
+    /** 褰掑睘鐨勫涓垎鍏徃ID鍒楄〃锛堢敤浜庢煡璇㈠拰鏄剧ず锛� */
+    private List<Long> deptIds;
+    
+    /** 褰掑睘鐨勫涓垎鍏徃鍚嶇О鍒楄〃锛堢敤浜庢樉绀猴級 */
+    private List<String> deptNames;
 
     public void setVehicleId(Long vehicleId) {
         this.vehicleId = vehicleId;
@@ -141,6 +149,22 @@
     public void setDeptName(String deptName) {
         this.deptName = deptName;
     }
+    
+    public List<Long> getDeptIds() {
+        return deptIds;
+    }
+    
+    public void setDeptIds(List<Long> deptIds) {
+        this.deptIds = deptIds;
+    }
+    
+    public List<String> getDeptNames() {
+        return deptNames;
+    }
+    
+    public void setDeptNames(List<String> deptNames) {
+        this.deptNames = deptNames;
+    }
 
     @Override
     public String toString() {
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/HospDataMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/HospDataMapper.java
index 1dcbfb2..192a29d 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/HospDataMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/HospDataMapper.java
@@ -32,4 +32,29 @@
      * @return 鍖婚櫌淇℃伅
      */
     HospData selectHospDataById(@Param("hospId") Integer hospId);
+    
+    /**
+     * 鏌ヨ甯哥敤杞嚭鍖婚櫌ID鍒楄〃
+     * 
+     * @param serviceOrdClass 鍒嗗叕鍙哥紪鐮侊紙service_order_class锛�
+     * @return 甯哥敤杞嚭鍖婚櫌ID鍒楄〃
+     */
+    List<Integer> selectFrequentOutHospitalIds(@Param("serviceOrdClass") String serviceOrdClass);
+    
+    /**
+     * 鏌ヨ甯哥敤杞叆鍖婚櫌ID鍒楄〃
+     * 
+     * @param serviceOrdClass 鍒嗗叕鍙哥紪鐮侊紙service_order_class锛�
+     * @return 甯哥敤杞叆鍖婚櫌ID鍒楄〃
+     */
+    List<Integer> selectFrequentInHospitalIds(@Param("serviceOrdClass") String serviceOrdClass);
+    
+    /**
+     * 鏍规嵁鍖婚櫌ID鍒楄〃鏌ヨ鍖婚櫌淇℃伅
+     * 
+     * @param hospIds 鍖婚櫌ID鍒楄〃
+     * @param region 鍦板煙鍏抽敭璇嶏紙鍙�夛級
+     * @return 鍖婚櫌鍒楄〃
+     */
+    List<HospData> selectHospDataByIds(@Param("hospIds") List<Integer> hospIds, @Param("region") String region);
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java
index ada4327..df69912 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java
@@ -141,4 +141,13 @@
      * @return 鍒嗗叕鍙窱D锛屽鏋滄壘涓嶅埌鍒欒繑鍥瀗ull
      */
     public Long selectBranchCompanyIdByDeptId(@Param("deptId") Long deptId);
+    
+    /**
+     * 鏍规嵁缂栫爜鍒楄〃鏌ヨ鍒嗗叕鍙�
+     * 鍦╯ervice_order_class鎴杁ispatch_order_class涓尮閰�
+     * 
+     * @param orderCodes 缂栫爜鍒楄〃
+     * @return 鍒嗗叕鍙稿垪琛�
+     */
+    public List<SysDept> selectBranchCompaniesByOrderCodes(@Param("orderCodes") List<String> orderCodes);
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleInfoMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleInfoMapper.java
index a08022f..1a5f016 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleInfoMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleInfoMapper.java
@@ -3,6 +3,7 @@
 import java.util.List;
 import org.apache.ibatis.annotations.Param;
 import com.ruoyi.system.domain.VehicleInfo;
+import com.ruoyi.system.domain.VehicleDept;
 
 /**
  * 杞﹁締淇℃伅Mapper鎺ュ彛
@@ -106,4 +107,20 @@
      * @return 杞﹁締淇℃伅
      */
     public VehicleInfo getUserBoundVehicle(@Param("userId") Long userId);
+    
+    /**
+     * 鎵归噺鎻掑叆杞﹁締-鍒嗗叕鍙稿叧鑱�
+     * 
+     * @param list 杞﹁締-鍒嗗叕鍙稿叧鑱斿垪琛�
+     * @return 缁撴灉
+     */
+    public int batchInsertVehicleDept(@Param("list") List<VehicleDept> list);
+    
+    /**
+     * 鍒犻櫎杞﹁締鐨勬墍鏈夊垎鍏徃鍏宠仈
+     * 
+     * @param vehicleId 杞﹁締ID
+     * @return 缁撴灉
+     */
+    public int deleteVehicleDeptByVehicleId(@Param("vehicleId") Long vehicleId);
 } 
\ No newline at end of file
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java
index f228208..a53ab4e 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java
@@ -3,6 +3,7 @@
 import java.util.List;
 import com.ruoyi.common.core.domain.TreeSelect;
 import com.ruoyi.common.core.domain.entity.SysDept;
+import com.ruoyi.common.core.domain.entity.SysUser;
 
 /**
  * 閮ㄩ棬绠$悊 鏈嶅姟灞�
@@ -121,4 +122,16 @@
      * @return 缁撴灉
      */
     public int deleteDeptById(Long deptId);
+    
+    /**
+     * 璁$畻鎸囧畾鐢ㄦ埛鐨勫垎鍏徃鍒楄〃
+     * 閫昏緫锛�
+     * 1. 鏍规嵁鐢ㄦ埛鐨刼aOrderClass鍖归厤鍒嗗叕鍙革紙鏈嶅姟鍗曠紪鐮�/璋冨害鍗曠紪鐮侊級
+     * 2. 闄勫姞鐢ㄦ埛鎵�灞炵殑鍒嗗叕鍙革紙浠巇eptId/ancestors瑙f瀽锛�
+     * 3. 鍘婚噸鍚庤繑鍥�
+     * 
+     * @param user 鐢ㄦ埛淇℃伅
+     * @return 鍒嗗叕鍙稿垪琛�
+     */
+    public List<SysDept> computeBranchCompaniesForUser(SysUser user);
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IVehicleInfoService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IVehicleInfoService.java
index cfcbd68..ca4db11 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/IVehicleInfoService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IVehicleInfoService.java
@@ -88,4 +88,13 @@
      * @return 杞﹁締淇℃伅
      */
     public VehicleInfo getUserBoundVehicle(Long userId);
+    
+    /**
+     * 鏍规嵁鐢ㄦ埛鏈夋潈闄愮鐞嗙殑鍒嗗叕鍙革紝鏌ヨ鎵�鏈夊彲鐢ㄨ溅杈�
+     * 閫氳繃杞﹁締-鍒嗗叕鍙稿叧鑱旇〃鏌ヨ
+     * 
+     * @param userId 鐢ㄦ埛ID
+     * @return 杞﹁締鍒楄〃
+     */
+    public List<VehicleInfo> selectAvailableVehiclesByUser(Long userId);
 } 
\ No newline at end of file
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java
index 54b605d..f990c3c 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java
@@ -1,8 +1,10 @@
 package com.ruoyi.system.service.impl;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 import java.util.stream.Collectors;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -335,4 +337,95 @@
     {
         return getChildList(list, t).size() > 0;
     }
+    
+    /**
+     * 璁$畻鎸囧畾鐢ㄦ埛鐨勫垎鍏徃鍒楄〃
+     * 閫昏緫锛�
+     * 1. 鏍规嵁鐢ㄦ埛鐨刼aOrderClass鍖归厤鍒嗗叕鍙革紙鏈嶅姟鍗曠紪鐮�/璋冨害鍗曠紪鐮侊級
+     * 2. 闄勫姞鐢ㄦ埛鎵�灞炵殑鍒嗗叕鍙革紙浠巇eptId/ancestors瑙f瀽锛�
+     * 3. 鍘婚噸鍚庤繑鍥�
+     * 
+     * @param user 鐢ㄦ埛淇℃伅
+     * @return 鍒嗗叕鍙稿垪琛�
+     */
+    @Override
+    public List<SysDept> computeBranchCompaniesForUser(SysUser user)
+    {
+        List<SysDept> result = new ArrayList<>();
+        Set<Long> seen = new HashSet<>();
+        
+        if (user == null) {
+            return result;
+        }
+        
+        // 1. 鏍规嵁oaOrderClass鍖归厤鍒嗗叕鍙革紙浼樺寲锛氫竴娆℃煡璇級
+        String orderClass = user.getOaOrderClass();
+        if (StringUtils.isNotEmpty(orderClass))
+        {
+            // 瑙f瀽orderClass涓虹紪鐮佸垪琛�
+            List<String> orderCodes = new ArrayList<>();
+            for (String raw : orderClass.split(",")) {
+                String code = raw.trim();
+                if (!code.isEmpty()) {
+                    orderCodes.add(code);
+                }
+            }
+            
+            // 涓�娆℃�ф煡璇㈡墍鏈夊尮閰嶇殑鍒嗗叕鍙�
+            if (!orderCodes.isEmpty()) {
+                List<SysDept> matchedDepts = deptMapper.selectBranchCompaniesByOrderCodes(orderCodes);
+                for (SysDept dept : matchedDepts) {
+                    if (seen.add(dept.getDeptId())) {
+                        result.add(dept);
+                    }
+                }
+            }
+        }
+        
+        // 2. 闄勫姞璇ョ敤鎴锋墍灞炲垎鍏徃锛堜粠deptId/ancestors瑙f瀽锛�
+        if (user.getDeptId() != null)
+        {
+            SysDept userDept = selectDeptById(user.getDeptId());
+            Long branchCompanyId = null;
+            
+            if (userDept != null)
+            {
+                // 鍒ゆ柇鏄惁鏈韩灏辨槸鍒嗗叕鍙�
+                if (userDept.getParentId() != null && userDept.getParentId() == 100L)
+                {
+                    branchCompanyId = userDept.getDeptId();
+                }
+                // 鍚﹀垯浠巃ncestors涓煡鎵�
+                else if (userDept.getAncestors() != null && !userDept.getAncestors().isEmpty())
+                {
+                    String[] ancestorIds = userDept.getAncestors().split(",");
+                    for (int i = 0; i < ancestorIds.length; i++)
+                    {
+                        // 鎵惧埌100鐨勪笅涓�涓氨鏄垎鍏徃ID
+                        if ("100".equals(ancestorIds[i]) && i + 1 < ancestorIds.length)
+                        {
+                            try {
+                                branchCompanyId = Long.parseLong(ancestorIds[i + 1]);
+                            } catch (NumberFormatException e) {
+                                branchCompanyId = null;
+                            }
+                            break;
+                        }
+                    }
+                }
+            }
+            
+            // 濡傛灉鎵惧埌浜嗗垎鍏徃ID锛屾坊鍔犲埌缁撴灉涓�
+            if (branchCompanyId != null)
+            {
+                SysDept branchCompany = selectDeptById(branchCompanyId);
+                if (branchCompany != null && seen.add(branchCompany.getDeptId()))
+                {
+                    result.add(branchCompany);
+                }
+            }
+        }
+        
+        return result;
+    }
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserSyncServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserSyncServiceImpl.java
index c82a875..ecadd20 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserSyncServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserSyncServiceImpl.java
@@ -219,6 +219,10 @@
         }
         
         existingUser.setUpdateBy("sync");
+        if (StringUtils.isNotEmpty(dto.getOaOrderClass()))
+        {
+            existingUser.setOaOrderClass(dto.getOaOrderClass());
+        }
         sysUserMapper.updateUser(existingUser);
     }
 
@@ -231,6 +235,10 @@
         newUser.setUserName(dto.getUserName());
         newUser.setNickName(dto.getNickName());
         newUser.setOaUserId(dto.getOaUserId());
+        if (StringUtils.isNotEmpty(dto.getOaOrderClass()))
+        {
+            newUser.setOaOrderClass(dto.getOaOrderClass());
+        }
         
         if (deptId != null)
         {
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleInfoServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleInfoServiceImpl.java
index d524b96..1b4a58d 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleInfoServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleInfoServiceImpl.java
@@ -1,14 +1,23 @@
 package com.ruoyi.system.service.impl;
 
+import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import java.util.Date;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.core.domain.entity.SysDept;
 import com.ruoyi.system.mapper.VehicleInfoMapper;
+import com.ruoyi.system.mapper.SysUserMapper;
+import com.ruoyi.system.mapper.SysDeptMapper;
 import com.ruoyi.system.domain.VehicleInfo;
+import com.ruoyi.system.domain.VehicleDept;
 import com.ruoyi.system.service.IVehicleInfoService;
+import com.ruoyi.system.service.ISysDeptService;
 
 /**
  * 杞﹁締淇℃伅Service涓氬姟灞傚鐞�
@@ -17,6 +26,15 @@
 public class VehicleInfoServiceImpl implements IVehicleInfoService {
     @Autowired
     private VehicleInfoMapper vehicleInfoMapper;
+    
+    @Autowired
+    private SysUserMapper sysUserMapper;
+    
+    @Autowired
+    private SysDeptMapper sysDeptMapper;
+    
+    @Autowired
+    private ISysDeptService sysDeptService;
 
     /**
      * 鏌ヨ杞﹁締淇℃伅
@@ -58,8 +76,16 @@
      * @return 缁撴灉
      */
     @Override
+    @Transactional
     public int insertVehicleInfo(VehicleInfo vehicleInfo) {
-        return vehicleInfoMapper.insertVehicleInfo(vehicleInfo);
+        int rows = vehicleInfoMapper.insertVehicleInfo(vehicleInfo);
+        
+        // 濡傛灉閫夋嫨浜嗗涓垎鍏徃锛屼繚瀛樺埌鍏宠仈琛�
+        if (vehicleInfo.getDeptIds() != null && !vehicleInfo.getDeptIds().isEmpty()) {
+            insertVehicleDept(vehicleInfo);
+        }
+        
+        return rows;
     }
 
     /**
@@ -69,8 +95,34 @@
      * @return 缁撴灉
      */
     @Override
+    @Transactional
     public int updateVehicleInfo(VehicleInfo vehicleInfo) {
+        // 鍏堝垹闄ゆ棫鐨勫叧鑱斿叧绯�
+        vehicleInfoMapper.deleteVehicleDeptByVehicleId(vehicleInfo.getVehicleId());
+        
+        // 濡傛灉閫夋嫨浜嗗涓垎鍏徃锛屼繚瀛樺埌鍏宠仈琛�
+        if (vehicleInfo.getDeptIds() != null && !vehicleInfo.getDeptIds().isEmpty()) {
+            insertVehicleDept(vehicleInfo);
+        }
+        
         return vehicleInfoMapper.updateVehicleInfo(vehicleInfo);
+    }
+    
+    /**
+     * 鎻掑叆杞﹁締-鍒嗗叕鍙稿叧鑱斿叧绯�
+     */
+    private void insertVehicleDept(VehicleInfo vehicleInfo) {
+        List<VehicleDept> vehicleDepts = new ArrayList<>();
+        for (Long deptId : vehicleInfo.getDeptIds()) {
+            VehicleDept vd = new VehicleDept();
+            vd.setVehicleId(vehicleInfo.getVehicleId());
+            vd.setDeptId(deptId);
+            vd.setCreateBy(vehicleInfo.getCreateBy());
+            vehicleDepts.add(vd);
+        }
+        if (!vehicleDepts.isEmpty()) {
+            vehicleInfoMapper.batchInsertVehicleDept(vehicleDepts);
+        }
     }
 
     /**
@@ -140,4 +192,51 @@
     public VehicleInfo getUserBoundVehicle(Long userId) {
         return vehicleInfoMapper.getUserBoundVehicle(userId);
     }
+    
+    /**
+     * 鏍规嵁鐢ㄦ埛鏈夋潈闄愮鐞嗙殑鍒嗗叕鍙革紝鏌ヨ鎵�鏈夊彲鐢ㄨ溅杈�
+     * 閫昏緫锛�
+     * 1. 鏌ヨ鐢ㄦ埛淇℃伅
+     * 2. 璋冪敤sysDeptService.computeBranchCompaniesForUser鑾峰彇鐢ㄦ埛绠$悊鐨勬墍鏈夊垎鍏徃
+     * 3. 閫氳繃tb_vehicle_dept鍏宠仈琛ㄦ煡璇㈣繖浜涘垎鍏徃涓嬬殑鎵�鏈夎溅杈�
+     * 
+     * @param userId 鐢ㄦ埛ID
+     * @return 杞﹁締鍒楄〃
+     */
+    @Override
+    public List<VehicleInfo> selectAvailableVehiclesByUser(Long userId) {
+        // 1. 鏌ヨ鐢ㄦ埛淇℃伅
+        SysUser user = sysUserMapper.selectUserById(userId);
+        if (user == null) {
+            return new ArrayList<>();
+        }
+        
+        // 2. 璋冪敤sysDeptService鑾峰彇鐢ㄦ埛绠$悊鐨勬墍鏈夊垎鍏徃
+        List<SysDept> branchCompanies = sysDeptService.computeBranchCompaniesForUser(user);
+        
+        if (branchCompanies.isEmpty()) {
+            // 濡傛灉娌℃湁鎵惧埌浠讳綍鍒嗗叕鍙革紝杩斿洖绌哄垪琛�
+            return new ArrayList<>();
+        }
+        
+        // 3. 鏍规嵁鍒嗗叕鍙稿垪琛ㄦ煡璇㈣溅杈嗭紝浣跨敤Set鍘婚噸
+        Set<Long> vehicleIdSet = new HashSet<>();
+        List<VehicleInfo> allVehicles = new ArrayList<>();
+        
+        for (SysDept branchCompany : branchCompanies) {
+            VehicleInfo query = new VehicleInfo();
+            query.setDeptId(branchCompany.getDeptId());
+            List<VehicleInfo> vehicles = vehicleInfoMapper.selectVehicleInfoList(query);
+            
+            // 鍘婚噸娣诲姞
+            for (VehicleInfo vehicle : vehicles) {
+                if (!vehicleIdSet.contains(vehicle.getVehicleId())) {
+                    vehicleIdSet.add(vehicle.getVehicleId());
+                    allVehicles.add(vehicle);
+                }
+            }
+        }
+        
+        return allVehicles;
+    }
 } 
\ No newline at end of file
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleSyncServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleSyncServiceImpl.java
index b9f4b69..56fc2c2 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleSyncServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleSyncServiceImpl.java
@@ -3,8 +3,10 @@
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.domain.entity.SysDept;
 import com.ruoyi.system.domain.VehicleInfo;
+import com.ruoyi.system.domain.VehicleDept;
 import com.ruoyi.system.domain.VehicleSyncDTO;
 import com.ruoyi.system.mapper.SysDeptMapper;
+import com.ruoyi.system.mapper.VehicleInfoMapper;
 import com.ruoyi.system.service.IVehicleInfoService;
 import com.ruoyi.system.service.IVehicleSyncDataService;
 import com.ruoyi.system.service.IVehicleSyncService;
@@ -15,6 +17,7 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -39,6 +42,9 @@
 
     @Autowired
     private SysDeptMapper sysDeptMapper;
+    
+    @Autowired
+    private VehicleInfoMapper vehicleInfoMapper;
 
 
     /**
@@ -82,18 +88,28 @@
                     // 鏌ヨ杞﹁締鏄惁瀛樺湪
                     VehicleInfo existingVehicle = findVehicleByPlateNumber(plateNumber);
 
-                    // 瑙f瀽閮ㄩ棬淇℃伅
-                    Long deptId = parseDeptIdFromCarOrdClass(vehicleDTO.getCarOrdClass());
+                    // 瑙f瀽鎵�鏈夊垎鍏徃ID锛圕arOrdClass鍙兘鍖呭惈澶氫釜缂栫爜锛屽锛欻B,TI锛�
+                    List<VehicleDept> vehicleDepts = parseVehicleDepts(vehicleDTO.getCarOrdClass());
+                    
+                    // 璁剧疆榛樿鐨勪富閮ㄩ棬ID锛堢涓�涓垎鍏徃锛�
+                    Long primaryDeptId = null;
+                    if (!vehicleDepts.isEmpty()) {
+                        primaryDeptId = vehicleDepts.get(0).getDeptId();
+                    }
 
                     if (existingVehicle != null)
                     {
                         // 鏇存柊杞﹁締淇℃伅
                         existingVehicle.setCarId(vehicleDTO.getCarId());
-                        existingVehicle.setDeptId(deptId);
-                        // 鍙互閫夋嫨鏄惁鏇存柊鍏朵粬瀛楁
+                        existingVehicle.setDeptId(primaryDeptId); // 璁剧疆涓婚儴闂�
                         vehicleInfoService.updateVehicleInfo(existingVehicle);
+                        
+                        // 鏇存柊杞﹁締-鍒嗗叕鍙稿叧鑱�
+                        syncVehicleDepts(existingVehicle.getVehicleId(), vehicleDepts);
+                        
                         updateCount++;
-                        log.debug("鏇存柊杞﹁締: {} (CarID={}), 閮ㄩ棬ID={}", plateNumber, vehicleDTO.getCarId(), deptId);
+                        log.debug("鏇存柊杞﹁締: {} (CarID={}), 鍏宠仈鍒嗗叕鍙告暟: {}", 
+                                plateNumber, vehicleDTO.getCarId(), vehicleDepts.size());
                     }
                     else
                     {
@@ -101,13 +117,18 @@
                         VehicleInfo newVehicle = new VehicleInfo();
                         newVehicle.setVehicleNo(plateNumber);
                         newVehicle.setCarId(vehicleDTO.getCarId());
-                        newVehicle.setDeptId(deptId);
+                        newVehicle.setDeptId(primaryDeptId); // 璁剧疆涓婚儴闂�
                         newVehicle.setStatus("0");
                         newVehicle.setPlatformCode("LEGACY"); // 鏍囪涓烘棫绯荤粺鍚屾
                         newVehicle.setRemark("浠庢棫绯荤粺鍚屾锛孋arID: " + vehicleDTO.getCarId());
                         vehicleInfoService.insertVehicleInfo(newVehicle);
+                        
+                        // 鏂板杞﹁締-鍒嗗叕鍙稿叧鑱�
+                        syncVehicleDepts(newVehicle.getVehicleId(), vehicleDepts);
+                        
                         insertCount++;
-                        log.debug("鏂板杞﹁締: {} (CarID={}), 閮ㄩ棬ID={}", plateNumber, vehicleDTO.getCarId(), deptId);
+                        log.debug("鏂板杞﹁締: {} (CarID={}), 鍏宠仈鍒嗗叕鍙告暟: {}", 
+                                plateNumber, vehicleDTO.getCarId(), vehicleDepts.size());
                     }
                 }
                 catch (Exception e)
@@ -231,22 +252,23 @@
     }
 
     /**
-     * 浠� CarOrdClass 瑙f瀽閮ㄩ棬ID锛屽苟杞崲涓哄垎鍏徃ID
-     * CarOrdClass鏍煎紡鍙兘鏄細ZB銆丠B.TI绛�
-     * 闇�瑕佹媶鍒嗗苟鍦╯ys_dept涓尮閰峝ispatch_order_class瀛楁
+     * 浠� CarOrdClass 瑙f瀽澶氫釜鍒嗗叕鍙稿叧鑱�
+     * CarOrdClass鏍煎紡鍙兘鏄細HB銆丠B,TI銆丠B.TI绛�
      * 
      * @param carOrdClass 杞﹁締鍗曟嵁绫诲瀷缂栫爜
-     * @return 鍒嗗叕鍙窱D锛屽鏋滄湭鎵惧埌杩斿洖null
+     * @return 杞﹁締-鍒嗗叕鍙稿叧鑱斿垪琛�
      */
-    private Long parseDeptIdFromCarOrdClass(String carOrdClass)
+    private List<VehicleDept> parseVehicleDepts(String carOrdClass)
     {
+        List<VehicleDept> vehicleDepts = new ArrayList<>();
+        
         if (StringUtils.isBlank(carOrdClass))
         {
-            log.debug("CarOrdClass涓虹┖锛屾棤娉曡В鏋愰儴闂�");
-            return null;
+            log.debug("CarOrdClass涓虹┖锛屾棤娉曡В鏋愬垎鍏徃");
+            return vehicleDepts;
         }
 
-        // 鎷嗗垎CarOrdClass锛屽彲鑳界殑鍒嗛殧绗︼細. , 绌烘牸
+        // 鎷嗗垎CarOrdClass锛屽彲鑳界殑鍒嗛殧绗︼細, . 绌烘牸
         String[] codes = carOrdClass.split("[.,\\s]+");
         
         for (String code : codes)
@@ -258,60 +280,95 @@
             
             code = code.trim();
             
-            // 鏌ヨ鍖归厤dispatch_order_class鐨勯儴闂�
-            SysDept dept = findDeptByDispatchOrderClass(code);
-            if (dept != null)
+            // 鏌ヨ鍖归厤dispatch_order_class鎴杝ervice_order_class鐨勯儴闂�
+            SysDept dept = findDeptByOrderClass(code);
+            if (dept != null && dept.getParentId() != null && dept.getParentId() == 100L)
             {
-                log.debug("閫氳繃dispatch_order_class='{}' 鎵惧埌閮ㄩ棬: {} (ID={})", 
-                        code, dept.getDeptName(), dept.getDeptId());
+                // 鍙鐞嗗垎鍏徃锛坧arent_id=100锛�
+                VehicleDept vehicleDept = new VehicleDept();
+                vehicleDept.setDeptId(dept.getDeptId());
+                vehicleDept.setOrderClass(code);
+                vehicleDept.setCreateBy("system");
+                vehicleDepts.add(vehicleDept);
                 
-                // 灏嗛儴闂↖D杞崲涓哄垎鍏徃ID
-                Long branchCompanyId = sysDeptMapper.selectBranchCompanyIdByDeptId(dept.getDeptId());
-                if (branchCompanyId != null)
-                {
-                    log.debug("灏嗛儴闂↖D {} 杞崲涓哄垎鍏徃ID: {}", dept.getDeptId(), branchCompanyId);
-                    return branchCompanyId;
-                }
-                else
-                {
-                    log.warn("閮ㄩ棬ID {} 鏃犳硶杞崲涓哄垎鍏徃ID锛屽彲鑳芥槸鎬诲叕鍙告垨鏁版嵁寮傚父", dept.getDeptId());
-                    return null;
-                }
+                log.debug("閫氳繃order_class='{}' 鎵惧埌鍒嗗叕鍙�: {} (ID={})", 
+                        code, dept.getDeptName(), dept.getDeptId());
+            }
+            else
+            {
+                log.debug("鏈壘鍒板尮閰峯rder_class='{}' 鐨勫垎鍏徃", code);
             }
         }
         
-        log.warn("鏈壘鍒板尮閰岰arOrdClass='{}' 鐨勯儴闂�", carOrdClass);
-        return null;
+        return vehicleDepts;
+    }
+    
+    /**
+     * 鍚屾杞﹁締-鍒嗗叕鍙稿叧鑱�
+     * 
+     * @param vehicleId 杞﹁締ID
+     * @param vehicleDepts 鍒嗗叕鍙稿叧鑱斿垪琛�
+     */
+    private void syncVehicleDepts(Long vehicleId, List<VehicleDept> vehicleDepts)
+    {
+        if (vehicleId == null || vehicleDepts == null)
+        {
+            return;
+        }
+        
+        // 鍏堝垹闄ゆ棫鐨勫叧鑱�
+        vehicleInfoMapper.deleteVehicleDeptByVehicleId(vehicleId);
+        
+        // 鍐嶆彃鍏ユ柊鐨勫叧鑱�
+        if (!vehicleDepts.isEmpty())
+        {
+            for (VehicleDept vd : vehicleDepts)
+            {
+                vd.setVehicleId(vehicleId);
+            }
+            vehicleInfoMapper.batchInsertVehicleDept(vehicleDepts);
+            log.debug("鍚屾杞﹁締ID={} 鐨勫垎鍏徃鍏宠仈锛屾暟閲�: {}", vehicleId, vehicleDepts.size());
+        }
     }
 
     /**
-     * 鏍规嵁dispatch_order_class鏌ヨ閮ㄩ棬
+     * 鏍规嵁order_class鏌ヨ閮ㄩ棬锛堝悓鏃跺尮閰峝ispatch_order_class鍜宻ervice_order_class锛�
      * 
-     * @param dispatchOrderClass 璋冨害鍗曠紪鐮�
+     * @param orderClass 缂栫爜
      * @return 閮ㄩ棬淇℃伅
      */
-    private SysDept findDeptByDispatchOrderClass(String dispatchOrderClass)
+    private SysDept findDeptByOrderClass(String orderClass)
     {
-        if (StringUtils.isBlank(dispatchOrderClass))
+        if (StringUtils.isBlank(orderClass))
         {
             return null;
         }
 
         try
         {
+            // 鍏堝皾璇曞尮閰峝ispatch_order_class
             SysDept query = new SysDept();
-            query.setDispatchOrderClass(dispatchOrderClass);
+            query.setDispatchOrderClass(orderClass);
             List<SysDept> depts = sysDeptMapper.selectDeptList(query);
             
             if (depts != null && !depts.isEmpty())
             {
-                // 杩斿洖绗竴涓尮閰嶇殑閮ㄩ棬
+                return depts.get(0);
+            }
+            
+            // 濡傛灉娌℃湁鎵惧埌锛屽皾璇曞尮閰峴ervice_order_class
+            query = new SysDept();
+            query.setServiceOrderClass(orderClass);
+            depts = sysDeptMapper.selectDeptList(query);
+            
+            if (depts != null && !depts.isEmpty())
+            {
                 return depts.get(0);
             }
         }
         catch (Exception e)
         {
-            log.error("鏌ヨdispatch_order_class='{}' 鐨勯儴闂ㄥけ璐�", dispatchOrderClass, e);
+            log.error("鏌ヨorder_class='{}' 鐨勯儴闂ㄥけ璐�", orderClass, e);
         }
         
         return null;
diff --git a/ruoyi-system/src/main/resources/mapper/system/HospDataMapper.xml b/ruoyi-system/src/main/resources/mapper/system/HospDataMapper.xml
index d3470a2..a7e7a9f 100644
--- a/ruoyi-system/src/main/resources/mapper/system/HospDataMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/HospDataMapper.xml
@@ -65,4 +65,47 @@
         FROM HospData
         WHERE HospID = #{hospId}
     </select>
+    
+    <!-- 鏌ヨ甯哥敤杞嚭鍖婚櫌ID鍒楄〃 -->
+    <select id="selectFrequentOutHospitalIds" resultType="java.lang.Integer">
+        select ServiceOrdPtOutHospID from (
+            select    ServiceOrdPtOutHospID,count(1) as InCount  from ServiceOrder 
+            where ServiceOrdClass=#{serviceOrdClass} and ServiceOrdPtOutHospID>0
+            group by ServiceOrdPtOutHospID
+        ) as t
+        order by InCount desc
+    </select>
+    
+    <!-- 鏌ヨ甯哥敤杞叆鍖婚櫌ID鍒楄〃 -->
+    <select id="selectFrequentInHospitalIds" resultType="java.lang.Integer">
+        select ServiceOrdPtInHospID from (
+            select    ServiceOrdPtInHospID,count(1) as InCount  from ServiceOrder 
+            where ServiceOrdClass=#{serviceOrdClass} and ServiceOrdPtInHospID>0
+            group by ServiceOrdPtInHospID
+        ) as t
+        order by InCount desc
+    </select>
+    
+    <!-- 鏍规嵁鍖婚櫌ID鍒楄〃鏌ヨ鍖婚櫌淇℃伅 -->
+    <select id="selectHospDataByIds" resultMap="HospDataResult">
+        SELECT 
+            HospID, HospName, HospCityID, HospShort, 
+            HopsProvince, HopsCity, HopsArea, HospAddress, 
+            HospTEL, HospUnitID, HospState, HospOAID, 
+            HospIntroducerID, HospIntroducerDate, HospLevel
+        FROM HospData
+        WHERE HospID IN
+        <foreach collection="hospIds" item="hospId" open="(" separator="," close=")">
+            #{hospId}
+        </foreach>
+        <if test="region != null and region != ''">
+        AND (
+            HopsProvince LIKE '%' + #{region} + '%'
+                OR HopsCity LIKE '%' + #{region} + '%'
+                OR HopsArea LIKE '%' + #{region} + '%'
+        )
+        </if>
+        AND (HospState IS NULL OR HospState = 1)
+        ORDER BY HospName
+    </select>
 </mapper>
diff --git a/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml
index aa40711..f4b16dd 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml
@@ -208,5 +208,18 @@
 			)
 		end
 	</select>
+	
+	<!-- 鏍规嵁缂栫爜鍒楄〃鏌ヨ鍒嗗叕鍙� -->
+	<select id="selectBranchCompaniesByOrderCodes" resultMap="SysDeptResult">
+		select dept_id, dept_name, parent_id, ancestors, service_order_class, dispatch_order_class
+		from sys_dept
+		where parent_id = 100
+		and del_flag = '0'
+		and (
+			<foreach collection="orderCodes" item="code" separator=" or ">
+				service_order_class = #{code} or dispatch_order_class = #{code}
+			</foreach>
+		)
+	</select>
 
 </mapper> 
\ No newline at end of file
diff --git a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
index aabf8a1..03654d9 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
@@ -19,6 +19,7 @@
         <result property="loginIp"      column="login_ip"     />
         <result property="loginDate"    column="login_date"   />
         <result property="oaUserId"     column="oa_user_id"   />
+        <result property="oaOrderClass" column="oa_order_class" />
         <result property="createBy"     column="create_by"    />
         <result property="createTime"   column="create_time"  />
         <result property="updateBy"     column="update_by"    />
@@ -48,7 +49,7 @@
     </resultMap>
 	
 	<sql id="selectUserVo">
-        select u.user_id, u.dept_id, u.user_name,u.oa_user_id, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.oa_user_id, u.create_by, u.create_time, u.remark,
+        select u.user_id, u.dept_id, u.user_name,u.oa_user_id, u.oa_order_class, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.oa_user_id, u.create_by, u.create_time, u.remark,
         d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status,
         r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status
         from sys_user u
@@ -197,6 +198,7 @@
  			<if test="password != null and password != ''">password,</if>
  			<if test="status != null and status != ''">status,</if>
  			<if test="oaUserId != null">oa_user_id,</if>
+ 			<if test="oaOrderClass != null and oaOrderClass != ''">oa_order_class,</if>
  			<if test="createBy != null and createBy != ''">create_by,</if>
  			<if test="remark != null and remark != ''">remark,</if>
  			create_time
@@ -212,6 +214,7 @@
  			<if test="password != null and password != ''">#{password},</if>
  			<if test="status != null and status != ''">#{status},</if>
  			<if test="oaUserId != null">#{oaUserId},</if>
+ 			<if test="oaOrderClass != null and oaOrderClass != ''">#{oaOrderClass},</if>
  			<if test="createBy != null and createBy != ''">#{createBy},</if>
  			<if test="remark != null and remark != ''">#{remark},</if>
  			sysdate()
@@ -230,6 +233,7 @@
  			<if test="password != null and password != ''">password = #{password},</if>
  			<if test="status != null and status != ''">status = #{status},</if>
  			<if test="oaUserId != null">oa_user_id = #{oaUserId},</if>
+ 			<if test="oaOrderClass != null">oa_order_class = #{oaOrderClass},</if>
  			<if test="loginIp != null and loginIp != ''">login_ip = #{loginIp},</if>
  			<if test="loginDate != null">login_date = #{loginDate},</if>
  			<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
diff --git a/ruoyi-system/src/main/resources/mapper/system/UserSyncMapper.xml b/ruoyi-system/src/main/resources/mapper/system/UserSyncMapper.xml
index 818d0c5..f96ef3c 100644
--- a/ruoyi-system/src/main/resources/mapper/system/UserSyncMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/UserSyncMapper.xml
@@ -12,6 +12,7 @@
         <result property="sex" column="sex" />
         <result property="email" column="email" />
         <result property="phonenumber" column="phonenumber" />
+        <result property="oaOrderClass" column="OA_OrderClass" />
     </resultMap>
 
     <!-- 鏌ヨSQL Server涓殑OA鐢ㄦ埛鍒楄〃 -->
@@ -24,7 +25,8 @@
             OA_departmentID AS department_id,
             OA_gender AS sex,
             OA_email AS email,
-            OA_mobile AS phonenumber
+            OA_mobile AS phonenumber,
+            OA_OrderClass AS OA_OrderClass
         FROM OA_User
         WHERE OA_User IS NOT NULL 
           AND OA_Name IS NOT NULL
diff --git a/ruoyi-system/src/main/resources/mapper/system/VehicleInfoMapper.xml b/ruoyi-system/src/main/resources/mapper/system/VehicleInfoMapper.xml
index e44b722..123a769 100644
--- a/ruoyi-system/src/main/resources/mapper/system/VehicleInfoMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/VehicleInfoMapper.xml
@@ -21,6 +21,13 @@
         <result property="updateBy"       column="update_by"       />
         <result property="updateTime"     column="update_time"     />
         <result property="remark"         column="remark"          />
+        <!-- 澶氫釜鍒嗗叕鍙稿叧鑱� -->
+        <collection property="deptIds" ofType="Long" 
+                    select="selectVehicleDeptIds" 
+                    column="vehicle_id"/>
+        <collection property="deptNames" ofType="String" 
+                    select="selectVehicleDeptNames" 
+                    column="vehicle_id"/>
     </resultMap>
 
     <sql id="selectVehicleInfoVo">
@@ -28,6 +35,19 @@
         from tb_vehicle_info v
         left join sys_dept d on v.dept_id = d.dept_id
     </sql>
+    
+    <!-- 鏌ヨ杞﹁締鍏宠仈鐨勬墍鏈夊垎鍏徃ID -->
+    <select id="selectVehicleDeptIds" resultType="Long">
+        SELECT dept_id FROM tb_vehicle_dept WHERE vehicle_id = #{vehicle_id}
+    </select>
+    
+    <!-- 鏌ヨ杞﹁締鍏宠仈鐨勬墍鏈夊垎鍏徃鍚嶇О -->
+    <select id="selectVehicleDeptNames" resultType="String">
+        SELECT d.dept_name 
+        FROM tb_vehicle_dept vd
+        LEFT JOIN sys_dept d ON vd.dept_id = d.dept_id
+        WHERE vd.vehicle_id = #{vehicle_id}
+    </select>
 
     <select id="selectVehicleInfoList" parameterType="VehicleInfo" resultMap="VehicleInfoResult">
         <include refid="selectVehicleInfoVo"/>
@@ -39,23 +59,12 @@
             <if test="vehicleModel != null  and vehicleModel != ''"> and v.vehicle_model = #{vehicleModel}</if>
             <if test="status != null  and status != ''"> and v.status = #{status}</if>
             <if test="platformCode != null  and platformCode != ''"> and v.platform_code = #{platformCode}</if>
-            <!-- 閮ㄩ棬杩囨护锛氳嚜鍔ㄦ煡鎵句紶鍏ラ儴闂ㄦ墍灞炵殑鍒嗗叕鍙革紙parent_id=100锛� -->
+            <!-- 閮ㄩ棬杩囨护锛氭牴鎹垎鍏徃ID鏌ヨ杞﹁締锛堥�氳繃鍏宠仈琛級 -->
             <if test="deptId != null">
-                and v.dept_id = (
-                    <!-- 濡傛灉浼犲叆鐨勫氨鏄垎鍏徃锛坧arent_id=100锛夛紝鐩存帴杩斿洖 -->
-                    select case 
-                        when exists(select 1 from sys_dept where dept_id = #{deptId} and parent_id = 100) then #{deptId}
-                        else (
-                            <!-- 鍚﹀垯浠� ancestors 涓煡鎵惧垎鍏徃ID -->
-                            select d.dept_id
-                            from sys_dept d
-                            where d.parent_id = 100
-                            and FIND_IN_SET(d.dept_id, (
-                                select ancestors from sys_dept where dept_id = #{deptId}
-                            ))
-                            limit 1
-                        )
-                    end
+                and EXISTS (
+                    SELECT 1 FROM tb_vehicle_dept vd 
+                    WHERE vd.vehicle_id = v.vehicle_id 
+                    AND vd.dept_id = #{deptId}
                 )
             </if>
             <!-- 浠诲姟杞﹁締閫夋嫨蹇呴』杩囨护锛氬彧鏄剧ずcar_id鍜宒ept_id閮戒笉涓虹┖鐨勮溅杈� -->
@@ -176,4 +185,22 @@
         ORDER BY uv.bind_time DESC
         LIMIT 1
     </select>
+    
+    <!-- 鎵归噺鎻掑叆杞﹁締-鍒嗗叕鍙稿叧鑱� -->
+    <insert id="batchInsertVehicleDept">
+        INSERT INTO tb_vehicle_dept (vehicle_id, dept_id, order_class, create_by, create_time)
+        VALUES
+        <foreach collection="list" item="item" separator=",">
+            (#{item.vehicleId}, #{item.deptId}, #{item.orderClass}, #{item.createBy}, NOW())
+        </foreach>
+        ON DUPLICATE KEY UPDATE
+        order_class = VALUES(order_class),
+        update_by = VALUES(create_by),
+        update_time = NOW()
+    </insert>
+    
+    <!-- 鍒犻櫎杞﹁締鐨勬墍鏈夊垎鍏徃鍏宠仈 -->
+    <delete id="deleteVehicleDeptByVehicleId">
+        DELETE FROM tb_vehicle_dept WHERE vehicle_id = #{vehicleId}
+    </delete>
 </mapper> 
\ No newline at end of file
diff --git a/ruoyi-ui/src/api/system/dept.js b/ruoyi-ui/src/api/system/dept.js
index fc943cd..7817d19 100644
--- a/ruoyi-ui/src/api/system/dept.js
+++ b/ruoyi-ui/src/api/system/dept.js
@@ -49,4 +49,20 @@
     url: '/system/dept/' + deptId,
     method: 'delete'
   })
-}
\ No newline at end of file
+}
+
+// 鎸夊綋鍓嶇櫥褰曠敤鎴风殑 OA 鏉冮檺杩斿洖鍒嗗叕鍙稿垪琛�
+export function listBranchByOa() {
+  return request({
+    url: '/system/dept/branch/by-oa',
+    method: 'get'
+  })
+}
+
+// 鎸夊閮ㄤ紶鍏ョ殑鐢ㄦ埛ID杩斿洖鍏跺彲绠$悊鍒嗗叕鍙稿垪琛�
+export function listBranchByUser(userId) {
+  return request({
+    url: '/system/dept/branch/by-user/' + userId,
+    method: 'get'
+  })
+}
diff --git a/ruoyi-ui/src/views/system/user/index.vue b/ruoyi-ui/src/views/system/user/index.vue
index 2d09ee4..f479f46 100644
--- a/ruoyi-ui/src/views/system/user/index.vue
+++ b/ruoyi-ui/src/views/system/user/index.vue
@@ -59,7 +59,7 @@
 
             <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
               <el-table-column type="selection" width="50" align="center" />
-              <el-table-column label="鐢ㄦ埛缂栧彿" align="center" key="userId" prop="userId" v-if="columns[0].visible" />
+              
               <!-- OA鐢ㄦ埛ID鍒楀凡闅愯棌锛屽彧鍦ㄧ紪杈戣〃鍗曚腑鏄剧ず -->
               <el-table-column label="鐢ㄦ埛鍚嶇О" align="center" key="userName" prop="userName" v-if="columns[2].visible" width="150" />
               <el-table-column label="鐢ㄦ埛鏄电О" align="center" key="nickName" prop="nickName" v-if="columns[3].visible" :show-overflow-tooltip="true" />
@@ -75,7 +75,7 @@
                   <span>{{ parseTime(scope.row.createTime) }}</span>
                 </template>
               </el-table-column>
-              <el-table-column label="鎿嶄綔" align="center" width="160" class-name="small-padding fixed-width">
+              <el-table-column label="鎿嶄綔" align="center" width="200" class-name="small-padding fixed-width">
                 <template slot-scope="scope" v-if="scope.row.userId !== 1">
                   <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:user:edit']">淇敼</el-button>
                   <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['system:user:remove']">鍒犻櫎</el-button>
@@ -84,6 +84,8 @@
                     <el-dropdown-menu slot="dropdown">
                       <el-dropdown-item command="handleResetPwd" icon="el-icon-key" v-hasPermi="['system:user:resetPwd']">閲嶇疆瀵嗙爜</el-dropdown-item>
                       <el-dropdown-item command="handleAuthRole" icon="el-icon-circle-check" v-hasPermi="['system:user:edit']">鍒嗛厤瑙掕壊</el-dropdown-item>
+                      <!-- 鏂板锛氱鐞嗗垎鍏徃閰嶇疆鍏ュ彛 -->
+                      <el-dropdown-item command="handleManageBranch" icon="el-icon-office-building" v-hasPermi="['system:user:edit']">绠$悊鍒嗗叕鍙�</el-dropdown-item>
                     </el-dropdown-menu>
                   </el-dropdown>
                 </template>
@@ -115,6 +117,16 @@
           <el-col :span="12">
             <el-form-item label="OA鐢ㄦ埛ID" prop="oaUserId">
               <el-input v-model="form.oaUserId" placeholder="OA绯荤粺鐨勭敤鎴稩D" type="number" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="鍙鐞嗗垎鍏徃">
+              <div>
+                <el-tag v-for="bc in userBranchCompanies" :key="bc.deptId" type="info" size="small" style="margin-right:6px;margin-bottom:6px">{{ bc.deptName }}</el-tag>
+                <span v-if="userBranchCompanies.length === 0" style="color:#999">鏆傛棤鍒嗗叕鍙�</span>
+              </div>
             </el-form-item>
           </el-col>
         </el-row>
@@ -206,6 +218,21 @@
         <el-button @click="upload.open = false">鍙� 娑�</el-button>
       </div>
     </el-dialog>
+
+    <!-- 鏂板锛氱敤鎴风鐞嗗垎鍏徃閰嶇疆瀵硅瘽妗� -->
+    <el-dialog title="閰嶇疆绠$悊鍒嗗叕鍙�" :visible.sync="branchDialog.open" width="500px" append-to-body>
+      <el-form label-width="100px">
+        <el-form-item label="鍙鐞嗗垎鍏徃">
+          <div>
+            <el-tag v-for="bc in branchDialog.companies" :key="bc.deptId" type="info" size="small" style="margin-right:6px;margin-bottom:6px">{{ bc.deptName }}</el-tag>
+            <span v-if="branchDialog.companies.length === 0" style="color:#999">鏆傛棤鍒嗗叕鍙�</span>
+          </div>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="branchDialog.open = false">鍏� 闂�</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
@@ -216,6 +243,8 @@
 import "@riophae/vue-treeselect/dist/vue-treeselect.css";
 import { Splitpanes, Pane } from "splitpanes";
 import "splitpanes/dist/splitpanes.css";
+import request from "@/utils/request";
+import { listDept, listBranchByUser } from "@/api/system/dept";
 
 export default {
   name: "User",
@@ -308,7 +337,7 @@
         password: [
           { required: true, message: "鐢ㄦ埛瀵嗙爜涓嶈兘涓虹┖", trigger: "blur" },
           { min: 5, max: 20, message: '鐢ㄦ埛瀵嗙爜闀垮害蹇呴』浠嬩簬 5 鍜� 20 涔嬮棿', trigger: 'blur' },
-          { pattern: /^[^<>"'|\\]+$/, message: "涓嶈兘鍖呭惈闈炴硶瀛楃锛�< > \" ' \\\ |", trigger: "blur" }
+          { pattern: /^[^<>"'|\\]+$/, message: "涓嶈兘鍖呭惈闈炴硶瀛楃锛�< > \" ' \\\\ |", trigger: "blur" }
         ],
         email: [
           {
@@ -324,7 +353,17 @@
             trigger: "blur"
           }
         ]
-      }
+      },
+      // 鏂板锛氬垎鍏徃閰嶇疆瀵硅瘽妗嗘暟鎹�
+      branchDialog: {
+        open: false,
+        userId: null,
+        deptOptions: [],
+        selectedDeptIds: [],
+        companies: []
+      },
+      // 鍩轰簬 oa_order_class 璁$畻鐨勫垎鍏徃鍒楄〃锛堝彧璇诲睍绀猴級
+      userBranchCompanies: []
     };
   },
   watch: {
@@ -404,6 +443,7 @@
         userName: undefined,
         nickName: undefined,
         oaUserId: undefined,
+        oaOrderClass: undefined,
         password: undefined,
         phonenumber: undefined,
         email: undefined,
@@ -443,6 +483,9 @@
         case "handleAuthRole":
           this.handleAuthRole(row);
           break;
+        case "handleManageBranch":
+          this.handleManageBranch(row);
+          break;
         default:
           break;
       }
@@ -471,8 +514,38 @@
         this.open = true;
         this.title = "淇敼鐢ㄦ埛";
         this.form.password = "";
+        this.loadUserBranchCompanies();
       });
     },
+    // 鏍规嵁 form.oaOrderClass 璁$畻鍒嗗叕鍙稿垪琛紙service/dispatch 缂栫爜鍖归厤锛�
+    loadUserBranchCompanies() {
+      this.userBranchCompanies = [];
+      const codesStr = this.form.oaOrderClass || '';
+      const codes = codesStr.split(',').map(s => s.trim()).filter(s => s);
+      if (codes.length === 0) {
+        return;
+      }
+      listDept({ parentId: 100 }).then(res => {
+        const all = res.data || [];
+        const codeSet = new Set(codes);
+        const list = [];
+        const seen = new Set();
+        all.forEach(d => {
+          const s = d.serviceOrderClass || '';
+          const dis = d.dispatchOrderClass || '';
+          if ((s && codeSet.has(s)) || (dis && codeSet.has(dis))) {
+            if (!seen.has(d.deptId)) {
+              seen.add(d.deptId);
+              list.push({ deptId: d.deptId, deptName: d.deptName });
+            }
+          }
+        });
+        this.userBranchCompanies = list;
+      }).catch(() => {
+        this.userBranchCompanies = [];
+      });
+    },
+
     /** 閲嶇疆瀵嗙爜鎸夐挳鎿嶄綔 */
     handleResetPwd(row) {
       this.$prompt('璇疯緭鍏�"' + row.userName + '"鐨勬柊瀵嗙爜', "鎻愮ず", {
@@ -483,7 +556,7 @@
         inputErrorMessage: "鐢ㄦ埛瀵嗙爜闀垮害蹇呴』浠嬩簬 5 鍜� 20 涔嬮棿",
         inputValidator: (value) => {
           if (/<|>|"|'|\||\\/.test(value)) {
-            return "涓嶈兘鍖呭惈闈炴硶瀛楃锛�< > \" ' \\\ |"
+            return "涓嶈兘鍖呭惈闈炴硶瀛楃锛�< > \" ' \\\\ |"
           }
         },
       }).then(({ value }) => {
@@ -497,6 +570,26 @@
       const userId = row.userId;
       this.$router.push("/system/user-auth/role/" + userId);
     },
+    /** 绠$悊鍒嗗叕鍙搁厤缃叆鍙� */
+    handleManageBranch(row) {
+      const userId = row.userId;
+      this.branchDialog.userId = userId;
+      // 鍔犺浇鍒嗗叕鍙稿垪琛紙OA鑷姩鎺у埗锛屽彧璇诲睍绀猴級
+      listBranchByUser(userId).then(res => {
+        const list = res.data || [];
+        this.branchDialog.companies = (list || []).map(d => ({ deptId: d.deptId, deptName: d.deptName }));
+        this.branchDialog.open = true;
+      }).catch(() => {
+        this.$modal.msgError('鍔犺浇鍒嗗叕鍙搁厤缃け璐�');
+      });
+    },
+    /** 淇濆瓨鍒嗗叕鍙搁厤缃� */
+    // 宸插彇娑堜繚瀛橈紝OA鑷姩鎺у埗锛堜粎鍙灞曠ず锛�
+    // submitBranchCompanies() {
+    //   const userId = this.branchDialog.userId;
+    //   const deptIds = this.branchDialog.selectedDeptIds || [];
+    //   // 淇濈暀鍗犱綅锛岄伩鍏嶈璋冪敤
+    // },
     /** 鎻愪氦鎸夐挳 */
     submitForm: function() {
       this.$refs["form"].validate(valid => {
@@ -561,4 +654,4 @@
     }
   }
 };
-</script>
\ No newline at end of file
+</script>
diff --git a/ruoyi-ui/src/views/system/vehicle/index.vue b/ruoyi-ui/src/views/system/vehicle/index.vue
index ee37dd0..e1fdf89 100644
--- a/ruoyi-ui/src/views/system/vehicle/index.vue
+++ b/ruoyi-ui/src/views/system/vehicle/index.vue
@@ -118,13 +118,19 @@
           <dict-tag :options="dict.type.sys_platform" :value="scope.row.platformCode"/>
         </template>
       </el-table-column>
-      <el-table-column label="褰掑睘閮ㄩ棬" align="center" prop="deptName" />
+      <el-table-column label="褰掑睘鍒嗗叕鍙�" align="center" prop="deptNames" width="200">
+        <template slot-scope="scope">
+          <span v-if="scope.row.deptNames && scope.row.deptNames.length > 0">
+            {{ scope.row.deptNames.join('銆�') }}
+          </span>
+          <span v-else>-</span>
+        </template>
+      </el-table-column>
       <el-table-column label="鐘舵��" align="center" prop="status">
         <template slot-scope="scope">
           <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
         </template>
       </el-table-column>
-      <el-table-column label="褰掑睘閮ㄩ棬" align="center" prop="deptName" />
       <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180">
         <template slot-scope="scope">
           <span>{{ parseTime(scope.row.createTime) }}</span>
@@ -190,16 +196,6 @@
             />
           </el-select>
         </el-form-item>
-        <el-form-item label="褰掑睘閮ㄩ棬" prop="deptId">
-          <el-select v-model="form.deptId" placeholder="璇烽�夋嫨閮ㄩ棬" clearable>
-            <el-option
-              v-for="dept in deptOptions"
-              :key="dept.deptId"
-              :label="dept.deptName"
-              :value="dept.deptId"
-            />
-          </el-select>
-        </el-form-item>
         <el-form-item label="鐘舵��" prop="status">
           <el-radio-group v-model="form.status">
             <el-radio
@@ -209,8 +205,8 @@
             >{{dict.label}}</el-radio>
           </el-radio-group>
         </el-form-item>
-        <el-form-item label="褰掑睘閮ㄩ棬" prop="deptId">
-          <el-select v-model="form.deptId" placeholder="璇烽�夋嫨褰掑睘閮ㄩ棬" clearable style="width: 100%">
+        <el-form-item label="褰掑睘鍒嗗叕鍙�" prop="deptIds">
+          <el-select v-model="form.deptIds" placeholder="璇烽�夋嫨褰掑睘鍒嗗叕鍙�" multiple clearable style="width: 100%">
             <el-option
               v-for="dept in deptList"
               :key="dept.deptId"
@@ -282,7 +278,8 @@
         status: "0",
         remark: null,
         platformCode: null,
-        deptId: null
+        deptId: null,
+        deptIds: []  // 澶氫釜鍒嗗叕鍙窱D鏁扮粍
       },
       // 琛ㄥ崟鏍¢獙
       rules: {
@@ -295,8 +292,8 @@
         platformCode: [
           { required: true, message: "骞冲彴鏍囪瘑涓嶈兘涓虹┖", trigger: "change" }
         ],
-        deptId: [
-          { required: true, message: "褰掑睘閮ㄩ棬涓嶈兘涓虹┖", trigger: "change" }
+        deptIds: [
+          { required: true, message: "褰掑睘鍒嗗叕鍙镐笉鑳戒负绌�", trigger: "change", type: 'array' }
         ]
       }
     };
@@ -342,7 +339,8 @@
         status: "0",
         remark: null,
         platformCode: null,
-        deptId: null
+        deptId: null,
+        deptIds: []  // 閲嶇疆涓虹┖鏁扮粍
       };
       this.resetForm("form");
     },
@@ -374,6 +372,14 @@
       const vehicleId = row.vehicleId || this.ids
       getVehicle(vehicleId).then(response => {
         this.form = response.data;
+        // 濡傛灉娌℃湁deptIds锛屽垯浠� deptId 鍜� deptName 涓濉�
+        if (!this.form.deptIds || this.form.deptIds.length === 0) {
+          if (this.form.deptId) {
+            this.form.deptIds = [this.form.deptId];
+          } else {
+            this.form.deptIds = [];
+          }
+        }
         this.open = true;
         this.title = "淇敼杞﹁締淇℃伅";
       });
@@ -382,6 +388,11 @@
     submitForm() {
       this.$refs["form"].validate(valid => {
         if (valid) {
+          // 濡傛灉閫夋嫨浜嗗涓垎鍏徃锛屽皢绗竴涓缃负deptId锛堜富鍒嗗叕鍙革級
+          if (this.form.deptIds && this.form.deptIds.length > 0) {
+            this.form.deptId = this.form.deptIds[0];
+          }
+          
           if (this.form.vehicleId != null) {
             updateVehicle(this.form).then(response => {
               this.$modal.msgSuccess("淇敼鎴愬姛");
diff --git a/sql/vehicle_dept_relation.sql b/sql/vehicle_dept_relation.sql
new file mode 100644
index 0000000..0ffe09f
--- /dev/null
+++ b/sql/vehicle_dept_relation.sql
@@ -0,0 +1,17 @@
+-- 杞﹁締-鍒嗗叕鍙稿叧鑱旇〃
+-- 鐢ㄤ簬鏀寔涓�杈嗚溅褰掑睘澶氫釜鍒嗗叕鍙哥殑澶氬澶氬叧绯�
+
+CREATE TABLE IF NOT EXISTS `tb_vehicle_dept` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '鍏宠仈ID',
+  `vehicle_id` bigint(20) NOT NULL COMMENT '杞﹁締ID',
+  `dept_id` bigint(20) NOT NULL COMMENT '鍒嗗叕鍙窱D锛坧arent_id=100鐨勯儴闂級',
+  `order_class` varchar(50) DEFAULT NULL COMMENT '瀵瑰簲鐨勫垎鍏徃缂栫爜锛堝HB,TI绛夛級',
+  `create_by` varchar(64) DEFAULT '' COMMENT '鍒涘缓鑰�',
+  `create_time` datetime DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_by` varchar(64) DEFAULT '' COMMENT '鏇存柊鑰�',
+  `update_time` datetime DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `uk_vehicle_dept` (`vehicle_id`, `dept_id`),
+  KEY `idx_vehicle_id` (`vehicle_id`),
+  KEY `idx_dept_id` (`dept_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='杞﹁締-鍒嗗叕鍙稿叧鑱旇〃';

--
Gitblit v1.9.1