删除无用文档

This commit is contained in:
yml
2026-06-09 22:38:35 +08:00
parent 3bbe356c3f
commit 5a7f2deff3
21 changed files with 19 additions and 5867 deletions
+4 -2
View File
@@ -27,10 +27,12 @@
```bash
docker compose -f deploy/docker-compose.dev.yml up -d
docker exec -i hfb-mysql mysql -uhfb -psecret hfb_sys < backend/migrations/000001_init.sql
cd backend
cp .env.example .env
go run github.com/pressly/goose/v3/cmd/goose@v3.27.1 \
-dir migrations \
mysql 'hfb:secret@tcp(127.0.0.1:3306)/hfb_sys?charset=utf8mb4&parseTime=True&loc=Local&multiStatements=true' \
up
go run ./cmd/api
cd ../frontend
+11 -4
View File
@@ -67,13 +67,20 @@ backend/logs/app-YYYY-MM-DD.log
docker compose -f deploy/docker-compose.prod.yml up -d --build
```
## 4. 手动初始化数据库
## 4. 手动执行数据库迁移
将命令中的 `change-hfb-password` 替换为 `backend/.env` 里的 `MYSQL_PASSWORD`
通常直接使用一键部署脚本即可。确实需要手动迁移时,使用后端镜像内置的 goose:
```bash
docker compose -f deploy/docker-compose.prod.yml exec -T mysql \
mysql -uhfb -pchange-hfb-password hfb_sys < backend/migrations/000001_init.sql
MYSQL_DSN="$(awk -F= '$1=="MYSQL_DSN"{sub(/^[^=]*=/,""); print; exit}' backend/.env)"
case "$MYSQL_DSN" in
*multiStatements=*) GOOSE_DSN="$MYSQL_DSN" ;;
*\?*) GOOSE_DSN="${MYSQL_DSN}&multiStatements=true" ;;
*) GOOSE_DSN="${MYSQL_DSN}?multiStatements=true" ;;
esac
docker compose -f deploy/docker-compose.prod.yml run --rm --no-deps backend \
/app/goose -dir /app/migrations mysql "$GOOSE_DSN" up
```
## 5. 验证
-922
View File
@@ -1,922 +0,0 @@
# HFB Sys 项目优化计划
> 生成时间: 2026-06-05
> 最后更新: 2026-06-05
> 项目版本: refactor/features-architecture 分支
## 优化进度总览
- 🟢 已完成: 4 项
- 🟡 进行中: 0 项
- ⚪ 待处理: 9 项
**已完成**:
- ✅ 前端统一请求封装优化 (2026-06-05)
- ✅ 路由守卫性能优化 (2026-06-05)
- ✅ 数据库索引优化 (2026-06-05)
- ✅ Swagger API 文档集成 (2026-06-05)
## 项目概况
**项目名称**: HFB Sys - 哈夫币租号平台
**技术栈**:
- 后端: Go 1.26 + Gin + GORM + MySQL 8.4 + Redis 7.4
- 前端: Vue 3 + TypeScript + Vite + Element Plus + Vant
- 基础设施: Docker Compose + MinIO
**代码规模**:
- 后端: 120个Go文件, ~18,625行代码, 21个业务模块
- 前端: 69个Vue组件, ~34,750行代码, 10个功能模块
- 测试覆盖: 仅5个测试文件 (覆盖率极低 ⚠️)
- 依赖包: 185MB node_modules
---
## 🔴 高优先级问题 (立即处理)
### 1. 测试覆盖率严重不足
**问题描述**:
- 整个项目只有5个测试文件 (`backend/internal/modules/order/repository_test.go` 等)
- 核心业务逻辑(订单、钱包、支付)缺少单元测试
- 前端组件完全没有测试
**影响范围**:
- 代码质量无法保证
- 重构和功能迭代风险高
- 无法及时发现回归问题
- 金额计算、订单状态流转等关键逻辑缺少验证
**解决方案**:
#### 后端测试
```go
// 示例: backend/internal/modules/wallet/service_test.go
package wallet_test
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
func TestWalletService_Deduct(t *testing.T) {
// 测试余额扣减
// 测试余额不足情况
// 测试并发扣减
}
```
#### 前端测试
```typescript
// 示例: frontend/src/features/orders/__tests__/OrderList.spec.ts
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import OrderList from '../views/OrderList.vue'
describe('OrderList', () => {
it('renders order items correctly', () => {
// 测试订单列表渲染
})
})
```
**目标**:
- [ ] 核心模块测试覆盖率达到 70%
- [ ] 订单模块: 状态流转、金额计算、超时处理
- [ ] 钱包模块: 余额操作、并发控制、流水记录
- [ ] 支付模块: 支付回调、退款流程
- [ ] 前端核心组件测试覆盖率 50%+
**工具选择**:
- 后端: Go `testing` + `testify` + `mockery`
- 前端: `vitest` + `@vue/test-utils`
---
### 2. ✅ 数据库索引优化(已完成 2026-06-05
**原问题描述**:
- 迁移文件 `backend/migrations/000001_init.sql` 中缺少针对高频复合查询的覆盖索引
- 时间范围查询缺少优化
- 订单列表查询、钱包流水查询性能不佳
**已完成的优化**:
#### 新增 5 个复合索引
1. **订单状态+创建时间索引** (`idx_rental_orders_status_created_at`)
- 优化订单列表查询性能
- 预计性能提升 90%
2. **钱包流水按用户+业务类型+时间索引** (`idx_wallet_ledger_user_biz_created`)
- 优化按业务类型筛选流水
- 预计性能提升 90%
3. **订单结算状态索引** (`idx_rental_orders_settlement`)
- 优化结算任务查询
- 支持财务报表生成
4. **商品发布时间索引** (`idx_rental_listings_published`)
- 优化首页商品列表
- 预计性能提升 90%
5. **用户实名认证状态索引** (`idx_users_realname_status`)
- 优化用户统计查询
- 支持后台用户管理
**相关文件**:
- `backend/migrations/000003_add_indexes.sql` - 索引迁移文件
- `backend/migrations/test_index_performance.sql` - 性能测试脚本
- `docs/DATABASE_INDEX_OPTIMIZATION.md` - 详细分析文档
**性能提升预估**:
- 订单列表查询: 500ms → 50ms (减少 90%)
- 钱包流水查询: 300ms → 30ms (减少 90%)
- 商品列表查询: 200ms → 20ms (减少 90%)
- 磁盘空间增加: ~3.1MB (可忽略)
**执行建议**:
- ✅ 在开发环境测试通过
- ⚠️ 生产环境需在低峰期执行
- ⚠️ 逐个表创建索引,监控系统负载
- ⚠️ 执行前备份数据库
---
### 原计划内容(已废弃)
- [ ] 创建新的迁移文件 `000003_add_indexes.sql`
- [ ] 在开发环境验证查询性能提升
- [ ] 使用 `EXPLAIN` 分析慢查询
- [ ] 生产环境灰度添加索引
**监控指标**:
- 慢查询日志 (>100ms)
- 索引命中率
- 查询平均响应时间
---
### 3. 环境变量管理不规范
**问题描述**:
- `.env.example` 包含40个环境变量
- JWT_SECRET 默认值为 "change-me" (安全隐患)
- 配置分散在多个文件中
- 缺少配置校验
**影响范围**:
- 生产环境可能使用不安全的默认值
- 配置错误难以发现
- 缺少环境差异化配置管理
**解决方案**:
#### 1. 使用 Viper 进行配置管理
```go
// backend/internal/config/config.go
package config
import (
"github.com/spf13/viper"
)
type Config struct {
App AppConfig
Database DatabaseConfig
JWT JWTConfig
// ...
}
func Load() (*Config, error) {
viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AddConfigPath("./configs")
viper.AutomaticEnv()
// 配置校验
if err := viper.ReadInConfig(); err != nil {
return nil, err
}
var cfg Config
if err := viper.Unmarshal(&cfg); err != nil {
return nil, err
}
// 安全配置强制校验
if cfg.App.Env == "production" {
if cfg.JWT.Secret == "change-me" || len(cfg.JWT.Secret) < 32 {
return nil, errors.New("production JWT secret must be set and >= 32 chars")
}
}
return &cfg, nil
}
```
#### 2. 配置文件分层
```
backend/configs/
├── config.yaml # 默认配置
├── config.dev.yaml # 开发环境覆盖
├── config.prod.yaml # 生产环境覆盖
└── config.local.yaml # 本地开发 (git ignore)
```
#### 3. 使用密钥管理服务
```yaml
# 生产环境使用 Vault / AWS Secrets Manager
jwt:
secret: ${VAULT_JWT_SECRET}
database:
password: ${VAULT_DB_PASSWORD}
```
**执行计划**:
- [ ] 安装 Viper: `go get github.com/spf13/viper`
- [ ] 重构 `internal/config`
- [ ] 迁移环境变量到 YAML 配置
- [ ] 添加配置校验逻辑
- [ ] 更新文档和部署脚本
---
### 4. ✅ 前端 HTTP 请求封装优化(已完成 2026-06-05
**原问题描述**:
- apiClient 缺少日志记录和性能监控
- 缺少类型安全的辅助函数
- 错误处理可以进一步增强
**已完成的优化**:
#### 1. 增强的日志记录和监控
- ✅ 开发环境自动记录请求/响应日志
- ✅ 记录请求耗时
- ✅ 慢请求自动警告(>1s
- ✅ 错误日志详细记录
#### 2. 性能监控系统
- ✅ 创建 `apiMonitor` 工具
- ✅ 记录所有请求的性能指标
- ✅ 支持查看平均响应时间、成功率
- ✅ 支持查看最慢的请求
- ✅ 支持按 URL 分组统计
- ✅ 开发环境下通过 `__apiMonitor.printReport()` 查看报告
#### 3. 类型安全的辅助函数
- ✅ 创建 `api` 对象,提供简洁的 API 调用方式
-`api.get<T>(url)` - GET 请求
-`api.post<T>(url, data)` - POST 请求
-`api.put<T>(url, data)` - PUT 请求
-`api.delete<T>(url)` - DELETE 请求
-`api.patch<T>(url, data)` - PATCH 请求
-`api.silent()` - 静默请求
-`api.retry()` - 带重试的请求
-`api.concurrent()` - 并发请求
-`api.sequential()` - 串行请求
#### 4. 增强的错误处理
- ✅ 新增 `skipErrorHandler` 配置项
- ✅ 支持跳过自动错误提示
- ✅ 保持原有 `silent` 参数功能
#### 5. 改进的超时配置
- ✅ 默认超时从 10s 增加到 30s,避免大文件上传超时
- ✅ 支持单个请求自定义超时时间
#### 6. 完整的使用文档
- ✅ 创建 `docs/API_OPTIMIZATION_GUIDE.md`
- ✅ 包含使用示例、最佳实践、故障排查
**相关文件**:
- `frontend/src/shared/api/client.ts` - 增强的 apiClient
- `frontend/src/shared/api/helpers.ts` - 类型安全辅助函数
- `frontend/src/shared/api/monitor.ts` - 性能监控工具
- `frontend/src/shared/api/index.ts` - 统一导出
- `docs/API_OPTIMIZATION_GUIDE.md` - 使用指南
**向后兼容**:
- ✅ 完全兼容现有代码,无需修改
- ✅ 新功能为可选增强,不影响现有功能
---
### 原计划内容(已废弃)
**问题描述**:
- 未找到 `frontend/src/utils/request.ts` 文件
- axios 直接在各个 API 文件中使用
- Token 刷新、错误处理逻辑可能分散
- 缺少统一的 Loading 状态管理
**影响范围**:
- Token 过期处理不一致
- 错误提示用户体验差
- 重复代码多
- 难以统一添加日志、监控
**解决方案**:
```typescript
// frontend/src/utils/request.ts
import axios, { AxiosError, AxiosRequestConfig } from 'axios'
import { ElMessage } from 'element-plus'
import { useSessionStore } from '@/stores/session'
import { getAccessToken, getRefreshToken, setAuthTokens } from '@/utils/authStorage'
// 创建 axios 实例
const request = axios.create({
baseURL: '/api',
timeout: 30000,
})
// 请求拦截器
request.interceptors.request.use(
(config) => {
// 自动添加 Token
const token = getAccessToken('user')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
},
(error) => {
return Promise.reject(error)
}
)
// 响应拦截器
let isRefreshing = false
let refreshSubscribers: Array<(token: string) => void> = []
request.interceptors.response.use(
(response) => {
return response.data
},
async (error: AxiosError) => {
const originalRequest = error.config as AxiosRequestConfig & { _retry?: boolean }
// Token 过期,尝试刷新
if (error.response?.status === 401 && !originalRequest._retry) {
if (isRefreshing) {
// 等待 Token 刷新完成
return new Promise((resolve) => {
refreshSubscribers.push((token: string) => {
if (originalRequest.headers) {
originalRequest.headers.Authorization = `Bearer ${token}`
}
resolve(request(originalRequest))
})
})
}
originalRequest._retry = true
isRefreshing = true
try {
const refreshToken = getRefreshToken('user')
if (!refreshToken) {
throw new Error('No refresh token')
}
// 调用刷新接口
const { data } = await axios.post('/api/auth/refresh', {
refresh_token: refreshToken,
})
setAuthTokens('user', {
access_token: data.access_token,
refresh_token: data.refresh_token,
})
// 通知所有等待的请求
refreshSubscribers.forEach((callback) => callback(data.access_token))
refreshSubscribers = []
// 重试原请求
if (originalRequest.headers) {
originalRequest.headers.Authorization = `Bearer ${data.access_token}`
}
return request(originalRequest)
} catch (refreshError) {
// 刷新失败,跳转登录
const session = useSessionStore()
session.logout()
window.location.href = '/login'
return Promise.reject(refreshError)
} finally {
isRefreshing = false
}
}
// 统一错误处理
const message = error.response?.data?.message || error.message || '请求失败'
ElMessage.error(message)
return Promise.reject(error)
}
)
export default request
```
**使用方式**:
```typescript
// frontend/src/features/orders/api/orders.ts
import request from '@/utils/request'
export const fetchOrders = (params: any) => {
return request.get('/orders', { params })
}
```
**执行计划**:
- [ ] 创建 `frontend/src/utils/request.ts`
- [ ] 重构所有 API 调用使用统一封装
- [ ] 实现 Token 刷新机制
- [ ] 添加请求/响应日志
- [ ] 测试 Token 过期场景
---
## 🟠 中优先级改进 (近期处理)
### 5. ✅ 路由守卫性能优化(已完成 2026-06-05
**原问题**: `frontend/src/router/index.ts``beforeEach` 在每次导航时都可能重复调用 `session.loadMe()`
**已完成的优化**:
#### 1. 添加加载状态标志
- ✅ 在 `sessionStore` 中添加 `_loadingMe` 标志
- ✅ 防止并发调用 `loadMe()`
- ✅ 如果正在加载,等待完成而不是重复请求
#### 2. 优化加载逻辑
- ✅ 只有当 `phone` 为空时才调用 `loadMe()`
- ✅ 避免每次路由跳转都发起请求
- ✅ 减少不必要的 API 调用
#### 3. 改进实名认证检查
- ✅ 优化实名状态检查逻辑
- ✅ 只在必要时重新加载用户信息
- ✅ 减少重复检查
**性能提升**:
- 🚀 路由跳转时的 API 请求减少约 70%
- 🚀 页面切换更快速
- 🚀 减轻后端服务器压力
**相关文件**:
- `frontend/src/stores/session.ts` - 添加加载标志和防重复逻辑
- `frontend/src/router/index.ts` - 优化路由守卫逻辑
**向后兼容**:
- ✅ 完全兼容现有功能
- ✅ 用户体验无影响,只是性能提升
---
### 原计划内容(已废弃)
### 6. 前端组件复用性不足
**现状**:
- `frontend/src/components/` 仅有2个共享组件
- `frontend/src/shared/composables/` 仅有4个组合式函数
- 许多页面可能存在重复的 UI 逻辑
**建议提取的通用组件**:
- [ ] `StatusTag.vue` - 状态标签
- [ ] `DateRangePicker.vue` - 日期范围选择
- [ ] `EmptyState.vue` - 空状态占位
- [ ] `LoadingOverlay.vue` - 加载遮罩
- [ ] `ImageUpload.vue` - 图片上传
- [ ] `MoneyDisplay.vue` - 金额展示
- [ ] `OrderStatusFlow.vue` - 订单状态流程
**建议提取的 Composables**:
- [ ] `useTable.ts` - 表格分页、排序
- [ ] `useForm.ts` - 表单验证、提交
- [ ] `useModal.ts` - 弹窗状态管理
- [ ] `usePermission.ts` - 权限判断
- [ ] `useWebSocket.ts` - WebSocket 连接
---
### 7. 后端路由初始化代码过长
**问题**: `backend/internal/router/router.go` 文件415行,所有依赖注入在一个 `New` 函数中
**重构方案**:
#### 方案一: 模块化路由注册
```go
// backend/internal/router/router.go
func New(cfg config.Config, deps Dependencies, logger *zap.Logger) *gin.Engine {
engine := gin.New()
engine.Use(middleware.RequestID())
engine.Use(middleware.RequestLogger(logger))
engine.Use(middleware.Recovery(logger))
// 初始化依赖
services := initServices(cfg, deps, logger)
// 注册路由
api := engine.Group("/api")
registerAuthRoutes(api, services.auth)
registerUserRoutes(api, services.user, services.auth.JWTManager)
registerOrderRoutes(api, services.order, services.auth.JWTManager)
// ...
return engine
}
// backend/internal/router/auth_routes.go
func registerAuthRoutes(api *gin.RouterGroup, authSvc *auth.Service) {
authHandler := auth.NewHandler(authSvc)
authRoutes := api.Group("/auth")
{
authRoutes.POST("/sms/send", authHandler.SendSMS)
authRoutes.POST("/sms/login", authHandler.Login)
authRoutes.POST("/refresh", authHandler.Refresh)
authRoutes.POST("/logout", authHandler.Logout)
}
}
```
#### 方案二: 使用依赖注入容器 (Wire)
```go
// backend/internal/wire/wire.go
//go:build wireinject
// +build wireinject
package wire
import (
"github.com/google/wire"
"hfb_sys/backend/internal/router"
)
func InitializeApp(cfg config.Config) (*gin.Engine, error) {
wire.Build(
provideDB,
provideRedis,
auth.NewJWTManager,
auth.NewService,
order.NewService,
router.New,
)
return nil, nil
}
```
---
### 8. ✅ Swagger API 文档集成(已完成 2026-06-05
**原问题**: 缺少 API 文档自动化,团队协作和前后端对接效率低
**已完成的工作**:
#### 1. 安装 Swagger 依赖
-`github.com/swaggo/swag` - Swagger 文档生成工具
-`github.com/swaggo/gin-swagger` - Gin 框架集成
-`github.com/swaggo/files` - 静态文件服务
#### 2. 添加 API 通用信息
`cmd/api/main.go` 中添加:
- API 标题、版本、描述
- 联系方式和许可证
- 认证方式(Bearer Token
#### 3. 为 Handler 添加 Swagger 注释
示例:`internal/modules/auth/handler.go`
- ✅ SendSMS - 发送短信验证码
- ✅ Login - 短信验证码登录
- ✅ Refresh - 刷新访问令牌
- ✅ Logout - 登出
#### 4. 集成 Swagger UI 路由
`internal/router/router.go` 中添加:
- 路由: `GET /swagger/*any`
- 仅在非生产环境启用
- 支持交互式 API 测试
#### 5. 生成文档文件
-`docs/docs.go` - Go 代码
-`docs/swagger.json` - JSON 格式
-`docs/swagger.yaml` - YAML 格式
**使用方式**:
1. **查看文档**:
启动服务后访问 `http://localhost:8080/swagger/index.html`
2. **添加新接口文档**:
在 handler 函数上方添加注释:
```go
// @Summary 接口摘要
// @Description 详细描述
// @Tags 标签
// @Accept json
// @Produce json
// @Param name type dataType required "说明"
// @Success 200 {object} response.Body
// @Router /path [method]
```
3. **重新生成文档**:
```bash
swag init -g cmd/api/main.go -o docs --parseDependency --parseInternal
```
**效果**:
- 📚 自动生成交互式 API 文档
- 🧪 支持在线测试 API
- 👥 提升团队协作效率
- 📝 文档与代码同步
**后续工作**:
- [ ] 为其他模块(订单、钱包、商品等)添加 Swagger 注释
- [ ] 添加请求/响应示例
- [ ] 完善错误码说明
---
### 原计划内容(已废弃)
## 🟢 低优先级优化 (持续改进)
### 9. 前端构建优化
```typescript
// frontend/vite.config.ts 优化
import { visualizer } from 'rollup-plugin-visualizer'
import viteCompression from 'vite-plugin-compression'
export default defineConfig({
plugins: [
vue(),
// Gzip 压缩
viteCompression({
algorithm: 'gzip',
ext: '.gz',
}),
// Brotli 压缩
viteCompression({
algorithm: 'brotliCompress',
ext: '.br',
}),
// 构建分析
visualizer({
open: true,
filename: 'dist/stats.html',
}),
],
build: {
// 代码分割优化
rollupOptions: {
output: {
manualChunks: {
'vendor-vue': ['vue', 'vue-router', 'pinia'],
'vendor-element': ['element-plus', '@element-plus/icons-vue'],
'vendor-vant': ['vant'],
'vendor-utils': ['axios', 'qrcode'],
},
},
},
// 启用 CSS 代码分割
cssCodeSplit: true,
// 文件大小限制警告
chunkSizeWarningLimit: 1000,
},
})
```
### 10. 日志和监控增强
#### Prometheus 指标收集
```go
// backend/internal/metrics/metrics.go
import "github.com/prometheus/client_golang/prometheus"
var (
httpRequestsTotal = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "http_requests_total",
Help: "Total HTTP requests",
},
[]string{"method", "path", "status"},
)
httpRequestDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Help: "HTTP request duration",
},
[]string{"method", "path"},
)
)
// 注册中间件
engine.Use(metrics.PrometheusMiddleware())
engine.GET("/metrics", gin.WrapH(promhttp.Handler()))
```
#### 慢查询日志
```go
// backend/internal/database/database.go
import "gorm.io/plugin/dbresolver"
db.Use(&SlowQueryLogger{
SlowThreshold: 100 * time.Millisecond,
Logger: logger,
})
```
### 11. Redis 缓存策略优化
```go
// 示例: 系统配置缓存
func (r *Repository) GetConfig(key string) (*model.SystemConfig, error) {
// 1. 查询缓存
cacheKey := fmt.Sprintf("config:%s", key)
cached, err := r.redis.Get(ctx, cacheKey).Result()
if err == nil {
var config model.SystemConfig
json.Unmarshal([]byte(cached), &config)
return &config, nil
}
// 2. 缓存未命中,查询数据库
var config model.SystemConfig
if err := r.db.Where("key = ?", key).First(&config).Error; err != nil {
return nil, err
}
// 3. 写入缓存 (5分钟过期)
data, _ := json.Marshal(config)
r.redis.Set(ctx, cacheKey, data, 5*time.Minute)
return &config, nil
}
```
### 12. 代码质量工具集成
#### 后端 golangci-lint
```yaml
# backend/.golangci.yml
linters:
enable:
- gofmt
- govet
- errcheck
- staticcheck
- gosimple
- ineffassign
- unused
- misspell
- gocyclo
```
#### 前端 ESLint + Prettier
```json
// frontend/.eslintrc.json
{
"extends": [
"plugin:vue/vue3-recommended",
"@vue/typescript/recommended",
"prettier"
],
"rules": {
"vue/multi-word-component-names": "off",
"@typescript-eslint/no-explicit-any": "warn"
}
}
```
#### Pre-commit hooks
```json
// package.json
{
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.{ts,vue}": ["eslint --fix", "prettier --write"],
"*.go": ["gofmt -w", "golangci-lint run"]
}
}
```
### 13. Docker 镜像优化
```dockerfile
# backend/Dockerfile (多阶段构建)
FROM golang:1.26-alpine AS builder
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o api ./cmd/api
FROM alpine:latest
RUN apk --no-cache add ca-certificates tzdata
WORKDIR /app
COPY --from=builder /app/api .
EXPOSE 8080
CMD ["./api"]
```
```dockerfile
# frontend/Dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
```
---
## 📅 实施计划
### 第一周 (基础设施)
- [ ] 周一-周二: 为 order、wallet、payment 模块添加单元测试
- [ ] 周三: 创建数据库索引迁移文件并测试
- [ ] 周四: 创建前端统一请求封装 `request.ts`
- [ ] 周五: 重构现有 API 调用使用新封装
### 第二周 (工具集成)
- [ ] 周一: 集成 Swagger API 文档
- [ ] 周二: 配置 golangci-lint 和 ESLint
- [ ] 周三: 添加 pre-commit hooks
- [ ] 周四-周五: 优化路由守卫和路由初始化代码
### 第三周 (性能优化)
- [ ] 周一-周二: 实现 Redis 缓存策略
- [ ] 周三: 添加 Prometheus 监控
- [ ] 周四: Docker 镜像优化
- [ ] 周五: 前端构建优化和测试
### 第四周 (测试和发布)
- [ ] 周一-周三: 补充测试用例,达到覆盖率目标
- [ ] 周四: 性能测试和压力测试
- [ ] 周五: 文档更新,代码审查
---
## 📊 成功指标
### 代码质量
- [ ] 核心模块测试覆盖率 ≥ 70%
- [ ] golangci-lint 检查通过
- [ ] 前端 ESLint 检查通过
- [ ] 0 个 TODO/FIXME 注释
### 性能指标
- [ ] API 平均响应时间 < 100ms (P95)
- [ ] 数据库慢查询 < 10 条/天
- [ ] 前端首屏加载时间 < 2s
- [ ] 缓存命中率 > 80%
### 安全性
- [ ] 生产环境所有默认密码已更改
- [ ] JWT Secret 长度 ≥ 32 字符
- [ ] 所有敏感信息使用密钥管理服务
- [ ] 通过安全扫描 (Snyk/Trivy)
---
## 附录
### 相关文档
- [项目计划](./project-plan.md)
- [数据库设计](./database.md)
- [API 文档](./api.md)
- [业务规则](./business-rules.md)
### 参考资源
- [Go Testing Best Practices](https://go.dev/doc/tutorial/add-a-test)
- [Vue Test Utils](https://test-utils.vuejs.org/)
- [MySQL Index Design](https://dev.mysql.com/doc/refman/8.0/en/optimization-indexes.html)
- [Viper Configuration](https://github.com/spf13/viper)
---
**最后更新**: 2026-06-05
**负责人**: 待分配
**审核人**: 待分配
-101
View File
@@ -1,101 +0,0 @@
# 公告系统功能说明
## 功能概述
在钱包旁边新增了公告中心功能,用户可以查看平台通知、使用教程、规则说明和常见问题解答。
## 主要特性
### 前台功能(用户端)
- **公告列表页** (`/announcements`)
- 支持按分类筛选(全部、通知公告、使用教程、规则说明、常见问题)
- 显示置顶和重要标记
- 分页浏览
- 点击查看详情
- **公告详情页** (`/announcements/:id`)
- 查看完整公告内容
- 支持富文本显示
- 自动统计浏览次数
### 后台功能(管理端)
- 公告管理 CRUD(创建、编辑、删除)
- 发布/归档公告
- 设置优先级、置顶、重要标记
- 按状态和分类筛选
## 数据库表结构
```sql
CREATE TABLE announcements (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
category VARCHAR(32) NOT NULL DEFAULT 'notice',
priority INT NOT NULL DEFAULT 0,
is_pinned TINYINT(1) NOT NULL DEFAULT 0,
is_important TINYINT(1) NOT NULL DEFAULT 0,
view_count INT NOT NULL DEFAULT 0,
status VARCHAR(32) NOT NULL DEFAULT 'draft',
published_at DATETIME NULL,
created_by BIGINT UNSIGNED NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
```
## API 端点
### 用户端
- `GET /api/announcements` - 获取公告列表
- `GET /api/announcements/:id` - 获取公告详情
### 管理端
- `GET /api/admin/announcements` - 管理员获取公告列表
- `GET /api/admin/announcements/:id` - 管理员获取公告详情
- `POST /api/admin/announcements` - 创建公告
- `PUT /api/admin/announcements/:id` - 更新公告
- `POST /api/admin/announcements/:id/publish` - 发布公告
- `POST /api/admin/announcements/:id/archive` - 归档公告
- `DELETE /api/admin/announcements/:id` - 删除公告
## 权限要求
管理端需要以下权限:
- `announcement:view` - 查看公告
- `announcement:manage` - 管理公告(创建、编辑、发布、归档、删除)
## 前端路由
- `/announcements` - 公告列表
- `/announcements/:id` - 公告详情
## 导航入口
在顶部导航栏"钱包"旁边添加了"公告"入口,用户可以方便地访问公告中心。
## 数据迁移
1. 运行 `000005_add_announcements.sql` 创建表结构
2. 运行 `000006_insert_sample_announcements.sql` 插入示例数据
## 技术实现
### 后端
- 使用 Go + Gin 框架
- GORM 作为 ORM
- 遵循模块化设计(handler -> service -> repository
### 前端
- Vue 3 + TypeScript
- Element Plus UI 组件库
- 响应式设计,支持移动端
## 未来扩展
可以考虑添加:
- 公告搜索功能
- 用户收藏公告
- 评论功能
- 富文本编辑器(管理端)
- 公告推送通知
-142
View File
@@ -1,142 +0,0 @@
## 🔒 彻底杜绝字符编码问题的方案
本文档说明如何在整个技术栈中确保使用 UTF-8 编码,避免出现乱码问题。
### 1. MySQL 服务器配置(已完成 ✅)
**配置文件:** `deploy/mysql/my.cnf`
```ini
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init-connect = 'SET NAMES utf8mb4'
skip-character-set-client-handshake
```
**Docker Compose 配置:** `deploy/docker-compose.prod.yml`
```yaml
mysql:
command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
volumes:
- ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf:ro
```
### 2. 数据库连接字符集(已完成 ✅)
**配置:** `backend/internal/config/config.go`
```go
MySQLDSN: "hfb:secret@tcp(127.0.0.1:3306)/hfb_sys?charset=utf8mb4&parseTime=True&loc=Local"
```
**关键参数:**
- `charset=utf8mb4` - 强制使用 UTF-8 编码
- `parseTime=True` - 正确解析时间类型
- `loc=Local` - 使用本地时区
### 3. 数据库表结构(已完成 ✅)
**迁移文件:** `backend/migrations/*.sql`
```sql
CREATE TABLE table_name (
...
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```
**转换现有表:**
```sql
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
```
### 4. 后端 API 响应头(建议添加)
**在 HTTP 响应中设置:**
```go
w.Header().Set("Content-Type", "application/json; charset=utf-8")
```
### 5. 前端 HTML 元信息(已完成 ✅)
**index.html**
```html
<meta charset="UTF-8">
```
### 6. 文件编辑器配置
**确保所有代码文件使用 UTF-8**
- `.editorconfig` - 统一团队编码
- IDE 设置 - 文件编码为 UTF-8
- Git 设置 - 避免行尾符问题
### 7. 验证检查清单
部署后执行以下命令验证:
```bash
# 1. 检查 MySQL 字符集配置
docker exec -i deploy-mysql-1 mysql -u hfb -p<password> -e "SHOW VARIABLES LIKE 'character%';"
# 2. 检查表字符集
docker exec -i deploy-mysql-1 mysql -u hfb -p<password> hfb_sys -e "SHOW CREATE TABLE announcements\G"
# 3. 验证数据正确性
docker exec -i deploy-mysql-1 mysql -u hfb -p<password> hfb_sys -e "SELECT id, title FROM announcements LIMIT 3;"
```
### 8. 常见问题排查
**问题:数据库中已有乱码数据**
```bash
# 执行修复脚本
docker exec -i deploy-mysql-1 mysql -u hfb -p<password> hfb_sys < backend/migrations/000008_fix_announcement_charset.sql
```
**问题:新插入的数据仍然乱码**
- 检查数据库连接 DSN 是否包含 `charset=utf8mb4`
- 检查 MySQL 配置文件是否生效
- 重启 MySQL 容器使配置生效
**问题:只有某些字段乱码**
```sql
-- 转换特定列
ALTER TABLE table_name MODIFY column_name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
```
### 9. 部署流程
每次部署时确保:
1. ✅ MySQL 配置文件已挂载
2. ✅ 环境变量 MYSQL_DSN 包含 charset 参数
3. ✅ 新建表使用正确的字符集
4. ✅ 迁移脚本指定字符集
### 10. 开发规范
**新建表时必须指定:**
```sql
CREATE TABLE new_table (
...
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='表注释';
```
**修改表时保持一致:**
```sql
ALTER TABLE existing_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
```
---
## 总结
通过以上配置,确保了从数据库服务器 → 连接驱动 → 表结构 → 应用层 → 前端展示的完整链路都使用 UTF-8 编码,彻底杜绝乱码问题。
-193
View File
@@ -1,193 +0,0 @@
# 部署故障排查指南
## SSH 连接断开问题
### 问题现象
执行 `scripts/deploy-prod.sh` 后:
- SSH 连接立即断开
- 无法重新连接服务器
- 服务器可能完全无响应
### 根本原因
**Docker 构建过程耗尽服务器内存,导致系统 OOM (Out of Memory) 崩溃**
#### 技术细节
1. **同时构建多个镜像**:原脚本使用 `docker compose up -d --build` 会并行构建 backend 和 frontend
2. **前端构建超高内存消耗**Node.js/npm 构建过程可能消耗 1-2GB 内存
3. **无资源限制**:所有容器没有 memory limit,可无限制消耗系统资源
4. **连锁反应**
- Docker 构建吃满内存
- Linux OOM Killer 开始杀进程
- SSH daemon 被杀死 → 连接断开
- 系统核心服务被杀 → 无法重连
- 最严重时整个系统死机
### 立即恢复方法
#### 方法 1:物理/远程控制台重启
```bash
# 通过云服务商控制台重启服务器
# 重启后立即禁用 Docker 自动启动
sudo systemctl disable docker
sudo systemctl stop docker
# 清理所有容器
cd /path/to/hfb_sys
docker compose -f deploy/docker-compose.prod.yml down
```
#### 方法 2:强制重启前快速执行
如果还能短暂连接,立即执行:
```bash
sudo systemctl stop docker
sudo killall -9 dockerd containerd
```
### 根本解决方案(已修复)
#### 1. 添加资源限制(docker-compose.prod.yml
所有服务现在都有明确的内存和 CPU 限制:
- MySQL: 512M memory, 1 CPU
- Redis: 256M memory, 0.5 CPU
- MinIO: 512M memory, 0.5 CPU
- Backend: 512M memory, 1 CPU
- Frontend: 256M memory, 0.5 CPU
总计:~2GB 内存(适合 4GB 服务器)
#### 2. 串行构建(deploy-prod.sh
修改后的脚本:
```bash
# 先构建 backend
compose build backend
# 再构建 frontend
compose build frontend
# 最后启动(不再构建)
compose up -d --no-build
```
这样可以避免内存峰值,但会增加 1-2 分钟部署时间。
### 安全部署流程
#### 首次部署
```bash
# 1. 在本地或有充足资源的机器上预构建镜像
docker compose -f deploy/docker-compose.prod.yml build
# 2. 保存镜像
docker save -o backend.tar <image_name>:latest
docker save -o frontend.tar <image_name>:latest
# 3. 上传到服务器
scp *.tar server:/tmp/
# 4. 在服务器上加载
ssh server
docker load -i /tmp/backend.tar
docker load -i /tmp/frontend.tar
# 5. 使用 --no-build 启动
./scripts/deploy-prod.sh --no-build
```
#### 日常更新(推荐)
```bash
# 直接使用修复后的脚本
./scripts/deploy-prod.sh
# 或者只更新不重新构建
./scripts/deploy-prod.sh --no-build
```
### 监控服务器资源
#### 部署前检查
```bash
# 查看可用内存
free -h
# 查看 CPU 负载
uptime
# 建议:至少保留 1GB 可用内存
```
#### 部署中监控
```bash
# 另一个终端实时监控
watch -n 1 'free -h && docker stats --no-stream'
```
### 服务器配置建议
#### 最低配置
- 内存:4GB
- CPU2 核
- 磁盘:20GB
#### 推荐配置
- 内存:8GB
- CPU4 核
- 磁盘:50GB
- 启用 Swap4GB
#### 启用 Swap(紧急缓冲)
```bash
# 创建 4GB swap
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# 永久启用
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
```
### 其他可能原因
#### 1. 网络超时
```bash
# 增加 SSH 保活
# 编辑 ~/.ssh/config
Host your-server
ServerAliveInterval 60
ServerAliveCountMax 3
```
#### 2. Docker daemon 崩溃
```bash
# 查看 Docker 日志
sudo journalctl -u docker -n 100 --no-pager
# 重启 Docker
sudo systemctl restart docker
```
#### 3. 磁盘满
```bash
# 检查磁盘空间
df -h
# 清理 Docker 垃圾
docker system prune -a --volumes -f
```
## 预防措施清单
- [x] 所有服务添加 memory/CPU 限制
- [x] 串行构建避免内存峰值
- [ ] 启用服务器 Swap
- [ ] 部署前检查可用内存
- [ ] 设置 SSH 保活
- [ ] 定期清理 Docker 磁盘
- [ ] 监控部署过程资源使用
## 紧急联系
如果服务器完全无响应:
1. 联系云服务商客服强制重启
2. 通过 VNC/控制台登录
3. 考虑升级服务器配置
-606
View File
@@ -1,606 +0,0 @@
# 压力测试指南
本文档提供完整的压力测试方案,用于评估系统在大数据量和高并发场景下的性能表现。
## 一、测试环境准备
### 1.1 硬件配置建议
**最低配置:**
- CPU: 4核
- 内存: 8GB
- 磁盘: SSD 50GB
**推荐配置:**
- CPU: 8核+
- 内存: 16GB+
- 磁盘: SSD 100GB+
- MySQL: 独立部署,开启慢查询日志
### 1.2 数据库优化配置
`deploy/docker-compose.dev.yml` 中调整 MySQL 配置:
```yaml
services:
mysql:
environment:
- MYSQL_ROOT_PASSWORD=secret
command:
- --max_connections=500
- --innodb_buffer_pool_size=2G
- --innodb_log_file_size=512M
- --slow_query_log=1
- --slow_query_log_file=/var/log/mysql/slow.log
- --long_query_time=0.5
```
### 1.3 后端配置优化
`backend/.env` 中调整:
```bash
# 数据库连接池
DB_MAX_OPEN_CONNS=100
DB_MAX_IDLE_CONNS=20
DB_CONN_MAX_LIFETIME=3600
# Redis配置
REDIS_POOL_SIZE=50
# 日志级别(压测时降低日志输出)
LOG_LEVEL=warn
# Gin模式
APP_ENV=production
```
## 二、生成测试数据
### 2.1 执行数据生成脚本
```bash
# 连接到数据库容器
docker exec -i hfb-mysql mysql -uhfb -psecret hfb_sys < scripts/load_test_data.sql
```
### 2.2 数据规模说明
该脚本会生成:
- **10,000** 个用户(90%已实名)
- **50,000** 个租号商品
- **30,000** 个订单(包含各种状态)
- **100,000** 条钱包流水
- **50,000** 条聊天消息
### 2.3 验证数据生成
```sql
-- 查看数据统计
SELECT '用户数' as item, COUNT(*) as count FROM users
UNION ALL
SELECT '商品数', COUNT(*) FROM rental_listings
UNION ALL
SELECT '订单数', COUNT(*) FROM rental_orders
UNION ALL
SELECT '钱包流水', COUNT(*) FROM wallet_ledger;
```
### 2.4 自定义数据量
修改脚本底部的调用参数:
```sql
-- 根据需要调整数量
CALL generate_users(50000); -- 生成5万用户
CALL generate_listings(200000); -- 生成20万商品
CALL generate_orders(100000); -- 生成10万订单
CALL generate_wallet_ledger(500000); -- 生成50万流水
```
## 三、索引优化验证
### 3.1 检查现有索引
```sql
-- 查看订单表索引
SHOW INDEX FROM rental_orders;
-- 查看钱包流水索引
SHOW INDEX FROM wallet_ledger;
-- 查看商品表索引
SHOW INDEX FROM rental_listings;
```
### 3.2 分析慢查询
```sql
-- 分析商品列表查询
EXPLAIN SELECT * FROM rental_listings
WHERE status = 'active'
AND review_status = 'approved'
ORDER BY published_at DESC
LIMIT 20;
-- 分析用户订单查询
EXPLAIN SELECT * FROM rental_orders
WHERE renter_id = 1234
AND status = 'active'
ORDER BY created_at DESC;
-- 分析钱包流水查询
EXPLAIN SELECT * FROM wallet_ledger
WHERE user_id = 1234
AND biz_type = 'rent_payment'
ORDER BY created_at DESC
LIMIT 50;
```
### 3.3 添加缺失索引(如果需要)
```sql
-- 示例:为常用查询组合添加联合索引
ALTER TABLE rental_orders
ADD INDEX idx_status_handoff_created (status, handoff_status, created_at);
-- 为管理后台查询优化
ALTER TABLE wallet_ledger
ADD INDEX idx_created_biz_type (created_at, biz_type);
```
## 四、压力测试执行
### 4.1 使用 Go 压测工具
```bash
cd scripts
# 编译压测工具
go build -o stress_test stress_test.go
# 场景1: 商品列表查询(高频读)
./stress_test -url http://localhost:8080 -c 50 -d 60 -s list_listings
# 场景2: 订单创建(写操作)
./stress_test -url http://localhost:8080 -c 20 -d 60 -s create_order
# 场景3: 钱包流水查询
./stress_test -url http://localhost:8080 -c 30 -d 60 -s wallet
# 场景4: 混合场景(模拟真实流量)
./stress_test -url http://localhost:8080 -c 100 -d 300 -s mixed
```
### 4.2 使用 Apache Bench (ab)
```bash
# 简单的商品列表查询压测
ab -n 10000 -c 100 http://localhost:8080/api/listings?page=1&page_size=20
# 健康检查接口压测
ab -n 50000 -c 200 http://localhost:8080/health
```
### 4.3 使用 wrk
```bash
# 安装 wrk
brew install wrk # macOS
# sudo apt install wrk # Ubuntu
# 基础压测
wrk -t4 -c100 -d60s http://localhost:8080/api/listings
# 使用脚本进行复杂场景测试
wrk -t4 -c100 -d60s -s scripts/wrk_scenario.lua http://localhost:8080
```
创建 `scripts/wrk_scenario.lua`
```lua
-- 模拟不同的查询参数
counter = 0
request = function()
counter = counter + 1
page = (counter % 10) + 1
path = "/api/listings?page=" .. page .. "&page_size=20"
return wrk.format("GET", path)
end
```
## 五、性能监控
### 5.1 数据库性能监控
```sql
-- 实时查看正在执行的查询
SHOW FULL PROCESSLIST;
-- 查看慢查询日志
docker exec hfb-mysql tail -f /var/log/mysql/slow.log
-- 查看表锁情况
SHOW OPEN TABLES WHERE In_use > 0;
-- 查看InnoDB状态
SHOW ENGINE INNODB STATUS;
-- 查看连接数
SHOW STATUS LIKE 'Threads_connected';
SHOW STATUS LIKE 'Max_used_connections';
```
### 5.2 应用性能监控
在压测期间,监控后端日志:
```bash
# 实时查看后端日志
tail -f backend/logs/app-*.log | grep -E "ERROR|WARN|latency"
# 监控容器资源使用
docker stats hfb-backend hfb-mysql hfb-redis
```
### 5.3 系统资源监控
```bash
# CPU和内存使用
top -p $(pgrep -f "go run")
# 网络连接数
netstat -an | grep :8080 | wc -l
# 查看打开的文件描述符
lsof -p $(pgrep -f "go run") | wc -l
```
## 六、性能指标基准
### 6.1 响应时间目标
| 接口类型 | P50 | P95 | P99 |
|---------|-----|-----|-----|
| 商品列表查询 | < 50ms | < 100ms | < 200ms |
| 订单详情查询 | < 30ms | < 80ms | < 150ms |
| 钱包流水查询 | < 40ms | < 100ms | < 200ms |
| 创建订单 | < 100ms | < 300ms | < 500ms |
| 支付处理 | < 200ms | < 500ms | < 1000ms |
### 6.2 吞吐量目标
- **读操作**:单机 QPS > 1000
- **写操作**:单机 QPS > 200
- **混合场景**:单机 QPS > 500
### 6.3 数据库查询目标
- **简单查询**< 10ms
- **联表查询**< 50ms
- **复杂聚合**< 100ms
## 七、常见性能瓶颈与优化
### 7.1 数据库层面
#### 问题1:商品列表查询慢
**症状:** `SELECT * FROM rental_listings WHERE status = 'active'` 耗时超过 100ms
**优化方案:**
```sql
-- 1. 添加覆盖索引
ALTER TABLE rental_listings
ADD INDEX idx_status_review_published_cover (
status, review_status, published_at, id, price, deposit_amount
);
-- 2. 避免 SELECT *,只查询需要的字段
SELECT id, owner_id, price, deposit_amount, published_at
FROM rental_listings
WHERE status = 'active' AND review_status = 'approved'
ORDER BY published_at DESC
LIMIT 20;
```
#### 问题2:用户订单分页查询慢
**症状:** 大偏移量分页(page > 100)性能下降
**优化方案:**
```sql
-- 使用游标分页代替 OFFSET
SELECT * FROM rental_orders
WHERE renter_id = ?
AND id < ? -- 上一页最后一条的ID
ORDER BY id DESC
LIMIT 20;
```
在代码中实现:
```go
// 使用游标分页
func (r *Repository) ListOrdersCursor(userID, lastID uint64, limit int) ([]Order, error) {
query := `SELECT * FROM rental_orders
WHERE renter_id = ? AND id < ?
ORDER BY id DESC LIMIT ?`
if lastID == 0 {
lastID = ^uint64(0) // Max uint64
}
// ...
}
```
#### 问题3:钱包流水查询慢(10万+数据)
**优化方案:**
```sql
-- 1. 确保有复合索引
ALTER TABLE wallet_ledger
ADD INDEX idx_user_created_desc (user_id, created_at DESC);
-- 2. 分区表(适用于超大数据量)
ALTER TABLE wallet_ledger
PARTITION BY RANGE (YEAR(created_at)) (
PARTITION p2024 VALUES LESS THAN (2025),
PARTITION p2025 VALUES LESS THAN (2026),
PARTITION p2026 VALUES LESS THAN (2027),
PARTITION p_future VALUES LESS THAN MAXVALUE
);
-- 3. 归档历史数据
CREATE TABLE wallet_ledger_archive LIKE wallet_ledger;
INSERT INTO wallet_ledger_archive
SELECT * FROM wallet_ledger
WHERE created_at < DATE_SUB(NOW(), INTERVAL 6 MONTH);
```
### 7.2 应用层面
#### 问题1N+1 查询问题
**症状:** 商品列表查询后,循环查询关联的账号信息
**优化方案:**
```go
// 错误做法:N+1查询
for _, listing := range listings {
account, _ := repo.GetAccount(listing.AccountID)
listing.Account = account
}
// 正确做法:预加载
func (r *Repository) ListWithAccounts(filter ListingFilter) ([]Listing, error) {
query := `
SELECT
rl.*,
ga.title as account_title,
ga.rank_level,
ga.server_region
FROM rental_listings rl
LEFT JOIN game_accounts ga ON rl.account_id = ga.id
WHERE rl.status = ?
ORDER BY rl.published_at DESC
LIMIT ?
`
// ...
}
```
#### 问题2:缓存缺失
**优化方案:**
```go
// 为热点数据添加Redis缓存
func (s *Service) GetListing(id uint64) (*Listing, error) {
cacheKey := fmt.Sprintf("listing:%d", id)
// 1. 尝试从缓存读取
if cached, err := s.redis.Get(ctx, cacheKey).Bytes(); err == nil {
var listing Listing
json.Unmarshal(cached, &listing)
return &listing, nil
}
// 2. 缓存未命中,从数据库读取
listing, err := s.repo.GetByID(id)
if err != nil {
return nil, err
}
// 3. 写入缓存
data, _ := json.Marshal(listing)
s.redis.Set(ctx, cacheKey, data, 10*time.Minute)
return listing, nil
}
```
#### 问题3:数据库连接池耗尽
**优化方案:**
```go
// 在 database/mysql.go 中优化连接池配置
db.SetMaxOpenConns(100) // 最大连接数
db.SetMaxIdleConns(20) // 空闲连接数
db.SetConnMaxLifetime(time.Hour) // 连接最大生命周期
db.SetConnMaxIdleTime(10 * time.Minute) // 空闲连接超时
```
### 7.3 Redis 优化
```bash
# 监控 Redis 性能
redis-cli --latency
redis-cli --stat
# 查看慢查询
redis-cli SLOWLOG GET 10
# 查看内存使用
redis-cli INFO memory
```
**配置优化:**
```redis
# 最大内存限制
maxmemory 2gb
# 内存淘汰策略
maxmemory-policy allkeys-lru
# 持久化配置(开发环境可以关闭以提升性能)
save ""
appendonly no
```
## 八、特定场景测试
### 8.1 订单高峰测试
模拟秒杀或活动高峰期:
```bash
# 同时创建1000个订单
./stress_test -url http://localhost:8080 -c 100 -d 10 -s create_order
```
**预期检查:**
- 数据库连接池是否耗尽
- 是否出现死锁
- 钱包余额扣减是否正确(需要事务隔离)
### 8.2 聊天消息压测
```bash
# 模拟100个用户同时发送消息
./stress_test -url http://localhost:8080 -c 100 -d 60 -s chat
```
**预期检查:**
- WebSocket 连接数限制
- 消息写入速度
- 未读消息计数准确性
### 8.3 大数据量查询
```sql
-- 测试后台钱包流水导出(大数据量)
SELECT * FROM wallet_ledger
WHERE created_at >= '2024-01-01'
ORDER BY created_at DESC;
-- 超时检查
SET SESSION max_execution_time = 30000; -- 30秒超时
```
## 九、压测后清理
### 9.1 清理测试数据
```sql
-- 谨慎执行!会删除所有测试数据
DELETE FROM wallet_ledger WHERE id > 100;
DELETE FROM rental_orders WHERE id > 100;
DELETE FROM rental_listings WHERE id > 100;
DELETE FROM game_accounts WHERE id > 100;
DELETE FROM users WHERE id > 1000;
-- 重置自增ID
ALTER TABLE users AUTO_INCREMENT = 1001;
ALTER TABLE rental_orders AUTO_INCREMENT = 101;
```
### 9.2 恢复配置
```bash
# 恢复开发环境配置
cd backend
cp .env.example .env
# 重启服务
./scripts/dev.sh
```
## 十、持续监控建议
### 10.1 生产环境监控
推荐集成:
- **APM**: New Relic / Datadog
- **日志**: ELK Stack / Grafana Loki
- **监控**: Prometheus + Grafana
- **告警**: PagerDuty / 企业微信
### 10.2 关键指标
**应用层:**
- API 响应时间(P50/P95/P99
- QPS / TPS
- 错误率
- 慢查询数量
**数据库层:**
- 连接数
- 慢查询数
- 锁等待时间
- InnoDB 缓存命中率
**系统层:**
- CPU 使用率
- 内存使用率
- 磁盘 IO
- 网络带宽
## 十一、性能优化 Checklist
- [ ] 数据库索引覆盖所有常用查询
- [ ] 消除 N+1 查询问题
- [ ] 热点数据使用 Redis 缓存
- [ ] 数据库连接池配置合理
- [ ] 分页查询使用游标而非 OFFSET
- [ ] 大数据量表考虑分区
- [ ] 历史数据定期归档
- [ ] 慢查询日志监控告警
- [ ] 数据库读写分离(如适用)
- [ ] CDN 加速静态资源
## 附录
### A. 压测命令速查
```bash
# 启动测试环境
docker-compose -f deploy/docker-compose.dev.yml up -d
cd backend && go run ./cmd/api
# 生成测试数据
docker exec -i hfb-mysql mysql -uhfb -psecret hfb_sys < scripts/load_test_data.sql
# 执行压测
cd scripts
go build -o stress_test stress_test.go
./stress_test -url http://localhost:8080 -c 100 -d 60 -s mixed
# 监控性能
docker stats
docker exec hfb-mysql mysqladmin -uhfb -psecret processlist
```
### B. 参考资料
- [MySQL 性能优化最佳实践](https://dev.mysql.com/doc/refman/8.0/en/optimization.html)
- [Go 性能优化](https://github.com/dgryski/go-perfbook)
- [Gin 框架性能调优](https://gin-gonic.com/docs/benchmarks/)
-121
View File
@@ -1,121 +0,0 @@
# 订单详情页 UI 优化
## 优化内容
### 问题
- 原页面 UI 过长,需要滚动到最底部才能看到"提交交接说明"、"提交结账"、"发起申诉"等操作按钮
- 用户体验差,操作流程不流畅
### 解决方案
#### 1. 布局调整
- 采用**左右分栏布局**:主内容区(左)+ 操作侧边栏(右)
- 侧边栏**固定悬浮**(sticky),始终可见
- 页面最大宽度从 1200px 扩展到 1400px,为侧边栏留出空间
#### 2. 操作侧边栏设计
- **宽度**: 320px
- **位置**: 右侧固定悬浮(sticky top: 24px
- **样式**: 白色卡片,带阴影和边框,重要操作突出显示
#### 3. 按钮优化
##### 快捷操作(直接执行)
- **提交交接**: 号主在侧边栏直接填写并提交
- **确认收号**: 租客一键确认
- **确认结账**: 号主一键确认
- **同意修正**: 租客一键同意
##### 复杂操作(跳转填写)
- **发起结账**: 点击后平滑滚动到结账表单填写区
- **修改结账**: 点击后平滑滚动到修改表单
- **拒绝修正**: 点击后平滑滚动到拒绝原因填写区
- **发起申诉**: 点击后平滑滚动到申诉表单
#### 4. 响应式设计
- **桌面端**: 左右分栏,侧边栏悬浮
- **移动端**: 单列布局,侧边栏移到顶部(order: -1)
## 核心代码变更
### 布局结构
```vue
<div class="content-layout">
<div class="main-content">
<!-- 主要内容进度信息交接记录详细表单 -->
</div>
<div class="action-sidebar">
<!-- 操作卡片根据订单状态和用户角色显示 -->
</div>
</div>
```
### 样式关键点
```css
.content-layout {
display: grid;
grid-template-columns: 1fr 320px;
gap: 24px;
align-items: start;
}
.action-sidebar {
position: sticky;
top: 24px;
display: flex;
flex-direction: column;
gap: 16px;
}
.sidebar-card {
padding: 20px;
background: #ffffff;
border: 2px solid #e5e7eb;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
```
### 平滑滚动函数
```typescript
function scrollToCheckout() {
const checkoutSection = document.querySelector('.checkout-form-section')
if (checkoutSection) {
checkoutSection.scrollIntoView({ behavior: 'smooth', block: 'start' })
}
}
```
## 优化效果
### 用户体验提升
1. **无需滚动查找**: 所有核心操作始终可见
2. **快速决策**: 重要信息和操作集中在右侧
3. **减少误操作**: 复杂操作跳转到详细表单,简单操作直接执行
4. **视觉引导**: 申诉等特殊操作用不同颜色背景突出
### 操作流程优化
- **交接**: 侧边栏直接提交 → 提升效率
- **结账**: 侧边栏点击跳转 → 避免误操作
- **申诉**: 侧边栏始终可见 → 降低投诉门槛
### 性能优化
- 使用 CSS `position: sticky` 代替 JavaScript 监听滚动
- 平滑滚动使用原生 `scrollIntoView` API
- 响应式布局使用 CSS Grid,无需 JavaScript
## 兼容性
- **现代浏览器**: 完全支持
- **移动端**: 自动切换为单列布局
- **低分辨率**: 自动调整为堆叠布局
## 文件变更
- `frontend/src/features/orders/views/OrderDetailView.vue`
- 添加 `.content-layout``.action-sidebar` 布局
- 添加侧边栏操作卡片
- 添加平滑滚动函数
- 为表单区域添加 class 标识
- 响应式样式优化
-74
View File
@@ -1,74 +0,0 @@
# 订单详情页 UI 优化总结
## 问题
- 原页面 UI 过长,操作按钮在页面底部
- 用户需要滚动到最底部才能执行"提交交接"、"提交结账"、"发起申诉"等关键操作
- 部分操作在侧边栏和主内容区重复显示
## 解决方案
### 1. 布局重构
- **左右分栏布局**:主内容区(左)+ 操作侧边栏(右,320px)
- **侧边栏悬浮**`position: sticky; top: 24px;` 始终可见
- **页面最大宽度**:从 1200px 扩展到 1400px
### 2. 操作整合(避免重复)
#### 简单操作 - 直接在侧边栏完成
-**提交交接说明**:侧边栏内直接填写 textarea 并提交(移除主内容区重复表单)
-**确认收号**:侧边栏一键确认(移除主内容区重复按钮)
-**确认结账**:侧边栏一键确认 + 跳转到修改表单按钮
-**同意修正结账**:侧边栏一键同意 + 跳转到拒绝表单按钮
#### 复杂操作 - 侧边栏提供快捷入口,主内容区保留详细表单
- 📝 **发起结账**:侧边栏可快速提交(使用当前表单值),也可跳转到详细表单修改消耗品、哈夫币等
- 📝 **修改结账**:侧边栏提供跳转按钮,主内容区保留完整修改表单
- 📝 **拒绝修正**:侧边栏提供跳转按钮,主内容区填写拒绝原因
- 📝 **发起申诉**:侧边栏提供跳转按钮,主内容区填写完整申诉信息
### 3. 视觉优化
- **卡片样式**:白色背景 + 边框 + 阴影
- **高亮卡片**:发起结账使用蓝色背景(`.highlight-card`
- **争议卡片**:发起申诉使用红色背景(`.dispute-card`
- **小分隔线**:侧边栏内使用 `.section-divider-mini` 分隔主次操作
### 4. 响应式设计
- **桌面端**`grid-template-columns: 1fr 320px`
- **移动端**:单列布局,侧边栏移到顶部(`order: -1`
## 主要代码变更
### 新增函数
```typescript
function scrollToCheckout()
function scrollToCounterCheckout()
function scrollToRejectCheckout()
function scrollToDispute()
```
### 新增样式类
```css
.content-layout { display: grid; grid-template-columns: 1fr 320px; }
.action-sidebar { position: sticky; top: 24px; }
.sidebar-card { ... }
.sidebar-card.highlight-card { background: #eff6ff; }
.sidebar-card.dispute-card { background: #fef2f2; }
.section-divider-mini { ... }
```
### 移除重复内容
- ❌ 主内容区的"提交交接说明"表单
- ❌ 主内容区的"确认收号"表单
- ❌ "确认结账"部分的重复按钮和分隔线
## 用户体验提升
1. **无需滚动**:所有关键操作始终在右侧可见
2. **快捷操作**:简单操作直接在侧边栏完成(如提交交接、确认收号)
3. **灵活选择**:复杂操作既可快速提交,也可跳转到详细表单修改
4. **视觉引导**:重要操作用颜色区分(蓝色高亮、红色警告)
5. **减少误操作**:复杂表单保留在主内容区,避免误提交
## 文件变更
- `frontend/src/features/orders/views/OrderDetailView.vue`
- `docs/ui-optimization-order-detail.md`(优化文档)
-319
View File
@@ -1,319 +0,0 @@
# 压力测试使用指南
**更新时间**2026-06-06
**状态**:✅ 已完成改进,工具可用
---
## 快速开始
### 1. 生成测试数据
```bash
cd /Users/yml/codes/hfb_sys
./scripts/stress_test.sh data -u 1000 -l 5000 -o 3000
```
### 2. 执行压力测试
```bash
# 真实业务场景(推荐)
./scripts/stress_test.sh test -c 100 -d 300 -s realistic --warmup 200
# 管理后台场景
./scripts/stress_test.sh test -c 50 -d 180 -s admin
# 商品查询专项测试
./scripts/stress_test.sh test -c 200 -d 120 -s listing_only
# 梯度压测(逐步加压)
./scripts/stress_test.sh test --gradual -c 200 -d 60 -s realistic --warmup 200
```
### 3. 监控和报告
```bash
# 实时监控
./scripts/stress_test.sh monitor
# 生成报告
./scripts/stress_test.sh report
# 清理数据
./scripts/stress_test.sh clean
```
---
## 测试场景说明
### realistic 场景(真实业务流量)
模拟真实用户行为,流量分布:
- 35% - 商品列表查询(高频操作)
- 25% - 商品详情查询
- 15% - 我的订单列表
- 10% - 钱包余额查询
- 7% - 聊天列表
- 5% - 订单详情
- 2% - 创建订单
- 1% - 支付订单
**适用场景**:评估系统整体性能,模拟生产环境
### admin 场景(管理后台)
模拟管理员操作,流量分布:
- 25% - 用户管理
- 20% - 订单管理
- 15% - 商品审核
- 15% - 钱包流水
- 10% - 申诉管理
- 10% - 审计日志
- 5% - 仪表盘
**适用场景**:评估后台管理系统性能
### listing_only 场景(商品查询)
专注于商品查询性能:
- 50% - 商品列表查询
- 50% - 商品详情查询
**适用场景**:评估商品模块单点性能
---
## 参数说明
### 数据生成参数
```bash
-u, --users NUM # 生成用户数量(默认: 1000
-l, --listings NUM # 生成商品数量(默认: 5000
-o, --orders NUM # 生成订单数量(默认: 3000
--ledger NUM # 生成钱包流水数量(默认: 10000)
--chat-messages NUM # 生成聊天消息数量(默认: 5000)
--use-optimized # 使用优化的数据生成脚本(实验性)
```
### 压力测试参数
```bash
-c, --concurrency NUM # 并发数(默认: 50
-d, --duration SEC # 测试时长/秒(默认: 60
-s, --scenario NAME # 测试场景: realistic, admin, listing_only
--gradual # 启用梯度压测
--warmup NUM # 预热用户数(默认: 100
--url URL # 后端地址(默认: http://localhost:8080
```
---
## 压测工具特性
### ✅ 已实现功能
1. **真实认证支持**
- 自动生成用户 token 池(避免 401 错误)
- 支持管理员 token 自动获取
- 模拟真实用户行为
2. **智能商品 ID 预加载**
- 启动时从 API 获取可用商品 ID 列表
- 避免 404 错误,提高成功率
3. **详细统计指标**
- P50/P95/P99 延迟分布
- 错误分类统计(Top 10
- 实时进度显示
- QPS 统计
4. **梯度压测**
- 阶段1: 10并发, 30秒(预热)
- 阶段2: 25%负载, 60秒
- 阶段3: 50%负载, 60秒
- 阶段4: 100%负载, 60秒
- 阶段5: 200%负载, 30秒(峰值)
5. **自动重试机制**
- Token 生成失败自动重试
- 支持固定验证码(123456)快速登录
---
## 性能基线
基于初步测试(10并发,现有数据):
| 指标 | 数值 | 状态 |
|------|------|------|
| QPS | 2,600+ | ✅ 优秀 |
| P50 延迟 | 3ms | ✅ 优秀 |
| P95 延迟 | 7ms | ✅ 优秀 |
| P99 延迟 | 10ms | ✅ 优秀 |
| 最大延迟 | 101ms | ✅ 可接受 |
**结论**:系统基础性能非常好,可以承受高并发压力。
---
## 完整流程示例
### 场景1:首次压测
```bash
# 1. 启动开发环境
./scripts/dev.sh
# 2. 生成测试数据(小规模)
./scripts/stress_test.sh data -u 1000 -l 5000 -o 3000
# 3. 执行压测(100并发,5分钟)
./scripts/stress_test.sh test -c 100 -d 300 -s realistic --warmup 200
# 4. 查看报告
./scripts/stress_test.sh report
```
### 场景2:梯度压测
```bash
# 逐步加压,找到系统极限
./scripts/stress_test.sh test --gradual -c 200 -d 60 -s realistic --warmup 200
```
### 场景3:专项测试
```bash
# 测试商品查询性能
./scripts/stress_test.sh test -c 200 -d 120 -s listing_only --warmup 100
# 测试管理后台性能
./scripts/stress_test.sh test -c 50 -d 180 -s admin
```
---
## 监控命令
### 实时监控
```bash
# 容器资源使用
docker stats hfb-backend hfb-mysql hfb-redis
# MySQL 连接数
docker exec hfb-mysql mysql -uhfb -psecret -e "SHOW STATUS LIKE 'Threads_connected';"
# MySQL 慢查询
docker exec hfb-mysql mysql -uhfb -psecret -e "SHOW STATUS LIKE 'Slow_queries';"
# Redis 统计
docker exec hfb-redis redis-cli INFO stats | grep -E "total_commands_processed|instantaneous_ops_per_sec"
```
### 查看正在执行的查询
```bash
docker exec hfb-mysql mysql -uhfb -psecret -e "SHOW FULL PROCESSLIST;"
```
---
## 性能优化建议
### 如果出现性能瓶颈
1. **数据库层面**
```sql
-- 检查慢查询
SHOW STATUS LIKE 'Slow_queries';
-- 查看缺失的索引
EXPLAIN SELECT * FROM rental_listings
WHERE status = 'active'
ORDER BY published_at DESC;
```
2. **应用层面**
- 检查是否有 N+1 查询
- 添加 Redis 缓存(商品列表、用户信息)
- 优化数据库连接池配置
3. **系统层面**
- 增加 MySQL `innodb_buffer_pool_size`
- 增加 `max_connections`
- 启用查询缓存
---
## 文件说明
```
scripts/
├── stress_test.sh # 统一入口脚本
├── load_stress.go # Go 压测工具(改进版)
├── load_test_data.sql # 数据生成脚本
└── load_test_data_optimized.sql # 优化版数据生成(实验性)
docs/
├── 压力测试使用指南.md # 本文档(快速上手)
└── stress-test-guide.md # 详细技术指南(性能优化)
```
---
## 常见问题
### Q: Token 生成失败怎么办?
**A:** 工具已自动处理:
1. 先尝试固定验证码 `123456`mock 模式)
2. 失败后自动发送验证码并重试
3. 等待 200ms 后重新登录
### Q: 商品详情 404 率高怎么办?
**A:** 工具已自动修复:
- 启动时从 `/api/listings` 预加载可用商品 ID
- 自动使用真实存在的商品 ID 进行测试
### Q: 如何提高成功率?
**A:**
1. 增加 `--warmup` 参数生成更多 token
2. 降低并发数 `-c`
3. 检查数据是否正常生成
### Q: 梯度压测的作用是什么?
**A:**
- 逐步增加负载,观察系统性能变化
- 找到系统性能拐点和极限
- 避免冷启动导致的误判
---
## 下一步
1. **执行完整压测**100-200并发,持续5-10分钟
2. **性能调优**:根据慢查询日志优化索引
3. **容量规划**:根据压测结果评估单机承载能力
4. **监控集成**:接入 Prometheus + Grafana
---
## 参考文档
- 详细技术指南:`docs/stress-test-guide.md`
- 项目架构分析:`docs/项目架构分析报告.md`
- API 文档:`docs/api.md`
---
**最后更新**2026-06-06
**维护人**Claude Opus 4.8
-636
View File
@@ -1,636 +0,0 @@
# 提现功能 API 文档
## 目录
- [收款账号管理 API](#收款账号管理-api)
- [提现申请 API (用户端)](#提现申请-api-用户端)
- [提现管理 API (管理员端)](#提现管理-api-管理员端)
---
## 收款账号管理 API
### 1. 查询收款账号列表
**请求**
```
GET /api/payment-accounts?page=1&page_size=20
Authorization: Bearer {user_token}
```
**响应**
```json
{
"code": 0,
"message": "success",
"data": {
"items": [
{
"id": 1,
"user_id": 123,
"account_type": "alipay",
"account_name": "张三",
"account_no": "138****5678",
"bank_name": "",
"bank_branch": "",
"certificate_urls": ["https://..."],
"is_default": true,
"status": "active",
"created_at": "2026-06-06T10:00:00Z",
"updated_at": "2026-06-06T10:00:00Z"
}
],
"total": 1,
"page": 1,
"page_size": 20
}
}
```
### 2. 查询收款账号详情
**请求**
```
GET /api/payment-accounts/:id
Authorization: Bearer {user_token}
```
**响应**
```json
{
"code": 0,
"message": "success",
"data": {
"id": 1,
"user_id": 123,
"account_type": "alipay",
"account_name": "张三",
"account_no": "138****5678",
"bank_name": "",
"bank_branch": "",
"certificate_urls": ["https://..."],
"is_default": true,
"status": "active",
"created_at": "2026-06-06T10:00:00Z",
"updated_at": "2026-06-06T10:00:00Z"
}
}
```
### 3. 添加收款账号
**请求**
```
POST /api/payment-accounts
Authorization: Bearer {user_token}
Content-Type: application/json
{
"account_type": "alipay", // alipay | wechat | bank
"account_name": "张三", // 必须与实名认证姓名一致
"account_no": "13812345678", // 支付宝账号/微信号/银行卡号
"bank_name": "中国工商银行", // 银行卡必填
"bank_branch": "北京分行", // 银行卡可选
"certificate_urls": [ // 凭证截图(可选)
"https://..."
]
}
```
**响应**
```json
{
"code": 0,
"message": "success",
"data": {
"id": 1,
"user_id": 123,
"account_type": "alipay",
"account_name": "张三",
"account_no": "138****5678",
"is_default": false,
"status": "active",
"created_at": "2026-06-06T10:00:00Z",
"updated_at": "2026-06-06T10:00:00Z"
}
}
```
**错误响应**
```json
{
"code": 40001,
"message": "账户名必须与实名认证姓名一致"
}
```
```json
{
"code": 40002,
"message": "请先完成实名认证"
}
```
```json
{
"code": 40003,
"message": "收款账号数量已达上限(最多5个)"
}
```
### 4. 更新收款账号
**请求**
```
PUT /api/payment-accounts/:id
Authorization: Bearer {user_token}
Content-Type: application/json
{
"bank_branch": "北京朝阳支行",
"certificate_urls": ["https://..."]
}
```
**响应**
```json
{
"code": 0,
"message": "success",
"data": {
"id": 1,
"account_type": "bank",
"account_name": "张三",
"account_no": "6222****1234",
"bank_name": "中国工商银行",
"bank_branch": "北京朝阳支行",
"is_default": false,
"status": "active",
"created_at": "2026-06-06T10:00:00Z",
"updated_at": "2026-06-06T10:05:00Z"
}
}
```
### 5. 删除收款账号
**请求**
```
DELETE /api/payment-accounts/:id
Authorization: Bearer {user_token}
```
**响应**
```json
{
"code": 0,
"message": "success",
"data": {
"deleted": true
}
}
```
### 6. 设置默认收款账号
**请求**
```
POST /api/payment-accounts/:id/set-default
Authorization: Bearer {user_token}
```
**响应**
```json
{
"code": 0,
"message": "success",
"data": {
"updated": true
}
}
```
---
## 提现申请 API (用户端)
### 1. 创建提现申请
**请求**
```
POST /api/withdrawals
Authorization: Bearer {user_token}
Content-Type: application/json
{
"payment_account_id": 1,
"amount": 100.00
}
```
**响应**
```json
{
"code": 0,
"message": "success",
"data": {
"id": 1,
"withdraw_no": "WD17362512001a2b3c4d",
"user_id": 123,
"amount": 100.00,
"fee": 0.00,
"actual_amount": 100.00,
"account_type": "alipay",
"account_name": "张三",
"account_no": "138****5678",
"bank_name": "",
"status": "pending",
"review_remark": "",
"created_at": "2026-06-06T10:00:00Z",
"updated_at": "2026-06-06T10:00:00Z",
"reviewed_at": null,
"paid_at": null
}
}
```
**错误响应**
```json
{
"code": 40001,
"message": "提现金额低于最小限额"
}
```
```json
{
"code": 40002,
"message": "提现金额超过最大限额"
}
```
```json
{
"code": 40003,
"message": "余额不足"
}
```
### 2. 查询提现列表
**请求**
```
GET /api/withdrawals?page=1&page_size=20
Authorization: Bearer {user_token}
```
**响应**
```json
{
"code": 0,
"message": "success",
"data": {
"items": [
{
"id": 1,
"withdraw_no": "WD17362512001a2b3c4d",
"user_id": 123,
"amount": 100.00,
"fee": 0.00,
"actual_amount": 100.00,
"account_type": "alipay",
"account_name": "张三",
"account_no": "138****5678",
"bank_name": "",
"status": "completed",
"review_remark": "审核通过",
"created_at": "2026-06-06T10:00:00Z",
"updated_at": "2026-06-06T10:30:00Z",
"reviewed_at": "2026-06-06T10:10:00Z",
"paid_at": "2026-06-06T10:30:00Z"
}
],
"total": 1,
"page": 1,
"page_size": 20
}
}
```
### 3. 查询提现详情
**请求**
```
GET /api/withdrawals/:id
Authorization: Bearer {user_token}
```
**响应**
```json
{
"code": 0,
"message": "success",
"data": {
"id": 1,
"withdraw_no": "WD17362512001a2b3c4d",
"user_id": 123,
"amount": 100.00,
"fee": 0.00,
"actual_amount": 100.00,
"account_type": "alipay",
"account_name": "张三",
"account_no": "138****5678",
"bank_name": "",
"status": "processing",
"review_remark": "审核通过",
"created_at": "2026-06-06T10:00:00Z",
"updated_at": "2026-06-06T10:10:00Z",
"reviewed_at": "2026-06-06T10:10:00Z",
"paid_at": null
}
}
```
### 4. 取消提现申请
**请求**
```
POST /api/withdrawals/:id/cancel
Authorization: Bearer {user_token}
```
**响应**
```json
{
"code": 0,
"message": "success",
"data": {
"cancelled": true
}
}
```
**错误响应**
```json
{
"code": 40001,
"message": "提现申请状态已锁定,无法操作"
}
```
---
## 提现管理 API (管理员端)
### 1. 查询提现列表
**请求**
```
GET /api/admin/withdrawals?status=pending&page=1&page_size=20
Authorization: Bearer {admin_token}
X-Required-Permission: withdrawal:list
```
**查询参数**
- `status`: 状态筛选 (pending | processing | completed | rejected | cancelled)
- `user_id`: 用户ID筛选
- `page`: 页码
- `page_size`: 每页数量
**响应**
```json
{
"code": 0,
"message": "success",
"data": {
"items": [
{
"id": 1,
"withdraw_no": "WD17362512001a2b3c4d",
"user_id": 123,
"user_nickname": "用户昵称",
"user_phone": "138****5678",
"amount": 100.00,
"fee": 0.00,
"actual_amount": 100.00,
"payment_account_id": 1,
"account_type": "alipay",
"account_name": "张三",
"account_no": "13812345678", // 管理员可见完整账号
"bank_name": "",
"bank_branch": "",
"status": "pending",
"reviewed_by": null,
"reviewed_by_name": "",
"reviewed_at": null,
"review_remark": "",
"paid_by": null,
"paid_by_name": "",
"paid_at": null,
"payment_proof_url": "",
"payment_remark": "",
"created_at": "2026-06-06T10:00:00Z",
"updated_at": "2026-06-06T10:00:00Z"
}
],
"total": 1,
"page": 1,
"page_size": 20
}
}
```
### 2. 查询提现详情
**请求**
```
GET /api/admin/withdrawals/:id
Authorization: Bearer {admin_token}
X-Required-Permission: withdrawal:detail
```
**响应**
```json
{
"code": 0,
"message": "success",
"data": {
"id": 1,
"withdraw_no": "WD17362512001a2b3c4d",
"user_id": 123,
"user_nickname": "用户昵称",
"user_phone": "13812345678",
"amount": 100.00,
"fee": 0.00,
"actual_amount": 100.00,
"payment_account_id": 1,
"account_type": "alipay",
"account_name": "张三",
"account_no": "13812345678",
"bank_name": "",
"bank_branch": "",
"status": "pending",
"reviewed_by": null,
"reviewed_by_name": "",
"reviewed_at": null,
"review_remark": "",
"paid_by": null,
"paid_by_name": "",
"paid_at": null,
"payment_proof_url": "",
"payment_remark": "",
"created_at": "2026-06-06T10:00:00Z",
"updated_at": "2026-06-06T10:00:00Z"
}
}
```
### 3. 审核提现申请
**请求**
```
POST /api/admin/withdrawals/:id/review
Authorization: Bearer {admin_token}
X-Required-Permission: withdrawal:review
Content-Type: application/json
{
"approved": true,
"remark": "审核通过"
}
```
**审核通过响应**
```json
{
"code": 0,
"message": "success",
"data": {
"id": 1,
"withdraw_no": "WD17362512001a2b3c4d",
"status": "processing",
"reviewed_by": 10,
"reviewed_by_name": "财务管理员",
"reviewed_at": "2026-06-06T10:10:00Z",
"review_remark": "审核通过",
...
}
}
```
**审核拒绝请求**
```json
{
"approved": false,
"remark": "账号信息不符"
}
```
**审核拒绝响应**
```json
{
"code": 0,
"message": "success",
"data": {
"id": 1,
"withdraw_no": "WD17362512001a2b3c4d",
"status": "rejected",
"reviewed_by": 10,
"reviewed_by_name": "财务管理员",
"reviewed_at": "2026-06-06T10:10:00Z",
"review_remark": "账号信息不符",
...
}
}
```
### 4. 确认打款
**请求**
```
POST /api/admin/withdrawals/:id/confirm-payment
Authorization: Bearer {admin_token}
X-Required-Permission: withdrawal:pay
Content-Type: application/json
{
"payment_proof_url": "https://storage.example.com/proofs/proof_123.jpg",
"remark": "已通过支付宝转账"
}
```
**响应**
```json
{
"code": 0,
"message": "success",
"data": {
"id": 1,
"withdraw_no": "WD17362512001a2b3c4d",
"status": "completed",
"paid_by": 10,
"paid_by_name": "财务管理员",
"paid_at": "2026-06-06T10:30:00Z",
"payment_proof_url": "https://storage.example.com/proofs/proof_123.jpg",
"payment_remark": "已通过支付宝转账",
...
}
}
```
---
## 状态说明
### 提现状态 (status)
| 状态 | 说明 | 允许操作 |
|------|------|---------|
| `pending` | 待审核 | 用户可取消、管理员可审核 |
| `processing` | 处理中 | 管理员可确认打款 |
| `completed` | 已完成 | 无 |
| `rejected` | 已拒绝 | 无 |
| `cancelled` | 已取消 | 无 |
### 账号类型 (account_type)
| 类型 | 说明 |
|------|------|
| `alipay` | 支付宝 |
| `wechat` | 微信 |
| `bank` | 银行卡 |
---
## 错误码说明
| 错误码 | 说明 |
|--------|------|
| 40001 | 请求参数错误 |
| 40002 | 实名认证未通过 |
| 40003 | 账号数量限制 |
| 40004 | 提现金额错误 |
| 40005 | 余额不足 |
| 40006 | 状态锁定 |
| 40401 | 未找到资源 |
| 40301 | 未授权 |
| 50001 | 服务器错误 |
---
## 接口权限说明
### 用户端接口
所有用户端接口需要携带用户 Token (`Authorization: Bearer {user_token}`)
### 管理员端接口
所有管理员端接口需要:
1. 携带管理员 Token (`Authorization: Bearer {admin_token}`)
2. 拥有对应的权限
#### 提现管理权限列表
- `withdrawal:list` - 查看提现申请列表
- `withdrawal:detail` - 查看提现详情
- `withdrawal:review` - 审核提现申请
- `withdrawal:pay` - 确认打款
**财务角色 (finance)** 默认拥有以上所有权限。
-365
View File
@@ -1,365 +0,0 @@
# 提现功能前端开发完成总结
## 🎉 已完成的工作
### 1. API 接口层(✅ 完成)
#### 文件:`frontend/src/features/wallet/api/withdrawal.ts`
- ✅ 收款账号管理 API(6个接口)
- fetchPaymentAccounts - 获取收款账号列表
- fetchPaymentAccount - 获取单个收款账号
- createPaymentAccount - 创建收款账号
- updatePaymentAccount - 更新收款账号
- deletePaymentAccount - 删除收款账号
- setDefaultPaymentAccount - 设置默认账号
- ✅ 提现申请 API4个接口)
- createWithdrawal - 创建提现申请
- fetchWithdrawals - 获取提现列表
- fetchWithdrawal - 获取单个提现详情
- cancelWithdrawal - 取消提现
#### 文件:`frontend/src/features/admin/api/adminWithdrawal.ts`
- ✅ 管理员端提现管理 API(4个接口)
- fetchAdminWithdrawals - 获取提现列表(支持筛选)
- fetchAdminWithdrawal - 获取提现详情
- reviewWithdrawal - 审核提现
- confirmPayment - 确认打款
### 2. 用户端页面(✅ 完成)
#### 收款账号管理页面
**文件**`frontend/src/features/wallet/views/PaymentAccountsView.vue`
**功能**
- ✅ 卡片式展示收款账号列表
- ✅ 支持三种账号类型(支付宝、微信、银行卡)
- ✅ 显示默认账号标识
- ✅ 账号脱敏显示
- ✅ 设置默认账号
- ✅ 编辑账号(仅部分字段)
- ✅ 删除账号
- ✅ 添加新账号
- ✅ 数量限制提示(最多5个)
#### 提现申请页面
**文件**`frontend/src/features/wallet/views/WithdrawalView.vue`
**功能**
- ✅ 显示钱包余额(可用余额、冻结余额)
- ✅ 提现表单
- 选择收款账号(下拉选择)
- 输入提现金额
- 实时计算到账金额
- 金额验证(最低10元,最高5000元)
- 余额不足提示
- ✅ 提现说明展示
- ✅ 提现记录列表
- 显示提现状态
- 取消待审核的提现
- 分页显示
- ✅ 无收款账号时引导添加
#### 收款账号编辑对话框
**文件**`frontend/src/features/wallet/components/PaymentAccountDialog.vue`
**功能**
- ✅ 新建/编辑收款账号
- ✅ 账号类型选择(支付宝/微信/银行卡)
- ✅ 银行卡特有字段(银行名称、开户支行)
- ✅ 实名验证提示
- ✅ 上传凭证(占位,待集成文件上传)
- ✅ 表单验证
### 3. 管理员端页面(✅ 完成)
#### 提现审核页面
**文件**`frontend/src/features/admin/views/AdminWithdrawalsView.vue`
**功能**
- ✅ 提现列表展示
- 显示用户信息(昵称、手机号)
- 显示金额信息
- 显示收款账号信息(完整账号)
- 显示状态标签
- ✅ 筛选功能
- 按状态筛选
- 按用户ID筛选
- ✅ 操作按钮
- 查看详情
- 通过审核(pending状态)
- 拒绝审核(pending状态)
- 确认打款(processing状态)
- ✅ 分页功能
- ✅ 刷新按钮
#### 提现详情对话框
**文件**`frontend/src/features/admin/components/WithdrawalDetailDialog.vue`
**功能**
- ✅ 完整的提现信息展示
- 基本信息(单号、状态、时间)
- 用户信息(ID、昵称、手机)
- 金额信息(提现金额、手续费、实际到账)
- 收款账号信息(完整账号,管理员可见)
- 审核信息(审核人、时间、备注)
- 打款信息(打款人、时间、备注、凭证)
- ✅ 操作按钮
- 通过审核
- 拒绝审核
- 确认打款
- ✅ 操作提示
- ✅ 状态标识
### 4. 路由配置(✅ 完成)
#### 用户端路由
**文件**`frontend/src/router/accountRoutes.ts`
```typescript
/wallet/payment-accounts PaymentAccountsView
/wallet/withdrawal WithdrawalView
```
#### 管理员端路由
**文件**`frontend/src/router/adminRoutes.ts`
```typescript
/admin/withdrawals AdminWithdrawalsView
```
### 5. 模块导出(✅ 完成)
**文件**`frontend/src/features/wallet/index.ts`
已更新导出配置,包含提现相关的 API 和类型。
---
## 📋 功能特性
### 用户端特性
1. **收款账号管理**
- 支持 3 种账号类型
- 账号加密存储(后端)
- 账号脱敏显示
- 实名验证
- 默认账号管理
- 最多 5 个账号
2. **提现申请**
- 实时余额显示
- 金额限制提示
- 手续费计算
- 收款账号选择
- 提现状态跟踪
- 取消待审核提现
3. **用户体验**
- 响应式设计
- 友好的错误提示
- 加载状态展示
- 确认对话框
- 引导式交互
### 管理员端特性
1. **提现审核**
- 多条件筛选
- 完整信息展示
- 快速审核操作
- 批注功能
2. **打款确认**
- 详细的收款信息
- 打款备注
- 凭证上传(待实现)
- 操作记录
3. **数据展示**
- 完整账号可见
- 用户信息展示
- 操作历史追踪
- 状态流转清晰
---
## 🎨 UI/UX 设计
### 设计特点
1. **卡片式布局** - 收款账号以卡片形式展示,清晰直观
2. **状态标签** - 使用不同颜色区分提现状态
3. **响应式设计** - 适配不同屏幕尺寸
4. **友好提示** - 充分的操作提示和帮助信息
5. **统一风格** - 与项目整体设计保持一致
### 颜色规范
- 支付宝:蓝色 (#1677ff)
- 微信:绿色 (#07c160)
- 银行卡:橙色 (#ff6a00)
- 待审核:警告黄 (warning)
- 处理中:主题蓝 (primary)
- 已完成:成功绿 (success)
- 已拒绝:危险红 (danger)
- 已取消:灰色 (info)
---
## 🔄 业务流程
### 用户提现流程
```
1. 用户登录
2. 进入钱包页面
3. 点击"提现"
4. 添加收款账号(如果没有)
5. 选择收款账号
6. 输入提现金额
7. 确认提交
8. 查看提现记录
```
### 管理员审核流程
```
1. 管理员登录
2. 进入提现管理页面
3. 筛选待审核提现
4. 查看详情
5. 审核(通过/拒绝)
6. 如果通过:手动转账
7. 上传凭证(可选)
8. 确认打款完成
```
---
## ⚠️ 待完善功能
### 1. 文件上传集成
- [ ] PaymentAccountDialog 中的凭证上传
- [ ] WithdrawalDetailDialog 中的打款凭证上传
- 需要集成项目的文件上传组件
### 2. 移动端适配
- [ ] 创建移动端版本的页面
- [ ] 响应式布局优化
### 3. 实时通知
- [ ] 提现状态变更通知
- [ ] WebSocket 实时推送
### 4. 更多功能
- [ ] 提现记录导出
- [ ] 批量审核
- [ ] 统计报表
---
## 🧪 测试建议
### 用户端测试
1. **收款账号管理**
- [ ] 添加支付宝账号
- [ ] 添加微信账号
- [ ] 添加银行卡账号
- [ ] 测试账号数量限制(5个)
- [ ] 设置默认账号
- [ ] 编辑账号信息
- [ ] 删除账号
2. **提现申请**
- [ ] 测试金额验证(最低10元)
- [ ] 测试金额验证(最高5000元)
- [ ] 测试余额不足提示
- [ ] 测试提现成功
- [ ] 测试取消提现
- [ ] 测试无收款账号提示
### 管理员端测试
1. **提现审核**
- [ ] 测试列表加载
- [ ] 测试状态筛选
- [ ] 测试用户ID筛选
- [ ] 测试审核通过
- [ ] 测试审核拒绝
- [ ] 测试确认打款
2. **权限测试**
- [ ] 测试非财务角色无法访问
- [ ] 测试财务角色正常访问
---
## 📝 使用说明
### 开发环境运行
```bash
# 确保后端已启动
cd /Users/yml/codes/hfb_sys
./scripts/dev.sh
# 访问前端
# 用户端:http://localhost:5173/wallet/payment-accounts
# 管理端:http://localhost:5173/admin/withdrawals
```
### 前端页面访问
**用户端**
- 收款账号管理:`/wallet/payment-accounts`
- 提现申请:`/wallet/withdrawal`
**管理员端**
- 提现审核:`/admin/withdrawals`
---
## 🎯 总结
**前端开发已完成**
已完成的功能:
1. ✅ 完整的 API 接口层
2. ✅ 用户端收款账号管理页面
3. ✅ 用户端提现申请页面
4. ✅ 管理员端提现审核页面
5. ✅ 所有必要的组件和对话框
6. ✅ 路由配置
7. ✅ TypeScript 类型定义
**系统现在具备完整的手动提现功能**,包括:
- 用户添加收款账号
- 用户发起提现申请
- 财务审核提现
- 财务确认打款
- 完整的状态流转
**下一步**
1. 集成文件上传功能
2. 完整的端到端测试
3. 移动端页面开发(可选)
4. 生产环境部署
---
## 📚 相关文档
- [后端实施总结](../../docs/提现功能实施总结.md)
- [API 文档](../../docs/提现功能API文档.md)
---
**开发完成时间**2026-06-06
**开发状态**:✅ 已完成并可用
-414
View File
@@ -1,414 +0,0 @@
# 🎉 提现功能完整实施总结
## 项目概述
**功能名称**:手动提现功能
**实施日期**2026-06-06
**实施状态**:✅ 已完成
**版本**v1.0
---
## ✅ 实施完成情况
### 后端开发(100% 完成)
#### 1. 数据库设计 ✅
- [x] 创建 `user_payment_accounts` 表(用户收款账号)
- [x] 创建 `withdrawal_requests` 表(提现申请)
- [x] 添加提现相关权限(4个)
- [x] 创建财务管理员角色
- [x] 数据模型定义
#### 2. 业务模块 ✅
- [x] **收款账号管理模块** (`paymentaccount`)
- Service 层、Repository 层、Handler 层
- AES 加密存储
- 账号脱敏
- 实名验证
- 默认账号管理
- [x] **提现申请模块** (`withdrawal`)
- Service 层、Repository 层、Handler 层
- 创建提现申请
- 审核流程
- 打款确认
- 钱包流水集成
#### 3. API 接口 ✅
- [x] 用户端 API10个接口)
- 收款账号管理(6个)
- 提现申请(4个)
- [x] 管理员端 API4个接口)
- 提现列表和详情
- 审核提现
- 确认打款
#### 4. 路由配置 ✅
- [x] 注册所有 API 路由
- [x] 配置权限验证
- [x] 编译测试通过
---
### 前端开发(100% 完成)
#### 1. API 接口层 ✅
- [x] `wallet/api/withdrawal.ts` - 用户端 API
- [x] `admin/api/adminWithdrawal.ts` - 管理员端 API
- [x] TypeScript 类型定义
#### 2. 用户端页面 ✅
- [x] **收款账号管理页面** (`PaymentAccountsView.vue`)
- 卡片式展示
- 增删改查
- 默认账号管理
- [x] **提现申请页面** (`WithdrawalView.vue`)
- 余额显示
- 提现表单
- 提现记录
- 取消提现
- [x] **收款账号对话框** (`PaymentAccountDialog.vue`)
- 新建/编辑
- 表单验证
- 实名提示
#### 3. 管理员端页面 ✅
- [x] **提现审核页面** (`AdminWithdrawalsView.vue`)
- 列表展示
- 筛选功能
- 审核操作
- [x] **提现详情对话框** (`WithdrawalDetailDialog.vue`)
- 完整信息展示
- 审核操作
- 打款确认
#### 4. 路由配置 ✅
- [x] 注册用户端路由(2个)
- [x] 注册管理员端路由(1个)
- [x] 编译测试通过
---
## 📊 功能统计
### 代码统计
| 类别 | 文件数 | 说明 |
|------|--------|------|
| 后端模型 | 2 | withdrawal.go, payment_account.go |
| 后端模块 | 8 | service, repository, handler, dto (×2) |
| 前端 API | 2 | withdrawal.ts, adminWithdrawal.ts |
| 前端页面 | 4 | 用户端3个,管理端1个 |
| 前端组件 | 1 | WithdrawalDetailDialog.vue |
| 数据库迁移 | 1 | 000002_add_withdrawal_tables.sql |
| 文档 | 4 | 实施总结、API文档、前端总结、测试清单 |
| **总计** | **22** | - |
### API 接口统计
| 类型 | 数量 | 说明 |
|------|------|------|
| 用户端 - 收款账号 | 6 | 增删改查、设置默认 |
| 用户端 - 提现 | 4 | 创建、查询、取消 |
| 管理端 - 提现 | 4 | 列表、详情、审核、打款 |
| **总计** | **14** | - |
### 数据库对象
| 类型 | 数量 | 说明 |
|------|------|------|
| 数据表 | 2 | user_payment_accounts, withdrawal_requests |
| 权限 | 5 | withdrawal:*, wallet:admin_ledger |
| 角色 | 1 | finance(财务管理员) |
---
## 🎯 核心功能
### 用户端功能
1.**收款账号管理**
- 支持支付宝、微信、银行卡
- AES 加密存储
- 账号脱敏显示
- 实名验证
- 默认账号
- 最多5个
2.**提现申请**
- 选择收款账号
- 金额限制(10-5000元)
- 手续费计算(当前0%
- 余额验证
- 状态跟踪
- 取消功能
### 管理员端功能
1.**提现审核**
- 列表查询
- 状态筛选
- 用户筛选
- 通过/拒绝审核
- 备注记录
2.**打款确认**
- 完整账号查看
- 打款备注
- 凭证上传(待实现)
- 状态更新
### 钱包集成
1.**余额管理**
- 提现冻结
- 审核拒绝解冻
- 用户取消解冻
- 打款完成扣除
2.**流水记录**
- withdraw_freeze
- withdraw_reject
- withdraw_cancel
- withdraw_complete
---
## 🔐 安全措施
1.**账号加密** - AES-256 加密存储
2.**实名验证** - 账户名必须与实名一致
3.**账号脱敏** - 用户端仅显示脱敏信息
4.**权限控制** - 财务角色专用权限
5.**金额限制** - 单笔限额10-5000元
6.**状态锁定** - 审核后无法随意修改
7.**快照机制** - 提现申请保存账号快照
---
## 📁 文件清单
### 后端文件
```
backend/
├── migrations/
│ └── 000002_add_withdrawal_tables.sql
├── internal/
│ ├── model/
│ │ ├── payment_account.go
│ │ └── withdrawal.go
│ ├── modules/
│ │ ├── paymentaccount/
│ │ │ ├── service.go
│ │ │ ├── repository.go
│ │ │ ├── handler.go
│ │ │ └── dto.go
│ │ └── withdrawal/
│ │ ├── service.go
│ │ ├── repository.go
│ │ ├── handler.go
│ │ └── dto.go
│ └── router/
│ └── router.go (已更新)
```
### 前端文件
```
frontend/src/
├── features/
│ ├── wallet/
│ │ ├── api/
│ │ │ └── withdrawal.ts
│ │ ├── views/
│ │ │ ├── PaymentAccountsView.vue
│ │ │ └── WithdrawalView.vue
│ │ ├── components/
│ │ │ └── PaymentAccountDialog.vue
│ │ └── index.ts (已更新)
│ └── admin/
│ ├── api/
│ │ └── adminWithdrawal.ts
│ ├── views/
│ │ └── AdminWithdrawalsView.vue
│ └── components/
│ └── WithdrawalDetailDialog.vue
└── router/
├── accountRoutes.ts (已更新)
└── adminRoutes.ts (已更新)
```
### 文档文件
```
docs/
├── 提现功能实施总结.md
├── 提现功能API文档.md
├── 提现功能前端开发总结.md
└── 提现功能测试清单.md
```
---
## 🔄 业务流程
### 完整提现流程
```
用户端:
1. 添加收款账号(需实名认证)
2. 选择收款账号
3. 输入提现金额
4. 提交申请
5. 系统冻结余额
6. 等待审核
管理员端:
7. 查看待审核列表
8. 审核通过
9. 手动转账到用户账号
10. 上传打款凭证(可选)
11. 确认打款完成
系统:
12. 扣除冻结余额
13. 记录流水
14. 状态变更为"已完成"
```
---
## ⚠️ 注意事项
### 生产环境部署前必做
1. **修改加密密钥** ⚠️
```go
// backend/internal/modules/paymentaccount/repository.go
const encryptionKey = "your-32-byte-secret-key-here!!"
```
建议从环境变量读取
2. **执行数据库迁移**
```bash
mysql -u root -p database < backend/migrations/000002_add_withdrawal_tables.sql
```
3. **配置财务管理员**
```sql
-- 查询 finance 角色ID
SELECT id FROM roles WHERE code = 'finance';
-- 分配角色
INSERT INTO admin_user_roles (admin_user_id, role_id)
VALUES (管理员ID, 财务角色ID);
```
4. **配置限额**(可选)
```go
// backend/internal/modules/withdrawal/service.go
const (
MinWithdrawalAmount = 10.0
MaxWithdrawalAmount = 5000.0
WithdrawalFeeRate = 0.0
)
```
---
## 🧪 测试状态
- [x] 后端编译通过
- [x] 前端编译通过
- [x] 系统正常启动
- [ ] 功能测试(待执行)
- [ ] 集成测试(待执行)
- [ ] 压力测试(待执行)
**测试清单**:详见 `docs/提现功能测试清单.md`
---
## 🚀 后续优化建议
### 短期优化
1. **文件上传集成** - 凭证上传功能
2. **移动端适配** - H5 页面开发
3. **实时通知** - WebSocket 状态推送
4. **数据导出** - 提现记录导出
### 中期优化
1. **自动化提现** - 小额自动审核
2. **批量打款** - 导出批量打款文件
3. **提现报表** - 财务统计报表
4. **风控规则** - 异常检测
### 长期优化
1. **支付网关对接** - 自动打款
2. **银行接口对接** - 企业网银直连
3. **实时到账** - T+0 提现
4. **多级审批** - 大额提现审批流程
---
## 📚 相关资源
### 文档
- [后端实施总结](./提现功能实施总结.md)
- [API 接口文档](./提现功能API文档.md)
- [前端开发总结](./提现功能前端开发总结.md)
- [测试清单](./提现功能测试清单.md)
### 访问地址
**用户端**
- 收款账号管理:http://localhost:5173/wallet/payment-accounts
- 提现申请:http://localhost:5173/wallet/withdrawal
**管理员端**
- 提现审核:http://localhost:5173/admin/withdrawals
### API 文档
- Swagger 文档:http://localhost:8080/swagger/index.html
---
## 🎉 项目总结
### 完成情况
**后端开发**100% 完成
**前端开发**100% 完成
**文档编写**100% 完成
**功能测试**:待执行
**生产部署**:待执行
### 技术亮点
1. **完整的业务流程** - 从申请到打款的完整闭环
2. **安全可靠** - 多层次安全措施
3. **用户友好** - 清晰的界面和流程引导
4. **可扩展性** - 预留自动化升级空间
5. **代码质量** - 规范的分层架构
### 交付物
- ✅ 22个代码文件
- ✅ 14个 API 接口
- ✅ 6个前端页面/组件
- ✅ 2张数据表
- ✅ 4份完整文档
---
## 👏 致谢
感谢您的信任和支持!
本项目已完整实现了手动提现功能,包括:
- 完整的后端业务逻辑
- 友好的前端用户界面
- 详尽的文档和测试清单
- 规范的代码结构
系统已具备上线条件,完成测试后即可投入使用。
如有任何问题或需要进一步的支持,请随时联系。
---
**项目状态**:✅ 开发完成,待测试
**完成日期**2026-06-06
**版本**v1.0
-356
View File
@@ -1,356 +0,0 @@
# 手动提现功能实施完成总结
## 🎉 已完成的工作
### 1. 数据库迁移(✅ 完成)
**文件**: `backend/migrations/000002_add_withdrawal_tables.sql`
创建了两张新表:
#### user_payment_accounts (用户收款账号表)
- 支持三种账号类型:支付宝 (alipay)、微信 (wechat)、银行卡 (bank)
- 账号信息加密存储
- 支持上传认证凭证(收款码截图)
- 支持设置默认账号
- 每个用户最多5个收款账号
#### withdrawal_requests (提现申请表)
- 记录用户提现申请的完整信息
- 账号信息快照(防止用户修改收款账号影响已有提现)
- 支持手续费计算
- 完整的审核流程:pending → processing → completed
- 记录审核人、打款人、打款凭证等信息
#### 权限和角色
- 新增 4 个提现相关权限
- 新增 `finance` 财务管理员角色
- 关联权限到角色
### 2. 数据模型(✅ 完成)
**文件**:
- `backend/internal/model/payment_account.go` - 收款账号模型
- `backend/internal/model/withdrawal.go` - 提现申请模型
### 3. 收款账号管理模块(✅ 完成)
**目录**: `backend/internal/modules/paymentaccount/`
#### 核心功能:
- **增删改查**:用户管理自己的收款账号
- **实名验证**:账户名必须与实名认证姓名一致
- **加密存储**:使用 AES 加密存储账号信息
- **脱敏显示**:前端显示时自动脱敏(如:138****5678
- **默认账号**:支持设置默认收款账号
- **数量限制**:每个用户最多 5 个收款账号
**文件**:
- `service.go` - 业务逻辑层
- `repository.go` - 数据访问层(含加密/解密/脱敏逻辑)
- `handler.go` - HTTP 接口处理
- `dto.go` - 数据传输对象
### 4. 提现申请模块(✅ 完成)
**目录**: `backend/internal/modules/withdrawal/`
#### 用户端功能:
- **创建提现申请**:选择收款账号、输入金额
- **查询提现列表**:查看自己的提现记录
- **查询提现详情**:查看单个提现申请
- **取消提现**:待审核状态可取消
#### 管理员端功能:
- **查询提现列表**:支持按状态、用户筛选
- **查询提现详情**:查看完整信息(包括完整账号)
- **审核提现**:通过/拒绝提现申请
- **确认打款**:上传打款凭证,完成提现
#### 核心流程:
1. **用户申请** → 冻结可用余额 → 创建提现记录(status=pending
2. **财务审核** → 通过(status=processing/ 拒绝(status=rejected,解冻余额)
3. **手动打款** → 上传凭证 → 确认完成(status=completed,扣除冻结余额)
#### 限额控制:
- 最低提现金额:10 元
- 最高单笔提现:5000 元
- 手续费率:0%(可配置)
**文件**:
- `service.go` - 业务逻辑层
- `repository.go` - 数据访问层(含钱包流水集成)
- `handler.go` - HTTP 接口处理
- `dto.go` - 数据传输对象
### 5. 路由配置(✅ 完成)
**文件**: `backend/internal/router/router.go`
#### 用户端 API:
```
POST /api/payment-accounts # 添加收款账号
GET /api/payment-accounts # 查询收款账号列表
GET /api/payment-accounts/:id # 查询收款账号详情
PUT /api/payment-accounts/:id # 更新收款账号
DELETE /api/payment-accounts/:id # 删除收款账号
POST /api/payment-accounts/:id/set-default # 设为默认
POST /api/withdrawals # 创建提现申请
GET /api/withdrawals # 查询提现列表
GET /api/withdrawals/:id # 查询提现详情
POST /api/withdrawals/:id/cancel # 取消提现
```
#### 管理员端 API:
```
GET /api/admin/withdrawals # 查询提现列表(需权限:withdrawal:list
GET /api/admin/withdrawals/:id # 查询提现详情(需权限:withdrawal:detail
POST /api/admin/withdrawals/:id/review # 审核提现(需权限:withdrawal:review
POST /api/admin/withdrawals/:id/confirm-payment # 确认打款(需权限:withdrawal:pay
```
### 6. 钱包模块更新(✅ 完成)
更新了 `wallet/service.go`,提现功能已迁移到独立的 withdrawal 模块。
---
## 📋 数据库表结构
### user_payment_accounts
```sql
id BIGINT
user_id BIGINT ID
account_type VARCHAR(32) alipay/wechat/bank
account_name VARCHAR(128)
account_no VARCHAR(255)
bank_name VARCHAR(128)
bank_branch VARCHAR(255)
certificate_urls JSON
is_default TINYINT
status VARCHAR(32) active/disabled
created_at DATETIME
updated_at DATETIME
```
### withdrawal_requests
```sql
id BIGINT
withdraw_no VARCHAR(64)
user_id BIGINT ID
amount DECIMAL(12,2)
fee DECIMAL(12,2)
actual_amount DECIMAL(12,2)
payment_account_id BIGINT ID
account_type VARCHAR(32)
account_name VARCHAR(128)
account_no VARCHAR(128)
bank_name VARCHAR(128)
bank_branch VARCHAR(255)
status VARCHAR(32) pending/processing/completed/rejected/cancelled
reviewed_by BIGINT ID
reviewed_at DATETIME
review_remark VARCHAR(255)
paid_by BIGINT ID
paid_at DATETIME
payment_proof_url VARCHAR(512) URL
payment_remark VARCHAR(255)
created_at DATETIME
updated_at DATETIME
```
---
## 🔐 安全措施
1. **账号加密存储**:使用 AES-256 加密收款账号
2. **实名验证**:账户名必须与实名认证姓名一致
3. **账号脱敏**:用户端仅显示脱敏账号(如 138****5678
4. **权限控制**:管理员操作需要对应权限
5. **金额限制**:单笔提现限额、最低提现金额
6. **状态锁定**:审核中/已完成的提现无法修改
7. **快照机制**:提现申请创建时保存账号信息快照
---
## 🔄 业务流程
### 用户提现流程
```
1. 用户添加收款账号(需实名认证)
2. 用户发起提现申请
3. 系统冻结用户可用余额
4. 创建提现申请(status=pending
5. 等待财务审核
```
### 财务审核流程
```
1. 财务管理员查看待审核列表
2. 审核提现申请
├─ 通过:status → processing
└─ 拒绝:status → rejected,解冻余额
3. 手动转账(支付宝/微信/银行)
4. 上传打款凭证
5. 确认完成(status → completed
6. 系统扣除冻结余额
```
---
## 📊 钱包流水业务类型
提现相关的 `biz_type`:
- `withdraw_freeze` - 提现冻结
- `withdraw_reject` - 提现拒绝(解冻)
- `withdraw_cancel` - 用户取消提现(解冻)
- `withdraw_complete` - 提现完成(扣除冻结余额)
---
## 🚀 部署步骤
### 1. 执行数据库迁移
```bash
mysql -u root -p your_database < backend/migrations/000002_add_withdrawal_tables.sql
```
### 2. 重新编译后端
```bash
cd backend
go build -o server cmd/api/main.go
```
### 3. 重启服务
```bash
./server
```
### 4. 配置财务管理员
```sql
-- 查询 finance 角色ID
SELECT id FROM roles WHERE code = 'finance';
-- 给管理员分配财务角色
INSERT INTO admin_user_roles (admin_user_id, role_id)
VALUES (ID, ID);
```
---
## ⚙️ 配置说明
### 加密密钥配置
文件:`backend/internal/modules/paymentaccount/repository.go`
**重要**:生产环境必须修改加密密钥!
```go
const encryptionKey = "your-32-byte-secret-key-here!!" // 32字节
```
建议从环境变量或配置文件读取:
```go
var encryptionKey = os.Getenv("PAYMENT_ACCOUNT_ENCRYPTION_KEY")
```
### 提现限额配置
文件:`backend/internal/modules/withdrawal/service.go`
```go
const (
MinWithdrawalAmount = 10.0 // 最低提现金额
MaxWithdrawalAmount = 5000.0 // 单笔最高提现金额
WithdrawalFeeRate = 0.0 // 手续费率
)
```
---
## ✅ 测试建议
### 1. 收款账号管理测试
- [ ] 添加支付宝账号
- [ ] 添加微信账号
- [ ] 添加银行卡账号
- [ ] 测试实名验证(账户名不匹配)
- [ ] 测试账号数量限制(最多5个)
- [ ] 测试设置默认账号
- [ ] 测试删除账号
- [ ] 验证账号加密和脱敏显示
### 2. 提现申请测试
- [ ] 测试最低金额限制(<10元)
- [ ] 测试最高金额限制(>5000元)
- [ ] 测试余额不足
- [ ] 测试正常提现申请
- [ ] 测试用户取消提现(pending状态)
- [ ] 测试无法取消已审核的提现
### 3. 财务审核测试
- [ ] 测试查询待审核列表
- [ ] 测试审核通过
- [ ] 测试审核拒绝(验证余额解冻)
- [ ] 测试确认打款(上传凭证)
- [ ] 测试管理员可见完整账号
### 4. 权限测试
- [ ] 测试非财务管理员无法访问审核接口
- [ ] 测试财务管理员可以访问所有提现接口
- [ ] 测试用户只能查看自己的提现记录
---
## 📝 后续优化建议
### 短期优化
1. **前端页面开发**:用户端收款账号管理、提现申请页面
2. **管理员前端**:提现审核列表、审核详情页面
3. **通知功能**:提现状态变更时发送通知
4. **文件上传**:集成打款凭证上传功能
### 中期优化
1. **自动化提现**:小额提现自动审核
2. **批量打款**:导出批量打款文件
3. **提现报表**:财务报表统计
4. **风控规则**:异常提现检测
### 长期优化
1. **支付网关对接**:集成自动打款接口
2. **银行接口对接**:企业网银直连
3. **实时到账**T+0 实时提现
4. **多级审批**:大额提现多级审批流程
---
## ⚠️ 注意事项
1. **加密密钥**:生产环境必须使用强随机密钥,并妥善保管
2. **权限配置**:确保财务管理员权限配置正确
3. **余额校验**:提现前严格校验余额,防止超额提现
4. **状态机**:严格按照状态流转规则操作
5. **审计日志**:所有财务操作应记录审计日志
6. **测试环境**:充分测试后再上线生产环境
---
## 🎯 项目总结
本次实施完成了**手动提现功能的完整开发**,包括:
- ✅ 数据库设计和迁移
- ✅ 后端业务逻辑实现
- ✅ API 接口开发
- ✅ 权限和角色配置
- ✅ 安全措施实施
系统已具备完整的手动提现能力,财务管理员可以通过管理后台进行提现审核和打款确认操作。
**下一步**:前端界面开发 → 完整测试 → 生产环境部署
-396
View File
@@ -1,396 +0,0 @@
# 提现功能测试清单
## 🧪 测试环境准备
### 前置条件
- [x] 后端服务已启动(http://localhost:8080
- [x] 前端服务已启动(http://localhost:5173
- [x] 数据库迁移已执行
- [x] 财务角色和权限已配置
---
## 📝 用户端测试
### 1. 收款账号管理测试
#### 1.1 添加支付宝账号
- [ ] 访问 `/wallet/payment-accounts`
- [ ] 点击"添加收款账号"
- [ ] 选择"支付宝"
- [ ] 输入账户名(需与实名认证姓名一致)
- [ ] 输入支付宝账号
- [ ] 点击"添加"
- [ ] **预期结果**:成功添加,显示在列表中,账号已脱敏
#### 1.2 添加微信账号
- [ ] 选择"微信"
- [ ] 输入账户名
- [ ] 输入微信号
- [ ] 点击"添加"
- [ ] **预期结果**:成功添加
#### 1.3 添加银行卡账号
- [ ] 选择"银行卡"
- [ ] 输入账户名
- [ ] 输入银行卡号
- [ ] 输入银行名称(如:中国工商银行)
- [ ] 输入开户支行(可选)
- [ ] 点击"添加"
- [ ] **预期结果**:成功添加,银行信息显示
#### 1.4 实名验证测试
- [ ] 使用未实名认证的账号添加收款账号
- [ ] **预期结果**:提示"请先完成实名认证"
- [ ] 使用已实名账号,但账户名与实名不一致
- [ ] **预期结果**:提示"账户名必须与实名认证姓名一致"
#### 1.5 账号数量限制测试
- [ ] 添加第5个收款账号
- [ ] **预期结果**:成功添加
- [ ] 尝试添加第6个收款账号
- [ ] **预期结果**:按钮变为"已达账号数量上限",无法添加
#### 1.6 设置默认账号
- [ ] 点击某个账号的"星星"图标
- [ ] **预期结果**:该账号标记为默认,其他账号取消默认
#### 1.7 编辑账号
- [ ] 点击某个账号的"编辑"按钮
- [ ] 修改支行信息(银行卡)
- [ ] 点击"更新"
- [ ] **预期结果**:信息更新成功
#### 1.8 删除账号
- [ ] 点击某个账号的"删除"按钮
- [ ] 确认删除
- [ ] **预期结果**:账号删除成功
---
### 2. 提现申请测试
#### 2.1 正常提现流程
- [ ] 访问 `/wallet/withdrawal`
- [ ] 查看钱包余额显示正确
- [ ] 选择收款账号
- [ ] 输入金额 100
- [ ] 查看到账金额显示为 100(手续费0%)
- [ ] 点击"提交申请"
- [ ] 确认提现
- [ ] **预期结果**:提现申请提交成功,在提现记录中显示"待审核"
#### 2.2 最低金额限制测试
- [ ] 输入金额 5
- [ ] **预期结果**:按钮禁用,或提示"提现金额低于最小限额"
#### 2.3 最高金额限制测试
- [ ] 输入金额 6000
- [ ] **预期结果**:提示"提现金额超过最大限额"
#### 2.4 余额不足测试
- [ ] 输入金额大于可用余额
- [ ] **预期结果**:显示红色警告"余额不足,可用余额:¥xxx"
#### 2.5 无收款账号测试
- [ ] 删除所有收款账号
- [ ] 访问提现页面
- [ ] **预期结果**:显示"还没有收款账号",引导添加
#### 2.6 取消提现测试
- [ ] 在提现记录中找到"待审核"状态的提现
- [ ] 点击"取消"按钮
- [ ] 确认取消
- [ ] **预期结果**:状态变为"已取消",余额解冻
#### 2.7 无法取消已审核提现
- [ ] 尝试取消"处理中"或"已完成"状态的提现
- [ ] **预期结果**:没有"取消"按钮
---
## 🔐 管理员端测试
### 3. 提现审核测试
#### 3.1 登录财务账号
- [ ] 使用财务管理员账号登录
- [ ] 访问 `/admin/withdrawals`
- [ ] **预期结果**:可以正常访问
#### 3.2 权限测试
- [ ] 使用非财务角色管理员登录
- [ ] 访问提现管理页面
- [ ] **预期结果**:无权限或看不到相关菜单
#### 3.3 查看提现列表
- [ ] 查看提现列表
- [ ] **预期结果**:显示所有提现申请,包含用户信息、金额、收款方式、状态
#### 3.4 状态筛选
- [ ] 选择"待审核"状态
- [ ] 点击"查询"
- [ ] **预期结果**:只显示待审核的提现
#### 3.5 用户筛选
- [ ] 输入用户ID
- [ ] 点击"查询"
- [ ] **预期结果**:只显示该用户的提现记录
#### 3.6 查看提现详情
- [ ] 点击某条记录的"详情"按钮
- [ ] **预期结果**
- 显示完整的提现信息
- 显示用户信息(昵称、手机号)
- 显示完整的收款账号(未脱敏)
- 显示金额信息
- 如有银行卡,显示开户支行
#### 3.7 审核通过
- [ ] 在待审核的提现详情中点击"通过审核"
- [ ] 输入审核备注(可选)
- [ ] 确认
- [ ] **预期结果**
- 状态变为"处理中"
- 显示审核人和审核时间
- 显示操作提示"请手动转账到用户收款账号"
#### 3.8 审核拒绝
- [ ] 在待审核的提现详情中点击"拒绝"
- [ ] 输入拒绝原因
- [ ] 确认
- [ ] **预期结果**
- 状态变为"已拒绝"
- 显示审核人和审核时间
- 用户余额解冻
#### 3.9 确认打款
- [ ] 手动转账到用户收款账号
- [ ] 在"处理中"的提现详情中点击"确认打款"
- [ ] 输入打款备注(如:已通过支付宝转账)
- [ ] 确认
- [ ] **预期结果**
- 状态变为"已完成"
- 显示打款人和打款时间
- 用户冻结余额扣除
#### 3.10 完整账号可见性测试
- [ ] 查看提现详情
- [ ] **预期结果**:管理员可以看到完整的收款账号(未脱敏)
---
## 💰 钱包余额测试
### 4. 余额流转测试
#### 4.1 提现冻结测试
- [ ] 记录提现前的可用余额和冻结余额
- [ ] 提交提现申请
- [ ] 查看钱包余额
- [ ] **预期结果**
- 可用余额减少(提现金额)
- 冻结余额增加(提现金额)
#### 4.2 审核拒绝解冻测试
- [ ] 管理员拒绝提现
- [ ] 查看钱包余额
- [ ] **预期结果**
- 冻结余额减少(提现金额)
- 可用余额增加(提现金额)
#### 4.3 用户取消解冻测试
- [ ] 用户取消待审核提现
- [ ] 查看钱包余额
- [ ] **预期结果**:余额解冻(同上)
#### 4.4 打款完成扣除测试
- [ ] 管理员确认打款
- [ ] 查看钱包余额
- [ ] **预期结果**
- 冻结余额减少(提现金额)
- 总余额减少(提现金额)
#### 4.5 钱包流水测试
- [ ] 访问钱包流水页面
- [ ] **预期结果**:可以看到以下流水记录
- `withdraw_freeze` - 提现冻结
- `withdraw_reject` - 提现拒绝(如有)
- `withdraw_cancel` - 用户取消提现(如有)
- `withdraw_complete` - 提现完成
---
## 🔄 业务流程完整性测试
### 5. 端到端测试
#### 场景1:正常提现流程
```
1. 用户添加收款账号 ✓
2. 用户发起提现 ✓
3. 余额冻结 ✓
4. 管理员审核通过 ✓
5. 管理员手动转账 ✓
6. 管理员确认打款 ✓
7. 冻结余额扣除 ✓
```
#### 场景2:提现被拒绝
```
1. 用户发起提现 ✓
2. 余额冻结 ✓
3. 管理员审核拒绝 ✓
4. 余额解冻 ✓
```
#### 场景3:用户取消提现
```
1. 用户发起提现 ✓
2. 余额冻结 ✓
3. 用户取消提现 ✓
4. 余额解冻 ✓
```
---
## 🎨 UI/UX 测试
### 6. 界面和交互测试
#### 6.1 响应式测试
- [ ] 桌面端显示正常
- [ ] 平板端显示正常
- [ ] 手机端显示正常(如已适配)
#### 6.2 加载状态
- [ ] 列表加载时显示 loading
- [ ] 提交操作时按钮显示 loading
- [ ] 数据为空时显示空状态
#### 6.3 错误提示
- [ ] 网络错误时显示友好提示
- [ ] 表单验证错误显示清晰
- [ ] 操作失败时显示具体原因
#### 6.4 确认对话框
- [ ] 删除账号需要确认
- [ ] 提交提现需要确认
- [ ] 取消提现需要确认
- [ ] 审核操作需要确认
#### 6.5 状态标签
- [ ] 待审核:黄色警告标签
- [ ] 处理中:蓝色主题标签
- [ ] 已完成:绿色成功标签
- [ ] 已拒绝:红色危险标签
- [ ] 已取消:灰色信息标签
---
## 🔒 安全性测试
### 7. 安全测试
#### 7.1 账号脱敏
- [ ] 用户端收款账号列表显示脱敏账号
- [ ] 提现记录显示脱敏账号
- [ ] 管理员端显示完整账号
#### 7.2 权限验证
- [ ] 未登录用户无法访问提现页面
- [ ] 用户只能查看自己的收款账号
- [ ] 用户只能查看自己的提现记录
- [ ] 非财务管理员无法访问提现审核
#### 7.3 实名验证
- [ ] 未实名用户无法添加收款账号
- [ ] 账户名不匹配无法添加
#### 7.4 金额验证
- [ ] 最低金额限制生效
- [ ] 最高金额限制生效
- [ ] 余额不足无法提现
---
## 📊 数据一致性测试
### 8. 数据库验证
#### 8.1 收款账号
- [ ] 账号加密存储(后端数据库检查)
- [ ] 默认账号只有一个
- [ ] 删除是软删除(status=disabled
#### 8.2 提现记录
- [ ] 提现单号唯一
- [ ] 账号信息快照正确
- [ ] 状态流转正确
- [ ] 审核信息记录完整
- [ ] 打款信息记录完整
#### 8.3 钱包流水
- [ ] 每次操作都有对应流水
- [ ] 流水金额正确
- [ ] 余额计算正确
- [ ] 业务类型标记正确
---
## ✅ 测试结果
### 通过标准
- [ ] 所有核心功能测试通过
- [ ] 无阻塞性 Bug
- [ ] UI/UX 友好
- [ ] 安全性验证通过
- [ ] 数据一致性正确
### 发现的问题
| 编号 | 问题描述 | 严重程度 | 状态 |
|------|----------|----------|------|
| 1 | | | |
| 2 | | | |
| 3 | | | |
---
## 📝 测试报告
**测试日期**
**测试人员**
**测试环境**
**测试结果**
**备注**
---
## 🚀 上线前检查清单
- [ ] 所有测试通过
- [ ] 生产环境加密密钥已更新
- [ ] 数据库迁移已在生产环境执行
- [ ] 财务管理员账号已创建
- [ ] 财务角色权限已配置
- [ ] 备份数据库
- [ ] 准备回滚方案
- [ ] 监控和告警配置
---
**测试完成后,系统即可上线使用!**
-215
View File
@@ -1,215 +0,0 @@
# 文件上传功能集成说明
## ✅ 已完成的修复
### 1. 钱包页面提现按钮(已修复)
**文件**`frontend/src/features/wallet/views/WalletView.vue`
**修复内容**
- ✅ 移除了 `disabled` 属性
- ✅ 添加了路由跳转功能
- ✅ 移除了"待开发"标签
- ✅ 改为 `type="primary"` 样式
**现在的功能**
- 点击"申请提现"按钮会跳转到 `/wallet/withdrawal` 页面
---
### 2. 收款账号凭证上传(已集成)
**文件**`frontend/src/features/wallet/components/PaymentAccountDialog.vue`
**集成内容**
- ✅ 导入文件上传 API (`uploadFile`)
- ✅ 添加上传处理函数 (`handleUpload`)
- ✅ 添加删除图片函数 (`removeImage`)
- ✅ 更新模板,支持图片预览和删除
- ✅ 添加完整样式
**功能特性**
1. **图片预览** - 已上传的图片显示缩略图
2. **删除功能** - 鼠标悬停显示删除按钮
3. **数量限制** - 最多上传 3 张图片
4. **文件验证**
- 只能上传图片文件
- 最大 5MB
5. **上传状态** - 显示上传进度和 loading 图标
6. **图片优化** - 自动压缩和优化图片(使用 WebP 格式)
**使用场景**
- 支付宝/微信收款码截图
- 银行卡照片
- 其他支付凭证
---
## 🎯 使用说明
### 用户端操作流程
1. **进入收款账号管理**
- 访问:http://localhost:5173/wallet/payment-accounts
- 或从钱包页面点击"管理收款账号"
2. **添加收款账号**
- 点击"添加收款账号"按钮
- 选择账号类型(支付宝/微信/银行卡)
- 填写必填信息
- 上传凭证图片(可选):
- 点击"上传凭证"按钮
- 选择图片文件
- 等待上传完成
- 可以上传最多 3 张图片
- 点击图片上的删除按钮可以移除
3. **申请提现**
- 在钱包页面点击"申请提现"
- 选择收款账号
- 输入金额
- 提交申请
---
## 📸 支持的图片格式
- **输入格式**JPEG, PNG, WebP
- **输出格式**:WebP(自动转换)
- **最大尺寸**5MB
- **图片处理**
- 自动压缩
- 保持宽高比
- 优化文件大小
---
## 🔧 技术实现
### 文件上传流程
```
1. 用户选择图片
2. 验证文件类型和大小
3. 调用 optimizeImageForUpload() 优化图片
4. 上传到服务器 (/api/files/upload)
5. 返回 URL 和元数据
6. 保存 URL 到 certificate_urls 数组
```
### API 接口
```typescript
uploadFile(file: File, scene: string): Promise<UploadedFile>
```
**参数**
- `file`: File 对象
- `scene`: 上传场景标识(使用 `'payment-cert'`
**返回**
```typescript
{
object_key: string
url: string
thumbnail_url?: string
medium_url?: string
filename: string
content_type: string
size: number
}
```
---
## 🎨 UI 设计
### 上传区域
```
┌─────────┬─────────┬─────────┐
│ 图片1 │ 图片2 │ + 上传 │
│ [删除] │ [删除] │ 凭证 │
└─────────┴─────────┴─────────┘
```
### 交互效果
- ✅ 鼠标悬停显示删除按钮
- ✅ 上传时显示 loading 图标
- ✅ 上传按钮有 hover 效果
- ✅ 图片预览(100x100px
- ✅ 响应式布局
---
## 🔒 安全说明
1. **文件验证**
- 前端验证文件类型
- 前端验证文件大小
- 后端也会进行二次验证
2. **图片处理**
- 自动压缩减小文件大小
- 统一转换为 WebP 格式
- 限制图片尺寸
3. **存储**
- URL 存储在数据库
- 图片存储在 MinIO/OSS
- 支持私有访问控制
---
## 📋 测试建议
### 功能测试
- [ ] 上传 JPEG 图片
- [ ] 上传 PNG 图片
- [ ] 上传 WebP 图片
- [ ] 上传超过 5MB 的图片(应该失败)
- [ ] 上传非图片文件(应该失败)
- [ ] 上传 3 张图片(达到上限)
- [ ] 删除已上传的图片
- [ ] 重新上传删除的图片
### UI 测试
- [ ] 图片预览显示正常
- [ ] 删除按钮悬停显示
- [ ] 上传中显示 loading
- [ ] 上传成功提示
- [ ] 上传失败提示
- [ ] 布局响应式
---
## 🐛 已知限制
1. **当前版本**
- 只支持图片上传
- 最多 3 张图片
- 单个文件最大 5MB
2. **未来优化**
- 支持 PDF 文件
- 批量上传
- 拖拽上传
- 图片裁剪
---
## 🎉 总结
**文件上传功能已完全集成**
两个主要修复:
1. ✅ 钱包页面"申请提现"按钮可点击
2. ✅ 收款账号凭证上传功能完整实现
用户现在可以:
- 正常使用提现功能
- 上传收款账号凭证图片
- 查看和管理已上传的图片
- 删除不需要的图片
系统功能完整,可以正常使用!
-218
View File
@@ -1,218 +0,0 @@
# ✅ 提现功能最终检查清单
## 🎉 开发完成状态
**开发进度**100% 完成
**测试状态**:待测试
**上线状态**:待部署
---
## 📦 已完成的功能
### 后端功能 ✅
- [x] 数据库表设计和迁移
- [x] 收款账号管理模块
- [x] 提现申请模块
- [x] 钱包流水集成
- [x] 权限和角色配置
- [x] API 接口开发
- [x] 路由配置
### 前端功能 ✅
- [x] 收款账号管理页面
- [x] 提现申请页面
- [x] 管理员审核页面
- [x] 文件上传功能
- [x] 路由配置
- [x] 编译测试通过
### 文档 ✅
- [x] 后端实施总结
- [x] API 接口文档
- [x] 前端开发总结
- [x] 测试清单
- [x] 完整实施总结
- [x] 文件上传集成说明
---
## 🔧 修复记录
### Bug #1: 钱包页面"申请提现"按钮无法点击
**状态**:✅ 已修复
**问题**
- 按钮被设置为 `disabled` 状态
- 显示"待开发"标签
- 点击没有响应
**修复**
- 移除 `disabled` 属性
- 添加路由跳转功能
- 移除"待开发"标签
- 改为 `type="primary"` 主题色
**文件**`frontend/src/features/wallet/views/WalletView.vue`
---
### Bug #2: 收款账号"上传凭证"按钮无法点击
**状态**:✅ 已修复
**问题**
- 上传按钮是占位按钮
- 没有实际功能
**修复**
- 集成项目文件上传 API
- 实现图片上传功能
- 添加图片预览
- 添加删除功能
- 添加文件验证
- 限制上传数量(3张)
**文件**`frontend/src/features/wallet/components/PaymentAccountDialog.vue`
---
## 🚀 部署前检查
### 1. 环境配置 ⚠️
#### 后端配置
```bash
# 1. 修改加密密钥(必须)
# 文件:backend/internal/modules/paymentaccount/repository.go
# 将 encryptionKey 改为随机生成的32字节密钥
const encryptionKey = "your-32-byte-secret-key-here!!"
```
#### 数据库迁移
```bash
# 2. 执行数据库迁移(必须)
cd backend/migrations
mysql -u root -p database < 000002_add_withdrawal_tables.sql
```
#### 财务管理员配置
```sql
-- 3. 创建财务管理员账号(必须)
-- 查询 finance 角色ID
SELECT id FROM roles WHERE code = 'finance';
-- 分配角色给管理员
INSERT INTO admin_user_roles (admin_user_id, role_id)
VALUES (ID, ID);
```
---
### 2. 功能测试 ⏳
#### 用户端测试
- [ ] 访问 http://localhost:5173/wallet
- [ ] 点击"申请提现"按钮能正常跳转
- [ ] 进入收款账号管理页面
- [ ] 添加支付宝账号
- [ ] 上传凭证图片
- [ ] 添加微信账号
- [ ] 添加银行卡账号
- [ ] 设置默认账号
- [ ] 删除账号
- [ ] 发起提现申请
- [ ] 查看提现记录
- [ ] 取消提现
#### 管理员端测试
- [ ] 使用财务账号登录
- [ ] 访问 http://localhost:5173/admin/withdrawals
- [ ] 查看提现列表
- [ ] 筛选待审核提现
- [ ] 查看提现详情
- [ ] 审核通过
- [ ] 审核拒绝
- [ ] 确认打款
#### 钱包余额测试
- [ ] 提现后余额冻结
- [ ] 审核拒绝后余额解冻
- [ ] 用户取消后余额解冻
- [ ] 打款完成后余额扣除
- [ ] 查看钱包流水
---
### 3. 安全检查 🔒
- [ ] 加密密钥已更新(生产环境)
- [ ] 账号信息加密存储
- [ ] 用户端账号脱敏显示
- [ ] 管理员端完整账号可见
- [ ] 实名验证生效
- [ ] 权限控制正常
- [ ] 金额限制生效
- [ ] 文件上传验证
---
## 📝 已修复的问题总结
### ✅ 问题1:申请提现按钮无法点击
- **修复文件**`WalletView.vue`
- **修复内容**:启用按钮,添加路由跳转
- **测试方法**:刷新页面,点击"申请提现"按钮,应跳转到提现页面
### ✅ 问题2:上传凭证按钮无法点击
- **修复文件**`PaymentAccountDialog.vue`
- **修复内容**:集成文件上传功能
- **测试方法**
1. 打开添加收款账号对话框
2. 点击"上传凭证"按钮
3. 选择图片文件
4. 查看上传结果
---
## 🎯 关键指标
### 功能完整性
- ✅ 用户端:100% 完成
- ✅ 管理端:100% 完成
- ✅ API 接口:100% 完成
- ✅ 文档:100% 完成
### Bug 修复
- ✅ Bug #1:申请提现按钮 - 已修复
- ✅ Bug #2:上传凭证按钮 - 已修复
---
## 📞 技术支持
### 文档位置
所有文档都在 `docs/` 目录下:
- `提现功能实施总结.md` - 后端完整说明
- `提现功能API文档.md` - API 接口文档
- `提现功能前端开发总结.md` - 前端开发说明
- `提现功能测试清单.md` - 详细测试清单
- `提现功能完整实施总结.md` - 项目总结
- `文件上传功能集成说明.md` - 文件上传详细说明
### 访问地址
- 用户端收款账号:http://localhost:5173/wallet/payment-accounts
- 用户端提现申请:http://localhost:5173/wallet/withdrawal
- 管理端提现审核:http://localhost:5173/admin/withdrawals
---
## 🎊 完成状态
**项目状态**:✅ 开发完成
**Bug 修复**:✅ 全部修复
**测试状态**:⏳ 待测试
**部署状态**:⏳ 待部署
---
**准备就绪,可以开始测试了!** 🚀
-672
View File
@@ -1,672 +0,0 @@
# HFB_SYS 项目架构分析报告
**分析时间**2026-06-06
**工具**Claude Code + Fast-Context MCP
**分析范围**:代码架构、业务流程、性能评估、优化建议
---
## 一、项目概述
### 1.1 项目定位
**HFB_SYS** 是一个游戏账号租赁交易平台(Rent-a-Game-Account Platform),支持用户发布、租赁游戏账号,并提供完整的订单、支付、客服、申诉等功能。
### 1.2 技术栈
#### 后端
- **语言**Go 1.21+
- **框架**Gin (HTTP路由)
- **数据库**MySQL 8.4
- **缓存**Redis 7.4
- **对象存储**MinIO
- **文档**Swagger (swaggo)
- **日志**zap
- **部署**Docker + Docker Compose
#### 前端
- **框架**Vue 3 + TypeScript
- **构建工具**Vite
- **UI库**Element Plus
- **路由**Vue Router
- **状态管理**Pinia
---
## 二、代码架构分析
### 2.1 后端模块划分
项目采用**按业务领域模块化**的设计,每个模块独立封装:
```
backend/internal/modules/
├── auth/ # 认证模块(短信登录、JWT)
├── user/ # 用户模块
├── realname/ # 实名认证模块
├── listing/ # 商品管理模块(游戏账号出租)
├── order/ # 订单管理模块
├── payment/ # 支付模块(乐刷)
├── wallet/ # 钱包模块
├── chat/ # 聊天模块
├── chathub/ # WebSocket聊天中心
├── dispute/ # 申诉模块
├── notification/ # 通知模块
├── file/ # 文件上传模块(MinIO)
├── adminauth/ # 管理员认证
├── adminuser/ # 用户管理(后台)
├── adminmgr/ # 管理员管理
├── adminrole/ # 角色权限管理
├── adminaudit/ # 审计日志
├── admindashboard/ # 仪表盘
├── systemconfig/ # 系统配置
└── announcement/ # 公告管理
```
**架构特点**
- ✅ 每个模块独立的 `handler.go`, `service.go`, `repository.go`, `dto.go`
- ✅ 清晰的三层架构(Handler → Service → Repository
- ✅ 依赖注入在 `router/router.go` 中统一管理
- ✅ 模块间通过接口解耦(如 order 模块注入 chat 模块的 repo
### 2.2 三层架构设计
```
┌─────────────────────────────────────┐
│ Handler Layer │ HTTP请求处理、参数验证、响应格式化
│ (handler.go) │
└──────────────┬──────────────────────┘
┌─────────────────────────────────────┐
│ Service Layer │ 业务逻辑、事务控制、跨模块协调
│ (service.go) │
└──────────────┬──────────────────────┘
┌─────────────────────────────────────┐
│ Repository Layer │ 数据访问、SQL查询、缓存操作
│ (repository.go) │
└─────────────────────────────────────┘
```
**示例:订单创建流程**
```go
// Handler 层
func (h *Handler) Create(c *gin.Context) {
var req CreateOrderRequest
c.ShouldBindJSON(&req)
order, err := h.service.CreateOrder(ctx, userID, req)
c.JSON(200, Response{Data: order})
}
// Service 层
func (s *Service) CreateOrder(ctx, userID, req) (*Order, error) {
// 1. 查询商品
listing := s.repo.FindListing(req.ListingID)
// 2. 验证库存
if listing.InTransaction { return ErrUnavailable }
// 3. 创建订单(事务)
order := s.repo.CreateOrder(...)
// 4. 锁定库存
s.repo.LockListing(listing.ID)
// 5. 创建聊天会话
s.chatRepo.CreateConversation(order.ID)
return order, nil
}
// Repository 层
func (r *Repository) CreateOrder(order *Order) error {
return r.db.Create(order).Error
}
```
### 2.3 路由设计
**API分组**
```go
/api/
/auth/ # 用户认证公开
/listings # 商品列表公开+认证
/orders # 订单管理需认证
/wallet # 钱包管理需认证
/chats # 聊天需认证
/disputes # 申诉需认证
/admin/ # 管理后台需管理员认证+权限
/users
/orders
/listings
/wallet/ledger
/disputes
/audit-logs
/roles
/admin-users
/announcements
```
**中间件链**
- `RequestID()` → 生成请求ID
- `RequestLogger()` → 请求日志
- `Recovery()` → Panic恢复
- `Auth()` → JWT认证(用户)
- `AdminAuth()` → JWT认证(管理员)
- `RequirePermission(code)` → RBAC权限校验
- `RequireRealname()` → 实名认证校验
---
## 三、核心业务流程
### 3.1 租号交易流程
```
号主发布商品
平台审核通过
商品上架展示
租客浏览选择
创建订单(待支付)
租客支付(冻结押金+租金)
号主交接账号(上传截图)
租客确认收货
租期结束 → 租客归还账号
号主确认归还 → 验收账号
系统结算(释放押金,转账租金给号主)
双方互评(可选)
```
**异常处理**
- 交接超时 → 自动取消订单
- 归还异常 → 发起申诉 → 客服介入 → 平台仲裁
- 恶意行为 → 冻结账户 → 扣除信用分
### 3.2 支付流程
```
用户下单
调用 payment.Start() → 生成支付单
调用第三方支付API(乐刷)
返回支付URL/二维码
用户扫码支付
支付回调 → payment.Notify()
验签 → 更新支付单状态
更新订单状态 → 冻结钱包余额
通知用户(WebSocket + 站内信)
```
**支持的支付方式**
- 乐刷支付(生产)
- Mock支付(测试)
- 钱包余额支付
### 3.3 客服聊天流程
```
用户/号主发起客服咨询
创建客服会话
系统自动发送欢迎语
客服在线 → 实时接收消息(WebSocket)
客服回复
支持快捷回复、会话转接、备注
```
**聊天类型**
- `order_group`:订单群聊(号主+租客)
- `support`:客服单聊
- `system`:系统通知
---
## 四、数据库设计分析
### 4.1 核心表结构
**用户相关**
- `users` - 用户基础信息
- `user_realname` - 实名认证记录
- `wallet_accounts` - 钱包账户
- `wallet_ledger` - 钱包流水
**商品订单**
- `game_accounts` - 游戏账号
- `rental_listings` - 租号商品
- `rental_orders` - 租赁订单
**交互模块**
- `chat_conversations` - 聊天会话
- `chat_messages` - 聊天消息
- `disputes` - 申诉记录
- `notifications` - 通知记录
**管理后台**
- `admin_users` - 管理员
- `admin_roles` - 角色
- `admin_permissions` - 权限
- `admin_role_permissions` - 角色权限关联
- `admin_user_roles` - 管理员角色关联
- `admin_audit_logs` - 审计日志
- `system_configs` - 系统配置
- `announcements` - 公告
### 4.2 关键索引
**高频查询索引**(通过代码分析推断):
```sql
-- 商品查询
CREATE INDEX idx_listings_status_review ON rental_listings(status, review_status, published_at);
-- 订单查询
CREATE INDEX idx_orders_renter ON rental_orders(renter_id, created_at);
CREATE INDEX idx_orders_owner ON rental_orders(owner_id, created_at);
CREATE INDEX idx_orders_status ON rental_orders(status, created_at);
-- 钱包流水
CREATE INDEX idx_ledger_user ON wallet_ledger(user_id, created_at);
-- 聊天消息
CREATE INDEX idx_messages_conv ON chat_messages(conversation_id, created_at);
-- 审计日志
CREATE INDEX idx_audit_admin ON admin_audit_logs(admin_id, created_at);
CREATE INDEX idx_audit_time ON admin_audit_logs(created_at);
```
### 4.3 性能瓶颈分析
**潜在慢查询点**(基于代码review):
1.**分页优化已完成**:所有管理后台列表已统一分页样式
2. ⚠️ **订单列表查询**:多条件筛选(status, renter_id, owner_id)可能需要复合索引
3. ⚠️ **钱包流水**:大量流水记录可能导致深度分页慢查询
4. ⚠️ **商品搜索**:全文搜索功能缺失(目前只能按status/review过滤)
---
## 五、压力测试结果评估
### 5.1 测试环境
- **平台**MacOS (Darwin 25.5.0)
- **数据库**MySQL 8.4 (Docker)
- **数据规模**
- 用户:10,001
- 商品:50,500
- 订单:30,200
- 钱包流水:100,500
### 5.2 性能基线(30并发60秒)
```
场景:realistic(真实业务比例)
- 35% 商品列表查询
- 25% 商品详情查询
- 15% 我的订单
- 10% 钱包余额
- 7% 聊天列表
- 5% 订单详情
- 2% 创建订单
- 1% 支付订单
结果:
✅ 总请求数:246,371
✅ 成功率:100%
✅ QPS4,106.18
延迟分布:
✅ P505ms ⭐ 优秀
✅ P9516ms ⭐ 优秀
✅ P9929ms ⭐ 良好
✅ 最大:492ms
```
### 5.3 性能评级
| 指标 | 标准 | 实际 | 评级 |
|------|------|------|------|
| QPS | >2000 | 4106 | ⭐⭐⭐ |
| P50延迟 | <10ms | 5ms | ⭐⭐⭐ |
| P95延迟 | <50ms | 16ms | ⭐⭐⭐ |
| P99延迟 | <100ms | 29ms | ⭐⭐⭐ |
| 成功率 | >95% | 100% | ⭐⭐⭐ |
**结论**:系统性能优秀,能够支撑中等规模业务(日活1万+)。
---
## 六、代码质量评估
### 6.1 优点
**清晰的模块化设计**
- 每个业务模块独立,职责明确
- 依赖注入统一管理
- 三层架构规范
**完善的中间件体系**
- 请求日志、认证、权限、错误恢复
- 可复用、易扩展
**RBAC权限系统**
- 角色-权限分离
- 灵活的权限配置
- 细粒度权限控制
**实时通信支持**
- WebSocket客服系统
- 订单状态推送
- 在线状态管理
**审计日志**
- 记录所有管理后台操作
- 便于追溯和审计
### 6.2 可改进点
⚠️ **缺少单元测试**
- 建议:为核心业务逻辑(订单、支付、钱包)添加单元测试
- 目标覆盖率:>60%
⚠️ **缺少集成测试**
- 建议:为关键业务流程添加E2E测试
- 场景:创建订单→支付→交接→归还→结算
⚠️ **缺少API文档维护**
- 虽然有Swagger,但需要保持与代码同步
- 建议:在CI中添加swagger检查
⚠️ **错误处理可以更细化**
- 当前:统一错误码(如 "bad_request"
- 建议:细分业务错误码(如 "listing_unavailable", "insufficient_balance"
⚠️ **缺少限流保护**
- 建议:添加API限流中间件(如 rate limiter
- 保护高频API(登录、创建订单、支付)
---
## 七、安全性分析
### 7.1 已实现的安全措施
**认证与授权**
- JWT Token认证
- RBAC权限控制
- 实名认证要求(敏感操作)
**数据安全**
- 密码加密存储(假设)
- 敏感信息脱敏(手机号、身份证)
- 支付回调验签
**输入验证**
- 参数校验(Gin binding
- SQL注入防护(GORM参数化查询)
**操作审计**
- 管理员操作日志
- IP地址记录
### 7.2 潜在安全风险
⚠️ **缺少HTTPS强制**
- 建议:生产环境强制HTTPS
- 在反向代理(Nginx)层面处理
⚠️ **短信验证码限流不足**
- 当前:60秒冷却期
- 建议:添加IP级别限流、图形验证码
⚠️ **WebSocket认证**
- 需确认:WebSocket连接是否有认证机制
- 建议:在握手阶段验证JWT token
⚠️ **文件上传安全**
- 需确认:是否有文件类型/大小验证
- 建议:文件类型白名单、病毒扫描
---
## 八、性能优化建议
### 8.1 数据库优化
**索引优化**
```sql
-- 添加复合索引
CREATE INDEX idx_orders_renter_status ON rental_orders(renter_id, status, created_at);
CREATE INDEX idx_orders_owner_status ON rental_orders(owner_id, status, created_at);
-- 优化钱包流水查询
CREATE INDEX idx_ledger_user_type ON wallet_ledger(user_id, biz_type, created_at);
-- 优化商品搜索
CREATE INDEX idx_listings_game_status ON rental_listings(game_name, status, review_status);
```
**查询优化**
- 使用游标分页替代offset(深度分页场景)
- 添加查询结果缓存(商品列表、系统配置)
### 8.2 缓存策略
**推荐缓存内容**
```go
// 热点商品(5分钟)
"listing:hot:{id}" Listing JSON
// 商品列表(1分钟)
"listings:page:{page}:{params}" []Listing JSON
// 用户信息(5分钟)
"user:{id}" User JSON
// 系统配置(长期)
"config:{key}" Config JSON
// 在线管理员列表(30秒)
"admin:online" []AdminID
```
### 8.3 架构优化
**读写分离**
- 主从复制(MySQL Replication
- 读请求走从库
- 写请求走主库
**消息队列**
- 异步任务:通知发送、日志写入、统计计算
- 技术选型:RabbitMQ / Kafka / Redis Stream
**CDN加速**
- 静态资源(前端、图片)走CDN
- 减轻服务器带宽压力
---
## 九、可扩展性分析
### 9.1 水平扩展能力
**无状态设计**
- ✅ HTTP服务无状态(JWT存储在客户端)
- ✅ Session存储在Redis(支持多实例)
- ⚠️ WebSocket有状态(需要sticky session或Redis pub/sub
**负载均衡方案**
```
┌────────────┐
Internet ─────┤ Nginx LB │
└──────┬─────┘
┌────────────┼────────────┐
│ │ │
┌───▼──┐ ┌──▼───┐ ┌───▼──┐
│ API1 │ │ API2 │ │ API3 │
└───┬──┘ └──┬───┘ └───┬──┘
│ │ │
└───────────┼────────────┘
┌───────▼────────┐
│ MySQL/Redis │
└────────────────┘
```
### 9.2 数据库扩展
**垂直扩展**
- 升级MySQL配置(CPU、内存、SSD
- 优化MySQL参数(innodb_buffer_pool_size、max_connections
**水平扩展**
- 分库分表(按用户ID哈希)
- 读写分离(主从复制)
- 分片方案(ShardingSphere
---
## 十、部署与运维
### 10.1 容器化部署
**当前方案**
- Docker Compose(开发/测试环境)
- 包含:MySQL, Redis, MinIO, Backend
**生产建议**
- Kubernetes编排
- 自动伸缩(HPA
- 健康检查
- 滚动更新
### 10.2 监控告警
**推荐方案**
```
Prometheus + Grafana + AlertManager
监控指标:
- QPS、延迟(P50/P95/P99
- 错误率
- 数据库连接数
- Redis内存使用率
- API响应时间
- 业务指标(订单量、交易额)
告警规则:
- API错误率 > 5%
- P99延迟 > 1秒
- 数据库连接池耗尽
- Redis内存 > 80%
```
### 10.3 日志管理
**推荐方案**
```
ELK Stack (Elasticsearch + Logstash + Kibana)
日志类型:
- 访问日志(Nginx
- 应用日志(zap
- 错误日志
- 审计日志
日志级别:
开发:DEBUG
生产:INFO(可动态调整)
```
---
## 十一、总结与建议
### 11.1 项目亮点
**清晰的模块化架构**:易维护、易扩展
**完善的RBAC权限系统**:灵活、安全
**优秀的性能表现**QPS 4000+, P95延迟16ms
**实时客服系统**WebSocket支持
**审计日志完善**:可追溯、可审计
### 11.2 短期优化建议(1-2周)
1.**管理后台分页统一** - 已完成
2. **添加API限流**:防止恶意请求
3. **优化短信验证码限流**:增加图形验证码
4. **完善错误码体系**:细分业务错误
5. **添加关键接口的单元测试**
### 11.3 中期优化建议(1-2月)
1. **实现缓存层**Redis缓存热点数据
2. **数据库索引优化**:添加复合索引
3. **实现读写分离**MySQL主从复制
4. **添加监控告警**Prometheus + Grafana
5. **完善API文档**:保持Swagger同步
### 11.4 长期演进建议(3-6月)
1. **微服务拆分**:订单、支付、聊天独立服务
2. **引入消息队列**:异步任务处理
3. **数据库分库分表**:应对数据增长
4. **容器编排**Kubernetes部署
5. **全链路监控**:分布式追踪(Jaeger
---
## 附录
### A. 技术债务清单
| 优先级 | 问题 | 影响 | 建议 |
|-------|------|------|------|
| P0 | 缺少单元测试 | 回归风险高 | 添加核心业务测试 |
| P1 | 缺少API限流 | 容易被刷 | 添加限流中间件 |
| P1 | 短信限流不足 | 验证码被刷 | 增加图形验证码 |
| P2 | 缺少缓存层 | 数据库压力大 | 添加Redis缓存 |
| P2 | 深度分页慢 | 用户体验差 | 游标分页 |
| P3 | 缺少监控 | 故障发现慢 | Prometheus |
### B. 性能测试数据
**商品查询场景**30并发60秒):
- QPS4,106
- P50延迟:5ms
- P95延迟:16ms
- 成功率:100%
**管理后台场景**(待测试):
- 预期QPS2,000+
- 预期P95延迟:<50ms
---
**报告编写人**Claude Opus 4.8
**审核状态**:已完成
**下次更新**:根据性能测试结果动态调整
-94
View File
@@ -1,94 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
# 这个脚本用于删除已合并到 000001_init.sql 的旧迁移文件
# 使用场景:迁移文件合并后,清理旧的分散文件
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
MIGRATIONS_DIR="${ROOT_DIR}/backend/migrations"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[1;34m'
NC='\033[0m'
log() {
printf "${BLUE}[clean]${NC} %s\n" "$*"
}
log_success() {
printf "${GREEN}[clean]${NC} %s\n" "$*"
}
log_warn() {
printf "${YELLOW}[clean]${NC} %s\n" "$*"
}
log_error() {
printf "${RED}[clean]${NC} %s\n" "$*" >&2
}
# 要删除的旧迁移文件列表
OLD_MIGRATIONS=(
"000002_payment_refund_schema.sql"
"000003_add_indexes.sql"
"000004_add_support_status.sql"
"000005_add_announcements.sql"
"000006_insert_sample_announcements.sql"
"000007_add_announcement_permissions.sql"
"000008_fix_announcement_charset.sql"
)
main() {
cd "${MIGRATIONS_DIR}"
log "检查旧迁移文件..."
local found=0
local file
for file in "${OLD_MIGRATIONS[@]}"; do
if [[ -f "${file}" ]]; then
found=$((found + 1))
log_warn "发现旧文件:${file}"
fi
done
if [[ "${found}" == "0" ]]; then
log_success "没有发现旧的迁移文件,无需清理"
exit 0
fi
log ""
log "即将删除 ${found} 个旧迁移文件"
log "这些文件的内容已经合并到 000001_init.sql 中"
log ""
# 确认删除
read -p "确认删除?(yes/no): " -r
echo
if [[ ! "${REPLY}" =~ ^[Yy][Ee][Ss]$ ]]; then
log "取消删除"
exit 0
fi
# 执行删除
local deleted=0
for file in "${OLD_MIGRATIONS[@]}"; do
if [[ -f "${file}" ]]; then
rm -f "${file}"
log_success "已删除:${file}"
deleted=$((deleted + 1))
fi
done
log ""
log_success "清理完成,已删除 ${deleted} 个文件"
log ""
log "注意事项:"
log "1. 如果是开发环境,建议执行:./scripts/dev.sh --clean-init"
log "2. 如果是生产环境,建议执行:./scripts/deploy-prod.sh --clean-init"
log "3. 这些命令会清理旧数据库并使用新的 000001_init.sql 初始化"
}
main "$@"
+3 -16
View File
@@ -62,7 +62,6 @@ show_help() {
选项:
--reset-db 重置数据库(删除并重建)
--seed-only 仅重新同步基础数据
--no-migrate 不执行数据库迁移
--no-frontend 不启动前端
--no-backend 不启动后端
@@ -90,14 +89,12 @@ show_help() {
示例:
./scripts/dev.sh # 正常启动
./scripts/dev.sh --reset-db # 重置数据库后启动(推荐迁移后使用)
./scripts/dev.sh --seed-only # 重新同步基础数据
EOF
exit 0
}
# 参数解析
RESET_DB="${DEV_RESET_DB:-0}"
SEED_ONLY=0
NO_MIGRATE=0
NO_FRONTEND=0
NO_BACKEND=0
@@ -108,10 +105,6 @@ while [[ $# -gt 0 ]]; do
RESET_DB=1
shift
;;
--seed-only)
SEED_ONLY=1
shift
;;
--no-migrate)
NO_MIGRATE=1
shift
@@ -546,13 +539,13 @@ watch_processes() {
main() {
need_cmd docker
if [[ "${SEED_ONLY}" != "1" && "${NO_BACKEND}" == "0" ]]; then
if [[ "${NO_BACKEND}" == "0" ]]; then
need_cmd go
fi
if [[ "${SEED_ONLY}" != "1" && "${NO_FRONTEND}" == "0" ]]; then
if [[ "${NO_FRONTEND}" == "0" ]]; then
need_cmd npm
fi
if [[ "${SEED_ONLY}" != "1" && ( "${NO_BACKEND}" == "0" || "${NO_FRONTEND}" == "0" ) ]]; then
if [[ "${NO_BACKEND}" == "0" || "${NO_FRONTEND}" == "0" ]]; then
need_cmd curl
fi
@@ -575,12 +568,6 @@ main() {
reset_database
run_migrations
# 仅同步基础数据模式
if [[ "${SEED_ONLY}" == "1" ]]; then
log_success "基础数据同步完成,退出"
exit 0
fi
if [[ "${NO_BACKEND}" == "0" ]]; then
ensure_port_free "${BACKEND_PORT}" "后端"
start_backend
+1 -1
View File
@@ -300,7 +300,7 @@ function run_stress_test() {
log_info "编译压测工具..."
cd "$SCRIPT_DIR"
go build -o stress_test stress_test.go
go build -o stress_test load_stress.go
if [ $? -ne 0 ]; then
log_error "压测工具编译失败"