171 lines
4.9 KiB
Go
171 lines
4.9 KiB
Go
// 服务入口,初始化所有组件并启动 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, &cfg.System)
|
||
|
||
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)
|
||
}
|
||
}
|