171 lines
9.3 KiB
HTML
171 lines
9.3 KiB
HTML
{{define "shopee/list"}}
|
||
{{template "header" .}}
|
||
|
||
{{/* ── 第一段:顶部工具条 ────────────────────────────── */}}
|
||
<div class="toolbar">
|
||
{{if .CurrentUser.IsAdmin}}<a class="button" href="/integrations/catalog">导入记录</a>{{end}}
|
||
<form id="shopee-collect-form" method="post" action="/shopee/collect-batch" hidden></form>
|
||
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}" form="shopee-collect-form">
|
||
<input type="hidden" name="list_goods_id" value="{{.Keyword}}" form="shopee-collect-form">
|
||
<input type="hidden" name="list_shop_name" value="{{.ShopNameKeyword}}" form="shopee-collect-form">
|
||
<input type="hidden" name="status" value="{{.StatusFilter}}" form="shopee-collect-form">
|
||
<input type="hidden" name="shop" value="{{.ShopFilter}}" form="shopee-collect-form">
|
||
<input type="hidden" name="image" value="{{.ImageFilter}}" form="shopee-collect-form">
|
||
<input type="hidden" name="page" value="{{.CurrentPage}}" form="shopee-collect-form">
|
||
<button type="button" data-modal-open="shopee-collect-modal" data-collect-open
|
||
data-collect-form="shopee-collect-form" data-need-checked>创建 PDD 采集任务</button>
|
||
<form class="inline grow" method="get" action="/shopee">
|
||
{{/* 状态筛选是刚需(找待补规格 / 找没填链接的),不是锦上添花,
|
||
见 docs/admin/05-ui-specification.md §4.1、工单 #43。
|
||
放在关键词前面:操作员大多是"看某一类"而不是"查某个 ID"。 */}}
|
||
<label for="status">状态</label>
|
||
<select id="status" name="status">
|
||
{{range .StatusOptions}}
|
||
<option value="{{.Value}}" {{if eq .Value $.StatusFilter}}selected{{end}}>{{.Text}}</option>
|
||
{{end}}
|
||
</select>
|
||
<label for="shop">店铺</label>
|
||
<select id="shop" name="shop">
|
||
{{range .ShopOptions}}
|
||
<option value="{{.Value}}" {{if eq .Value $.ShopFilter}}selected{{end}}>{{.Text}}</option>
|
||
{{end}}
|
||
</select>
|
||
<label for="image">图片</label>
|
||
<select id="image" name="image">
|
||
{{range .ImageOptions}}
|
||
<option value="{{.Value}}" {{if eq .Value $.ImageFilter}}selected{{end}}>{{.Text}}</option>
|
||
{{end}}
|
||
</select>
|
||
<label for="q">商品 ID / 名称</label>
|
||
<input id="q" class="shopee-search-field" type="text" name="goods_id" value="{{.Keyword}}" placeholder="商品 ID / 名称">
|
||
<label for="shop-name">店铺名称</label>
|
||
<input id="shop-name" class="shopee-search-field" type="text" name="shop_name" value="{{.ShopNameKeyword}}" placeholder="店铺名称">
|
||
<button type="submit">搜索</button>
|
||
</form>
|
||
|
||
<form class="inline" method="post" action="/shopee/delete"
|
||
data-confirm-delete>
|
||
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
||
<input type="hidden" name="list_goods_id" value="{{.Keyword}}">
|
||
<input type="hidden" name="list_shop_name" value="{{.ShopNameKeyword}}">
|
||
<input type="hidden" name="status" value="{{.StatusFilter}}">
|
||
<input type="hidden" name="shop" value="{{.ShopFilter}}">
|
||
<input type="hidden" name="image" value="{{.ImageFilter}}">
|
||
<input type="hidden" name="page" value="{{.CurrentPage}}">
|
||
<button type="submit" class="danger" data-need-checked>删除</button>
|
||
</form>
|
||
</div>
|
||
|
||
{{/* ── 第二段:带勾选的表格 ──────────────────────────── */}}
|
||
{{/* 一个商品一行(不是一个 SKU 一行),见工单 #41。
|
||
双击行打开详情弹窗,见 static/js/app.js。 */}}
|
||
<div class="table-wrap">
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th class="col-check"><input type="checkbox" data-check-all></th>
|
||
<th>商品 ID</th>
|
||
<th>图片</th>
|
||
<th>商品名称</th>
|
||
<th>蝦皮店铺</th>
|
||
<th>颜色</th>
|
||
<th>尺码</th>
|
||
{{/* SKU 数是这个商品报表里实际出现过的规格条数。
|
||
`[必须]` 必须单独显示——颜色数 × 尺码数经常大于它(蝦皮报表只含
|
||
有销售成绩的 SKU),只看前两列会让人误以为要匹配的规格更多,见 #41。 */}}
|
||
<th>SKU</th>
|
||
{{/* `[必须]` 待补 > 0 说明该商品有 SKU 解析失败,整行标黄(.row-warn)。
|
||
聚合成商品级之后,"部分失败"的行光看数字是正常的,
|
||
不加这一列坏数据就会被悄悄吃掉,见 #41。 */}}
|
||
<th>待补</th>
|
||
<th>来源</th>
|
||
<th>PDD 链接</th>
|
||
<th>采集状态</th>
|
||
<th>更新时间</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{{range .Rows}}
|
||
<tr data-detail-id="{{.GoodsID}}"{{if gt .PendingCount 0}} class="row-warn"{{end}}>
|
||
<td class="col-check"><input type="checkbox" name="ids" value="{{.GoodsID}}" form="shopee-collect-form"></td>
|
||
<td>{{.GoodsID}}</td>
|
||
<td>{{if .ImageURL}}<button type="button" class="thumb-action" data-image-preview-url="{{.ImageURL}}" data-image-preview-title="{{.Title}}" title="查看蝦皮主图"><img src="{{.ImageURL}}" alt="{{.Title}} 缩略图" class="thumb" width="32" height="32" loading="lazy" referrerpolicy="no-referrer" data-image-thumb><span class="thumb-fallback" hidden data-image-thumb-fallback>加载失败</span></button>{{else}}<span class="thumb-placeholder">无图</span>{{end}}</td>
|
||
{{/* 商品名称列收窄,用独立的 .col-title 类设 max-width(具体数值见 app.css),
|
||
不用 flex——表格单元格和工具条的 .search-narrow 那套不一样,见 #41。
|
||
title 属性让悬停能看完整标题,收窄之后必须留着。 */}}
|
||
<td class="truncate col-title" title="{{.Title}}">{{.Title}}</td>
|
||
<td class="truncate col-shop" title="{{.ShopName}}">{{if .ShopName}}{{.ShopName}}{{else}}—{{end}}</td>
|
||
<td>{{.ColorCount}}</td>
|
||
<td>{{.SizeCount}}</td>
|
||
<td>{{.SKUCount}}</td>
|
||
<td>{{.PendingCount}}</td>
|
||
<td>{{.SourceText}}</td>
|
||
<td{{if .PddMissing}} class="missing"{{end}}>{{.PddURL}}</td>
|
||
<td>{{.StatusText}}</td>
|
||
<td>{{.UpdatedAt}}</td>
|
||
</tr>
|
||
{{else}}
|
||
<tr class="empty">
|
||
<td colspan="13">
|
||
{{if .IsFiltered}}
|
||
当前筛选条件下没有商品。请调整状态、店铺、图片或商品 ID。<br>
|
||
<small><a href="/shopee">清除筛选条件</a></small>
|
||
{{else}}
|
||
还没有数据。蝦皮与 PDD 对应数据由第三方脚本通过商品目录接口导入。<br>
|
||
{{if $.CurrentUser.IsAdmin}}<small>可点击左上角「导入记录」查看脚本提交结果。</small>{{end}}
|
||
{{end}}
|
||
</td>
|
||
</tr>
|
||
{{end}}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div class="modal-backdrop" id="shopee-collect-modal" hidden>
|
||
<div class="modal" role="dialog" aria-modal="true" aria-labelledby="shopee-collect-modal-title">
|
||
<div class="modal-head">
|
||
<h2 id="shopee-collect-modal-title">创建 PDD 采集任务</h2>
|
||
<button type="button" class="modal-x" data-modal-close aria-label="关闭">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<p>将按当前 PDD 关联处理已选择的 <strong data-collect-count>0</strong> 个蝦皮商品。</p>
|
||
<div class="field">
|
||
<label for="shopee-collect-client">执行客户端</label>
|
||
<select id="shopee-collect-client" name="client_id" form="shopee-collect-form" autofocus>
|
||
<option value="">不指定(任意客户端可领取)</option>
|
||
{{range .AssignableClients}}
|
||
<option value="{{.ClientID}}">{{.Name}}({{.ClientID}},{{.Status}})</option>
|
||
{{end}}
|
||
</select>
|
||
</div>
|
||
<p class="hint">相同 PDD 商品只创建一个任务;未关联、已删除、已采集和正在采集的商品会按原因统计并跳过。</p>
|
||
</div>
|
||
<div class="modal-foot">
|
||
<button type="button" data-modal-close>取消</button>
|
||
<button type="submit" form="shopee-collect-form" class="primary" data-collect-submit>确认创建</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="modal-backdrop" id="image-preview-modal" hidden><div class="modal image-preview-modal" role="dialog" aria-modal="true" aria-labelledby="image-preview-title"><div class="modal-head"><h2 id="image-preview-title" data-image-preview-title>蝦皮商品主图</h2><button type="button" class="modal-x" data-modal-close aria-label="关闭">×</button></div><div class="modal-body image-preview-body"><p class="hint image-preview-status" data-image-preview-status role="status">正在加载原图…</p><img data-image-preview-image alt="" hidden></div><div class="modal-foot"><a class="button-link" data-image-preview-link href="#" target="_blank" rel="noopener noreferrer">新窗口打开原图</a><button type="button" data-modal-close>关闭</button></div></div></div>
|
||
|
||
<p class="hint">
|
||
双击任意一行可以查看这个商品的完整规格表。
|
||
</p>
|
||
|
||
|
||
{{/* ── 详情弹窗的壳子 ───────────────────────────
|
||
里面的内容双击行时由 /shopee/detail 返回,前端只负责放进来和显示,
|
||
复用 #18 的机制(data-detail-url / data-detail-slot / data-detail-id),
|
||
app.js 不需要改,见工单 #41。
|
||
|
||
弹窗同时提供当前 PDD 关联和单商品采集入口。 */}}
|
||
<div class="modal-backdrop" id="detail-modal" data-detail-url="{{.DetailURL}}" hidden>
|
||
<div class="modal" role="dialog" aria-modal="true" data-detail-slot>
|
||
<div class="modal-body">正在加载…</div>
|
||
</div>
|
||
</div>
|
||
|
||
{{template "footer" .}}
|
||
{{end}}
|