From fd047fa7234dc11643dab8ecbf38e8d7a8ba0854 Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期六, 22 十一月 2025 23:48:12 +0800
Subject: [PATCH] feat:修改任务

---
 app/pages/task/create-normal.vue |  453 ++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 323 insertions(+), 130 deletions(-)

diff --git a/app/pages/task/create-normal.vue b/app/pages/task/create-normal.vue
index 9fe739c..a2a7bdf 100644
--- a/app/pages/task/create-normal.vue
+++ b/app/pages/task/create-normal.vue
@@ -39,17 +39,49 @@
       
       <view class="form-item">
         <view class="form-label">浠诲姟鍑哄彂鍦�</view>
-        <view class="form-input picker-input" @click="selectStartLocation">
-          {{ taskForm.startLocation || '璇烽�夋嫨浠诲姟鍑哄彂鍦�' }}
-          <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+        <view class="address-input-container">
+          <input 
+            class="form-input" 
+            placeholder="璇疯緭鍏ヤ换鍔″嚭鍙戝湴" 
+            v-model="taskForm.startLocation"
+            @input="onStartLocationInput"
+            @focus="onStartLocationFocus"
+          />
+          <view class="address-suggestions" v-if="showStartSuggestions && startSuggestions.length > 0">
+            <view 
+              class="address-suggestion-item" 
+              v-for="(item, index) in startSuggestions" 
+              :key="index"
+              @click="selectStartSuggestion(item)"
+            >
+              <view class="suggestion-name">{{ item.name }}</view>
+              <view class="suggestion-address">{{ item.address }}</view>
+            </view>
+          </view>
         </view>
       </view>
       
       <view class="form-item">
         <view class="form-label">浠诲姟鐩殑鍦�</view>
-        <view class="form-input picker-input" @click="selectEndLocation">
-          {{ taskForm.endLocation || '璇烽�夋嫨浠诲姟鐩殑鍦�' }}
-          <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+        <view class="address-input-container">
+          <input 
+            class="form-input" 
+            placeholder="璇疯緭鍏ヤ换鍔$洰鐨勫湴" 
+            v-model="taskForm.endLocation"
+            @input="onEndLocationInput"
+            @focus="onEndLocationFocus"
+          />
+          <view class="address-suggestions" v-if="showEndSuggestions && endSuggestions.length > 0">
+            <view 
+              class="address-suggestion-item" 
+              v-for="(item, index) in endSuggestions" 
+              :key="index"
+              @click="selectEndSuggestion(item)"
+            >
+              <view class="suggestion-name">{{ item.name }}</view>
+              <view class="suggestion-address">{{ item.address }}</view>
+            </view>
+          </view>
         </view>
       </view>
       
@@ -109,40 +141,22 @@
       </view>
     </view>
     
-    <!-- 鍦板浘閫夋嫨鍣ㄥ脊绐� -->
-    <uni-popup ref="mapPopup" type="bottom" :mask-click="false">
-      <view class="map-popup-container">
-        <view class="popup-header">
-          <view class="popup-title">閫夋嫨鍦板潃</view>
-          <view class="close-btn" @click="closeMapSelector">
-            <uni-icons type="closeempty" size="20" color="#999"></uni-icons>
-          </view>
-        </view>
-        <map-selector 
-          :initial-address="getInitialAddress()" 
-          @addressSelected="onAddressSelected"
-        ></map-selector>
-      </view>
-    </uni-popup>
+
   </scroll-view>
 </template>
 
 <script>
 import { mapState } from 'vuex'
 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 { getUserProfile } from "@/api/system/user"
 import { addTask } from "@/api/task"
 import { listAvailableVehicles } from "@/api/vehicle"
-import { calculateDistance } from "@/api/map"
+import { baiduPlaceSuggestion, baiduGeocoding, baiduDistanceByAddress } from "@/api/map"
 import { getDicts } from "@/api/dict"
