更新记录

1.0.0(2026-10-29)

  • 首个插件市场版本,类型为「uniCloud → 前后一体项目模板」(unicloud-template-project)。
  • 新增 uniCloud-aliyun:wvp-ingest(入库)、wvp-yolo(YOLOv8 检测)、wvp-common(公共模块)与 wvp-cameras / wvp-events 集合 schema。
  • 新增客户端 api/cloud.js:有 uniCloud 空间时走云函数,没有时自动回落到 HTTP 直连 kitchen-api。
  • 新增 static/readme/ 四张线上演示截图(采集自 https://codesuccess.online/wvp)。
  • manifest.json 移除 DCloud appid,符合项目模板发布要求;导入后由 HBuilderX 重新生成。
  • package.json 增加 uni_modules.encrypt(三个云函数/公共模块入口)与 uni_modules.platforms(阿里云 + Vue3 / Web / App / 微信小程序),并补 darkmode / i18n / widescreen 标记。
  • 按插件市场要求精简 README.md,只保留线上演示、截图、入库、YOLOv 使用四部分。

平台兼容性

云端兼容性

支付宝云 腾讯云 阿里云
× × √

uni-app(5.26)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
× √ √ √ √ × √ √ ×
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
√ × × × × × × × × - × ×

uni-app x(5.31)

Chrome Safari Android iOS 鸿蒙 微信小程序
× × × × × ×

明厨亮灶 · 云端一体

GB/T 28181 摄像头接入 → WVP 转流 → YOLOv8 识别 → 入库 → 手机端看画面、收告警。

云端一体:uniCloud-aliyun/cloudfunctions 负责入库与推理调度,api/cloud.js 在「有云空间」和「只有 kitchen-api」两种部署下自动切换,页面代码不用改。


一、线上演示

https://codesuccess.online/wvp

纯静态演示站:数据写死在前端,打开即看,不需要账号,也不请求任何后端。

首页(概览 / 正在直播 / 厨房点位) 实时播放(抓图 / 全屏 / 点位信息)
首页 播放
违规告警(类型 / 状态 / 置信度) 告警详情(证据片段 + 判定说明)
告警 详情

截图采集自线上站点,390×844 移动端视口,2026-10-29。图片托管在 43 服务器 /usr/local/nginx/html/wvp/readme/,重新采集用 ../scripts/h5-shot.mjs(输出 PNG,再转 JPG 压到 200KB 左右)。


二、截图

三种截图,全部由服务端取帧,前端只拿 URL。

场景 触发 结果
播放页抓图 POST /api/cameras/{id}/snapshot { url, path },落盘 media/snapshots/YYYYMMDD/
AI 证据截图 worker 判定违规时自动生成 画框存证,随事件入库,告警详情直接播放
前端调用 cloud.snapshot(cameraId) 有云空间走云函数,没有则直连 API
import cloud from '@/api/cloud'

const { code, data } = await cloud.snapshot(cameraId)
if (code === 0) {
  // #ifdef APP-PLUS
  uni.downloadFile({ url: data.url, success: (f) => uni.saveImageToPhotosAlbum({ filePath: f.tempFilePath }) })
  // #endif
  // #ifdef H5
  window.open(data.url)
  // #endif
}
  • 服务端取帧顺序:舌尖安全网 / 萤石云抓图 → ZLM RTSP 抽帧 → WVP snap,任一可用即返回 JPEG。
  • App 保存到相册需要 NSPhotoLibraryAddUsageDescription,manifest.json 已声明;H5 走浏览器下载。
  • 证据截图的命名与目录:media/snapshots/<yyyyMMdd>/cam<cameraId>_<HHmmss_SSS>.jpg。

三、入库

WVP 通道列表 ──> wvp-ingest 云函数 ──┬─> 云数据库 wvp-cameras(唯一键 device_id + channel_id)
                                     └─> kitchen-api POST /api/wvp/import ──> MySQL cameras

3.1 云函数 wvp-ingest

action 作用 主要入参
channels 拉取设备下的国标通道,不入库 deviceId
import 入库:写云库 + 同步业务库 kitchenId、deviceId、channels?、syncApi?
list 查询已入库摄像头 kitchenId?、size?
// 1) 先看这台设备有哪些通道
const { data } = await uniCloud.callFunction({
  name: 'wvp-ingest',
  data: { action: 'channels', deviceId: '34020000001320000001' },
})
// data.channels = [{ channelId, deviceId, name, location, status }]

// 2) 全部入库(不传 channels 时云函数自己去 WVP 拉)
await uniCloud.callFunction({
  name: 'wvp-ingest',
  data: { action: 'import', kitchenId: 1, deviceId: '34020000001320000001' },
})

// 3) 只入库勾选的通道,并跳过业务库同步
await uniCloud.callFunction({
  name: 'wvp-ingest',
  data: {
    action: 'import',
    kitchenId: 1,
    deviceId: '34020000001320000001',
    syncApi: false,
    channels: [{ channelId: '34020000001320000002', name: '粗加工间', location: '粗加工' }],
  },
})

返回:{ code: 0, data: { total, created, updated, api } }。api 是业务库的写入结果,业务库失败只回报不回滚,可直接重试。

3.2 没有云空间时直连

TOKEN=$(curl -s -X POST "http://服务器IP:8000/api/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin123"}' | python3 -c "import sys,json;print(json.load(sys.stdin)['token'])")

curl -X POST "http://服务器IP:8000/api/wvp/import" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "kitchen_id": 1,
    "device_id": "34020000001320000001",
    "channels": [
      {"channelId": "34020000001320000001", "name": "烹饪间", "location": "烹饪"},
      {"channelId": "34020000001320000002", "name": "粗加工间", "location": "粗加工"}
    ]
  }'

