From 7aff31e97ba8c49b9325bc80ebb281339e9d2193 Mon Sep 17 00:00:00 2001
From: 董国庆 <364620639@qq.com>
Date: 星期四, 14 五月 2026 09:45:56 +0800
Subject: [PATCH] feat(pointManagement): 优化点位点击逻辑,调整接口ID类型并重构数据处理

---
 src/service/api/point.ts                               |    2 
 src/service/api/copyText.ts                            |    2 
 src/views/businessOperations/pointManagement/index.vue |  151 ++++++++++++++----------
 src/views/testDemo/testPointManagement/index.vue       |  154 ++++++++++++++-----------
 4 files changed, 174 insertions(+), 135 deletions(-)

diff --git a/src/service/api/copyText.ts b/src/service/api/copyText.ts
index 3cb3752..b02633e 100644
--- a/src/service/api/copyText.ts
+++ b/src/service/api/copyText.ts
@@ -20,7 +20,7 @@
   return request.Post<Service.ResponseResult<any>>('/map/api/v1/testPoint/enableDisable', data)
 }
 
-export function fetchPointDetail(id: number) {
+export function fetchPointDetail(id: string) {
   return request.Get<Service.ResponseResult<Entity.Point>>('/map/api/v1/testPoint/queryById', { params: { id } })
 }
 
diff --git a/src/service/api/point.ts b/src/service/api/point.ts
index 9caf1f8..ac9fead 100644
--- a/src/service/api/point.ts
+++ b/src/service/api/point.ts
@@ -19,7 +19,7 @@
   return request.Post<Service.ResponseResult<any>>('/map/api/v1/point/enableDisable', data)
 }
 
