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') < #{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