diff --git a/.gitignore b/.gitignore index 4285625..eaf4bc3 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,6 @@ secrets/* .idea/ .vscode/ *.swp + +# 运行日志(run.sh 输出, 不入库) +*.log diff --git a/app/api/v1/auth.py b/app/api/v1/auth.py index 294ca77..ed7e4b6 100644 --- a/app/api/v1/auth.py +++ b/app/api/v1/auth.py @@ -15,10 +15,10 @@ import logging from fastapi import APIRouter, HTTPException, status from app.api.deps import CurrentUser, DbSession -from app.core.jiguang import JiguangError, mask_phone, verify_and_get_phone from app.core.security import TokenError, decode_token, issue_token_pair -from app.core.sms import SmsError, send_code, verify_code -from app.crud import user as crud_user +from app.integrations.jiguang import JiguangError, mask_phone, verify_and_get_phone +from app.integrations.sms import SmsError, send_code, verify_code +from app.repositories import user as user_repo from app.schemas.auth import ( JverifyLoginRequest, LogoutResponse, @@ -61,7 +61,7 @@ def jverify_login(req: JverifyLoginRequest, db: DbSession) -> TokenWithUser: logger.error("[JG] verify+decrypt failed: %s", e, exc_info=True) raise HTTPException(status_code=502, detail=f"jiguang verify failed: {e}") from e - user = crud_user.upsert_user_for_login(db, phone=phone, register_channel="jverify") + user = user_repo.upsert_user_for_login(db, phone=phone, register_channel="jverify") if user.status != "active": raise HTTPException(status_code=403, detail="account disabled") @@ -88,7 +88,7 @@ def sms_login(req: SmsLoginRequest, db: DbSession) -> TokenWithUser: if not verify_code(req.phone, req.code): raise HTTPException(status_code=400, detail="invalid sms code") - user = crud_user.upsert_user_for_login(db, phone=req.phone, register_channel="sms") + user = user_repo.upsert_user_for_login(db, phone=req.phone, register_channel="sms") if user.status != "active": raise HTTPException(status_code=403, detail="account disabled") @@ -106,7 +106,7 @@ def refresh(req: RefreshRequest, db: DbSession) -> TokenPair: raise HTTPException(status_code=401, detail=str(e)) from e user_id = int(payload["sub"]) - user = crud_user.get_user_by_id(db, user_id) + user = user_repo.get_user_by_id(db, user_id) if user is None or user.status != "active": raise HTTPException(status_code=401, detail="user not found or disabled") diff --git a/app/api/v1/meituan.py b/app/api/v1/meituan.py index a24364a..4d56b73 100644 --- a/app/api/v1/meituan.py +++ b/app/api/v1/meituan.py @@ -9,7 +9,7 @@ from concurrent.futures import ThreadPoolExecutor, as_completed from fastapi import APIRouter, HTTPException -from app.core.meituan import MeituanCpsError, get_referral_link, query_coupon +from app.integrations.meituan import MeituanCpsError, get_referral_link, query_coupon from app.schemas.meituan import ( CouponCard, CouponListRequest, diff --git a/app/crud/__init__.py b/app/integrations/__init__.py similarity index 100% rename from app/crud/__init__.py rename to app/integrations/__init__.py diff --git a/app/core/jiguang.py b/app/integrations/jiguang.py similarity index 100% rename from app/core/jiguang.py rename to app/integrations/jiguang.py diff --git a/app/core/meituan.py b/app/integrations/meituan.py similarity index 100% rename from app/core/meituan.py rename to app/integrations/meituan.py diff --git a/app/core/sms.py b/app/integrations/sms.py similarity index 100% rename from app/core/sms.py rename to app/integrations/sms.py diff --git a/app/repositories/__init__.py b/app/repositories/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/crud/user.py b/app/repositories/user.py similarity index 100% rename from app/crud/user.py rename to app/repositories/user.py diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..bc00fe8 --- /dev/null +++ b/run.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# 本地开发启动脚本:监听 0.0.0.0(真机局域网 / adb reverse 都能连),改代码自动重启。 +# +# 前置(首次):先激活装好依赖的环境,例如: +# conda activate price && pip install -e . +# 真机联调流程见前台 local.properties 的 debug.api.host。 +set -e +cd "$(dirname "$0")" + +if [ ! -f .env ]; then + echo "❌ 缺 .env:先 cp .env.example .env 并填值(至少 JWT_SECRET_KEY;测美团再填 MT_CPS_*)" + exit 1 +fi + +mkdir -p data # sqlite 文件所在目录 +alembic upgrade head # 确保表已建(幂等,已是最新则 no-op) + +exec uvicorn app.main:app --host 0.0.0.0 --port 8770 --reload