feat: 优化控制台交互 - 移除冗余选项、添加自动执行和任务详情功能

This commit is contained in:
2026-03-10 23:52:01 +08:00
parent 5bcfa9effc
commit 110367fe4f
2 changed files with 147 additions and 36 deletions

View File

@@ -91,13 +91,17 @@
<select id="taskType"> <select id="taskType">
<option value="ephemeral">即时任务 (Ephemeral)</option> <option value="ephemeral">即时任务 (Ephemeral)</option>
<option value="persistent">持久任务 (Persistent)</option> <option value="persistent">持久任务 (Persistent)</option>
<option value="scheduled">定时任务 (Scheduled)</option>
</select> </select>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>任务描述 (Prompt)</label> <label>任务描述 (Prompt)</label>
<textarea id="taskPrompt" placeholder="输入任务描述..."></textarea> <textarea id="taskPrompt" placeholder="输入任务描述..."></textarea>
</div> </div>
<div class="form-group">
<label>
<input type="checkbox" id="autoExecute" checked> 创建后自动执行
</label>
</div>
<button class="btn" onclick="createTask()">创建任务</button> <button class="btn" onclick="createTask()">创建任务</button>
</div> </div>
<div class="card"> <div class="card">
@@ -121,6 +125,10 @@
<tbody id="tasksTable"></tbody> <tbody id="tasksTable"></tbody>
</table> </table>
</div> </div>
<div class="card" id="taskDetailPanel" style="display: none;">
<h2>任务详情</h2>
<div id="taskDetailContent"></div>
</div>
</div> </div>
<!-- 定时任务 --> <!-- 定时任务 -->
@@ -161,6 +169,7 @@
<th>ID</th> <th>ID</th>
<th>名称</th> <th>名称</th>
<th>Cron</th> <th>Cron</th>
<th>状态</th>
<th>提示词</th> <th>提示词</th>
<th>操作</th> <th>操作</th>
</tr> </tr>
@@ -322,6 +331,7 @@
async function createTask() { async function createTask() {
const type = document.getElementById('taskType').value; const type = document.getElementById('taskType').value;
const prompt = document.getElementById('taskPrompt').value; const prompt = document.getElementById('taskPrompt').value;
const autoExecute = document.getElementById('autoExecute').checked;
if (!prompt) return alert('请输入任务描述'); if (!prompt) return alert('请输入任务描述');
try { try {
@@ -334,6 +344,11 @@
addLog('创建任务: ' + task.id, 'info'); addLog('创建任务: ' + task.id, 'info');
document.getElementById('taskPrompt').value = ''; document.getElementById('taskPrompt').value = '';
loadTasks(); loadTasks();
if (autoExecute) {
addLog('正在自动执行任务...', 'info');
await executeTask(task.id, type === 'persistent');
}
} catch (e) { } catch (e) {
alert('创建失败: ' + e.message); alert('创建失败: ' + e.message);
} }
@@ -351,6 +366,7 @@
<td>${t.prompt.substring(0, 30)}${t.prompt.length > 30 ? '...' : ''}</td> <td>${t.prompt.substring(0, 30)}${t.prompt.length > 30 ? '...' : ''}</td>
<td><span class="status-badge status-${t.status}">${t.status}</span></td> <td><span class="status-badge status-${t.status}">${t.status}</span></td>
<td class="flex"> <td class="flex">
<button class="btn" style="padding: 5px 10px; font-size: 12px;" onclick="viewTask('${t.id}')">详情</button>
<button class="btn" style="padding: 5px 10px; font-size: 12px;" onclick="executeTask('${t.id}', false)">执行</button> <button class="btn" style="padding: 5px 10px; font-size: 12px;" onclick="executeTask('${t.id}', false)">执行</button>
<button class="btn btn-success" style="padding: 5px 10px; font-size: 12px;" onclick="executeTask('${t.id}', true)">异步</button> <button class="btn btn-success" style="padding: 5px 10px; font-size: 12px;" onclick="executeTask('${t.id}', true)">异步</button>
<button class="btn btn-danger" style="padding: 5px 10px; font-size: 12px;" onclick="abortTask('${t.id}')">中止</button> <button class="btn btn-danger" style="padding: 5px 10px; font-size: 12px;" onclick="abortTask('${t.id}')">中止</button>
@@ -362,6 +378,32 @@
} }
} }
async function viewTask(taskId) {
try {
const res = await fetch(API_BASE + '/task/' + taskId);
const task = await res.json();
const panel = document.getElementById('taskDetailPanel');
const content = document.getElementById('taskDetailContent');
panel.style.display = 'block';
content.innerHTML = `
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px;">
<div><strong>任务ID:</strong> ${task.id}</div>
<div><strong>类型:</strong> ${task.type}</div>
<div><strong>状态:</strong> <span class="status-badge status-${task.status}">${task.status}</span></div>
<div><strong>Session ID:</strong> ${task.session_id || '-'}</div>
<div style="grid-column: 1 / -1;"><strong>提示词:</strong> <pre style="background: #0f0f23; padding: 10px; border-radius: 4px; margin-top: 5px;">${task.prompt}</pre></div>
${task.error ? `<div style="grid-column: 1 / -1; color: #ff4757;"><strong>错误信息:</strong> ${task.error}</div>` : ''}
<div><strong>创建时间:</strong> ${task.created_at || '-'}</div>
<div><strong>开始时间:</strong> ${task.started_at || '-'}</div>
<div><strong>完成时间:</strong> ${task.finished_at || '-'}</div>
</div>
`;
panel.scrollIntoView({behavior: 'smooth'});
} catch (e) {
alert('获取详情失败: ' + e.message);
}
}
async function executeTask(taskId, async_) { async function executeTask(taskId, async_) {
try { try {
const endpoint = async_ ? '/execute_async' : '/execute'; const endpoint = async_ ? '/execute_async' : '/execute';
@@ -418,7 +460,8 @@
<td>${s.id}</td> <td>${s.id}</td>
<td>${s.name || '-'}</td> <td>${s.name || '-'}</td>
<td>${s.cron}</td> <td>${s.cron}</td>
<td>${(s.prompt || '').substring(0, 30)}...</td> <td><span class="status-badge status-${s.enabled ? 'completed' : 'pending'}">${s.enabled ? '已启用' : '已禁用'}</span></td>
<td>${(s.prompt || '').substring(0, 30)}${(s.prompt || '').length > 30 ? '...' : ''}</td>
<td> <td>
<button class="btn btn-danger" style="padding: 5px 10px; font-size: 12px;" onclick="deleteSchedule('${s.id}')">删除</button> <button class="btn btn-danger" style="padding: 5px 10px; font-size: 12px;" onclick="deleteSchedule('${s.id}')">删除</button>
</td> </td>

View File

@@ -12,8 +12,8 @@ http://localhost:8888/console.html
| Tab | 功能 | | Tab | 功能 |
|-----|------| |-----|------|
| 任务管理 | 创建、执行、管理即时/持久/定时任务 | | 任务管理 | 创建、执行一次性任务 |
| 定时任务 | 创建和管理 Cron 定时任务 | | 定时任务 | 创建和管理 Cron 循环调度任务 |
| 历史记录 | 查看任务执行历史 | | 历史记录 | 查看任务执行历史 |
| 持久会话 | 创建和管理多轮对话会话 | | 持久会话 | 创建和管理多轮对话会话 |
| 实时日志 | WebSocket 实时推送的任务状态 | | 实时日志 | WebSocket 实时推送的任务状态 |
@@ -22,39 +22,61 @@ http://localhost:8888/console.html
## 1. 任务管理 ## 1. 任务管理
> 用于创建一次性执行的任务。任务创建后不会自动执行,需要手动点击「执行」按钮。
### 任务类型
| 类型 | 说明 | 使用场景 |
|------|------|----------|
| **Ephemeral (即时任务)** | 一次性任务,执行完成后结束 | 临时性的 AI 问答、代码生成等 |
| **Persistent (持久任务)** | 可多轮交互的任务会话 | 需要多轮对话才能完成的任务 |
### 创建任务 ### 创建任务
1. 选择任务类型 1. 选择任务类型(即时任务/持久任务)
- **Ephemeral (即时任务)**:一次性任务,执行后结束
- **Persistent (持久任务)**:可多轮交互的任务
- **Scheduled (定时任务)**:需要配合定时任务模块使用
2. 输入任务描述 (Prompt) 2. 输入任务描述 (Prompt)
3. 可选:勾选「创建后自动执行」
4. 点击「创建任务」
3. 点击「创建任务」 > 💡 **提示**:默认勾选「创建后自动执行」,任务创建后会立即执行。如果需要手动控制执行,取消勾选即可。
### 执行任务 ### 执行任务
创建任务后,在任务列表中可以: 创建任务后,在任务列表中可以执行以下操作
| 按钮 | 功能 | | 按钮 | 功能 |
|------|------| |------|------|
| 详情 | 查看任务的完整信息,包括 Session ID、错误信息等 |
| 执行 | 同步执行任务,等待完成 | | 执行 | 同步执行任务,等待完成 |
| 异步 | 异步执行任务,立即返回 | | 异步 | 异步执行任务,立即返回 |
| 中止 | 终止正在执行的任务 | | 中止 | 终止正在执行的任务 |
### 任务状态 ### 任务详情
- `pending` - 待执行 点击「详情」按钮可以查看任务的完整信息:
- `running` - 执行中
- `completed` - 已完成 - **任务ID**:任务的唯一标识
- `failed` - 执行失败 - **类型**:即时任务/持久任务
- `aborted` - 已中止 - **状态**:任务的当前状态
- **Session ID**OpenCode 会话 ID可用于在 OpenCode 界面查看对话详情
- **提示词**:任务的完整描述
- **错误信息**:任务失败时的错误原因
- **创建/开始/完成时间**:任务的时间线
--- ---
## 2. 定时任务 ## 2. 定时任务
> 用于创建**循环执行**的定时调度任务。基于 Cron 表达式,在指定时间自动执行任务。
### 与「任务管理」的区别
| 功能 | 任务管理 | 定时任务 |
|------|----------|----------|
| 执行方式 | 手动点击执行 | 自动执行 |
| 执行次数 | 一次 | 循环执行 |
| 配置方式 | 创建后手动执行 | 配置 Cron 表达式,自动触发 |
### 创建定时任务 ### 创建定时任务
| 字段 | 说明 | | 字段 | 说明 |
@@ -63,7 +85,19 @@ http://localhost:8888/console.html
| 任务名称 | 显示名称,如「每日任务」 | | 任务名称 | 显示名称,如「每日任务」 |
| Cron 表达式 | 执行时间,如 `0 9 * * *` (每天9点) | | Cron 表达式 | 执行时间,如 `0 9 * * *` (每天9点) |
| 执行内容 | 定时执行的 Prompt | | 执行内容 | 定时执行的 Prompt |
| 启用 | 是否启用此定时任务 | | 启用 | 是否启用此定时任务(未启用则不会执行) |
### 定时任务列表
表格显示所有定时任务,包含以下信息:
| 列 | 说明 |
|-----|------|
| ID | 任务唯一标识 |
| 名称 | 任务显示名称 |
| Cron | 执行时间表达式 |
| 状态 | 已启用 / 已禁用 |
| 提示词 | 执行内容摘要 |
### 常用 Cron 示例 ### 常用 Cron 示例
@@ -78,43 +112,77 @@ http://localhost:8888/console.html
## 3. 历史记录 ## 3. 历史记录
- 查看所有已完成的任务记录 > 查看所有已完成的任务执行历史记录。
- 支持限制显示条数
- 可清空历史记录 ### 功能说明
- **查看历史**:显示所有任务的执行记录,包括类型、描述、状态、时间等
- **显示条数**:可自定义显示的记录数量
- **清空历史**:一键清空所有历史记录
### 任务状态说明
| 状态 | 说明 |
|------|------|
| `pending` | 待执行 |
| `running` | 执行中 |
| `completed` | 已完成 |
| `failed` | 执行失败 |
| `aborted` | 已中止 |
--- ---
## 4. 持久会话 ## 4. 持久会话
### 创建会话 > 创建可**多轮交互**的对话会话。与「任务管理」中的即时任务不同,持久会话可以多次发送消息,保持上下文连贯。
输入会话名称(可选),点击「创建」 ### 与即时任务的区别
### 发送消息 | 特性 | 即时任务 | 持久会话 |
|------|----------|----------|
| 交互次数 | 单次 | 多次 |
| 上下文 | 不保持 | 自动保持 |
| 适用场景 | 简单问答 | 复杂任务、多轮对话 |
1. 在列表中找到目标会话 ### 使用流程
2. 点击「发消息」按钮
3. 输入消息内容 1. **创建会话**:输入会话名称(可选),点击「创建」
4. 选择发送方式: 2. **发送消息**:点击会话的「发消息」按钮
- **同步发送**:等待响应返回 3. **选择发送方式**
- **同步发送**:等待 AI 响应返回后再操作
- **异步发送**:立即返回,任务在后台执行 - **异步发送**:立即返回,任务在后台执行
--- ---
## 5. 实时日志 ## 5. 实时日志
通过 WebSocket 实时显示 > 通过 WebSocket 实时显示任务状态和系统消息。
- 任务状态变化 ### 显示内容
- WebSocket 连接状态
- 操作日志 - 任务创建、执行、完成的实时通知
- WebSocket 连接状态变化
- 操作日志和错误信息
### 连接状态
页面左上角显示 WebSocket 连接状态:
- **已连接** - 绿色圆点,正常接收消息
- **未连接** - 红色圆点,需要刷新页面重连
--- ---
## 快捷操作 ## 快速参考
- **自动刷新**:健康检查和任务列表每 5 秒自动刷新 ### 功能对比
- **WebSocket**:页面左上角显示连接状态
| 需求 | 推荐功能 |
|------|----------|
| 临时性的 AI 问答 | 任务管理 → 即时任务 |
| 需要多轮对话的复杂任务 | 任务管理 → 持久任务 |
| 每天定时执行某任务 | 定时任务 |
| 查看任务执行历史 | 历史记录 |
| 实时监控任务状态 | 实时日志 |
--- ---