-export function fetchPointDetail(id: number) {
+export function fetchPointDetail(id: string) {
   return request.Get<Service.ResponseResult<Entity.Point>>('/map/api/v1/point/queryById', { params: { id } })
 }
 
diff --git a/src/views/businessOperations/pointManagement/index.vue b/src/views/businessOperations/pointManagement/index.vue
index 54857eb..5a43b26 100644
--- a/src/views/businessOperations/pointManagement/index.vue
+++ b/src/views/businessOperations/pointManagement/index.vue
@@ -2,7 +2,7 @@
 import { computed, nextTick, onMounted, onUnmounted, ref, shallowRef, watch } from 'vue'
 import { useScriptTag } from '@vueuse/core'
 import { useRoute } from 'vue-router'
-import { createPoint, deletePoint, enableDisablePoint, fetchElectronicFenceAreaList, fetchPointList, updatePoint } from '@/service/api/point'
+import { createPoint, deletePoint, enableDisablePoint, fetchElectronicFenceAreaList, fetchPointDetail, fetchPointList, updatePoint } from '@/service/api/point'
 import PointStatusSteps from '@/components/PointStatusSteps/custom.vue'
 import ConfirmDialog from '@/components/ConfirmDialog/index.vue'
 import { debounce } from 'radash'
@@ -138,6 +138,7 @@
 
 const pointList = ref<any[]>([])
 const allPoints = ref<any[]>([])
+let pointDetailRequestId = 0
 
 async function initMap() {
   try {
@@ -314,35 +315,45 @@
   startAddFromAmap(point)
 }
 
-// 点击点位
-function handlePointClick(point: any) {
-  console.log('point', point)
-  isCollapsed.value = false
-  activePointId.value = point.id
-  editPointSnapshot.value = null
-  currentPoint.value = JSON.parse(JSON.stringify(point)) // 深拷贝,避免直接修改列表数据
-  pointDetailMode.value = 'view'
-  isStatusModified.value = false
-
-  if (point.source === 'amap') {
-    operationTimeType.value = 'sync'
-    customTimeRanges.value = [{ id: Date.now(), startTime: null, endTime: null }]
-    selectedEffectivePeriod.value = 1
-    uploadedImages.value = []
-    return
+function normalizePointData(point: any) {
+  return {
+    ...point,
+    id: point.id,
+    pointNumber: point.pointNumber,
+    name: point.pointName || point.name || '',
+    address: point.pointAddress || point.address || '',
+    status: point.status || getPointStatusText(point.operationStatus, point.verificationStatus),
+    verificationStatus: point.verificationStatus,
+    operationStatus: point.operationStatus,
+    lon: point.pointLon ?? point.lon,
+    lat: point.pointLat ?? point.lat,
+    remark: point.remarks ?? point.remark ?? '',
+    limitTime: point.parkingTimeLimit ?? point.limitTime ?? '',
+    operationType: point.operationType,
+    effectivePeriod: point.effectivePeriod,
+    effectiveTimePeriod: point.effectiveTimePeriod,
+    pointPictures: point.pointPictures,
+    updateBy: point.updateBy,
+    updateTime: point.updateTime,
+    source: point.source || 'api',
   }
+}
 
-  if (map.value && point.pointLon && point.pointLat) {
-    map.value.setCenter([Number(point.pointLon), Number(point.pointLat)])
+function applyPointDetail(point: any) {
+  const normalizedPoint = normalizePointData(point)
+  currentPoint.value = JSON.parse(JSON.stringify(normalizedPoint))
+
+  if (map.value && normalizedPoint.lon && normalizedPoint.lat) {
+    map.value.setCenter([Number(normalizedPoint.lon), Number(normalizedPoint.lat)])
   }
 
   // 处理运营时间回显
-  if (point.operationType === '2' || point.operationType === 2) {
+  if (normalizedPoint.operationType === '2' || normalizedPoint.operationType === 2) {
     operationTimeType.value = 'custom'
-    selectedEffectivePeriod.value = Number(point.effectivePeriod) || 1
-    if (point.effectiveTimePeriod) {
+    selectedEffectivePeriod.value = Number(normalizedPoint.effectivePeriod) || 1
+    if (normalizedPoint.effectiveTimePeriod) {
       try {
-        const ranges = JSON.parse(point.effectiveTimePeriod)
+        const ranges = JSON.parse(normalizedPoint.effectiveTimePeriod)
         if (Array.isArray(ranges)) {
           customTimeRanges.value = ranges.map((rangeStr: string, index: number) => {
             const [start, end] = rangeStr.split('-')
@@ -357,7 +368,7 @@
       catch (e) {
         console.error('解析运营时间段失败:', e)
         // 兼容旧格式 (逗号分隔)
-        const ranges = point.effectiveTimePeriod.split(',')
+        const ranges = normalizedPoint.effectiveTimePeriod.split(',')
         customTimeRanges.value = ranges.map((rangeStr: string, index: number) => {
           const [start, end] = rangeStr.split('-')
           return {
@@ -377,9 +388,9 @@
   }
 
   // 处理图片回显
-  if (point.pointPictures) {
+  if (normalizedPoint.pointPictures) {
     try {
-      const pictures = JSON.parse(point.pointPictures)
+      const pictures = JSON.parse(normalizedPoint.pointPictures)
       if (Array.isArray(pictures)) {
         uploadedImages.value = pictures.map((img: any) => ({
           id: img.id || Date.now() + Math.random(),
@@ -396,13 +407,55 @@
   else {
     uploadedImages.value = []
   }
+}
 
-  // 回显创建人与创建时间(从列表项中获取,或需要后端返回字段支持)
-  // 假设后端返回字段为 updateBy 和 updateTime
-  currentPoint.value.updateBy = point.updateBy
-  currentPoint.value.updateTime = point.updateTime
+// 点击点位
+async function handlePointClick(point: any) {
+  console.log('point', point)
+  isCollapsed.value = false
+  activePointId.value = point.id
+  editPointSnapshot.value = null
+  pointDetailMode.value = 'view'
+  isStatusModified.value = false
 
-  console.log('点击点位:', point)
+  if (point.source === 'amap') {
+    currentPoint.value = JSON.parse(JSON.stringify(point)) // 深拷贝,避免直接修改列表数据
+    operationTimeType.value = 'sync'
+    customTimeRanges.value = [{ id: Date.now(), startTime: null, endTime: null }]
+    selectedEffectivePeriod.value = 1
+    uploadedImages.value = []
+    return
+  }
+
+  const fallbackPoint = normalizePointData(point)
+  const currentRequestId = ++pointDetailRequestId
+
+  try {
+    const pointId = String(point.id || '').trim()
+    if (pointId) {
+      const { data, isSuccess } = await fetchPointDetail(pointId)
+      if (currentRequestId !== pointDetailRequestId) {
+        return
+      }
+      if (isSuccess && data) {
+        applyPointDetail(data)
+        console.log('点击点位(详情接口):', data)
+        return
+      }
+    }
+  }
+  catch (error) {
+    if (currentRequestId !== pointDetailRequestId) {
+      return
+    }
+    console.error('获取点位详情失败,回退列表数据:', error)
+  }
+
+  if (currentRequestId !== pointDetailRequestId) {
+    return
+  }
+  applyPointDetail(fallbackPoint)
+  console.log('点击点位(列表兜底):', fallbackPoint)
 }
 
 // 辅助函数:将 HH:mm 解析为当日的时间戳
@@ -1572,23 +1625,7 @@
       const { data, isSuccess } = await fetchPointList(buildPointListParams())
       if (isSuccess && data) {
         console.log('点位列表:', data)
-        allPoints.value = data.map(point => ({
-          ...point,
-          id: point.id,
-          pointNumber: point.pointNumber, // 显式映射 pointNumber 字段
-          name: point.pointName || '',
-          address: point.pointAddress || '',
-          status: getPointStatusText(point.operationStatus, point.verificationStatus),
-          verificationStatus: point.verificationStatus,
-          operationStatus: point.operationStatus,
-          lon: point.pointLon,
-          lat: point.pointLat,
-          remark: point.remarks || '',
-          limitTime: point.parkingTimeLimit || '',
-          updateBy: point.updateBy,
-          updateTime: point.updateTime,
-          source: 'api',
-        }))
+        allPoints.value = data.map(point => normalizePointData({ ...point, source: 'api' }))
         pointList.value = allPoints.value
         renderPoints(pointList.value)
       }
@@ -1602,23 +1639,7 @@
 
     const apiPoints: any[] = []
     if (apiResult.status === 'fulfilled' && apiResult.value.isSuccess && apiResult.value.data) {
-      apiPoints.push(...apiResult.value.data.map(point => ({
-        ...point,
-        id: point.id,
-        pointNumber: point.pointNumber, // 显式映射 pointNumber 字段
-        name: point.pointName || '',
-        address: point.pointAddress || '',
-        status: getPointStatusText(point.operationStatus, point.verificationStatus),
-        verificationStatus: point.verificationStatus,
-        operationStatus: point.operationStatus,
-        lon: point.pointLon,
-        lat: point.pointLat,
-        remark: point.remarks || '',
-        limitTime: point.parkingTimeLimit || '',
-        updateBy: point.updateBy,
-        updateTime: point.updateTime,
-        source: 'api',
-      })))
+      apiPoints.push(...apiResult.value.data.map(point => normalizePointData({ ...point, source: 'api' })))
     }
 
     const amapPoints: any[] = []
diff --git a/src/views/testDemo/testPointManagement/index.vue b/src/views/testDemo/testPointManagement/index.vue
index c4724a7..e5b836d 100644
--- a/src/views/testDemo/testPointManagement/index.vue
+++ b/src/views/testDemo/testPointManagement/index.vue
@@ -2,7 +2,7 @@
 import { computed, nextTick, onMounted, onUnmounted, ref, shallowRef, watch } from 'vue'
 import { useScriptTag } from '@vueuse/core'
 import { useRoute } from 'vue-router'
-import { createPoint, deletePoint, enableDisablePoint, fetchElectronicFenceAreaList, fetchPointList, updatePoint } from '@/service/api/copyText'
+import { createPoint, deletePoint, enableDisablePoint, fetchElectronicFenceAreaList, fetchPointDetail, fetchPointList, updatePoint } from '@/service/api/copyText'
 import PointStatusSteps from '@/components/PointStatusSteps/custom.vue'
 import ConfirmDialog from '@/components/ConfirmDialog/index.vue'
 import { debounce } from 'radash'
@@ -137,6 +137,7 @@
 
 const pointList = ref<any[]>([])
 const allPoints = ref<any[]>([])
+let pointDetailRequestId = 0
 
 async function initMap() {
   try {
@@ -313,35 +314,45 @@
   startAddFromAmap(point)
 }
 
-// 点击点位
-function handlePointClick(point: any) {
-  console.log('point', point)
-  isCollapsed.value = false
-  activePointId.value = point.id
-  editPointSnapshot.value = null
-  currentPoint.value = JSON.parse(JSON.stringify(point)) // 深拷贝,避免直接修改列表数据
-  pointDetailMode.value = 'view'
-  isStatusModified.value = false
-
-  if (point.source === 'amap') {
-    operationTimeType.value = 'sync'
-    customTimeRanges.value = [{ id: Date.now(), startTime: null, endTime: null }]
-    selectedEffectivePeriod.value = 1
-    uploadedImages.value = []
-    return
+function normalizePointData(point: any) {
+  return {
+    ...point,
+    id: point.id,
+    pointNumber: point.pointNumber,
+    name: point.pointName || point.name || '',
+    address: point.pointAddress || point.address || '',
+    status: point.status || getPointStatusText(point.operationStatus, point.verificationStatus),
+    verificationStatus: point.verificationStatus,
+    operationStatus: point.operationStatus,
+    lon: point.pointLon ?? point.lon,
+    lat: point.pointLat ?? point.lat,
+    remark: point.remarks ?? point.remark ?? '',
+    limitTime: point.parkingTimeLimit ?? point.limitTime ?? '',
+    operationType: point.operationType,
+    effectivePeriod: point.effectivePeriod,
+    effectiveTimePeriod: point.effectiveTimePeriod,
+    pointPictures: point.pointPictures,
+    updateBy: point.updateBy,
+    updateTime: point.updateTime,
+    source: point.source || 'api',
   }
+}
 
-  if (map.value && point.pointLon && point.pointLat) {
-    map.value.setCenter([Number(point.pointLon), Number(point.pointLat)])
+function applyPointDetail(point: any) {
+  const normalizedPoint = normalizePointData(point)
+  currentPoint.value = JSON.parse(JSON.stringify(normalizedPoint))
+
+  if (map.value && normalizedPoint.lon && normalizedPoint.lat) {
+    map.value.setCenter([Number(normalizedPoint.lon), Number(normalizedPoint.lat)])
   }
 
   // 处理运营时间回显
-  if (point.operationType === '2' || point.operationType === 2) {
+  if (normalizedPoint.operationType === '2' || normalizedPoint.operationType === 2) {
     operationTimeType.value = 'custom'
-    selectedEffectivePeriod.value = Number(point.effectivePeriod) || 1
-    if (point.effectiveTimePeriod) {
+    selectedEffectivePeriod.value = Number(normalizedPoint.effectivePeriod) || 1
+    if (normalizedPoint.effectiveTimePeriod) {
       try {
-        const ranges = JSON.parse(point.effectiveTimePeriod)
+        const ranges = JSON.parse(normalizedPoint.effectiveTimePeriod)
         if (Array.isArray(ranges)) {
           customTimeRanges.value = ranges.map((rangeStr: string, index: number) => {
             const [start, end] = rangeStr.split('-')
@@ -355,8 +366,7 @@
       }
       catch (e) {
         console.error('解析运营时间段失败:', e)
-        // 兼容旧格式 (逗号分隔)
-        const ranges = point.effectiveTimePeriod.split(',')
+        const ranges = normalizedPoint.effectiveTimePeriod.split(',')
         customTimeRanges.value = ranges.map((rangeStr: string, index: number) => {
           const [start, end] = rangeStr.split('-')
           return {
@@ -370,15 +380,13 @@
   }
   else {
     operationTimeType.value = 'sync'
-    // 重置自定义时间
     customTimeRanges.value = [{ id: Date.now(), startTime: null, endTime: null }]
     selectedEffectivePeriod.value = 1
   }
 
-  // 处理图片回显
-  if (point.pointPictures) {
+  if (normalizedPoint.pointPictures) {
     try {
-      const pictures = JSON.parse(point.pointPictures)
+      const pictures = JSON.parse(normalizedPoint.pointPictures)
       if (Array.isArray(pictures)) {
         uploadedImages.value = pictures.map((img: any) => ({
           id: img.id || Date.now() + Math.random(),
@@ -395,13 +403,55 @@
   else {
     uploadedImages.value = []
   }
+}
 
-  // 回显创建人与创建时间(从列表项中获取,或需要后端返回字段支持)
-  // 假设后端返回字段为 updateBy 和 updateTime
-  currentPoint.value.updateBy = point.updateBy
-  currentPoint.value.updateTime = point.updateTime
+// 点击点位
+async function handlePointClick(point: any) {
+  console.log('point', point)
+  isCollapsed.value = false
+  activePointId.value = point.id
+  editPointSnapshot.value = null
+  pointDetailMode.value = 'view'
+  isStatusModified.value = false
 
-  console.log('点击点位:', point)
+  if (point.source === 'amap') {
+    currentPoint.value = JSON.parse(JSON.stringify(point)) // 深拷贝,避免直接修改列表数据
+    operationTimeType.value = 'sync'
+    customTimeRanges.value = [{ id: Date.now(), startTime: null, endTime: null }]
+    selectedEffectivePeriod.value = 1
+    uploadedImages.value = []
+    return
+  }
+
+  const fallbackPoint = normalizePointData(point)
+  const currentRequestId = ++pointDetailRequestId
+
+  try {
+    const pointId = String(point.id || '').trim()
+    if (pointId) {
+      const { data, isSuccess } = await fetchPointDetail(pointId)
+      if (currentRequestId !== pointDetailRequestId) {
+        return
+      }
+      if (isSuccess && data) {
+        applyPointDetail(data)
+        console.log('点击点位(详情接口):', data)
+        return
+      }
+    }
+  }
+  catch (error) {
+    if (currentRequestId !== pointDetailRequestId) {
+      return
+    }
+    console.error('获取点位详情失败,回退列表数据:', error)
+  }
+
+  if (currentRequestId !== pointDetailRequestId) {
+    return
+  }
+  applyPointDetail(fallbackPoint)
+  console.log('点击点位(列表兜底):', fallbackPoint)
 }
 
 // 辅助函数:将 HH:mm 解析为当日的时间戳
@@ -1558,23 +1608,7 @@
       const { data, isSuccess } = await fetchPointList(buildPointListParams())
       if (isSuccess && data) {
         console.log('点位列表:', data)
-        allPoints.value = data.map(point => ({
-          ...point,
-          id: point.id,
-          pointNumber: point.pointNumber, // 显式映射 pointNumber 字段
-          name: point.pointName || '',
-          address: point.pointAddress || '',
-          status: getPointStatusText(point.operationStatus, point.verificationStatus),
-          verificationStatus: point.verificationStatus,
-          operationStatus: point.operationStatus,
-          lon: point.pointLon,
-          lat: point.pointLat,
-          remark: point.remarks || '',
-          limitTime: point.parkingTimeLimit || '',
-          updateBy: point.updateBy,
-          updateTime: point.updateTime,
-          source: 'api',
-        }))
+        allPoints.value = data.map(point => normalizePointData({ ...point, source: 'api' }))
         pointList.value = allPoints.value
         renderPoints(pointList.value)
       }
@@ -1588,23 +1622,7 @@
 
     const apiPoints: any[] = []
     if (apiResult.status === 'fulfilled' && apiResult.value.isSuccess && apiResult.value.data) {
-      apiPoints.push(...apiResult.value.data.map(point => ({
-        ...point,
-        id: point.id,
-        pointNumber: point.pointNumber, // 显式映射 pointNumber 字段
-        name: point.pointName || '',
-        address: point.pointAddress || '',
-        status: getPointStatusText(point.operationStatus, point.verificationStatus),
-        verificationStatus: point.verificationStatus,
-        operationStatus: point.operationStatus,
-        lon: point.pointLon,
-        lat: point.pointLat,
-        remark: point.remarks || '',
-        limitTime: point.parkingTimeLimit || '',
-        updateBy: point.updateBy,
-        updateTime: point.updateTime,
-        source: 'api',
-      })))
+      apiPoints.push(...apiResult.value.data.map(point => normalizePointData({ ...point, source: 'api' })))
     }
 
     const amapPoints: any[] = []

--
Gitblit v1.7.1