Files
iot-device-management-service/docs/芋道前端对接文档.md
16337 12e127f1f0 docs: 添加告警平台与芋道前端对接文档
包含以下内容:
- 后端 API 接口详细说明
- 芋道前端集成步骤
- 边缘端对接示例代码
- 阿里云 OSS 配置说明
- 大模型分析配置(可选)
- 部署说明
2026-02-02 09:44:05 +08:00

13 KiB
Raw Permalink Blame History

AI 告警平台与芋道前端对接文档

本文档指导如何在芋道前端项目yudao-ui-admin-vben中集成告警平台功能。

一、项目概述

1.1 告警平台后端

  • 技术栈: FastAPI + SQLite + 阿里云 OSS
  • 职责: 接收边缘端告警、存储告警证据、提供 REST API
  • 端口: 8000

1.2 芋道前端

  • 技术栈: Vue 3 + Vben Admin + Ant Design Vue
  • 职责: 告警列表展示、详情查看、人工处理
  • 复用: 用户体系、权限管理、页面布局

二、后端 API 接口

2.1 基础信息

  • Base URL: http://localhost:8000
  • 文档地址: http://localhost:8000/docs

2.2 接口列表

2.2.1 健康检查

GET /health

响应:

{
  "status": "healthy",
  "database": "healthy"
}

2.2.2 创建告警(边缘端调用)

POST /api/v1/alerts
Content-Type: multipart/form-data

请求参数:

  • data (FormField): JSON 字符串
    {
      "camera_id": "cam-001",
      "roi_id": "roi-01",
      "alert_type": "leave_post",
      "algorithm": "LeavePostAlgorithm",
      "confidence": 85,
      "duration_minutes": 5,
      "trigger_time": "2024-01-20T10:30:00Z",
      "message": "离岗告警"
    }
    
  • snapshot (File, 可选): 告警抓拍图片

响应:

{
  "id": 1,
  "alert_no": "ALT20240120103000ABC12345",
  "camera_id": "cam-001",
  "roi_id": "roi-01",
  "alert_type": "leave_post",
  "algorithm": "LeavePostAlgorithm",
  "confidence": 85,
  "duration_minutes": 5,
  "trigger_time": "2024-01-20T10:30:00Z",
  "message": "离岗告警",
  "snapshot_url": "https://your-bucket.oss-cn-hangzhou.aliyuncs.com/alerts/xxx.jpg",
  "status": "pending",
  "created_at": "2024-01-20T10:30:00Z"
}

2.2.3 查询告警列表

GET /api/v1/alerts

查询参数:

参数 类型 必填 说明
cameraId string 摄像头ID
alertType string 告警类型
status string 处理状态
startTime datetime 开始时间
endTime datetime 结束时间
page int 页码默认1
pageSize int 每页条数默认20

响应:

{
  "alerts": [...],
  "total": 100,
  "page": 1,
  "pageSize": 20
}

2.2.4 获取告警详情

GET /api/v1/alerts/{alertId}

2.2.5 处理告警

PUT /api/v1/alerts/{alertId}/handle

请求体:

{
  "status": "confirmed",
  "remark": "确认为真实告警"
}

状态枚举: pending | confirmed | ignored | resolved

2.2.6 获取告警统计

GET /api/v1/alerts/statistics

响应:

{
  "total": 100,
  "pending": 10,
  "confirmed": 50,
  "ignored": 20,
  "resolved": 20,
  "by_type": {
    "leave_post": 80,
    "intrusion": 20
  }
}

三、芋道前端集成步骤

3.1 创建 API 文件

apps/web-antd/src/api/ 目录下创建 alert 目录,并添加 alert.ts:

import { requestClient } from '#/api/request';

export namespace AlertApi {
  export interface Alert {
    id: number;
    alertNo: string;
    cameraId: string;
    roiId?: string;
    alertType: string;
    algorithm?: string;
    confidence?: number;
    durationMinutes?: number;
    triggerTime: string;
    message?: string;
    snapshotUrl?: string;
    status: 'pending' | 'confirmed' | 'ignored' | 'resolved';
    handleRemark?: string;
    handledBy?: string;
    handledAt?: string;
    aiAnalysis?: Record<string, any>;
    createdAt: string;
    updatedAt: string;
  }

  export interface AlertListParams {
    pageNo: number;
    pageSize: number;
    cameraId?: string;
    alertType?: string;
    status?: string;
    startTime?: string;
    endTime?: string;
  }

  export interface AlertListResponse {
    alerts: Alert[];
    total: number;
    page: number;
    pageSize: number;
  }

