- 提取 getWKFromContext 辅助函数,消除 handler 中 5 处重复代码 - 提取 retryCode 函数,消除 Login/performStudy 中验证码重试重复 - 提取 removeSession 内部方法,消除 Del/ClearAll/ClearExpired 中 3 处重复 - 提取 WK.UserKey() 方法,消除 4 处 userKey 手动拼接 - SessionManager.Get() 改用 RLock 优化读性能 - GetRecords 递归分页改为迭代,避免栈溢出 - prepareRequestClient 添加配置缓存,仅在 debug 设置变化时重建 - 修正 schedule.go 时区为 Asia/Shanghai + cron "0 6 * * *" - 修正 typo "以达到" → "已达到" - 删除未使用的 QAList struct - 修复 bufferHub.append 切片内存泄漏 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5.1 KiB
5.1 KiB
doc_type, refactor, status, scope, summary
| doc_type | refactor | status | scope | summary |
|---|---|---|---|---|
| refactor-design | 2026-04-25-backend-cleanup | approved | 后端 Go 代码全部(internal/、pkg/、cmd/),21 文件 ~2485 行 | 执行 11 条低中风险重构:6 条提取函数消除重复、2 条性能修复(递归改迭代、锁优化)、3 条小修(typo、删除死代码、内存泄漏) |
backend-cleanup refactor design
1. 本次范围
- 勾选:#1 #2 #3 #4 #5 #6 #7 #8 #9 #10 #12
- 明确不做:#11(Handler 层业务逻辑下沉——高风险、跨模块,建议单独开一轮 refactor)
- 预估总工作量:小 / 总风险:低
2. 前置依赖
- 无需补测试(本次全部为纯提取/等价替换,不改变控制流)
- #8 需要用户确认业务意图(北京时间 6 点 vs 新加坡时间凌晨 2 点)
3. 执行顺序
步骤 1:删除未使用的 QAList struct(#10)
- 引用方法:M-L2-02
- 具体操作:删除
internal/ckwk/types.go中type QAList struct{} - 退出信号:
go build ./internal/ckwk/...通过 - 验证责任:AI 自证
- 回滚:git revert
步骤 2:修正 typo "以达到" → "已达到"(#9)
- 引用方法:M-L2-03
- 具体操作:
internal/ckwk/api.go两处 "以达到" 改为 "已达到"(约第 168 行和第 416 行) - 退出信号:
go build ./...通过 - 验证责任:AI 自证
- 回滚:git revert
步骤 3:确认 schedule.go 时区意图并修正(#8)
- 引用方法:M-L2-03
- 具体操作:注释写"每天 6 点执行",改为
Asia/Shanghai+0 6 * * *对齐注释意图 - 退出信号:
go build ./...通过 - 验证责任:AI 自证(确认编译通过)+ HUMAN(确认业务意图)
- 回滚:git revert
步骤 4:提取 userKey 构造为 WK.UserKey() 方法(#4)
- 引用方法:M-L2-03
- 具体操作:
- 在
internal/ckwk/api.go的WKstruct 上添加func (wk *WK) UserKey() string { return wk.Host + ":" + wk.Username } - 在
session_manager.go中替换 4 处手动拼接为wk.UserKey()或item.Instance.UserKey()
- 在
- 退出信号:
go build ./...通过 + grep 确认无残留的Host + ":" + Username拼接 - 验证责任:AI 自证
- 回滚:git revert
步骤 5:提取 getWKFromContext 辅助函数(#1)
- 引用方法:M-L2-01
- 具体操作:
- 在
internal/handler/ckwk.go添加func getWKFromContext(ctx *gin.Context) (*ckwk.WK, bool) - 替换 5 处重复代码为调用此函数
- 在
- 退出信号:
go build ./...通过 + grep 确认无残留的ctx.Get("wk_instance")模式 - 验证责任:AI 自证
- 回滚:git revert
步骤 6:提取 retryCode 函数(#2)
- 引用方法:M-L2-01
- 具体操作:
- 在
internal/ckwk/api.go添加func retryCode(wk *WK, maxRetries int) (string, error) - 替换
Login()和performStudy()中的重复重试代码为调用
- 在
- 退出信号:
go build ./...通过 - 验证责任:AI 自证
- 回滚:git revert
步骤 7:提取 removeSession 内部方法(#3)
- 引用方法:M-L2-01
- 具体操作:
- 在
SessionManager上添加func (m *SessionManager) removeSession(sessionID string, item SessionItem) - 替换
Del()、ClearAll()、ClearExpired()中的重复清理代码
- 在
- 退出信号:
go build ./...通过 - 验证责任:AI 自证
- 回滚:git revert
步骤 8:SessionManager.Get() 优化锁策略(#5)
- 引用方法:M-L4-01
- 具体操作:
Get()改为先 RLock 读取,只更新 LastValue 时升级为写锁- 由于 Go 的 RWMutex 不支持锁升级,改为:RLock 读 → 检查存在 → RUnlock → Lock 更新 LastValue → Unlock
- 退出信号:
go build ./...通过 - 验证责任:AI 自证
- 回滚:git revert
步骤 9:GetRecords 递归改迭代(#6)
- 引用方法:M-L2-01
- 具体操作:将
GetRecords中的递归分页改为 for 循环,逐页追加到 result.List - 退出信号:
go build ./...通过 - 验证责任:AI 自证
- 回滚:git revert
步骤 10:prepareRequestClient 缓存配置(#7)
- 引用方法:M-L4-01
- 具体操作:
- 在
WKstruct 上缓存上次配置的 debug/proxy/ssl-verify 状态 prepareRequestClient()只在配置变化时重建,否则跳过- 在
conf.SetRuntimeDebugEnabled被调用后,下次请求时自动触发重建
- 在
- 退出信号:
go build ./...通过 - 验证责任:AI 自证 + HUMAN(切换 debug 开关确认代理/SSL 行为生效)
- 回滚:git revert
步骤 11:修复 bufferHub.append 切片内存泄漏(#12)
- 引用方法:M-L4-01
- 具体操作:在
h.entries = append(h.entries[1:], entry)之前,将h.entries[0]置为零值Entry{} - 退出信号:
go build ./...通过 - 验证责任:AI 自证
- 回滚:git revert
4. 风险与看点
- 步骤 8(锁优化):Go RWMutex 不支持锁升级,需 RLock→RUnlock→Lock 两步走,中间可能有竞态导致 LastValue 偶尔不准,但不影响正确性(LastValue 只用于过期清理的时间戳判断)
- 步骤 10(配置缓存):需确保 debug 开关切换后首次请求即生效,不能有"延迟一拍"问题