feat(v1.10.0): 新增客户自助查询页 /customer
需求与确认: - 完全公开、不加入口链接(用户确认) - 输入手机尾号查询;同一尾号命中多个客户时必须补姓名,模糊匹配(用户确认) - 只展示排单与完成情况:月历每日 已完成/总数、订阅套餐名与类型、到期时间、今日是否清完;不显示备注、打手、价格(用户确认) 实现: - 新增 internal/web/handlers_portal.go:handleCustomerPortal + buildPortal - 尾号查客户(CustomersByTail,已过滤归档客户) - 多命中时返回候选家数并要求补姓名,姓名模糊匹配(不区分大小写) - 月度网格:按订阅覆盖日期统计每日应打/已完成,打卡数据复用 CheckinsBetween - 今日汇总、最近到期日、活跃订阅数 - 新增模板 pages/portal.html(Bootstrap 卡片 + 自定义 .pcal 月历) - 路由 GET /customer(公开,无需登录) - app.css 增加门户与 pcal 样式 - 数据库零改动,未新增表或列 测试: - HTTP 验证 6 条路径全部 200:落地页、仅尾号(提示补姓名)、尾号+姓名模糊、姓名不匹配、尾号不存在、翻月 - 无头浏览器实拍 shots/portal-v110.png(公开页) - 已知待办:门户标题与主按钮的品牌色内联覆盖未生效,需下一版修正(Bootstrap 后加载覆盖了主题色)
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
{{define "content"}}
|
||||
<div class="portal-wrap">
|
||||
<header class="portal-head">
|
||||
<div>
|
||||
<h1>排单查询</h1>
|
||||
<p class="muted">输入手机尾号查看自己的排单与完成情况{{if not .D}};同一尾号有多位客户时需要再填姓名{{end}}</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<form class="portal-form card" method="get" action="/customer">
|
||||
<div class="card-body">
|
||||
<div class="row g-2 align-items-end">
|
||||
<div class="col-12 col-sm-4">
|
||||
<label class="form-label" for="tail">手机尾号</label>
|
||||
<input class="form-control" id="tail" name="tail" value="{{.Query}}" inputmode="numeric" maxlength="8" placeholder="例如 2300" required autofocus>
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<label class="form-label" for="name">客户姓名(可选)</label>
|
||||
<input class="form-control" id="name" name="name" maxlength="32" placeholder="尾号重复时填写">
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<button class="btn btn-primary w-100" type="submit">查询</button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="muted small mb-0 mt-2">只显示排单与完成情况,不含备注与价格。如有疑问请联系代打。</p>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{{if .Error}}<div class="alert alert-warning mt-3" role="alert">{{.Error}}</div>{{end}}
|
||||
|
||||
{{with .D}}
|
||||
{{if .Names}}
|
||||
<div class="card mt-3"><div class="card-body">
|
||||
<h2 class="h5">找到 {{.Count}} 位客户</h2>
|
||||
<p class="muted mb-2">同一尾号有多位客户,请在上方补填姓名(支持模糊匹配)后重新查询。</p>
|
||||
</div></div>
|
||||
{{else}}
|
||||
<section class="portal-result">
|
||||
<div class="card mt-3"><div class="card-body">
|
||||
<div class="d-flex flex-wrap align-items-center gap-2">
|
||||
<h2 class="h4 mb-0">{{.Tail}} · {{.Name}}</h2>
|
||||
{{if .Game}}<span class="tagchip">{{.Game}}</span>{{end}}
|
||||
<span class="tagchip">{{.ActiveSubs}} 个订阅</span>
|
||||
{{if .Expiring}}<span class="tagchip">最近到期 {{.Expiring}}</span>{{end}}
|
||||
<span class="ms-auto">
|
||||
{{if .AllDone}}<span class="badge text-bg-success">今日已清完</span>
|
||||
{{else}}<span class="badge text-bg-warning">今日待完成 {{.TodayDone}} / {{.TodayTotal}}</span>{{end}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="portal-progress mt-3">
|
||||
<div class="bar"><i style="width:{{.TodayPct}}%"></i></div>
|
||||
<span class="muted small">今日 {{.TodayDone}} / {{.TodayTotal}} 单完成</span>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
{{if .Subs}}
|
||||
<div class="row g-3 mt-1">
|
||||
{{range .Subs}}
|
||||
<div class="col-12 col-md-6 col-xl-4">
|
||||
<div class="card h-100"><div class="card-body">
|
||||
<div class="d-flex align-items-center gap-2 mb-1">
|
||||
<strong>{{.Name}}</strong>
|
||||
<span class="tagchip">{{.UnitLabel}}</span>
|
||||
<span class="ms-auto">{{if .TodayDone}}<span class="badge text-bg-success">今日已完成</span>{{else}}<span class="badge text-bg-secondary">今日未完成</span>{{end}}</span>
|
||||
</div>
|
||||
<div class="muted small">{{.Period}}</div>
|
||||
</div></div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<div class="card mt-3"><div class="card-body">
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<h3 class="h6 mb-0">当月排单</h3>
|
||||
<div class="ms-auto d-flex align-items-center gap-2">
|
||||
<a class="btn btn-sm btn-outline-secondary" href="{{.Prev}}">‹</a>
|
||||
<b>{{.MonthTitle}}</b>
|
||||
<a class="btn btn-sm btn-outline-secondary" href="{{.Next}}">›</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pcal">
|
||||
<div class="pcal-dow"><span>一</span><span>二</span><span>三</span><span>四</span><span>五</span><span>六</span><span>日</span></div>
|
||||
{{range .Weeks}}
|
||||
<div class="pcal-row">
|
||||
{{range .}}
|
||||
<div class="pcal-cell{{if not .InMonth}} out{{end}}{{if .Today}} today{{end}}">
|
||||
<b>{{.Day}}</b>
|
||||
{{if and .InMonth .Total}}<span>{{.Done}}/{{.Total}}</span>{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div></div>
|
||||
</section>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user