# app.py import requests from fastapi import FastAPI, HTTPException from fastapi.staticfiles import StaticFiles from fastapi.responses import FileResponse from pydantic import BaseModel from datetime import datetime import pytz # --- 配置区域 --- # 在这里更新您的 Token 和其他固定参数 CONFIG = { "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3OTEwMjE4MjgsInVzZXJuYW1lIjoiMTgwNjc2Mzk1ODgifQ.M5tFVgNKq2HTjClRQYzeGMBKjU9jIrEXXP8mS7yPPU0", "ptype": "appid_wx8317b90ed5e4fba3", "weixinType": "0", "aliId": "2021003196691127", "target_api_url": "https://parking.youboyun.com.cn/parkWeb/common/preferential/qrcodes/getQrCode" } # --- 配置区域结束 --- app = FastAPI() # 定义请求体模型,确保前端传来正确的数据 class QrCodeRequest(BaseModel): qrCodeId: str # 创建一个API端点,前端将请求这个地址 @app.post("/api/get_qrcode") async def get_qrcode_proxy(request_data: QrCodeRequest): """ 这个函数作为代理,向停车场的API发起请求。 """ # 准备请求头 headers = { 'Content-Type': 'application/json', 'token': CONFIG["token"], 'ptype': CONFIG["ptype"], 'weixinType': CONFIG["weixinType"], 'aliId': CONFIG["aliId"], 'User-Agent': 'Python/Requests', # 模拟一个User-Agent } # 准备请求体 payload = { "qrCodeId": request_data.qrCodeId } # 准备带时间戳的URL参数 # 使用中国时区 (Asia/Shanghai) tz = pytz.timezone('Asia/Shanghai') current_time = datetime.now(tz).strftime('%a %b %d %Y %H:%M:%S GMT%z (%Z)') # 格式化成API需要的样子,例如 'Fri Oct 03 2025 18:16:11 GMT+0800 (中国标准时间)' # Python的 %Z 有时不会输出中文,我们手动替换 current_time_str = current_time.replace('CST', '中国标准时间') params = { 't': current_time_str } try: # 发起POST请求 response = requests.post( CONFIG["target_api_url"], headers=headers, params=params, json=payload, timeout=10 # 10秒超时 ) # 检查响应状态码 response.raise_for_status() # 将从目标API收到的JSON数据直接返回给前端 return response.json() except requests.exceptions.RequestException as e: # 如果请求失败,返回一个详细的错误信息 raise HTTPException(status_code=502, detail=f"Failed to fetch from target API: {e}") # 托管 static 文件夹中的所有文件(如 video) app.mount("/static", StaticFiles(directory="static"), name="static") # 将根路径 ("/") 指向我们的 index.html 文件 @app.get("/") async def read_index(): return FileResponse('static/index.html')