需求与确认(用户逐项确认): - 老数据「按次 / 通行证 / 深渊」统一迁移成按日,代码里彻底删除三种模式 - 打手归属一并移除(只剩一个人,颜色与指派没有区分意义) - 盲水印做成完全不可见:只存在于 DOM / 源码,肉眼与截图都看不到 - 拼写采用更正后的 Powered by Baka春秋 - 版本号与品牌全站统一带 -L - screen_public / portal_public 保留解析但不起作用,保证旧 ini 能直接启动 - README 同步更新 品牌与版本(全站统一): - const version = "1.11.5-L":<title>、启动横幅、日志前缀 [代打台-L]、 设置页版本号、页脚版本号全部带 -L - 左上角导航品牌 代打台 → 代打台-L(登录页、初始化页同步) - 页脚新增可见署名 Powered by Baka春秋 盲水印: - _layout.html 在 <body> 起始处注入 .wm-blind 容器(含注释与 data-wm 双标记), 覆盖包括登录/初始化在内的所有页面 - app.css 用零尺寸 + 透明 + opacity:0 + clip-path:inset(50%) 四重隐藏, 同时留同名注释;不占位、不上色、不进无障碍树、不影响打印 功能移除: - 大屏:删除 handlers_screen.go、pages/screen.html、_screen_layout.html、 static/screen.css、static/screen.js、store.Stats/ScreenStats; 导航「大屏 ↗」、页脚「大屏」、设置页「大屏刷新/大屏」行、启动横幅大屏行一并删除 - 客户自查:删除 handlers_portal.go、pages/portal.html 与 .portal-*/.pcal-* 样式, 设置页「客户自助」行删除 - 多管理员:删除 handleUserCreate/Toggle/Color/UserEditPage/UserEditSave、 pages/user_form.html、store 侧 ActiveUsers/SetUserColor/SetUserActive/ UpdateUserByAdmin/NormalizeColor/AssigneePalette;设置页「管理员」整块移除, 只保留首次启动创建的那一个账户与「修改我的密码」 - 打手归属:删除 customers.assignee_id 相关读写与 UI(客户详情指派下拉、 客户表单「归属打手」、日历格左侧打手色竖条、任务卡打手标签、套餐详情客户列) - 登录页与初始化页的说明文案同步改为单账户口径(「只有一个管理员账户」 「创建后不能再添加其他管理员」),字数与 main 对齐,卡片不换行、高度不变 - 触摸小键盘:删除 3×4 键盘、⌨/触控开关、localStorage 记忆、.keypad* 样式 - 套餐计费方式:只保留按日。删除按次/通行证/深渊的 Package 与 Subscription 字段、 domain 里的 UnitCount/StateUsedUp/CycleIndex、package_form 计费方式单选与 通行证/深渊/有效期字段、日历整段色块(has-block/cell-block/season-band)、 追加次数分支、SeasonComplete/AddCount、CountActiveSubs 的次数条件 数据库迁移(幂等,Migrate 内自动执行): - normalizeLegacyData:套餐一律 unit='day' 并清 season/abyss/cycle_days/ default_validity_days/season_*;订阅清 season/abyss/cycle_days/season_done - 通行证、深渊当年就是 unit='day' 且起止日完整,仅清标记,服务区间原样保留 - 按次按「1 次 = 1 天」折算:结束日 = 开始日 + 总次数 − 1;仍缺结束日退回开始日 - 只动数据,不删表不删列:老库的 season/abyss/cycle_days/total_count/used_count 保留但不再使用,升级可逆、不会因为 DDL 失败卡住 - 新库 schema 干净:不再创建上述列,users.color / customers.assignee_id 也不创建 - 老库 ensureColumn 保留 calendar_separate / tag / archived 三项(真增量列) 兼容: - config 仍解析 screen_public / portal_public(结构体字段注明已废弃), 默认 ini 模板里改为「已废弃,写了不报错、不生效」 测试: - go vet ./... 通过;go test ./... 全部通过 (新增 TestNormalizeLegacyTypeData 验证三模式折算成按日; TestSingleUserAccount / TestSessionLifecycle 覆盖单用户与会话; 删除按次、深渊、打手颜色、多用户等已不存在的能力的用例) - 新增 scripts/smoke-lite.ps1:起隔离实例,19 个页面级请求全部 200, 已移除的 /screen、/customer、/api/screen/day 均 404, 水印/品牌/v1.11.5-L/无残留词 12 项断言通过, 真实数据下日历出现待打任务、「剩 30 天」、今天到期徽标 4 项断言通过, 本次 0 失败 README:改为 lite 版说明,删除大屏/客户自查/通行证/深渊/按次/小键盘/多用户章节, 新增「盲水印」与「与 main 分支的差异」两节(含老数据折算规则与列保留说明)。
323 lines
19 KiB
Markdown
323 lines
19 KiB
Markdown
# 代打台-L · 代打管理平台(lite 版)
|
||
|
||
一个给代打工作室用的单文件管理程序:**套餐 → 订阅 → 追加时长 → 日历打卡**。
|
||
整个程序就是一个 `daili.exe` + 一个 `daili.ini`,数据存在同目录的 `daili.db` 里,局域网内手机、电视都能打开。界面支持亮色 / 暗色切换,默认跟随系统。
|
||
|
||
> **这是 lite 分支**:只保留「按日(包时)」一种套餐,去掉了大屏、客户自助查询、多管理员、触摸小键盘。
|
||
> 版本号统一带 `-L` 后缀(当前 `1.11.5-L`),界面品牌为「代打台-L」,页脚署名 `Powered by Baka春秋`。
|
||
> 与 `main` 分支的差异见文末「[10. 与 main 分支的差异](#10-与-main-分支的差异)」。
|
||
|
||
---
|
||
|
||
## 1. 快速开始
|
||
|
||
1. 把 `daili.exe` 放进任意文件夹(建议路径不含空格,例如 `D:\代打台\`);
|
||
2. 双击 `daili.exe`:
|
||
- 首次运行会自动生成配置文件 `daili.ini`;
|
||
- 弹出一个黑色窗口,打印访问地址(默认 **17777** 端口);
|
||
- 默认会自动打开浏览器;
|
||
3. 浏览器打开 `http://127.0.0.1:17777` → 第一次会让你**创建管理员账号**(这是唯一的账号,之后不能再添加);
|
||
4. 之后按「套餐 → 客户 → 订阅」的顺序录入即可。
|
||
|
||
```
|
||
┌───────────────────────────────────────────────┐
|
||
│ 代 打 台 - L · 代打管理平台 │
|
||
└───────────────────────────────────────────────┘
|
||
版本 1.11.5-L 配置文件 daili.ini
|
||
数据库 D:\代打台\daili.db
|
||
访问地址:
|
||
本机 http://127.0.0.1:17777
|
||
局域网 http://192.168.1.23:17777
|
||
按 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` | 启动后自动打开浏览器 |
|
||
| `log_enabled` | `true` | 运行日志写文件(控制台始终输出) |
|
||
| `log_dir` | `logs` | 日志目录,按天切分 `daili-YYYY-MM-DD.log` |
|
||
|
||
> `screen_public`(大屏)与 `portal_public`(客户自助)在 lite 版**已废弃**:仍然接受解析,但不起任何作用。
|
||
> 保留它们只是为了让你从 `main` 升级时,旧 `daili.ini` 能直接启动,不会被「未知配置项」拦住。
|
||
|
||
**行为约定**
|
||
|
||
- 文件不存在 → 自动生成默认配置,照常启动;
|
||
- 文件写错 → **报错退出并指出行号**,原文件不会被修改。例如:
|
||
|
||
```
|
||
[代打台-L] 配置文件有问题,已停止启动:
|
||
|
||
第 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 天,色签绿;
|
||
- 只有「按日」一种计费方式:有开始日与结束日,每天一条待打任务。
|
||
> 以后要加套餐 D/E/F,直接再加一行就行,**不会影响任何已有客户数据**。
|
||
2. **建客户**:`客户 → 新建客户`,填手机尾号 + 客户名(这两项组合唯一)。
|
||
3. **开通订阅**:进客户详情 → 选套餐、开始日、天数 → 开通订阅。
|
||
4. **日常使用**:打开「日历」,今天那格里就是这个客户今天要打的单,点「完成」打卡。
|
||
5. **续费**:客户转账后,点订阅上的「追加时长」→ 在日历上点新的终止日期 → 确认。
|
||
面板会实时显示「计算起点 / 原结束日 / 新结束日 / 本次追加几天 / 追加后剩余几天」,并在客户页留下追加记录。
|
||
|
||
> 想先看效果再录自己的数据?程序启动后运行 `powershell -ExecutionPolicy Bypass -File scripts\seed.ps1`,会写入演示客户与套餐(默认账号 `admin` / `daili123`)。
|
||
|
||
---
|
||
|
||
## 4. 业务规则(和 PRD 一致)
|
||
|
||
**剩余时长**
|
||
- `剩余天数 = 结束日 − 今天 + 1`,结束日当天仍算服务日;
|
||
- 没有次数、没有周期:一个订阅就是从开始日到结束日的一段连续服务期。
|
||
|
||
**追加时长(核心)**
|
||
- 打开追加面板,**在月历上点选新的终止日期**,系统自动反算;
|
||
- 未到期的订阅:从原结束日的**次日**起算,追加天数 = 新结束日 − 原结束日;
|
||
- 已到期的订阅:**从今天起算**(不会把中间空档的天数白送给客户);
|
||
- 追加记录保留:计算起点、旧结束日、新结束日、天数、备注、操作人、时间。
|
||
|
||
**暂停 / 恢复**
|
||
- 暂停期间冻结剩余时长,日历上不出现待打任务;
|
||
- 恢复时结束日**自动顺延**暂停的自然日天数,时间轴上是灰色斜纹段。
|
||
|
||
**打卡**
|
||
- 每天一条「完成 / 跳过」,只做记录不扣天数(天数按自然日流逝);
|
||
- 撤销打卡会删掉这条记录,不影响结束日。
|
||
|
||
**预警**
|
||
- 剩余 ≤3 天橙色、今天到期红色、已过期灰色;顶栏常驻「今日到期 / 3 天内 / 7 天内」三个数字。
|
||
|
||
**查询**
|
||
- 顶栏搜索框输入手机尾号即可定位客户(也支持姓名、游戏名、联系方式),按 `/` 快速聚焦。
|
||
|
||
---
|
||
|
||
## 4.1 工作台速用
|
||
|
||
- **按尾号快速完成**:日历右侧「当日待完成」顶部输入手机尾号 → 回车。
|
||
- 只匹配到 1 项:直接完成并提示;
|
||
- 同一尾号有多个客户,或一个客户今天有多个服务:弹出勾选面板,默认全选,可多选后一次完成。
|
||
- **加急**:每条任务右侧点「加急」,会加红色 `加急` 标签并排到最前;日历格子出现红点。再点一次取消。
|
||
- **按套餐分日历**:套餐编辑页勾选「在日历中独立显示」后,工作台顶部会出现套餐标签(全部 / 每日任务 / …),可以只看某类委托的排单。
|
||
- **日历格子**:只保留大字「已完成 / 总数」(如 1/2 = 2 单里做完 1 单)。
|
||
- **按钮收纳**:任务行只露出「完成」,跳过 / 加急 / 追加收进「⋯」菜单,点空白处自动收起。
|
||
- **停用客户**:客户详情页可「停用」(默认从列表与日历隐藏,订阅保留)或「彻底删除」(连订阅/打卡/追加记录一起删,需二次确认);列表右上角可切换到「显示已停用」再恢复;
|
||
- **7 天内到期**:顶栏徽标,固定统计未来 7 天内到期的订阅;
|
||
- **抽屉时钟**:右侧当日面板顶部有时钟,24 小时制精确到秒,下面一行是当天日期;
|
||
- **已完成折叠**:当日清单里已完成/已跳过的单子自动折叠成一行(尾号 + 姓名 + 套餐 + 状态),点这一行展开看剩余,以及撤销/加急/追加;未完成的行不受影响;
|
||
- **主题**:顶栏右上角 ☾ / ☀ 切换亮 / 暗,偏好记在浏览器里;没选过时由页面在首屏按系统偏好自动决定。整套界面只认 `<html data-bs-theme>` 一个开关,不会出现「半亮半暗」。
|
||
- **升级不缓存旧界面**:CSS/JS 链接带**内容指纹**(`app.css?v=<12 位哈希>`)。资源可以长缓存(一年、immutable),但样式或脚本一改、重新编译,URL 就会变,浏览器自动取新文件,不用手动清缓存;HTML 仍然 `no-store`。
|
||
|
||
---
|
||
|
||
## 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.tag`;客户停用是 `customers.archived`(0/1);加急标记存在 `task_flags` 表;套餐的「独立日历」是 `packages.calendar_separate` 列,老版本数据库打开时会**自动加列**,不用手工迁移。
|
||
- **从 main 升级**:lite 版启动时会自动把老库里的「按次 / 通行证 / 深渊」统一折算成按日(详见文末差异说明),老库直接打开即可,无需手工改数据。
|
||
- `daili.ini`(监听/备份/日志配置)与 `backup/`、`logs/` 都是**独立于数据**的,迁移时可以不拷,程序会按默认值重新生成。
|
||
|
||
- 手动备份:`设置 → 立即备份`(同样遵守保留份数),备份文件本身也是可直接打开的单文件库;
|
||
- 导出:`设置 → 导出客户 / 订阅 / 日志 CSV`,UTF-8 BOM,Excel 直接打开不乱码。
|
||
|
||
---
|
||
|
||
## 6. 从源码构建
|
||
|
||
环境: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 ./...
|
||
```
|
||
|
||
页面级冒烟(起一个隔离实例,把所有页面渲染一遍,并校验水印/品牌/已移除入口):
|
||
|
||
```powershell
|
||
powershell -ExecutionPolicy Bypass -File scripts\smoke-lite.ps1
|
||
```
|
||
|
||
目录结构:
|
||
|
||
```
|
||
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 / app.js
|
||
scripts/smoke-lite.ps1 lite 版页面级冒烟(渲染 + 水印 + 已移除入口 404)
|
||
scripts/acceptance.ps1 冒烟清单执行器(main 分支遗留,部分条目已不适用)
|
||
scripts/config-test.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` 里排除。
|
||
|
||
---
|
||
|
||
## 7. 常见问题
|
||
|
||
**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`。
|
||
|
||
**忘记密码**
|
||
lite 版只有一个管理员,没有「新增管理员」可以绕过,只能二选一:删掉 `daili.db` 从零开始,或用任意 SQLite 工具把 `users` 表的 `password_hash` 清空后重新初始化。请务必记牢密码。
|
||
|
||
**数据会不会因为程序崩溃丢?**
|
||
单文件 SQLite + 每次操作即时落盘,正常使用不会丢;每天的自动备份是双保险。仍然建议定期把 `backup/` 拷到别的盘。
|
||
|
||
**能放到公网吗?**
|
||
不建议。程序按「局域网内可信环境」设计:会话 Cookie 有 HttpOnly / SameSite 保护,但没有 HTTPS、没有登录失败锁定。要放公网请套一层反向代理 + HTTPS + 访问控制。
|
||
|
||
---
|
||
|
||
## 8. 安全说明
|
||
|
||
- lite 版**只有一个管理员**,就是首次启动时创建的那个账户(`users.id = 1`),不提供新增、停用或编辑他人账户的入口;
|
||
- 改自己的密码用 `设置 → 修改我的密码`;
|
||
- 口令使用 PBKDF2-HMAC-SHA256(12 万次迭代 + 随机盐)存储,不可逆;
|
||
- 所有写操作记录操作人、时间、IP 与摘要,可在「操作日志」里查询;
|
||
- 服务端模板全部走 `html/template` 自动转义;
|
||
- 所有 POST 校验 `Origin`,会话 Cookie 使用 `SameSite=Lax` + `HttpOnly`;
|
||
- 配置文件里的数据库/备份/日志路径请自行确保目录权限,程序不会覆盖已有文件(备份重名会跳过)。
|
||
|
||
---
|
||
|
||
## 9. 盲水印
|
||
|
||
界面里带一处不可见的版权水印 `Powered by Baka春秋`:写在 `_layout.html` 里由 `.wm-blind` 样式隐藏(零尺寸、透明、`clip-path` 裁掉、不进入无障碍树),同时在 `app.css` 里留了同名注释。它不占位、不上色、不影响布局与打印,只用于源码/DOM 层面溯源,**请勿删除**。
|
||
|
||
页脚另有一行可见署名 `Powered by Baka春秋`。
|
||
|
||
---
|
||
|
||
## 10. 与 main 分支的差异
|
||
|
||
| 项目 | main | lite(本分支) |
|
||
| --- | --- | --- |
|
||
| 版本号 | `1.11.5` | `1.11.5-L`(`<title>`、启动横幅、日志前缀、页脚全站统一带 `-L`) |
|
||
| 品牌 | 代打台 | 代打台-L |
|
||
| 大屏 `/screen` | 有,`screen_public` 控制免登录 | **已移除**,路由返回 404 |
|
||
| 客户自助 `/customer` | 有,`portal_public` 控制免登录 | **已移除**,路由返回 404 |
|
||
| 套餐计费方式 | 按日 / 按次 / 通行证 / 深渊 | **只有按日** |
|
||
| 管理员 | 可新增多个,为主管可编辑他人 | **只有首次启动创建的那一个** |
|
||
| 打手归属 | 客户可指派打手,彩色竖条标识 | **已移除**(只剩一个人,颜色无意义) |
|
||
| 触摸小键盘 | 3×4 小键盘 + 触控/PC 切换 | **已移除** |
|
||
| 署名 | 无 | 页脚 + 盲水印 `Powered by Baka春秋` |
|
||
|
||
**老数据怎么折算成按日**(启动时自动完成,可重复执行):
|
||
|
||
- **通行证**:当年就是 `unit='day'` 且起止日期完整,清掉 `season` 标记即可,服务区间原样保留;
|
||
- **深渊**:同样已是 `unit='day'`,结束日 = 开始日 + 周期天数 × 周期数 − 1,清掉 `abyss/cycle_days` 标记,区间原样保留;
|
||
- **按次**:按「1 次 = 1 天」折算。有总次数但没结束日的,结束日 = 开始日 + 总次数 − 1 天;仍缺结束日的退回开始日;
|
||
- 折算只动数据,不删表、不删列:老库里的 `season / abyss / cycle_days / total_count / used_count` 等列会保留但不再使用,避免升级过程不可逆。
|
||
|
||
`screen_public` 与 `portal_public` 两个配置项在 lite 版仍然被解析(不报错),但不再有任何作用。
|