From 364adbc9a93a396b74e154f910c2a0a72bfb1a0f Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期六, 29 十一月 2025 22:10:41 +0800
Subject: [PATCH] feat: 更新车辆里程统计

---
 sql/dryad_payment_tables.sql                                                                      |    1 
 sql/gps_compensation_config.sql                                                                   |   15 
 app/pages.json                                                                                    |   85 ++-
 app/pagesTask/components/VehicleSelector.vue                                                      |    0 
 sql/fixes/fix_task_ratio_column.sql                                                               |   26 +
 ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CmsVehicleSyncTask.java                          |   74 ++
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/AdditionalFeeSyncServiceImpl.java        |    6 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleMileageStatsServiceImpl.java      |   21 +
 ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/VehicleGpsSegmentMileageTask.java                |   44 ++
 app/pagesTask/edit.vue                                                                            |    6 
 app/pagesTask/components/uni-section/uni-section.vue                                              |    0 
 ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml                                   |    2 
 sql/updates/add_segment_count_to_mileage_stats.sql                                                |    5 
 app/pagesTask/settlement.vue                                                                      |    0 
 sql/updates/add_task_id_to_segment_mileage.sql                                                    |    2 
 app/pagesTask/edit-emergency.vue                                                                  |   10 
 app/pagesTask/edit-welfare.vue                                                                    |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java                             |    4 
 app/pagesTask/create-welfare.vue                                                                  |    2 
 app/pages/task/create.vue                                                                         |    8 
 app/pagesTask/components/TaskTypeSelector.vue                                                     |    0 
 app/pagesTask/create-normal.vue                                                                   |    0 
 app/pages/index.vue                                                                               |    2 
 app/pagesTask/components/OrganizationSelector.vue                                                 |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleGpsSegmentMileageMapper.java            |    9 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleInfoServiceImpl.java              |   25 
 ruoyi-system/src/main/resources/mapper/system/VehicleMileageStatsMapper.xml                       |   10 
 sql/fixes/fix_duplicate_mileage_stats.sql                                                         |   35 +
 app/pagesTask/create-emergency.vue                                                                |   11 
 app/pages/message/index.vue                                                                       |    4 
 app/pagesTask/components/DepartureSelector.vue                                                    |  122 ++++-
 app/pagesTask/components/DiseaseSelector.vue                                                      |    0 
 app/pagesTask/components/AttachmentUpload.vue                                                     |    0 
 app/pages/task/index.vue                                                                          |    2 
 sql/resync_vehicle_personnel_job.sql                                                              |    2 
 ruoyi-admin/src/main/resources/application.yml                                                    |   12 
 app/pagesTask/components/map-selector.vue                                                         |    0 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTaskPaymentMapper.java                      |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleGpsSegmentMileageServiceImpl.java |  535 +++++++++++++++++-------
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTaskEmergencyMapper.java                    |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTaskMapper.java                             |    6 
 sql/fix_duplicate_vehicle_plates.sql                                                              |  101 ++++
 app/pagesTask/components/HospitalSelector.vue                                                     |    0 
 app/pagesTask/detail.vue                                                                          |   10 
 ruoyi-system/src/main/resources/mapper/system/VehicleInfoMapper.xml                               |    1 
 ruoyi-system/src/main/resources/mapper/system/VehicleGpsSegmentMileageMapper.xml                  |   11 
 46 files changed, 908 insertions(+), 315 deletions(-)

diff --git a/app/pages.json b/app/pages.json
index 8685365..bf309f7 100644
--- a/app/pages.json
+++ b/app/pages.json
@@ -101,51 +101,56 @@
       "navigationBarTitleText": "閫夋嫨浠诲姟绫诲瀷"
     }
   }, {
-    "path": "pages/task/create-normal",
-    "style": {
-      "navigationBarTitleText": "鍒涘缓鏅�氫换鍔�"
-    }
-  }, {
-    "path": "pages/task/create-emergency",
-    "style": {
-      "navigationBarTitleText": "鍒涘缓杞繍浠诲姟"
-    }
-  }, {
-    "path": "pages/task/create-welfare",
-    "style": {
-      "navigationBarTitleText": "鍒涘缓绂忕杞︿换鍔�"
-    }
-  }, {
-    "path": "pages/task/detail",
-    "style": {
-      "navigationBarTitleText": "浠诲姟璇︽儏"
-    }
-  }, {
-    "path": "pages/task/edit",
-    "style": {
-      "navigationBarTitleText": "缂栬緫浠诲姟"
-    }
-  }, {
-    "path": "pages/task/edit-emergency",
-    "style": {
-      "navigationBarTitleText": "缂栬緫杞繍浠诲姟"
-    }
-  }, {
-    "path": "pages/task/edit-welfare",
-    "style": {
-      "navigationBarTitleText": "缂栬緫绂忕杞︿换鍔�"
-    }
-  }, {
-    "path": "pages/task/settlement",
-    "style": {
-      "navigationBarTitleText": "浠诲姟缁撶畻"
-    }
-  }, {
     "path": "pages/message/index",
     "style": {
       "navigationBarTitleText": "娑堟伅涓績"
     }
   }],
+  "subPackages": [{
+    "root": "pagesTask",
+    "name": "task",
+    "pages": [{
+      "path": "create-normal",
+      "style": {
+        "navigationBarTitleText": "鍒涘缓鏅�氫换鍔�"
+      }
+    }, {
+      "path": "create-emergency",
+      "style": {
+        "navigationBarTitleText": "鍒涘缓杞繍浠诲姟"
+      }
+    }, {
+      "path": "create-welfare",
+      "style": {
+        "navigationBarTitleText": "鍒涘缓绂忕杞︿换鍔�"
+      }
+    }, {
+      "path": "detail",
+      "style": {
+        "navigationBarTitleText": "浠诲姟璇︽儏"
+      }
+    }, {
+      "path": "edit",
+      "style": {
+        "navigationBarTitleText": "缂栬緫浠诲姟"
+      }
+    }, {
+      "path": "edit-emergency",
+      "style": {
+        "navigationBarTitleText": "缂栬緫杞繍浠诲姟"
+      }
+    }, {
+      "path": "edit-welfare",
+      "style": {
+        "navigationBarTitleText": "缂栬緫绂忕杞︿换鍔�"
+      }
+    }, {
+      "path": "settlement",
+      "style": {
+        "navigationBarTitleText": "浠诲姟缁撶畻"
+      }
+    }]
+  }],
   "tabBar": {
     "color": "#000000",
     "selectedColor": "#000000",
diff --git a/app/pages/index.vue b/app/pages/index.vue
index 72efa8a..4df32d4 100644
--- a/app/pages/index.vue
+++ b/app/pages/index.vue
@@ -402,7 +402,7 @@
       // 鏌ョ湅浠诲姟璇︽儏
       viewTaskDetail(task) {
         // 璺宠浆鍒颁换鍔¤鎯呴〉闈� - 浣跨敤taskId
-        this.$tab.navigateTo(`/pages/task/detail?id=${task.taskId || task.id}`);
+        this.$tab.navigateTo(`/pagesTask/detail?id=${task.taskId || task.id}`);
       },
       
       // 澶勭悊浠诲姟鎿嶄綔
diff --git a/app/pages/message/index.vue b/app/pages/message/index.vue
index a35c92c..dd713e4 100644
--- a/app/pages/message/index.vue
+++ b/app/pages/message/index.vue
@@ -123,7 +123,7 @@
           
           // 璺宠浆鍒颁换鍔¤鎯呴〉闈�
           if (message.taskId) {
-            this.$tab.navigateTo(`/pages/task/detail?id=${message.taskId}`)
+            this.$tab.navigateTo(`/pagesTask/detail?id=${message.taskId}`)
           } else {
             this.$modal.showToast('鏃犳硶鎵惧埌鍏宠仈浠诲姟')
           }
@@ -131,7 +131,7 @@
           console.error('鏍囪娑堟伅宸茶澶辫触锛�', error)
           // 鍗充娇鏍囪澶辫触锛屼篃鍏佽璺宠浆
           if (message && message.taskId) {
-            this.$tab.navigateTo(`/pages/task/detail?id=${message.taskId}`)
+            this.$tab.navigateTo(`/pagesTask/detail?id=${message.taskId}`)
           }
         }
       },
diff --git a/app/pages/task/create.vue b/app/pages/task/create.vue
index 948f6af..23fa2dd 100644
--- a/app/pages/task/create.vue
+++ b/app/pages/task/create.vue
@@ -37,7 +37,7 @@
           color: '#E54D42',
           description: '绱ф�ュ尰鐤楄浆杩愪换鍔�',
           taskType: 'EMERGENCY_TRANSFER',
-          page: '/pages/task/create-emergency'
+          page: '/pagesTask/create-emergency'
         },
         {
           type: 'normal',
@@ -46,7 +46,7 @@
           color: '#007AFF',
           description: '璁惧缁翠慨銆佷繚鍏荤瓑鏃ュ父浠诲姟',
           taskType: 'MAINTENANCE',
-          page: '/pages/task/create-normal'
+          page: '/pagesTask/create-normal'
         },
         {
           type: 'normal',
@@ -55,7 +55,7 @@
           color: '#1AAD19',
           description: '杞﹁締鍔犳补绛変换鍔�',
           taskType: 'FUEL',
-          page: '/pages/task/create-normal'
+          page: '/pagesTask/create-normal'
         },
 
         {
@@ -65,7 +65,7 @@
           color: '#F37B1D',
           description: '鑰佸勾浜恒�佹畫鐤句汉绛夌壒娈婄兢浣撶敤杞︽湇鍔�',
           taskType: 'WELFARE',
-          page: '/pages/task/create-welfare'
+          page: '/pagesTask/create-welfare'
         }
       ]
     }
diff --git a/app/pages/task/index.vue b/app/pages/task/index.vue
index 0358e7f..99f61b6 100644
--- a/app/pages/task/index.vue
+++ b/app/pages/task/index.vue
@@ -456,7 +456,7 @@
         
         // 璺宠浆鍒颁换鍔¤鎯呴〉闈� - 浣跨敤uni.navigateTo
         uni.navigateTo({
-          url: `/pages/task/detail?id=${task.taskId}`
+          url: `/pagesTask/detail?id=${task.taskId}`
         });
       },
       
diff --git a/app/components/AttachmentUpload.vue b/app/pagesTask/components/AttachmentUpload.vue
similarity index 100%
rename from app/components/AttachmentUpload.vue
rename to app/pagesTask/components/AttachmentUpload.vue
diff --git a/app/components/DepartureSelector.vue b/app/pagesTask/components/DepartureSelector.vue
similarity index 77%
rename from app/components/DepartureSelector.vue
rename to app/pagesTask/components/DepartureSelector.vue
index b863f91..ac00b3c 100644
--- a/app/components/DepartureSelector.vue
+++ b/app/pagesTask/components/DepartureSelector.vue
@@ -26,7 +26,7 @@
         
         <view class="current-location-btn" @click="getCurrentLocation">
           <uni-icons type="location" size="20" color="#007AFF"></uni-icons>
-          <text>褰撳墠浣嶇疆</text>
+          
         </view>
       </view>
       
@@ -199,48 +199,68 @@
       this.showAddressSuggestions = false
       this.addressSuggestions = []
     },