  export interface AlertStatistics {
    total: number;
    pending: number;
    confirmed: number;
    ignored: number;
    resolved: number;
    by_type: Record<string, number>;
  }

  export interface HandleAlertRequest {
    status: 'confirmed' | 'ignored' | 'resolved';
    remark?: string;
  }
}

export function getAlertList(params: AlertApi.AlertListParams) {
  return requestClient.get<AlertApi.AlertListResponse>('/api/v1/alerts', {
    params,
  });
}

export function getAlertDetail(alertId: number) {
  return requestClient.get<AlertApi.Alert>(`/api/v1/alerts/${alertId}`);
}

export function handleAlert(alertId: number, data: AlertApi.HandleAlertRequest) {
  return requestClient.put<AlertApi.Alert>(`/api/v1/alerts/${alertId}/handle`, data, {
    params: { handledBy: 'currentUser' },
  });
}

export function getAlertStatistics() {
  return requestClient.get<AlertApi.AlertStatistics>('/api/v1/alerts/statistics');
}

3.2 创建路由配置

apps/web-antd/src/router/routes/modules/ 下创建 alert.ts:

import type { RouteRecordRaw } from 'vue-router';

const routes: RouteRecordRaw[] = [
  {
    path: '/alert',
    name: 'AlertCenter',
    meta: {
      title: '告警中心',
      icon: 'lucide:bell',
      keepAlive: true,
    },
    children: [
      {
        path: 'list',
        name: 'AlertList',
        meta: {
          title: '告警列表',
          noCache: true,
        },
        component: () => import('#/views/alert/list/index.vue'),
      },
    ],
  },
];

export default routes;

将此路由添加到主路由配置中(编辑 apps/web-antd/src/router/routes/modules/ 下的 dashboard.ts 或其他菜单配置)。

3.3 创建页面组件

apps/web-antd/src/views/ 下创建 alert/list/ 目录:

data.ts:

import type { VbenFormSchema } from '#/adapter/form';
import type { VxeTableGridOptions } from '#/adapter/vxe-table';

import { getRangePickerDefaultProps } from '#/utils';

export function useAlertFormSchema(): VbenFormSchema[] {
  return [
    { fieldName: 'cameraId', label: '摄像头ID', component: 'Input', componentProps: { placeholder: '请输入摄像头ID', allowClear: true } },
    { fieldName: 'alertType', label: '告警类型', component: 'Input', componentProps: { placeholder: '请输入告警类型', allowClear: true } },
    {
      fieldName: 'status',
      label: '处理状态',
      component: 'Select',
      componentProps: {
        options: [
          { label: '待处理', value: 'pending' },
          { label: '已确认', value: 'confirmed' },
          { label: '已忽略', value: 'ignored' },
          { label: '已解决', value: 'resolved' },
        ],
        placeholder: '请选择处理状态',
        allowClear: true,
      },
    },
    { fieldName: 'createTime', label: '创建时间', component: 'RangePicker', componentProps: { ...getRangePickerDefaultProps(), allowClear: true } },
  ];
}

export function useAlertColumns(): VxeTableGridOptions['columns'] {
  return [
    { type: 'checkbox', width: 40 },
    { field: 'id', title: '编号', minWidth: 80 },
    { field: 'alertNo', title: '告警编号', minWidth: 150 },
    { field: 'cameraId', title: '摄像头', minWidth: 100 },
    { field: 'alertType', title: '告警类型', minWidth: 100 },
    { field: 'algorithm', title: '算法', minWidth: 120 },
    { field: 'confidence', title: '置信度', minWidth: 80, slots: { default: 'confidence' } },
    { field: 'durationMinutes', title: '离岗时长', minWidth: 100, slots: { default: 'duration' } },
    { field: 'status', title: '状态', minWidth: 100, slots: { default: 'status' } },
    { field: 'createdAt', title: '创建时间', minWidth: 180, formatter: 'formatDateTime' },
    { title: '操作', width: 150, fixed: 'right', slots: { default: 'actions' } },
  ];
}

index.vue: 参考芋道现有的 IoT 告警页面 apps/web-antd/src/views/iot/alert/record/index.vue 进行修改。


四、边缘端对接示例

4.1 Python (ai_edge 项目)

ai_edge 项目的 main.py 中添加告警上报功能:

import requests
from datetime import datetime

