ai-coding
2026-08-19 b13b85ca27404c17d5b7335c0237ee929b3ac32e
feat(workbench): 支持删除已停用电子围栏并同步列表地图入口

Co-Authored-By: 黄星炤 <huangxz@xiaopeng.com>
5个文件已修改
91 ■■■■■ 已修改文件
src/service/api/operations.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/businessOperations/operationWorkbench/components/FencePanel.vue 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/businessOperations/operationWorkbench/list.vue 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/businessOperations/operationWorkbench/map.vue 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/testDemo/operationWorkbench/components/FencePanel.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/service/api/operations.ts
@@ -225,6 +225,11 @@
  return request.Post<Service.ResponseResult<any>>('/map/api/v1/electronicFence/updateStatus', params)
}
// 删除围栏
export function deleteFence(id: number | string) {
  return request.Post<Service.ResponseResult<any>>(`/map/api/v1/electronicFence/delete?id=${id}`)
}
// 获取所有运营中的区域
export function fetchElectronicFenceAreaList() {
  return request.Post<Service.ResponseResult<any>>('/map/api/v1/point/listElectronicFenceArea')
src/views/businessOperations/operationWorkbench/components/FencePanel.vue
@@ -52,6 +52,7 @@
  'view-source',
  'edit-current',
  'stop-current',
  'delete-current',
  'close-panel',
  'cancel-edit',
  'save-draft',
@@ -94,6 +95,10 @@
)
// 停用按钮:围栏已停用(3)时禁用,避免重复操作。
const isStopFenceDisabled = computed(
  () => Number(props.fenceDetailData?.status) === 3,
)
// 删除按钮:仅已停用(3)状态的围栏可删除,与列表页删除条件保持一致。
const isDeletableFence = computed(
  () => Number(props.fenceDetailData?.status) === 3,
)
const showDraftButton = computed(
@@ -1282,6 +1287,14 @@
      </div>
      <div class="drawer-footer">
        <NButton
          v-if="isDeletableFence"
          type="error"
          style="flex: 1;"
          @click="emit('delete-current')"
        >
          删除
        </NButton>
        <NButton
          secondary
          style="flex: 1;"
          :disabled="isStopFenceDisabled"
src/views/businessOperations/operationWorkbench/list.vue
@@ -7,7 +7,7 @@
import SearchPanel from '@/components/custom/SearchPanel.vue'
import OperationLogModal from '@/components/custom/OperationLogModal.vue'
import { useBoolean, usePermission } from '@/hooks'
import { exportFenceExcel, fetchEnabledOpenCityList, getFenceList, updateFenceStatus } from '@/service/api/operations'
import { deleteFence, exportFenceExcel, fetchEnabledOpenCityList, getFenceList, updateFenceStatus } from '@/service/api/operations'
import { deletePoint, enableDisablePoint, exportPointExcel, fetchFenceAndStationAreaList, fetchPointPageList } from '@/service/api/point'
import { deleteStation, exportStationExcel, fetchStationListByElectronicId, fetchStationPageList, updateStationStatus } from '@/service/api/station'
import { useWorkbenchStore } from '@/store'
@@ -1451,6 +1451,32 @@
  })
}
function handleFenceDelete(row: any) {
  dialog.warning({
    title: `确认删除${row.electronicName}吗?`,
    content: '删除后该电子围栏相关配置将永久清除,无法恢复,确定继续删除吗?',
    positiveText: '确定',
    negativeText: '取消',
    maskClosable: false,
    autoFocus: false,
    onPositiveClick: async () => {
      try {
        const res = await deleteFence(row.id)
        if (res.code === 200) {
          message.success('删除成功')
          getList()
        }
        else {
          message.error(res.msg || '删除失败,请稍后重试。')
        }
      }
      catch (e) {
        message.error('删除失败,请稍后重试。')
      }
    },
  })
}
function handlePointDelete(row: any) {
  dialog.warning({
    title: `确认删除${row.pointName}吗?`,
@@ -2568,6 +2594,11 @@
              <NButton v-permission="202642922" text type="primary" disabled={Number(row.status) === 3} onClick={() => handleFenceDisable(row)}>
                停用
              </NButton>
              {Number(row.status) === 3 && (
                <NButton v-permission="202642923" text type="primary" onClick={() => handleFenceDelete(row)}>
                  删除
                </NButton>
              )}
            </NSpace>
          )
        },
src/views/businessOperations/operationWorkbench/map.vue
@@ -32,6 +32,7 @@
} from '@/service/api/station'
import {
  addFence,
  deleteFence,
  editFence,
  fetchEnabledOpenCityList,
  getFenceDetail,
@@ -7744,6 +7745,38 @@
  }
}
async function handleDeleteCurrentFence() {
  const fence = fenceDetailData.value
  if (!fence?.id)
    return
  const confirmed = await openConfirmDialog(
    `确认删除${fence.electronicName}吗?`,
    '删除后该电子围栏相关配置将永久清除,无法恢复,确定继续删除吗?',
    { positiveText: '确定', negativeText: '取消' },
  )
  if (!confirmed)
    return
  try {
    const res = await deleteFence(fence.id)
    if (res.code === 200) {
      window.$message?.success('删除成功')
      const workflowState = buildFenceClosePanelState()
      fencePanelClosed.value = workflowState.fencePanelClosed
      readonlyRestrictedAreaId.value = ''
      selectedId.value = ''
      fenceDetailData.value = null
      workbenchStore.markListNeedRefresh()
      renderMapEntities()
    }
    else {
      window.$message?.error(res.msg || '删除失败,请稍后重试。')
    }
  }
  catch (e) {
    window.$message?.error('删除失败,请稍后重试。')
  }
}
async function handleWorkbenchCreateByTab(tab: WorkbenchTab) {
  if (tab !== 'station')
    return
@@ -10348,6 +10381,7 @@
          @view-source="handleViewSourcePage"
          @edit-current="handleEnterFenceEdit"
          @stop-current="handleStopCurrentFence"
          @delete-current="handleDeleteCurrentFence"
          @close-panel="handleCloseFencePanel"
          @cancel-edit="handleCancelFenceEdit"
          @save-draft="() => handleSaveFenceEdit(0)"
src/views/testDemo/operationWorkbench/components/FencePanel.vue
@@ -1257,8 +1257,8 @@
          </div>
        </div>
      </div>
      <!-- 运营围栏在测试工作台只允许查看详情,不展示底部编辑入口。 -->
      <div v-if="!isLocked" class="drawer-footer">
      <!-- 运营围栏在测试工作台只允许查看详情,不展示底部编辑入口;但已停用/草稿等可删除状态下仍展示删除入口。 -->
      <div v-if="!isLocked || isDeletableFence" class="drawer-footer">
        <NButton
          v-if="isDeletableFence"
          type="error"
@@ -1267,7 +1267,7 @@
        >
          删除
        </NButton>
        <NButton type="primary" style="flex: 1;" @click="emit('edit-current')">
        <NButton v-if="!isLocked" type="primary" style="flex: 1;" @click="emit('edit-current')">
          编辑
        </NButton>
      </div>