build / build-and-test (push) Successful in 3m38s
背景:v1.9.0 把界面迁到 Bootstrap 5 时保留了旧自研 CSS,v1.9.2 又叠加了一层 「墨绿渐变」覆盖层,形成三套令牌(--paper/--ink、prefers-color-scheme、 data-bs-theme)并存。系统偏好与 Cookie 不一致时,页面会出现半亮半暗、表单 标签/抽屉标题/订阅页签不可见、输入框变黑块等问题。 本次改动: - 样式加载顺序改为 bootstrap → app.css;删除旧纸墨令牌与 v1.9.2 覆盖层, app.css 重写为单一主题层(:root/[data-bs-theme=light] 与 [data-bs-theme=dark] 两套语义令牌)。组件只读 --app-*,解决 --ink-2 同时被当作「次级文字色」和 「卡片底色」的语义冲突。 - 主题只认 <html data-bs-theme>:服务端按 Cookie 直出;没有 Cookie 时由 <head> 内联脚本在首屏按系统偏好补齐,修好「跟随系统」并避免闪白。大屏同理。 - 修复 Bootstrap 覆盖自研设计的问题:正文 14px + 中文字体栈、22/16/14px 标题、 按钮/输入框/焦点环/卡片回到设计值;普通按钮新增 .btn-soft,不再变透明文字。 - 布局修复:客户/套餐表单的 .grid-2 不再塞 3 个字段;包详情页把筛选独立成 GET 表单(在搜索框回车不再误触批量开通);客户详情操作区与 meta 重排; 抽屉时钟改为固定 46px 并用它对齐抽屉头的 sticky 偏移;追加面板在抽屉里 两列月历、不再 1100px 竖排;手机端日历数字不再换行溢出,移动端表格隐藏 低优先级列,不再被裁切。 - 大屏:KPI/面板去掉 Bootstrap utility,统一由 screen.css 控制;TOP/今日待打 改为固定列宽 + grid-column 对齐;浅色主题的链接、热力、图例对比度补齐; 热力格不再整体降透明度;当日浮层可滚动并支持点击/键盘打开。 - 配色与可读性:普通文本对比度全部达标(截图 lint 由 65 处降到 0);日历 外月日期改为浅底深字,不再整格 opacity;archived 行改为中性底色而非降透明。 - 缓存:新增内嵌静态资源内容指纹 AssetVersion(12 位 sha256),所有 /static 链接带 ?v=;带指纹的响应 public, max-age=31536000, immutable,不带指纹的 回源 no-cache;HTML 继续 no-store。改样式重新编译即自动破缓存,不再依赖 手改版本号(仍保留 v1.10.0 作为产品版本)。 - 认证页重做:登录/初始化页改用 .auth 卡片(品牌、主题切换、绿色焦点环), 去掉 min-height:100vh 叠加 main padding 造成的 40px 纵向滚动。 - JS:修 toISOString 计算自然日差一天的时区 bug;主题切换读 data-bs-theme 并同步 aria-pressed;全选支持半选;大屏切主题同时更新 data-bs-theme; 提示条改为固定定位、淡出不再顶动页面。 - README 更新主题与缓存说明;版本号 1.9.5 → 1.10.0。 验证:gofmt / go vet / go test 全绿;1440、1100、390 三档,明暗两套,工作台/ 客户/套餐/订阅/设置/日志/大屏/登录全部截图走查,无横向溢出与控制台错误。
113 lines
6.1 KiB
HTML
113 lines
6.1 KiB
HTML
{{define "content"}}
|
|
<div class="page narrow">
|
|
<header class="page-head">
|
|
<div>
|
|
<h1>设置</h1>
|
|
<p>预警天数、备份、账户与数据导出</p>
|
|
</div>
|
|
</header>
|
|
|
|
<section class="section card">
|
|
<h2>基础设置</h2>
|
|
<form method="post" action="/settings" class="form">
|
|
<div class="grid-2">
|
|
<label class="field"><span>到期预警(天)</span>
|
|
<input type="number" name="warn_days" min="0" max="60" value="{{.D.WarnDays}}">
|
|
</label>
|
|
<label class="field"><span>大屏自动刷新(秒)</span>
|
|
<input type="number" name="screen_refresh" min="5" max="600" value="{{.D.ScreenRefresh}}">
|
|
</label>
|
|
</div>
|
|
<p class="muted small">监听地址、端口、数据库、备份、日志、时区等部署参数在 <code>daili.ini</code> 里配置,改完重启生效。</p>
|
|
<div class="actions"><button class="btn btn-primary" type="submit">保存设置</button></div>
|
|
</form>
|
|
</section>
|
|
|
|
<section class="section card">
|
|
<h2>管理员</h2>
|
|
<p class="muted small">所有账户权限相同,任何操作都会记在日志里。每个管理员的颜色用于日历左侧竖条和待办标识。</p>
|
|
<p class="muted small">{{if eq .User.ID 1}}你是初始管理员,可以点「编辑」修改其他管理员的用户名、昵称和密码。{{else}}只有初始管理员(首个账号)可以修改其他管理员的资料。{{end}}</p>
|
|
<div class="table-wrap">
|
|
<table class="table tight table-users">
|
|
<thead><tr><th scope="col">用户名</th><th scope="col">显示名称</th><th scope="col">打手颜色</th><th scope="col">状态</th><th scope="col">创建时间</th><th scope="col">最近登录</th><th scope="col"><span class="visually-hidden">操作</span></th></tr></thead>
|
|
<tbody>
|
|
{{$me := .User}}
|
|
{{range .D.Users}}
|
|
<tr>
|
|
<td class="mono">{{.Username}}</td>
|
|
<td>{{.DisplayName}}</td>
|
|
<td>
|
|
<form method="post" action="/settings/users/{{.ID}}/color" class="color-form">
|
|
<input type="color" name="color" value="{{if .Color}}{{.Color}}{{else}}#8A8F98{{end}}" title="打手颜色" aria-label="打手颜色">
|
|
<button class="btn btn-soft btn-sm" type="submit">保存</button>
|
|
</form>
|
|
</td>
|
|
<td>{{if .IsActive}}<span class="chip chip-active">启用</span>{{else}}<span class="chip chip-closed">停用</span>{{end}}</td>
|
|
<td class="mono small">{{.CreatedAt}}</td>
|
|
<td class="mono small">{{if .LastLoginAt}}{{.LastLoginAt}}{{else}}—{{end}}</td>
|
|
<td class="actions-cell">
|
|
{{if eq .ID $me.ID}}
|
|
<span class="muted small">当前账户</span>
|
|
{{else}}
|
|
{{if eq $me.ID 1}}
|
|
<a class="btn btn-soft btn-sm" href="/settings/users/{{.ID}}/edit">编辑</a>
|
|
{{end}}
|
|
<form method="post" action="/settings/users/{{.ID}}/toggle">
|
|
<button class="btn btn-ghost btn-sm">{{if .IsActive}}停用{{else}}启用{{end}}</button>
|
|
</form>
|
|
{{end}}
|
|
</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<form method="post" action="/settings/users" class="inline-form">
|
|
<label class="inline-field">用户名 <input type="text" name="username" required minlength="3" maxlength="32" autocomplete="off"></label>
|
|
<label class="inline-field">显示名称 <input type="text" name="display_name" maxlength="32"></label>
|
|
<label class="inline-field">初始密码 <input type="password" name="password" required minlength="6" autocomplete="new-password"></label>
|
|
<button class="btn btn-primary" type="submit">新增管理员</button>
|
|
</form>
|
|
</section>
|
|
|
|
<section class="section card">
|
|
<h2>修改我的密码</h2>
|
|
<form method="post" action="/settings/password" class="form">
|
|
<div class="grid-3">
|
|
<label class="field"><span>原密码</span><input type="password" name="old_password" required autocomplete="current-password"></label>
|
|
<label class="field"><span>新密码(≥6 位)</span><input type="password" name="password" required minlength="6" autocomplete="new-password"></label>
|
|
<label class="field"><span>再输一次</span><input type="password" name="password2" required minlength="6" autocomplete="new-password"></label>
|
|
</div>
|
|
<div class="actions"><button class="btn btn-primary" type="submit">更新密码</button></div>
|
|
</form>
|
|
</section>
|
|
|
|
<section class="section card">
|
|
<h2>数据</h2>
|
|
<dl class="kv">
|
|
<div><dt>配置文件</dt><dd class="mono small">{{.D.ConfigPath}} <span class="muted">(修改后重启生效)</span></dd></div>
|
|
<div><dt>数据库</dt><dd class="mono small">{{.D.DBPath}}</dd></div>
|
|
<div><dt>备份</dt><dd class="mono small">{{.D.BackupDir}} · 保留 {{.D.BackupKeep}} 份 · {{if .D.BackupEnabled}}自动备份已开启{{else}}自动备份已关闭{{end}}</dd></div>
|
|
<div><dt>大屏</dt><dd class="mono small">/screen {{if .D.ScreenPublic}}免登录{{else}}需登录{{end}}</dd></div>
|
|
<div><dt>局域网地址</dt><dd class="mono small">http://{{if .D.Addrs}}{{index .D.Addrs 0}}{{else}}127.0.0.1{{end}}:{{.D.Port}}/screen</dd></div>
|
|
<div><dt>已运行</dt><dd class="mono">{{.D.Uptime}}</dd></div>
|
|
<div><dt>数据量</dt><dd>{{.D.CustomerCount}} 位客户 · {{.D.PackageCount}} 个套餐 · {{.D.LogCount}} 条日志</dd></div>
|
|
</dl>
|
|
<div class="actions wrap">
|
|
<form method="post" action="/settings/backup"><button class="btn btn-soft" type="submit">立即备份</button></form>
|
|
<a class="btn btn-soft" href="/export/customers.csv">导出客户 CSV</a>
|
|
<a class="btn btn-soft" href="/export/subscriptions.csv">导出订阅 CSV</a>
|
|
<a class="btn btn-soft" href="/export/logs.csv">导出日志 CSV</a>
|
|
</div>
|
|
{{if .D.Backups}}
|
|
<details class="backups">
|
|
<summary>最近备份({{len .D.Backups}} 份)</summary>
|
|
<ul class="mono small">
|
|
{{range .D.Backups}}<li>{{.}}</li>{{end}}
|
|
</ul>
|
|
</details>
|
|
{{end}}
|
|
</section>
|
|
</div>
|
|
{{end}}
|