feat: 完成B端认证系统和商户管理模块测试补全

主要变更:
- 新增B端认证系统(后台+H5):登录、登出、Token刷新、密码修改
- 完善商户管理和商户账号管理功能
- 补全单元测试(ShopService: 72.5%, ShopAccountService: 79.8%)
- 新增集成测试(商户管理+商户账号管理)
- 归档OpenSpec提案(add-shop-account-management, implement-b-end-auth-system)
- 完善文档(使用指南、API文档、认证架构说明)

测试统计:
- 13个测试套件,37个测试用例,100%通过率
- 平均覆盖率76.2%,达标

OpenSpec验证:通过(strict模式)
This commit is contained in:
2026-01-15 18:15:17 +08:00
parent 7ccd3d146c
commit 18f35f3ef4
64 changed files with 11875 additions and 242 deletions

View File

@@ -1,9 +1,16 @@
package bootstrap
import (
"context"
"time"
"github.com/break/junhong_cmp_fiber/internal/middleware"
"github.com/break/junhong_cmp_fiber/pkg/auth"
pkgauth "github.com/break/junhong_cmp_fiber/pkg/auth"
"github.com/break/junhong_cmp_fiber/pkg/config"
"github.com/break/junhong_cmp_fiber/pkg/constants"
"github.com/break/junhong_cmp_fiber/pkg/errors"
pkgmiddleware "github.com/break/junhong_cmp_fiber/pkg/middleware"
"github.com/gofiber/fiber/v2"
)
// initMiddlewares 初始化所有中间件
@@ -12,12 +19,76 @@ func initMiddlewares(deps *Dependencies) *Middlewares {
cfg := config.Get()
// 创建 JWT Manager
jwtManager := auth.NewJWTManager(cfg.JWT.SecretKey, cfg.JWT.TokenDuration)
jwtManager := pkgauth.NewJWTManager(cfg.JWT.SecretKey, cfg.JWT.TokenDuration)
// 创建个人客户认证中间件
personalAuthMiddleware := middleware.NewPersonalAuthMiddleware(jwtManager, deps.Logger)
// 创建 Token Manager用于后台和H5认证
accessTTL := time.Duration(cfg.JWT.AccessTokenTTL) * time.Second
refreshTTL := time.Duration(cfg.JWT.RefreshTokenTTL) * time.Second
tokenManager := pkgauth.NewTokenManager(deps.Redis, accessTTL, refreshTTL)
// 创建后台认证中间件
adminAuthMiddleware := createAdminAuthMiddleware(tokenManager)
// 创建H5认证中间件
h5AuthMiddleware := createH5AuthMiddleware(tokenManager)
return &Middlewares{
PersonalAuth: personalAuthMiddleware,
AdminAuth: adminAuthMiddleware,
H5Auth: h5AuthMiddleware,
}
}
func createAdminAuthMiddleware(tokenManager *pkgauth.TokenManager) fiber.Handler {
return pkgmiddleware.Auth(pkgmiddleware.AuthConfig{
TokenValidator: func(token string) (*pkgmiddleware.UserContextInfo, error) {
tokenInfo, err := tokenManager.ValidateAccessToken(context.Background(), token)
if err != nil {
return nil, errors.New(errors.CodeInvalidToken, "认证令牌无效或已过期")
}
// 检查用户类型:后台允许 SuperAdmin(1), Platform(2), Agent(3)
if tokenInfo.UserType != constants.UserTypeSuperAdmin &&
tokenInfo.UserType != constants.UserTypePlatform &&
tokenInfo.UserType != constants.UserTypeAgent {
return nil, errors.New(errors.CodeForbidden, "权限不足")
}
return &pkgmiddleware.UserContextInfo{
UserID: tokenInfo.UserID,
UserType: tokenInfo.UserType,
ShopID: tokenInfo.ShopID,
EnterpriseID: tokenInfo.EnterpriseID,
}, nil
},
SkipPaths: []string{"/api/admin/login", "/api/admin/refresh-token"},
})
}
func createH5AuthMiddleware(tokenManager *pkgauth.TokenManager) fiber.Handler {
return pkgmiddleware.Auth(pkgmiddleware.AuthConfig{
TokenValidator: func(token string) (*pkgmiddleware.UserContextInfo, error) {
tokenInfo, err := tokenManager.ValidateAccessToken(context.Background(), token)
if err != nil {
return nil, errors.New(errors.CodeInvalidToken, "认证令牌无效或已过期")
}
// 检查用户类型H5 允许 Agent(3), Enterprise(4)
if tokenInfo.UserType != constants.UserTypeAgent &&
tokenInfo.UserType != constants.UserTypeEnterprise {
return nil, errors.New(errors.CodeForbidden, "权限不足")
}
return &pkgmiddleware.UserContextInfo{
UserID: tokenInfo.UserID,
UserType: tokenInfo.UserType,
ShopID: tokenInfo.ShopID,
EnterpriseID: tokenInfo.EnterpriseID,
}, nil
},
SkipPaths: []string{"/api/h5/login", "/api/h5/refresh-token"},
})
}