yearning
18 小时以前 e3e6db2d9974588f91ac1567a58fa4846655ce1b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
from pathlib import Path
 
from fastapi import APIRouter, Depends, File, HTTPException, UploadFile
from fastapi.responses import FileResponse
from sqlalchemy.orm import Session
 
from app.auth import require_admin
from app.database import get_db
from app.models import User
from app.schemas import SystemSettingsOut, SystemSettingsUpdate
from app.system_settings import (
    clear_logo_files,
    ensure_upload_dir,
    find_logo_file,
    get_or_create_settings,
    logo_path,
    public_logo_url,
)
 
router = APIRouter(prefix="/api", tags=["settings"])
 
ALLOWED_LOGO_EXT = {".png", ".jpg", ".jpeg", ".webp", ".svg", ".gif"}
MAX_LOGO_BYTES = 2 * 1024 * 1024
 
 
def _settings_out(db: Session) -> SystemSettingsOut:
    row = get_or_create_settings(db)
    return SystemSettingsOut(
        system_name=row.system_name,
        logo_url=public_logo_url(row.logo_ext or None),
        grader_can_see_privacy=row.grader_can_see_privacy,
    )
 
 
@router.get("/settings", response_model=SystemSettingsOut)
def get_settings(db: Session = Depends(get_db)):
    return _settings_out(db)
 
 
@router.get("/settings/logo")
def get_logo(db: Session = Depends(get_db)):
    row = get_or_create_settings(db)
    path = find_logo_file(row.logo_ext or None)
    if not path:
        raise HTTPException(404, detail="未设置 Logo")
    media = {
        ".png": "image/png",
        ".jpg": "image/jpeg",
        ".jpeg": "image/jpeg",
        ".webp": "image/webp",
        ".svg": "image/svg+xml",
        ".gif": "image/gif",
    }.get(path.suffix.lower(), "application/octet-stream")
    return FileResponse(path, media_type=media)
 
 
@router.put("/admin/settings", response_model=SystemSettingsOut)
def update_settings(
    body: SystemSettingsUpdate,
    db: Session = Depends(get_db),
    _: User = Depends(require_admin),
):
    row = get_or_create_settings(db)
    row.system_name = body.system_name.strip()
    row.grader_can_see_privacy = body.grader_can_see_privacy
    db.commit()
    db.refresh(row)
    return _settings_out(db)
 
 
@router.post("/admin/settings/logo", response_model=SystemSettingsOut)
async def upload_logo(
    file: UploadFile = File(...),
    db: Session = Depends(get_db),
    _: User = Depends(require_admin),
):
    if not file.filename:
        raise HTTPException(400, detail="请选择文件")
    ext = Path(file.filename).suffix.lower()
    if ext not in ALLOWED_LOGO_EXT:
        raise HTTPException(400, detail="仅支持 png、jpg、webp、svg、gif")
    content = await file.read()
    if len(content) > MAX_LOGO_BYTES:
        raise HTTPException(400, detail="Logo 不能超过 2MB")
    ensure_upload_dir()
    clear_logo_files()
    ext_clean = ext.lstrip(".")
    dest = logo_path(ext_clean)
    dest.write_bytes(content)
    row = get_or_create_settings(db)
    row.logo_ext = ext_clean
    db.commit()
    db.refresh(row)
    return _settings_out(db)
 
 
@router.delete("/admin/settings/logo", response_model=SystemSettingsOut)
def delete_logo(
    db: Session = Depends(get_db),
    _: User = Depends(require_admin),
):
    clear_logo_files()
    row = get_or_create_settings(db)
    row.logo_ext = ""
    db.commit()
    db.refresh(row)
    return _settings_out(db)