import { ecologicalProtectionMenu } from "@/config/ecologicalProtection" export { ecologicalProtectionMenu } const round = (value, digits = 2) => Number(Number(value || 0).toFixed(digits)) const ecologicalDirectPanelDefinitions = { left: [ { key: "grasslandDistribution", title: "草地分布", type: "column", variant: "plain", labelMode: "horizontal", scrollable: false, span: 1 }, { key: "wetlandDistribution", title: "湿地面积", type: "rank", labelMode: "horizontal", scrollable: false, span: 1 }, { key: "woodlandDistribution", title: "林地分布", type: "split", variant: "compact", span: 1 }, { key: "grasslandProductivity", title: "草地生产力", type: "line", fixedType: true, labelMode: "horizontal", span: 1 }, ], right: [ { key: "grasslandTypes", title: "草原类型", type: "donut", variant: "ring", span: 1 }, { key: "grasslandLevels", title: "草原级占比", type: "rose", span: 1 }, { key: "woodlandQuality", title: "林地质量", type: "heat", limit: 6, span: 1 }, { key: "resourceStructure", title: "林草湿面积构成", type: "structure", span: 1 }, ], } function buildEcologicalDirectPanels(panels = {}) { return Object.fromEntries( Object.entries(ecologicalDirectPanelDefinitions).map(([side, definitions]) => [ side, definitions.map((definition) => ({ ...definition, rows: Array.isArray(panels?.[definition.key]?.rows) ? panels[definition.key].rows : [], count: panels?.[definition.key]?.count, })), ]), ) } export const buildEcologicalRedlinePanels = buildEcologicalDirectPanels export const buildNaturalProtectedAreaPanels = buildEcologicalDirectPanels function normalizeEcologicalRows(value = []) { let rows = value if (rows && typeof rows === "object" && !Array.isArray(rows) && "value" in rows) { rows = rows.value } if (typeof rows === "string") { try { rows = JSON.parse(rows) } catch { rows = [] } } return (Array.isArray(rows) ? rows : []).map((item, index) => ({ ...item, key: item.key || `ecological-${item.name || item.zh || index}`, name: item.name || item.zh || `统计项${index + 1}`, value: Number.isFinite(Number(item.value)) ? round(item.value, 2) : item.value, })) } function getNationalParkRows(stats, key) { return stats?.[key]?.rows || [] } function getNationalParkPanelRows(stats, key) { return stats?.panels?.[key]?.rows || [] } export function getNationalParkTopStats(stats = {}) { return getNationalParkRows(stats, "topRows") } export function getNationalParkCoreRows(stats = {}) { return getNationalParkRows(stats, "coreRows") } export function getNationalParkTownRows(stats = {}) { return getNationalParkRows(stats, "townRows") } export function buildNationalParkPanels(stats = {}) { return { left: [ { key: "park-town-grass-wet-area", title: "草地湿地面积分布", type: "stackColumn", variant: "parkSlim", showValue: true, sharedScale: true, unit: "万亩", segments: [ { key: "grassland", name: "草地面积", color: "#24f6c4" }, { key: "wetland", name: "湿地面积", color: "#8bf7ff" }, ], rows: getNationalParkPanelRows(stats, "townResource"), }, { key: "park-town-productivity", title: "草地湿地生产力", type: "line", fixedType: true, labelMode: "horizontal", showValues: true, unit: "万吨", rows: getNationalParkPanelRows(stats, "townProductivity"), }, { key: "park-town-yak", title: "乡镇牦牛数量", type: "bar", variant: "parkBar", rows: getNationalParkPanelRows(stats, "townYak"), }, { key: "park-town-balance", title: "草畜平衡超载率", type: "balanceGaugeGrid", limit: 1, rows: getNationalParkPanelRows(stats, "balance"), }, ], right: [ { key: "park-zoning-structure", title: "红原管控区结构", type: "donut", rows: getNationalParkPanelRows(stats, "zoning"), }, { key: "park-town-household", title: "牧户分布", type: "split", rows: getNationalParkPanelRows(stats, "townHousehold"), }, { key: "park-town-ecology-job", title: "公益岗位分布", type: "column", variant: "plain", rows: getNationalParkPanelRows(stats, "townJob"), }, ], } } export function getEcologicalRestorationTopStats(stats = {}) { return normalizeEcologicalRows(stats.topRows).map((item, index) => ({ icon: item.icon || (index % 2 === 0 ? "xiaoshoujine" : "zongxiaoliang"), en: "", ...item, })) } export function getEcologicalEngineeringAnalysisTopStats(stats = {}) { return normalizeEcologicalRows(stats.topRows).map((item, index) => ({ icon: item.icon || (index % 2 === 0 ? "xiaoshoujine" : "zongxiaoliang"), en: "", ...item, })) } export function getEcologicalEngineeringTypeRows(stats = {}) { return normalizeEcologicalRows(stats.engineeringTypes).map((item) => ({ ...item, value: Number(item.baseCount || 0), unit: "个图斑", extra: `候选面积 ${round(item.baseAreaWanMu, 2)}万亩`, })) } export function getEcologicalEngineeringTownRows(stats = {}) { return normalizeEcologicalRows(stats.townRows).map((item) => ({ ...item, value: Number(item.candidateFeatureCount || 0), unit: "个图斑", extra: `候选面积 ${round(item.candidateAreaWanMu, 2)}万亩`, })) } function getRestorationScale(item = {}) { const area = Number(item.areaWanMu || 0) const length = Number(item.lengthKm || 0) if (area > 0) return { value: round(area, 2), unit: "万亩", metric: "治理面积" } if (length > 0) return { value: round(length, 2), unit: "公里", metric: "工程长度" } return { value: Number(item.subjectFeatureCount || 0), unit: "个", metric: "主体要素" } } export function getEcologicalRestorationProjectRows(stats = {}) { return normalizeEcologicalRows(stats.projectRows).map((item, index) => { const scale = getRestorationScale(item) const measure = String(item.measureTypes || "") const townships = String(item.townships || "") const year = item.year || "未知" return { ...item, index: index + 1, name: item.projectName, category: item.projectCategory, year, areaWanMu: round(item.areaWanMu, 4), lengthKm: round(item.lengthKm, 2), measure, townships, subjectFeatureCount: Number(item.subjectFeatureCount || 0), value: scale.value, unit: scale.unit, metric: scale.metric, extra: [year, measure].filter(Boolean).join(" / "), searchText: [item.projectName, item.projectCategory, year, measure, townships].filter(Boolean).join(" "), } }) } export function buildEcologicalRestorationPanels(stats = {}) { const yearRows = normalizeEcologicalRows(stats.yearRows) const townRows = normalizeEcologicalRows(stats.townRows) const categoryRows = normalizeEcologicalRows(stats.categoryRows) const measureRows = normalizeEcologicalRows(stats.measureRows) const projectRows = getEcologicalRestorationProjectRows(stats) return { left: [ { key: "restoration-year-area", title: "治理面积分布", type: "line", labelMode: "horizontal", rows: yearRows.map((item) => ({ ...item, value: round(item.areaWanMu, 2), unit: "万亩", extra: `${Number(item.projectCount || 0)}个项目`, })), }, { key: "restoration-town-area", title: "乡镇治理面积分布", type: "column", variant: "plain", labelMode: "horizontal", scrollable: false, rows: townRows.map((item) => ({ ...item, value: round(item.areaWanMu, 2), unit: "万亩", extra: `${round(item.lengthKm, 2)}公里`, })), }, { key: "restoration-category", title: "修复类型占比", type: "donut", rows: categoryRows.map((item) => ({ ...item, ...getRestorationScale(item), extra: `${Number(item.subjectFeatureCount || 0)}个图斑`, })), }, { key: "restoration-year-length", title: "年度工程长度", type: "bar", variant: "rankBar", labelMode: "horizontal", rows: yearRows .filter((item) => Number(item.lengthKm) > 0) .map((item) => ({ ...item, value: round(item.lengthKm, 2), unit: "公里", extra: `${Number(item.projectCount || 0)}个项目`, })), }, ], right: [ { key: "restoration-measure-area", title: "修复措施统计", type: "structure", rows: measureRows.slice(0, 8).map((item) => ({ ...item, ...getRestorationScale(item), extra: `${Number(item.projectCount || 0)}个项目`, })), }, { key: "restoration-year-project", title: "年度项目数量", type: "heat", labelMode: "horizontal", rows: yearRows .filter((item) => item.name !== "未知") .map((item) => ({ ...item, value: Number(item.projectCount || 0), unit: "个", extra: `${round(item.areaWanMu, 2)}万亩`, })), }, { key: "restoration-projects", title: "重点项目库", type: "projectTable", span: 2, columns: [ { key: "name", label: "项目名称", field: "name", width: "58%", className: "business-project-col-name" }, { key: "year", label: "年份", field: "year", width: "16%", fallback: "未知", align: "right", className: "business-project-col-year" }, { key: "category", label: "类型", field: "category", width: "26%", className: "business-project-col-category" }, ], rows: projectRows, }, ], } } export const engineeringAnalysisPanels = { left: [], right: [], } export const centerMapNotes = { "ecological-redline": { title: "红原县生态保护红线", subtitle: "保护范围 / 林草湿资源 / 生产力统计", tags: ["红线范围", "草地", "湿地", "林地"], }, "natural-protected-area": { title: "红原县自然保护地", subtitle: "功能分区 / 林草湿资源 / 生产力统计", tags: ["核心保护区", "一般控制区", "草地", "湿地"], }, "national-park": { title: "若尔盖国家公园红原区域", subtitle: "核心保护区 / 一般控制区 / 生态资源统计", tags: ["植被盖度", "草地面积", "湿地面积", "牧户牦牛"], }, restoration: { title: "生态修复工程项目库", subtitle: "草地修复 / 湿地修复 / 林地修复 / 水源涵养", tags: ["项目库", "治理面积", "工程长度", "乡镇排行"], }, "engineering-analysis": { title: "生态工程分析", subtitle: "工程初筛 / 乡镇筛选 / 近年项目排除", tags: ["封山育林", "草原改良", "人工种草", "空间分析"], }, } export function getEcologicalMapRanking(viewKey, stats = {}) { if (["ecological-redline", "natural-protected-area"].includes(viewKey)) { return { status: "success", title: viewKey === "natural-protected-area" ? "自然保护地" : "生态保护红线", metricLabel: "", unit: "", rows: [], } } if (viewKey === "restoration") { return { status: "success", title: "乡镇治理排行", metricLabel: "治理面积", unit: "万亩", rows: normalizeEcologicalRows(stats.townRows).map((item) => ({ name: item.name, value: round(item.areaWanMu, 2), unit: "万亩", })), } } if (viewKey === "engineering-analysis") { return { status: "success", title: "工程分析", metricLabel: "", unit: "", rows: [], } } return { status: "success", title: "国家公园乡镇划定面积", scope: "town", hideTownNames: false, onlyRankedTownLabels: true, metricLabel: "划定面积", unit: "万亩", rows: getNationalParkTownRows(stats).map((item) => ({ name: item.name, value: item.value, unit: "万亩", metricLabel: "划定面积", })), } }