Files
Environment-Monitoring-System/Design/frontend_Design/GridManagementPage_Design.md
ChuXun 4ce487588a 1
2025-10-19 20:31:01 +08:00

6.3 KiB
Raw Blame History

网格管理页面设计文档

1. 页面概述

网格管理页面允许系统管理员创建、查看、编辑和删除地理网格。每个网格代表一个责任区域,可以关联到特定的主管或网格员。此功能是任务分配和地理数据可视化的基础。

2. 页面布局

网格管理页面布局示意图

2.1 布局结构

页面由两部分组成:

  • 左侧: 网格列表,以表格形式展示所有已定义的网格及其基本信息(名称、负责人等)。
  • 右侧: 交互式地图,用于可视化展示所选网格的地理边界。当创建或编辑网格时,地图将进入绘图模式。

3. 组件结构

<template>
  <div class="grid-management-page">
    <el-page-header title="网格管理" content="定义地理责任区" />

    <el-row :gutter="20" class="page-container">
      <!-- 左侧网格列表与操作 -->
      <el-col :span="10" :xs="24">
        <el-card>
          <template #header>
            <div class="table-toolbar">
              <span>网格列表</span>
              <el-button type="primary" icon="Plus" @click="handleCreate">新建网格</el-button>
            </div>
          </template>
          <el-table :data="grids" v-loading="loading" @row-click="handleRowClick" highlight-current-row>
            <el-table-column prop="name" label="网格名称" />
            <el-table-column prop="manager" label="负责人" />
            <el-table-column label="操作" width="120">
              <template #default="{ row }">
                <el-button link type="primary" @click.stop="handleEdit(row)">编辑</el-button>
                <el-popconfirm title="确定删除此网格?" @confirm="handleDelete(row)">
                  <template #reference>
                    <el-button link type="danger" @click.stop>删除</el-button>
                  </template>
                </el-popconfirm>
              </template>
            </el-table-column>
          </el-table>
        </el-card>
      </el-col>

      <!-- 右侧地图显示 -->
      <el-col :span="14" :xs="24">
        <el-card>
          <template #header>地图预览</template>
          <div ref="mapContainer" class="map-container"></div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 网格编辑/创建对话框 -->
    <GridFormDialog v-model="dialogVisible" :grid-id="selectedGridId" @success="onFormSuccess" />
  </div>
</template>

4. 数据结构

// 网格列表项
interface GridListItem {
  id: number;
  name: string;
  manager?: string;
  // GeoJSON 字符串
  geometry: string; 
}

// 网格表单数据 (用于对话框)
interface GridFormData {
  id?: number;
  name: string;
  managerId?: number;
  // GeoJSON 字符串
  geometry: string;
}

5. 状态管理

// 地图实例
let mapInstance = null;
let currentGridLayer = null;

// 组件内状态
const mapContainer = ref<HTMLElement>();
const dialogVisible = ref(false);
const selectedGridId = ref<number | null>(null);

// 全局状态 (Pinia Store)
const gridStore = useGridStore();
const { grids, loading } = storeToRefs(gridStore);

6. 交互逻辑

6.1 地图与列表交互

onMounted(() => {
  gridStore.fetchGrids();
  initializeMap();
});

const initializeMap = () => {
  // ... 地图初始化逻辑
};

// 点击表格行,在地图上高亮显示对应网格
const handleRowClick = (row: GridListItem) => {
  if (currentGridLayer) {
    mapInstance.removeLayer(currentGridLayer);
  }
  if (row.geometry) {
    const geoJson = JSON.parse(row.geometry);
    currentGridLayer = L.geoJSON(geoJson).addTo(mapInstance);
    mapInstance.fitBounds(currentGridLayer.getBounds());
  }
};

6.2 CRUD 操作

const handleCreate = () => {
  selectedGridId.value = null;
  dialogVisible.value = true;
};

const handleEdit = (grid: GridListItem) => {
  selectedGridId.value = grid.id;
  dialogVisible.value = true;
};

const handleDelete = async (grid: GridListItem) => {
  await gridStore.deleteGrid(grid.id);
  ElMessage.success('网格删除成功');
  gridStore.fetchGrids();
};

const onFormSuccess = () => {
  dialogVisible.value = false;
  gridStore.fetchGrids();
};

7. API 调用

// api/grid.ts
export const gridApi = {
  getGrids: () => apiClient.get('/grid'),
  getGridById: (id: number) => apiClient.get(`/grid/${id}`),
  createGrid: (data: GridFormData) => apiClient.post('/grid', data),
  updateGrid: (id: number, data: GridFormData) => apiClient.put(`/grid/${id}`, data),
  deleteGrid: (id: number) => apiClient.delete(`/grid/${id}`),
};

// stores/grid.ts
export const useGridStore = defineStore('grid', {
  state: () => ({
    grids: [] as GridListItem[],
    loading: false,
  }),
  actions: {
    async fetchGrids() {
      this.loading = true;
      try {
        const { data } = await gridApi.getGrids();
        this.grids = data;
      } finally {
        this.loading = false;
      }
    },
    // ... create, update, delete actions
  }
});

8. 样式设计

.grid-management-page {
  padding: 24px;

  .page-container {
    margin-top: 24px;
  }

  .table-toolbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  .map-container {
    height: 600px;
  }
}

9. 关联组件

GridFormDialog.vue

这是本页面的核心复杂组件,用于创建和编辑网格。

  • Props: modelValue, gridId
  • 内部组件:
    • 一个表单,包含网格名称、负责人(下拉选择)等字段。
    • 一个内嵌的 Leaflet 地图,用于绘制和编辑网格边界。
  • 功能:
    • 地图绘制: 提供多边形Polygon绘制工具。用户可以在地图上绘制闭合区域来定义网格边界。
    • 数据加载: 在编辑模式下,根据 gridId 加载网格数据,并在表单和内嵌地图上显示。
    • 数据保存: 用户完成绘制和表单填写后,点击保存。组件将绘制的多边形转换为 GeoJSON 字符串,连同表单数据一起,调用 store 的 action 进行保存。

10. 测试用例

  • 集成测试:
    • 测试能否成功创建一个新网格,包括在地图上绘制边界和填写信息。
    • 测试点击列表中的网格,地图上是否正确显示其边界。
    • 测试编辑功能,包括修改网格信息和在地图上重新编辑边界。
    • 测试删除网格功能。