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:
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/bootstrap"
|
||||
"github.com/break/junhong_cmp_fiber/internal/handler/admin"
|
||||
"github.com/break/junhong_cmp_fiber/internal/handler/h5"
|
||||
"github.com/break/junhong_cmp_fiber/internal/routes"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/openapi"
|
||||
)
|
||||
@@ -16,27 +17,39 @@ import (
|
||||
// 生成失败时记录错误但不影响程序继续运行
|
||||
func generateOpenAPIDocs(outputPath string, logger *zap.Logger) {
|
||||
// 1. 创建生成器
|
||||
adminDoc := openapi.NewGenerator("Admin API", "1.0")
|
||||
adminDoc := openapi.NewGenerator("君鸿卡管系统 API", "1.0.0")
|
||||
|
||||
// 2. 创建临时 Fiber App 用于路由注册
|
||||
app := fiber.New()
|
||||
|
||||
// 3. 创建 Handler(使用 nil 依赖,因为只需要路由结构)
|
||||
adminAuthHandler := admin.NewAuthHandler(nil, nil)
|
||||
h5AuthHandler := h5.NewAuthHandler(nil, nil)
|
||||
accHandler := admin.NewAccountHandler(nil)
|
||||
roleHandler := admin.NewRoleHandler(nil)
|
||||
permHandler := admin.NewPermissionHandler(nil)
|
||||
shopHandler := admin.NewShopHandler(nil)
|
||||
shopAccHandler := admin.NewShopAccountHandler(nil)
|
||||
|
||||
handlers := &bootstrap.Handlers{
|
||||
Account: accHandler,
|
||||
Role: roleHandler,
|
||||
Permission: permHandler,
|
||||
AdminAuth: adminAuthHandler,
|
||||
H5Auth: h5AuthHandler,
|
||||
Account: accHandler,
|
||||
Role: roleHandler,
|
||||
Permission: permHandler,
|
||||
Shop: shopHandler,
|
||||
ShopAccount: shopAccHandler,
|
||||
}
|
||||
|
||||
// 4. 注册路由到文档生成器
|
||||
// 4. 注册后台路由到文档生成器
|
||||
adminGroup := app.Group("/api/admin")
|
||||
routes.RegisterAdminRoutes(adminGroup, handlers, adminDoc, "/api/admin")
|
||||
routes.RegisterAdminRoutes(adminGroup, handlers, &bootstrap.Middlewares{}, adminDoc, "/api/admin")
|
||||
|
||||
// 5. 保存规范到指定路径
|
||||
// 5. 注册 H5 路由到文档生成器
|
||||
h5Group := app.Group("/api/h5")
|
||||
routes.RegisterH5Routes(h5Group, handlers, &bootstrap.Middlewares{}, adminDoc, "/api/h5")
|
||||
|
||||
// 6. 保存规范到指定路径
|
||||
if err := adminDoc.Save(outputPath); err != nil {
|
||||
logger.Error("生成 OpenAPI 文档失败", zap.String("path", outputPath), zap.Error(err))
|
||||
return
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/bytedance/sonic"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
@@ -19,6 +20,8 @@ import (
|
||||
"github.com/break/junhong_cmp_fiber/internal/bootstrap"
|
||||
internalMiddleware "github.com/break/junhong_cmp_fiber/internal/middleware"
|
||||
"github.com/break/junhong_cmp_fiber/internal/routes"
|
||||
"github.com/break/junhong_cmp_fiber/internal/service/verification"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/auth"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/config"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/database"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/logger"
|
||||
@@ -47,34 +50,40 @@ func main() {
|
||||
queueClient := initQueue(redisClient, appLogger)
|
||||
defer closeQueue(queueClient, appLogger)
|
||||
|
||||
// 6. 初始化所有业务组件(通过 Bootstrap)
|
||||
// 6. 初始化认证管理器
|
||||
jwtManager, tokenManager, verificationSvc := initAuthComponents(cfg, redisClient, appLogger)
|
||||
|
||||
// 7. 初始化所有业务组件(通过 Bootstrap)
|
||||
result, err := bootstrap.Bootstrap(&bootstrap.Dependencies{
|
||||
DB: db,
|
||||
Redis: redisClient,
|
||||
Logger: appLogger,
|
||||
DB: db,
|
||||
Redis: redisClient,
|
||||
Logger: appLogger,
|
||||
JWTManager: jwtManager,
|
||||
TokenManager: tokenManager,
|
||||
VerificationService: verificationSvc,
|
||||
})
|
||||
if err != nil {
|
||||
appLogger.Fatal("初始化业务组件失败", zap.Error(err))
|
||||
}
|
||||
|
||||
// 7. 启动配置监听器
|
||||
// 8. 启动配置监听器
|
||||
watchCtx, cancelWatch := context.WithCancel(context.Background())
|
||||
defer cancelWatch()
|
||||
go config.Watch(watchCtx, appLogger)
|
||||
|
||||
// 8. 创建 Fiber 应用
|
||||
// 9. 创建 Fiber 应用
|
||||
app := createFiberApp(cfg, appLogger)
|
||||
|
||||
// 9. 注册中间件
|
||||
// 10. 注册中间件
|
||||
initMiddleware(app, cfg, appLogger)
|
||||
|
||||
// 10. 注册路由
|
||||
// 11. 注册路由
|
||||
initRoutes(app, cfg, result, queueClient, db, redisClient, appLogger)
|
||||
|
||||
// 11. 生成 OpenAPI 文档
|
||||
// 12. 生成 OpenAPI 文档
|
||||
generateOpenAPIDocs("./openapi.yaml", appLogger)
|
||||
|
||||
// 12. 启动服务器
|
||||
// 13. 启动服务器
|
||||
startServer(app, cfg, appLogger, cancelWatch)
|
||||
}
|
||||
|
||||
@@ -281,3 +290,15 @@ func startServer(app *fiber.App, cfg *config.Config, appLogger *zap.Logger, canc
|
||||
|
||||
appLogger.Info("服务器已停止")
|
||||
}
|
||||
|
||||
func initAuthComponents(cfg *config.Config, redisClient *redis.Client, appLogger *zap.Logger) (*auth.JWTManager, *auth.TokenManager, *verification.Service) {
|
||||
jwtManager := auth.NewJWTManager(cfg.JWT.SecretKey, cfg.JWT.TokenDuration)
|
||||
|
||||
accessTTL := time.Duration(cfg.JWT.AccessTokenTTL) * time.Second
|
||||
refreshTTL := time.Duration(cfg.JWT.RefreshTokenTTL) * time.Second
|
||||
tokenManager := auth.NewTokenManager(redisClient, accessTTL, refreshTTL)
|
||||
|
||||
verificationSvc := verification.NewService(redisClient, nil, appLogger)
|
||||
|
||||
return jwtManager, tokenManager, verificationSvc
|
||||
}
|
||||
|
||||
@@ -34,16 +34,18 @@ func generateAdminDocs(outputPath string) error {
|
||||
accHandler := admin.NewAccountHandler(nil)
|
||||
roleHandler := admin.NewRoleHandler(nil)
|
||||
permHandler := admin.NewPermissionHandler(nil)
|
||||
authHandler := admin.NewAuthHandler(nil, nil)
|
||||
|
||||
handlers := &bootstrap.Handlers{
|
||||
Account: accHandler,
|
||||
Role: roleHandler,
|
||||
Permission: permHandler,
|
||||
AdminAuth: authHandler,
|
||||
}
|
||||
|
||||
// 4. 注册路由到文档生成器
|
||||
adminGroup := app.Group("/api/admin")
|
||||
routes.RegisterAdminRoutes(adminGroup, handlers, adminDoc, "/api/admin")
|
||||
routes.RegisterAdminRoutes(adminGroup, handlers, &bootstrap.Middlewares{}, adminDoc, "/api/admin")
|
||||
|
||||
// 5. 保存规范到指定路径
|
||||
if err := adminDoc.Save(outputPath); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user