中文化所有页面 UI 文本

- index.html: 中文化设备操作、任务队列相关文本
- video-learning.html: 中文化会话创建、控制、状态显示等所有文本

Changes:
- placeholder "Enter task..." → "输入任务..."
- button "Execute" → "执行"
- button "Running..." → "运行中..."
- section "Task Queue" → "任务队列"
- section "Devices" → "设备"
- title "Video Learning" → "视频学习"
- form labels: "Device" → "设备", "Platform" → "平台", etc.
- button "Start Learning" → "开始学习"
- session controls: "Resume" → "恢复", "Pause" → "暂停", "Stop" → "停止"
- toast messages: all converted to Chinese
- empty states: "No devices found" → "未找到设备", etc.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
let5sne.win10
2026-01-10 02:28:47 +08:00
parent a356c481ca
commit 88a233284a
2 changed files with 53 additions and 53 deletions

View File

@@ -110,7 +110,7 @@
<input <input
v-model="device.taskInput" v-model="device.taskInput"
type="text" type="text"
placeholder="Enter task..." placeholder="输入任务..."
@keyup.enter="executeTask(device)" @keyup.enter="executeTask(device)"
:disabled="device.status === 'busy' || !device.is_connected" :disabled="device.status === 'busy' || !device.is_connected"
> >
@@ -119,7 +119,7 @@
class="btn btn-primary" class="btn btn-primary"
:disabled="device.status === 'busy' || !device.is_connected || !device.taskInput" :disabled="device.status === 'busy' || !device.is_connected || !device.taskInput"
> >
{{ device.status === 'busy' ? 'Running...' : 'Execute' }} {{ device.status === 'busy' ? '运行中...' : '执行' }}
</button> </button>
</div> </div>
</div> </div>
@@ -129,14 +129,14 @@
<rect x="5" y="2" width="14" height="20" rx="2" ry="2"></rect> <rect x="5" y="2" width="14" height="20" rx="2" ry="2"></rect>
<line x1="12" y1="18" x2="12" y2="18"></line> <line x1="12" y1="18" x2="12" y2="18"></line>
</svg> </svg>
<p>No devices found</p> <p>未找到设备</p>
<button @click="refreshDevices" class="btn btn-secondary">Scan for Devices</button> <button @click="refreshDevices" class="btn btn-secondary">扫描设备</button>
</div> </div>
</section> </section>
<!-- Task Queue --> <!-- Task Queue -->
<section class="tasks-section"> <section class="tasks-section">
<h2>Task Queue</h2> <h2>任务队列</h2>
<div class="task-list" v-if="tasks.length > 0"> <div class="task-list" v-if="tasks.length > 0">
<div <div
class="task-item" class="task-item"
@@ -151,8 +151,8 @@
</div> </div>
<p class="task-description">{{ task.task }}</p> <p class="task-description">{{ task.task }}</p>
<div class="task-meta"> <div class="task-meta">
<span>Device: {{ task.device_id }}</span> <span>设备:{{ task.device_id }}</span>
<span>Step: {{ task.current_step }}/{{ task.max_steps }}</span> <span>步数:{{ task.current_step }}/{{ task.max_steps }}</span>
</div> </div>
<div class="task-progress" v-if="task.status === 'running'"> <div class="task-progress" v-if="task.status === 'running'">
<div class="progress-bar" :style="{ width: (task.current_step / task.max_steps * 100) + '%' }"></div> <div class="progress-bar" :style="{ width: (task.current_step / task.max_steps * 100) + '%' }"></div>
@@ -192,7 +192,7 @@
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="6" y="6" width="12" height="12"></rect> <rect x="6" y="6" width="12" height="12"></rect>
</svg> </svg>
Stop 停止
</button> </button>
</div> </div>
<div class="task-actions" v-else> <div class="task-actions" v-else>
@@ -202,7 +202,7 @@
<polyline points="1 20 1 14 7 14"></polyline> <polyline points="1 20 1 14 7 14"></polyline>
<path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"></path> <path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"></path>
</svg> </svg>
Re-execute 重新执行
</button> </button>
</div> </div>
</div> </div>
@@ -211,8 +211,8 @@
<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1"> <svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1">
<polyline points="22 12 18 12 15 21 9 3 6 12 2 12"></polyline> <polyline points="22 12 18 12 15 21 9 3 6 12 2 12"></polyline>
</svg> </svg>
<p>No tasks yet</p> <p>暂无任务</p>
<p class="hint">Enter a task above to get started</p> <p class="hint">在上方输入任务开始使用</p>
</div> </div>
</section> </section>
</main> </main>

