jerry 6 ヶ月 前
コミット
d7d98c2528
5 ファイル変更102 行追加15 行削除
  1. 3 3
      .env
  2. 35 6
      app/api/router.py
  3. 6 0
      app/schemas/sms.py
  4. 1 6
      app/schemas/user.py
  5. 57 0
      app/services/sms_service.py

+ 3 - 3
.env

@@ -1,3 +1,3 @@
-DATABASE_URL=postgresql://user:password@127.0.0.1:5432/dbname
-REDIS_URL=redis://:STEs2x6ML0U1HlpE9SojM6YU7QPhqzY8@92.119.127.236:6379/0
-API_TOKEN=7x9EjFpmv7GjZc6AfVeqxuUBANpqkpkHAtxJM7CAW5oZhs0nEyCJBy39N4XXs5hgfYWXw3jFrcgXqQ42HAx9Qvwtk9vC2GvKBbWz
+DATABASE_URL=mysql://root:GqLLL7Bofj0WaaOpp.0@visafly.top:3306/book_user_info?charset=utf8mb4&timezone=UTC
+REDIS_URL=redis://:STEs2x6ML0U1HlpE9SojM6YU7QPhqzY8@45.137.220.138:6379/0
+API_TOKEN=7x9EjFpmv7GjZc6AfVeqxuUBANpqkpkHAtxJM7CAW5oZhs0nEyCJBy39N4XXs5hgfYWXw3jFrcgXqQ42HAx9Qvwtk9vC2GvKBbWz

+ 35 - 6
app/api/router.py

@@ -1,30 +1,59 @@
+import time
 from typing import List
 from fastapi import APIRouter, Query, Depends
 from app.core.redis import get_redis_client
 from redis.asyncio import Redis
 from app.schemas.user import UserOut
 from app.schemas.troov import TroovRate
+from app.schemas.sms import ShortMessageDetail
 from app.services.troov_service import get_rate_by_date
+from app.services.sms_service import save_short_message, query_short_message
 
 # 公共路由
-public_router = APIRouter(prefix="/api", tags=["troov"])
+public_router = APIRouter(tags=["public"])
+# 受保护路由
+protected_router = APIRouter(tags=["protected"])
 
-@public_router.get("/ping")
+@public_router.get("/ping", summary="心跳检测")
 def ping():
     return {"message": "pong"}
 
-# 受保护路由
-protected_router = APIRouter(prefix="/api", tags=["troov"])
+@public_router.get("/sms/upload", summary="上报短信", response_model=ShortMessageDetail)
+def sms_upload(
+    phone: str = Query(..., description="手机号"),
+    message: str = Query(..., description="短信内容"),
+    max_ttl: int = Query(300, description="短信保存时间(秒)"),
+    redis_client: Redis = Depends(get_redis_client)
+):
+    """
+    保存短信到 Redis
+    """
+    received_at = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
+    msg = save_short_message(redis_client, phone, message, received_at, max_ttl)
+    return msg
 
-@protected_router.get("/users", response_model=List[UserOut])
+@protected_router.get("/users", summary="查询用户", response_model=List[UserOut])
 def get_users():
     return [
         {"id": 1, "name": "Alice"},
         {"id": 2, "name": "Bob"}
     ]
 
-@protected_router.get("/troov/rate", response_model=List[TroovRate])
+@protected_router.get("/troov/rate", summary="TROOV 查询rate", response_model=List[TroovRate])
 def troov_rate(date: str = Query(..., description="查询的日期, 格式: YYYY-MM-DD"),
                redis_client: Redis = Depends(get_redis_client)):
     # 调用 service 层获取数据
     return get_rate_by_date(redis_client, date)
+
+@protected_router.get("/sms/download", summary="读取短信", response_model=List[ShortMessageDetail])
+def sms_download(
+    phone: str = Query(..., description="手机号"),
+    keyword: str = Query('', description="短信内容关键字"),
+    sent_at: str = Query('', description="筛选时间(可选)"),
+    redis_client: Redis = Depends(get_redis_client)
+):
+    """
+    查询短信(支持关键字和时间过滤)
+    """
+    results = query_short_message(redis_client, phone, keyword or None, sent_at or None)
+    return results

+ 6 - 0
app/schemas/sms.py

@@ -0,0 +1,6 @@
+from pydantic import BaseModel
+
+class ShortMessageDetail(BaseModel):
+    phone: str
+    message: str
+    received_at: str

+ 1 - 6
app/schemas/user.py

@@ -2,9 +2,4 @@ from pydantic import BaseModel
 
 class UserOut(BaseModel):
     id: int
-    name: str
-
-class TroovRate(BaseModel):
-    time: str
-    rate: str
-    capacity: int
+    name: str

+ 57 - 0
app/services/sms_service.py

@@ -0,0 +1,57 @@
+import json
+import time
+import requests
+from typing import List
+from fastapi import Depends
+from app.schemas.sms import ShortMessageDetail
+
+
+def save_short_message(redis_client, phone: str, message: str, received_at: str, max_ttl: int) -> ShortMessageDetail:
+    """
+    将短信保存到 Redis。
+    键格式: sms:{phone}
+    值为 JSON 数组(保存最近多条短信)
+    """
+    key = f"sms:{phone}"
+
+    # 取出已有数据
+    existing_data = redis_client.get(key)
+    if existing_data:
+        messages = json.loads(existing_data)
+    else:
+        messages = []
+
+    # 添加新短信
+    new_msg = ShortMessageDetail(phone=phone, message=message, received_at=received_at)
+    messages.append(new_msg.dict())
+
+    # 最多保留最近 20 条(可调整)
+    messages = messages[-20:]
+
+    # 保存回 Redis
+    redis_client.setex(key, max_ttl, json.dumps(messages))
+
+    return new_msg
+
+
+def query_short_message(redis_client, phone: str, keyword: str, sent_at: str) -> List[ShortMessageDetail]:
+    """
+    从 Redis 查询短信。
+    支持按关键字和时间过滤。
+    """
+    key = f"sms:{phone}"
+    existing_data = redis_client.get(key)
+    if not existing_data:
+        return []
+
+    messages = [ShortMessageDetail(**m) for m in json.loads(existing_data)]
+
+    # 关键字过滤
+    if keyword:
+        messages = [m for m in messages if keyword in m.message]
+
+    # 时间过滤(如果需要更复杂可转为时间戳比较)
+    if sent_at:
+        messages = [m for m in messages if m.received_at >= sent_at]
+
+    return messages