class AlertReporter:
    ALERT_PLATFORM_URL = "http://localhost:8000/api/v1/alerts"
    
    def report_alert(
        self,
        camera_id: str,
        roi_id: str,
        alert_type: str,
        algorithm: str,
        confidence: float,
        duration_minutes: int,
        message: str,
        screenshot: bytes,
    ):
        alert_data = {
            "camera_id": camera_id,
            "roi_id": roi_id,
            "alert_type": alert_type,
            "algorithm": algorithm,
            "confidence": int(confidence * 100),
            "duration_minutes": duration_minutes,
            "trigger_time": datetime.utcnow().isoformat() + "Z",
            "message": message,
        }
        
        files = {
            "snapshot": ("alert.jpg", screenshot, "image/jpeg"),
            "data": (None, json.dumps(alert_data), "application/json"),
        }
        
        response = requests.post(self.ALERT_PLATFORM_URL, files=files)
        response.raise_for_status()
        return response.json()

4.2 在推理服务中调用

EdgeInferenceService._handle_detections 方法中调用:

def _handle_detections(self, camera_id: str, roi, frame: VideoFrame, alerts: list):
    for alert in alerts:
        # 上报到云端告警平台
        self._reporter.report_to_platform(
            camera_id=camera_id,
            roi_id=roi.roi_id,
            alert_type=alert.get("alert_type"),
            algorithm="LeavePostAlgorithm",
            confidence=alert.get("confidence", 1.0),
            duration_minutes=alert.get("duration_minutes", 0),
            message=alert.get("message", ""),
            screenshot=frame.image,
        )

五、阿里云 OSS 配置

5.1 配置项

在告警平台的 .env 文件中配置:

OSS_ACCESS_KEY_ID=your_access_key_id
OSS_ACCESS_KEY_SECRET=your_access_key_secret
OSS_ENDPOINT=oss-cn-hangzhou.aliyuncs.com
OSS_BUCKET_NAME=your_bucket_name
OSS_URL_PREFIX=https://your-bucket-name.oss-cn-hangzhou.aliyuncs.com

5.2 权限要求

OSS Bucket 需要配置以下权限:

  • CORS: 允许前端跨域访问
  • 公共读: 告警图片需要可以公开访问

六、大模型分析配置(可选)

6.1 配置项

AI_MODEL_ENDPOINT=http://localhost:8001
AI_MODEL_API_KEY=your_api_key

6.2 大模型 API 格式

告警平台期望大模型服务提供以下接口:

POST /analyze
Content-Type: application/json

{
  "alert_id": 1,
  "snapshot_url": "https://xxx/alert.jpg",
  "alert_info": {
    "camera_id": "cam-001",
    "roi_id": "roi-01",
    "alert_type": "leave_post",
    "confidence": 85,
    "duration_minutes": 5
  }
}

响应格式:

{
  "risk_level": "HIGH",
  "description": "检测到人员在非工作区域长时间停留,建议现场核实",
  "suggestion": "可能是误报,建议确认监控区域工作安排",
  "confidence_score": 0.92
}

七、部署说明

7.1 后端部署

# 1. 安装依赖
pip install -r requirements.txt

# 2. 配置环境变量
cp .env.example .env
# 编辑 .env 文件

# 3. 启动服务
python -m app.main

7.2 使用 Gunicorn 生产部署

gunicorn app.main:app -k uvicorn.workers.UvicornWorker -w 4 -b 0.0.0.0:8000

7.3 Docker 部署

创建 Dockerfile:

FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "-m", "app.main"]

八、注意事项

  1. 芋道项目权限: 告警相关接口需要芋道后端配合实现用户认证
  2. 跨域配置: 告警平台需要配置 CORS 以允许芋道前端访问
  3. 图片存储: 阿里云 OSS 需要配置 CORS 允许前端直接访问图片
  4. 时区处理: 建议统一使用 UTC 时间,前端展示时转换为本地时间
  5. 大模型服务: AI 分析功能可选,需要部署大模型服务支持

九、目录结构总结

# 告警平台后端
alert_platform/
├── app/
│   ├── main.py              # FastAPI 入口
│   ├── config.py            # 配置
│   ├── models.py            # SQLAlchemy 模型
│   ├── schemas.py           # Pydantic 模型
│   ├── services/
│   │   ├── alert_service.py # 告警业务逻辑
│   │   ├── oss_storage.py   # OSS 存储
│   │   └── ai_analyzer.py   # AI 分析
│   └── utils/
│       └── logger.py        # 日志
├── data/                    # SQLite 数据库
├── uploads/                 # 本地临时存储
├── requirements.txt
├── .env.example
└── README.md

# 芋道前端需要创建的文件
yudao-ui-admin-vben/
└── apps/web-antd/src/
    ├── api/
    │   └── alert/
    │       └── alert.ts     # 告警 API
    ├── router/routes/modules/
    │   └── alert.ts         # 告警路由
    └── views/alert/
        └── list/
            ├── data.ts      # 列表配置
            └── index.vue    # 列表页面