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.
7.1 KiB
7.1 KiB
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/questions500: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 ./...复核