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

232 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 网格管理页面设计文档
## 1. 页面概述
网格管理页面允许系统管理员创建、查看、编辑和删除地理网格。每个网格代表一个责任区域,可以关联到特定的主管或网格员。此功能是任务分配和地理数据可视化的基础。
## 2. 页面布局
![网格管理页面布局示意图](https://placeholder-for-grid-page-mockup.png)
### 2.1 布局结构
页面由两部分组成:
- **左侧**: 网格列表,以表格形式展示所有已定义的网格及其基本信息(名称、负责人等)。
- **右侧**: 交互式地图,用于可视化展示所选网格的地理边界。当创建或编辑网格时,地图将进入绘图模式。
## 3. 组件结构
```vue
<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. 数据结构
```typescript
// 网格列表项
interface GridListItem {
id: number;
name: string;
manager?: string;
// GeoJSON 字符串
geometry: string;
}
// 网格表单数据 (用于对话框)
interface GridFormData {
id?: number;
name: string;
managerId?: number;
// GeoJSON 字符串
geometry: string;
}
```
## 5. 状态管理
```typescript
// 地图实例
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 地图与列表交互
```typescript
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 操作
```typescript
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 调用
```typescript
// 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. 样式设计
```scss
.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. 测试用例
- **集成测试**:
- 测试能否成功创建一个新网格,包括在地图上绘制边界和填写信息。
- 测试点击列表中的网格,地图上是否正确显示其边界。
- 测试编辑功能,包括修改网格信息和在地图上重新编辑边界。
- 测试删除网格功能。