2026-08-06 16:33:45 +08:00
|
|
|
|
{{define "syb/list"}}
|
|
|
|
|
|
{{template "header" .}}
|
|
|
|
|
|
|
|
|
|
|
|
<div class="toolbar">
|
|
|
|
|
|
<form class="inline" method="post" action="/syb/sync">
|
2026-08-06 16:56:18 +08:00
|
|
|
|
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
2026-08-09 11:49:13 +08:00
|
|
|
|
<input type="hidden" name="order_no" value="{{.Keyword}}">
|
2026-08-06 16:33:45 +08:00
|
|
|
|
<button type="submit">同步</button>
|
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
|
|
|
|
<form class="inline" method="post" action="/syb/create-task">
|
2026-08-06 16:56:18 +08:00
|
|
|
|
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
2026-08-06 16:33:45 +08:00
|
|
|
|
<button type="submit" data-need-checked>创建采购任务</button>
|
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
|
|
|
|
<form class="inline grow" method="get" action="/syb">
|
|
|
|
|
|
<label for="q">订单号</label>
|
2026-08-07 17:13:42 +08:00
|
|
|
|
{{/* search-narrow 把搜索框收到 30%,让「搜索」按钮紧挨着它。
|
|
|
|
|
|
用类名而不是改 .toolbar input[type="text"]——那条被五个页面共用。 */}}
|
|
|
|
|
|
<input id="q" type="text" name="order_no" value="{{.Keyword}}"
|
|
|
|
|
|
class="search-narrow" placeholder="订单号">
|
2026-08-06 16:33:45 +08:00
|
|
|
|
<button type="submit">搜索</button>
|
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
|
|
|
|
<form class="inline" method="post" action="/syb/delete" data-confirm-delete>
|
2026-08-06 16:56:18 +08:00
|
|
|
|
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
2026-08-06 16:33:45 +08:00
|
|
|
|
<button type="submit" class="danger" data-need-checked>删除</button>
|
|
|
|
|
|
</form>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-08-09 11:49:13 +08:00
|
|
|
|
{{if .ConfigProblem}}
|
|
|
|
|
|
<p class="missing">
|
|
|
|
|
|
顺运宝配置有问题:{{.ConfigProblem}}
|
|
|
|
|
|
</p>
|
|
|
|
|
|
{{end}}
|
|
|
|
|
|
|
2026-08-09 12:48:21 +08:00
|
|
|
|
{{/* 未登录只给一行提示,**不弹窗**(工单 #48)。
|
|
|
|
|
|
打开页面纯粹是看数据,不该触发任何对外部系统的动作;
|
|
|
|
|
|
真正会登录的只有「同步」那一个按钮。
|
|
|
|
|
|
用 .hint 不用 .missing——这是状态说明不是错误,
|
|
|
|
|
|
红色留给「PDD 链接未填写」那种要立刻处理的。 */}}
|
|
|
|
|
|
{{if .LoginHint}}
|
|
|
|
|
|
<p class="hint">{{.LoginHint}}</p>
|
|
|
|
|
|
{{end}}
|
|
|
|
|
|
|
2026-08-06 16:33:45 +08:00
|
|
|
|
<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>
|
2026-08-09 11:49:13 +08:00
|
|
|
|
<th>规格</th>
|
2026-08-06 16:33:45 +08:00
|
|
|
|
<th>蝦皮商品 ID</th>
|
|
|
|
|
|
<th>规格 SKU</th>
|
|
|
|
|
|
<th>数量</th>
|
|
|
|
|
|
<th>价格</th>
|
|
|
|
|
|
<th>图片</th>
|
|
|
|
|
|
<th>匹配状态</th>
|
|
|
|
|
|
<th>更新时间</th>
|
|
|
|
|
|
</tr>
|
|
|
|
|
|
</thead>
|
|
|
|
|
|
<tbody>
|
|
|
|
|
|
{{range .Rows}}
|
2026-08-09 11:49:13 +08:00
|
|
|
|
<tr data-detail-id="{{.SybID}}" {{if not .Matched}}class="row-warn"{{end}}>
|
|
|
|
|
|
<td class="col-check">
|
|
|
|
|
|
<input type="checkbox" value="{{.SybID}}" name="ids"
|
|
|
|
|
|
aria-label="选择货运单明细 {{.SybID}}">
|
|
|
|
|
|
</td>
|
|
|
|
|
|
<td>{{.SybID}}</td>
|
|
|
|
|
|
<td>{{.OrderNo}}</td>
|
|
|
|
|
|
<td class="truncate" title="{{.Title}}">{{.Title}}</td>
|
|
|
|
|
|
<td class="truncate" title="{{.ProductSpec}}">{{.ProductSpec}}</td>
|
|
|
|
|
|
<td>{{.ShopeeGoodsID}}</td>
|
|
|
|
|
|
{{/* 匹配状态是算出来的(shopee_sku_id 是否非空),本工单不做匹配功能,
|
|
|
|
|
|
待匹配的行整行标黄提醒,但不提供匹配入口——那是后续工单的范围 */}}
|
|
|
|
|
|
<td>{{if .ShopeeSKUID}}{{.ShopeeSKUID}}{{else}}—{{end}}</td>
|
|
|
|
|
|
<td>{{.Quantity}}</td>
|
|
|
|
|
|
<td>{{.PriceText}}</td>
|
|
|
|
|
|
<td>
|
|
|
|
|
|
{{if .ImageURL}}<img src="{{.ImageURL}}" alt="" class="thumb">{{else}}—{{end}}
|
|
|
|
|
|
</td>
|
|
|
|
|
|
<td>{{.MatchText}}</td>
|
|
|
|
|
|
<td>{{.UpdatedAt}}</td>
|
|
|
|
|
|
</tr>
|
2026-08-06 16:33:45 +08:00
|
|
|
|
{{else}}
|
|
|
|
|
|
<tr class="empty">
|
2026-08-09 11:49:13 +08:00
|
|
|
|
<td colspan="12">
|
|
|
|
|
|
{{if .IsFiltered}}
|
|
|
|
|
|
当前筛选条件下没有货运单明细。<br>
|
|
|
|
|
|
<small>换个订单号或清空搜索词再试。<a href="/syb">查看全部</a></small>
|
|
|
|
|
|
{{else}}
|
|
|
|
|
|
还没有货运单明细。<br>
|
|
|
|
|
|
<small>点上方「同步」从顺运宝拉取,第一次同步需要先登录(验证码需要手工输入)。</small>
|
|
|
|
|
|
{{end}}
|
2026-08-06 16:33:45 +08:00
|
|
|
|
</td>
|
|
|
|
|
|
</tr>
|
|
|
|
|
|
{{end}}
|
|
|
|
|
|
</tbody>
|
|
|
|
|
|
</table>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-08-09 11:49:13 +08:00
|
|
|
|
<p class="hint">
|
|
|
|
|
|
「匹配状态」是根据规格 SKU 是否已填算出来的,本页暂不提供匹配入口
|
|
|
|
|
|
(规格匹配是后续工单的范围)。
|
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
|
{{/* ── 登录弹窗 ─────────────────────────────────
|
|
|
|
|
|
会话未登录/已过期时自动打开(不加 hidden);
|
|
|
|
|
|
`[必须]` 密码不在界面上显示、也不回显到 HTML,只显示只读账号。 */}}
|
|
|
|
|
|
<div class="modal-backdrop" id="login-modal" {{if not .NeedLogin}}hidden{{end}}>
|
|
|
|
|
|
<div class="modal" role="dialog" aria-modal="true" aria-labelledby="login-modal-title">
|
|
|
|
|
|
<div class="modal-head">
|
|
|
|
|
|
<h2 id="login-modal-title">登录顺运宝</h2>
|
|
|
|
|
|
<button type="button" class="modal-x" data-modal-close aria-label="关闭">×</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<form method="post" action="/syb/login-and-sync">
|
|
|
|
|
|
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
|
|
|
|
|
<input type="hidden" name="order_no" value="{{.Keyword}}">
|
|
|
|
|
|
<div class="modal-body">
|
2026-08-09 12:35:02 +08:00
|
|
|
|
{{/* `[必须]` 工单 #47:自动识别验证码失败/降级时要说明原因
|
|
|
|
|
|
(已尝试 N 次 / 服务不可用),操作员才知道是配置错了还是
|
|
|
|
|
|
服务挂了。ocr_url 留空时压根没尝试过自动识别,不显示这条。 */}}
|
|
|
|
|
|
{{if .NeedLoginReason}}
|
|
|
|
|
|
<p class="hint login-degrade-reason">{{.NeedLoginReason}}</p>
|
|
|
|
|
|
{{end}}
|
2026-08-09 11:49:13 +08:00
|
|
|
|
<div class="field">
|
|
|
|
|
|
<label for="login-username">账号</label>
|
|
|
|
|
|
<input id="login-username" type="text" value="{{.Username}}" readonly>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="field">
|
|
|
|
|
|
<label for="login-captcha-img">验证码</label>
|
|
|
|
|
|
{{/* 图片地址带一个时间戳查询参数,确保每次打开弹窗/点"换一张"
|
|
|
|
|
|
都拿到新图,不被浏览器缓存吃掉旧的 */}}
|
|
|
|
|
|
<img id="login-captcha-img" src="/syb/captcha" alt="验证码"
|
|
|
|
|
|
class="captcha-img" data-captcha-refresh="/syb/captcha">
|
|
|
|
|
|
<button type="button" id="login-captcha-refresh">换一张</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="field">
|
|
|
|
|
|
<label for="login-code">验证码文字</label>
|
|
|
|
|
|
<input id="login-code" type="text" name="code" required autocomplete="off"
|
|
|
|
|
|
maxlength="8" placeholder="图片里的 4 位字母数字">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<p class="hint">
|
|
|
|
|
|
账号密码取自 <code>admin/config.yaml</code>,界面上不显示密码。
|
|
|
|
|
|
</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="modal-foot">
|
|
|
|
|
|
<button type="button" data-modal-close>取消</button>
|
|
|
|
|
|
<button type="submit" class="primary">登录并同步</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</form>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-08-06 16:33:45 +08:00
|
|
|
|
|
|
|
|
|
|
{{template "footer" .}}
|
|
|
|
|
|
{{end}}
|