Files
subtrack/internal/web/templates/pages/package_form.html
T
subtrack 85f98dff5c feat(v1.2): 亮暗主题、按尾号快速完成、加急置顶、按套餐分日历、大屏升级
1) 全站亮色 / 暗色
- 管理端与大屏都提供切换按钮(顶栏 ☾/☀、大屏右上角),偏好写 cookie,服务端首屏直出,不闪
- 未选择时跟随系统(prefers-color-scheme);两套配色都改成 CSS 变量,色签、热力、表格、抽屉全部适配
- 大屏默认仍是深色记分板,浅色为纸感背景

2) 工作台 → 当日待完成:按手机尾号快速完成
- 输入尾号回车:唯一匹配直接完成并提示
- 同尾号多客户 / 一单多服务:跳到选择面板,默认全选,可多选后一次完成
- 新增 POST /checkins/quick 与 POST /checkins/batch;抽屉标题改为「未完成数 / 总单数」

3) 加急
- 每条任务右侧可勾选/取消加急;加急任务红 tag + 置顶(抽屉与大屏「今日待打」)
- 日历格子出现红点,单据色签加红边;大屏热力格也带红点
- 新增表 task_flags(sub_id, service_date, urgent),按 订阅+日期 存,避免和打卡状态耦合

4) 套餐「在日历中独立显示」
- 套餐表单新增勾选项,列表页显示「独立日历」标记
- 勾选后工作台与大屏顶部出现套餐标签页(全部 / 每日任务 / …),可只看某类委托的排单、热量与待办
- 新增列 packages.calendar_separate;老库打开时自动 ALTER,无需手工迁移

5) 大屏
- 热力默认改为「每日待完成单量」,右上角可切回「到期热力」
- 鼠标悬停任意日期格,浮出当日待办明细(客户、套餐、剩余、加急),数据来自 GET /api/screen/day
- 底部面板改为「今日到期」(左)+「今日待打」(右,加急置顶),最近追加改为最底部细条

数据库兼容性:
- 只做加法:新增 task_flags 表与 packages.calendar_separate 列,原有表结构、字段、接口与已有数据均不变
- 迁移可重复执行(CREATE TABLE IF NOT EXISTS + PRAGMA 检查后 ALTER)

测试:
- 新增单元测试:套餐独立日历标记、加急增删查、旧库自动加列与重复迁移
- 新增功能冒烟 33 项(主题 cookie、套餐标签、快速完成单/多匹配、加急排序、大屏接口)全部通过
- 原有 119 项验收回归全绿(3 条断言按新 UI 更新:抽屉标题、热力默认口径、今日待打数取值方式)
- go vet / go test ./... 通过;版本号 1.2.0
2026-10-18 22:07:25 +08:00

63 lines
2.8 KiB
HTML

{{define "content"}}
<div class="page narrow">
<header class="page-head">
<div>
<h1>{{if .D.IsNew}}新增套餐{{else}}编辑套餐{{end}}</h1>
<p class="muted">按日套餐用起止日期计算剩余天数;按次套餐记录剩余次数。</p>
</div>
</header>
<form method="post" class="form card" data-package-form
action="{{if .D.IsNew}}/packages{{else}}/packages/{{.D.Package.ID}}/edit{{end}}">
<label class="field"><span>套餐名称 <i>*</i></span>
<input name="name" required maxlength="32" value="{{.D.Package.Name}}" placeholder="例如 包月日常 / 赛季深渊 / 10 次副本">
</label>
<fieldset class="field">
<span>计费方式 <i>*</i></span>
<div class="radios">
<label><input type="radio" name="unit" value="day"{{if eq .D.Package.Unit "day"}} checked{{end}}>
<b>按日</b><small>有开始日与结束日,每天一条待打任务,可打卡</small></label>
<label><input type="radio" name="unit" value="count"{{if eq .D.Package.Unit "count"}} checked{{end}}>
<b>按次</b><small>记录剩余次数,排期完成时自动扣 1 次,有效期可选</small></label>
</div>
</fieldset>
<div class="grid-2">
<label class="field"><span>默认量 <i>*</i></span>
<div class="input-suffix">
<input type="number" name="default_amount" min="1" max="10000" value="{{.D.Package.DefaultAmount}}" required>
<b data-unit-label>{{if eq .D.Package.Unit "count"}}次{{else}}天{{end}}</b>
</div>
</label>
<label class="field"><span>参考价(元,可空)</span>
<input type="number" name="price" min="0" step="1" value="{{if .D.Package.HasPrice}}{{money .D.Package.PriceCents}}{{end}}" placeholder="例如 300">
</label>
</div>
<div class="grid-2">
<label class="field"><span>日历色签</span>
<input type="color" name="color" value="{{.D.Package.Color}}">
</label>
<label class="field"><span>排序(小的靠前)</span>
<input type="number" name="sort_order" value="{{.D.Package.SortOrder}}">
</label>
</div>
<label class="check-line">
<input type="checkbox" name="calendar_separate" value="1"{{if .D.Package.CalendarSeparate}} checked{{end}}>
<span>在日历中独立显示<small>勾选后工作台和大屏的日历会为该套餐单独开一个标签页,便于把“每日任务”和其他委托分开看</small></span>
</label>
<label class="field"><span>说明</span>
<textarea name="note" rows="2" maxlength="200" placeholder="套餐包含什么、怎么个打法">{{.D.Package.Note}}</textarea>
</label>
<div class="actions">
<button class="btn btn-primary" type="submit">保存</button>
<a class="btn" href="/packages">取消</a>
</div>
</form>
</div>
{{end}}