后端: Go(Gin+GORM+MySQL+Redis) - 17张业务表(yz_pw_前缀), 自动迁移 - JWT认证(3小时) + 盐+MD5密码 + 图形验证码 - 班级CRUD/加入(8人姓名验证/邀请码)/审核/30天自动清理 - 系统配置(16项)/菜单管理(动态路由)/数据统计 - 文件MD5去重/数据隔离/账号封禁/敏感词DFA检测 前端: Vue3+Vite+Element Plus+Less+ECharts+FontAwesome - 动态路由(数据库菜单驱动) - 蓝白配色, H5响应式 - 登录/注册/忘记密码/个人中心 - 班级创建向导/详情/加入/列表 - 管理后台: 审核/配置/菜单/统计/用户/敏感词 数据库: MySQL 10.31.100.3:3306/photowall 管理员: hero920103 / 920103
86 lines
2.4 KiB
Go
86 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"photowall/internal/config"
|
|
"photowall/internal/database"
|
|
"photowall/internal/handler"
|
|
"photowall/internal/router"
|
|
"photowall/internal/scheduler"
|
|
"photowall/internal/service"
|
|
"photowall/pkg/jwt"
|
|
"photowall/pkg/redis"
|
|
"photowall/pkg/sensitive"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func main() {
|
|
// 1. 加载配置
|
|
cfg := config.Load()
|
|
log.Printf("[config] port=%s db=%s@%s:%s/%s", cfg.Port, cfg.DBUser, cfg.DBHost, cfg.DBPort, cfg.DBName)
|
|
|
|
// 2. 初始化数据库(连接 + 自动迁移 + 管理员 + 种子数据)
|
|
if err := database.Init(); err != nil {
|
|
log.Fatalf("[database] init failed: %v", err)
|
|
}
|
|
|
|
// 2.1 初始化 Redis(连接失败自动降级内存模式)
|
|
redis.Init(redis.Config{
|
|
Host: cfg.RedisHost,
|
|
Port: cfg.RedisPort,
|
|
Password: cfg.RedisPassword,
|
|
DB: cfg.RedisDB,
|
|
})
|
|
|
|
// 3. JWT
|
|
jm := jwt.New(cfg.JWTSecret, cfg.JWTExpireHrs)
|
|
|
|
// 4. 初始化 Service
|
|
authSvc := service.NewAuthService(database.DB, jm)
|
|
userSvc := service.NewUserService(database.DB)
|
|
regionSvc := service.NewRegionService(database.DB)
|
|
schoolSvc := service.NewSchoolService(database.DB)
|
|
classSvc := service.NewClassService(database.DB)
|
|
adminSvc := service.NewAdminService(database.DB)
|
|
configSvc := service.NewConfigService(database.DB)
|
|
menuSvc := service.NewMenuService(database.DB)
|
|
|
|
// 初始化系统默认配置
|
|
if err := configSvc.InitDefaults(); err != nil {
|
|
log.Printf("[config] init defaults failed: %v", err)
|
|
}
|
|
// 初始化默认菜单
|
|
if err := menuSvc.InitDefaults(); err != nil {
|
|
log.Printf("[menu] init defaults failed: %v", err)
|
|
}
|
|
// 初始化敏感词过滤器
|
|
sensitive.Init(database.DB)
|
|
|
|
// 5. 初始化 Handler
|
|
deps := &router.Deps{
|
|
Auth: handler.NewAuthHandler(authSvc),
|
|
User: handler.NewUserHandler(userSvc),
|
|
Region: handler.NewRegionHandler(regionSvc),
|
|
School: handler.NewSchoolHandler(schoolSvc),
|
|
Class: handler.NewClassHandler(classSvc),
|
|
Admin: handler.NewAdminHandler(adminSvc),
|
|
Upload: handler.NewUploadHandler(database.DB),
|
|
Config: handler.NewConfigHandler(configSvc),
|
|
Menu: handler.NewMenuHandler(menuSvc),
|
|
}
|
|
|
|
// 6. 启动定时清理任务
|
|
scheduler.StartCleanup(adminSvc)
|
|
|
|
// 7. 启动 HTTP 服务
|
|
gin.SetMode(gin.ReleaseMode)
|
|
r := gin.Default()
|
|
router.Register(r, jm, deps)
|
|
|
|
log.Printf("[server] photowall API listening on :%s", cfg.Port)
|
|
if err := r.Run(":" + cfg.Port); err != nil {
|
|
log.Fatalf("[server] failed: %v", err)
|
|
}
|
|
}
|