267 lines
8.8 KiB
Markdown
267 lines
8.8 KiB
Markdown
# GIS与LLM结合Web应用设计与实施方案
|
||
|
||
## 一、数据库设计
|
||
|
||
### 1.1 核心数据表结构
|
||
|
||
#### 用户表(users)
|
||
| 字段名 | 类型 | 约束 | 描述 |
|
||
|--------|------|------|------|
|
||
| user_id | SERIAL | PRIMARY KEY | 用户唯一标识 |
|
||
| username | VARCHAR(50) | UNIQUE, NOT NULL | 用户名 |
|
||
| email | VARCHAR(100) | UNIQUE, NOT NULL | 用户邮箱 |
|
||
| password_hash | VARCHAR(255) | NOT NULL | 密码哈希 |
|
||
| api_key | VARCHAR(100) | UNIQUE | 第三方API密钥 |
|
||
| role | ENUM('admin', 'user') | DEFAULT 'user' | 用户角色 |
|
||
| created_at | TIMESTAMP | DEFAULT NOW() | 创建时间 |
|
||
| updated_at | TIMESTAMP | DEFAULT NOW() | 更新时间 |
|
||
|
||
#### 对话记录表(conversations)
|
||
| 字段名 | 类型 | 约束 | 描述 |
|
||
|--------|------|------|------|
|
||
| conversation_id | SERIAL | PRIMARY KEY | 对话唯一标识 |
|
||
| user_id | INTEGER | FOREIGN KEY(users.user_id) | 关联用户ID |
|
||
| title | VARCHAR(100) | NOT NULL | 对话标题 |
|
||
| created_at | TIMESTAMP | DEFAULT NOW() | 创建时间 |
|
||
| is_active | BOOLEAN | DEFAULT TRUE | 是否活跃 |
|
||
|
||
#### 对话消息表(conversation_messages)
|
||
| 字段名 | 类型 | 约束 | 描述 |
|
||
|--------|------|------|------|
|
||
| message_id | SERIAL | PRIMARY KEY | 消息唯一标识 |
|
||
| conversation_id | INTEGER | FOREIGN KEY(conversations.conversation_id) | 关联对话ID |
|
||
| sender | ENUM('user', 'system', 'llm') | NOT NULL | 发送者类型 |
|
||
| content | TEXT | NOT NULL | 消息内容 |
|
||
| content_type | ENUM('text', 'image', 'map') | DEFAULT 'text' | 内容类型 |
|
||
| timestamp | TIMESTAMP | DEFAULT NOW() | 发送时间 |
|
||
|
||
#### 空间分析任务表(spatial_tasks)
|
||
| 字段名 | 类型 | 约束 | 描述 |
|
||
|--------|------|------|------|
|
||
| task_id | SERIAL | PRIMARY KEY | 任务唯一标识 |
|
||
| user_id | INTEGER | FOREIGN KEY(users.user_id) | 关联用户ID |
|
||
| conversation_id | INTEGER | FOREIGN KEY(conversations.conversation_id) | 关联对话ID |
|
||
| mcp_service_name | VARCHAR(50) | NOT NULL | MCP服务名称 |
|
||
| tool_name | VARCHAR(50) | NOT NULL | 工具名称 |
|
||
| parameters | JSONB | NOT NULL | 任务参数 |
|
||
| status | ENUM('pending', 'executing', 'success', 'failed') | DEFAULT 'pending' | 任务状态 |
|
||
| result_path | VARCHAR(255) | NULL | 结果存储路径 |
|
||
| started_at | TIMESTAMP | NULL | 开始时间 |
|
||
| completed_at | TIMESTAMP | NULL | 完成时间 |
|
||
|
||
#### MCP服务配置表(mcp_services)
|
||
| 字段名 | 类型 | 约束 | 描述 |
|
||
|--------|------|------|------|
|
||
| service_id | SERIAL | PRIMARY KEY | 服务唯一标识 |
|
||
| name | VARCHAR(100) | NOT NULL | 服务名称 |
|
||
| service_type | ENUM('RESOURCE', 'PROMPT', 'TOOL') | NOT NULL | 服务类型 |
|
||
| description | TEXT | NULL | 服务描述 |
|
||
| url | VARCHAR(255) | NOT NULL | 服务URL |
|
||
| auth_method | ENUM('none', 'api_key', 'oauth2') | DEFAULT 'none' | 认证方式 |
|
||
| auth_config | JSONB | NULL | 认证配置 |
|
||
| schema | JSONB | NULL | 参数JSON Schema |
|
||
| is_official | BOOLEAN | DEFAULT FALSE | 是否官方认证 |
|
||
| created_at | TIMESTAMP | DEFAULT NOW() | 创建时间 |
|
||
|
||
#### 地图图层配置表(map_layers)
|
||
| 字段名 | 类型 | 约束 | 描述 |
|
||
|--------|------|------|------|
|
||
| layer_id | SERIAL | PRIMARY KEY | 图层唯一标识 |
|
||
| user_id | INTEGER | FOREIGN KEY(users.user_id) | 关联用户ID |
|
||
| name | VARCHAR(100) | NOT NULL | 图层名称 |
|
||
| data_source | VARCHAR(255) | NOT NULL | 数据源路径 |
|
||
| style_config | JSONB | NULL | 样式配置 |
|
||
| is_visible | BOOLEAN | DEFAULT TRUE | 是否可见 |
|
||
| z_index | INTEGER | DEFAULT 0 | 图层顺序 |
|
||
| created_at | TIMESTAMP | DEFAULT NOW() | 创建时间 |
|
||
|
||
### 1.2 数据库安全策略
|
||
|
||
#### 行级安全策略(RLS)
|
||
```sql
|
||
-- 启用RLS
|
||
ALTER TABLE spatial_tasks ENABLE ROW LEVEL SECURITY;
|
||
ALTER TABLE map_layers ENABLE ROW LEVEL SECURITY;
|
||
|
||
-- 创建策略
|
||
CREATE POLICY user_spatial_tasks_isolation ON spatial_tasks
|
||
FOR ALL USING (user_id = current_user_id());
|
||
|
||
CREATE POLICY user_layers_isolation ON map_layers
|
||
FOR ALL USING (user_id = current_user_id());
|
||
```
|
||
|
||
#### 索引设计
|
||
```sql
|
||
-- 性能优化索引
|
||
CREATE INDEX idx_spatial_tasks_user_id ON spatial_tasks(user_id);
|
||
CREATE INDEX idx_conversations_user_id ON conversations(user_id);
|
||
CREATE INDEX idx_mcp_services_type ON mcp_services(service_type);
|
||
```
|
||
|
||
## 二、系统模块设计
|
||
|
||
### 2.1 客户端模块
|
||
|
||
#### 2.1.1 UI层
|
||
| 模块 | 核心功能 | 关键函数 |
|
||
|------|----------|----------|
|
||
| 地图组件 | 图层渲染、交互控制 | `renderLayer(layerConfig)`、`handleMapClick(event)` |
|
||
| 对话窗口 | 消息展示、输入处理 | `appendMessage(message)`、`handleSend()` |
|
||
| 任务面板 | 任务列表、状态展示 | `updateTaskStatus(taskId, status)` |
|
||
| 设置面板 | 服务配置、参数调整 | `saveServiceConfig(config)` |
|
||
|
||
#### 2.1.2 Host层
|
||
| 模块 | 核心功能 | 关键函数 |
|
||
|------|----------|----------|
|
||
| LLM客户端 | 大模型请求、流式处理 | `requestStream(prompt, callbacks)` |
|
||
| 工具解析器 | XML解析、参数提取 | `parseToolCall(xmlContent)`、`validateParameters(params)` |
|
||
| 权限管理器 | 用户授权、操作审计 | `requestPermission(action)`、`logAction(action)` |
|
||
|
||
#### 2.1.3 Client层
|
||
| 模块 | 核心功能 | 关键函数 |
|
||
|------|----------|----------|
|
||
| MCP资源客户端 | 资源获取、缓存管理 | `getResource(uri, params)`、`cacheResource(resource)` |
|
||
| MCP工具客户端 | 工具调用、结果处理 | `callTool(toolName, params)`、`handleToolResponse(response)` |
|
||
| MCP提示客户端 | 模板加载、参数替换 | `getPromptTemplate(name)`、`renderPrompt(template, params)` |
|
||
|
||
### 2.2 服务端模块
|
||
|
||
#### 2.2.1 Server层
|
||
| 模块 | 核心功能 | 关键接口 |
|
||
|------|----------|----------|
|
||
| LLM服务 | 模型集成、流式响应 | `POST /api/v1/llm/chat` |
|
||
| MCP服务 | 服务注册、请求路由 | `POST /api/v1/mcp/execute` |
|
||
| 地图服务 | 图层管理、WMS发布 | `GET /api/v1/map/wms` |
|
||
| 用户服务 | 认证授权、配置管理 | `POST /api/v1/auth/login` |
|
||
|
||
#### 2.2.2 Resource层
|
||
| 模块 | 核心功能 | 技术实现 |
|
||
|------|----------|----------|
|
||
| 空间分析引擎 | 地理处理、数据转换 | GeoTools + JTS |
|
||
| 知识库服务 | 文档存储、检索 | PostgreSQL +向量索引 |
|
||
| 数据存储服务 | 文件管理、元数据 | MinIO + PostgreSQL |
|
||
|
||
## 三、API接口设计
|
||
|
||
### 3.1 客户端-服务端接口
|
||
|
||
#### LLM对话接口
|
||
```
|
||
POST /api/v1/llm/chat
|
||
Content-Type: application/json
|
||
Authorization: Bearer {token}
|
||
|
||
{
|
||
"conversation_id": "conv_123",
|
||
"prompt": "分析海珠区的建筑密度",
|
||
"stream": true,
|
||
"model": "deepseek-r1"
|
||
}
|
||
```
|
||
|
||
响应(SSE):
|
||
```
|
||
event: message
|
||
data: {"type": "text", "content": "正在调用空间分析工具..."}
|
||
|
||
event: tool_call
|
||
data: {
|
||
"service": "arcgis",
|
||
"tool": "density_analysis",
|
||
"parameters": {"region": "海珠区", "type": "building"}
|
||
}
|
||
|
||
event: message
|
||
data: {"type": "map", "content": "/api/v1/map/layers/result_456"}
|
||
```
|
||
|
||
#### MCP工具调用接口
|
||
```
|
||
POST /api/v1/mcp/execute
|
||
Content-Type: application/json
|
||
Authorization: Bearer {token}
|
||
|
||
{
|
||
"service_name": "arcgis",
|
||
"tool_name": "clip_analysis",
|
||
"parameters": {
|
||
"input_layer": "buildings",
|
||
"clip_layer": "haizhu_boundary"
|
||
}
|
||
}
|
||
```
|
||
|
||
响应:
|
||
```json
|
||
{
|
||
"request_id": "req_789",
|
||
"status": "success",
|
||
"result": {
|
||
"output_layer": "clipped_buildings",
|
||
"feature_count": 1562
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3.2 MCP服务接口规范
|
||
|
||
#### 资源服务接口
|
||
```
|
||
GET /mcp/resources/{resource_uri}
|
||
Accept: application/json
|
||
Authorization: Bearer {token}
|
||
```
|
||
|
||
#### 工具服务接口
|
||
```
|
||
POST /mcp/tools/{tool_name}
|
||
Content-Type: application/json
|
||
Authorization: Bearer {token}
|
||
|
||
{
|
||
"parameters": {
|
||
"param1": "value1",
|
||
"param2": "value2"
|
||
}
|
||
}
|
||
```
|
||
|
||
## 四、安全实现
|
||
|
||
### 4.1 认证与授权
|
||
- OAuth 2.1授权框架集成
|
||
- JWT令牌管理(访问令牌2小时,刷新令牌7天)
|
||
- 基于角色的访问控制(RBAC)
|
||
|
||
### 4.2 数据安全
|
||
- 所有API通信使用TLS 1.3加密
|
||
- 敏感数据存储加密(AES-256)
|
||
- 工具调用审计日志(保留90天)
|
||
|
||
### 4.3 MCP安全策略
|
||
- 用户明确授权机制(工具调用前弹窗确认)
|
||
- 资源访问白名单(仅允许访问指定目录)
|
||
- 第三方服务沙箱隔离(Docker容器化部署)
|
||
|
||
## 五、部署架构
|
||
|
||
### 5.1 容器化部署
|
||
```
|
||
├── docker-compose.yml
|
||
├── frontend/ # React应用
|
||
├── backend/ # Spring Boot服务
|
||
├── geoserver/ # 地图服务
|
||
├── postgres/ # 数据库
|
||
└── minio/ # 对象存储
|
||
```
|
||
|
||
### 5.2 服务交互流程
|
||
1. 用户在前端输入自然语言请求
|
||
2. 前端Host层调用LLM客户端获取响应
|
||
3. LLM返回工具调用指令(XML格式)
|
||
4. Host层解析指令并调用MCP工具客户端
|
||
5. 服务端MCP模块路由请求至对应工具
|
||
6. 工具执行完成后返回结果
|
||
7. Host层将结果整理后发送至LLM生成最终回答
|
||
8. 前端展示回答及地图结果 |