feat: 设置页调 batch_size + 删除任务 + /docs 去认证 + 离线模式

设置页(/settings):
- 新增 Setting DB 模型(键值存储,持久化运行时覆盖)
- config.py 加 _apply_overrides:get_settings() 合并 DB 覆盖值
  (_applying_overrides 标志防递归:DB 初始化回调 get_settings 时不重入)
- save_setting() 写 DB + 清 lru_cache,后续任务读到新值
- settings_router.py: GET/PUT /api/settings
- settings_html.py: 设置页表单(batch_size/beam_size/sort_by_length)
  + 设备只读信息 + 保存后 reload 确认
- 验证:改 asr_batch_size=16 beam_size=1 -> 任务 ASR 日志确认生效
- 验证:重启容器后设置从 DB 恢复(持久化)

删除任务:
- task_router.py: DELETE /api/tasks/{id},仅 done/failed 可删
  删字幕/音频/视频产物 + UploadSession + Task DB 记录
- home_html.py + history_html.py: done/failed 任务显示删除按钮
  + confirm 确认 + 调用 DELETE API + 刷新列表
- 验证:删除 task 15 成功,删除进行中 task 返回 409

/docs 去认证:
- 移除 require_docs_auth 依赖,/docs /redoc /openapi.json 直接公开

离线模式:
- Dockerfile dev/final 加 HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1
  (模型已缓存在 ./models volume,无需联网验证)
- 验证:离线模式完整跑通 ASR+翻译(task 15 done)
This commit is contained in:
audio2text dev
2026-07-11 11:33:34 +08:00
parent 78b87bfb24
commit 7635e5e766
12 changed files with 523 additions and 15 deletions

View File

@@ -77,6 +77,12 @@ function renderTaskInner(task) {{
try {{ created = fmtDateTime24(new Date(task.created_at + "Z")); }}
catch (e) {{ created = task.created_at; }}
// 删除按钮:仅 done/failed 且非上传中任务显示
const canDelete = (task.status === "done" || task.status === "failed") && !task.is_upload;
const delBtn = canDelete
? `<button class="btn-sm del-btn" onclick="deleteTask(${{task.id}}, this)">删除</button>`
: "";
let body;
if (task.status === "done") {{
body = `<div class="task-meta"><b>完成</b> · ${{downloadLinks(task.id)}}</div>`;
@@ -91,11 +97,30 @@ function renderTaskInner(task) {{
<div class="task-head">
<span class="fname">${{task.is_upload ? "" : "#" + task.id + " "}}${{escapeHtml(task.filename)}}</span>
<span class="fstate ${{stateClass}}">${{label}}</span>
${{delBtn}}
</div>
${{body}}
<div class="task-time">${{created}}</div>`;
}}
async function deleteTask(taskId, btn) {{
if (!confirm("确认删除任务 #" + taskId + "?字幕和中间文件将被清除。")) return;
btn.disabled = true;
try {{
const r = await fetch("/api/tasks/" + taskId, {{ method: "DELETE" }});
if (!r.ok) {{
const err = await r.text();
alert("删除失败:" + err);
btn.disabled = false;
return;
}}
refreshList();
}} catch (e) {{
alert("删除失败:" + e);
btn.disabled = false;
}}
}}
async function pollTask(task) {{
// 上传会话:轮询 upload status 接口Task轮询 task 接口
const isUpload = task.is_upload === true && task.upload_id;