-    
-    // 鑾峰彇褰撳墠浣嶇疆
-    getCurrentLocation() {
-      uni.showLoading({
-        title: '鑾峰彇浣嶇疆涓�...'
-      })
-      
-      // 浣跨敤uni-app鐨凣PS瀹氫綅鍔熻兘
-      uni.getLocation({
-        type: 'gcj02', // 杩斿洖鍥芥祴灞�鍧愭爣锛岄�傜敤浜庡浗鍐呭湴鍥�
-        success: (res) => {
-          console.log('鑾峰彇鍒癎PS鍧愭爣:', res)
-          const latitude = res.latitude
-          const longitude = res.longitude
-          
-          // 鏇存柊GPS鍧愭爣
-          this.$emit('update:longitude', longitude)
-          this.$emit('update:latitude', latitude)
-          
-          // 璋冪敤閫嗗湴鐞嗙紪鐮佹帴鍙o紝灏嗗潗鏍囪浆鎹负鍦板潃
+    geocoder(longitude, latitude){
+ // 璋冪敤閫嗗湴鐞嗙紪鐮佹帴鍙o紝灏嗗潗鏍囪浆鎹负鍦板潃
           reverseGeocoder(latitude, longitude)
             .then(response => {
               uni.hideLoading()
               
+              console.log('閫嗗湴鐞嗙紪鐮丄PI瀹屾暣鍝嶅簲:', JSON.stringify(response))
+              
               if (response.code === 200 && response.data) {
-                // 鑾峰彇璇︾粏鍦板潃
-                const address = response.data.address || response.data.formattedAddress || ''
+                // 瑙f瀽鍚庣杩斿洖鐨勬暟鎹�(鍙兘鏄瓧绗︿覆,闇�瑕乸arse)
+                let responseData = response.data
+                if (typeof responseData === 'string') {
+                  try {
+                    responseData = JSON.parse(responseData)
+                  } catch (e) {
+                    console.error('瑙f瀽鍝嶅簲鏁版嵁澶辫触:', e)
+                    responseData = {}
+                  }
+                }
                 
-                // 鏇存柊鍦板潃
-                this.$emit('update:address', address)
+                console.log('瑙f瀽鍚庣殑responseData:', responseData)
                 
-                // 瑙﹀彂浣嶇疆鑾峰彇鎴愬姛浜嬩欢
-                this.$emit('location-success', {
-                  address: address,
-                  longitude: longitude,
-                  latitude: latitude
-                })
+                // 鑵捐鍦板浘API杩斿洖鏍煎紡: {status: 0, result: {address: "..."}}
+                let address = ''
+                if (responseData.status === 0 && responseData.result) {
+                  address = responseData.result.address || responseData.result.formatted_addresses?.recommend || ''
+                } else if (responseData.address) {
+                  // 鍏煎鍏朵粬鍙兘鐨勮繑鍥炴牸寮�
+                  address = responseData.address
+                } else if (responseData.formattedAddress) {
+                  address = responseData.formattedAddress
+                }
                 
-                console.log('閫嗗湴鐞嗙紪鐮佹垚鍔�:', address)
-                this.$modal.showToast('宸茶幏鍙栧綋鍓嶄綅缃�')
+                console.log('瑙f瀽鍑虹殑鍦板潃:', address)
+                
+                if (address) {
+                  // 鏇存柊鍦板潃
+                  this.$emit('update:address', address)
+                  
+                  // 瑙﹀彂浣嶇疆鑾峰彇鎴愬姛浜嬩欢
+                  this.$emit('location-success', {
+                    address: address,
+                    longitude: longitude,
+                    latitude: latitude
+                  })
+                  
+                  console.log('閫嗗湴鐞嗙紪鐮佹垚鍔燂紝鍦板潃宸叉洿鏂�:', address)
+                  this.$modal.showToast('宸茶幏鍙栧綋鍓嶄綅缃�')
+                } else {
+                  console.error('鏈兘浠庡搷搴斾腑鎻愬彇鍦板潃,responseData:', responseData)
+                  
+                  // 鍗充娇鍦板潃瑙f瀽澶辫触锛屽潗鏍囧凡淇濆瓨锛岃Е鍙戜簨浠�
+                  this.$emit('location-success', {
+                    address: '',
+                    longitude: longitude,
+                    latitude: latitude
+                  })
+                  
+                  this.$modal.showToast('浣嶇疆瑙f瀽澶辫触锛岃鎵嬪姩杈撳叆鍦板潃')
+                }
               } else {
-                console.error('閫嗗湴鐞嗙紪鐮佸け璐�:', response.msg)
+                console.error('閫嗗湴鐞嗙紪鐮佸け璐ワ紝response.code:', response.code, 'msg:', response.msg)
                 
                 // 鍗充娇鍦板潃瑙f瀽澶辫触锛屽潗鏍囧凡淇濆瓨锛岃Е鍙戜簨浠�
                 this.$emit('location-success', {
@@ -265,11 +285,41 @@
               
               this.$modal.showToast('浣嶇疆瑙f瀽澶辫触锛屼絾GPS鍧愭爣宸蹭繚瀛�')
             })
+    },
+    // 鑾峰彇褰撳墠浣嶇疆
+    getCurrentLocation() {
+      uni.showLoading({
+        title: '鑾峰彇浣嶇疆涓�...'
+      })
+      
+      // 浣跨敤uni-app鐨凣PS瀹氫綅鍔熻兘
+      uni.getLocation({
+        type: 'gcj02', // 杩斿洖鍥芥祴灞�鍧愭爣锛岄�傜敤浜庡浗鍐呭湴鍥�
+        success: (res) => {
+          console.log('鑾峰彇鍒癎PS鍧愭爣:', res)
+          const latitude = res.latitude
+          const longitude = res.longitude
+          
+          // 鏇存柊GPS鍧愭爣
+          this.$emit('update:longitude', longitude)
+          this.$emit('update:latitude', latitude)
+          this.geocoder(longitude, latitude)
+         
         },
         fail: (err) => {
           uni.hideLoading()
           console.error('鑾峰彇浣嶇疆澶辫触:', err)
-          
+          //鎴戜滑浣跨敤榛樿鐨勫潗鏍囨潵澶勭悊
+          //23.20593,113.228998
+          const longitude = 113.228998
+          const latitude = 23.20593
+          this.$emit('location-success', {
+            address: '',
+            longitude: longitude,
+            latitude: latitude
+          })
+          this.geocoder(longitude, latitude)
+        
           // 鎻愮ず鐢ㄦ埛鍙兘鐨勫師鍥�
           let errorMsg = '鑾峰彇浣嶇疆澶辫触'
           if (err.errMsg && err.errMsg.includes('auth deny')) {
@@ -373,7 +423,7 @@
         background-color: #f0f7ff;
         border-radius: 10rpx;
         white-space: nowrap;
-        min-height: 70rpx;
+        min-height: 40rpx;
         
         &:active {
           background-color: #e0f0ff;
diff --git a/app/components/DiseaseSelector.vue b/app/pagesTask/components/DiseaseSelector.vue
similarity index 100%
rename from app/components/DiseaseSelector.vue
rename to app/pagesTask/components/DiseaseSelector.vue
diff --git a/app/components/HospitalSelector.vue b/app/pagesTask/components/HospitalSelector.vue
similarity index 100%
rename from app/components/HospitalSelector.vue
rename to app/pagesTask/components/HospitalSelector.vue
diff --git a/app/components/OrganizationSelector.vue b/app/pagesTask/components/OrganizationSelector.vue
similarity index 98%
rename from app/components/OrganizationSelector.vue
rename to app/pagesTask/components/OrganizationSelector.vue
index 531aaf9..4dd4a82 100644
--- a/app/components/OrganizationSelector.vue
+++ b/app/pagesTask/components/OrganizationSelector.vue
@@ -152,7 +152,7 @@
       if (organization) {
         // 鎻愬彇鍦板煙鍏抽敭璇嶏紙鍘婚櫎"鍒嗗叕鍙�"銆�"鎬诲叕鍙�"銆�"鎬婚儴"鍚庣紑锛�
         const region = organization.deptName.replace(/(鍒嗗叕鍙竱鎬诲叕鍙竱鎬婚儴)$/g, '').trim()
-        
+        // console.log('region', organization)
         this.$emit('input', organization.deptId)
         this.$emit('change', {
           deptId: organization.deptId,
diff --git a/app/components/TaskTypeSelector.vue b/app/pagesTask/components/TaskTypeSelector.vue
similarity index 100%
rename from app/components/TaskTypeSelector.vue
rename to app/pagesTask/components/TaskTypeSelector.vue
diff --git a/app/components/VehicleSelector.vue b/app/pagesTask/components/VehicleSelector.vue
similarity index 100%
rename from app/components/VehicleSelector.vue
rename to app/pagesTask/components/VehicleSelector.vue
diff --git a/app/components/map-selector.vue b/app/pagesTask/components/map-selector.vue
similarity index 100%
rename from app/components/map-selector.vue
rename to app/pagesTask/components/map-selector.vue
diff --git a/app/components/uni-section/uni-section.vue b/app/pagesTask/components/uni-section/uni-section.vue
similarity index 100%
rename from app/components/uni-section/uni-section.vue
rename to app/pagesTask/components/uni-section/uni-section.vue
diff --git a/app/pages/task/create-emergency.vue b/app/pagesTask/create-emergency.vue
similarity index 99%
rename from app/pages/task/create-emergency.vue
rename to app/pagesTask/create-emergency.vue
index 2a6c730..a6fde13 100644
--- a/app/pages/task/create-emergency.vue
+++ b/app/pagesTask/create-emergency.vue
@@ -96,7 +96,6 @@
           v-model="taskForm.transferTime" 
           type="datetime" 
           :placeholder="'璇烽�夋嫨杞繍鏃堕棿'"
-          class="form-input"
         />
       </view>
       
@@ -332,7 +331,7 @@
 import { addTask } from "@/api/task"
 import { listAvailableVehicles, getUserBoundVehicle } from "@/api/vehicle"
 import { searchHospitals, searchHospitalsByDeptRegion } from "@/api/hospital"
-import DepartureSelector from '@/components/DepartureSelector.vue'
+import DepartureSelector from './components/DepartureSelector.vue'
 import { calculateDistance, baiduDistanceByAddress, baiduPlaceSuggestion } from "@/api/map"
 import { listBranchUsers } from "@/api/system/user"
 import { searchIcd10 } from "@/api/icd10"
@@ -342,10 +341,10 @@
 import { getDicts } from "@/api/dict"
 import { getServiceOrdAreaTypes, getServiceOrderTypes, getHospitalDepartments } from "@/api/dictionary"
 import { listBranchCompany, getDept } from "@/api/system/dept"
-import MapSelector from '@/components/map-selector.vue'
-import OrganizationSelector from '@/components/OrganizationSelector.vue'
-import HospitalSelector from '@/components/HospitalSelector.vue'
-import DiseaseSelector from '@/components/DiseaseSelector.vue'
+import MapSelector from './components/map-selector.vue'
+import OrganizationSelector from './components/OrganizationSelector.vue'
+import HospitalSelector from './components/HospitalSelector.vue'
+import DiseaseSelector from './components/DiseaseSelector.vue'
 
 export default {
   components: {
diff --git a/app/pages/task/create-normal.vue b/app/pagesTask/create-normal.vue
similarity index 100%
rename from app/pages/task/create-normal.vue
rename to app/pagesTask/create-normal.vue
diff --git a/app/pages/task/create-welfare.vue b/app/pagesTask/create-welfare.vue
similarity index 99%
rename from app/pages/task/create-welfare.vue
rename to app/pagesTask/create-welfare.vue
index 9a5d4d9..096e089 100644
--- a/app/pages/task/create-welfare.vue
+++ b/app/pagesTask/create-welfare.vue
@@ -149,7 +149,7 @@
 import { addTask } from "@/api/task"
 import { listAvailableVehicles } from "@/api/vehicle"
 import { calculateDistance } from "@/api/map"
-import MapSelector from '@/components/map-selector.vue'
+import MapSelector from './components/map-selector.vue'
 
 export default {
   components: {
diff --git a/app/pages/task/detail.vue b/app/pagesTask/detail.vue
similarity index 99%
rename from app/pages/task/detail.vue
rename to app/pagesTask/detail.vue
index fcbd8d7..781b0d4 100644
--- a/app/pages/task/detail.vue
+++ b/app/pagesTask/detail.vue
@@ -414,7 +414,7 @@
   import { checkVehicleActiveTasks } from '@/api/task'
   import { getPaymentInfo } from '@/api/payment'
   import { formatDateTime } from '@/utils/common'
-  import AttachmentUpload from '@/components/AttachmentUpload.vue'
+  import AttachmentUpload from './components/AttachmentUpload.vue'
   
   export default {
     components: {
@@ -644,17 +644,17 @@
         if (taskType === 'EMERGENCY_TRANSFER') {
           // 杞繍浠诲姟锛氳烦杞埌杞繍浠诲姟缂栬緫椤甸潰
           uni.navigateTo({
-            url: `/pages/task/edit-emergency?id=${taskId}`
+            url: `/pagesTask/edit-emergency?id=${taskId}`
           })
         } else if (taskType === 'WELFARE') {
           // 绂忕杞︿换鍔★細璺宠浆鍒扮绁楄溅缂栬緫椤甸潰
           uni.navigateTo({
-            url: `/pages/task/edit-welfare?id=${taskId}`
+            url: `/pagesTask/edit-welfare?id=${taskId}`
           })
         } else {
           // 鍏朵粬浠诲姟锛氳烦杞埌閫氱敤浠诲姟缂栬緫椤甸潰
           uni.navigateTo({
-            url: `/pages/task/edit?id=${taskId}`
+            url: `/pagesTask/edit?id=${taskId}`
           })
         }
       },
@@ -688,7 +688,7 @@
       // 澶勭悊缁撶畻
       handleSettlement() {
         uni.navigateTo({
-          url: '/pages/task/settlement?taskId=' + this.taskId
+          url: '/pagesTask/settlement?taskId=' + this.taskId
         })
       },
       
diff --git a/app/pages/task/edit-emergency.vue b/app/pagesTask/edit-emergency.vue
similarity index 99%
rename from app/pages/task/edit-emergency.vue
rename to app/pagesTask/edit-emergency.vue
index 3aafe37..e23f4b5 100644
--- a/app/pages/task/edit-emergency.vue
+++ b/app/pagesTask/edit-emergency.vue
@@ -273,11 +273,11 @@
 import { listBranchUsers } from "@/api/system/user"
 import { baiduDistanceByAddress } from "@/api/map"
 import { calculateTransferPrice } from "@/api/price"
-import MapSelector from '@/components/map-selector.vue'
-import VehicleSelector from '@/components/VehicleSelector.vue'
-import OrganizationSelector from '@/components/OrganizationSelector.vue'
-import HospitalSelector from '@/components/HospitalSelector.vue'
-import DiseaseSelector from '@/components/DiseaseSelector.vue'
+import MapSelector from './components/map-selector.vue'
+import VehicleSelector from './components/VehicleSelector.vue'
+import OrganizationSelector from './components/OrganizationSelector.vue'
+import HospitalSelector from './components/HospitalSelector.vue'
+import DiseaseSelector from './components/DiseaseSelector.vue'
 import distanceCalculator from '@/mixins/distanceCalculator.js'
 
 export default {
diff --git a/app/pages/task/edit-welfare.vue b/app/pagesTask/edit-welfare.vue
similarity index 98%
rename from app/pages/task/edit-welfare.vue
rename to app/pagesTask/edit-welfare.vue
index 68c0684..22d9ea6 100644
--- a/app/pages/task/edit-welfare.vue
+++ b/app/pagesTask/edit-welfare.vue
@@ -152,8 +152,8 @@
 import uniDatetimePicker from '@/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue'
 import uniPopup from '@/uni_modules/uni-popup/components/uni-popup/uni-popup.vue'
 import { getTask, updateTask } from "@/api/task"
-import MapSelector from '@/components/map-selector.vue'
-import VehicleSelector from '@/components/VehicleSelector.vue'
+import MapSelector from './components/map-selector.vue'
+import VehicleSelector from './components/VehicleSelector.vue'
 import distanceCalculator from '@/mixins/distanceCalculator.js'
 
 export default {
diff --git a/app/pages/task/edit.vue b/app/pagesTask/edit.vue
similarity index 98%
rename from app/pages/task/edit.vue
rename to app/pagesTask/edit.vue
index 8d93d34..0404fc5 100644
--- a/app/pages/task/edit.vue
+++ b/app/pagesTask/edit.vue
@@ -131,9 +131,9 @@
 import uniDatetimePicker from '@/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue'
 import uniPopup from '@/uni_modules/uni-popup/components/uni-popup/uni-popup.vue'
 import { getTask, updateTask } from "@/api/task"
-import MapSelector from '@/components/map-selector.vue'
-import VehicleSelector from '@/components/VehicleSelector.vue'
-import TaskTypeSelector from '@/components/TaskTypeSelector.vue'
+import MapSelector from './components/map-selector.vue'
+import VehicleSelector from './components/VehicleSelector.vue'
+import TaskTypeSelector from './components/TaskTypeSelector.vue'
 import distanceCalculator from '@/mixins/distanceCalculator.js'
 
 export default {
diff --git a/app/pages/task/settlement.vue b/app/pagesTask/settlement.vue
similarity index 100%
rename from app/pages/task/settlement.vue
rename to app/pagesTask/settlement.vue
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index ce30935..121ba1d 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -137,6 +137,18 @@
 
 # GPS鏈嶅姟閰嶇疆
 gps:
+  mileage:
+    compensation:
+      days: 7
+    segment:
+    # 鍒嗘璁$畻鏃堕棿闂撮殧锛堝崟浣嶏細鍒嗛挓锛�
+      minutes: 5
+  calculate:
+  # 璁$畻鏂规硶锛屽彲閫夊�硷細haversine锛坔aversine鍏紡锛夈�乼ianditu锛堝ぉ鍦板浘锛�
+    method: haversine
+  # 鏄惁璺宠繃宸茬粡璁$畻鐨勭偣
+  skip:
+    calculated: true
   service:
     domain: https://gps51.com
     username: 鐜嬫煇浜�
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CmsVehicleSyncTask.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CmsVehicleSyncTask.java
index c5abe54..b55780a 100644
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CmsVehicleSyncTask.java
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CmsVehicleSyncTask.java
@@ -67,27 +67,61 @@
             List<String> onlyCms=cmsPlateNos.stream().filter(e->!notCmsVehicles.contains(e)).collect((Collectors.toList()));
 
             Integer syncCarCount=0;
-            response.getDevices().stream().filter(e->onlyCms.contains(this.getPlateNo(e.getVid()))).forEach(vehicle->{
-                String plateNo =this.getPlateNo(vehicle.getVid());
-
-                VehicleInfo vehicleInfo= vehicleInfoService.selectVehicleInfoByPlateNumber(plateNo);
-                if (vehicleInfo==null) {
-                    vehicleInfo = new VehicleInfo();
-                    vehicleInfo.setVehicleNo(plateNo);
-                    vehicleInfo.setDeviceId(vehicle.getDid());
-                    vehicleInfo.setPlatformCode("CMS");
-                    vehicleInfo.setStatus("0");
-                    vehicleInfoService.insertVehicleInfo(vehicleInfo);
+            for (CmsVehicleDeviceListResponse.CmsVehicleDevice vehicle : response.getDevices()) {
+                try {
+                    if (!onlyCms.contains(this.getPlateNo(vehicle.getVid()))) {
+                        continue;
+                    }
+                    
+                    String plateNo = this.getPlateNo(vehicle.getVid());
+                    
+                    // 浣跨敤閲嶈瘯鏈哄埗澶勭悊姝婚攣
+                    int maxRetries = 3;
+                    int retryCount = 0;
+                    boolean success = false;
+                    
+                    while (!success && retryCount < maxRetries) {
+                        try {
+                            // 鏌ヨ杞﹁締淇℃伅锛堜娇鐢ㄧ簿纭尮閰嶏級
+                            VehicleInfo vehicleInfo = vehicleInfoService.selectVehicleInfoByPlateNumber(plateNo);
+                            if (vehicleInfo == null) {
+                                // 鏂板杞﹁締
+                                vehicleInfo = new VehicleInfo();
+                                vehicleInfo.setVehicleNo(plateNo);
+                                vehicleInfo.setDeviceId(vehicle.getDid());
+                                vehicleInfo.setPlatformCode("CMS");
+                                vehicleInfo.setStatus("0");
+                                vehicleInfoService.insertVehicleInfo(vehicleInfo);
+                                syncCarCount++;
+                                log.info("鏂板CMS杞﹁締: {}", plateNo);
+                            } else {
+                                // 鏇存柊杞﹁締 - 浠呮洿鏂板繀瑕佸瓧娈�,閬垮厤瑙﹀彂鍏宠仈琛ㄦ搷浣�
+                                vehicleInfo.setDeviceId(vehicle.getDid());
+                                vehicleInfo.setPlatformCode("CMS");
+                                vehicleInfo.setStatus("0");
+                                vehicleInfo.setDeptIds(null); // 涓嶆洿鏂伴儴闂ㄥ叧鑱�,閬垮厤姝婚攣
+                                vehicleInfoService.updateVehicleInfo(vehicleInfo);
+                                syncCarCount++;
+                                log.debug("鏇存柊CMS杞﹁締: {}", plateNo);
+                            }
+                            success = true;
+                        } catch (org.springframework.dao.DeadlockLoserDataAccessException e) {
+                            retryCount++;
+                            if (retryCount < maxRetries) {
+                                log.warn("鍚屾杞﹁締 {} 閬囧埌姝婚攣,绗瑊}娆¢噸璇�", plateNo, retryCount);
+                                // 闅忔満绛夊緟50-200ms鍚庨噸璇�,閬垮厤澶氫釜绾跨▼鍚屾椂閲嶈瘯
+                                Thread.sleep(50 + (long)(Math.random() * 150));
+                            } else {
+                                log.error("鍚屾杞﹁締 {} 澶辫触: 姝婚攣閲嶈瘯{}娆″悗浠嶅け璐�", plateNo, maxRetries);
+                                throw e;
+                            }
+                        }
+                    }
+                } catch (Exception e) {
+                    log.error("鍚屾杞﹁締 {} 澶辫触: {}", vehicle.getVid(), e.getMessage());
+                    // 缁х画澶勭悊涓嬩竴涓溅杈�
                 }
-                else{
-                    vehicleInfo.setVehicleNo(plateNo);
-                    vehicleInfo.setDeviceId(vehicle.getDid());
-                    vehicleInfo.setPlatformCode("CMS");
-                    vehicleInfo.setStatus("0");
-                    vehicleInfoService.updateVehicleInfo(vehicleInfo);
-                }
-
-            });
+            }
 
 
 
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/VehicleGpsSegmentMileageTask.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/VehicleGpsSegmentMileageTask.java
index e1713ce..371896a 100644
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/VehicleGpsSegmentMileageTask.java
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/VehicleGpsSegmentMileageTask.java
@@ -2,6 +2,7 @@
 
 import java.util.Calendar;
 import java.util.Date;
+import javax.annotation.PostConstruct;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -22,6 +23,45 @@
     
     @Autowired
     private ISysConfigService configService;
+    
+    /**
+     * 鏈嶅姟鍚姩鏃舵墽琛岃ˉ鍋胯绠�
+     * 妫�鏌ユ渶杩�7澶╁唴鏈澶勭悊鐨凣PS鍧愭爣骞惰繘琛岃ˉ鍋胯绠�
+     */
+    @PostConstruct
+    public void init() {
+        // 鍚姩鍚庡欢杩熸墽琛岋紝閬垮厤褰卞搷鏈嶅姟鍚姩閫熷害
+        new Thread(() -> {
+            try {
+                // 寤惰繜30绉掑惎鍔紝纭繚鎵�鏈夋湇鍔″凡灏辩华
+                Thread.sleep(30000);
+                
+                logger.info("========== 寮�濮嬫墽琛孏PS鍒嗘閲岀▼琛ュ伩璁$畻 ==========");
+                
+                // 鑾峰彇閰嶇疆鐨勫洖婧ぉ鏁帮紝榛樿7澶�
+                int lookbackDays = 7;
+                String lookbackConfig = configService.selectConfigByKey("gps.mileage.compensation.days");
+                if (lookbackConfig != null && !lookbackConfig.isEmpty()) {
+                    try {
+                        lookbackDays = Integer.parseInt(lookbackConfig);
+                    } catch (NumberFormatException e) {
+                        logger.warn("琛ュ伩鍥炴函澶╂暟閰嶇疆閿欒锛屼娇鐢ㄩ粯璁ゅ��7澶�");
+                    }
+                }
+                
+                // 鎵ц琛ュ伩璁$畻
+                int successCount = segmentMileageService.compensateCalculation(lookbackDays);
+                
+                logger.info("========== GPS鍒嗘閲岀▼琛ュ伩璁$畻瀹屾垚 - 鎴愬姛澶勭悊 {} 杈嗚溅 ==========", successCount);
+                
+            } catch (InterruptedException e) {
+                logger.error("琛ュ伩璁$畻绾跨▼琚腑鏂�", e);
+                Thread.currentThread().interrupt();
+            } catch (Exception e) {
+                logger.error("GPS鍒嗘閲岀▼琛ュ伩璁$畻澶辫触", e);
+            }
+        }, "GPS-Compensation-Thread").start();
+    }
 
     /**
      * 璁$畻鏈�杩戜竴娈垫椂闂寸殑GPS鍒嗘閲岀▼
@@ -59,12 +99,14 @@
                 }
             }
             
-            // 璁$畻鏃堕棿鑼冨洿
+            // 璁$畻鏃堕棿鑼冨洿锛堝悜鍓嶅洖婧寚瀹氬垎閽熸暟锛�
             Calendar cal = Calendar.getInstance();
             Date endTime = cal.getTime();
             cal.add(Calendar.MINUTE, -minutes);
             Date startTime = cal.getTime();
             
+            // 娉ㄦ剰锛氭鏂规硶鍙绠楁渶杩戞椂闂存鐨勬暟鎹紝鍘嗗彶閬楁紡鏁版嵁鐢辫ˉ鍋挎満鍒跺鐞�
+            
             logger.info("寮�濮嬭绠桮PS鍒嗘閲岀▼ - 鏃堕棿鑼冨洿: {} 鍒� {}, 鏃堕棿娈甸棿闅�: {}鍒嗛挓", 
                        startTime, endTime, segmentMinutes);
             
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTaskEmergencyMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTaskEmergencyMapper.java
index 8684a38..b27cb02 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTaskEmergencyMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTaskEmergencyMapper.java
@@ -1,6 +1,9 @@
 package com.ruoyi.system.mapper;
 
 import java.util.List;
+
+import com.ruoyi.common.annotation.DataSource;
+import com.ruoyi.common.enums.DataSourceType;
 import org.apache.ibatis.annotations.Param;
 import com.ruoyi.system.domain.SysTaskEmergency;
 
@@ -10,6 +13,7 @@
  * @author ruoyi
  * @date 2024-01-16
  */
+@DataSource(DataSourceType.MASTER)
 public interface SysTaskEmergencyMapper {
     
     /**
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTaskMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTaskMapper.java
index a356c6a..deeda59 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTaskMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTaskMapper.java
@@ -1,6 +1,9 @@
 package com.ruoyi.system.mapper;
 
 import java.util.List;
+
+import com.ruoyi.common.annotation.DataSource;
+import com.ruoyi.common.enums.DataSourceType;
 import com.ruoyi.system.domain.SysTask;
 import com.ruoyi.system.domain.vo.TaskQueryVO;
 import com.ruoyi.system.domain.vo.TaskStatisticsVO;
@@ -11,6 +14,7 @@
  * @author ruoyi
  * @date 2024-01-15
  */
+@DataSource(DataSourceType.MASTER)
 public interface SysTaskMapper {
     
     /**
@@ -24,7 +28,7 @@
     /**
      * 鏌ヨ浠诲姟绠$悊鍒楄〃
      * 
-     * @param sysTask 浠诲姟绠$悊
+     * @param queryVO 浠诲姟绠$悊
      * @return 浠诲姟绠$悊闆嗗悎
      */
     public List<SysTask> selectSysTaskList(TaskQueryVO queryVO);
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTaskPaymentMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTaskPaymentMapper.java
index 8ac9c66..e8b6c70 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTaskPaymentMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTaskPaymentMapper.java
@@ -1,6 +1,9 @@
 package com.ruoyi.system.mapper;
 
 import java.util.List;
+
+import com.ruoyi.common.annotation.DataSource;
+import com.ruoyi.common.enums.DataSourceType;
 import com.ruoyi.system.domain.SysTaskPayment;
 import org.apache.ibatis.annotations.Param;
 
@@ -10,6 +13,7 @@
  * @author ruoyi
  * @date 2025-01-15
  */
+@DataSource(DataSourceType.MASTER)
 public interface SysTaskPaymentMapper {
     
     /**
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java
index e67ea91..05caeba 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java
@@ -1,6 +1,9 @@
 package com.ruoyi.system.mapper;
 
 import java.util.List;
+
+import com.ruoyi.common.annotation.DataSource;
+import com.ruoyi.common.enums.DataSourceType;
 import org.apache.ibatis.annotations.Param;
 import com.ruoyi.common.core.domain.entity.SysUser;
 
@@ -9,6 +12,7 @@
  * 
  * @author ruoyi
  */
+@DataSource(DataSourceType.MASTER)
 public interface SysUserMapper
 {
     /**
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleGpsSegmentMileageMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleGpsSegmentMileageMapper.java
index 57a4b75..3314f93 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleGpsSegmentMileageMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleGpsSegmentMileageMapper.java
@@ -75,4 +75,13 @@
      * 妫�鏌PS鐐规槸鍚﹀凡琚绠�
      */
     public Long selectGpsCalculatedSegmentId(@Param("gpsId") Long gpsId);
+    
+    /**
+     * 鏌ヨ杞﹁締鍦ㄦ寚瀹氭椂闂翠箣鍓嶆渶鍚庝竴涓凡澶勭悊鐨凣PS鍧愭爣ID
+     * @param vehicleId 杞﹁締ID
+     * @param beforeTime 鎴鏃堕棿锛堟煡璇㈡鏃堕棿涔嬪墠鐨勬渶鍚庝竴涓凡澶勭悊GPS鐐癸級
+     * @return GPS鍧愭爣ID锛屽鏋滄病鏈夊垯杩斿洖null
+     */
+    public Long selectLastCalculatedGpsId(@Param("vehicleId") Long vehicleId,
+                                           @Param("beforeTime") Date beforeTime);
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/AdditionalFeeSyncServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/AdditionalFeeSyncServiceImpl.java
index 2aaeef3..63f2f31 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/AdditionalFeeSyncServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/AdditionalFeeSyncServiceImpl.java
@@ -92,8 +92,6 @@
     }
     
     @Override
-    @Transactional
-    @DataSource(DataSourceType.SQLSERVER)
     public boolean syncAdditionalFeeToLegacy(Long feeId) {
         try {
             // 1. 鏌ヨ鏂扮郴缁熼檮鍔犺垂鐢ㄨ褰�
@@ -176,7 +174,6 @@
     }
     
     @Override
-    @Transactional
     public boolean syncAdditionalFeeFromLegacy(Long paidMoneyAddId) {
         try {
             // 1. 鏌ヨ鏃х郴缁烶aidMoney_Add璁板綍
@@ -278,8 +275,7 @@
         return successCount;
     }
     
-    @Override
-    @DataSource(DataSourceType.SQLSERVER)
+   @Override
     public int batchSyncAdditionalFeeFromLegacy(Integer hours) {
         int successCount = 0;
         try {
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleGpsSegmentMileageServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleGpsSegmentMileageServiceImpl.java
index 45fe76f..08beb40 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleGpsSegmentMileageServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleGpsSegmentMileageServiceImpl.java
@@ -129,7 +129,7 @@
     @Override
     public int compensateCalculation(int lookbackDays) {
         try {
-            // 璁$畻鏃堕棿鑼冨洿
+            // 璁$畻鏃堕棿鑼冨洿锛堝洖婧寚瀹氬ぉ鏁帮級
             Calendar cal = Calendar.getInstance();
             Date endTime = cal.getTime();
             cal.add(Calendar.DAY_OF_MONTH, -lookbackDays);
@@ -162,9 +162,30 @@
                     logger.info("杞﹁締 {} 鍙戠幇 {} 涓湭璁$畻鐨凣PS鐐癸紝寮�濮嬭ˉ鍋胯绠�...", 
                                vehicleId, uncalculatedGps.size());
                     
+                    // 鑾峰彇鏈绠桮PS鏁版嵁鐨勬椂闂磋寖鍥�
+                    Date uncalculatedStartTime = parseDateTime(uncalculatedGps.get(0).getCollectTime());
+                    Date uncalculatedEndTime = parseDateTime(uncalculatedGps.get(uncalculatedGps.size() - 1).getCollectTime());
+                    
+                    // 鏌ユ壘璇ユ椂闂存涔嬪墠鏈�鍚庝竴涓凡澶勭悊鐨凣PS鍧愭爣ID
+                    Long lastCalculatedGpsId = segmentMileageMapper.selectLastCalculatedGpsId(vehicleId, uncalculatedStartTime);
+                    
+                    if (lastCalculatedGpsId != null) {
+                        logger.info("杞﹁締 {} 鎵惧埌鏈�鍚庝竴涓凡澶勭悊鐨凣PS鐐笽D: {}锛屽皢涓庢湭澶勭悊鏁版嵁涓�璧疯绠�", vehicleId, lastCalculatedGpsId);
+                        
+                        // 灏嗘渶鍚庝竴涓凡澶勭悊鐨凣PS鐐瑰姞鍏ュ垪琛ㄥ墠闈紝浣滀负鍓嶇疆鐐�
+                        VehicleGps lastCalculatedGps = vehicleGpsMapper.selectVehicleGpsById(lastCalculatedGpsId);
+                        if (lastCalculatedGps != null) {
+                            uncalculatedGps.add(0, lastCalculatedGps); // 鎻掑叆鍒板垪琛ㄦ渶鍓嶉潰
+                            logger.info("宸插皢GPS鐐� {} 浣滀负鍓嶇疆鐐瑰姞鍏ヨ绠楀垪琛�", lastCalculatedGpsId);
+                        }
+                    } else {
+                        logger.info("杞﹁締 {} 娌℃湁鎵惧埌宸插鐞嗙殑鍓嶇疆 GPS鐐癸紝浠庣涓�涓湭澶勭悊鐐瑰紑濮嬭绠�", vehicleId);
+                    }
+                    
                     // 閲嶆柊璁$畻璇ヨ溅杈嗗湪璇ユ椂闂磋寖鍥寸殑鍒嗘閲岀▼
                     // 娉ㄦ剰锛氳繖閲屼細閲嶆柊璁$畻鏁翠釜鏃堕棿鑼冨洿锛岀‘淇濊竟缂樿妭鐐硅姝g‘澶勭悊
-                    int segmentCount = calculateVehicleSegmentMileage(vehicleId, startTime, endTime);
+                    int segmentCount = calculateVehicleSegmentMileageWithGpsList(
+                        vehicleId, uncalculatedGps, uncalculatedStartTime, uncalculatedEndTime);
                     
                     if (segmentCount > 0) {
                         successCount++;
@@ -188,21 +209,6 @@
     @Override
     public int calculateVehicleSegmentMileage(Long vehicleId, Date startTime, Date endTime) {
         try {
-            // 鑾峰彇閰嶇疆鐨勬椂闂撮棿闅旓紙鍒嗛挓锛�
-            int segmentMinutes = configService.selectConfigByKey("gps.mileage.segment.minutes") != null 
-                ? Integer.parseInt(configService.selectConfigByKey("gps.mileage.segment.minutes")) 
-                : 5;
-            
-            // 鑾峰彇璁$畻鏂瑰紡閰嶇疆
-            String calculateMethod = configService.selectConfigByKey("gps.mileage.calculate.method");
-            if (calculateMethod == null || calculateMethod.isEmpty()) {
-                calculateMethod = "tianditu";
-            }
-            
-            // 鑾峰彇鏄惁璺宠繃宸茶绠桮PS鐐圭殑閰嶇疆
-            String skipCalculatedConfig = configService.selectConfigByKey("gps.mileage.skip.calculated");
-            boolean skipCalculated = skipCalculatedConfig == null || "true".equalsIgnoreCase(skipCalculatedConfig);
-            
             // 鏌ヨ杞﹁締鍦ㄦ椂闂磋寖鍥村唴鐨凣PS鏁版嵁
             List<VehicleGps> gpsList = vehicleGpsMapper.selectGpsDataByTimeRange(vehicleId, startTime, endTime);
             
@@ -211,153 +217,47 @@
                 return 0;
             }
             
-            logger.info("杞﹁締ID: {} 鏌ヨ鍒� {} 鏉PS鏁版嵁", vehicleId, gpsList.size());
+            logger.info("杞﹁締ID: {} 鏌ヨ鍒� {} 鏉PS鏁版嵁 startTime:{},endTime:{}", vehicleId, gpsList.size(),startTime,endTime);
+            
+            return calculateVehicleSegmentMileageWithGpsList(vehicleId, gpsList, startTime, endTime);
+            
+        } catch (Exception e) {
+            logger.error("璁$畻杞﹁締 {} 鍒嗘閲岀▼澶辫触", vehicleId, e);
+            throw new RuntimeException("璁$畻鍒嗘閲岀▼澶辫触: " + e.getMessage());
+        }
+    }
+    
+    /**
+     * 鏍规嵁鎻愪緵鐨凣PS鍒楄〃璁$畻杞﹁締鍒嗘閲岀▼
+     * @param vehicleId 杞﹁締ID
+     * @param gpsList GPS鍒楄〃锛堝凡鎸夋椂闂存帓搴忥級
+     * @param startTime 璧峰鏃堕棿
+     * @param endTime 缁撴潫鏃堕棿
+     * @return 鐢熸垚鐨勫垎娈垫暟閲�
+     */
+    private int calculateVehicleSegmentMileageWithGpsList(Long vehicleId, List<VehicleGps> gpsList, 
+                                                           Date startTime, Date endTime) {
+        try {
+            // 楠岃瘉杈撳叆鏁版嵁
+            if (gpsList == null || gpsList.isEmpty()) {
+                logger.debug("杞﹁締ID: {} 鍦ㄦ椂闂磋寖鍥� {} 鍒� {} 鍐呮棤GPS鏁版嵁", vehicleId, startTime, endTime);
+                return 0;
+            }
+            
+            // 鍔犺浇閰嶇疆鍙傛暟
+            MileageCalculationConfig config = loadMileageCalculationConfig();
             
             // 鎸夋椂闂存鍒嗙粍GPS鏁版嵁
-            Map<Date, List<VehicleGps>> segmentedData = segmentGpsDataByTime(gpsList, segmentMinutes);
+            Map<Date, List<VehicleGps>> segmentedData = segmentGpsDataByTime(gpsList, config.segmentMinutes);
             
-            int savedCount = 0;
-            VehicleGps previousSegmentLastPoint = null; // 璁板綍涓婁竴涓椂闂存鐨勬渶鍚庝竴涓偣
-            
-            // 閬嶅巻姣忎釜鏃堕棿娈碉紝璁$畻閲岀▼
-            for (Map.Entry<Date, List<VehicleGps>> entry : segmentedData.entrySet()) {
-                Date segmentStartTime = entry.getKey();
-                List<VehicleGps> segmentGpsList = entry.getValue();
-                
-                if (segmentGpsList.size() < 2) {
-                    // 濡傛灉鏈鍙湁1涓偣锛屼絾鏈変笂涓�娈电殑鏈�鍚庝竴涓偣锛屼粛鍙绠楄法娈佃窛绂�
-                    if (segmentGpsList.size() == 1 && previousSegmentLastPoint != null) {
-                        // 淇濈暀褰撳墠鐐逛綔涓轰笅涓�娈电殑鍓嶇疆鐐癸紝浣嗕笉鍒涘缓璁板綍
-                        previousSegmentLastPoint = segmentGpsList.get(0);
-                    }
-                    continue; // 鑷冲皯闇�瑕�2涓偣鎵嶈兘璁$畻璺濈
-                }
-                
-                // 妫�鏌ユ槸鍚﹀凡瀛樺湪璇ユ椂闂存鐨勮褰�
-                VehicleGpsSegmentMileage existing = segmentMileageMapper.selectByVehicleIdAndTime(vehicleId, segmentStartTime);
-                if (existing != null) {
-                    logger.debug("杞﹁締 {} 鏃堕棿娈� {} 鐨勫垎娈甸噷绋嬪凡瀛樺湪锛岃烦杩�", vehicleId, segmentStartTime);
-                    // 鏇存柊涓婁竴娈垫渶鍚庝竴涓偣
-                    previousSegmentLastPoint = segmentGpsList.get(segmentGpsList.size() - 1);
-                    continue;
-                }
-                
-                // 璁$畻鏃堕棿娈电殑缁撴潫鏃堕棿
-                Calendar cal = Calendar.getInstance();
-                cal.setTime(segmentStartTime);
-                cal.add(Calendar.MINUTE, segmentMinutes);
-                Date segmentEndTime = cal.getTime();
-                
-                // 璁$畻璇ユ椂闂存鐨勯噷绋嬶紙鍖呮嫭璺ㄦ璺濈锛�
-                BigDecimal distance = calculateSegmentDistanceWithGap(segmentGpsList, calculateMethod, previousSegmentLastPoint);
-                
-                // 鏀堕泦GPS ID鍒楄〃锛堝寘鎷笂涓�娈电殑鏈�鍚庝竴涓偣锛屽洜涓鸿法娈甸棿闅欒窛绂讳篃鐢ㄥ埌浜嗗畠锛�
-                List<Long> gpsIdList = new ArrayList<>();
-                // 濡傛灉鏈変笂涓�娈电殑鏈�鍚庝竴涓偣锛屽厛娣诲姞瀹冪殑ID
-                if (previousSegmentLastPoint != null && previousSegmentLastPoint.getGpsId() != null) {
-                    gpsIdList.add(previousSegmentLastPoint.getGpsId());
-                }
-                // 鍐嶆坊鍔犲綋鍓嶆鐨勬墍鏈塆PS鐐笽D
-                for (VehicleGps gps : segmentGpsList) {
-                    if (gps.getGpsId() != null) {
-                        gpsIdList.add(gps.getGpsId());
-                    }
-                }
-                String gpsIds = gpsIdList.stream()
-                    .map(String::valueOf)
-                    .collect(java.util.stream.Collectors.joining(","));
-                
-                // 鍒涘缓鍒嗘閲岀▼璁板綍
-                VehicleGpsSegmentMileage segment = new VehicleGpsSegmentMileage();
-                segment.setVehicleId(vehicleId);
-                
-                // 浠嶨PS鏁版嵁鎴栬溅杈嗚〃鑾峰彇杞︾墝鍙�
-                String vehicleNo = segmentGpsList.get(0).getVehicleNo();
-                if (vehicleNo == null || vehicleNo.trim().isEmpty()) {
-                    // GPS鏁版嵁涓病鏈夎溅鐗屽彿锛屼粠杞﹁締琛ㄦ煡璇�
-                    VehicleInfo vehicleInfo = vehicleInfoMapper.selectVehicleInfoById(vehicleId);
-                    if (vehicleInfo != null) {
-                        vehicleNo = vehicleInfo.getVehicleNo();
-                    }
-                }
-                segment.setVehicleNo(vehicleNo);
-                
-                segment.setSegmentStartTime(segmentStartTime);
-                segment.setSegmentEndTime(segmentEndTime);
-                
-                // 璧风偣鍧愭爣
-                VehicleGps firstPoint = segmentGpsList.get(0);
-                segment.setStartLongitude(BigDecimal.valueOf(firstPoint.getLongitude()));
-                segment.setStartLatitude(BigDecimal.valueOf(firstPoint.getLatitude()));
-                
-                // 缁堢偣鍧愭爣
-                VehicleGps lastPoint = segmentGpsList.get(segmentGpsList.size() - 1);
-                segment.setEndLongitude(BigDecimal.valueOf(lastPoint.getLongitude()));
-                segment.setEndLatitude(BigDecimal.valueOf(lastPoint.getLatitude()));
-                
-                segment.setSegmentDistance(distance);
-                segment.setGpsPointCount(gpsIdList.size()); // GPS鐐规暟锛氬寘鎷竟缂樼偣 + 褰撳墠娈电殑鐐�
-                segment.setGpsIds(gpsIds); // 璁剧疆GPS ID鍒楄〃
-                segment.setCalculateMethod(calculateMethod);
-                
-                // 鏌ヨ骞跺叧鑱旀鍦ㄦ墽琛岀殑浠诲姟
-                associateActiveTask(segment, vehicleId, segmentStartTime, segmentEndTime);
-                
-                // 淇濆瓨鍒版暟鎹簱
-                segmentMileageMapper.insertVehicleGpsSegmentMileage(segment);
-                
-                // 鏇存柊涓婁竴娈垫渶鍚庝竴涓偣锛屼緵涓嬩竴娈典娇鐢�
-                previousSegmentLastPoint = segmentGpsList.get(segmentGpsList.size() - 1);
-                
-                // 璁板綍宸茶绠楃殑GPS鐐瑰埌鐘舵�佽〃锛堝鏋滃紑鍚簡閲嶅璁$畻鎺у埗锛�
-                if (skipCalculated && segment.getSegmentId() != null) {
-                    for (Long gpsId : gpsIdList) {
-                        try {
-                            segmentMileageMapper.insertGpsCalculated(gpsId, segment.getSegmentId(), vehicleId);
-                        } catch (Exception e) {
-                            // 蹇界暐閲嶅閿紓甯革紝缁х画澶勭悊
-                            logger.debug("璁板綍GPS璁$畻鐘舵�佸け璐ワ紝鍙兘宸插瓨鍦�: gpsId={}", gpsId);
-                        }
-                    }
-                }
-                
-                savedCount++;
-                
-                logger.debug("杞﹁締 {} 鏃堕棿娈� {} 鍒� {} 閲岀▼: {}km, GPS鐐规暟: {}, GPS IDs: {}", 
-                           vehicleId, segmentStartTime, segmentEndTime, distance, segmentGpsList.size(), 
-                           gpsIds.length() > 50 ? gpsIds.substring(0, 50) + "..." : gpsIds);
-            }
+            // 澶勭悊姣忎釜鏃堕棿娈靛苟璁$畻閲岀▼
+            int savedCount = processSegmentedGpsData(vehicleId, segmentedData, config);
             
             logger.info("杞﹁締 {} 璁$畻瀹屾垚锛屼繚瀛樹簡 {} 涓椂闂存鐨勯噷绋嬫暟鎹�", vehicleId, savedCount);
             
-            // 鑷姩瑙﹀彂姹囨�荤敓鎴愭瘡鏃ョ粺璁★紙濡傛灉鏈夋暟鎹淇濆瓨锛�
+            // 鑷姩瑙﹀彂姣忔棩缁熻姹囨��
             if (savedCount > 0) {
-                try {
-                    // 鑾峰彇娑夊強鐨勬棩鏈熻寖鍥达紝瑙﹀彂姹囨��
-                    Set<Date> affectedDates = new HashSet<>();
-                    Calendar cal = Calendar.getInstance();
-                    
-                    for (Map.Entry<Date, List<VehicleGps>> entry : segmentedData.entrySet()) {
-                        cal.setTime(entry.getKey());
-                        cal.set(Calendar.HOUR_OF_DAY, 0);
-                        cal.set(Calendar.MINUTE, 0);
-                        cal.set(Calendar.SECOND, 0);
-                        cal.set(Calendar.MILLISECOND, 0);
-                        affectedDates.add(cal.getTime());
-                    }
-                    
-                    // 瀵规瘡涓秹鍙婄殑鏃ユ湡锛岃Е鍙戞眹鎬�
-                    for (Date statDate : affectedDates) {
-                        try {
-                            mileageStatsService.aggregateFromSegmentMileage(vehicleId, statDate);
-                            logger.info("杞﹁締 {} 鏃ユ湡 {} 鐨勭粺璁℃暟鎹凡鑷姩姹囨�荤敓鎴�", vehicleId, statDate);
-                        } catch (Exception e) {
-                            logger.error("杞﹁締 {} 鏃ユ湡 {} 鑷姩姹囨�荤粺璁″け璐�", vehicleId, statDate, e);
-                        }
-                    }
-                } catch (Exception e) {
-                    logger.error("瑙﹀彂鑷姩姹囨�诲け璐�", e);
-                }
+                triggerDailyMileageAggregation(vehicleId, segmentedData);
             }
             
             return savedCount;
@@ -366,6 +266,305 @@
             logger.error("璁$畻杞﹁締 {} 鍒嗘閲岀▼澶辫触", vehicleId, e);
             throw new RuntimeException("璁$畻鍒嗘閲岀▼澶辫触: " + e.getMessage());
         }
+    }
+    
+    /**
+     * 鍔犺浇閲岀▼璁$畻閰嶇疆鍙傛暟
+     */
+    private MileageCalculationConfig loadMileageCalculationConfig() {
+        MileageCalculationConfig config = new MileageCalculationConfig();
+        
+        // 鑾峰彇鏃堕棿闂撮殧閰嶇疆锛堝垎閽燂級
+        config.segmentMinutes = configService.selectConfigByKey("gps.mileage.segment.minutes") != null 
+            ? Integer.parseInt(configService.selectConfigByKey("gps.mileage.segment.minutes")) 
+            : 5;
+        
+        // 鑾峰彇璁$畻鏂瑰紡閰嶇疆
+        config.calculateMethod = configService.selectConfigByKey("gps.mileage.calculate.method");
+        if (config.calculateMethod == null || config.calculateMethod.isEmpty()) {
+            config.calculateMethod = "tianditu";
+        }
+        
+        // 鑾峰彇鏄惁璺宠繃宸茶绠桮PS鐐圭殑閰嶇疆
+        String skipCalculatedConfig = configService.selectConfigByKey("gps.mileage.skip.calculated");
+        config.skipCalculated = skipCalculatedConfig == null || "true".equalsIgnoreCase(skipCalculatedConfig);
+        logger.info("鎺у埗璺宠繃閲嶅璁$畻鏍囪瘑: {}", config.skipCalculated);
+        
+        return config;
+    }
+    
+    /**
+     * 澶勭悊鍒嗘鍚庣殑GPS鏁版嵁骞惰绠楅噷绋�
+     * @param vehicleId 杞﹁締ID
+     * @param segmentedData 鍒嗘鍚庣殑GPS鏁版嵁
+     * @param config 璁$畻閰嶇疆
+     * @return 鎴愬姛淇濆瓨鐨勫垎娈垫暟閲�
+     */
+    private int processSegmentedGpsData(Long vehicleId, Map<Date, List<VehicleGps>> segmentedData, 
+                                         MileageCalculationConfig config) {
+        int savedCount = 0;
+        VehicleGps previousSegmentLastPoint = null; // 璁板綍涓婁竴涓椂闂存鐨勬渶鍚庝竴涓偣
+        
+        // 閬嶅巻姣忎釜鏃堕棿娈碉紝璁$畻閲岀▼
+        for (Map.Entry<Date, List<VehicleGps>> entry : segmentedData.entrySet()) {
+            Date segmentStartTime = entry.getKey();
+            List<VehicleGps> segmentGpsList = entry.getValue();
+            
+            // 鏍¢獙褰撳墠鏃堕棿娈垫暟鎹�
+            if (!isSegmentValidForCalculation(segmentGpsList, previousSegmentLastPoint, vehicleId, segmentStartTime)) {
+                // 淇濈暀褰撳墠鐐逛綔涓轰笅涓�娈电殑鍓嶇疆鐐癸紙濡傛灉鏈夌殑璇濓級
+                if (!segmentGpsList.isEmpty()) {
+                    previousSegmentLastPoint = segmentGpsList.get(0);
+                }
+                continue;
+            }
+            
+            // 妫�鏌ユ槸鍚﹀凡瀛樺湪璇ユ椂闂存鐨勮褰�
+            if (isSegmentAlreadyCalculated(vehicleId, segmentStartTime, segmentGpsList)) {
+                previousSegmentLastPoint = segmentGpsList.get(segmentGpsList.size() - 1);
+                continue;
+            }
+            
+            // 璁$畻骞朵繚瀛樺垎娈甸噷绋�
+            boolean success = calculateAndSaveSegment(vehicleId, segmentStartTime, segmentGpsList, 
+                                                       previousSegmentLastPoint, config);
+            if (success) {
+                savedCount++;
+            }
+            
+            // 鏇存柊涓婁竴娈垫渶鍚庝竴涓偣锛屼緵涓嬩竴娈典娇鐢�
+            previousSegmentLastPoint = segmentGpsList.get(segmentGpsList.size() - 1);
+        }
+        
+        return savedCount;
+    }
+    
+    /**
+     * 鏍¢獙鏃堕棿娈垫暟鎹槸鍚︽湁鏁�
+     */
+    private boolean isSegmentValidForCalculation(List<VehicleGps> segmentGpsList, 
+                                                  VehicleGps previousSegmentLastPoint,
+                                                  Long vehicleId, Date segmentStartTime) {
+        // 濡傛灉褰撳墠娈垫病鏈塆PS鐐癸紝璺宠繃
+        if (segmentGpsList == null || segmentGpsList.isEmpty()) {
+            return false;
+        }
+        
+        // 濡傛灉鏈鍙湁1涓偣锛屼笖娌℃湁涓婁竴娈电殑鏈�鍚庝竴涓偣锛屾棤娉曡绠楄窛绂�
+        if (segmentGpsList.size() == 1 && previousSegmentLastPoint == null) {
+            logger.debug("杞﹁締 {} 鏃堕棿娈� {} 鍙湁1涓狦PS鐐逛笖鏃犲墠缃偣锛屾殏瀛樺緟涓嬩竴娈佃绠�", vehicleId, segmentStartTime);
+            return false;
+        }
+        
+        return true;
+    }
+    
+    /**
+     * 妫�鏌ユ椂闂存鏄惁宸茶璁$畻
+     */
+    private boolean isSegmentAlreadyCalculated(Long vehicleId, Date segmentStartTime, List<VehicleGps> segmentGpsList) {
+        VehicleGpsSegmentMileage existing = segmentMileageMapper.selectByVehicleIdAndTime(vehicleId, segmentStartTime);
+        if (existing != null) {
+            logger.debug("杞﹁締 {} 鏃堕棿娈� {} 鐨勫垎娈甸噷绋嬪凡瀛樺湪锛岃烦杩�", vehicleId, segmentStartTime);
+            return true;
+        }
+        return false;
+    }
+    
+    /**
+     * 璁$畻骞朵繚瀛樺崟涓椂闂存鐨勯噷绋�
+     */
+    private boolean calculateAndSaveSegment(Long vehicleId, Date segmentStartTime, 
+                                             List<VehicleGps> segmentGpsList,
+                                             VehicleGps previousSegmentLastPoint,
+                                             MileageCalculationConfig config) {
+        try {
+            // 璁$畻鏃堕棿娈电殑缁撴潫鏃堕棿
+            Date segmentEndTime = calculateSegmentEndTime(segmentStartTime, config.segmentMinutes);
+            
+            // 璁$畻璇ユ椂闂存鐨勯噷绋嬶紙鍖呮嫭璺ㄦ璺濈锛�
+            BigDecimal distance = calculateSegmentDistanceWithGap(segmentGpsList, config.calculateMethod, previousSegmentLastPoint);
+            
+            // 鏀堕泦GPS ID鍒楄〃
+            List<Long> gpsIdList = collectGpsIds(segmentGpsList, previousSegmentLastPoint);
+            String gpsIds = gpsIdList.stream()
+                .map(String::valueOf)
+                .collect(java.util.stream.Collectors.joining(","));
+            
+            // 鍒涘缓鍒嗘閲岀▼璁板綍
+            VehicleGpsSegmentMileage segment = buildSegmentMileageRecord(
+                vehicleId, segmentStartTime, segmentEndTime, segmentGpsList, 
+                distance, gpsIdList, gpsIds, config.calculateMethod);
+            
+            // 淇濆瓨鍒版暟鎹簱
+            logger.info("淇濆瓨杞﹁締鍒嗘椂娈甸噷绋嬪埌鏁版嵁搴撲腑,杞﹁締ID: {}, 鏃堕棿娈�: {} 鍒� {}", vehicleId, segmentStartTime, segmentEndTime);
+            segmentMileageMapper.insertVehicleGpsSegmentMileage(segment);
+            
+            // 璁板綍宸茶绠楃殑GPS鐐癸紙濡傛灉寮�鍚簡閲嶅璁$畻鎺у埗锛�
+            if (config.skipCalculated && segment.getSegmentId() != null) {
+                recordCalculatedGpsPoints(gpsIdList, segment.getSegmentId(), vehicleId);
+            }
+            
+            logger.debug("杞﹁締 {} 鏃堕棿娈� {} 鍒� {} 閲岀▼: {}km, GPS鐐规暟: {}, GPS IDs: {}", 
+                       vehicleId, segmentStartTime, segmentEndTime, distance, segmentGpsList.size(), 
+                       gpsIds.length() > 50 ? gpsIds.substring(0, 50) + "..." : gpsIds);
+            
+            return true;
+            
+        } catch (Exception e) {
+            logger.error("淇濆瓨杞﹁締 {} 鏃堕棿娈� {} 鐨勯噷绋嬭褰曞け璐�", vehicleId, segmentStartTime, e);
+            return false;
+        }
+    }
+    
+    /**
+     * 璁$畻鏃堕棿娈电粨鏉熸椂闂�
+     */
+    private Date calculateSegmentEndTime(Date segmentStartTime, int segmentMinutes) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(segmentStartTime);
+        cal.add(Calendar.MINUTE, segmentMinutes);
+        return cal.getTime();
+    }
+    
+    /**
+     * 鏀堕泦GPS ID鍒楄〃锛堝寘鎷墠缃偣锛�
+     */
+    private List<Long> collectGpsIds(List<VehicleGps> segmentGpsList, VehicleGps previousSegmentLastPoint) {
+        List<Long> gpsIdList = new ArrayList<>();
+        
+        // 濡傛灉鏈変笂涓�娈电殑鏈�鍚庝竴涓偣锛屽厛娣诲姞瀹冪殑ID锛堢敤浜庤绠楄法娈佃窛绂伙級
+        if (previousSegmentLastPoint != null && previousSegmentLastPoint.getGpsId() != null) {
+            gpsIdList.add(previousSegmentLastPoint.getGpsId());
+        }
+        
+        // 鍐嶆坊鍔犲綋鍓嶆鐨勬墍鏈塆PS鐐笽D
+        for (VehicleGps gps : segmentGpsList) {
+            if (gps.getGpsId() != null) {
+                gpsIdList.add(gps.getGpsId());
+            }
+        }
+        
+        return gpsIdList;
+    }
+    
+    /**
+     * 鏋勫缓鍒嗘閲岀▼璁板綍瀵硅薄
+     */
+    private VehicleGpsSegmentMileage buildSegmentMileageRecord(Long vehicleId, Date segmentStartTime, 
+                                                                 Date segmentEndTime, List<VehicleGps> segmentGpsList,
+                                                                 BigDecimal distance, List<Long> gpsIdList, 
+                                                                 String gpsIds, String calculateMethod) {
+        VehicleGpsSegmentMileage segment = new VehicleGpsSegmentMileage();
+        segment.setVehicleId(vehicleId);
+        
+        // 鑾峰彇杞︾墝鍙�
+        String vehicleNo = getVehicleNo(vehicleId, segmentGpsList.get(0));
+        segment.setVehicleNo(vehicleNo);
+        
+        // 璁剧疆鏃堕棿鑼冨洿
+        segment.setSegmentStartTime(segmentStartTime);
+        segment.setSegmentEndTime(segmentEndTime);
+        
+        // 璁剧疆璧风偣鍧愭爣
+        VehicleGps firstPoint = segmentGpsList.get(0);
+        segment.setStartLongitude(BigDecimal.valueOf(firstPoint.getLongitude()));
+        segment.setStartLatitude(BigDecimal.valueOf(firstPoint.getLatitude()));
+        
+        // 璁剧疆缁堢偣鍧愭爣
+        VehicleGps lastPoint = segmentGpsList.get(segmentGpsList.size() - 1);
+        segment.setEndLongitude(BigDecimal.valueOf(lastPoint.getLongitude()));
+        segment.setEndLatitude(BigDecimal.valueOf(lastPoint.getLatitude()));
+        
+        // 璁剧疆閲岀▼鏁版嵁
+        segment.setSegmentDistance(distance);
+        segment.setGpsPointCount(gpsIdList.size());
+        segment.setGpsIds(gpsIds);
+        segment.setCalculateMethod(calculateMethod);
+        
+        // 鏌ヨ骞跺叧鑱旀鍦ㄦ墽琛岀殑浠诲姟
+        associateActiveTask(segment, vehicleId, segmentStartTime, segmentEndTime);
+        
+        return segment;
+    }
+    
+    /**
+     * 鑾峰彇杞︾墝鍙�
+     */
+    private String getVehicleNo(Long vehicleId, VehicleGps firstGps) {
+        String vehicleNo = firstGps.getVehicleNo();
+        if (vehicleNo == null || vehicleNo.trim().isEmpty()) {
+            // GPS鏁版嵁涓病鏈夎溅鐗屽彿锛屼粠杞﹁締琛ㄦ煡璇�
+            VehicleInfo vehicleInfo = vehicleInfoMapper.selectVehicleInfoById(vehicleId);
+            if (vehicleInfo != null) {
+                vehicleNo = vehicleInfo.getVehicleNo();
+            }
+        }
+        return vehicleNo;
+    }
+    
+    /**
+     * 璁板綍宸茶绠楃殑GPS鐐瑰埌鐘舵�佽〃
+     */
+    private void recordCalculatedGpsPoints(List<Long> gpsIdList, Long segmentId, Long vehicleId) {
+        for (Long gpsId : gpsIdList) {
+            try {
+                segmentMileageMapper.insertGpsCalculated(gpsId, segmentId, vehicleId);
+            } catch (Exception e) {
+                // 蹇界暐閲嶅閿紓甯革紝缁х画澶勭悊
+                logger.debug("璁板綍GPS璁$畻鐘舵�佸け璐ワ紝鍙兘宸插瓨鍦�: gpsId={}", gpsId);
+            }
+        }
+    }
+    
+    /**
+     * 瑙﹀彂姣忔棩閲岀▼缁熻姹囨��
+     */
+    private void triggerDailyMileageAggregation(Long vehicleId, Map<Date, List<VehicleGps>> segmentedData) {
+        try {
+            // 鑾峰彇娑夊強鐨勬棩鏈熻寖鍥�
+            Set<Date> affectedDates = extractAffectedDates(segmentedData);
+            
+            // 瀵规瘡涓秹鍙婄殑鏃ユ湡锛岃Е鍙戞眹鎬�
+            for (Date statDate : affectedDates) {
+                try {
+                    mileageStatsService.aggregateFromSegmentMileage(vehicleId, statDate);
+                    logger.info("杞﹁締 {} 鏃ユ湡 {} 鐨勭粺璁℃暟鎹凡鑷姩姹囨�荤敓鎴�", vehicleId, statDate);
+                } catch (Exception e) {
+                    logger.error("杞﹁締 {} 鏃ユ湡 {} 鑷姩姹囨�荤粺璁″け璐�", vehicleId, statDate, e);
+                }
+            }
+        } catch (Exception e) {
+            logger.error("瑙﹀彂鑷姩姹囨�诲け璐�", e);
+        }
+    }
+    
+    /**
+     * 鎻愬彇鍙楀奖鍝嶇殑鏃ユ湡鍒楄〃锛堢敤浜庢眹鎬荤粺璁★級
+     */
+    private Set<Date> extractAffectedDates(Map<Date, List<VehicleGps>> segmentedData) {
+        Set<Date> affectedDates = new HashSet<>();
+        Calendar cal = Calendar.getInstance();
+        
+        for (Map.Entry<Date, List<VehicleGps>> entry : segmentedData.entrySet()) {
+            cal.setTime(entry.getKey());
+            cal.set(Calendar.HOUR_OF_DAY, 0);
+            cal.set(Calendar.MINUTE, 0);
+            cal.set(Calendar.SECOND, 0);
+            cal.set(Calendar.MILLISECOND, 0);
+            affectedDates.add(cal.getTime());
+        }
+        
+        return affectedDates;
+    }
+    
+    /**
+     * 閲岀▼璁$畻閰嶇疆绫�
+     */
+    private static class MileageCalculationConfig {
+        int segmentMinutes;          // 鏃堕棿娈甸棿闅旓紙鍒嗛挓锛�
+        String calculateMethod;      // 璁$畻鏂瑰紡
+        boolean skipCalculated;      // 鏄惁璺宠繃宸茶绠楃殑GPS鐐�
     }
 
     /**
@@ -409,12 +608,13 @@
 
     /**
      * 璁$畻涓�涓椂闂存鍐呯殑鎬婚噷绋嬶紙鍖呮嫭涓庝笂涓�娈电殑闂撮殭璺濈锛�
-     * @param gpsList 褰撳墠鏃堕棿娈电殑GPS鐐瑰垪琛�
+     * @param gpsList 褰撳墠鏃堕棿娈电殑GPS鐐瑰垪琛紙鑷冲皯1涓偣锛�
      * @param calculateMethod 璁$畻鏂瑰紡
      * @param previousLastPoint 涓婁竴涓椂闂存鐨勬渶鍚庝竴涓偣锛堝彲涓簄ull锛�
+     * @return 鎬婚噷绋嬶紙鍏噷锛夛紝淇濈暀3浣嶅皬鏁�
      */
     private BigDecimal calculateSegmentDistanceWithGap(List<VehicleGps> gpsList, String calculateMethod, VehicleGps previousLastPoint) {
-        if (gpsList == null || gpsList.size() < 2) {
+        if (gpsList == null || gpsList.isEmpty()) {
             return BigDecimal.ZERO;
         }
         
@@ -435,14 +635,17 @@
                 String.format("%.3f", gapDistance));
         }
         
-        // 2. 鍐嶈绠楀綋鍓嶆鍐呴儴鐨勮窛绂�
-        BigDecimal segmentInternalDistance;
-        if ("tianditu".equalsIgnoreCase(calculateMethod)) {
-            segmentInternalDistance = calculateDistanceByTianditu(gpsList);
-        } else {
-            segmentInternalDistance = calculateDistanceByHaversine(gpsList);
+        // 2. 鍐嶈绠楀綋鍓嶆鍐呴儴鐨勮窛绂伙紙濡傛灉鏈�2涓垨浠ヤ笂GPS鐐癸級
+        if (gpsList.size() >= 2) {
+            BigDecimal segmentInternalDistance;
+            if ("tianditu".equalsIgnoreCase(calculateMethod)) {
+                segmentInternalDistance = calculateDistanceByTianditu(gpsList);
+            } else {
+                segmentInternalDistance = calculateDistanceByHaversine(gpsList);
+            }
+            totalDistance = totalDistance.add(segmentInternalDistance);
         }
-        totalDistance = totalDistance.add(segmentInternalDistance);
+        // 濡傛灉鍙湁1涓偣锛屾鍐呰窛绂讳负0锛屽彧璁$畻璺ㄦ璺濈
         
         return totalDistance.setScale(3, RoundingMode.HALF_UP);
     }
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 9f6a373..a04d09a 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
@@ -115,15 +115,28 @@
      * @param vehicleInfo 杞﹁締淇℃伅
      * @return 缁撴灉
      */
+    /**
+     * 淇敼杞﹁締淇℃伅
+     * 娉ㄦ剰:
+     * - 濡傛灉闇�瑕佹洿鏂伴儴闂ㄥ叧鑱�,璇疯缃� vehicleInfo.deptIds
+     * - 濡傛灉涓嶉渶瑕佹洿鏂伴儴闂ㄥ叧鑱�(浠呮洿鏂拌溅杈嗗熀鏈俊鎭�),璇蜂繚鎸� vehicleInfo.deptIds = null
+     * - 杩欐牱鍙互閬垮厤骞跺彂鍚屾鏃剁殑姝婚攣闂
+     * 
+     * @param vehicleInfo 杞﹁締淇℃伅
+     * @return 缁撴灉
+     */
     @Override
     @Transactional
     public int updateVehicleInfo(VehicleInfo vehicleInfo) {
-        // 鍏堝垹闄ゆ棫鐨勫叧鑱斿叧绯�
-        vehicleInfoMapper.deleteVehicleDeptByVehicleId(vehicleInfo.getVehicleId());
-        
-        // 濡傛灉閫夋嫨浜嗗涓垎鍏徃锛屼繚瀛樺埌鍏宠仈琛�
-        if (vehicleInfo.getDeptIds() != null && !vehicleInfo.getDeptIds().isEmpty()) {
-            insertVehicleDept(vehicleInfo);
+        // 鍙湁褰� deptIds 涓嶄负 null 鏃舵墠鏇存柊閮ㄩ棬鍏宠仈(閬垮厤涓嶅繀瑕佺殑閿佺珵浜�)
+        if (vehicleInfo.getDeptIds() != null) {
+            // 鍏堝垹闄ゆ棫鐨勫叧鑱斿叧绯�
+            vehicleInfoMapper.deleteVehicleDeptByVehicleId(vehicleInfo.getVehicleId());
+            
+            // 濡傛灉閫夋嫨浜嗗涓垎鍏徃,淇濆瓨鍒板叧鑱旇〃
+            if (!vehicleInfo.getDeptIds().isEmpty()) {
+                insertVehicleDept(vehicleInfo);
+            }
         }
         
         return vehicleInfoMapper.updateVehicleInfo(vehicleInfo);
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleMileageStatsServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleMileageStatsServiceImpl.java
index 3cf88f0..1cda18e 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleMileageStatsServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleMileageStatsServiceImpl.java
@@ -246,6 +246,16 @@
         // 璁$畻浠诲姟閲岀▼鍗犳瘮
         if (result.totalMileage.compareTo(BigDecimal.ZERO) > 0) {
             result.taskRatio = result.taskMileage.divide(result.totalMileage, 4, RoundingMode.HALF_UP);
+            
+            // 鏁版嵁鏍¢獙:鍗犳瘮搴斿湪0-1涔嬮棿
+            if (result.taskRatio.compareTo(BigDecimal.ONE) > 0) {
+                logger.warn("浠诲姟閲岀▼鍗犳瘮寮傚父: {} (浠诲姟閲岀▼:{}, 鎬婚噷绋�:{}), 寮哄埗璁句负1.0", 
+                           result.taskRatio, result.taskMileage, result.totalMileage);
+                result.taskRatio = BigDecimal.ONE;
+            } else if (result.taskRatio.compareTo(BigDecimal.ZERO) < 0) {
+                logger.warn("浠诲姟閲岀▼鍗犳瘮涓鸿礋: {}, 寮哄埗璁句负0", result.taskRatio);
+                result.taskRatio = BigDecimal.ZERO;
+            }
         }
         
         // 淇濈暀涓や綅灏忔暟
@@ -405,6 +415,17 @@
             BigDecimal taskRatio = BigDecimal.ZERO;
             if (totalMileage.compareTo(BigDecimal.ZERO) > 0) {
                 taskRatio = taskMileage.divide(totalMileage, 4, RoundingMode.HALF_UP);
+                
+                // 鏁版嵁鏍¢獙:鍗犳瘮搴斿湪0-1涔嬮棿,濡傛灉瓒呭嚭璇存槑鏁版嵁寮傚父
+                if (taskRatio.compareTo(BigDecimal.ONE) > 0) {
+                    logger.warn("杞﹁締ID: {} 鏃ユ湡: {} 浠诲姟閲岀▼鍗犳瘮寮傚父: {} (浠诲姟閲岀▼:{}, 鎬婚噷绋�:{}), 寮哄埗璁句负1.0", 
+                               vehicleId, statDate, taskRatio, taskMileage, totalMileage);
+                    taskRatio = BigDecimal.ONE;
+                } else if (taskRatio.compareTo(BigDecimal.ZERO) < 0) {
+                    logger.warn("杞﹁締ID: {} 鏃ユ湡: {} 浠诲姟閲岀▼鍗犳瘮涓鸿礋: {}, 寮哄埗璁句负0", 
+                               vehicleId, statDate, taskRatio);
+                    taskRatio = BigDecimal.ZERO;
+                }
             }
             
             // 5. 鏌ヨ鎴栧垱寤虹粺璁¤褰�
diff --git a/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml
index 67c9fae..3e3f83d 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml
@@ -231,7 +231,7 @@
 	
 	<!-- 鏍规嵁缂栫爜鍒楄〃鏌ヨ鍒嗗叕鍙� -->
 	<select id="selectBranchCompaniesByOrderCodes" resultMap="SysDeptResult">
-		select dept_id, dept_name, parent_id, ancestors, service_order_class, dispatch_order_class
+		select dept_id, dept_name, parent_id, ancestors, service_order_class, dispatch_order_class,departure_address, departure_longitude, departure_latitude
 		from sys_dept
 		where parent_id = 100
 		and del_flag = '0'
diff --git a/ruoyi-system/src/main/resources/mapper/system/VehicleGpsSegmentMileageMapper.xml b/ruoyi-system/src/main/resources/mapper/system/VehicleGpsSegmentMileageMapper.xml
index 43b5fb3..53443f9 100644
--- a/ruoyi-system/src/main/resources/mapper/system/VehicleGpsSegmentMileageMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/VehicleGpsSegmentMileageMapper.xml
@@ -154,4 +154,15 @@
     <select id="selectGpsCalculatedSegmentId" resultType="Long">
         SELECT segment_id FROM tb_vehicle_gps_calculated WHERE gps_id = #{gpsId} LIMIT 1
     </select>
+    
+    <!-- 鏌ヨ杞﹁締鍦ㄦ寚瀹氭椂闂翠箣鍓嶆渶鍚庝竴涓凡澶勭悊鐨凣PS鍧愭爣ID -->
+    <select id="selectLastCalculatedGpsId" resultType="Long">
+        SELECT c.gps_id 
+        FROM tb_vehicle_gps_calculated c
+        INNER JOIN tb_vehicle_gps g ON c.gps_id = g.gps_id
+        WHERE c.vehicle_id = #{vehicleId}
+          AND STR_TO_DATE(g.collect_time, '%Y-%m-%d %H:%i:%s') &lt; #{beforeTime}
+        ORDER BY STR_TO_DATE(g.collect_time, '%Y-%m-%d %H:%i:%s') DESC
+        LIMIT 1
+    </select>
 </mapper>
diff --git a/ruoyi-system/src/main/resources/mapper/system/VehicleInfoMapper.xml b/ruoyi-system/src/main/resources/mapper/system/VehicleInfoMapper.xml
index c80eb04..09303ac 100644
--- a/ruoyi-system/src/main/resources/mapper/system/VehicleInfoMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/VehicleInfoMapper.xml
@@ -131,6 +131,7 @@
     <select id="selectVehicleInfoByPlateNumber" parameterType="String" resultMap="VehicleInfoResult">
         <include refid="selectVehicleInfoVo"/>
         where v.vehicle_no LIKE concat('%', #{plateNumber}, '%')
+        limit 1
     </select>
 
     <select id="selectVehicleInfoByVehicleNo" parameterType="String" resultMap="VehicleInfoResult">
diff --git a/ruoyi-system/src/main/resources/mapper/system/VehicleMileageStatsMapper.xml b/ruoyi-system/src/main/resources/mapper/system/VehicleMileageStatsMapper.xml
index 69ddb7e..4179acf 100644
--- a/ruoyi-system/src/main/resources/mapper/system/VehicleMileageStatsMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/VehicleMileageStatsMapper.xml
@@ -77,12 +77,14 @@
                  s.data_source, s.create_time, s.update_time, vd.dept_id
     </select>
 
+    <!-- 鏍规嵁杞﹁締ID鍜岀粺璁℃棩鏈熸煡璇㈠敮涓�缁熻璁板綍 -->
     <select id="selectByVehicleIdAndDate" resultMap="VehicleMileageStatsResult">
-        <include refid="selectVehicleMileageStatsVo"/>
+        select s.stats_id, s.vehicle_id, s.vehicle_no, s.stat_date, s.total_mileage, s.task_mileage, 
+               s.non_task_mileage, s.task_ratio, s.gps_point_count, s.task_count, s.segment_count, 
+               s.data_source, s.create_time, s.update_time
+        from tb_vehicle_mileage_stats s
         where s.vehicle_id = #{vehicleId} and s.stat_date = #{statDate}
-        group by s.stats_id, s.vehicle_id, s.vehicle_no, s.stat_date, s.total_mileage, s.task_mileage,
-                 s.non_task_mileage, s.task_ratio, s.gps_point_count, s.task_count, s.segment_count,
-                 s.data_source, s.create_time, s.update_time, vd.dept_id
+        limit 1
     </select>
 
     <select id="selectTaskTimeIntervals" resultMap="TaskTimeIntervalResult">
diff --git a/sql/dryad_payment_tables.sql b/sql/dryad_payment_tables.sql
index a879875..45ba3c6 100644
--- a/sql/dryad_payment_tables.sql
+++ b/sql/dryad_payment_tables.sql
@@ -1,7 +1,6 @@
 -- dryad-payment 鏀粯妯″潡鏁版嵁琛�
 -- 鍦ㄤ富鏁版嵁搴� 966120 涓垱寤烘敮浠樻ā鍧楁墍闇�鐨勮〃
 
-USE `966120`;
 
 -- 鏀粯璁㈠崟琛�
 CREATE TABLE IF NOT EXISTS `pay_order` (
diff --git a/sql/fix_duplicate_vehicle_plates.sql b/sql/fix_duplicate_vehicle_plates.sql
new file mode 100644
index 0000000..d877917
--- /dev/null
+++ b/sql/fix_duplicate_vehicle_plates.sql
@@ -0,0 +1,101 @@
+-- ============================================
+-- 淇閲嶅杞︾墝鍙烽棶棰�
+-- ============================================
+
+-- 1. 鏌ヨ閲嶅鐨勮溅鐗屽彿
+SELECT 
+    vehicle_no, 
+    COUNT(*) as count,
+    GROUP_CONCAT(vehicle_id ORDER BY vehicle_id) as vehicle_ids,
+    GROUP_CONCAT(platform_code ORDER BY vehicle_id) as platform_codes,
+    GROUP_CONCAT(create_time ORDER BY vehicle_id) as create_times
+FROM tb_vehicle_info
+GROUP BY vehicle_no
+HAVING COUNT(*) > 1
+ORDER BY count DESC;
+
+-- 2. 鏌ョ湅鍏蜂綋閲嶅璁板綍鐨勮鎯�
+SELECT 
+    vehicle_id,
+    vehicle_no,
+    platform_code,
+    device_id,
+    car_id,
+    status,
+    create_time,
+    update_time
+FROM tb_vehicle_info
+WHERE vehicle_no IN (
+    SELECT vehicle_no 
+    FROM tb_vehicle_info 
+    GROUP BY vehicle_no 
+    HAVING COUNT(*) > 1
+)
+ORDER BY vehicle_no, vehicle_id;
+
+-- 3. 澶囦唤閲嶅鏁版嵁锛堝湪鍒犻櫎鍓嶏級
+CREATE TABLE IF NOT EXISTS tb_vehicle_info_duplicate_backup AS
+SELECT * FROM tb_vehicle_info
+WHERE vehicle_no IN (
+    SELECT vehicle_no 
+    FROM tb_vehicle_info 
+    GROUP BY vehicle_no 
+    HAVING COUNT(*) > 1
+);
+
+-- 4. 鍒犻櫎閲嶅璁板綍锛堜繚鐣欐渶鏃╁垱寤虹殑璁板綍锛�
+-- 娉ㄦ剰锛氭墽琛屽墠璇峰厛纭澶囦唤瀹屾垚锛�
+-- 鍙栨秷涓嬮潰鐨勬敞閲婃潵鎵ц鍒犻櫎鎿嶄綔锛�
+
+/*
+DELETE v1 FROM tb_vehicle_info v1
+INNER JOIN tb_vehicle_info v2 
+WHERE v1.vehicle_no = v2.vehicle_no 
+  AND v1.vehicle_id > v2.vehicle_id;
+*/
+
+-- 5. 楠岃瘉鍒犻櫎鍚庣殑缁撴灉
+SELECT 
+    vehicle_no, 
+    COUNT(*) as count
+FROM tb_vehicle_info
+GROUP BY vehicle_no
+HAVING COUNT(*) > 1;
+
+-- 6. 娣诲姞鍞竴绱㈠紩锛堥槻姝㈡湭鏉ュ嚭鐜伴噸澶嶏級
+-- 娉ㄦ剰锛氬彧鏈夊湪纭娌℃湁閲嶅鏁版嵁鍚庢墠鑳芥墽琛岋紒
+-- 鍙栨秷涓嬮潰鐨勬敞閲婃潵娣诲姞鍞竴绱㈠紩锛�
+
+/*
+ALTER TABLE tb_vehicle_info 
+ADD UNIQUE INDEX uk_vehicle_no (vehicle_no);
+*/
+
+-- 7. 鏌ヨ缁熻淇℃伅
+SELECT 
+    '鎬昏溅杈嗘暟' as item,
+    COUNT(*) as count
+FROM tb_vehicle_info
+UNION ALL
+SELECT 
+    '鍞竴杞︾墝鏁�' as item,
+    COUNT(DISTINCT vehicle_no) as count
+FROM tb_vehicle_info
+UNION ALL
+SELECT 
+    'CMS骞冲彴杞﹁締' as item,
+    COUNT(*) as count
+FROM tb_vehicle_info
+WHERE platform_code = 'CMS'
+UNION ALL
+SELECT 
+    'GPS51骞冲彴杞﹁締' as item,
+    COUNT(*) as count
+FROM tb_vehicle_info
+WHERE platform_code = 'GPS51'
+UNION ALL
+SELECT 
+    'LEGACY骞冲彴杞﹁締' as item,
+    COUNT(*) as count
+FROM tb_vehicle_info
+WHERE platform_code = 'LEGACY';
diff --git a/sql/fixes/fix_duplicate_mileage_stats.sql b/sql/fixes/fix_duplicate_mileage_stats.sql
new file mode 100644
index 0000000..d926d17
--- /dev/null
+++ b/sql/fixes/fix_duplicate_mileage_stats.sql
@@ -0,0 +1,35 @@
+-- ============================================
+-- 淇杞﹁締閲岀▼缁熻琛ㄤ腑鐨勯噸澶嶆暟鎹�
+-- 闂: 鍚屼竴杞﹁締鍚屼竴澶╁瓨鍦ㄥ鏉$粺璁¤褰�
+-- 鍘熷洜: 鍘嗗彶鏁版嵁鎴栧苟鍙戞彃鍏ュ鑷�
+-- 瑙e喅: 淇濈暀stats_id鏈�澶х殑璁板綍,鍒犻櫎鍏朵粬閲嶅璁板綍
+-- ============================================
+
+-- 1. 鏌ョ湅閲嶅鏁版嵁
+SELECT vehicle_id, stat_date, COUNT(*) as count
+FROM tb_vehicle_mileage_stats
+GROUP BY vehicle_id, stat_date
+HAVING COUNT(*) > 1
+ORDER BY count DESC;
+
+-- 2. 鍒犻櫎閲嶅鏁版嵁(淇濈暀stats_id鏈�澶х殑璁板綍)
+DELETE FROM tb_vehicle_mileage_stats
+WHERE stats_id NOT IN (
+    SELECT max_id FROM (
+        SELECT MAX(stats_id) as max_id
+        FROM tb_vehicle_mileage_stats
+        GROUP BY vehicle_id, stat_date
+    ) as temp
+);
+
+-- 3. 楠岃瘉娓呯悊缁撴灉
+SELECT vehicle_id, stat_date, COUNT(*) as count
+FROM tb_vehicle_mileage_stats
+GROUP BY vehicle_id, stat_date
+HAVING COUNT(*) > 1;
+
+-- 4. 纭鍞竴绱㈠紩瀛樺湪
+SHOW INDEX FROM tb_vehicle_mileage_stats WHERE Key_name = 'uk_vehicle_date';
+
+-- 5. 濡傛灉鍞竴绱㈠紩涓嶅瓨鍦�,鍒欏垱寤�
+-- ALTER TABLE tb_vehicle_mileage_stats ADD UNIQUE KEY `uk_vehicle_date` (`vehicle_id`, `stat_date`);
diff --git a/sql/fixes/fix_task_ratio_column.sql b/sql/fixes/fix_task_ratio_column.sql
new file mode 100644
index 0000000..4ba99f8
--- /dev/null
+++ b/sql/fixes/fix_task_ratio_column.sql
@@ -0,0 +1,26 @@
+-- ============================================
+-- 淇 task_ratio 瀛楁鑼冨洿闄愬埗闂
+-- 闂: decimal(5,4) 鏈�澶у�间负 9.9999,鍙兘涓嶈冻浠ュ瓨鍌ㄥ紓甯告暟鎹�
+-- 瑙e喅: 鎵╁ぇ涓� decimal(6,4),鏈�澶у�� 99.9999
+-- ============================================
+
+-- 1. 鏌ョ湅褰撳墠瀛楁瀹氫箟
+DESC tb_vehicle_mileage_stats;
+
+-- 2. 淇敼瀛楁绫诲瀷
+ALTER TABLE tb_vehicle_mileage_stats 
+MODIFY COLUMN task_ratio DECIMAL(6,4) DEFAULT 0.0000 COMMENT '浠诲姟閲岀▼鍗犳瘮(0-1,寮傚父鏃跺彲鑳借秴鍑�)';
+
+-- 3. 楠岃瘉淇敼缁撴灉
+DESC tb_vehicle_mileage_stats;
+
+-- 4. 鏌ヨ瓒呭嚭姝e父鑼冨洿鐨勬暟鎹�(鍗犳瘮搴斿湪0-1涔嬮棿)
+SELECT stats_id, vehicle_id, vehicle_no, stat_date, 
+       total_mileage, task_mileage, task_ratio
+FROM tb_vehicle_mileage_stats
+WHERE task_ratio > 1.0 OR task_ratio < 0.0
+ORDER BY task_ratio DESC;
+
+-- 5. 淇寮傚父鏁版嵁(鍙��)
+-- UPDATE tb_vehicle_mileage_stats SET task_ratio = 1.0 WHERE task_ratio > 1.0;
+-- UPDATE tb_vehicle_mileage_stats SET task_ratio = 0.0 WHERE task_ratio < 0.0;
diff --git a/sql/gps_compensation_config.sql b/sql/gps_compensation_config.sql
new file mode 100644
index 0000000..6fae101
--- /dev/null
+++ b/sql/gps_compensation_config.sql
@@ -0,0 +1,15 @@
+-- GPS鍒嗘閲岀▼琛ュ伩璁$畻閰嶇疆
+-- 鐢ㄤ簬閰嶇疆鏈嶅姟鍚姩鏃剁殑琛ュ伩璁$畻鍥炴函澶╂暟
+
+-- 鎻掑叆琛ュ伩鍥炴函澶╂暟閰嶇疆锛堥粯璁�7澶╋級
+INSERT INTO sys_config (config_name, config_key, config_value, config_type, create_by, create_time, update_by, update_time, remark) 
+VALUES 
+('GPS閲岀▼琛ュ伩鍥炴函澶╂暟', 'gps.mileage.compensation.days', '7', 'N', 'admin', NOW(), 'admin', NOW(), 
+ '鏈嶅姟鍚姩鏃惰ˉ鍋胯绠楃殑鍥炴函澶╂暟锛屾鏌ュ苟澶勭悊璇ユ椂闂磋寖鍥村唴鏈璁$畻鐨凣PS鍧愭爣銆傞粯璁�7澶┿��');
+
+-- 璇存槑锛�
+-- 1. gps.mileage.compensation.days 鎺у埗鏈嶅姟鍚姩鏃惰嚜鍔ㄨˉ鍋胯绠楃殑鍥炴函澶╂暟
+-- 2. 琛ュ伩鏈哄埗浼氬湪鏈嶅姟鍚姩30绉掑悗鑷姩鎵ц
+-- 3. 琛ュ伩璁$畻浼氭煡鎵炬瘡杈嗚溅鏈澶勭悊鐨凣PS鍧愭爣锛屽苟涓庢渶鍚庝竴涓凡澶勭悊鐨勫潗鏍囦竴璧疯绠楄窛绂�
+-- 4. 宸插鐞嗚繃鐨凣PS鍧愭爣浼氳璁板綍鍒� tb_vehicle_gps_calculated 琛ㄤ腑锛岄伩鍏嶉噸澶嶈绠�
+-- 5. 濡傛灉涓嶅笇鏈涘惎鍔ㄦ椂鎵ц琛ュ伩璁$畻锛屽彲灏嗘閰嶇疆鍊艰涓�0
diff --git a/sql/resync_vehicle_personnel_job.sql b/sql/resync_vehicle_personnel_job.sql
index 128b77b..13de161 100644
--- a/sql/resync_vehicle_personnel_job.sql
+++ b/sql/resync_vehicle_personnel_job.sql
@@ -11,7 +11,7 @@
 -- 閲嶆柊鍚屾杞﹁締鍜屼汉鍛樺彉鏇寸殑浠诲姟鍒版棫绯荤粺
 INSERT INTO sys_job (job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark)
 VALUES 
-('閲嶆柊鍚屾杞﹁締浜哄憳鍙樻洿', 'DEFAULT', 'legacySystemSyncTask.resyncVehicleAndPersonnel', '0 0/5 * * * ?', '3', '1', '0', 'admin', sysdate(), 
+('鍚屾鏈嶅姟璋冨害鍒版棫绯荤粺鍙樻洿', 'DEFAULT', 'legacySystemSyncTask.resyncVehicleAndPersonnel', '0 0/5 * * * ?', '3', '1', '0', 'admin', sysdate(), 
 '姣�5鍒嗛挓鑷姩閲嶆柊鍚屾杞﹁締銆佷汉鍛樸�佸湴鍧�銆佹垚浜や环鍙戠敓鍙樻洿鐨勪换鍔″埌鏃х郴缁熴�傚綋浠诲姟鐨勮溅杈嗐�佷汉鍛樸�佸湴鍧�鎴栬垂鐢ㄨ淇敼鍚庯紝浼氭爣璁皀eed_resync=1锛屽畾鏃朵换鍔′細灏嗚繖浜涘彉鏇村悓姝ュ埌鏃х郴缁熻皟搴﹀崟琛ㄣ��');
 
 -- 璇存槑锛�
diff --git a/sql/updates/add_segment_count_to_mileage_stats.sql b/sql/updates/add_segment_count_to_mileage_stats.sql
index 9cad4f0..6a5938d 100644
--- a/sql/updates/add_segment_count_to_mileage_stats.sql
+++ b/sql/updates/add_segment_count_to_mileage_stats.sql
@@ -1,7 +1,7 @@
 -- 涓鸿溅杈嗛噷绋嬬粺璁¤〃娣诲姞鍒嗘鏁伴噺瀛楁
 -- 鐢ㄩ�旓細璁板綍褰撴棩鍏宠仈鐨凣PS鍒嗘鏁伴噺锛岀敤浜庢暟鎹畬鏁存�ф牎楠屽拰涓氬姟鐩戞帶
 
-USE `ry-vue`;
+-- USE `ry-vue`;
 
 -- 妫�鏌ュ瓧娈垫槸鍚﹀瓨鍦紝濡傛灉涓嶅瓨鍦ㄥ垯娣诲姞
 SET @dbname = DATABASE();
@@ -24,3 +24,6 @@
 
 -- 楠岃瘉瀛楁鏄惁娣诲姞鎴愬姛
 DESC tb_vehicle_mileage_stats;
+
+
+alter table tb_vehicle_mileage_stats add column segment_count int(11) default 0 comment '鍏宠仈鐨勫垎娈垫暟閲�' after task_count;
\ No newline at end of file
diff --git a/sql/updates/add_task_id_to_segment_mileage.sql b/sql/updates/add_task_id_to_segment_mileage.sql
index cfb8a8a..b0c3c3a 100644
--- a/sql/updates/add_task_id_to_segment_mileage.sql
+++ b/sql/updates/add_task_id_to_segment_mileage.sql
@@ -1,7 +1,7 @@
 -- 涓鸿溅杈咷PS鍒嗘閲岀▼琛ㄦ坊鍔犱换鍔″叧鑱斿瓧娈�
 -- 鐢ㄩ�旓細鍦ㄨ绠桮PS閲岀▼鏃讹紝鑷姩鍏宠仈杞﹁締姝e湪鎵ц鐨勪换鍔★紝鏂逛究缁熻浠诲姟閲岀▼
 
-USE ry-vue;
+-- USE ry-vue;
 
 -- 娣诲姞浠诲姟ID瀛楁
 ALTER TABLE tb_vehicle_gps_segment_mileage 

--
Gitblit v1.9.1