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 三档,明暗两套,工作台/ 客户/套餐/订阅/设置/日志/大屏/登录全部截图走查,无横向溢出与控制台错误。
316 lines
20 KiB
Markdown
316 lines
20 KiB
Markdown
# 代打台 · 代打管理平台
|
||
|
||
一个给代打工作室用的单文件管理程序:**套餐 → 订阅 → 追加时长 → 日历打卡 → 大屏**。
|
||
整个程序就是一个 `daili.exe` + 一个 `daili.ini`,数据存在同目录的 `daili.db` 里,局域网内手机、电视都能打开。界面支持亮色 / 暗色切换,默认跟随系统。
|
||
|
||
---
|
||
|
||
## 1. 快速开始
|
||
|
||
1. 把 `daili.exe` 放进任意文件夹(建议路径不含空格,例如 `D:\代打台\`);
|
||
2. 双击 `daili.exe`:
|
||
- 首次运行会自动生成配置文件 `daili.ini`;
|
||
- 弹出一个黑色窗口,打印访问地址(默认 **17777** 端口);
|
||
- 默认会自动打开浏览器;
|
||
3. 浏览器打开 `http://127.0.0.1:17777` → 第一次会让你**创建管理员账号**;
|
||
4. 之后按「套餐 → 客户 → 订阅」的顺序录入即可。
|
||
|
||
```
|
||
┌───────────────────────────────────────────────┐
|
||
│ 代 打 台 · 代打管理平台 │
|
||
└───────────────────────────────────────────────┘
|
||
版本 1.10.0 配置文件 daili.ini
|
||
数据库 D:\代打台\daili.db
|
||
访问地址:
|
||
本机 http://127.0.0.1:17777
|
||
局域网 http://192.168.1.23:17777
|
||
大屏 http://127.0.0.1:17777/screen(免登录)
|
||
注意:大屏免登录且监听所有网卡,同局域网内任何人都能打开 /screen
|
||
按 Ctrl+C 停止服务
|
||
```
|
||
|
||
> 关掉黑窗口 = 停止服务。数据已经落盘,下次打开继续用。
|
||
|
||
---
|
||
|
||
## 2. 配置文件 daili.ini
|
||
|
||
配置文件固定放在 **exe 同级目录**,首次运行自动生成(带中文注释),改完**重启生效**。
|
||
写法:`key = value`,`#` 或 `;` 开头的整行是注释,不支持分节;**相对路径相对于 exe 所在目录**。
|
||
|
||
| 配置项 | 默认值 | 说明 |
|
||
| --- | --- | --- |
|
||
| `listen_ip` | `0.0.0.0` | 监听 IP。`0.0.0.0` = 所有网卡(局域网可访问);`127.0.0.1` = 只允许本机 |
|
||
| `listen_port` | `17777` | 监听端口(1–65535) |
|
||
| `database_path` | `daili.db` | SQLite 数据库文件(单文件,含全部数据) |
|
||
| `backup_enabled` | `true` | 是否每日自动备份 |
|
||
| `backup_dir` | `backup` | 备份目录(留空则用 exe 同级 `backup/`) |
|
||
| `backup_keep` | `14` | 备份保留份数(1–365),超出自动清理 |
|
||
| `timezone` | 空 | 留空跟随系统;可固定 `Asia/Shanghai`。**影响所有“自然日”计算** |
|
||
| `open_browser` | `true` | 启动后自动打开浏览器 |
|
||
| `screen_public` | `true` | 大屏 `/screen` 免登录(投屏用);改 `false` 则需登录 |
|
||
| `log_enabled` | `true` | 运行日志写文件(控制台始终输出) |
|
||
| `log_dir` | `logs` | 日志目录,按天切分 `daili-YYYY-MM-DD.log` |
|
||
|
||
**行为约定**
|
||
|
||
- 文件不存在 → 自动生成默认配置,照常启动;
|
||
- 文件写错 → **报错退出并指出行号**,原文件不会被修改。例如:
|
||
|
||
```
|
||
[代打台] 配置文件有问题,已停止启动:
|
||
|
||
第 3 行: listen_port 必须在 1-65535 之间,当前是 99999
|
||
修好后重新启动即可(原文件未被修改)
|
||
```
|
||
|
||
- 未知配置项、重复配置项、布尔值写成 `maybe`、时区写错,都会带行号报错;
|
||
- 端口被占用不会自动换端口,而是明确报错并提示改 `listen_port`。
|
||
|
||
### 命令行参数(临时覆盖配置,优先级更高)
|
||
|
||
| 参数 | 说明 |
|
||
| --- | --- |
|
||
| `-config <路径>` | 指定别的配置文件(默认 exe 同级 `daili.ini`) |
|
||
| `-addr <ip:端口>` | 临时覆盖监听地址,如 `-addr 127.0.0.1:19000` |
|
||
| `-db <路径>` | 临时覆盖数据库路径 |
|
||
| `-backup-keep <n>` | 临时覆盖备份保留份数 |
|
||
| `-no-backup` | 本次运行关闭自动备份 |
|
||
| `-no-open` | 本次运行不自动打开浏览器 |
|
||
|
||
示例:`daili.exe -addr 127.0.0.1:19000 -no-open`
|
||
|
||
> 业务参数(到期预警天数、大屏刷新秒数)不在配置文件里,仍在网页「设置」中修改。
|
||
|
||
---
|
||
|
||
## 3. 第一次使用(5 分钟走完)
|
||
|
||
1. **建套餐**:`套餐 → 新增套餐`
|
||
- 「包月日常」按日 30 天,色签绿;
|
||
- 「深渊十次」按次 10 次,色签紫。
|
||
> 以后要加套餐 D/E/F,直接再加一行就行,**不会影响任何已有客户数据**。
|
||
2. **建客户**:`客户 → 新建客户`,填手机尾号 + 客户名(这两项组合唯一)。
|
||
3. **开通订阅**:进客户详情 → 选套餐、开始日、天数(按次则填次数)→ 开通订阅。
|
||
4. **日常使用**:打开「日历」,今天那格里就是这个客户今天要打的单,点「完成」打卡。
|
||
5. **续费**:客户转账后,点订阅上的「追加时长」→ 在日历上点新的终止日期 → 确认。
|
||
面板会实时显示「计算起点 / 原结束日 / 新结束日 / 本次追加几天 / 追加后剩余几天」,并在客户页留下追加记录。
|
||
|
||
> 想先看效果再录自己的数据?程序启动后运行 `powershell -ExecutionPolicy Bypass -File scripts\seed.ps1`,会写入 8 个演示客户和 4 个套餐(默认账号 `admin` / `daili123`)。
|
||
|
||
---
|
||
|
||
## 4. 业务规则(和 PRD 一致)
|
||
|
||
**剩余时长**
|
||
- 按日:`剩余天数 = 结束日 − 今天 + 1`,结束日当天仍算服务日;
|
||
- 按次:`剩余次数 = 总次数 − 已用次数`;按次套餐的「有效期」可留空,留空就一直有效直到次数用完。
|
||
|
||
**追加时长(核心)**
|
||
- 打开追加面板,**在月历上点选新的终止日期**,系统自动反算;
|
||
- 未到期的订阅:从原结束日的**次日**起算,追加天数 = 新结束日 − 原结束日;
|
||
- 已到期的订阅:**从今天起算**(不会把中间空档的天数白送给客户);
|
||
- 追加记录保留:计算起点、旧结束日、新结束日、天数、备注、操作人、时间。
|
||
|
||
**暂停 / 恢复**
|
||
- 暂停期间冻结剩余时长,日历上不出现待打任务;
|
||
- 恢复时按日套餐的结束日**自动顺延**暂停的自然日天数,时间轴上是灰色斜纹段。
|
||
|
||
**打卡**
|
||
- 按日套餐:每天一条「完成 / 跳过」,只做记录不扣天数(天数按自然日流逝);
|
||
- 按次套餐:打卡「完成」自动扣 1 次,撤销打卡返还 1 次;次数为 0 时不允许再打;
|
||
- 按次套餐如果没设有效期,它不会出现在日历里 —— 直接在客户详情点订阅卡片上的「今日打卡」扣次。
|
||
|
||
**预警**
|
||
- 剩余 ≤3 天橙色、今天到期红色、已过期灰色;顶栏常驻「今日到期 / 3 天内」两个数字。
|
||
|
||
**查询**
|
||
- 顶栏搜索框输入手机尾号即可定位客户(也支持姓名、游戏名、联系方式),按 `/` 快速聚焦。
|
||
|
||
---
|
||
|
||
## 4.1 工作台速用
|
||
|
||
- **按尾号快速完成**:日历右侧「当日待完成」顶部输入手机尾号 → 回车。
|
||
- 只匹配到 1 项:直接完成并提示;
|
||
- 同一尾号有多个客户,或一个客户今天有多个服务:弹出勾选面板,默认全选,可多选后一次完成。
|
||
- **加急**:每条任务右侧点「加急」,会加红色 `加急` 标签并排到最前;日历格子出现红点,大屏「今日待打」同步置顶。再点一次取消。
|
||
- **按套餐分日历**:套餐编辑页勾选「在日历中独立显示」后,工作台与大屏顶部会出现套餐标签(全部 / 每日任务 / …),可以只看某类委托的排单。
|
||
- **触摸小键盘**:日历右侧输入框下面有 3 列 4 行数字键盘,底行是 ⌫ / 0 / ✓,点 ✓ 直接提交;按键为自定义样式,不是浏览器原生按钮,触摸目标 52px 高;
|
||
- **日历格子**:不再显示排单缩略信息,只保留左侧打手色竖条 + 大字「待完成 / 总数」(如 1/2 = 还剩 1 单,共 2 单);
|
||
- **按钮收纳**:任务行只露出「完成」,跳过 / 加急 / 追加收进「⋯」菜单,点空白处自动收起;
|
||
- **停用客户**:客户详情页可「停用」(默认从列表、日历、大屏隐藏,订阅保留)或「彻底删除」(连订阅/打卡/追加记录一起删,需二次确认);列表右上角可切换到「显示已停用」再恢复;
|
||
- **7 天内到期**:顶栏新增徽标,固定统计未来 7 天内到期的订阅;
|
||
- **抽屉时钟**:右侧当日面板顶部有时钟,30px 大写、水平垂直居中,24 小时制精确到秒,下面一行是当天日期;
|
||
- **触控 / PC 模式**:尾号输入框右侧有「⌨ / 触控」开关。切到触控时展开 3×4 小键盘、输入框变只读并关闭系统输入法(`inputmode=none`),点键直接写值;切回 PC 收起键盘。选择记在浏览器里。
|
||
- **格子计数**:工作台和大屏的日历格都显示「已完成 / 总数」,例如 2/5 = 5 单里做完 2 单。
|
||
- **已完成折叠**:当日清单里已完成/已跳过的单子自动折叠成一行(尾号 + 姓名 + 套餐 + 状态),点这一行展开看剩余、打手,以及撤销/加急/追加;未完成的行不受影响;
|
||
- **打手颜色**:`设置 → 管理员` 里给每个管理员选一个颜色。客户详情或编辑页可以把客户指派给某个打手,之后这个客户的所有单子都用该颜色标识:
|
||
- 日历格左侧竖条 = 当天涉及的所有打手颜色(几种人几条,等分显示);
|
||
- 「当日待完成」每条前面有打手色条 + 名字,未指派的显示灰色「未指派」;
|
||
- 大屏的今日待打、悬停浮层、热力格竖条同样带颜色。
|
||
- **主题**:顶栏右上角 ☾ / ☀ 切换亮 / 暗,偏好记在浏览器里;没选过时由页面在首屏按系统偏好自动决定。整套界面只认 `<html data-bs-theme>` 一个开关,不会出现「半亮半暗」。
|
||
- **升级不缓存旧界面**:CSS/JS 链接带**内容指纹**(`app.css?v=<12 位哈希>`)。资源可以长缓存(一年、immutable),但样式或脚本一改、重新编译,URL 就会变,浏览器自动取新文件,不用手动清缓存;HTML 仍然 `no-store`。
|
||
|
||
---
|
||
|
||
## 4.3 包赛季与按次有效期
|
||
|
||
- **包赛季**:套餐计费方式新增第三种「包赛季」,套餐上直接填赛季开始日/结束日。客户开通后,日历上用一条横向色带标出整段赛季;赛季内任意一天点「完成」即整段完成,完成后不再出现在日历与待打,客户详情显示「赛季已完成 + 日期」。
|
||
- **赛季过期不可选**:今天已过赛季结束日的套餐,在客户开通下拉里会置灰并标「赛季已结束」,服务端也会拒绝开通。
|
||
- **按次默认有效期**:按次套餐可设「默认有效期(天)」,开单时自动算出到期日(开始日 + 天数 − 1),仍可手动改。
|
||
- **删除订阅**:已结束的订阅卡片上,在「重新启用」旁新增「删除」,二次确认后彻底删除该订阅及其打卡/追加记录。
|
||
|
||
---
|
||
|
||
## 4.2 套餐标签与批量开通
|
||
|
||
- **套餐标签**:套餐编辑页可以填一个标签(如「包月」)。日历/大屏顶部页签会**按标签合并**:同标签的套餐合成一个页签;勾了「在日历中独立显示」的套餐**额外**再开一个自己的页签。
|
||
- **批量开通**:`套餐 → 详情/批量`,勾选客户(表头有全选,已订阅该套餐的客户置灰),填开始日期与天数/次数后一次开通;重复的会自动跳过并提示。
|
||
- **客户月历**:客户详情页新增「当月排单」,显示该客户当月每天几单、完成几单,可翻月,点某天直接跳到日历那天。
|
||
- **按次到期**:按次订阅的「到期日」仍是选填;填了到期后状态显示「已到期」、不再进日历待排。
|
||
|
||
---
|
||
|
||
## 5. 数据、备份与导出
|
||
|
||
| 文件 | 说明 |
|
||
| --- | --- |
|
||
| `daili.db` | **全部数据都在这一个文件里**(SQLite,单文件回滚日志模式,运行中也不会产生 `-wal`/`-shm`) |
|
||
| `backup/daili-YYYYMMDD-HHMMSS.db` | 每天首次启动时自动备份一份,保留份数见 `backup_keep` |
|
||
| `logs/daili-YYYY-MM-DD.log` | 运行日志,按天切分 |
|
||
|
||
### 迁移与重置(只说一次,很重要)
|
||
|
||
- **迁移**:关闭程序 → 把 `daili.db` 复制到新电脑的新目录 → 放入 `daili.exe` 双击即可,账号、套餐、客户、订阅、追加记录、打卡、日志全部原样保留。
|
||
- **重置**:关闭程序 → 删除 `daili.db` → 重新打开,会回到「创建第一个管理员」的全新状态。
|
||
- 包赛季是 `packages.season/season_start/season_end` 与 `subscriptions.season/season_done`;套餐标签是 `packages.tag`;客户停用是 `customers.archived`(0/1);打手颜色存在 `users.color`,客户归属打手是 `customers.assignee_id`;加急标记存在 `daili.db` 的 `task_flags` 表;套餐的「独立日历」是 `packages.calendar_separate` 列,老版本数据库打开时会**自动加列**,不用手工迁移;
|
||
- `daili.ini`(监听/备份/日志配置)与 `backup/`、`logs/` 都是**独立于数据**的,迁移时可以不拷,程序会按默认值重新生成。
|
||
|
||
- 手动备份:`设置 → 立即备份`(同样遵守保留份数),备份文件本身也是可直接打开的单文件库;
|
||
- 导出:`设置 → 导出客户 / 订阅 / 日志 CSV`,UTF-8 BOM,Excel 直接打开不乱码。
|
||
|
||
---
|
||
|
||
## 6. 大屏
|
||
|
||
- 地址:`http://<本机IP>:17777/screen`
|
||
- 默认 `screen_public = true`:**免登录**,电视/副屏直接打开即可(仅建议局域网使用);
|
||
- 改成 `screen_public = false` 后大屏回到登录保护;
|
||
- 「记分板」风格,亮 / 暗主题同样可切(右上角 ☾ / ☀):
|
||
- 顶部 KPI:客户 / 活跃订阅 / 今日到期 / 7 天内到期;
|
||
- 中部:**热力月历 + 即将到期 TOP10**。热力默认统计「每日待完成单量」,点右上角按钮可切回「到期热力」;鼠标悬停任意格子会浮出当日待办明细(含加急标记);
|
||
- 底部:**今日到期**(左)+ **今日待打**(右,加急置顶带红 tag);
|
||
- 最下方细条:最近追加流水;
|
||
- 套餐勾选「在日历中独立显示」后,大屏顶部会出现套餐标签,可切换只看某类委托;
|
||
- 默认 30 秒自动刷新(设置页可改),按 `F` 全屏。
|
||
|
||
---
|
||
|
||
## 7. 从源码构建
|
||
|
||
环境:Windows + Go 1.25(本项目在 `go1.25.6` 上验证)。
|
||
|
||
```powershell
|
||
.\build.ps1
|
||
```
|
||
|
||
`build.ps1` 会设置 `GOPROXY=off`、`GOCACHE=<项目>\.gocache`,用本地模块缓存离线构建,产物为 `daili.exe`(约 13.5 MB,内含 SQLite 引擎、时区库、模板与静态资源,不依赖任何 DLL)。
|
||
|
||
> **为什么有 `third_party/fileutil`**:SQLite 驱动 `modernc.org/sqlite` 的**测试代码**引用了 `modernc.org/fileutil`,但编译产物并不依赖它。本机无法访问任何 Go 模块源,因此用一个空模块占位,仅用于满足模块图解析。
|
||
>
|
||
> **为什么内嵌时区库**:Windows 没有 `/usr/share/zoneinfo`,为了 `timezone = Asia/Shanghai` 在任何机器上都可用,引入了 `time/tzdata`(约 0.5 MB)。
|
||
|
||
> 改了依赖之后,请在 Windows 上额外跑一次 `GOOS=linux go build ./...` 再提交 `go.sum`:
|
||
> 有些依赖(例如 `modernc.org/libc` 的 Linux 专用文件)只在 Linux 构建路径下被编译,
|
||
> 只在本机 Windows 构建会漏掉它们的 `go.sum` 条目,导致 CI 报 `missing go.sum entry`。
|
||
|
||
测试:
|
||
|
||
```powershell
|
||
$env:GOFLAGS='-mod=mod'; $env:GOPROXY='off'; $env:GOCACHE="$PWD\.gocache"
|
||
go test ./...
|
||
```
|
||
|
||
目录结构:
|
||
|
||
```
|
||
main.go 程序入口(读配置、日志、时区、监听、备份)
|
||
internal/config daili.ini 的生成/解析/校验(含单测)
|
||
internal/domain 纯业务计算(日期、剩余天数、状态、追加换算)+ 单元测试
|
||
internal/store SQLite 连接、迁移、全部读写 + 单元测试
|
||
internal/logx 控制台 + 按天切分的运行日志
|
||
internal/pw 口令散列(PBKDF2-SHA256,标准库实现)
|
||
internal/web 路由、会话、模板渲染、处理器
|
||
internal/web/templates 页面与布局(embed 进二进制)
|
||
internal/web/static app.css / screen.css / app.js / screen.js
|
||
scripts/acceptance.ps1 冒烟清单执行器(119 条断言)
|
||
scripts/config-test.ps1 配置文件专项测试(14 条断言)
|
||
scripts/smoke.ps1 端到端冒烟(早期版本,保留)
|
||
scripts/seed.ps1 写入演示数据
|
||
scripts/dbtool.py 测试预处理(暂停回溯、批量造数、完整性检查)
|
||
.gitea/workflows/build.yml Gitea Actions:vet → test → 交叉编译 → 上传产物
|
||
.gitattributes 统一换行(.go/.yml 用 LF,.ps1 用 CRLF)
|
||
PRD.md 产品需求文档(本地文档,不入库)
|
||
TEST-CHECKLIST.md 冒烟测试清单 + 执行结果 + 缺陷记录(本地,不入库)
|
||
test-evidence/ 测试证据(本地,不入库)
|
||
daili.ini 首次运行自动生成
|
||
```
|
||
|
||
### 持续集成(Gitea Actions)
|
||
|
||
仓库:<https://git.code.cq.cn/chun_qiu/subtrack.git>,CI 配置在 `.gitea/workflows/build.yml`。
|
||
|
||
- 触发:推送到 `main` / `master`、打 `v*` 标签、PR、手动执行;
|
||
- 运行环境:`runs-on: ubuntu-latest`;Go 版本由 `actions/setup-go@v5` 读取 `go.mod`(1.25);
|
||
- 步骤:`go vet ./...` → `go test ./...` → 交叉编译 Windows / Linux 两个二进制 → `sha256sum` → 用 `actions/upload-artifact@v4` 上传;
|
||
- 上传步骤带 `env: ACTIONS_RESULTS_URL: https://git.code.cq.cn/`;
|
||
- 产物:`subtrack-<run_number>`,内含 `daili-windows-amd64.exe`、`daili-linux-amd64`、`SHA256SUMS.txt`,保留 14 天;
|
||
- 模块代理默认 `https://goproxy.cn,direct`,如在海外或内网构建,改 workflow 顶部的 `GOPROXY` 即可。
|
||
|
||
> 仓库只入库源码、构建脚本、CI 配置和本 README;PRD、测试清单、截图与测试证据都在 `.gitignore` 里排除。
|
||
|
||
---
|
||
|
||
## 8. 常见问题
|
||
|
||
**Windows 提示「已保护你的电脑」**
|
||
点「更多信息 → 仍要运行」。这是 Windows 对未签名 exe 的默认拦截。
|
||
|
||
**端口被占用 / 想换端口**
|
||
改 `daili.ini` 里的 `listen_port` 后重启;临时换端口可用 `daili.exe -addr :19000`。
|
||
|
||
**只想自己用,不让局域网访问**
|
||
把 `listen_ip` 改成 `127.0.0.1`,启动横幅会提示「仅本机可访问」。
|
||
|
||
**手机打不开局域网地址**
|
||
1. 确认 `listen_ip` 是 `0.0.0.0`;
|
||
2. 确认手机和电脑在同一个 WiFi;
|
||
3. Windows 防火墙首次会弹窗,选「允许访问」(专用网络);
|
||
4. 用启动时打印的那个 `192.168.x.x` 地址,不要用 `127.0.0.1`。
|
||
|
||
**忘记密码**
|
||
让另一位管理员在 `设置 → 管理员` 里新增一个账户即可;如果只剩一个管理员且忘了密码,只能删掉 `daili.db` 重来。
|
||
|
||
**数据会不会因为程序崩溃丢?**
|
||
单文件 SQLite + 每次操作即时落盘,正常使用不会丢;每天的自动备份是双保险。仍然建议定期把 `backup/` 拷到别的盘。
|
||
|
||
**能放到公网吗?**
|
||
不建议。程序按「局域网内可信环境」设计:会话 Cookie 有 HttpOnly / SameSite 保护,但没有 HTTPS、没有登录失败锁定,且大屏默认免登录。要放公网请套一层反向代理 + HTTPS + 访问控制,并把 `screen_public` 改成 `false`。
|
||
|
||
---
|
||
|
||
## 9. 安全说明
|
||
|
||
- **初始管理员**(第一个创建的账号,`id=1`)在 `设置 → 管理员` 每行可以点「编辑」,修改其他管理员的用户名、昵称,或重置密码;
|
||
- 重置密码会立刻清除对方的登录会话,他需要用新密码重新登录;昵称/用户名的修改不影响会话;
|
||
- 自己那一行不显示编辑(改自己的密码用「修改我的密码」),避免误操作把自己锁在门外;
|
||
- 其余管理员权限相同,但只能改自己的密码。
|
||
|
||
|
||
- 口令使用 PBKDF2-HMAC-SHA256(12 万次迭代 + 随机盐)存储,不可逆;
|
||
- 所有写操作记录操作人、时间、IP 与摘要,可在「操作日志」里查询;
|
||
- 服务端模板全部走 `html/template` 自动转义;
|
||
- 所有 POST 校验 `Origin`,会话 Cookie 使用 `SameSite=Lax` + `HttpOnly`;
|
||
- 配置文件里的数据库/备份/日志路径请自行确保目录权限,程序不会覆盖已有文件(备份重名会跳过)。
|