董国庆
2026-06-01 32251d164c81714701a1629eebfdfc9e0c47533c
修改问题
3个文件已修改
121 ■■■■■ 已修改文件
src/views/businessOperations/operationWorkbench/list.vue 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/businessOperations/operationWorkbench/map.vue 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/businessOperations/operationWorkbench/workbench.payload.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/businessOperations/operationWorkbench/list.vue
@@ -2322,6 +2322,11 @@
})
const cardClassName = computed(() => activeTab.value === 'point' ? 'point-management-list' : '')
const showBatchExportButton = computed(() => ['point', 'station'].includes(activeTab.value))
const batchExportButtonKey = computed(() => `batch-export-${activeTab.value}`)
const batchExportButtonId = computed(() => activeTab.value === 'station' ? 'exportStationExcel' : 'exportPointExcel')
const batchExportPermissionCode = computed(() => activeTab.value === 'station' ? 202642934 : 202642928)
const batchExportButtonText = computed(() => activeTab.value === 'station' ? '批量导出场站' : '批量导出点位')
const currentOperationLogBusinessType = computed(() => {
  if (activeTab.value === 'fence')
    return 22
@@ -2332,6 +2337,14 @@
function handleOpenOperationLog() {
  showOperationLogModal.value = true
}
function handleBatchExport() {
  if (activeTab.value === 'station') {
    handleStationBatchExport()
    return
  }
  handlePointBatchExport()
}
watch(
@@ -2464,30 +2477,18 @@
            <NButton v-permission="2026051805" @click="handleOpenOperationLog">
              操作日志
            </NButton>
            <template v-if="activeTab === 'point'">
            <template v-if="showBatchExportButton">
              <span v-if="checkedRowKeys.length > 0" class="selected-text">
                已选择{{ checkedRowKeys.length }}条记录
              </span>
              <NButton
                id="exportPointExcel"
                v-permission="202642928"
                :key="batchExportButtonKey"
                :id="batchExportButtonId"
                v-permission="batchExportPermissionCode"
                :disabled="checkedRowKeys.length === 0"
                @click="handlePointBatchExport"
                @click="handleBatchExport"
              >
                批量导出点位
              </NButton>
            </template>
            <template v-else-if="activeTab === 'station'">
              <span v-if="checkedRowKeys.length > 0" class="selected-text">
                已选择 {{ checkedRowKeys.length }} 条记录
              </span>
              <NButton
                id="exportStationExcel"
                v-permission="202642934"
                :disabled="checkedRowKeys.length === 0"
                @click="handleStationBatchExport"
              >
                批量导出场站
                {{ batchExportButtonText }}
              </NButton>
            </template>
          </n-flex>
src/views/businessOperations/operationWorkbench/map.vue
@@ -1337,8 +1337,17 @@
  if (!isStationFormMode.value) return "";
  if (!stationForm.value.stationName.trim()) return "请输入场站名称";
  if (stationDraftPoints.value.length < 3) return "请先在运营区内绘制场站";
  const geometryError = getStationGeometryInvalidReason(stationDraftPoints.value);
  const geometryError = getStationGeometryInvalidReason(stationDraftPoints.value, {
    allowOutsideOperationArea: isStationEditWorkflow.value,
  });
  if (geometryError) return geometryError;
  if (
    isStationEditWorkflow.value &&
    !resolveStationOperationAreaByPolygon(stationDraftPoints.value) &&
    Number(stationForm.value.areaStatus || 1) === 1
  ) {
    return "当前场站不在围栏区域内,不允许启用";
  }
  if (!stationForm.value.parkingTimeLimit) return "请输入限停时长";
  return getStationCustomTimeErrorMessage();
});
@@ -1587,14 +1596,25 @@
    .filter((item) => item.points.length >= 3);
}
function getStationGeometryInvalidReason(points: LngLatTuple[]) {
function resolveStationOperationAreaByPolygon(points: LngLatTuple[]) {
  if (points.length < 3) return null;
  return (
    getStationOperationAreas().find((area) => isRingInRing(points, area.points))
    || null
  );
}
function getStationGeometryInvalidReason(
  points: LngLatTuple[],
  options: {
    allowOutsideOperationArea?: boolean;
  } = {}
) {
  if (points.length < 3) return "请绘制至少3个点的场站";
  if (isFencePolygonSelfIntersect(points)) return "场站区域不允许自相交";
  const operationAreas = getStationOperationAreas();
  const isInsideOperationArea = operationAreas.some((area) =>
    isRingInRing(points, area.points)
  );
  if (!isInsideOperationArea) return "场站需完全处于运营区内";
  const matchedOperationArea = resolveStationOperationAreaByPolygon(points);
  if (!matchedOperationArea && !options.allowOutsideOperationArea)
    return "场站需完全处于运营区内";
  const otherStations = getOtherStations();
  const geometryUtil = (window as any).AMap?.GeometryUtil;
  if (geometryUtil) {
@@ -1622,7 +1642,9 @@
}
function validateStationGeometry(points: LngLatTuple[]) {
  const errorMessage = getStationGeometryInvalidReason(points);
  const errorMessage = getStationGeometryInvalidReason(points, {
    allowOutsideOperationArea: isStationEditWorkflow.value,
  });
  if (errorMessage) {
    window.$message?.warning(errorMessage);
    return false;
@@ -2774,23 +2796,14 @@
function resolveStationOperationArea() {
  if (!fenceAreaData.value.length) return null;
  const draftPolygonPath = clonePolygonPath(stationDraftPoints.value);
  const draftCenter = getPolygonCenter(draftPolygonPath);
  const centerLon = Number.isFinite(Number(draftCenter?.[0]))
    ? Number(draftCenter?.[0])
    : selectedItem.value?.type === "station"
    ? Number(selectedItem.value.lng)
    : NaN;
  const centerLat = Number.isFinite(Number(draftCenter?.[1]))
    ? Number(draftCenter?.[1])
    : selectedItem.value?.type === "station"
    ? Number(selectedItem.value.lat)
    : NaN;
  if (!Number.isFinite(centerLon) || !Number.isFinite(centerLat)) return null;
  return resolveOperationArea(
    fenceAreaData.value,
    centerLon,
    centerLat
  if (draftPolygonPath.length >= 3)
    return resolveStationOperationAreaByPolygon(draftPolygonPath);
  const detailPolygonPath = clonePolygonPath(
    stationDetailData.value?.polygonPath || stationForm.value.polygonPath
  );
  if (detailPolygonPath.length >= 3)
    return resolveStationOperationAreaByPolygon(detailPolygonPath);
  return null;
}
const stationLifecycleCache = ref<Record<string, Record<string, any> | null>>({});
@@ -2844,6 +2857,7 @@
}
const stationOperationLifecycle = computed(() => {
  if (!stationOperationArea.value) return null;
  const detailLifecycle = normalizeStationLifecycleSource(stationDetailData.value);
  if (detailLifecycle) return detailLifecycle;
  return stationOperationLifecycleFallback.value;
@@ -3332,14 +3346,7 @@
      ? Number(polygonCenter?.[1])
      : undefined;
    const currentSelectedStation = selectedItem.value;
    const operationArea =
      polygonCenter && fenceAreaData.value.length
        ? resolveOperationArea(
            fenceAreaData.value,
            Number(polygonCenter[0]),
            Number(polygonCenter[1])
          )
        : null;
    const operationArea = resolveStationOperationAreaByPolygon(polygonPath);
    const stationArea = Number(calcFenceArea(polygonPath).toFixed(2));
    const detail = {
      id:
@@ -3444,6 +3451,14 @@
  }
}
watch(
  [isStationEditWorkflow, stationOperationArea, () => stationForm.value.areaStatus],
  ([editing, operationArea, areaStatus]) => {
    if (!editing || operationArea || Number(areaStatus) !== 1) return;
    stationForm.value.areaStatus = 2;
  }
);
// tab 切换时重置左侧筛选与选中态,并按目标 tab 刷新对应资源。
watch(activeTab, async (value) => {
  keyword.value = "";
src/views/businessOperations/operationWorkbench/workbench.payload.ts
@@ -337,6 +337,7 @@
  );
  // 场站保存状态码。
  const statusCode = getStationStatusCode(saveType, areaStatus);
  const shouldClearOperationArea = !isCreatingStation && !operationArea;
  return omitUndefinedFields({
    ...(isCreatingStation ? {} : { id: Number(detailId) }),
@@ -347,11 +348,15 @@
    electronicAreaId:
      operationArea?.id !== undefined && operationArea?.id !== null
        ? Number(operationArea.id)
        : shouldClearOperationArea
        ? null
        : undefined,
    electronicId:
      operationArea?.electronicId !== undefined &&
      operationArea?.electronicId !== null
        ? Number(operationArea.electronicId)
        : shouldClearOperationArea
        ? null
        : undefined,
    fencePoints: stringifyFencePoints(polygonPath) || undefined,
    operationType: Number(operationType || 1),