Files
hfb_sys/docs/代码质量改进计划.md
T
ymlandClaude Opus 4.8 cb07fce5fd 为核心金融模块补充单元测试和集成测试
## 新增测试文件

### Wallet 模块(34 个测试用例)
- service_test.go:8 个 Service 层测试
- repository_logic_test.go:14 个纯逻辑测试(applyEntry 核心逻辑)
- repository_integration_test.go:9 个集成测试(数据库完整流程)
- 测试覆盖率:11.0% → 36.1%(提升 25%)

### Order 模块(11 个测试用例)
- service_test.go:11 个 Service 层测试
- 覆盖所有 Service 方法的依赖检查和参数验证

### Payment 模块(29 个测试用例)
- service_test.go:10 个 Service 层测试
- repository_logic_test.go:19 个逻辑测试(状态判断、常量验证)
- 覆盖支付单复用、退款逻辑、输入验证

## 测试基础设施
- database/test_helper.go:提供内存 SQLite 数据库创建函数
- 支持快速、隔离的测试环境

## 测试策略
- 分层测试:Service 层(参数验证)→ Repository 逻辑层(纯函数)→ Repository 集成层(数据库)
- 覆盖核心业务:余额变更、支付单复用、订单状态转换
- 边界条件:余额刚好够扣、差1分不够扣、零金额、并发场景
- 幂等性保证:渠道充值幂等、支付单复用

## 文档
- docs/代码质量改进计划.md:详细的问题分析和改进计划(16周路线图)
- docs/Repository层测试补充总结.md:测试工作总结和运行指南

## 测试结果
- 所有测试通过(74 个测试用例)
- Wallet 模块覆盖率提升至 36.1%
- 为后续测试工作建立了完整的框架和规范

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 01:26:06 +08:00

