Repo .git was damaged (refs/ missing, index truncated, object store near-empty). Repaired via git init (rebuilt refs), stale index preserved as .git/index.corrupt-20260910.bak, then full worktree committed as a rollback baseline.
91 lines
7.1 KiB
Markdown
91 lines
7.1 KiB
Markdown
# TamaBox 功能与修复变更记录
|
||
|
||
> 变更日期:2026-08-12 ~ 2026-08-13
|
||
> 说明:本文档汇总本阶段对 TamaBox(NekoBox fork)新增的功能、修复的问题与性能/安全优化,供部署、维护与后续开发参考。
|
||
|
||
---
|
||
|
||
## 一、新增功能
|
||
|
||
| # | 功能 | 说明 |
|
||
|---|------|------|
|
||
| 1 | **问题置顶 / 精选回答** | 提问箱主人在管理页可置顶/取消置顶提问,公开主页置顶优先展示(`is_pinned` 字段 + `PinFirst` 排序) |
|
||
| 2 | **单题分享图** | 单个问题(提问+回答)生成分享卡片图,仅公开且已回答可生成;复用主页分享图的绘制/缓存/字体模块 |
|
||
| 3 | **回答后追问** | 提问者凭 token/登录身份对已回答的问题最多追问 3 次,主人可回复;事务+行锁保证并发上限;追问框仅在主人回复上一轮后显示,等待期间提示提问者 |
|
||
| 4 | **回答 Markdown 渲染** | 回答与追问回答支持 Markdown 排版,服务端渲染 + HTML 白名单过滤(防存储型 XSS),带 XSS 单测 |
|
||
| 5 | **深色模式** | 全站一键切换深/浅色(cookie 持久化 365 天);桌面端顶栏图标、移动端底部固定操作栏,双入口 |
|
||
| 6 | **同 IP 重复内容拦截** | 同一 IP 在 5 分钟内提交相同内容(提问/私聊首条)会被拒绝,防刷屏 |
|
||
| 7 | **匿名 / 登录分级限流** | 登录用户享有 3 倍请求额度,匿名与登录独立限流器统计(滑动窗口) |
|
||
| 8 | **封禁用户连带清理** | 新增 CLI 命令 `TamaBox ban --email/--domain`:事务级联删除该用户提问、追问、私聊、消息、图片关联并物理删除账号(含二次确认) |
|
||
| 9 | **提问箱统计看板** | 管理页顶部 6 张统计卡:总提问 / 已回答 / 未回答 / 私密 / 置顶 / 私聊会话 |
|
||
| 10 | **热门标签榜** | 探索页展示高频用户标签(点击即搜索),热门问题区块按需移除 |
|
||
| 11 | **全文搜索提问箱** | 管理页可按关键词搜索自己收到的提问与回答(LIKE 模糊匹配,通配符转义,含私密提问) |
|
||
| 12 | **JSON 全量导出** | `/user/profile/export-json` 导出用户信息 + 提问/回答/追问/图片 + 私聊全部消息,满足数据可携带权;与既有 Excel 导出并存 |
|
||
| 13 | **多语言(i18n)** | 简体中文 / 繁體中文 / English / 日本語;按 语言 cookie > 登录用户配置 > 提问箱主人配置 > 站点默认 解析;**注册页可直接选择界面语言**(登录后即刻生效),注册成功提示跟随所选语言 |
|
||
| 14 | **私聊**(已有功能完善) | 登录用户可向开启私聊的提问箱发起会话,支持图片、拉黑、每日条数上限、会话关闭;管理页批量获取首条消息避免 N+1 |
|
||
| 15 | **页面密码 / 提问密码** | 提问箱页面可设置访问密码、提问可设置密码(bcrypt 存储) |
|
||
|
||
## 二、问题修复
|
||
|
||
### 编译阻断(在 Linux 上也会编译失败,已全部修复)
|
||
- `QuestionsStore` 接口缺失 `SetPinned` 方法 → **置顶功能无法编译**,已补接口声明
|
||
- `internal/route` 限流、IP 黑名单中间件 `ctx.Request()` 类型错误(应为 `ctx.Request().Request`)→ 修复
|
||
|
||
### 运行时 500 / 功能异常
|
||
- `templates/embed.go` 遗漏 `about-me.html` → `/about-me` 页面 500,已补嵌入
|
||
- **`/user/questions` 500**:`question-list.html` 在 `{{range}}` 内 6 处误用 `.LangCode`(应为 `$.LangCode`),渲染到私密/未回答/私聊条目即报错;已全部修正并新增渲染回归测试
|
||
- "等待主人回复"提示误显示给提问箱主人 → 增加提问者身份判断
|
||
- 邮箱 / 域名无唯一索引(并发注册可重复)→ 改为唯一索引
|
||
- 验证码 remoteIP 未统一解析(反代部署失效)→ 统一走 `shared.ResolveClientIP`
|
||
|
||
### 安全 / 稳定性
|
||
- 图片代理无响应体大小限制(DoS)→ 10MB 上限
|
||
- 图片代理缺少 302 重定向 SSRF 防护 → 域名白名单 + 内网 IP 拦截 + 逐跳重定向校验
|
||
- 限流器每个实例泄漏常驻 goroutine → 包级注册表 + 单一清理循环
|
||
- `censor.RemoveTrustedURL` 白名单删除机制保留(建议定期审查 TrustedHosts)
|
||
|
||
### UI / 交互
|
||
- 提问成功页复制按钮与链接栏大小不协调、两个操作按钮样式不统一 → 统一 flex 布局与按钮样式
|
||
- 顶栏多语言文字(英文/日文)溢出:最终方案为**恢复 UIkit 居中三列布局**,桌面端原样;手机端(≤640px)改流式单行 + 横向滚动兜底,用户名限宽省略号截断
|
||
- 管理页置顶按钮与"未回答"等标签不对齐 → 标签组改 flex 容器统一对齐;置顶按钮改用 `uk-label` 标签样式,完全继承 UIkit 尺寸(定制版 `.uk-label` 字号为 0.875rem,不再硬编码)
|
||
- 语言切换 / 深色模式入口在移动端移入底部固定操作栏(毛玻璃样式)
|
||
|
||
## 三、性能与体积优化(分享图)
|
||
|
||
- **画布尺寸 1280×720 → 960×540**:绘制与编码工作量降至约 40%
|
||
- **输出格式 PNG → JPEG(质量 88)**:单张体积约减小 90%(从数百 KB~1MB 降至约 100KB 量级),编码更快
|
||
- **文字宽度测量改估算**(逐字符宽度累加,替代每次创建 freetype.Context + DrawString 测量)
|
||
- 分享图结果缓存 TTL 由 30 分钟延长至 1 小时,远程图片缓存 1 小时不变
|
||
- 名称文字增加柔和投影,增强复杂背景上的可读性
|
||
|
||
## 四、新增命令与配置
|
||
|
||
### CLI 命令
|
||
| 命令 | 用途 |
|
||
|------|------|
|
||
| `TamaBox web` | 启动 Web 服务 |
|
||
| `TamaBox censor` | 批量补审未审查的提问/回答(需配置文本审查服务) |
|
||
| `TamaBox uid` | 为历史用户补生成 UID |
|
||
| `TamaBox ban --email [email protected]`(或 `--domain`,可加 `--yes` 跳过确认) | 封禁用户并连带清理其全部数据(不可恢复) |
|
||
|
||
### 配置项(conf/app.ini)
|
||
| 配置 | 说明 |
|
||
|------|------|
|
||
| `[app] default_lang` | 站点默认语言(zh-CN / zh-TW / en / ja),留空默认简体中文 |
|
||
| `[security] ip_blacklist` / `ip_blacklist_redirect_url` | 逗号分隔 IP/CIDR 黑名单,命中跳转指定 URL |
|
||
| `[security] trust_proxy` | 反代部署且代理已覆盖 X-Real-IP/X-Forwarded-For 时设为 true,否则 false(防伪造 IP 绕过限流/黑名单) |
|
||
| `[recaptcha] captcha_type` | recaptcha / turnstile / math(本地算数验证码) |
|
||
| `[upload] image_*` / `aliyun_*` | 图片存储(R2/S3 或 OSS) |
|
||
| `[mail] skip_tls_verify` | 自签名 SMTP 证书时跳过校验 |
|
||
| `[service] tls_insecure_skip_verify` | 内网后端自签名证书时跳过校验 |
|
||
|
||
### 编译依赖提示
|
||
- `chai2010/webp` 需要 CGO 与系统 `libwebp`(Linux:`apt install libwebp-dev`),转换失败自动回退原始格式
|
||
- 动画 GIF 转 WebP 需要系统 `cwebp` 命令,未安装时回退原始 GIF
|
||
|
||
## 五、测试
|
||
|
||
- 非 DB 依赖测试全部通过:`templates`(模板解析 + 交叉引用 + 渲染回归)、`internal/i18n`、`internal/shared`、`internal/security/censor`、`internal/template`(含 Markdown XSS 用例)
|
||
- DB 层测试需要外部 MySQL/Postgres(`DB_TYPE` 环境变量),建议 CI 配置
|
||
- 注意:Windows 上因 webp 依赖无法完整编译,请在 Linux 环境 `go build ./...` 复核
|