feat: 管理后台补齐完整功能

- 页面切换卡片:数据大屏/数字孪生/AI 助手/媒体轮播 → MQTT navigate 控制所有大屏
- 立即播放:新增 POST /api/playlist/play(加入播放列表 + MQTT play_target),
  MediaScreen 监听 play_target 跳转并播放指定媒体
- 远程 URL 支持两种操作:添加到媒体库 / 加入播放列表
- 本地媒体卡片显示 FastAPI 输出 URL(/file/...)+ 一键复制
- 预览弹窗增加「立即播放」;新增 page-switch/media-url/copy-btn 样式
This commit is contained in:
Pine
2026-08-17 21:38:04 +08:00
parent 00cb76c73f
commit 1a95ecbacb
6 changed files with 173 additions and 8 deletions
+21 -1
View File
@@ -209,6 +209,9 @@ export default function MediaScreen() {
setPaused(false);
skip(-1);
break;
case 'play_target':
if (msg.params && msg.params.path) playTarget(msg.params.path);
break;
case 'minimize_window':
getCurrentWindow().minimize().catch(() => {});
break;
@@ -292,6 +295,20 @@ export default function MediaScreen() {
}
}, []);
// 指定媒体立即播放:刷新播放列表并跳转到目标项
const playTarget = useCallback(async (path) => {
try {
const data = await api.getPlaylist();
const newList = data.files || [];
if (newList.length === 0) return;
setList(newList);
setLoaded(true);
const idx = newList.findIndex((it) => it.relative_path === path);
if (idx >= 0) setIndex(idx);
setPaused(false);
} catch { /* ignore */ }
}, []);
// MQTT 控制通道(后端 opc/display/command → window 事件)
useEffect(() => {
const handler = (e) => {
@@ -316,6 +333,9 @@ export default function MediaScreen() {
case 'set_mode':
if (msg.params && msg.params.mode) setPlayMode(msg.params.mode);
break;
case 'play_target':
if (msg.params && msg.params.path) playTarget(msg.params.path);
break;
case 'minimize':
getCurrentWindow().minimize().catch(() => {});
break;
@@ -331,7 +351,7 @@ export default function MediaScreen() {
};
window.addEventListener('dpm:media-control', handler);
return () => window.removeEventListener('dpm:media-control', handler);
}, [skip, reloadPlaylist, applySettings]);
}, [skip, reloadPlaylist, applySettings, playTarget]);
const enableSound = useCallback(() => {
const video = videoRef.current;