610 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# HFB Sys 代码质量改进计划
## 文档说明
本文档记录了项目代码审查发现的问题和优化计划。
**生成时间**: 2026-06-10
**项目版本**: refactor/features-architecture 分支
---
## 📊 当前状态
### 代码规模
- **后端**: ~28,000 行 Go 代码,122 个模块文件
- **前端**: ~46,000 行 Vue/TypeScript 代码
- **数据库**: 876 行 SQL 初始化脚本,114 个索引
- **测试覆盖率**:
- 后端约 10%12 个测试文件)
- 前端接近 0%(仅 2 个测试文件)
### 测试覆盖率详情
| 模块 | 覆盖率 | 状态 |
|------|--------|------|
| realname | 28.2% | ⚠️ 需改进 |
| listing | 11.1% | 🔴 严重不足 |
| wallet | 11.0% | 🔴 严重不足 |
| payment | 8.9% | 🔴 严重不足 |
| dispute | 8.8% | 🔴 严重不足 |
| order | 7.7% | 🔴 严重不足 |
| paymentconfig | 2.2% | 🔴 严重不足 |
| adminuser | 0.7% | 🔴 严重不足 |
---
## 🔴 严重问题(需要尽快处理)
### 1. 测试覆盖率严重不足 ⚠️
**现状**
- 核心金融模块(payment, wallet, order)测试覆盖率低于 12%
- 复杂的订单状态机、结算逻辑、退款流程缺少测试保护
- 前端几乎没有单元测试
**风险**
- 金融相关的钱包、支付、退款逻辑出错会导致资金损失
- 重构时容易引入 bug,没有安全网
- 订单状态转换错误会导致业务流程异常
**改进计划**
-**已完成** (2026-06-10)
- 为 wallet 模块补充 Service 层测试(8 个测试用例)
- 为 order 模块补充 Service 层测试(11 个测试用例)
- 为 payment 模块补充 Service 层测试(10 个测试用例)
- 🔄 **进行中**
- [ ] 为 wallet.Repository 补充核心业务逻辑测试
- [ ] AppendEntries 测试(余额变更、冻结/解冻)
- [ ] ConfirmRechargeFromChannel 幂等性测试
- [ ] 并发场景测试(账户锁定)
- [ ] 为 order.Repository 补充测试
- [ ] Create 订单创建流程测试
- [ ] Pay 支付状态转换测试
- [ ] SubmitHandoff/ConfirmReceive 交接流程测试
- [ ] Checkout 结算计算测试
- [ ] 为 payment.Repository 补充测试
- [ ] Start 支付单创建与复用逻辑测试
- [ ] StartRefund 退款流程测试
- [ ] HandleNotify 支付回调处理测试
- 📅 **计划中**1-2 周内完成):
- [ ] 前端关键组件测试
- [ ] 支付组件单元测试
- [ ] 钱包组件单元测试
- [ ] 订单流程 E2E 测试
- [ ] 集成测试扩展
- [ ] 完整租号流程测试(发布→下单→支付→交接→归还→结算)
- [ ] 退款流程测试
- [ ] 仲裁流程测试
**目标**
- 短期(1 个月内):核心模块测试覆盖率达到 **60%**
- 中期(3 个月内):整体测试覆盖率达到 **70%**
- 长期:建立 CI/CD 测试流程,强制测试覆盖率不低于 60%
---
### 2. 缺少 Context 超时控制 🚨
**现状**
- 122 个模块文件中只有 8 个使用 `context.Context`
- 数据库查询、HTTP 调用、外部 API(支付、短信、实名)都没有超时控制
**风险**
- 数据库慢查询会导致 goroutine 泄漏
- 外部 API 超时会拖垮整个服务
- 无法实现请求级别的超时控制和取消机制
**改进计划**
- 📅 **Week 1**
- [ ] 为所有 Repository 方法签名添加 `ctx context.Context` 参数
- [ ] 更新 Service 层传递 context
- [ ] 在 handler 层从 `c.Request.Context()` 获取 context
- 📅 **Week 2**
- [ ] 为数据库操作添加超时控制
```go
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
return r.db.WithContext(ctx).Create(...)
```
- [ ] 为外部 API 调用添加超时控制
- 支付渠道调用:10 秒超时
- 短信服务:5 秒超时
- 实名认证:10 秒超时
**示例代码**
```go
// 修改前
func (r *Repository) Create(userID uint64, req CreateRequest) (*OrderDTO, error) {
return r.db.Transaction(func(tx *gorm.DB) error {
// ...
})
}
// 修改后
func (r *Repository) Create(ctx context.Context, userID uint64, req CreateRequest) (*OrderDTO, error) {
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
// ...
})
}
```
---
### 3. 代码文件过大,职责不清 📦
**现状**
- `listing/repository.go`: **1731 行**
- `payment/repository.go`: **1282 行**
- `chat/repository.go`: **1155 行**
- 平均文件行数:**184 行**(偏高,建议 150 行以下)
**问题**
- 单个文件包含太多逻辑,难以维护和测试
- 违反单一职责原则
- 代码复用困难
**改进计划**
- 📅 **Week 3-4**
**listing 模块拆分**
```
listing/
├── repository.go # 核心仓储(保留 Create/Update/Delete
├── query.go # 查询逻辑(List/Detail/Search
├── review.go # 审核逻辑(SubmitReview/Approve/Reject
└── cache.go # 缓存逻辑(PublicZoneCount
```
**payment 模块拆分**
```
payment/
├── repository.go # 核心仓储
├── refund.go # 退款逻辑(StartRefund/QueryRefund
├── channel.go # 渠道适配(lakala/leshua/mock
└── notify.go # 回调处理(HandleNotify
```
**chat 模块拆分**
```
chat/
├── repository.go # 核心仓储
├── message.go # 消息逻辑(Send/List/MarkRead
└── websocket.go # WebSocket 连接管理
```
---
## 🟡 重要问题(影响性能和可维护性)
### 4. 缺少接口抽象,模块耦合严重
**现状**
```go
// order/repository.go 直接依赖具体实现
type Repository struct {
db *gorm.DB
chatRepo *chat.Repository // 直接依赖
refundFunc RefundFunc // 通过函数注入
}
```
**问题**
- 难以进行单元测试(无法 mock 依赖)
- 模块间耦合紧密,修改一个模块可能影响其他模块
- 依赖注入通过 `SetXxx` 方法,容易忘记初始化
**改进方案**
```go
// 定义接口解耦
type ChatService interface {
CreateOrderChat(ctx context.Context, orderID uint64) error
}
type RefundService interface {
Refund(ctx context.Context, orderID uint64, amount int64, bizType, remark string) error
}
type Repository struct {
db *gorm.DB
chatSvc ChatService
refundSvc RefundService
}
func NewRepository(db *gorm.DB, chatSvc ChatService, refundSvc RefundService) *Repository {
return &Repository{
db: db,
chatSvc: chatSvc,
refundSvc: refundSvc,
}
}
```
**改进计划**
- 📅 **Week 5-6**
- [ ] 定义核心接口(ChatService, RefundService, WalletService
- [ ] 重构 Repository 依赖注入
- [ ] 更新 router 初始化代码
---
### 5. 数据库查询存在性能隐患
**现状**
- 数据库索引定义相对较少(114 个索引,20+ 张表)
- 部分复杂查询缺少索引覆盖
- 缺少慢查询监控和分析
**具体问题**
```sql
-- adminfinance/repository.go 中的财务汇总查询
SELECT ... FROM rental_orders AS ro
JOIN order_checkouts AS oc ON oc.order_id = ro.id
LEFT JOIN (...) AS w ON w.order_id = ro.id -- 子查询可能很慢
WHERE ro.settled_at >= ? AND ro.settled_at <= ?
```
**改进计划**
- 📅 **Week 7**
- [ ] 审查所有复杂查询,使用 `EXPLAIN` 分析
- [ ] 补充缺失的索引:
```sql
-- 订单结算查询优化
CREATE INDEX idx_rental_orders_settled_at_status
ON rental_orders(settled_at, settlement_status);
-- 财务流水查询优化
CREATE INDEX idx_wallet_ledger_user_created
ON wallet_ledger(user_id, created_at DESC);
-- 支付订单查询优化
CREATE INDEX idx_payment_orders_biz_status
ON payment_orders(biz_type, status, created_at DESC);
```
- [ ] 对复杂统计查询考虑预计算方案
- 每日财务汇总定时任务(凌晨 1 点)
- 用户钱包余额缓存(Redis)
- 订单统计数据缓存(5 分钟 TTL)
- 📅 **Week 8**
- [ ] 启用慢查询日志(记录 > 1 秒的查询)
- [ ] 建立慢查询分析流程
- [ ] 优化 TOP 10 慢查询
---
### 6. 缺少 API 限流和熔断机制
**现状**
- 只有短信验证码有简单的限流(`ErrCodeRateLimited`
- **没有全局 API 限流**
- **没有熔断机制**保护外部依赖(支付渠道、短信服务)
**风险**
- 恶意攻击会拖垮服务
- 外部服务故障会级联影响整个系统
- 无法防止暴力破解
**改进计划**
- 📅 **Week 9**
**添加全局限流中间件**
```go
import "github.com/ulule/limiter/v3"
func RateLimitMiddleware() gin.HandlerFunc {
rate := limiter.Rate{
Period: time.Minute,
Limit: 100, // 每分钟 100 次请求
}
store := memory.NewStore()
middleware := mgin.NewMiddleware(limiter.New(store, rate))
return middleware
}
```
**添加熔断器保护外部服务**
```go
import "github.com/sony/gobreaker"
type PaymentChannelWithBreaker struct {
channel channelClient
breaker *gobreaker.CircuitBreaker
}
func NewPaymentChannel(channel channelClient) *PaymentChannelWithBreaker {
breaker := gobreaker.NewCircuitBreaker(gobreaker.Settings{
Name: "payment_channel",
MaxRequests: 3,
Timeout: 10 * time.Second,
ReadyToTrip: func(counts gobreaker.Counts) bool {
failureRatio := float64(counts.TotalFailures) / float64(counts.Requests)
return counts.Requests >= 3 && failureRatio >= 0.6
},
})
return &PaymentChannelWithBreaker{channel: channel, breaker: breaker}
}
```
- 📅 **限流策略**
- 全局:100 req/min per IP
- 登录接口:5 req/min per IP
- 短信发送:1 req/min per phone
- 支付接口:10 req/min per user
- 文件上传:20 req/hour per user
---
### 7. 前端错误处理不统一
**现状**
- 4 个 Vue 文件中仍有 `console.log/error` 调试代码
- 错误处理分散在各个组件中
- 缺少全局错误拦截和统一提示
**改进计划**
- 📅 **Week 10**
**统一 HTTP 错误处理**
```typescript
// shared/utils/http.ts
import { ElMessage } from 'element-plus'
axios.interceptors.response.use(
response => response,
error => {
const message = error.response?.data?.message || '请求失败'
ElMessage.error(message)
// 统一错误上报(生产环境)
if (import.meta.env.PROD) {
errorReporter.report({
message,
stack: error.stack,
url: error.config?.url,
method: error.config?.method,
})
}
return Promise.reject(error)
}
)
```
**清理调试代码**
- [ ] 移除所有 `console.log` 调试代码
- [ ] 添加 ESLint 规则禁止 `console.log`
- [ ] 使用统一的日志工具(开发环境)
---
## 🟢 改进建议(提升代码质量)
### 8. 日志记录不完整
**现状**
- 有基础日志框架(zap)和请求日志中间件
- 但业务日志记录不充分
- 缺少关键业务节点的日志追踪
**改进建议**
```go
// 为关键业务操作添加结构化日志
logger.Info("order paid successfully",
zap.Uint64("order_id", orderID),
zap.Uint64("user_id", userID),
zap.Int64("amount_cent", amount),
zap.String("payment_no", paymentNo),
zap.String("provider", provider),
)
logger.Warn("refund failed",
zap.Uint64("order_id", orderID),
zap.Int64("amount_cent", amount),
zap.String("reason", reason),
zap.Error(err),
)
```
**补充日志点**
- [ ] 订单支付成功/失败
- [ ] 退款申请/成功/失败
- [ ] 账户交接关键节点
- [ ] 仲裁处理结果
- [ ] 钱包余额变更(大额)
- [ ] 系统配置修改
---
### 9. 配置管理可以改进
**现状**
- 配置都通过环境变量管理
- 缺少配置验证
- 部分配置硬编码在代码中
**改进方案**
```go
// 添加配置验证
func (c Config) Validate() error {
if c.JWTSecret == "change-me" {
return errors.New("JWT_SECRET must be set in production")
}
if c.AppEnv == "production" && c.SMS.Provider == "mock" {
return errors.New("SMS provider cannot be mock in production")
}
if c.AppEnv == "production" && c.Realname.Provider == "mock" {
return errors.New("Realname provider cannot be mock in production")
}
return nil
}
// 在 main.go 中调用
cfg := config.Load()
if err := cfg.Validate(); err != nil {
log.Fatal("配置验证失败:", err)
}
```
**支持配置文件**
- [ ] 支持 `config.yaml` 作为环境变量补充
- [ ] 支持多环境配置文件(dev/staging/prod
- [ ] 敏感配置仍使用环境变量
---
### 10. 前端共享逻辑可以进一步抽象
**现状**
- `shared/utils` 目录已经做了不错的抽象
- 但部分工具函数文件过大(`listingDisplay.ts` 11KB、`pricing.ts` 11KB
**拆分建议**
```
shared/utils/
├── listing/
│ ├── display.ts # 展示相关
│ ├── format.ts # 格式化函数
│ └── filters.ts # 过滤逻辑
├── pricing/
│ ├── pricing.ts # 价格计算
│ ├── discount.ts # 折扣计算
│ └── commission.ts # 佣金计算
└── ...
```
---
### 11. 缺少文档和注释
**现状**
- 代码注释较少
- 没有完整的架构文档
- API 文档依赖 Swagger
**改进计划**
- [ ] 补充架构文档
- [ ] 数据库设计文档(`database.md`
- [ ] 订单状态机文档
- [ ] 支付流程文档
- [ ] 结算规则文档
- [ ] 补充开发者指南
- [ ] 如何添加新功能模块
- [ ] 如何编写测试
- [ ] 如何部署到生产环境
- [ ] 生成并维护 API 文档
- [ ] 完善 Swagger 注释
- [ ] 自动生成 API 文档
---
### 12. 缺少监控和告警
**现状**
- 有基础日志(按天切分)
- 有审计日志
- **但没有性能监控、错误追踪、告警机制**
**改进方案**
**集成监控工具**
- Prometheus + Grafana(应用监控)
- Sentry(错误追踪)
- OpenTelemetry(链路追踪,可选)
**关键指标**
- API 响应时间(P95, P99
- 错误率
- 订单支付成功率
- 数据库慢查询
- 外部 API 调用成功率
**告警规则**
- API 错误率 > 5%
- 支付成功率 < 95%
- 数据库慢查询 > 10 次/分钟
- 外部服务调用失败率 > 10%
---
## 📊 优先级和时间计划
### 🔥 立即处理(已完成)
- ✅ 为核心金融模块补充单元测试(wallet, order, payment Service 层)
### ⚡ 短期优化(1-2 周)
- **Week 1-2**: 添加 Context 超时控制
- **Week 3-4**: 拆分大文件(listing/payment/chat repository
- **Week 5-6**: 引入接口抽象,降低模块耦合
- **Week 7-8**: 补充数据库索引,优化慢查询
### 🎯 中期改进(1-2 个月)
- **Week 9**: 添加 API 限流和熔断机制
- **Week 10**: 统一前端错误处理
- **Week 11-12**: 补充 Repository 层集成测试
- **Week 13-14**: 补充前端组件测试
- **Week 15-16**: 添加监控和告警系统
### 🌟 长期目标(3-6 个月)
- 建立 CI/CD 测试流程
- 测试覆盖率达到 70%+
- 完善技术文档
- 性能优化(P95 响应时间 < 200ms
---
## 📈 成功指标
### 代码质量
- [ ] 测试覆盖率 ≥ 60%(核心模块 ≥ 70%)
- [ ] 平均文件行数 < 150 行
- [ ] 代码重复率 < 5%
### 性能指标
- [ ] API P95 响应时间 < 200ms
- [ ] API P99 响应时间 < 500ms
- [ ] 数据库慢查询 < 5 次/分钟
### 可靠性指标
- [ ] API 可用性 > 99.9%
- [ ] 错误率 < 0.1%
- [ ] 支付成功率 > 99%
---
## 🎉 已完成的改进
### 2026-06-10
- ✅ 为 `wallet` 模块补充 Service 层单元测试(8 个测试用例)
- ✅ 为 `order` 模块补充 Service 层单元测试(11 个测试用例)
- ✅ 为 `payment` 模块补充 Service 层单元测试(10 个测试用例)
- ✅ 所有新增测试通过验证
- ✅ 测试覆盖率基线建立:
- wallet: 11.0%
- order: 7.7%
- payment: 8.9%
---
## 📝 备注
- 本文档是活文档,随着项目演进持续更新
- 每完成一项改进,更新进度标记(✅)
- 定期回顾(每 2 周),调整优先级
**文档维护者**: Claude Code
**最后更新**: 2026-06-10