Files
hfb_sys/docs/PROJECT_ANALYSIS.md
T
yml2213andClaude Opus 4.7 4ebf7f75fe refactor: 统一全项目金额精度为角(0.1元)
## 变更概述
将全项目金额处理从整元四舍五入统一为角精度(0.1元),提高金额计算准确性和显示一致性。

## 后端改动
- 新增 pkg/money/format.go 统一金额处理包
  - Round(): 角精度四舍五入
  - Min/Max(): 金额比较
  - Format(): 格式化字符串
- 更新业务模块使用统一金额函数
  - internal/modules/order: 订单结算改为角精度
  - internal/modules/dispute: 纠纷金额处理
  - internal/modules/listing: 商品定价和存储
- 更新测试用例期望值为角精度

## 前端改动
- 新增 shared/utils/money.ts 金额工具函数
  - roundMoney(): 角精度四舍五入
  - formatMoney(): 格式化为字符串(保留1位小数)
  - formatMoneyWithSymbol(): 添加¥符号
- 更新金额计算和显示逻辑
  - shared/utils/pricing.ts: 定价计算
  - shared/utils/listingDisplay.ts: 商品显示
  - shared/composables/useMoney.ts: 组合式函数
- 修复视图文件导入声明
  - features/listings/views: 商品详情页
  - features/seller/views: 卖家管理页

## 效果
- 金额显示:¥123.0(统一保留1位小数)
- 计算精度:12.45 -> 12.5(角精度)
- 减少误差:避免整元四舍五入损失
- 显示一致:全项目统一格式

## 测试
-  后端单元测试通过
-  TypeScript 类型检查通过
-  开发环境正常运行

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-04 16:42:49 +08:00

