Files
canglan c6db68a9f4 feat: 多班级版班级管理系统 v2.0
技术栈:Go (Gin + GORM) + PHP + MySQL 5.7 + Redis

主要功能:
- 多班级完全隔离(class_id 贯穿全系统)
- 后端 Go Gin(端口 56789),Nginx 反代
- 超级管理员独立登录(env 配置,默认账密 admin/Admin123)
- bcrypt 密码加密(无 PASSWORD_SALT)
- 科任老师/课代表新角色
- 课代表作业管理页面
- 排行榜分项排行(操行分/考勤/作业)
- 角色加减分上下限由班主任配置
- 家长改密功能(可开关)
- 班级角色按需开关
- 宿舍号格式:南0-000
- 周度/月度重置功能
- MySQL 5.7 兼容
- 43 轮代码审查 + 全部修复

开发者: Canglan
版权归属: Sea Network Technology Studio
许可证: Apache License 2.0
2026-06-23 16:02:28 +08:00

156 lines
4.1 KiB
Go

// ===========================================
// 多班级版班级管理系统 - Go 后端
//
// 开发者: Canglan
// 联系方式: admin@sea-studio.top
// 版权归属: Sea Network Technology Studio
// 许可证: Apache License 2.0
//
// 版权所有 © Sea Network Technology Studio
// ===========================================
package config
import (
"fmt"
"os"
"strconv"
"strings"
"github.com/joho/godotenv"
)
// Config 应用全局配置结构体
type Config struct {
// 应用基础配置
AppName string
AppEnv string
Debug bool
AppPort string
// MySQL 数据库配置
DBHost string
DBPort int
DBUser string
DBPassword string
DBName string
DBMaxOpenConns int
DBMaxIdleConns int
DBConnMaxLife int // 秒
// Redis 配置
RedisHost string
RedisPort int
RedisPassword string
RedisDB int
RedisMaxConns int
// JWT 配置
JWTSecretKey string
JWTAlgorithm string
JWTExpireMinutes int
JWTIdleTimeoutMinutes int
// 系统管理员配置
SuperAdminLoginPath string
SuperAdminDefaultUser string
SuperAdminDefaultPass string
// 日志
LogLevel string
LogFile string
}
// AppConfig 全局配置实例
var AppConfig *Config
// Load 加载配置:先尝试加载 .env 文件,然后读取环境变量
func Load() (*Config, error) {
// 尝试加载 .env 文件(不存在不报错)
_ = godotenv.Load()
cfg := &Config{
AppName: getEnv("APP_NAME", "多班级版班级管理系统"),
AppEnv: getEnv("APP_ENV", "production"),
Debug: getEnvBool("DEBUG", false),
AppPort: getEnv("APP_PORT", "56789"),
DBHost: getEnv("DB_HOST", "localhost"),
DBPort: getEnvInt("DB_PORT", 3306),
DBUser: getEnv("DB_USER", "class_admin"),
DBPassword: getEnv("DB_PASSWORD", ""),
DBName: getEnv("DB_NAME", "classmanagerdb"),
DBMaxOpenConns: getEnvInt("DB_MAX_OPEN_CONNS", 25),
DBMaxIdleConns: getEnvInt("DB_MAX_IDLE_CONNS", 10),
DBConnMaxLife: getEnvInt("DB_CONN_MAX_LIFETIME", 300),
RedisHost: getEnv("REDIS_HOST", "localhost"),
RedisPort: getEnvInt("REDIS_PORT", 6379),
RedisPassword: getEnv("REDIS_PASSWORD", ""),
RedisDB: getEnvInt("REDIS_DB", 0),
RedisMaxConns: getEnvInt("REDIS_MAX_CONNECTIONS", 500),
JWTSecretKey: getEnv("JWT_SECRET_KEY", ""),
JWTAlgorithm: getEnv("JWT_ALGORITHM", "HS256"),
JWTExpireMinutes: getEnvInt("JWT_EXPIRE_MINUTES", 60),
JWTIdleTimeoutMinutes: getEnvInt("JWT_IDLE_TIMEOUT_MINUTES", 10),
SuperAdminLoginPath: getEnv("SUPER_ADMIN_LOGIN_PATH", "/super-admin"),
SuperAdminDefaultUser: getEnv("SUPER_ADMIN_DEFAULT_USERNAME", "admin"),
// 安全警告:默认密码仅用于首次部署初始化,上线前必须在 .env 中修改 SUPER_ADMIN_DEFAULT_PASSWORD。
// EnsureDefaultAdmin 通过 need_change_password=1 强制首次登录改密作为缓解措施。
SuperAdminDefaultPass: getEnv("SUPER_ADMIN_DEFAULT_PASSWORD", "Admin123"),
LogLevel: getEnv("LOG_LEVEL", "info"),
LogFile: getEnv("LOG_FILE", "logs/app.log"),
}
// 校验必填项
// 校验必填项
if cfg.JWTSecretKey == "" {
return nil, fmt.Errorf("配置 JWT_SECRET_KEY 不能为空")
}
AppConfig = cfg
return cfg, nil
}
// DSN 返回 MySQL 连接字符串
func (c *Config) DSN() string {
return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local",
c.DBUser, c.DBPassword, c.DBHost, c.DBPort, c.DBName)
}
// RedisAddr 返回 Redis 地址
func (c *Config) RedisAddr() string {
return fmt.Sprintf("%s:%d", c.RedisHost, c.RedisPort)
}
// IsProduction 判断是否为生产环境
func (c *Config) IsProduction() bool {
return c.AppEnv == "production"
}
// --- 辅助函数 ---
func getEnv(key, fallback string) string {
if val, ok := os.LookupEnv(key); ok {
return val
}
return fallback
}
func getEnvInt(key string, fallback int) int {
if val, ok := os.LookupEnv(key); ok {
if i, err := strconv.Atoi(val); err == nil {
return i
}
}
return fallback
}
func getEnvBool(key string, fallback bool) bool {
if val, ok := os.LookupEnv(key); ok {
return strings.ToLower(val) == "true"
}
return fallback
}