添加完整学生系统

This commit is contained in:
2026-09-21 20:20:16 +08:00
parent 1d05044e4f
commit 78a95518ed
59 changed files with 7044 additions and 0 deletions
@@ -0,0 +1,108 @@
# settings.py
# 统一配置入口:所有可变参数都从环境变量 / .env 读取,代码里不再出现硬编码密码。
#
# 真实业务里"配置"和"代码"必须分离:
# 开发 / 测试 / 生产 用的是三套数据库,靠改代码切环境一定会出事故。
import os
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent
def _load_dotenv(path: Path) -> None:
"""极简 .env 加载器。
优先使用 python-dotenv;没装则用内置的简易解析,保证零依赖也能跑。
"""
if not path.exists():
return
try:
from dotenv import load_dotenv # type: ignore
load_dotenv(path, override=False)
return
except ImportError:
pass
for raw in path.read_text(encoding="utf-8").splitlines():
line = raw.strip()
if not line or line.startswith("#") or "=" not in line:
continue
key, _, value = line.partition("=")
key, value = key.strip(), value.strip().strip('"').strip("'")
# 已存在的真实环境变量优先,不被文件覆盖
os.environ.setdefault(key, value)
_load_dotenv(BASE_DIR / ".env")
def _env(key: str, default: str) -> str:
value = os.getenv(key)
return default if value is None or value == "" else value
def _env_bool(key: str, default: bool) -> bool:
return _env(key, str(default)).strip().lower() in ("1", "true", "yes", "on")
def _env_int(key: str, default: int) -> int:
try:
return int(_env(key, str(default)))
except ValueError:
return default
class Settings:
# ---------- 应用 ----------
APP_NAME: str = _env("APP_NAME", "学生管理系统")
APP_VERSION: str = _env("APP_VERSION", "1.1.0")
DEBUG: bool = _env_bool("DEBUG", True)
HOST: str = _env("HOST", "127.0.0.1")
PORT: int = _env_int("PORT", 8004)
# API 统一前缀。改这里就能整体换版本,不用一个个改路由。
API_PREFIX: str = _env("API_PREFIX", "/api/v1")
# ---------- 跨域 ----------
# 注意:allow_credentials=True 时浏览器【禁止】返回 "*",
# 必须显式列出前端域名,否则带 Cookie / 登录态一定失败。
CORS_ORIGINS: list[str] = [
o.strip()
for o in _env(
"CORS_ORIGINS",
"http://localhost:5500,http://127.0.0.1:5500,"
"http://localhost:8000,http://127.0.0.1:8000,"
"http://localhost:5173,http://127.0.0.1:5173",
).split(",")
if o.strip()
]
# ---------- 数据库 ----------
DB_HOST: str = _env("DB_HOST", "127.0.0.1")
DB_PORT: int = _env_int("DB_PORT", 3306)
DB_USER: str = _env("DB_USER", "root")
DB_PASSWORD: str = _env("DB_PASSWORD", "")
DB_NAME: str = _env("DB_NAME", "student_management_system")
DB_CHARSET: str = _env("DB_CHARSET", "utf8mb4")
DB_ECHO: bool = _env_bool("DB_ECHO", False)
DB_POOL_SIZE: int = _env_int("DB_POOL_SIZE", 5)
DB_MAX_OVERFLOW: int = _env_int("DB_MAX_OVERFLOW", 10)
DB_POOL_RECYCLE: int = _env_int("DB_POOL_RECYCLE", 3600)
@property
def database_url(self) -> str:
from urllib.parse import quote_plus
return (
f"mysql+pymysql://{self.DB_USER}:{quote_plus(self.DB_PASSWORD)}"
f"@{self.DB_HOST}:{self.DB_PORT}/{self.DB_NAME}"
f"?charset={self.DB_CHARSET}"
)
settings = Settings()