feat(v1.9.0): Bootstrap 5 迁移第 2/4 轮(登录/初始化页 + 基础组件)

本轮全部为前端改动,版本号保持 1.9.0:
- CSS 加载顺序调整为 app.css → bootstrap,让 Bootstrap 覆盖表格/按钮/表单/卡片等基础组件,日历/热屏等自定义组件类不受影响
- 主题切换同时写 data-theme 与 data-bs-theme,Bootstrap 组件跟随亮/暗
- 登录页、初始化页重写为 Bootstrap card + form-control + btn-primary,垂直居中
- 客户列表搜索框加 form-control

验证:
- 无头 Chrome 实拍登录、客户列表、套餐、设置四页(shots/bs2-*.png)
- 数据库与业务逻辑零改动

后续:第 3 轮日历抽屉/追加面板/客户月历,第 4 轮大屏内部与收尾
This commit is contained in:
subtrack
2026-10-19 22:15:39 +08:00
parent d955d0d7d2
commit a83bfbb2b3
5 changed files with 54 additions and 39 deletions
+1
View File
@@ -155,6 +155,7 @@
btn.addEventListener('click', function () { btn.addEventListener('click', function () {
var next = effective() === 'dark' ? 'light' : 'dark'; var next = effective() === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', next); document.documentElement.setAttribute('data-theme', next);
document.documentElement.setAttribute('data-bs-theme', next);
document.cookie = KEY + '=' + next + '; path=/; max-age=31536000; SameSite=Lax'; document.cookie = KEY + '=' + next + '; path=/; max-age=31536000; SameSite=Lax';
}); });
}); });
+1 -1
View File
@@ -5,8 +5,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{.Title}} · 代打台</title> <title>{{.Title}} · 代打台</title>
<link rel="icon" href="/static/favicon.svg" type="image/svg+xml"> <link rel="icon" href="/static/favicon.svg" type="image/svg+xml">
<link rel="stylesheet" href="/static/vendor/bootstrap.min.css?v={{.Version}}">
<link rel="stylesheet" href="/static/app.css?v={{.Version}}"> <link rel="stylesheet" href="/static/app.css?v={{.Version}}">
<link rel="stylesheet" href="/static/vendor/bootstrap.min.css?v={{.Version}}">
</head> </head>
<body class="bg-body-tertiary"> <body class="bg-body-tertiary">
{{if .User}} {{if .User}}
+1 -1
View File
@@ -16,7 +16,7 @@
</header> </header>
<form class="filterbar" method="get" action="/customers"> <form class="filterbar" method="get" action="/customers">
<input type="search" name="q" value="{{.D.Q}}" placeholder="手机尾号 / 姓名 / 游戏名 / 联系方式" autocomplete="off"> <input class="form-control" type="search" name="q" value="{{.D.Q}}" placeholder="手机尾号 / 姓名 / 游戏名 / 联系方式" autocomplete="off">
<button class="btn" type="submit">搜索</button> <button class="btn" type="submit">搜索</button>
{{if .D.Q}}<a class="btn btn-ghost" href="/customers">清除</a>{{end}} {{if .D.Q}}<a class="btn btn-ghost" href="/customers">清除</a>{{end}}
</form> </form>
+22 -16
View File
@@ -1,20 +1,26 @@
{{define "content"}} {{define "content"}}
<div class="auth"> <div class="d-flex align-items-center justify-content-center" style="min-height:100vh">
<div class="auth-card"> <div class="card shadow-sm" style="width:100%;max-width:400px">
<div class="auth-brand"><span class="brand-mark">代</span><span>代打台</span></div> <div class="card-body p-4">
<h1>登录</h1> <div class="d-flex align-items-center gap-2 mb-3">
<p class="muted">所有账户均为管理员,任何操作都会留痕。</p> <span class="badge text-bg-success fs-6">代</span><span class="fw-bold">代打台</span>
<form method="post" action="/login" class="form"> </div>
<input type="hidden" name="next" value="{{.Next}}"> <h1 class="h4 mb-1">登录</h1>
<label class="field"><span>用户名</span> <p class="text-secondary small mb-4">所有账户均为管理员,任何操作都会留痕。</p>
<input type="text" name="username" required autofocus autocomplete="username"> <form method="post" action="/login" class="vstack gap-3">
</label> <input type="hidden" name="next" value="{{.Next}}">
<label class="field"><span>密码</span> <div>
<input type="password" name="password" required autocomplete="current-password"> <label class="form-label" for="username">用户名</label>
</label> <input class="form-control" id="username" type="text" name="username" required autofocus autocomplete="username">
<button type="submit" class="btn btn-primary btn-block">登录</button> </div>
</form> <div>
<p class="auth-foot muted">代打台 · 单文件部署 · 数据只在本机</p> <label class="form-label" for="password">密码</label>
<input class="form-control" id="password" type="password" name="password" required autocomplete="current-password">
</div>
<button type="submit" class="btn btn-primary w-100">登录</button>
</form>
<p class="text-secondary small text-center mt-3 mb-0">代打台 · 单文件部署 · 数据只在本机</p>
</div>
</div> </div>
</div> </div>
{{end}} {{end}}
+29 -21
View File
@@ -1,25 +1,33 @@
{{define "content"}} {{define "content"}}
<div class="auth"> <div class="d-flex align-items-center justify-content-center" style="min-height:100vh">
<div class="auth-card"> <div class="card shadow-sm" style="width:100%;max-width:440px">
<div class="auth-brand"><span class="brand-mark">代</span><span>代打台</span></div> <div class="card-body p-4">
<h1>创建第一个管理员</h1> <div class="d-flex align-items-center gap-2 mb-3">
<p class="muted">数据库里还没有账户。设置好账号后即可开始录入套餐与客户。</p> <span class="badge text-bg-success fs-6">代</span><span class="fw-bold">代打台</span>
<form method="post" action="/setup" class="form"> </div>
<label class="field"><span>用户名</span> <h1 class="h4 mb-1">创建第一个管理员</h1>
<input type="text" name="username" required minlength="3" maxlength="32" autocomplete="username" placeholder="建议用拼音或英文名"> <p class="text-secondary small mb-4">数据库里还没有账户。设置好账号后即可开始录入套餐与客户。</p>
</label> <form method="post" action="/setup" class="vstack gap-3">
<label class="field"><span>显示名称</span> <div>
<input type="text" name="display_name" maxlength="32" placeholder="例如:老王(可留空)"> <label class="form-label" for="username">用户名</label>
</label> <input class="form-control" id="username" type="text" name="username" required minlength="3" maxlength="32" autocomplete="username" placeholder="建议用拼音或英文名">
<label class="field"><span>密码(至少 6 位)</span> </div>
<input type="password" name="password" required minlength="6" autocomplete="new-password"> <div>
</label> <label class="form-label" for="display_name">显示名称</label>
<label class="field"><span>再输一次密码</span> <input class="form-control" id="display_name" type="text" name="display_name" maxlength="32" placeholder="例如:老王(可留空)">
<input type="password" name="password2" required minlength="6" autocomplete="new-password"> </div>
</label> <div>
<button type="submit" class="btn btn-primary btn-block">创建并登录</button> <label class="form-label" for="password">密码(至少 6 位)</label>
</form> <input class="form-control" id="password" type="password" name="password" required minlength="6" autocomplete="new-password">
<p class="auth-foot muted">忘记密码只能手动改数据库,请妥善保管。</p> </div>
<div>
<label class="form-label" for="password2">再输一次密码</label>
<input class="form-control" id="password2" type="password" name="password2" required minlength="6" autocomplete="new-password">
</div>
<button type="submit" class="btn btn-primary w-100">创建并登录</button>
</form>
<p class="text-secondary small text-center mt-3 mb-0">忘记密码只能手动改数据库,请妥善保管。</p>
</div>
</div> </div>
</div> </div>
{{end}} {{end}}