Files
photowall/go/cmd/server/main.go
T
hero920103 57d9866dab feat: PhotoWall 毕业照存储系统初始版本
后端: 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
2026-09-03 05:55:23 +08:00

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)
}
}