crawl(品牌抓取任务队列) - /admin/internal/crawl/tasks 领取 / :id/result 回报,spider 可常驻拉任务 - 后台品牌列表支持「加入抓取队列」,队列页可看状态与重试 - 租约超时的 running 自动回收为 queued,避免 worker 崩溃后任务卡死 media(媒体机直传) - ingest 载荷新增 main_key/detail_keys/main_size/detail_sizes: 有 key 就直接落库,跳过下载与上传;与 URL 形态可逐图混用 - 细节图按 Details/DetailKeys 两者较长者遍历(只给 key 时不再丢图) - 媒体机上传的 key 不进失败回滚清单(内容寻址、可能与他人共享) - /admin/internal/upload-url 签发 S4 PUT 预签名(spider 不持有 AK/SK) embeddings(向量回填) - GET /admin/internal/embeddings/pending 派发缺向量的图(含可直接下载的 url) - POST /admin/internal/embeddings 回写向量并重算近邻;失败项计入 image_embedding_failures,连续失败到上限后退出队列(坏图不占位) - 近邻重算改为异步串行:同步会让 100 张的批次 POST 超时(实测 >60s) - 新增 key 分支单测:混用 key/url、细节图只给 key、字节数、回滚清单、向量占位
45 lines
2.1 KiB
HTML
45 lines
2.1 KiB
HTML
{{define "title"}}抓取任务 · 管理后台{{end}}
|
|
{{define "barLabel"}}管理后台 · 品牌抓取任务{{end}}
|
|
{{define "barRight"}}<a href="/admin/brands">去品牌管理加任务</a> · <a href="/admin/logout">退出</a>{{end}}
|
|
{{define "content"}}
|
|
{{template "bar" .}}
|
|
<div class="main">
|
|
<h1>抓取任务</h1>
|
|
<p class="muted">
|
|
任务是「从品牌管理页加入」的:勾选品牌 → 选场次上限 → 加入抓取队列。
|
|
这里看的是执行状态与失败原因。真正干活的是 spider 服务(可在另一台机器)。
|
|
</p>
|
|
<p class="muted">
|
|
待领取 {{.Queued}} · 执行中 {{.Running}} · 已完成 {{.Done}} · 失败 {{.Failed}},共 {{.Total}} 条。
|
|
<strong>「已提交 0 场」不是错误</strong>——Vogue 上很多品牌没有走秀页面(实测 A 开头里约 75%)。
|
|
</p>
|
|
|
|
<table>
|
|
<thead><tr>
|
|
<th>ID</th><th>品牌</th><th>状态</th><th>场次上限</th><th>已提交</th><th>尝试</th><th>Worker</th><th>更新时间</th><th>错误</th><th>操作</th>
|
|
</tr></thead>
|
|
<tbody>
|
|
{{range .Rows}}<tr>
|
|
<td><code>{{.ID}}</code></td>
|
|
<td><a class="view" href="/admin/brands/{{.BrandUID}}">{{.BrandName}}</a></td>
|
|
<td><span class="badge">{{.StatusLabel}}</span></td>
|
|
<td>{{if eq .MaxShows 0}}<strong>全量</strong>{{else}}{{.MaxShows}}{{end}}</td>
|
|
<td>{{.Shows}}</td>
|
|
<td>{{.Attempts}}</td>
|
|
<td class="muted">{{if .Worker}}{{.Worker}}{{else}}—{{end}}</td>
|
|
<td class="muted">{{.UpdatedAt}}</td>
|
|
<td class="err break">{{.LastError}}</td>
|
|
<td>
|
|
<div class="ops">
|
|
{{if .CanRetry}}<form class="inline" method="post" action="/admin/crawl/tasks/{{.ID}}/retry"><button class="op" type="submit">重试</button></form>{{end}}
|
|
{{if .CanCancel}}<form class="inline" method="post" action="/admin/crawl/tasks/{{.ID}}/cancel"><button class="op" type="submit">取消</button></form>{{end}}
|
|
<form class="inline" method="post" action="/admin/crawl/tasks/{{.ID}}/delete" onsubmit="return confirm('删除任务记录?已入库的数据不受影响。')"><button class="op" type="submit">删除</button></form>
|
|
</div>
|
|
</td>
|
|
</tr>{{end}}
|
|
</tbody>
|
|
</table>
|
|
{{template "pager" .Pager}}
|
|
</div>
|
|
{{end}}
|