View File

@@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Video Learning - AutoGLM Dashboard</title> <title>视频学习 - AutoGLM Dashboard</title>
<!-- Vue.js 3 --> <!-- Vue.js 3 -->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<!-- Axios for API requests --> <!-- Axios for API requests -->
@@ -56,7 +56,7 @@
<line x1="19" y1="12" x2="5" y2="12"></line> <line x1="19" y1="12" x2="5" y2="12"></line>
<polyline points="12 19 5 12 12 5"></polyline> <polyline points="12 19 5 12 12 5"></polyline>
</svg> </svg>
Back 返回
</button> </button>
</div> </div>
</header> </header>
@@ -65,60 +65,60 @@
<main class="main-content"> <main class="main-content">
<!-- Configuration Section --> <!-- Configuration Section -->
<section class="config-section" v-if="!currentSessionId"> <section class="config-section" v-if="!currentSessionId">
<h2>Create Learning Session</h2> <h2>创建学习会话</h2>
<div class="config-form"> <div class="config-form">
<div class="form-group"> <div class="form-group">
<label>Device</label> <label>设备</label>
<select v-model="config.deviceId" :disabled="loading"> <select v-model="config.deviceId" :disabled="loading">
<option value="">Select a device...</option> <option value="">选择设备...</option>
<option v-for="device in devices" :key="device.device_id" :value="device.device_id" <option v-for="device in devices" :key="device.device_id" :value="device.device_id"
:disabled="!device.is_connected || device.status === 'busy'"> :disabled="!device.is_connected || device.status === 'busy'">
{{ device.device_id }} {{ device.device_id }}
{{ !device.is_connected ? '(Disconnected)' : '' }} {{ !device.is_connected ? '(未连接)' : '' }}
{{ device.status === 'busy' ? '(Busy)' : '' }} {{ device.status === 'busy' ? '(忙碌)' : '' }}
</option> </option>
</select> </select>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>Platform</label> <label>平台</label>
<select v-model="config.platform" :disabled="loading"> <select v-model="config.platform" :disabled="loading">
<option value="douyin">Douyin (抖音)</option> <option value="douyin">抖音</option>
<option value="kuaishou">Kuaishou (快手)</option> <option value="kuaishou">快手</option>
<option value="tiktok">TikTok</option> <option value="tiktok">TikTok</option>
</select> </select>
</div> </div>
<div class="form-row"> <div class="form-row">
<div class="form-group"> <div class="form-group">
<label>Target Videos</label> <label>目标视频数</label>
<input type="number" v-model.number="config.targetCount" min="1" max="100" :disabled="loading"> <input type="number" v-model.number="config.targetCount" min="1" max="100" :disabled="loading">
</div> </div>
<div class="form-group"> <div class="form-group">
<label>Watch Duration (s)</label> <label>观看时长(秒)</label>
<input type="number" v-model.number="config.watchDuration" min="1" max="30" step="0.5" :disabled="loading"> <input type="number" v-model.number="config.watchDuration" min="1" max="30" step="0.5" :disabled="loading">
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>Category (Optional)</label> <label>分类(可选)</label>
<input type="text" v-model="config.category" placeholder="e.g., 美食, 旅行, 搞笑" :disabled="loading"> <input type="text" v-model="config.category" placeholder="例如:美食、旅行、搞笑" :disabled="loading">
<small>Leave empty to watch recommended videos</small> <small>留空则观看推荐视频</small>
</div> </div>
<div class="form-group checkbox-group"> <div class="form-group checkbox-group">
<label> <label>
<input type="checkbox" v-model="config.enableAnalysis" :disabled="loading"> <input type="checkbox" v-model="config.enableAnalysis" :disabled="loading">
<span>Enable Screenshot Analysis</span> <span>启用画面分析</span>
</label> </label>
<small>Analyze video content using VLM to extract description, likes, comments, tags, etc.</small> <small>使用视觉语言模型分析视频内容,提取描述、点赞、评论、标签等信息</small>
</div> </div>
<button @click="createAndStartSession" class="btn btn-primary" :disabled="loading || !config.deviceId"> <button @click="createAndStartSession" class="btn btn-primary" :disabled="loading || !config.deviceId">
<svg v-if="loading" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="spinning"> <svg v-if="loading" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="spinning">
<path d="M21 12a9 9 0 1 1-6.219-8.56"></path> <path d="M21 12a9 9 0 1 1-6.219-8.56"></path>
</svg> </svg>
{{ loading ? 'Creating...' : 'Start Learning' }} {{ loading ? '创建中...' : '开始学习' }}
</button> </button>
</div> </div>
</section> </section>
@@ -126,26 +126,26 @@
<!-- Session Control Section --> <!-- Session Control Section -->
<section class="session-section" v-if="currentSessionId && sessionStatus"> <section class="session-section" v-if="currentSessionId && sessionStatus">
<div class="session-header"> <div class="session-header">
<h2>Session: {{ currentSessionId }}</h2> <h2>会话:{{ currentSessionId }}</h2>
<div class="session-controls"> <div class="session-controls">
<button v-if="sessionStatus.is_paused" @click="resumeSession" class="btn btn-primary btn-sm"> <button v-if="sessionStatus.is_paused" @click="resumeSession" class="btn btn-primary btn-sm">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<polygon points="5 3 19 12 5 21 5 3"></polygon> <polygon points="5 3 19 12 5 21 5 3"></polygon>
</svg> </svg>
Resume 恢复
</button> </button>
<button v-else-if="sessionStatus.is_active" @click="pauseSession" class="btn btn-secondary btn-sm"> <button v-else-if="sessionStatus.is_active" @click="pauseSession" class="btn btn-secondary btn-sm">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="6" y="4" width="4" height="16"></rect> <rect x="6" y="4" width="4" height="16"></rect>
<rect x="14" y="4" width="4" height="16"></rect> <rect x="14" y="4" width="4" height="16"></rect>
</svg> </svg>
Pause 暂停
</button> </button>
<button v-if="sessionStatus.is_active" @click="stopSession" class="btn btn-danger btn-sm"> <button v-if="sessionStatus.is_active" @click="stopSession" class="btn btn-danger btn-sm">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="6" y="6" width="12" height="12"></rect> <rect x="6" y="6" width="12" height="12"></rect>
</svg> </svg>
Stop 停止
</button> </button>
</div> </div>
</div> </div>
@@ -153,20 +153,20 @@
<!-- Progress Bar --> <!-- Progress Bar -->
<div class="progress-section" v-if="sessionStatus.is_active || sessionStatus.is_paused"> <div class="progress-section" v-if="sessionStatus.is_active || sessionStatus.is_paused">
<div class="progress-info"> <div class="progress-info">
<span>Progress: {{ sessionStatus.watched_count }} / {{ sessionStatus.target_count }}</span> <span>进度:{{ sessionStatus.watched_count }} / {{ sessionStatus.target_count }}</span>
<span>{{ Math.round(sessionStatus.progress_percent) }}%</span> <span>{{ Math.round(sessionStatus.progress_percent) }}%</span>
</div> </div>
<div class="progress-bar-large"> <div class="progress-bar-large">
<div class="progress-fill" :style="{ width: sessionStatus.progress_percent + '%' }"></div> <div class="progress-fill" :style="{ width: sessionStatus.progress_percent + '%' }"></div>
</div> </div>
<div class="progress-stats"> <div class="progress-stats">
<span>Total Duration: {{ formatDuration(sessionStatus.total_duration) }}</span> <span>总时长:{{ formatDuration(sessionStatus.total_duration) }}</span>
</div> </div>
</div> </div>
<!-- Current Video --> <!-- Current Video -->
<div class="current-video" v-if="sessionStatus.current_video"> <div class="current-video" v-if="sessionStatus.current_video">
<h3>Current Video</h3> <h3>当前视频</h3>
<div class="video-card"> <div class="video-card">
<div class="video-screenshot" v-if="sessionStatus.current_video.screenshot_path"> <div class="video-screenshot" v-if="sessionStatus.current_video.screenshot_path">
<img :src="sessionStatus.current_video.screenshot_path" alt="Current video"> <img :src="sessionStatus.current_video.screenshot_path" alt="Current video">
@@ -202,15 +202,15 @@
<polyline points="22 4 12 14.01 9 11.01"></polyline> <polyline points="22 4 12 14.01 9 11.01"></polyline>
</svg> </svg>
</div> </div>
<h3>Session Complete!</h3> <h3>会话完成!</h3>
<p>Watched {{ sessionStatus.watched_count }} videos in {{ formatDuration(sessionStatus.total_duration) }}</p> <p>已观看 {{ sessionStatus.watched_count }} 个视频,总时长 {{ formatDuration(sessionStatus.total_duration) }}</p>
<button @click="resetSession" class="btn btn-primary">Start New Session</button> <button @click="resetSession" class="btn btn-primary">开始新会话</button>
</div> </div>
</section> </section>
<!-- Video History --> <!-- Video History -->
<section class="history-section" v-if="videos.length > 0"> <section class="history-section" v-if="videos.length > 0">
<h2>Watched Videos</h2> <h2>已观看视频</h2>
<div class="video-grid"> <div class="video-grid">
<div v-for="video in videos" :key="video.sequence_id" class="video-card"> <div v-for="video in videos" :key="video.sequence_id" class="video-card">
<div class="video-screenshot" v-if="video.screenshot_path"> <div class="video-screenshot" v-if="video.screenshot_path">
@@ -319,13 +319,13 @@
const response = await axios.get('/api/devices'); const response = await axios.get('/api/devices');
this.devices = response.data; this.devices = response.data;
} catch (error) { } catch (error) {
this.showToast('Failed to load devices', 'error'); this.showToast('加载设备失败', 'error');
} }
}, },
async createAndStartSession() { async createAndStartSession() {
if (!this.config.deviceId) { if (!this.config.deviceId) {
this.showToast('Please select a device', 'error'); this.showToast('请选择设备', 'error');
return; return;
} }
@@ -348,16 +348,16 @@
// 保存到 localStorage // 保存到 localStorage
localStorage.setItem('current_session_id', this.currentSessionId); localStorage.setItem('current_session_id', this.currentSessionId);
this.showToast('Session created! Starting...', 'success'); this.showToast('会话已创建!正在启动...', 'success');
// Start session // Start session
await VideoLearningModule.startSession(this.currentSessionId); await VideoLearningModule.startSession(this.currentSessionId);
this.showToast('Learning session started!', 'success'); this.showToast('学习会话已启动!', 'success');
// Initial status update // Initial status update
await this.updateSessionStatus(); await this.updateSessionStatus();
} catch (error) { } catch (error) {
this.showToast('Failed to create session: ' + error.message, 'error'); this.showToast('创建会话失败:' + error.message, 'error');
} finally { } finally {
this.loading = false; this.loading = false;
} }
@@ -369,9 +369,9 @@
try { try {
await VideoLearningModule.controlSession(this.currentSessionId, 'pause'); await VideoLearningModule.controlSession(this.currentSessionId, 'pause');
await this.updateSessionStatus(); await this.updateSessionStatus();
this.showToast('Session paused', 'info'); this.showToast('会话已暂停', 'info');
} catch (error) { } catch (error) {
this.showToast('Failed to pause session', 'error'); this.showToast('暂停会话失败', 'error');
} }
}, },
@@ -381,16 +381,16 @@
try { try {
await VideoLearningModule.controlSession(this.currentSessionId, 'resume'); await VideoLearningModule.controlSession(this.currentSessionId, 'resume');
await this.updateSessionStatus(); await this.updateSessionStatus();
this.showToast('Session resumed', 'info'); this.showToast('会话已恢复', 'info');
} catch (error) { } catch (error) {
this.showToast('Failed to resume session', 'error'); this.showToast('恢复会话失败', 'error');
} }
}, },
async stopSession() { async stopSession() {
if (!this.currentSessionId) return; if (!this.currentSessionId) return;
if (!confirm('Are you sure you want to stop this session?')) return; if (!confirm('确定要停止此会话吗?')) return;
try { try {
await VideoLearningModule.controlSession(this.currentSessionId, 'stop'); await VideoLearningModule.controlSession(this.currentSessionId, 'stop');
@@ -400,9 +400,9 @@
if (this.sessionStatus) { if (this.sessionStatus) {
this.sessionStatus.is_active = false; this.sessionStatus.is_active = false;
} }
this.showToast('Session stopped', 'info'); this.showToast('会话已停止', 'info');
} catch (error) { } catch (error) {
this.showToast('Failed to stop session', 'error'); this.showToast('停止会话失败', 'error');
} }
}, },
@@ -413,7 +413,7 @@
this.sessionStatus = await VideoLearningModule.getSessionStatus(this.currentSessionId); this.sessionStatus = await VideoLearningModule.getSessionStatus(this.currentSessionId);
this.videos = await VideoLearningModule.getSessionVideos(this.currentSessionId); this.videos = await VideoLearningModule.getSessionVideos(this.currentSessionId);
} catch (error) { } catch (error) {
console.error('Error updating session status:', error); console.error('更新会话状态错误:', error);
} }
}, },