473 lines
13 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 租号平台项目分析报告
生成时间:2026-06-04
## 项目概况
**项目定位**:《三角洲行动》游戏账号租赁平台,面向 C2C 租号场景
**技术栈**Go + Gin + GORM + MySQL + Redis / Vue 3 + TypeScript + Vite + Element Plus
**代码规模**
- 后端:~18,000 行 Go 代码,121 个文件
- 前端:~32,000 行 TypeScript/Vue 代码,158 个文件
- 测试覆盖:后端 5 个测试文件(覆盖率极低)
- 最近活跃度:近两周 179 次提交(开发活跃)
**架构特点**
- 前后端分离,RESTful API 设计
- 模块化设计(19 个业务模块)
- Docker Compose 本地开发环境
- 支持 Mock 和真实服务切换
---
## 一、优势亮点 ✅
### 1.1 架构设计合理
- **清晰的模块化**:按业务领域拆分(auth、listing、order、wallet、dispute 等),职责清晰
- **三层架构**Repository → Service → Handler 分层明确
- **依赖注入**:通过构造函数注入,便于测试和扩展
- **中间件设计**request_id、logger、recovery、auth、permission 等职责分离
### 1.2 工程化完善
- **一键启动脚本**`./scripts/dev.sh` 自动化所有启动流程
- **健康检查机制**Docker 容器和 HTTP 服务都有完善的健康检查
- **日志管理**:使用 Zap 结构化日志,支持按天切分
- **配置管理**:支持环境变量和 .env 文件,开发/生产环境隔离
- **数据库迁移**:自动检测并执行 SQL 迁移脚本
### 1.3 业务功能完整
- 核心交易流程:发布 → 审核 → 下单 → 交接 → 归还 → 结算
- 风控体系:实名认证、信用分、冻结机制
- 纠纷处理:申诉仲裁、证据上传、客服介入
- 通知系统:站内信 + 订单群聊
- 后台管理:用户、订单、商品、审核、审计日志
### 1.4 开发体验良好
- **类型安全**:前端 TypeScript 严格模式,后端 Go 强类型
- **组件化**:前端按 features 组织,共享组件复用
- **自动化构建**Vite 热更新 + Docker 多阶段构建优化镜像体积
- **代码整洁**:无 TODO/FIXME 残留,console.log 极少
---
## 二、待优化问题 ⚠️
### 2.1 测试覆盖严重不足 🔴
**现状**
- 后端仅 5 个测试文件,覆盖率不足 5%
- 前端配置了 Vitest 但无测试用例
- 缺少集成测试、E2E 测试
**风险**
- 核心金融逻辑(钱包、订单、押金)无测试保障
- 重构时容易引入 Bug
- 交付质量完全依赖手工测试
**建议**
```
优先级 P0
1. 钱包服务单元测试(余额计算、流水记录、并发安全)
2. 订单状态机测试(状态转换、超时处理)
3. 支付回调测试(幂等性、签名校验)
优先级 P1
4. 实名认证集成测试
5. 权限中间件测试
6. 前端核心流程 E2E 测试(发布-下单-交接)
```
### 2.2 错误处理不一致
**现状**
- 部分模块返回自定义错误(如 `auth.ErrInvalidPhone`
- 部分模块直接返回 `fmt.Errorf`
- 缺少统一的错误码体系
- 前端错误处理分散在各组件
**建议**
```go
// 统一错误定义
package errors
type BizError struct {
Code string // "AUTH_INVALID_PHONE"
Message string // "手机号格式错误"
HTTPCode int // 400
}
// 错误注册表
var (
ErrInvalidPhone = &BizError{"AUTH_INVALID_PHONE", "手机号格式错误", 400}
ErrInsufficientBalance = &BizError{"WALLET_INSUFFICIENT", "余额不足", 400}
// ...
)
// 中间件统一处理
func ErrorHandler() gin.HandlerFunc {
return func(c *gin.Context) {
c.Next()
if len(c.Errors) > 0 {
err := c.Errors.Last().Err
if bizErr, ok := err.(*BizError); ok {
c.JSON(bizErr.HTTPCode, gin.H{"code": bizErr.Code, "message": bizErr.Message})
}
}
}
}
```
### 2.3 性能瓶颈隐患
**问题点**
1. **N+1 查询风险**
```go
// 潜在问题:循环中查询用户信息
for _, order := range orders {
user := getUserByID(order.UserID) // N+1 查询
}
// 优化方案:使用 GORM Preload
db.Preload("Owner").Preload("Renter").Find(&orders)
```
2. **缺少缓存层**
- 系统配置每次查询数据库
- 用户实名状态高频读取无缓存
- 商品列表无 Redis 缓存
3. **Redis 连接未复用**
- 每个请求都创建新连接(检查 `redis.Client` 是否全局单例)
**建议**
```go
// 系统配置缓存
func (s *SystemConfigService) GetConfig(key string) (string, error) {
cacheKey := "config:" + key
val, err := s.redis.Get(ctx, cacheKey).Result()
if err == redis.Nil {
val, err = s.repo.GetConfig(key)
if err == nil {
s.redis.Set(ctx, cacheKey, val, 5*time.Minute)
}
}
return val, err
}
```
### 2.4 安全加固建议
**现状问题**
1. **JWT Secret 弱密钥**
```env
JWT_SECRET=change-me # 开发环境默认值风险
```
2. **缺少 Rate Limiting**
- 登录接口无防暴力破解
- 短信验证码虽有冷却但无 IP 级限流
3. **文件上传安全**
- 虽限制文件类型,但未检测文件内容(MIME 伪造风险)
- 无文件大小限制(潜在 DoS)
4. **SQL 注入风险低但需注意**
- GORM 参数化查询保护较好
- 但存在 `db.Where("status = ?", status)` 手动拼接风险
**建议**
```go
// 1. 强制生产环境强密钥
if cfg.AppEnv == "production" && cfg.JWTSecret == "change-me" {
log.Fatal("生产环境必须设置强 JWT_SECRET")
}
// 2. 添加限流中间件
func RateLimitMiddleware(redis *redis.Client) gin.HandlerFunc {
return func(c *gin.Context) {
key := "rate:" + c.ClientIP() + ":" + c.Request.URL.Path
count, _ := redis.Incr(c, key).Result()
if count == 1 {
redis.Expire(c, key, time.Minute)
}
if count > 100 { // 每分钟 100 次
c.AbortWithStatusJSON(429, gin.H{"error": "请求过于频繁"})
return
}
c.Next()
}
}
// 3. 文件内容检测
func validateFileContent(file []byte, allowedTypes []string) error {
mimeType := http.DetectContentType(file)
for _, allowed := range allowedTypes {
if mimeType == allowed {
return nil
}
}
return errors.New("文件类型不允许")
}
```
### 2.5 数据库设计可优化
**问题点**
1. **索引缺失**
```sql
-- 缺少复合索引
SELECT * FROM rental_orders
WHERE renter_id = ? AND status = ?
ORDER BY created_at DESC;
-- 建议添加:KEY idx_orders_renter_status_time (renter_id, status, created_at)
```
2. **JSON 字段查询效率低**
```sql
-- asset_summary、season_tags 使用 JSON 存储
-- 如需频繁按标签查询,建议改为关联表
CREATE TABLE listing_tags (
listing_id BIGINT,
tag_type VARCHAR(32),
tag_value VARCHAR(64),
INDEX(listing_id),
INDEX(tag_type, tag_value)
);
```
3. **大字段分离不足**
- `description TEXT` 与主查询字段混在一起
- 建议分离到 `listing_details` 表
**建议**
```sql
-- 优化热点查询索引
ALTER TABLE rental_orders
ADD INDEX idx_orders_renter_status_time (renter_id, status, created_at);
ALTER TABLE rental_orders
ADD INDEX idx_orders_owner_status_time (owner_id, status, created_at);
-- 钱包流水查询优化
ALTER TABLE wallet_ledger
ADD INDEX idx_ledger_user_time (user_id, created_at DESC);
```
### 2.6 前端优化空间
**问题点**
1. **代码分割可优化**
- 虽有 `manualChunks`,但 Element Plus 和 Vant 同时使用导致体积臃肿
- 建议按桌面/移动端路由懒加载
2. **API 调用缺少取消机制**
```typescript
// 问题:用户快速切换页面时,旧请求未取消
const fetchData = async () => {
const data = await api.get('/listings');
}
// 建议:使用 AbortController
const controller = new AbortController();
const data = await api.get('/listings', { signal: controller.signal });
onUnmounted(() => controller.abort());
```
3. **状态管理可简化**
- 部分简单状态用 Pinia 过度设计
- 可用 `provide/inject` 或 `localStorage` 简化
4. **TypeScript `any` 残留**
- 虽然很少(1 处),但建议完全消除
**建议**
```typescript
// 1. 路由懒加载 + 预加载
const routes = [
{
path: '/admin',
component: () => import('@/layouts/AdminLayout.vue'),
children: [
{
path: 'users',
component: () => import('@/features/admin/views/UsersView.vue'),
}
]
}
];
// 2. API 取消封装
export const useCancelableRequest = () => {
const controller = ref(new AbortController());
onUnmounted(() => controller.value.abort());
const request = async (url: string, options = {}) => {
return axios.get(url, {
...options,
signal: controller.value.signal
});
};
return { request };
};
```
### 2.7 监控和运维缺失 🔴
**现状**
- 无性能监控(APM
- 无错误追踪(Sentry
- 无业务指标监控(Prometheus + Grafana
- 日志仅存储本地,无集中采集
**建议**
```yaml
# docker-compose.prod.yml 添加监控栈
services:
prometheus:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
grafana:
image: grafana/grafana
ports:
- "3000:3000"
loki:
image: grafana/loki
promtail:
image: grafana/promtail
volumes:
- ./backend/logs:/logs
- ./promtail.yml:/etc/promtail/config.yml
```
```go
// 后端添加 Prometheus 指标
import "github.com/prometheus/client_golang/prometheus"
var (
httpRequestDuration = prometheus.NewHistogramVec(...)
orderCreated = prometheus.NewCounterVec(...)
walletBalance = prometheus.NewGaugeVec(...)
)
```
### 2.8 文档维护问题
**现状**
- API 文档手动维护(`docs/api.md`),易过期
- 缺少 Swagger/OpenAPI 自动生成
- 缺少架构图、流程图
- 开发规范未文档化
**建议**
```go
// 使用 swaggo 自动生成 API 文档
// @title HFB 租号平台 API
// @version 1.0
// @host localhost:8080
// @BasePath /api
// @Summary 发送登录验证码
// @Tags 认证
// @Param phone body string true "手机号"
// @Success 200 {object} response.Success
// @Router /auth/send-code [post]
func (h *Handler) SendCode(c *gin.Context) { ... }
// 启动时访问 /swagger/index.html
```
---
## 三、优化优先级建议
### P0 - 立即修复(影响生产安全)
1. **补充核心业务单元测试**(钱包、订单、支付)
2. **生产环境安全加固**(强密钥、限流、文件校验)
3. **添加监控告警**(至少日志采集 + 错误告警)
4. **数据库热点索引优化**
### P1 - 近期优化(提升质量)
5. **统一错误处理体系**
6. **系统配置缓存层**
7. **N+1 查询优化**
8. **前端代码分割优化**
9. **API 文档自动化**
### P2 - 长期改进(提升体验)
10. **引入 APM 性能监控**
11. **前端错误边界和离线缓存**
12. **数据库读写分离(如果流量增长)**
13. **CI/CD 流水线完善**
---
## 四、技术债务清单
| 类别 | 问题 | 影响 | 工作量估算 |
|------|------|------|-----------|
| 测试 | 缺少单元测试 | 高 | 3-5 人天 |
| 安全 | 限流机制缺失 | 高 | 1 人天 |
| 性能 | 缺少缓存层 | 中 | 2 人天 |
| 监控 | 无 APM 和告警 | 高 | 3 人天 |
| 文档 | API 文档手动维护 | 低 | 1 人天 |
| 数据库 | 索引优化 | 中 | 0.5 人天 |
**总估算**10-15 人天可完成 P0+P1 优化
---
## 五、架构演进建议
### 5.1 短期(3 个月内)
- 完善测试覆盖到 60%+
- 接入 Sentry 错误追踪
- 添加 Redis 缓存层
- 补充核心业务监控指标
### 5.2 中期(6-12 个月)
- 考虑微服务拆分(订单服务独立)
- 引入消息队列(RabbitMQ/Kafka)处理异步任务
- 实施数据库分库分表(按用户 ID 哈希)
- WebSocket 优化为独立长连接服务
### 5.3 长期(1 年以上)
- 多租户改造(支持多游戏品类)
- 智能定价和反欺诈模型
- 区块链存证(订单不可篡改)
- 海外市场国际化
---
## 六、总结
**整体评价**:⭐⭐⭐⭐☆ (4/5)
这是一个**架构清晰、工程化良好**的商业项目,核心业务逻辑完整,代码质量整体优秀。主要短板在**测试覆盖和监控体系**,这在快速迭代期可以理解,但在生产上线前必须补齐。
**最紧迫的 3 件事**
1. 补充核心金融逻辑单元测试
2. 生产环境安全加固(限流 + 强密钥 + 文件校验)
3. 接入基础监控(日志采集 + 错误告警)
完成这 3 项后,项目就具备了生产级可靠性。后续可按优先级逐步优化性能和体验。
---
**分析人**Claude Code
**项目规模**:中型(5 万行代码)
**技术栈成熟度**:高(Go + Vue 主流栈)
**团队建议规模**:3-5 人(2 后端 + 2 前端 + 1 测试/运维)