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
This commit is contained in:
155
backend-go/internal/config/config.go
Normal file
155
backend-go/internal/config/config.go
Normal file
@@ -0,0 +1,155 @@
|
||||
// ===========================================
|
||||
// 多班级版班级管理系统 - 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
|
||||
}
|
||||
Reference in New Issue
Block a user