Files
xbxs/routers/home.py

182 lines
4.9 KiB
Python
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from datetime import datetime
import json
import os
from pathlib import Path
from typing import List
from uuid import uuid4
from fastapi import (
APIRouter,
Depends,
File,
Form,
HTTPException,
Request,
UploadFile,
status,
)
from fastapi.responses import HTMLResponse, RedirectResponse
from starlette.templating import Jinja2Templates
from services.services import XBXS
from config import BASE_DIR
from exceptions.unauthorized import UnauthorizedError
router = APIRouter()
templates = Jinja2Templates(directory=str(BASE_DIR / "templates"))
def get_xbxs(request: Request) -> XBXS:
token = request.cookies.get("xbxs_token")
if not token:
# 没有 token 跳转到登录页面
raise HTTPException(
status_code=status.HTTP_303_SEE_OTHER,
detail="Redirect to login",
headers={"Location": "/login"},
)
return XBXS(token=token)
@router.get("/home")
async def home(
request: Request,
xbxs: XBXS = Depends(get_xbxs),
):
return templates.TemplateResponse(
"home.html",
{
"request": request,
"active": "home",
},
)
@router.get("/profile")
async def profile(
request: Request,
xbxs: XBXS = Depends(get_xbxs),
):
try:
student = await xbxs.get_student_info_cached()
return templates.TemplateResponse(
"profile.html",
{
"request": request,
"student": student,
"active": "profile",
},
)
except UnauthorizedError as e:
raise HTTPException(
status_code=401,
detail=e.message,
)
@router.get("/sign")
async def sign_list(
request: Request,
xbxs: XBXS = Depends(get_xbxs),
):
try:
result = await xbxs.get_know_list()
except UnauthorizedError as e:
raise HTTPException(
status_code=401,
detail=e.message,
)
rows = result.get("rows", [])
now = datetime.now()
for item in rows:
# 1⃣ 计算是否结束(核心)
end_str = f"{item['endDate']} {item['endTime']}"
end_time = datetime.strptime(end_str, "%Y-%m-%d %H:%M")
item["isEnded"] = now > end_time
return templates.TemplateResponse(
"sign_list.html",
{
"request": request,
"list": rows,
"total": result.get("total", 0),
},
)
@router.get("/sign/{knowing_id}", response_class=HTMLResponse)
async def sign_detail(
knowing_id: int,
request: Request,
xbxs: XBXS = Depends(get_xbxs),
):
try:
know_detail = await xbxs.get_know(str(knowing_id))
except UnauthorizedError as e:
raise HTTPException(
status_code=401,
detail=e.message,
)
data = know_detail.get("data", {})
# 获取具体的数据
knowing_name = data.get("knowingName", "未知签到")
start_date = data.get("startDate", "未知")
start_time = data.get("startTime", "未知")
end_time = data.get("endTime", "未知")
send_name = data.get("sendName", "未知")
send_role = data.get("sendRole", "未知")
is_check = data.get("isCheck", 0)
is_picture = data.get("isPicture", 0)
# is_finish_know = data.get("isFinishKnowing", 0)
locations = json.loads(data.get("location", []))
return templates.TemplateResponse(
"sign_detail.html",
{
"request": request,
"know_id": knowing_id,
"knowing_name": knowing_name,
"start_date": start_date,
"start_time": start_time,
"end_time": end_time,
"send_name": send_name,
"send_role": send_role,
"is_check": is_check,
"is_picture": is_picture,
"locations": locations,
# "is_finish_know": is_finish_know,
},
)
# 完善的 sign 完成接口
@router.post("/sign/{know_id}/complete")
async def complete_sign(
know_id: int,
request: Request,
location: str = Form(...), # 获取经纬度,必填
address: str = Form(...), # 获取经纬度,必填
remark: str = Form(...), # 获取备注,必填
images: List[UploadFile] = File(...), # 获取上传的图片,支持多张
xbxs: XBXS = Depends(get_xbxs),
):
# 备注必填,未填写时返回错误
if not remark:
raise HTTPException(status_code=400, detail="备注是必填项")
try:
await xbxs.update_student_know(str(know_id), remark, address, location, images)
except UnauthorizedError as e:
raise HTTPException(
status_code=401,
detail=e.message,
)
except Exception as e:
raise HTTPException(status_code=500, detail="保存签到数据失败")
# 成功后跳转到签到列表
return RedirectResponse(url="/sign", status_code=status.HTTP_303_SEE_OTHER)