Files
H3ConuMS-v2/backend/app/api/v1/settings.py
T
v6ole eaabebbceb feat: v0.8.x 功能更新与数据维护优化
- MAC地址格式统一为小写 xxxx-xxxx-xxxx,支持三种格式输入
- 更换设备MAC时自动清理OLT新发现列表中的冲突ONU记录
- 设备编辑新增场所类型字段(手动输入),区域改为下拉快速填充
- 编辑/更换设备时自动移除new_devices中同MAC的待入库记录
- 新增登录过期自动跳转(401拦截 + 过期提示)
- 新增关于页面(/about),支持Markdown渲染,管理员可在设置中编辑内容
- 新增device_status_history每日自动清理任务(保留30天)
- 更新README.md和about.md
2026-04-24 08:53:28 +08:00

101 lines
3.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""系统设置 API(仅管理员)"""
import time
import redis as redis_lib
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from app.core.database import get_db
from app.core.config import settings
from app.middleware.permission_middleware import require_permission
from app.models.setting import SystemSetting
router = APIRouter(prefix="/api/settings", tags=["系统设置"])
MIN_CHECK_INTERVAL = 300 # 5 分钟
MAX_CHECK_INTERVAL = 86400 # 24 小时
_INTERVAL_REDIS_KEY = "system:check_interval_seconds"
def _get_redis():
return redis_lib.from_url(settings.REDIS_URL, decode_responses=True)
@router.get("")
def get_settings(
db: Session = Depends(get_db),
_: dict = Depends(require_permission('*')),
):
"""获取所有系统设置,附带下次扫描时间"""
rows = db.query(SystemSetting).all()
result = {row.key: {"value": row.value, "description": row.description} for row in rows}
# 计算下次扫描时间
try:
r = _get_redis()
interval_str = r.get(_INTERVAL_REDIS_KEY)
last_run_str = r.get("check_all_devices:last_run")
is_running = bool(r.get("check_all_devices:running"))
interval = int(interval_str) if interval_str else 1800
next_run_ts = (float(last_run_str) + interval) if last_run_str else None
result["next_check_at"] = {
"value": str(int(next_run_ts)) if next_run_ts else None,
"running": is_running,
"description": "下次扫描时间戳(Unix"
}
except Exception:
result["next_check_at"] = {"value": None, "running": False, "description": "下次扫描时间戳(Unix"}
return result
@router.put("/check_interval")
def update_check_interval(
seconds: int,
db: Session = Depends(get_db),
_: dict = Depends(require_permission('*')),
):
"""更新定时检查间隔(秒),范围 300~86400"""
if seconds < MIN_CHECK_INTERVAL:
raise HTTPException(status_code=400, detail=f"间隔不能小于 {MIN_CHECK_INTERVAL} 秒(5分钟)")
if seconds > MAX_CHECK_INTERVAL:
raise HTTPException(status_code=400, detail=f"间隔不能大于 {MAX_CHECK_INTERVAL} 秒(24小时)")
setting = db.query(SystemSetting).filter_by(key='check_interval_seconds').first()
if setting:
setting.value = str(seconds)
else:
db.add(SystemSetting(key='check_interval_seconds', value=str(seconds), description='定时检查间隔(秒)'))
db.commit()
# 同步到 Redis,让 Celery 任务立即生效
_get_redis().set(_INTERVAL_REDIS_KEY, str(seconds))
# 重置上次运行时间,让下次触发时立即按新间隔计算
_get_redis().delete("check_all_devices:last_run")
return {"key": "check_interval_seconds", "value": seconds}
@router.get("/about")
def get_about(db: Session = Depends(get_db)):
"""获取关于页面内容(公开接口,无需登录)"""
setting = db.query(SystemSetting).filter_by(key='about_content').first()
return {"content": setting.value if setting else ""}
@router.put("/about")
def update_about(
body: dict,
db: Session = Depends(get_db),
_: dict = Depends(require_permission('*')),
):
"""更新关于页面内容(仅管理员)"""
content = body.get("content", "")
setting = db.query(SystemSetting).filter_by(key='about_content').first()
if setting:
setting.value = content
else:
db.add(SystemSetting(key='about_content', value=content, description='关于页面内容(Markdown'))
db.commit()
return {"key": "about_content", "value": content}