Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fb6a84cb7e | ||
|
|
621adfa4a8 | ||
|
|
a83bfbb2b3 | ||
|
|
d955d0d7d2 |
@@ -1119,3 +1119,26 @@ fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
|
||||
background: var(--surface-2);
|
||||
}
|
||||
.subcard.is-closed:hover { opacity: 0.8; }
|
||||
|
||||
|
||||
/* ---------- v1.9 bootstrap 收敛 ---------- */
|
||||
.list-group-item { background: transparent; }
|
||||
.task.list-group-item { border-bottom: 1px dashed var(--line-2); }
|
||||
.task.list-group-item:last-child { border-bottom: 0; }
|
||||
.quick-form .form-control { max-width: 220px; }
|
||||
|
||||
|
||||
/* ---------- v1.9.1:自绘组件对齐 Bootstrap ---------- */
|
||||
.cal-grid, .cal-cell { border-color: var(--bs-border-color); }
|
||||
.cal-cell:hover { background: var(--bs-tertiary-bg); }
|
||||
.cal-cell.sel { box-shadow: inset 0 0 0 2px var(--bs-primary); }
|
||||
.cal-cell.today .dnum { background: var(--bs-success); color: #fff; }
|
||||
.cell-count b { color: var(--bs-success); }
|
||||
.cal-cell.heat-1 { background: rgba(var(--bs-success-rgb), 0.06); }
|
||||
.cal-cell.heat-2 { background: rgba(var(--bs-success-rgb), 0.11); }
|
||||
.cal-cell.heat-3 { background: rgba(var(--bs-success-rgb), 0.16); }
|
||||
.cal-cell.heat-4 { background: rgba(var(--bs-success-rgb), 0.22); }
|
||||
.keypad { gap: 8px; }
|
||||
.keypad .key { height: 50px; font-size: 18px; font-weight: 600; }
|
||||
.keypad .key-ok { color: #fff; }
|
||||
.season-band { opacity: 0.6; }
|
||||
|
||||
@@ -155,6 +155,7 @@
|
||||
btn.addEventListener('click', function () {
|
||||
var next = effective() === 'dark' ? 'light' : 'dark';
|
||||
document.documentElement.setAttribute('data-theme', next);
|
||||
document.documentElement.setAttribute('data-bs-theme', next);
|
||||
document.cookie = KEY + '=' + next + '; path=/; max-age=31536000; SameSite=Lax';
|
||||
});
|
||||
});
|
||||
|
||||
@@ -409,3 +409,12 @@ body::before {
|
||||
display: inline-block; width: 7px; height: 7px;
|
||||
border-radius: 1px; margin-right: 4px; vertical-align: 0;
|
||||
}
|
||||
|
||||
|
||||
/* ---------- v1.9.1:大屏对齐 Bootstrap ---------- */
|
||||
.heat-cell { border-color: var(--bs-border-color); }
|
||||
.heat-cell.h1 { background: rgba(var(--bs-success-rgb), 0.14); }
|
||||
.heat-cell.h2 { background: rgba(var(--bs-success-rgb), 0.26); }
|
||||
.heat-cell.h3 { background: rgba(var(--bs-success-rgb), 0.40); }
|
||||
.heat-cell.h4 { background: rgba(var(--bs-success-rgb), 0.58); }
|
||||
.scr-kpis .kpi { --bs-card-border-color: var(--bs-border-color); }
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,49 +1,54 @@
|
||||
{{define "layout"}}<!doctype html>
|
||||
<html lang="zh-CN"{{if .Theme}} data-theme="{{.Theme}}"{{end}}>
|
||||
<html lang="zh-CN" data-bs-theme="{{if eq .Theme "dark"}}dark{{else}}light{{end}}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{{.Title}} · 代打台</title>
|
||||
<link rel="icon" href="/static/favicon.svg" type="image/svg+xml">
|
||||
<link rel="stylesheet" href="/static/app.css?v={{.Version}}">
|
||||
<link rel="stylesheet" href="/static/vendor/bootstrap.min.css?v={{.Version}}">
|
||||
</head>
|
||||
<body>
|
||||
<body class="bg-body-tertiary">
|
||||
{{if .User}}
|
||||
<header class="topbar">
|
||||
<a class="brand" href="/calendar"><span class="brand-mark">代</span><span class="brand-name">代打台</span></a>
|
||||
<form class="search" action="/customers" method="get" role="search">
|
||||
<input type="search" name="q" value="{{.Query}}" placeholder="手机尾号 / 姓名 / 游戏名" aria-label="搜索客户" autocomplete="off" data-search>
|
||||
<kbd>/</kbd>
|
||||
</form>
|
||||
<nav class="nav">
|
||||
<a href="/calendar" class="{{if eq .Nav "calendar"}}on{{end}}">日历</a>
|
||||
<a href="/customers" class="{{if eq .Nav "customers"}}on{{end}}">客户</a>
|
||||
<a href="/subscriptions" class="{{if eq .Nav "subscriptions"}}on{{end}}">订阅</a>
|
||||
<a href="/packages" class="{{if eq .Nav "packages"}}on{{end}}">套餐</a>
|
||||
<a href="/screen" target="_blank" rel="noopener" class="nav-screen">大屏 ↗</a>
|
||||
</nav>
|
||||
<div class="topbar-right">
|
||||
<a class="pill pill-due" href="/subscriptions?state=due_today" title="今天到期的订阅">今日到期 <b>{{.DueToday}}</b></a>
|
||||
<a class="pill pill-warn" href="/subscriptions?state=due3" title="3 天内到期">3 天内 <b>{{.Due3}}</b></a>
|
||||
<a class="pill" href="/subscriptions?state=due7" title="7 天内到期">7 天内 <b>{{.Due7}}</b></a>
|
||||
<button class="theme-toggle" type="button" data-theme-toggle aria-label="切换亮色/暗色" title="切换亮色/暗色">
|
||||
<span class="ic-moon" aria-hidden="true">☾</span><span class="ic-sun" aria-hidden="true">☀</span>
|
||||
</button>
|
||||
<div class="me">
|
||||
<a href="/settings">{{if .User.DisplayName}}{{.User.DisplayName}}{{else}}{{.User.Username}}{{end}}</a>
|
||||
<form method="post" action="/logout"><button type="submit" class="link-btn">退出</button></form>
|
||||
<nav class="navbar navbar-expand-lg bg-body border-bottom sticky-top">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand fw-bold text-success" href="/calendar">代打台</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#mainNav"><span class="navbar-toggler-icon"></span></button>
|
||||
<div class="collapse navbar-collapse" id="mainNav">
|
||||
<ul class="navbar-nav me-auto">
|
||||
<li class="nav-item"><a class="nav-link{{if eq .Nav "calendar"}} active{{end}}" href="/calendar">日历</a></li>
|
||||
<li class="nav-item"><a class="nav-link{{if eq .Nav "customers"}} active{{end}}" href="/customers">客户</a></li>
|
||||
<li class="nav-item"><a class="nav-link{{if eq .Nav "subscriptions"}} active{{end}}" href="/subscriptions">订阅</a></li>
|
||||
<li class="nav-item"><a class="nav-link{{if eq .Nav "packages"}} active{{end}}" href="/packages">套餐</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/screen" target="_blank" rel="noopener">大屏 ↗</a></li>
|
||||
</ul>
|
||||
<form class="d-flex me-2" role="search" action="/customers" method="get">
|
||||
<input class="form-control form-control-sm" type="search" name="q" value="{{.Query}}" placeholder="手机尾号 / 姓名 / 游戏名" aria-label="搜索客户" data-search>
|
||||
</form>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<a class="badge text-bg-danger text-decoration-none" href="/subscriptions?state=due_today">今日到期 {{.DueToday}}</a>
|
||||
<a class="badge text-bg-warning text-decoration-none" href="/subscriptions?state=due3">3 天内 {{.Due3}}</a>
|
||||
<a class="badge text-bg-secondary text-decoration-none" href="/subscriptions?state=due7">7 天内 {{.Due7}}</a>
|
||||
<button class="btn btn-sm btn-outline-secondary" type="button" data-theme-toggle aria-label="切换亮色/暗色"><span class="ic-moon">☾</span><span class="ic-sun">☀</span></button>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-sm btn-outline-secondary dropdown-toggle" data-bs-toggle="dropdown">{{if .User.DisplayName}}{{.User.DisplayName}}{{else}}{{.User.Username}}{{end}}</button>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li><a class="dropdown-item" href="/settings">设置</a></li>
|
||||
<li><a class="dropdown-item" href="/logs">操作日志</a></li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li><form method="post" action="/logout"><button class="dropdown-item text-danger" type="submit">退出登录</button></form></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
{{else}}
|
||||
<button class="theme-toggle auth-theme" type="button" data-theme-toggle aria-label="切换亮色/暗色" title="切换亮色/暗色">
|
||||
<span class="ic-moon" aria-hidden="true">☾</span><span class="ic-sun" aria-hidden="true">☀</span>
|
||||
</button>
|
||||
</nav>
|
||||
{{end}}
|
||||
{{if .Flash}}<div class="flash" data-flash>{{.Flash}}</div>{{end}}
|
||||
{{if .Error}}<div class="flash flash-error">{{.Error}}</div>{{end}}
|
||||
<main{{if .User}} class="with-top"{{end}}>{{template "content" .}}</main>
|
||||
{{if .User}}<footer class="foot">代打台 v{{.Version}} · <a href="/logs">操作日志</a> · <a href="/settings">设置</a> · <a href="/screen" target="_blank" rel="noopener">大屏</a></footer>{{end}}
|
||||
{{if .Flash}}<div class="alert alert-success alert-dismissible fade show m-3" role="alert" data-flash>{{.Flash}}<button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>{{end}}
|
||||
{{if .Error}}<div class="alert alert-danger m-3" role="alert">{{.Error}}</div>{{end}}
|
||||
<main class="{{if .User}}container-fluid py-3{{end}}">{{template "content" .}}</main>
|
||||
{{if .User}}<footer class="container-fluid text-secondary small border-top py-3 mt-4">代打台 v{{.Version}} · <a href="/logs">操作日志</a> · <a href="/settings">设置</a> · <a href="/screen" target="_blank" rel="noopener">大屏</a></footer>{{end}}
|
||||
<script src="/static/vendor/bootstrap.bundle.min.js?v={{.Version}}" defer></script>
|
||||
<script src="/static/app.js?v={{.Version}}" defer></script>
|
||||
</body>
|
||||
</html>{{end}}
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
{{define "screenlayout"}}<!doctype html>
|
||||
<html lang="zh-CN"{{if .Theme}} data-theme="{{.Theme}}"{{end}}>
|
||||
<html lang="zh-CN" data-bs-theme="{{if eq .Theme "light"}}light{{else}}dark{{end}}"{{if .Theme}} data-theme="{{.Theme}}"{{end}}>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta http-equiv="refresh" content="{{.D.Refresh}}">
|
||||
<title>{{.Title}} · 代打台</title>
|
||||
<link rel="icon" href="/static/favicon.svg" type="image/svg+xml">
|
||||
<link rel="stylesheet" href="/static/vendor/bootstrap.min.css?v={{.D.Version}}">
|
||||
<link rel="stylesheet" href="/static/screen.css?v={{.D.Version}}">
|
||||
</head>
|
||||
<body class="screen-body">
|
||||
{{template "content" .}}
|
||||
<script src="/static/vendor/bootstrap.bundle.min.js?v={{.D.Version}}" defer></script>
|
||||
<script src="/static/screen.js?v={{.D.Version}}" defer></script>
|
||||
</body>
|
||||
</html>{{end}}
|
||||
|
||||
@@ -83,24 +83,24 @@
|
||||
<input type="hidden" name="pkg" value="{{.D.PkgID}}">
|
||||
<input type="hidden" name="tag" value="{{.D.Tag}}">
|
||||
<input type="hidden" name="back" value="{{.D.Back}}">
|
||||
<input type="text" name="tail" placeholder="输入手机尾号,回车即可完成" maxlength="8" autocomplete="off" inputmode="numeric" aria-label="手机尾号快速完成">
|
||||
<input class="form-control form-control-sm" type="text" name="tail" placeholder="输入手机尾号,回车即可完成" maxlength="8" autocomplete="off" inputmode="numeric" aria-label="手机尾号快速完成">
|
||||
<button class="btn btn-sm btn-primary" type="submit">完成</button>
|
||||
<button type="button" class="btn btn-sm btn-ghost keypad-toggle" data-keypad-toggle title="切换触控/PC 模式" aria-label="切换触控/PC 模式">⌨</button>
|
||||
</form>
|
||||
<p class="muted small quick-hint">唯一匹配直接完成;同尾号多人 / 一单多服务会列出让你勾选。</p>
|
||||
<div class="keypad" data-keypad role="group" aria-label="数字小键盘" hidden>
|
||||
<button type="button" class="key" data-key="1">1</button>
|
||||
<button type="button" class="key" data-key="2">2</button>
|
||||
<button type="button" class="key" data-key="3">3</button>
|
||||
<button type="button" class="key" data-key="4">4</button>
|
||||
<button type="button" class="key" data-key="5">5</button>
|
||||
<button type="button" class="key" data-key="6">6</button>
|
||||
<button type="button" class="key" data-key="7">7</button>
|
||||
<button type="button" class="key" data-key="8">8</button>
|
||||
<button type="button" class="key" data-key="9">9</button>
|
||||
<button type="button" class="key key-fn" data-key="back" aria-label="退格">⌫</button>
|
||||
<button type="button" class="key" data-key="0">0</button>
|
||||
<button type="button" class="key key-ok" data-key="ok" aria-label="确认完成">✓</button>
|
||||
<button type="button" class="key btn btn-outline-secondary" data-key="1">1</button>
|
||||
<button type="button" class="key btn btn-outline-secondary" data-key="2">2</button>
|
||||
<button type="button" class="key btn btn-outline-secondary" data-key="3">3</button>
|
||||
<button type="button" class="key btn btn-outline-secondary" data-key="4">4</button>
|
||||
<button type="button" class="key btn btn-outline-secondary" data-key="5">5</button>
|
||||
<button type="button" class="key btn btn-outline-secondary" data-key="6">6</button>
|
||||
<button type="button" class="key btn btn-outline-secondary" data-key="7">7</button>
|
||||
<button type="button" class="key btn btn-outline-secondary" data-key="8">8</button>
|
||||
<button type="button" class="key btn btn-outline-secondary" data-key="9">9</button>
|
||||
<button type="button" class="key key-fn btn btn-outline-secondary" data-key="back" aria-label="退格">⌫</button>
|
||||
<button type="button" class="key btn btn-outline-secondary" data-key="0">0</button>
|
||||
<button type="button" class="key key-ok btn btn-success" data-key="ok" aria-label="确认完成">✓</button>
|
||||
</div>
|
||||
|
||||
{{if .D.PickTail}}
|
||||
@@ -115,7 +115,7 @@
|
||||
<input type="hidden" name="back" value="{{.D.Back}}">
|
||||
<ul class="pick-list">
|
||||
{{range .D.PickRows}}
|
||||
<li>
|
||||
<li class="list-group-item px-0">
|
||||
<label>
|
||||
<input type="checkbox" name="sub_ids" value="{{.ID}}"{{if not .Done}}{{if not .Skipped}} checked{{end}}{{end}}>
|
||||
<span class="ticket" style="--tag:{{.PackageColor}}"><b>{{.CustomerTail}}</b>{{.CustomerName}}</span>
|
||||
@@ -139,16 +139,16 @@
|
||||
{{end}}
|
||||
|
||||
{{if .D.Tasks}}
|
||||
<ul class="task-list">
|
||||
<ul class="list-group list-group-flush task-list">
|
||||
{{range .D.Tasks}}
|
||||
{{if or .Done .Skipped}}
|
||||
<li class="task task-done" style="--asg:{{.AssigneeHex}}">
|
||||
<li class="list-group-item task task-done px-0" style="--asg:{{.AssigneeHex}}">
|
||||
<details class="done-fold">
|
||||
<summary>
|
||||
<span class="ticket" style="--tag:{{.PackageColor}}"><b>{{.CustomerTail}}</b>{{.CustomerName}}</span>
|
||||
<span class="pkg">{{.PackageName}}</span>
|
||||
<span class="chip {{if .Done}}chip-active{{else}}chip-paused{{end}}">{{if .Done}}已完成{{else}}已跳过{{end}}</span>
|
||||
{{if .Urgent}}<span class="tag-urgent">加急</span>{{end}}
|
||||
{{if .Urgent}}<span class="badge text-bg-danger tag-urgent">加急</span>{{end}}
|
||||
<span class="fold-caret" aria-hidden="true"></span>
|
||||
</summary>
|
||||
<div class="done-detail">
|
||||
@@ -181,7 +181,7 @@
|
||||
</details>
|
||||
</li>
|
||||
{{else}}
|
||||
<li class="task{{if .Urgent}} urgent{{end}}" style="--asg:{{.AssigneeHex}}">
|
||||
<li class="list-group-item task{{if .Urgent}} urgent{{end}} px-0" style="--asg:{{.AssigneeHex}}">
|
||||
<div class="task-main">
|
||||
<a class="task-title" href="/customers/{{.CustomerID}}">
|
||||
<span class="ticket" style="--tag:{{.PackageColor}}"><b>{{.CustomerTail}}</b>{{.CustomerName}}</span>
|
||||
@@ -234,7 +234,7 @@
|
||||
<section class="drawer-block">
|
||||
<h3>这天到期 <em>{{len .D.Due}}</em></h3>
|
||||
{{if .D.Due}}
|
||||
<ul class="due-list">
|
||||
<ul class="list-group list-group-flush due-list">
|
||||
{{range .D.Due}}
|
||||
<li>
|
||||
<a class="due-main" href="/customers/{{.CustomerID}}">
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
|
||||
{{if .D.Packages}}
|
||||
<form method="post" action="/customers/{{.D.Customer.ID}}/subscriptions" class="inline-form" data-sub-form>
|
||||
<select name="package_id" required data-pkg-select>
|
||||
<select class="form-select form-select-sm" name="package_id" required data-pkg-select>
|
||||
<option value="">选择套餐…</option>
|
||||
{{range .D.Packages}}
|
||||
<option value="{{.ID}}" data-unit="{{if .Season}}season{{else}}{{.Unit}}{{end}}" data-amount="{{.DefaultAmount}}" data-validity="{{.DefaultValidityDays}}"{{if .Archived}} disabled{{end}}{{if .SeasonExpired $.TodayStr}} disabled{{end}}>
|
||||
@@ -95,16 +95,16 @@
|
||||
{{end}}
|
||||
</select>
|
||||
<label class="inline-field" data-start-wrap>开始日
|
||||
<input type="date" name="start_date" value="{{.TodayStr}}" required>
|
||||
<input class="form-control form-control-sm" type="date" name="start_date" value="{{.TodayStr}}" required>
|
||||
</label>
|
||||
<label class="inline-field" data-days-wrap>{{/* 默认显示 */}}
|
||||
天数 <input type="number" name="days" min="1" max="3650" value="30">
|
||||
天数 <input class="form-control form-control-sm" type="number" name="days" min="1" max="3650" value="30">
|
||||
</label>
|
||||
<label class="inline-field" data-count-wrap hidden>
|
||||
次数 <input type="number" name="total_count" min="1" max="10000" value="10">
|
||||
次数 <input class="form-control form-control-sm" type="number" name="total_count" min="1" max="10000" value="10">
|
||||
</label>
|
||||
<label class="inline-field" data-end-wrap>
|
||||
终止日(可留空)<input type="date" name="end_date">
|
||||
终止日(可留空)<input class="form-control form-control-sm" type="date" name="end_date">
|
||||
</label>
|
||||
<button class="btn btn-primary" type="submit">开通订阅</button>
|
||||
</form>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</header>
|
||||
|
||||
<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>
|
||||
{{if .D.Q}}<a class="btn btn-ghost" href="/customers">清除</a>{{end}}
|
||||
</form>
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
{{define "content"}}
|
||||
<div class="auth">
|
||||
<div class="auth-card">
|
||||
<div class="auth-brand"><span class="brand-mark">代</span><span>代打台</span></div>
|
||||
<h1>登录</h1>
|
||||
<p class="muted">所有账户均为管理员,任何操作都会留痕。</p>
|
||||
<form method="post" action="/login" class="form">
|
||||
<input type="hidden" name="next" value="{{.Next}}">
|
||||
<label class="field"><span>用户名</span>
|
||||
<input type="text" name="username" required autofocus autocomplete="username">
|
||||
</label>
|
||||
<label class="field"><span>密码</span>
|
||||
<input type="password" name="password" required autocomplete="current-password">
|
||||
</label>
|
||||
<button type="submit" class="btn btn-primary btn-block">登录</button>
|
||||
</form>
|
||||
<p class="auth-foot muted">代打台 · 单文件部署 · 数据只在本机</p>
|
||||
<div class="d-flex align-items-center justify-content-center" style="min-height:100vh">
|
||||
<div class="card shadow-sm" style="width:100%;max-width:400px">
|
||||
<div class="card-body p-4">
|
||||
<div class="d-flex align-items-center gap-2 mb-3">
|
||||
<span class="badge text-bg-success fs-6">代</span><span class="fw-bold">代打台</span>
|
||||
</div>
|
||||
<h1 class="h4 mb-1">登录</h1>
|
||||
<p class="text-secondary small mb-4">所有账户均为管理员,任何操作都会留痕。</p>
|
||||
<form method="post" action="/login" class="vstack gap-3">
|
||||
<input type="hidden" name="next" value="{{.Next}}">
|
||||
<div>
|
||||
<label class="form-label" for="username">用户名</label>
|
||||
<input class="form-control" id="username" type="text" name="username" required autofocus autocomplete="username">
|
||||
</div>
|
||||
<div>
|
||||
<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>
|
||||
{{end}}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{{define "content"}}
|
||||
<div class="scr" data-pkg="{{.D.PkgID}}" data-heat="{{.D.HeatMode}}" data-api="/api/screen/day">
|
||||
<header class="scr-head">
|
||||
<div class="scr-brand"><span class="mark">代</span>代打台<em>控制台</em></div>
|
||||
<header class="scr-head navbar bg-body-tertiary border-bottom px-3 py-2">
|
||||
<div class="scr-brand navbar-brand mb-0"><span class="mark">代</span>代打台<em>控制台</em></div>
|
||||
|
||||
{{if .D.HasTabs}}
|
||||
<nav class="scr-tabs">
|
||||
@@ -26,23 +26,23 @@
|
||||
</header>
|
||||
|
||||
<section class="scr-kpis">
|
||||
<div class="kpi">
|
||||
<div class="kpi card bg-body-tertiary border-secondary-subtle">
|
||||
<span>客户</span><b>{{.D.Stats.Customers}}</b><i>位</i>
|
||||
</div>
|
||||
<div class="kpi">
|
||||
<span>活跃订阅</span><b>{{.D.Stats.ActiveSubs}}</b><i>条</i>
|
||||
</div>
|
||||
<div class="kpi kpi-hot">
|
||||
<div class="kpi kpi-hot card bg-body-tertiary border-secondary-subtle">
|
||||
<span>今日到期</span><b>{{.D.Stats.DueToday}}</b><i>条</i>
|
||||
</div>
|
||||
<div class="kpi kpi-warm">
|
||||
<div class="kpi kpi-warm card bg-body-tertiary border-secondary-subtle">
|
||||
<span>7 天内到期</span><b>{{.D.Stats.Due7}}</b><i>条</i>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="scr-main">
|
||||
<div class="panel panel-cal">
|
||||
<div class="panel-head">
|
||||
<div class="panel panel-cal card bg-body-tertiary border-secondary-subtle">
|
||||
<div class="panel-head card-header bg-transparent border-secondary-subtle py-2">
|
||||
<h2>{{if eq .D.HeatMode "due"}}到期热力{{else}}每日待完成{{end}}</h2>
|
||||
<span>{{.D.MonthTitle}} · 本月合计 {{.D.HeatTotal}} 单</span>
|
||||
</div>
|
||||
@@ -69,10 +69,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-top">
|
||||
<div class="panel panel-top card bg-body-tertiary border-secondary-subtle">
|
||||
<div class="panel-head"><h2>即将到期 TOP 10</h2><span>按剩余量排序</span></div>
|
||||
{{if .D.Top}}
|
||||
<ol class="top-list">
|
||||
<ol class="top-list list-group list-group-flush">
|
||||
{{range $i, $s := .D.Top}}
|
||||
<li class="top-item lv-{{$s.Eval.Level}}">
|
||||
<span class="rank">{{add $i 1}}</span>
|
||||
@@ -97,7 +97,7 @@
|
||||
<span>{{len .D.DueToday}} 条</span>
|
||||
</div>
|
||||
{{if .D.DueToday}}
|
||||
<ul class="today-list">
|
||||
<ul class="today-list list-group list-group-flush">
|
||||
{{range .D.DueToday}}
|
||||
<li class="lv-{{.Eval.Level}}">
|
||||
<span class="tchip" style="--tag:{{.PackageColor}}"><b>{{.CustomerTail}}</b>{{.CustomerName}}</span>
|
||||
@@ -123,7 +123,7 @@
|
||||
<span class="tchip" style="--tag:{{.PackageColor}}"><b>{{.CustomerTail}}</b>{{.CustomerName}}</span>
|
||||
<span class="pkg">{{.PackageName}}</span>
|
||||
<span class="asg{{if .AssigneeNone}} none{{end}}"><i style="background:{{.AssigneeHex}}"></i>{{.AssigneeLabel}}</span>
|
||||
{{if .Urgent}}<span class="tag-urgent">加急</span>{{end}}
|
||||
{{if .Urgent}}<span class="badge text-bg-danger tag-urgent">加急</span>{{end}}
|
||||
<span class="rem">{{.RemainShort}}</span>
|
||||
</li>
|
||||
{{end}}
|
||||
|
||||
@@ -1,25 +1,33 @@
|
||||
{{define "content"}}
|
||||
<div class="auth">
|
||||
<div class="auth-card">
|
||||
<div class="auth-brand"><span class="brand-mark">代</span><span>代打台</span></div>
|
||||
<h1>创建第一个管理员</h1>
|
||||
<p class="muted">数据库里还没有账户。设置好账号后即可开始录入套餐与客户。</p>
|
||||
<form method="post" action="/setup" class="form">
|
||||
<label class="field"><span>用户名</span>
|
||||
<input type="text" name="username" required minlength="3" maxlength="32" autocomplete="username" placeholder="建议用拼音或英文名">
|
||||
</label>
|
||||
<label class="field"><span>显示名称</span>
|
||||
<input type="text" name="display_name" maxlength="32" placeholder="例如:老王(可留空)">
|
||||
</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>
|
||||
<button type="submit" class="btn btn-primary btn-block">创建并登录</button>
|
||||
</form>
|
||||
<p class="auth-foot muted">忘记密码只能手动改数据库,请妥善保管。</p>
|
||||
<div class="d-flex align-items-center justify-content-center" style="min-height:100vh">
|
||||
<div class="card shadow-sm" style="width:100%;max-width:440px">
|
||||
<div class="card-body p-4">
|
||||
<div class="d-flex align-items-center gap-2 mb-3">
|
||||
<span class="badge text-bg-success fs-6">代</span><span class="fw-bold">代打台</span>
|
||||
</div>
|
||||
<h1 class="h4 mb-1">创建第一个管理员</h1>
|
||||
<p class="text-secondary small mb-4">数据库里还没有账户。设置好账号后即可开始录入套餐与客户。</p>
|
||||
<form method="post" action="/setup" class="vstack gap-3">
|
||||
<div>
|
||||
<label class="form-label" for="username">用户名</label>
|
||||
<input class="form-control" id="username" type="text" name="username" required minlength="3" maxlength="32" autocomplete="username" placeholder="建议用拼音或英文名">
|
||||
</div>
|
||||
<div>
|
||||
<label class="form-label" for="display_name">显示名称</label>
|
||||
<input class="form-control" id="display_name" type="text" name="display_name" maxlength="32" placeholder="例如:老王(可留空)">
|
||||
</div>
|
||||
<div>
|
||||
<label class="form-label" for="password">密码(至少 6 位)</label>
|
||||
<input class="form-control" id="password" type="password" name="password" required minlength="6" autocomplete="new-password">
|
||||
</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>
|
||||
{{end}}
|
||||
|
||||
Reference in New Issue
Block a user