1
This commit is contained in:
232
Design/frontend_Design/GridManagementPage_Design.md
Normal file
232
Design/frontend_Design/GridManagementPage_Design.md
Normal file
@@ -0,0 +1,232 @@
|
||||
# 网格管理页面设计文档
|
||||
|
||||
## 1. 页面概述
|
||||
|
||||
网格管理页面允许系统管理员创建、查看、编辑和删除地理网格。每个网格代表一个责任区域,可以关联到特定的主管或网格员。此功能是任务分配和地理数据可视化的基础。
|
||||
|
||||
## 2. 页面布局
|
||||
|
||||

|
||||
|
||||
### 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. 测试用例
|
||||
|
||||
- **集成测试**:
|
||||
- 测试能否成功创建一个新网格,包括在地图上绘制边界和填写信息。
|
||||
- 测试点击列表中的网格,地图上是否正确显示其边界。
|
||||
- 测试编辑功能,包括修改网格信息和在地图上重新编辑边界。
|
||||
- 测试删除网格功能。
|
||||
Reference in New Issue
Block a user