| | |
| | | options: OptionItem[] = cityOptions.value |
| | | ): WorkbenchEntryContext { |
| | | const routeQuery = route.query as Record<string, unknown>; |
| | | if (hasWorkbenchEntryQuery(routeQuery)) |
| | | if (hasActiveWorkbenchEntryQuery(routeQuery)) |
| | | return resolveWorkbenchEntryContext(routeQuery, options); |
| | | |
| | | const defaultCityValue = options[0]?.value || DEFAULT_CITY_OPTIONS[0].value; |
| | |
| | | ? cityCode |
| | | : defaultCityValue |
| | | : defaultCityValue, |
| | | id: workbenchStore.context.id || undefined, |
| | | type: workbenchStore.context.type || undefined, |
| | | status: workbenchStore.context.status || undefined, |
| | | id: undefined, |
| | | type: undefined, |
| | | status: undefined, |
| | | }; |
| | | } |
| | | |
| | | function shouldConsumeWorkbenchStoreIntent( |
| | | routeQuery: Record<string, unknown> = route.query as Record<string, unknown> |
| | | ) { |
| | | return !hasWorkbenchEntryQuery(routeQuery) && |
| | | !!( |
| | | workbenchStore.context.id || |
| | | workbenchStore.context.type || |
| | | workbenchStore.context.status |
| | | ); |
| | | function buildWorkbenchEntryQueryKey(query: Record<string, unknown>) { |
| | | if (!hasWorkbenchEntryQuery(query)) return ""; |
| | | return [ |
| | | getQueryStringValue(query.tab), |
| | | getQueryStringValue(query.cityCode) || getQueryStringValue(query.cityId), |
| | | getQueryStringValue(query.id) || getQueryStringValue(query.selectedId), |
| | | getQueryStringValue(query.type) || getQueryStringValue(query.mode), |
| | | getQueryStringValue(query.status), |
| | | ].join("|"); |
| | | } |
| | | |
| | | function clearWorkbenchEntryIntentIfNeeded( |
| | | const consumedWorkbenchEntryQueryKey = ref(""); |
| | | |
| | | function hasActiveWorkbenchEntryQuery( |
| | | routeQuery: Record<string, unknown> = route.query as Record<string, unknown> |
| | | ) { |
| | | if (!shouldConsumeWorkbenchStoreIntent(routeQuery)) return; |
| | | workbenchStore.clearEntryIntent(); |
| | | return hasWorkbenchEntryQuery(routeQuery) && |
| | | buildWorkbenchEntryQueryKey(routeQuery) !== consumedWorkbenchEntryQueryKey.value; |
| | | } |
| | | |
| | | function shouldApplyWorkbenchEditIntent(tab: WorkbenchTab, id: string) { |
| | | const entryContext = getWorkbenchEntryContext(cityOptions.value); |
| | | return entryContext.type === "edit" && |
| | | entryContext.tab === tab && |
| | | entryContext.id === id; |
| | | function consumeWorkbenchEntryQuery( |
| | | routeQuery: Record<string, unknown> = route.query as Record<string, unknown> |
| | | ) { |
| | | if (!hasWorkbenchEntryQuery(routeQuery)) return; |
| | | consumedWorkbenchEntryQueryKey.value = buildWorkbenchEntryQueryKey(routeQuery); |
| | | } |
| | | |
| | | const initialEntryContext = getWorkbenchEntryContext(); |
| | |
| | | resetStationForm(tempDetail); |
| | | stationEditSnapshot.value = stationEditPayloadSnapshot.value; |
| | | renderMapEntities(); |
| | | await nextTick(); |
| | | focusSelectedEntity(true); |
| | | startStationPolygonDraw(); |
| | | } |
| | | |
| | |
| | | resetStationForm(detail); |
| | | enterStationDraftByDetail(detail); |
| | | stationEditSnapshot.value = stationEditPayloadSnapshot.value; |
| | | renderMapEntities(); |
| | | } |
| | | |
| | | function closeStationDetailPanelAfterSave(nextSelectedId = "") { |
| | | stationDetailData.value = null; |
| | | stationCreateMode.value = false; |
| | | stationEditMode.value = false; |
| | | stationPanelClosed.value = true; |
| | | selectedCreateTool.value = ""; |
| | | stationEditSnapshot.value = ""; |
| | | selectedStationPointId.value = ""; |
| | | selectedId.value = nextSelectedId; |
| | | stationForm.value = createEmptyStationForm(); |
| | | cleanupStationEditorState(); |
| | | renderMapEntities(); |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | if (isCreatingStation) { |
| | | stationDetailData.value = null; |
| | | stationCreateMode.value = false; |
| | | stationEditMode.value = false; |
| | | stationPanelClosed.value = true; |
| | | selectedCreateTool.value = ""; |
| | | stationEditSnapshot.value = ""; |
| | | selectedId.value = ""; |
| | | stationForm.value = createEmptyStationForm(); |
| | | cleanupStationEditorState(); |
| | | renderMapEntities(); |
| | | closeStationDetailPanelAfterSave(refreshedStation?.id || detail.id); |
| | | window.$message?.success(saveType === 0 ? "保存草稿成功" : "添加成功"); |
| | | return; |
| | | } |
| | | stationDetailData.value = refreshedStation?.raw || detail; |
| | | stationCreateMode.value = false; |
| | | stationEditMode.value = false; |
| | | selectedCreateTool.value = ""; |
| | | stationEditSnapshot.value = ""; |
| | | selectedId.value = refreshedStation?.id || detail.id; |
| | | resetStationForm(refreshedStation?.raw || detail); |
| | | cleanupStationEditorState(); |
| | | renderMapEntities(); |
| | | await nextTick(); |
| | | focusSelectedEntity(true); |
| | | closeStationDetailPanelAfterSave(refreshedStation?.id || detail.id); |
| | | window.$message?.success( |
| | | saveType === 0 ? "保存草稿成功" : isCreatingStation ? "添加成功" : "编辑成功" |
| | | ); |
| | |
| | | } |
| | | if (activeTab.value === "fence" && fenceCreateMode.value) return; |
| | | if (activeTab.value === "fence") { |
| | | const selectedFenceDetailId = String(fenceDetailData.value?.id || ""); |
| | | if ( |
| | | selectedId.value && |
| | | selectedFenceDetailId && |
| | | selectedFenceDetailId === selectedId.value |
| | | ) |
| | | return; |
| | | if (selectedId.value && !list.some((item) => item.id === selectedId.value)) |
| | | selectedId.value = ""; |
| | | return; |
| | |
| | | pointEditSnapshot.value = ""; |
| | | cleanupPointEditMapState(); |
| | | syncPointDetailFromSelected(); |
| | | if ( |
| | | pendingWorkbenchType.value === "edit" || |
| | | shouldApplyWorkbenchEditIntent("point", id) |
| | | ) { |
| | | if (pendingWorkbenchType.value === "edit") { |
| | | handleEnterPointEdit(); |
| | | } |
| | | pendingWorkbenchType.value = ""; |
| | | clearWorkbenchEntryIntentIfNeeded(); |
| | | consumeWorkbenchEntryQuery(); |
| | | return; |
| | | } |
| | | |
| | |
| | | stationDetailData.value = null; |
| | | selectedStationPointId.value = ""; |
| | | await loadFenceDetailData(id); |
| | | if ( |
| | | pendingWorkbenchType.value === "edit" || |
| | | shouldApplyWorkbenchEditIntent("fence", id) |
| | | ) { |
| | | if (pendingWorkbenchType.value === "edit") { |
| | | handleEnterFenceEdit(); |
| | | } |
| | | pendingWorkbenchType.value = ""; |
| | | clearWorkbenchEntryIntentIfNeeded(); |
| | | consumeWorkbenchEntryQuery(); |
| | | await nextTick(); |
| | | focusSelectedEntity(true); |
| | | return; |
| | | } |
| | | |
| | | if (stationPanelClosed.value && pendingWorkbenchType.value !== "edit") return; |
| | | fenceDetailData.value = null; |
| | | const stationDetail = await loadStationDetailData(id); |
| | | if ( |
| | | stationDetail && |
| | | ( |
| | | pendingWorkbenchType.value === "edit" || |
| | | shouldApplyWorkbenchEditIntent("station", id) |
| | | ) |
| | | ) { |
| | | if (stationDetail && pendingWorkbenchType.value === "edit") { |
| | | applyStationEditByDetail(stationDetail); |
| | | } |
| | | pendingWorkbenchType.value = ""; |
| | | clearWorkbenchEntryIntentIfNeeded(); |
| | | consumeWorkbenchEntryQuery(); |
| | | await nextTick(); |
| | | focusSelectedEntity(true); |
| | | }, |
| | |
| | | }); |
| | | |
| | | watch( |
| | | () => [route.name, route.fullPath, workbenchStore.version], |
| | | () => { |
| | | () => [route.name, route.fullPath], |
| | | async () => { |
| | | if (route.name !== "operationWorkbenchMap") return; |
| | | const entryContext = getWorkbenchEntryContext(cityOptions.value); |
| | | const routeQuery = route.query as Record<string, unknown>; |
| | | const hasActiveEntryQuery = hasActiveWorkbenchEntryQuery(routeQuery); |
| | | const cityChanged = cityValue.value !== entryContext.cityCode; |
| | | if (activeTab.value !== entryContext.tab) |
| | | activeTab.value = entryContext.tab; |
| | |
| | | ) { |
| | | handleWorkbenchCreateByTab(entryContext.tab); |
| | | pendingWorkbenchType.value = ""; |
| | | clearWorkbenchEntryIntentIfNeeded(routeQuery); |
| | | consumeWorkbenchEntryQuery(routeQuery); |
| | | } |
| | | else if ( |
| | | entryContext.type === "edit" && |
| | | hasActiveEntryQuery && |
| | | (entryContext.type === "edit" || entryContext.type === "detail") && |
| | | entryContext.id && |
| | | selectedId.value === entryContext.id |
| | | ) { |
| | | if (entryContext.tab === "station") { |
| | | handleEnterStationEdit(); |
| | | } else if (entryContext.tab === "fence") { |
| | | handleEnterFenceEdit(); |
| | | if (entryContext.tab === "fence") { |
| | | const hasLoadedFenceDetail = |
| | | String(fenceDetailData.value?.id || "") === entryContext.id; |
| | | if (!hasLoadedFenceDetail) await loadFenceDetailData(entryContext.id); |
| | | if (entryContext.type === "edit") handleEnterFenceEdit(); |
| | | } else if (entryContext.tab === "station") { |
| | | const hasLoadedStationDetail = |
| | | String(stationDetailData.value?.id || "") === entryContext.id; |
| | | const stationDetail = hasLoadedStationDetail |
| | | ? stationDetailData.value |
| | | : await loadStationDetailData(entryContext.id); |
| | | if (entryContext.type === "edit" && stationDetail) |
| | | applyStationEditByDetail(stationDetail); |
| | | } else if (entryContext.tab === "point") { |
| | | handleEnterPointEdit(); |
| | | syncPointDetailFromSelected(); |
| | | if (entryContext.type === "edit") handleEnterPointEdit(); |
| | | } |
| | | pendingWorkbenchType.value = ""; |
| | | clearWorkbenchEntryIntentIfNeeded(routeQuery); |
| | | consumeWorkbenchEntryQuery(routeQuery); |
| | | return; |
| | | } |
| | | } |
| | | ); |
| | |
| | | } |
| | | |
| | | async function handleSelectItem(id: string) { |
| | | const currentSelectedId = String(selectedId.value || ""); |
| | | const isSameSelection = currentSelectedId === String(id || ""); |
| | | if ( |
| | | activeTab.value === "point" && |
| | | isPointFormMode.value && |
| | |
| | | if (activeTab.value === "fence") fencePanelClosed.value = false; |
| | | if (activeTab.value === "station") stationPanelClosed.value = false; |
| | | selectedId.value = id; |
| | | if (activeTab.value === "station" && !isStationFormMode.value) { |
| | | if (isSameSelection) { |
| | | await loadStationDetailData(id); |
| | | } |
| | | await nextTick(); |
| | | focusSelectedEntity(true); |
| | | return; |
| | | } |
| | | if (activeTab.value === "fence" && !isFenceFormMode.value) { |
| | | await nextTick(); |
| | | focusSelectedEntity(true); |
| | |
| | | ? (res.data as any).records |
| | | : []; |
| | | stationData.value = stationList.map(mapStationApiItemToListItem); |
| | | console.log("[operationWorkbench][station:list]", { |
| | | cityCode: cityValue.value || undefined, |
| | | apiCount: stationList.length, |
| | | mappedCount: stationData.value.length, |
| | | stations: stationList.map((item: any, index: number) => { |
| | | const mappedItem = stationData.value[index]; |
| | | return { |
| | | id: String(item?.id || ""), |
| | | stationName: item?.stationName || "-", |
| | | status: item?.status, |
| | | centerLon: item?.centerLon, |
| | | centerLat: item?.centerLat, |
| | | fencePoints: item?.fencePoints || "", |
| | | fencePointCount: parseFencePoints(item?.fencePoints).length, |
| | | polygonPathCount: Array.isArray(mappedItem?.polygonPath) |
| | | ? mappedItem.polygonPath.length |
| | | : 0, |
| | | }; |
| | | }), |
| | | }); |
| | | } catch (error) { |
| | | console.error("加载场站失败:", error); |
| | | stationData.value = []; |
| | |
| | | if ( |
| | | activeTab.value !== "point" && |
| | | activeTab.value !== "fence" && |
| | | !stationCreateMode.value && |
| | | !selectedId.value && |
| | | pendingWorkbenchType.value !== "create" |
| | | ) { |
| | |
| | | handlePointMapMoveEnd(); |
| | | }); |
| | | map.value.on("moveend", handlePointMapMoveEnd); |
| | | loadWorkbenchData(); |
| | | await loadWorkbenchData(); |
| | | if (isFenceFormMode.value && fenceDetailData.value) { |
| | | enterFenceDraftByDetail(fenceDetailData.value); |
| | | renderMapEntities(); |
| | | await nextTick(); |
| | | focusSelectedEntity(false); |
| | | } |
| | | } catch (error) { |
| | | mapError.value = `地图初始化失败: ${(error as Error).message}`; |
| | | } finally { |
| | |
| | | } |
| | | |
| | | if (layerControl.value.showStation) { |
| | | const stationRenderDiagnostics = visibleStationList.value.map((item) => { |
| | | const polygonPathCount = Array.isArray(item.polygonPath) |
| | | ? item.polygonPath.length |
| | | : 0; |
| | | const hiddenByEditMode = |
| | | !!( |
| | | stationEditMode.value && |
| | | !stationCreateMode.value && |
| | | selectedId.value && |
| | | String(item.id) === String(selectedId.value) |
| | | ); |
| | | return { |
| | | id: String(item.id), |
| | | name: item.name, |
| | | status: item.status, |
| | | polygonPathCount, |
| | | hiddenByEditMode, |
| | | renderable: polygonPathCount >= 3 && !hiddenByEditMode, |
| | | }; |
| | | }); |
| | | console.log("[operationWorkbench][station:render]", { |
| | | activeTab: activeTab.value, |
| | | stationCreateMode: stationCreateMode.value, |
| | | stationEditMode: stationEditMode.value, |
| | | selectedId: selectedId.value, |
| | | visibleStationCount: visibleStationList.value.length, |
| | | renderableCount: stationRenderDiagnostics.filter((item) => item.renderable).length, |
| | | hiddenCount: stationRenderDiagnostics.filter((item) => !item.renderable).length, |
| | | stations: stationRenderDiagnostics, |
| | | }); |
| | | stationPolygons.value = visibleStationList.value |
| | | .filter((item) => Array.isArray(item.polygonPath) && item.polygonPath.length >= 3) |
| | | .filter( |
| | | (item) => |
| | | !( |
| | | isStationFormMode.value && |
| | | stationEditMode.value && |
| | | !stationCreateMode.value && |
| | | selectedId.value && |
| | | String(item.id) === String(selectedId.value) |
| | | ) |
| | |
| | | map.value.setFitView([stationDraftPolygon.value], false, [80, 80, 80, 80]); |
| | | return; |
| | | } |
| | | if (stationCreateMode.value && activeTab.value === "station") { |
| | | if (stationPolygons.value.length && fitView) |
| | | map.value.setFitView(stationPolygons.value, false, [80, 80, 80, 80]); |
| | | return; |
| | | } |
| | | if (!selectedItem.value) return; |
| | | |
| | | if (selectedItem.value.type === "station" && selectedStationPointId.value) { |