支持通过网页增加、删除、修改摄像头配置信息
支持摄像头配置信息中句柄的设置,并实测有效
This commit is contained in:
148
SHH.CameraSdk/Htmls/Main.html
Normal file
148
SHH.CameraSdk/Htmls/Main.html
Normal file
@@ -0,0 +1,148 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>SHH 视频网关 - 控制底座</title>
|
||||
<script src="https://cdn.staticfile.org/axios/1.5.0/axios.min.js"></script>
|
||||
<link href="https://cdn.staticfile.org/twitter-bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdn.staticfile.org/bootstrap-icons/1.10.0/font/bootstrap-icons.min.css" rel="stylesheet">
|
||||
<style>
|
||||
body, html { margin: 0; padding: 0; height: 100vh; overflow: hidden; background: #f4f6f9; }
|
||||
.app-shell { display: flex; height: 100vh; }
|
||||
.sidebar-container { width: 320px; border-right: 1px solid #ddd; background: #fff; flex-shrink: 0; }
|
||||
.main-workarea { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
|
||||
.top-container { height: 110px; padding: 15px 15px 0 15px; flex-shrink: 0; }
|
||||
.editor-container { flex: 1; padding: 15px; overflow: hidden; position: relative; }
|
||||
.log-panel { height: 45px; border-top: 1px solid #333; transition: height 0.3s; background: #1e1e1e; }
|
||||
.modal-body iframe { border: none; width: 100%; }
|
||||
#frame-editor { width: 100%; height: 100%; border: none; background: #fff; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.05); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="app-shell">
|
||||
<div class="sidebar-container">
|
||||
<iframe id="frame-list" src="List.html" style="width:100%; height:100%; border:none;" name="list"></iframe>
|
||||
</div>
|
||||
|
||||
<div class="main-workarea">
|
||||
<div class="top-container">
|
||||
<iframe id="frame-top" src="EditorTop.html" style="width:100%; height:100%; border:none;" name="top"></iframe>
|
||||
</div>
|
||||
|
||||
<div class="editor-container">
|
||||
<iframe id="frame-editor" src="Editor.html" name="editor"></iframe>
|
||||
</div>
|
||||
|
||||
<div id="diag-wrapper" class="log-panel">
|
||||
<iframe id="frame-diag" src="Diagnostic.html" style="width:100%; height:100%; border:none;" name="diag"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="subModal" tabindex="-1"><div class="modal-dialog modal-lg modal-dialog-centered"><div class="modal-content shadow-lg"><div class="modal-body p-0"><iframe id="frame-sub" src="Subscription.html" style="height: 650px;" name="sub"></iframe></div></div></div></div>
|
||||
<div class="modal fade" id="preModal" tabindex="-1"><div class="modal-dialog modal-md modal-dialog-centered"><div class="modal-content shadow-lg"><div class="modal-body p-0"><iframe id="frame-pre" src="Preprocessing.html" style="height: 580px;" name="pre"></iframe></div></div></div></div>
|
||||
<div class="modal fade" id="ctrlModal" tabindex="-1"><div class="modal-dialog modal-dialog-centered"><div class="modal-content shadow-lg"><div class="modal-body p-0"><iframe id="frame-ctrl" src="CameraControl.html" style="height: 480px;" name="ctrl"></iframe></div></div></div></div>
|
||||
|
||||
<script src="https://cdn.staticfile.org/bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
|
||||
<script>
|
||||
const API_BASE = "http://localhost:5000";
|
||||
let currentDeviceId = 0;
|
||||
|
||||
window.addEventListener('message', (event) => {
|
||||
const msg = event.data;
|
||||
if (!msg || !msg.type) return;
|
||||
|
||||
const frames = {
|
||||
list: document.getElementById('frame-list').contentWindow,
|
||||
top: document.getElementById('frame-top').contentWindow,
|
||||
editor: document.getElementById('frame-editor').contentWindow,
|
||||
diag: document.getElementById('frame-diag').contentWindow,
|
||||
sub: document.getElementById('frame-sub').contentWindow,
|
||||
pre: document.getElementById('frame-pre').contentWindow,
|
||||
ctrl: document.getElementById('frame-ctrl').contentWindow
|
||||
};
|
||||
const editorIframe = document.getElementById('frame-editor');
|
||||
|
||||
const switchToDetail = () => {
|
||||
editorIframe.src = "Editor.html";
|
||||
editorIframe.onload = () => {
|
||||
setTimeout(() => {
|
||||
if(currentDeviceId) editorIframe.contentWindow.postMessage({ type: 'LOAD_DEVICE', deviceId: currentDeviceId }, '*');
|
||||
}, 100);
|
||||
};
|
||||
};
|
||||
|
||||
switch(msg.type) {
|
||||
case 'DEVICE_SELECTED':
|
||||
currentDeviceId = msg.data.id;
|
||||
// 如果当前不是Editor页面,切回
|
||||
if (!editorIframe.src.includes('Editor.html')) {
|
||||
switchToDetail();
|
||||
} else {
|
||||
if(frames.top) frames.top.postMessage({ type: 'UPDATE_TOP_INFO', data: msg.data }, '*');
|
||||
if(frames.editor) frames.editor.postMessage({ type: 'LOAD_DEVICE', deviceId: msg.data.id }, '*');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'DEVICE_CONTROL':
|
||||
const controlUrl = `${API_BASE}/api/Cameras/${msg.deviceId}/power?enabled=${msg.action === 'start'}`;
|
||||
axios.post(controlUrl).then(() => {
|
||||
frames.list.postMessage({ type: 'REFRESH_LIST' }, '*');
|
||||
frames.diag.postMessage({ type: 'PUSH_LOG', log: { method: 'POST', url: controlUrl, status: 200, msg: `Device ${msg.action}` } }, '*');
|
||||
}).catch(e => console.error(e));
|
||||
break;
|
||||
|
||||
case 'API_LOG':
|
||||
if(frames.diag) frames.diag.postMessage({ type: 'PUSH_LOG', log: msg.log }, '*');
|
||||
break;
|
||||
|
||||
case 'UI_RESIZE_DIAG':
|
||||
const diagEl = document.getElementById('diag-wrapper');
|
||||
if(diagEl) diagEl.style.height = msg.expanded ? '350px' : '45px';
|
||||
break;
|
||||
|
||||
// 弹窗逻辑
|
||||
case 'OPEN_SUBSCRIPTION':
|
||||
new bootstrap.Modal(document.getElementById('subModal')).show();
|
||||
setTimeout(() => frames.sub.postMessage({ type: 'LOAD_SUBS_DATA', deviceId: msg.id }, '*'), 400);
|
||||
break;
|
||||
case 'OPEN_PREPROCESS':
|
||||
editorIframe.src = "Preprocessing.html";
|
||||
editorIframe.onload = () => {
|
||||
editorIframe.contentWindow.postMessage({ type: 'LOAD_PREPROCESS_DATA', deviceId: msg.id, apiBase: API_BASE }, '*');
|
||||
};
|
||||
break;
|
||||
case 'OPEN_CAMERA_CONTROL':
|
||||
new bootstrap.Modal(document.getElementById('ctrlModal')).show();
|
||||
setTimeout(() => frames.ctrl.postMessage({ type: 'LOAD_CTRL_DATA', deviceId: msg.id, apiBase: API_BASE }, '*'), 400);
|
||||
break;
|
||||
|
||||
// --- 统一使用 CameraEdit.html ---
|
||||
|
||||
case 'OPEN_CAMERA_EDIT':
|
||||
editorIframe.src = "CameraEdit.html";
|
||||
editorIframe.onload = () => {
|
||||
editorIframe.contentWindow.postMessage({ type: 'LOAD_EDIT_DATA', deviceId: msg.id, apiBase: API_BASE }, '*');
|
||||
};
|
||||
break;
|
||||
|
||||
case 'OPEN_CAMERA_ADD': // 新增也指向同一个文件
|
||||
editorIframe.src = "CameraEdit.html";
|
||||
editorIframe.onload = () => {
|
||||
editorIframe.contentWindow.postMessage({ type: 'INIT_ADD_PAGE', apiBase: API_BASE }, '*');
|
||||
};
|
||||
break;
|
||||
|
||||
// 统一关闭逻辑
|
||||
case 'CLOSE_EDIT_MODE':
|
||||
case 'CLOSE_PREPROCESS_MODE':
|
||||
case 'CLOSE_ADD_MODE':
|
||||
switchToDetail();
|
||||
if(msg.needRefresh) frames.list.postMessage({ type: 'REFRESH_LIST' }, '*');
|
||||
break;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user