-import MapSelector from '@/components/map-selector.vue'
 
 export default {
   components: {
-    uniDatetimePicker,
-    uniPopup,
-    MapSelector
+    uniDatetimePicker
   },
   data() {
     return {
@@ -157,7 +171,13 @@
       boundVehicleId: null,
       taskTypeOptions: [],
       taskTypeLabels: [],
-      mapSelectorType: '',
+      // 鍦板潃鎼滅储鐩稿叧
+      startSuggestions: [],
+      endSuggestions: [],
+      showStartSuggestions: false,
+      showEndSuggestions: false,
+      startSearchTimer: null,
+      endSearchTimer: null,
       taskForm: {
         taskDescription: '',
         taskType: '',
@@ -173,15 +193,18 @@
       vehicleOptions: [],
       loading: false,
       addressCoordinates: {
-        startLocation: null,
-        endLocation: null
-      }
+        startLocation: { lon: null, lat: null },
+        endLocation: { lon: null, lat: null }
+      },
+      // 鎼滅储鍖哄煙锛堝彲鏍规嵁鐢ㄦ埛鎵�鍦ㄥ煄甯傝皟鏁达級
+      searchRegion: '骞垮窞甯�'
     }
   },
   computed: {
     ...mapState({
       currentUser: state => ({
-        name: state.user.name || '寮犱笁',
+        id: state.user.userId,
+        name: state.user.nickName || '寮犱笁',
         position: '鍙告満',
         deptId: state.user.deptId || 100
       })
@@ -300,77 +323,202 @@
       this.taskForm.vehicleId = this.selectedVehicleId
     },
     
-    selectStartLocation() {
-      this.mapSelectorType = 'startLocation'
-      this.$refs.mapPopup.open()
-    },
-    
-    selectEndLocation() {
-      this.mapSelectorType = 'endLocation'
-      this.$refs.mapPopup.open()
-    },
-    
-    getInitialAddress() {
-      return this.mapSelectorType === 'startLocation' ? this.taskForm.startLocation : this.taskForm.endLocation
-    },
-    
-    onAddressSelected(address) {
-      if (this.mapSelectorType === 'startLocation') {
-        this.taskForm.startLocation = address.title + ' - ' + address.address
-        this.addressCoordinates.startLocation = {
-          lat: address.lat,
-          lng: address.lng
-        }
-      } else if (this.mapSelectorType === 'endLocation') {
-        this.taskForm.endLocation = address.title + ' - ' + address.address
-        this.addressCoordinates.endLocation = {
-          lat: address.lat,
-          lng: address.lng
-        }
+    // 鍑哄彂鍦拌緭鍏ョ洃鍚�
+    onStartLocationInput(e) {
+      const keyword = e.detail.value
+      this.taskForm.startLocation = keyword
+      
+      if (this.startSearchTimer) {
+        clearTimeout(this.startSearchTimer)
       }
       
-      this.calculateDistance()
-      this.closeMapSelector()
-    },
-    
-    calculateDistance() {
-      if (this.addressCoordinates.startLocation && this.addressCoordinates.endLocation) {
-        this.getDistanceBetweenPoints(
-          this.addressCoordinates.startLocation.lat,
-          this.addressCoordinates.startLocation.lng,
-          this.addressCoordinates.endLocation.lat,
-          this.addressCoordinates.endLocation.lng
-        ).then(distance => {
-          this.taskForm.distance = distance.toFixed(2)
-        }).catch(error => {
-          console.error('璺濈璁$畻澶辫触:', error)
-        })
+      if (!keyword || keyword.trim() === '') {
+        this.startSuggestions = []
+        this.showStartSuggestions = false
+        return
       }
+      
+      // 闃叉姈澶勭悊
+      this.startSearchTimer = setTimeout(() => {
+        this.searchStartAddress(keyword)
+      }, 300)
     },
     
-    getDistanceBetweenPoints(lat1, lng1, lat2, lng2) {
-      return new Promise((resolve, reject) => {
-        calculateDistance(lat1, lng1, lat2, lng2).then(response => {
-          if (response.code === 200) {
-            const responseData = typeof response.data === 'string' ? JSON.parse(response.data) : response.data
-            if (responseData && responseData.status === 0 && responseData.result && responseData.result.elements && responseData.result.elements.length > 0) {
-              const distanceInKm = responseData.result.elements[0].distance / 1000
-              resolve(distanceInKm)
-            } else {
-              reject(new Error('璺濈璁$畻鎺ュ彛杩斿洖鏁版嵁鏍煎紡涓嶆纭�'))
-            }
-          } else {
-            reject(new Error('璺濈璁$畻鎺ュ彛璋冪敤澶辫触'))
-          }
-        }).catch(error => {
-          reject(error)
-        })
+    // 鎼滅储鍑哄彂鍦板湴鍧�
+    searchStartAddress(keyword) {
+      baiduPlaceSuggestion(keyword, this.searchRegion).then(response => {
+        if (response.code === 200 && response.data) {
+          this.startSuggestions = response.data
+          this.showStartSuggestions = true
+        } else {
+          this.startSuggestions = []
+          this.showStartSuggestions = false
+        }
+      }).catch(error => {
+        console.error('鎼滅储鍑哄彂鍦板湴鍧�澶辫触:', error)
+        this.startSuggestions = []
+        this.showStartSuggestions = false
       })
     },
     
-    closeMapSelector() {
-      this.$refs.mapPopup.close()
-      this.mapSelectorType = ''
+    // 鍑哄彂鍦拌緭鍏ユ鑾峰緱鐒︾偣
+    onStartLocationFocus() {
+      if (this.taskForm.startLocation && this.startSuggestions.length > 0) {
+        this.showStartSuggestions = true
+      }
+    },
+    
+    // 閫夋嫨鍑哄彂鍦板湴鍧�寤鸿
+    selectStartSuggestion(item) {
+      this.taskForm.startLocation = item.name
+      this.showStartSuggestions = false
+      this.startSuggestions = []
+      
+      // 鑾峰彇鍦板潃鍧愭爣
+      if (item.location && item.location.lng && item.location.lat) {
+        this.addressCoordinates.startLocation = {
+          lon: item.location.lng,
+          lat: item.location.lat
+        }
+      } else {
+        // 濡傛灉娌℃湁鍧愭爣锛岄渶瑕侀�氳繃鍦板潃鑾峰彇鍧愭爣
+        this.getCoordinatesByAddress(item.name, 'start')
+      }
+      
+      // 濡傛灉涓や釜鍦板潃閮藉凡閫夋嫨锛岃嚜鍔ㄨ绠楄窛绂�
+      if (this.taskForm.endLocation && this.addressCoordinates.endLocation.lon) {
+        this.calculateDistance()
+      }
+    },
+    
+    // 鐩殑鍦拌緭鍏ョ洃鍚�
+    onEndLocationInput(e) {
+      const keyword = e.detail.value
+      this.taskForm.endLocation = keyword
+      
+      if (this.endSearchTimer) {
+        clearTimeout(this.endSearchTimer)
+      }
+      
+      if (!keyword || keyword.trim() === '') {
+        this.endSuggestions = []
+        this.showEndSuggestions = false
+        return
+      }
+      
+      // 闃叉姈澶勭悊
+      this.endSearchTimer = setTimeout(() => {
+        this.searchEndAddress(keyword)
+      }, 300)
+    },
+    
+    // 鎼滅储鐩殑鍦板湴鍧�
+    searchEndAddress(keyword) {
+      baiduPlaceSuggestion(keyword, this.searchRegion).then(response => {
+        if (response.code === 200 && response.data) {
+          this.endSuggestions = response.data
+          this.showEndSuggestions = true
+        } else {
+          this.endSuggestions = []
+          this.showEndSuggestions = false
+        }
+      }).catch(error => {
+        console.error('鎼滅储鐩殑鍦板湴鍧�澶辫触:', error)
+        this.endSuggestions = []
+        this.showEndSuggestions = false
+      })
+    },
+    
+    // 鐩殑鍦拌緭鍏ユ鑾峰緱鐒︾偣
+    onEndLocationFocus() {
+      if (this.taskForm.endLocation && this.endSuggestions.length > 0) {
+        this.showEndSuggestions = true
+      }
+    },
+    
+    // 閫夋嫨鐩殑鍦板湴鍧�寤鸿
+    selectEndSuggestion(item) {
+      this.taskForm.endLocation = item.name
+      this.showEndSuggestions = false
+      this.endSuggestions = []
+      
+      // 鑾峰彇鍦板潃鍧愭爣
+      if (item.location && item.location.lng && item.location.lat) {
+        this.addressCoordinates.endLocation = {
+          lon: item.location.lng,
+          lat: item.location.lat
+        }
+      } else {
+        // 濡傛灉娌℃湁鍧愭爣锛岄渶瑕侀�氳繃鍦板潃鑾峰彇鍧愭爣
+        this.getCoordinatesByAddress(item.name, 'end')
+      }
+      
+      // 濡傛灉涓や釜鍦板潃閮藉凡閫夋嫨锛岃嚜鍔ㄨ绠楄窛绂�
+      if (this.taskForm.startLocation && this.addressCoordinates.startLocation.lon) {
+        this.calculateDistance()
+      }
+    },
+    
+    // 閫氳繃鍦板潃鑾峰彇鍧愭爣
+    getCoordinatesByAddress(address, type) {
+      baiduGeocoding(address, this.searchRegion).then(response => {
+        if (response.code === 200 && response.data && response.data.location) {
+          if (type === 'start') {
+            this.addressCoordinates.startLocation = {
+              lon: response.data.location.lng,
+              lat: response.data.location.lat
+            }
+          } else if (type === 'end') {
+            this.addressCoordinates.endLocation = {
+              lon: response.data.location.lng,
+              lat: response.data.location.lat
+            }
+          }
+          
+          // 濡傛灉涓や釜鍦板潃閮藉凡鏈夊潗鏍囷紝鑷姩璁$畻璺濈
+          if (this.addressCoordinates.startLocation.lon && this.addressCoordinates.endLocation.lon) {
+            this.calculateDistance()
+          }
+        }
+      }).catch(error => {
+        console.error('鑾峰彇鍦板潃鍧愭爣澶辫触:', error)
+      })
+    },
+    
+    // 璁$畻涓ゅ湴涔嬮棿鐨勮窛绂�
+    calculateDistance() {
+      if (!this.taskForm.startLocation || !this.taskForm.endLocation) {
+        return
+      }
+      
+      // 浣跨敤鐧惧害鍦板浘璁$畻璺濈(缁勫悎鎺ュ彛)
+      baiduDistanceByAddress(this.taskForm.startLocation, this.searchRegion, this.taskForm.endLocation, this.searchRegion).then(response => {
+        if (response.code === 200 && response.data) {
+          // 鐧惧害鍦板浘杩斿洖鐨勮窛绂诲崟浣嶆槸绫�,闇�瑕佽浆鎹负鍏噷
+          const distanceInMeters = response.data.distance
+          const distanceInKm = distanceInMeters / 1000
+          this.taskForm.distance = distanceInKm.toFixed(2)
+          
+          console.log('璺濈璁$畻鎴愬姛:', distanceInMeters, '绫� =', distanceInKm, '鍏噷')
+          
+          // 鍚屾椂鏇存柊鍧愭爣淇℃伅
+          if (response.data.fromLocation) {
+            this.addressCoordinates.startLocation = {
+              lon: response.data.fromLocation.lng,
+              lat: response.data.fromLocation.lat
+            }
+          }
+          if (response.data.toLocation) {
+            this.addressCoordinates.endLocation = {
+              lon: response.data.toLocation.lng,
+              lat: response.data.toLocation.lat
+            }
+          }
+        }
+      }).catch(error => {
+        console.error('璁$畻璺濈澶辫触:', error)
+        this.$modal.showToast('璁$畻璺濈澶辫触,璇锋墜鍔ㄨ緭鍏�')
+      })
     },
     
     validateForm() {
@@ -413,10 +561,17 @@
     },
     
     buildSubmitData() {
+      // 璋冭瘯锛氭墦鍗板綋鍓嶇敤鎴蜂俊鎭�
+      console.log('褰撳墠鐢ㄦ埛淇℃伅:', this.currentUser)
+      console.log('鐢ㄦ埛ID:', this.currentUser.id)
+      console.log('Vuex State:', this.$store.state.user)
+      
       const submitData = {
         taskDescription: this.taskForm.taskDescription,
         taskType: this.taskForm.taskType,
         vehicleIds: this.taskForm.vehicleId ? [this.taskForm.vehicleId] : [],
+        assigneeId: this.currentUser.id || this.$store.state.user.userId, // 涓昏鎵ц浜�
+        assigneeIds: (this.currentUser.id || this.$store.state.user.userId) ? [this.currentUser.id || this.$store.state.user.userId] : [], // 鎵ц浜哄憳ID鍒楄〃
         plannedStartTime: this.taskForm.plannedStartTime,
         plannedEndTime: this.taskForm.plannedEndTime,
         departureAddress: this.taskForm.startLocation,
@@ -425,13 +580,16 @@
         remark: this.taskForm.remark
       }
       
-      if (this.addressCoordinates.startLocation) {
-        submitData.departureLongitude = this.addressCoordinates.startLocation.lng
+      // 璋冭瘯锛氭墦鍗版彁浜ゆ暟鎹�
+      console.log('鎻愪氦鏁版嵁:', submitData)
+      
+      if (this.addressCoordinates.startLocation && this.addressCoordinates.startLocation.lon) {
+        submitData.departureLongitude = this.addressCoordinates.startLocation.lon
         submitData.departureLatitude = this.addressCoordinates.startLocation.lat
       }
       
-      if (this.addressCoordinates.endLocation) {
-        submitData.destinationLongitude = this.addressCoordinates.endLocation.lng
+      if (this.addressCoordinates.endLocation && this.addressCoordinates.endLocation.lon) {
+        submitData.destinationLongitude = this.addressCoordinates.endLocation.lon
         submitData.destinationLatitude = this.addressCoordinates.endLocation.lat
       }
       
@@ -450,9 +608,18 @@
         addTask(submitData).then(response => {
           this.loading = false
           this.$modal.showToast('浠诲姟鍒涘缓鎴愬姛')
+          
+          // 寤惰繜璺宠浆锛岃鐢ㄦ埛鐪嬪埌鎴愬姛鎻愮ず
           setTimeout(() => {
-            this.$tab.navigateTo('/pages/task/index')
-          }, 1500)
+            // 璺宠浆鍒颁换鍔″垪琛ㄥ苟瑙﹀彂鍒锋柊
+            uni.switchTab({
+              url: '/pages/task/index',
+              success: () => {
+                // 浣跨敤浜嬩欢鎬荤嚎閫氱煡浠诲姟鍒楄〃椤甸潰鍒锋柊
+                uni.$emit('refreshTaskList')
+              }
+            })
+          }, 1000)
         }).catch(error => {
           this.loading = false
           console.error('浠诲姟鍒涘缓澶辫触:', error)
@@ -540,6 +707,60 @@
         border-radius: 10rpx;
         font-size: 28rpx;
       }
+      
+      // 鍦板潃杈撳叆瀹瑰櫒
+      .address-input-container {
+        position: relative;
+        
+        .form-input {
+          width: 100%;
+          height: 70rpx;
+          padding: 0 20rpx;
+          border: 1rpx solid #eee;
+          border-radius: 10rpx;
+          font-size: 28rpx;
+          box-sizing: border-box;
+        }
+        
+        .address-suggestions {
+          position: absolute;
+          top: 75rpx;
+          left: 0;
+          right: 0;
+          max-height: 400rpx;
+          overflow-y: auto;
+          background-color: white;
+          border: 1rpx solid #eee;
+          border-radius: 10rpx;
+          box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+          z-index: 100;
+          
+          .address-suggestion-item {
+            padding: 20rpx;
+            border-bottom: 1rpx solid #f0f0f0;
+            
+            &:last-child {
+              border-bottom: none;
+            }
+            
+            &:active {
+              background-color: #f5f5f5;
+            }
+            
+            .suggestion-name {
+              font-size: 28rpx;
+              color: #333;
+              margin-bottom: 8rpx;
+              font-weight: 500;
+            }
+            
+            .suggestion-address {
+              font-size: 24rpx;
+              color: #999;
+            }
+          }
+        }
+      }
     }
     
     .form-actions {
@@ -562,34 +783,6 @@
     }
   }
   
-  .map-popup-container {
-    height: 80vh;
-    background-color: white;
-    border-top-left-radius: 20rpx;
-    border-top-right-radius: 20rpx;
-    overflow: hidden;
-    
-    .popup-header {
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      padding: 20rpx 30rpx;
-      border-bottom: 1rpx solid #f0f0f0;
-      
-      .popup-title {
-        font-size: 32rpx;
-        font-weight: bold;
-        color: #333;
-      }
-      
-      .close-btn {
-        width: 50rpx;
-        height: 50rpx;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-      }
-    }
-  }
+
 }
 </style>

--
Gitblit v1.9.1