Files
sc-lktx-mp/sc-lktx-backend/cmd/server/main.go
huangjin 37930bb3c2 .
2026-06-29 18:44:25 +08:00

171 lines
4.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 服务入口,初始化所有组件并启动 HTTP 服务
package main
import (
"fmt"
"log"
"os"
"com.sclktx/m/v2/internal/admin"
"com.sclktx/m/v2/internal/auth"
"com.sclktx/m/v2/internal/common/middleware"
"com.sclktx/m/v2/internal/modules/appointment"
"com.sclktx/m/v2/internal/modules/banner"
"com.sclktx/m/v2/internal/modules/certification"
"com.sclktx/m/v2/internal/modules/upload"
"com.sclktx/m/v2/internal/modules/workflow"
"com.sclktx/m/v2/internal/pkg/config"
"com.sclktx/m/v2/internal/pkg/database"
"com.sclktx/m/v2/internal/pkg/dingtalk"
"com.sclktx/m/v2/internal/pkg/minio"
"com.sclktx/m/v2/internal/pkg/wechat"
"github.com/gin-gonic/gin"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
"go.uber.org/zap"
// swagger docs
_ "com.sclktx/m/v2/docs"
)
// @title 来访预约管理系统 API
// @version 1.0
// @description 来访预约管理系统的后端API接口文档
// @termsOfService http://swagger.io/terms/
// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email support@swagger.io
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @host localhost:8080
// @BasePath /v1
// @securityDefinitions.apikey BearerAuth
// @in header
// @name Authorization
// @externalDocs.description OpenAPI
// @externalDocs.url https://swagger.io/resources/open-api/
func main() {
configPath := "config/config.yaml"
if len(os.Args) > 1 {
configPath = os.Args[1]
}
cfg, err := config.LoadConfig(configPath)
if err != nil {
log.Fatalf("Failed to load config: %v", err)
}
logger, err := zap.NewProduction()
if err != nil {
log.Fatalf("Failed to init logger: %v", err)
}
defer logger.Sync()
db := database.InitDB(&cfg.Database)
// 初始化基础数据(流程定义等)
database.InitData(db)
wxClient := wechat.NewMiniProgramClient(&cfg.Wechat)
dingTalkClient := dingtalk.NewClient(&cfg.DingTalk)
minioClient, err := minio.NewClient(&cfg.MinIO)
if err != nil {
log.Printf("Warning: MinIO 初始化失败: %v", err)
}
gin.SetMode(cfg.Server.Mode)
r := gin.New()
r.Use(middleware.CORS())
r.Use(middleware.Logger(logger))
r.Use(gin.Recovery())
r.GET("/health", func(c *gin.Context) {
c.JSON(200, gin.H{"status": "ok"})
})
// Swagger 文档
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
v1 := r.Group("/v1")
authHandler := auth.NewAuthHandler(db, cfg, wxClient)
// ========== 管理员路由(使用独立管理员 JWT优先注册避免被小程序 JWT 拦截)==========
var adminHandler *admin.AdminHandler
{
adminAuthHandler := admin.NewAdminAuthHandler(db, cfg.JWT.Secret, cfg.JWT.ExpireHours)
// 公开:管理员登录
v1.POST("/admin/login", adminAuthHandler.Login)
adminJWTMiddleware := middleware.AdminJWTAuth(cfg.JWT.Secret)
// 管理员个人信息
v1.GET("/admin/profile", adminJWTMiddleware, adminAuthHandler.GetProfile)
// 管理员 CRUD 接口
adminHandler = admin.NewAdminHandler(db, wxClient)
adminHandler.RegisterRoutes(v1, adminJWTMiddleware)
// 工作流流程定义管理(管理员后台使用)
wfAdmin := workflow.NewHandler(db, wxClient.SendSubscribeMessage, nil)
adminWF := v1.Group("/admin", adminJWTMiddleware)
{
adminWF.GET("/workflow/definitions", wfAdmin.ListDefinitions)
adminWF.POST("/workflow/definitions", wfAdmin.CreateDefinition)
adminWF.PUT("/workflow/definitions/:id", wfAdmin.UpdateDefinition)
adminWF.DELETE("/workflow/definitions/:id", wfAdmin.DeleteDefinition)
// 工作流实例查询(管理后台查看审批进度)
adminWF.GET("/workflow/instances", wfAdmin.ListInstances)
adminWF.GET("/workflow/instances/:id", wfAdmin.GetInstanceDetail)
}
}
// 公开路由
{
authHandler.RegisterRoutes(v1)
bannerHandler := banner.NewBannerHandler(db)
bannerHandler.RegisterRoutes(v1)
uploadHandler := upload.NewUploadHandler(wxClient, minioClient)
uploadHandler.RegisterRoutes(v1)
// 到访区域列表(小程序端需要)
v1.GET("/visitor-areas", adminHandler.ListVisitorAreas)
// 部门列表(小程序认证申请需要)
v1.GET("/departments", adminHandler.ListAllDepartments)
}
// 认证路由(需要 JWT
authV1 := v1.Group("")
authV1.Use(middleware.JWTAuth(cfg.JWT.Secret))
{
authHandler.RegisterAuthRoutes(authV1)
appointmentHandler := appointment.NewAppointmentHandler(db, wxClient, dingTalkClient)
appointmentHandler.RegisterRoutes(authV1)
certificationHandler := certification.NewHandler(db)
certificationHandler.RegisterRoutes(authV1)
workflowHandler := workflow.NewHandler(db, wxClient.SendSubscribeMessage, dingTalkClient)
workflowHandler.RegisterRoutes(authV1)
}
addr := fmt.Sprintf(":%d", cfg.Server.Port)
logger.Info("Server starting", zap.String("addr", addr))
log.Printf("Server is running at http://localhost%s", addr)
if err := r.Run(addr); err != nil {
log.Fatalf("Failed to start server: %v", err)
}
}