feat: 启动/停止合并为切换按钮 + 设置参数改为中文

This commit is contained in:
2026-04-17 13:01:12 +08:00
parent 2f0f287c0f
commit 975ca5e894
3 changed files with 106 additions and 68 deletions

View File

@@ -73,27 +73,17 @@ function loadStatus() {
}
function updateUI(data) {
var startBtn = document.getElementById('start-btn');
var stopBtn = document.getElementById('stop-btn');
// 更新切换按钮状态
updateToggleButton(data.scheduler.running);
if (data.scheduler.running) {
startBtn.disabled = true;
stopBtn.disabled = false;
document.getElementById('scheduler-status').innerHTML = 'Status: Running';
} else {
startBtn.disabled = false;
stopBtn.disabled = true;
document.getElementById('scheduler-status').innerHTML = 'Status: Stopped';
}
document.getElementById('capture-count').textContent = 'Capture count: ' + data.scheduler.capture_count;
document.getElementById('capture-count').textContent = '拍照次数: ' + data.scheduler.capture_count;
document.getElementById('total-images').textContent = data.stats.total_images;
document.getElementById('analyzed-images').textContent = data.stats.analyzed_images;
document.getElementById('total-events').textContent = data.stats.total_events;
// Event type filter
// 事件类型筛选
var eventFilter = document.getElementById('event-filter');
eventFilter.innerHTML = '<option value="all">All types</option>';
eventFilter.innerHTML = '<option value="all">全部类型</option>';
data.stats.event_types.forEach(function(item) {
var opt = document.createElement('option');
opt.value = item.type;
@@ -103,30 +93,58 @@ function updateUI(data) {
}
// Control
function startScheduler() {
fetch(API_BASE + '/api/scheduler/start', {method: 'POST'})
.then(function(res) { return res.json(); })
.then(function(data) {
if (data.success) {
showToast('Started!', 1500);
refreshAll();
} else {
showToast('Failed: ' + data.error, 3000);
}
})
.catch(function(e) { showToast('Error: ' + e.message, 3000); });
function toggleScheduler() {
var btn = document.getElementById('toggle-btn');
if (btn.classList.contains('stopped')) {
// 当前已停止,启动
fetch(API_BASE + '/api/scheduler/start', {method: 'POST'})
.then(function(res) { return res.json(); })
.then(function(data) {
if (data.success) {
btn.classList.remove('stopped');
btn.classList.add('running');
btn.innerHTML = '▶ 运行中';
btn.style.background = '#4CAF50';
showToast('已启动!', 1500);
refreshAll();
} else {
showToast('启动失败: ' + data.error, 3000);
}
})
.catch(function(e) { showToast('错误: ' + e.message, 3000); });
} else {
// 当前运行中,停止
fetch(API_BASE + '/api/scheduler/stop', {method: 'POST'})
.then(function(res) { return res.json(); })
.then(function(data) {
if (data.success) {
btn.classList.remove('running');
btn.classList.add('stopped');
btn.innerHTML = '⏹ 已停止';
btn.style.background = '#f44336';
showToast('已停止!', 1500);
refreshAll();
}
})
.catch(function(e) { showToast('错误: ' + e.message, 3000); });
}
}
function stopScheduler() {
fetch(API_BASE + '/api/scheduler/stop', {method: 'POST'})
.then(function(res) { return res.json(); })
.then(function(data) {
if (data.success) {
showToast('Stopped!', 1500);
refreshAll();
}
})
.catch(function(e) { showToast('Error: ' + e.message, 3000); });
function updateToggleButton(running) {
var btn = document.getElementById('toggle-btn');
if (running) {
btn.classList.remove('stopped');
btn.classList.add('running');
btn.innerHTML = '▶ 运行中';
btn.style.background = '#4CAF50';
} else {
btn.classList.remove('running');
btn.classList.add('stopped');
btn.innerHTML = '⏹ 已停止';
btn.style.background = '#f44336';
}
}
function captureNow() {

View File

@@ -23,8 +23,7 @@
<div class="panel-section">
<h3>📹 摄像头控制</h3>
<div class="control-buttons">
<button onclick="startScheduler()" id="start-btn" class="btn-primary">▶ 启动</button>
<button onclick="stopScheduler()" id="stop-btn" class="btn-danger">⏹ 停止</button>
<button onclick="toggleScheduler()" id="toggle-btn" class="btn-toggle stopped">⏹ 已停止</button>
<button onclick="captureNow()" class="btn-secondary">📸 立即拍照</button>
</div>
</div>
@@ -102,108 +101,116 @@
<div class="modal" id="settings-modal" onclick="closeModalOnBackground(event, 'settings-modal')">
<div class="modal-content settings-modal-content" onclick="event.stopPropagation()">
<span class="modal-close" onclick="closeSettingsModal()">×</span>
<h2>Settings</h2>
<h2>⚙️ 参数设置</h2>
<div class="settings-section">
<h4>Save Settings</h4>
<h4>💾 保存设置</h4>
<div class="setting-item">
<label>Save Dir:</label>
<label>保存目录:</label>
<input type="text" id="setting-images-dir">
</div>
<div class="setting-item">
<label>Interval (s):</label>
<label>拍照间隔 ():</label>
<input type="number" id="setting-interval" value="60" min="10" max="3600">
</div>
<div class="setting-item">
<label>Display Limit:</label>
<label>显示数量:</label>
<input type="number" id="setting-display-limit" value="20" min="5" max="100">
</div>
<div class="setting-item">
<label>Refresh (s):</label>
<label>刷新间隔 ():</label>
<input type="number" id="setting-refresh-interval" value="5" min="1" max="60">
</div>
</div>
<div class="settings-section">
<h4>Person Detection (YOLO)</h4>
<h4>👤 人体检测 (YOLO)</h4>
<div class="setting-item">
<label>Enable:</label>
<label>启用 YOLO:</label>
<input type="checkbox" id="setting-use-yolo" checked>
</div>
<div class="setting-item">
<label>Min Conf:</label>
<label>最小置信度:</label>
<input type="number" id="setting-yolo-confidence" value="0.3" min="0.1" max="1" step="0.1">
<span class="setting-desc">越小越敏感</span>
</div>
</div>
<div class="settings-section">
<h4>Person Identification</h4>
<h4>🔍 人员识别</h4>
<div class="setting-item">
<label>Face Rec:</label>
<label>人脸识别:</label>
<input type="checkbox" id="setting-use-face-rec" checked>
<span class="setting-desc">最准确</span>
</div>
<div class="setting-item">
<label>MediaPipe:</label>
<input type="checkbox" id="setting-use-mediapipe" checked>
<span class="setting-desc">人脸关键点</span>
</div>
<div class="setting-item">
<label>Color Hist:</label>
<label>颜色直方图:</label>
<input type="checkbox" id="setting-use-color-hist" checked>
<span class="setting-desc">备用方法</span>
</div>
<div class="setting-item">
<label>Threshold:</label>
<label>匹配阈值:</label>
<input type="number" id="setting-match-threshold" value="0.6" min="0.1" max="1" step="0.1">
<span class="setting-desc">越小越严格</span>
</div>
</div>
<div class="settings-section">
<h4>Confirmation</h4>
<h4>✅ 连续性判断</h4>
<div class="setting-item">
<label>Confirm Frames:</label>
<label>确认帧数:</label>
<input type="number" id="setting-confirm-frames" value="3" min="1" max="10">
<span class="setting-desc">连续几帧确认变化</span>
</div>
<div class="setting-item">
<label>Leave Frames:</label>
<label>离开帧数:</label>
<input type="number" id="setting-leave-frames" value="2" min="1" max="10">
<span class="setting-desc">连续几帧确认离开</span>
</div>
</div>
<div class="settings-section">
<h4>AI Analysis</h4>
<h4>🤖 AI 大模型分析</h4>
<div class="setting-item">
<label>Enable:</label>
<label>启用大模型:</label>
<input type="checkbox" id="setting-use-vision-api">
<span class="setting-desc">调用 Vision API</span>
</div>
<div class="setting-item">
<label>Trigger:</label>
<label>触发条件:</label>
<select id="setting-vision-trigger">
<option value="person_change">Person Change</option>
<option value="motion">Motion</option>
<option value="brightness">Brightness</option>
<option value="always">Always</option>
<option value="person_change">人员变化时</option>
<option value="motion">运动检测时</option>
<option value="brightness">亮度变化时</option>
<option value="always">总是分析</option>
</select>
</div>
</div>
<div class="settings-section">
<h4>API Config</h4>
<h4>🔑 API 配置</h4>
<div class="setting-item">
<label>URL:</label>
<label>API 地址:</label>
<input type="text" id="setting-api-url">
</div>
<div class="setting-item">
<label>Key:</label>
<label>API Key:</label>
<input type="password" id="setting-api-key">
</div>
<div class="setting-item">
<label>Model:</label>
<label>模型名称:</label>
<input type="text" id="setting-model">
</div>
</div>
<div class="settings-actions">
<button onclick="saveSettings()" class="btn-primary">Save</button>
<button onclick="closeSettingsModal()" class="btn-secondary">Cancel</button>
<button onclick="saveSettings()" class="btn-primary">保存设置</button>
<button onclick="closeSettingsModal()" class="btn-secondary">取消</button>
</div>
</div>
</div>

View File

@@ -128,6 +128,19 @@ button {
background: #f57c00;
}
.btn-toggle {
min-width: 100px;
font-weight: bold;
}
.btn-toggle.stopped {
background: #f44336;
}
.btn-toggle.running {
background: #4CAF50;
}
/* 统计网格 */
.stats-grid {
display: grid;