3.3 字段映射与去重

WVP 字段 云数据库 wvp-cameras 业务库 cameras
deviceId device_id device_id
channelId / gbDeviceId / gbId channel_id、gb_id channel_id、gb_id
name / channelName name name
location / civilCode location location
— kitchen_id kitchen_id
— ai_enabled(默认 true) ai_enabled
  • 幂等:device_id + channel_id 唯一,重复入库只更新名称与点位,不会产生重复摄像头;单次最多 200 路。
  • 集合 schema 见 uniCloud-aliyun/database/:wvp-cameras(通道)、wvp-events(检测记录),客户端无读写权限,只允许云函数写入。

四、YOLOv 使用

4.1 模型

权重 用途 类别
models/yolov8n.pt 人员 person
models/ppe.pt 口罩 / 发网 / 手套 mask、hairnet、gloves
models/kitchen_ppe.pt 厨师帽 / 围裙 / 未戴口罩 厨房 PPE
models/smoking.pt 吸烟 cigarette、face、smoking
models/phone.pt 玩手机 mobile_phone
models/rat.pt 老鼠 item(单类)
models/fire_smoke.pt 明火 / 烟雾 fire、smoke

权重来源、sha256 与类别写在 ai-service/models/manifest.json,缺模型时对应能力标记为不可用,不会拿错模型硬识别。

4.2 跑起来

python scripts/download_ai_models.py     # 校验/补齐权重
bash scripts/run-ai-local.sh             # 本机 MPS/CPU 跑 worker,--daemon 后台
docker compose -f docker/docker-compose.yml up -d bk-ai   # 服务器上跑

worker 每 30 秒拉一次启用的摄像头,每路一个线程:WVP 点播拿 RTSP → OpenCV 解码只留最新帧 → 抽帧 → YOLO 检测 + ByteTrack → 规则引擎(ROI / 时间窗 / 冷却)→ 画框存证 → POST /api/internal/events 入库 → WebSocket 推 App。

违规 判定 默认参数
no_hat 未戴工作帽 no_hat 类别,或 head 与 hat 关联失败 4s 内 2 次,冷却 5 分钟
no_mask 未戴口罩 no_mask 类别,或头部无 mask 6s 内 2 次,冷却 5 分钟
smoking 吸烟 香烟落在人体上半身 5s 内 2 次,冷却 3 分钟
phone 玩手机 手机落在人体上半身 8s 内 3 次,冷却 3 分钟
rat 老鼠 直接检测 5s 内 2 次,冷却 5 分钟
fire 明火 直接检测 立即告警,冷却 1 分钟

参数用 RULES_JSON 覆盖,详见 docs/03-AI识别方案.md。

4.3 从云端调用

// 1) 模型状态:确认加载的是真实权重
const s = await uniCloud.callFunction({ name: 'wvp-yolo', data: { action: 'status' } })
// s.result.data.loaded = ['ppe', 'rat', 'fire_smoke', 'smoking', 'phone']

// 2) 对一张截图跑一次检测
const r = await uniCloud.callFunction({
  name: 'wvp-yolo',
  data: { action: 'detect', imageUrl: 'https://.../snapshots/20261029/cam1_093211.jpg', cameraId: 1, conf: 0.35, save: true },
})
// r.result.data.detections = [{ label: 'no_hat', conf: 0.94, box: [x1, y1, x2, y2] }]

云函数把 imageUrl 转发给推理服务 POST /api/ai/detect(入参 { image_url, conf, camera_id });用 YOLO_ENDPOINT 环境变量可指向自建服务。save: true 会把结果写进 wvp-events 集合。

4.4 自训

cd ai-service
python train.py --data dataset/kitchen.yaml --model yolov8s.pt --epochs 120 --imgsz 960
cp runs/kitchen/v1/weights/best.pt models/kitchen_ppe.pt

把 best.pt 放到 models/ 并在 manifest.json 登记类别后,worker 重启即加载。公开 COCO 权重认不出帽子、口罩、老鼠,现场数据至少每类 300~500 张、覆盖白天/夜间与遮挡场景。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

网络访问;App 端抓图需相机、保存截图需相册

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件本身不采集用户数据。仅在用户自行配置 WVP_API_BASE 后,由云函数向用户自己的 kitchen-api 发送通道查询、入库与模型状态请求;默认演示地址 https://codesuccess.online/wvp 为纯静态页面,不上传任何数据。

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

暂无用户评论。