feat(大屏): 顶部加「📤 发布」按钮 —— 选设备直接注入视频/图片、注入剪贴板

用户要求:"大屏按钮右边加一个按钮叫发布,就是选择设备号注入视频或者图片,位置就和发布页面的一样,
然后还有在选择设备号注入剪贴板"。

大屏(`/wall`)顶栏「一键亮屏」右边加 **「📤 发布」**,点开是一块面板:
  · **设备**下拉(设备名 + 地址,离线会标注;每次打开现取最新列表)
  · **视频 / 图片**:选文件 → 「注入素材」→ 推到该机相册 `/sdcard/DCIM/Camera`
  · **剪贴板文字**:填一段 → 「注入剪贴板」→ 写进该机剪贴板(发文案用)
  · 面板下方是操作日志(✅/❌ + 原因),失败会写清为什么

后端(`web/tools_api.py`,都按 **设备位** 放行 —— 大屏上随手一推是设备操作,不该要管理员位):
  · `POST /api/tools/push_material`(form-data:file + serial):
    保存上传 → `publish_flow.push_video` 推到相册(文件名带 `wall` 前缀、mtime 改成现在,
    保证它在相册里排最前)→ `verify_pushed` 校验进没进相册索引 → 返回 `{ok,msg,remote,verify}`
    · **不占位、不写库**:与「发布计划 → 推送」是两回事(那条按计划走占位/去重/回写状态);
      这条是"手上有一段素材,想马上在这台机器上发"
    · 扩展名按 `video_plan.MEDIA_EXTS` 校验(视频+图片),不在其中 → 400;设备不在线 → 400
    · 临时目录用完即删(`finally` 里 rmtree)
  · `POST /api/tools/push_clipboard`:与 `/api/tools/clipboard/set` **同一个实现**
    (`_set_device_clipboard`),只是权限位不同

真机验过(A01):剪贴板注入 ✅;1×1 测试图推到相册 ✅(`verify=no_index` 的 ⚠ 是这张图太小、
媒体库没索引它,真视频/图片是 ✅);`.txt` 被 400 拦住 ✅;测试文件已从手机删掉、不留痕。

文档:doc/API.md 加两条接口(含请求/返回/错误口径)、README 实时看屏那行补上发布面板。
This commit is contained in:
2026-10-12 14:57:01 +08:00
parent f4641c3e2d
commit 3bd7f636a0
4 changed files with 218 additions and 3 deletions
+4
View File
@@ -211,6 +211,8 @@
| GET | `/api/adb/devices` | Admin | 维护终端设备列表(本机 adb + 设备池) |
| POST | `/api/adb/cmd` | Admin | 执行 adb 命令(20s 超时;拦截 `kill-server`/`disconnect`) |
| POST | `/api/tools/clipboard/set` | Admin | 剪贴板注入到多台设备 |
| POST | `/api/tools/push_clipboard` | D | 同上(**同一个实现**),权限按设备位放行 —— 大屏「发布」面板用 |
| POST | `/api/tools/push_material` | D | 大屏「发布」面板:把上传的视频/图片**直接推到指定设备**相册(不占发布计划) |
| POST | `/api/tools/appver` | Admin | 查指定包名在所有在线设备的版本 |
### 2.8 tailscale(`web/tailscale_api.py`,全部 Admin)
@@ -771,6 +773,8 @@
| 接口 | 请求 | 说明 |
|------|------|------|
| `POST /api/tools/clipboard/set` | `{"serials":[…],"text":"…"}` | 设备端 Agent 通道写入并读回校验(旧版独立 ClipInject 自动兜底);serials 空或非列表 → 400 |
| `POST /api/tools/push_clipboard` | `{"serial":"…"}`(或 `serials:[…]`)+ `{"text":"…"}` | 与上一条**同一个实现**(`_set_device_clipboard`),权限**设备位**即可 —— 大屏「发布」面板注入剪贴板用 |
| `POST /api/tools/push_material` | form-data:`file`(视频/图片)+ `serial` + `album_dir`(可省) | 大屏「发布」面板:推文件到该设备相册(默认 `/sdcard/DCIM/Camera`,文件名带 `wall` 前缀、mtime 改成现在)。**不占位、不写库**;扩展名不在 `MEDIA_EXTS` 或设备不在线 → 400;推完做相册索引校验,返回 `{ok,msg,remote,verify,size}`(`verify=no_index` 时 `ok=true` 但文案带 ⚠) |
| `POST /api/tools/appver` | `{"package":"com.xxx"}` | 并发查所有在线设备(≤10 并发);包名须匹配 `^[A-Za-z0-9_.]+$` |
### Tailscale(全部 Admin)