Initial commit: migrate badge-admin from /tmp to /home/gpsystem
via HAPI (https://hapi.run) Co-Authored-By: HAPI <noreply@hapi.run>
This commit is contained in:
100
app/main.py
Normal file
100
app/main.py
Normal file
@@ -0,0 +1,100 @@
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi import FastAPI
|
||||
from fastapi.responses import HTMLResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from contextlib import asynccontextmanager
|
||||
from app.database import init_db, async_session
|
||||
from app.tcp_server import tcp_manager
|
||||
from app.config import settings
|
||||
from app.routers import devices, locations, alarms, attendance, commands, bluetooth, beacons
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
# Startup
|
||||
logger.info("Initializing database...")
|
||||
await init_db()
|
||||
# Reset all devices to offline on startup (stale state from previous run)
|
||||
try:
|
||||
from sqlalchemy import update
|
||||
from app.models import Device
|
||||
async with async_session() as session:
|
||||
async with session.begin():
|
||||
await session.execute(update(Device).values(status="offline"))
|
||||
logger.info("All devices reset to offline on startup")
|
||||
except Exception:
|
||||
logger.exception("Failed to reset device statuses on startup")
|
||||
logger.info("Starting TCP server on %s:%d", settings.TCP_HOST, settings.TCP_PORT)
|
||||
tcp_task = asyncio.create_task(tcp_manager.start(settings.TCP_HOST, settings.TCP_PORT))
|
||||
yield
|
||||
# Shutdown
|
||||
logger.info("Shutting down TCP server...")
|
||||
await tcp_manager.stop()
|
||||
tcp_task.cancel()
|
||||
|
||||
app = FastAPI(
|
||||
title="KKS Badge Management System / KKS工牌管理系统",
|
||||
description="""
|
||||
## KKS P240 & P241 蓝牙工牌管理后台
|
||||
|
||||
### 功能模块 / Features:
|
||||
- **设备管理 / Device Management** - 设备注册、状态监控
|
||||
- **位置数据 / Location Data** - GPS/LBS/WIFI定位数据查询与轨迹回放
|
||||
- **报警管理 / Alarm Management** - SOS、围栏、低电等报警处理
|
||||
- **考勤管理 / Attendance** - 打卡记录查询与统计
|
||||
- **指令管理 / Commands** - 远程指令下发与留言
|
||||
- **蓝牙数据 / Bluetooth** - 蓝牙打卡与定位数据
|
||||
- **信标管理 / Beacons** - 蓝牙信标注册与位置配置
|
||||
|
||||
### 通讯协议 / Protocol:
|
||||
- TCP端口: {tcp_port} (设备连接)
|
||||
- 支持协议: KKS P240/P241 通讯协议
|
||||
""".format(tcp_port=settings.TCP_PORT),
|
||||
version="1.0.0",
|
||||
docs_url="/docs",
|
||||
redoc_url="/redoc",
|
||||
lifespan=lifespan,
|
||||
)
|
||||
|
||||
# Include routers
|
||||
app.include_router(devices.router)
|
||||
app.include_router(locations.router)
|
||||
app.include_router(alarms.router)
|
||||
app.include_router(attendance.router)
|
||||
app.include_router(commands.router)
|
||||
app.include_router(bluetooth.router)
|
||||
app.include_router(beacons.router)
|
||||
|
||||
_STATIC_DIR = Path(__file__).parent / "static"
|
||||
app.mount("/static", StaticFiles(directory=str(_STATIC_DIR)), name="static")
|
||||
|
||||
|
||||
@app.get("/admin", response_class=HTMLResponse, tags=["Admin"])
|
||||
async def admin_page():
|
||||
"""管理后台页面 / Admin Dashboard"""
|
||||
html_path = _STATIC_DIR / "admin.html"
|
||||
return HTMLResponse(content=html_path.read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
@app.get("/", tags=["Root"])
|
||||
async def root():
|
||||
return {
|
||||
"name": settings.APP_NAME,
|
||||
"version": "1.0.0",
|
||||
"docs": "/docs",
|
||||
"redoc": "/redoc",
|
||||
"admin": "/admin",
|
||||
"tcp_port": settings.TCP_PORT,
|
||||
}
|
||||
|
||||
@app.get("/health", tags=["Root"])
|
||||
async def health():
|
||||
return {
|
||||
"status": "healthy",
|
||||
"connected_devices": len(tcp_manager.connections),
|
||||
}
|
||||
Reference in New Issue
Block a user