jerry 2 місяців тому
батько
коміт
e32daa45ae

+ 14 - 2
app/api/router.py

@@ -23,7 +23,7 @@ from app.models.product import VasProduct
 from app.models.payment import VasPayment
 from app.models.payment import VasPayment
 from app.schemas.common import ApiResponse, PageResponse
 from app.schemas.common import ApiResponse, PageResponse
 from app.schemas.troov import TroovRate, TroovCheckForbiddenInput, TroovProb
 from app.schemas.troov import TroovRate, TroovCheckForbiddenInput, TroovProb
-from app.schemas.sms import ShortMessageDetail
+from app.schemas.sms import ShortMessageDetail, SmsSendIn
 from app.schemas.configuration import ConfigurationCreate, ConfigurationUpdate, ConfigurationOut
 from app.schemas.configuration import ConfigurationCreate, ConfigurationUpdate, ConfigurationOut
 from app.schemas.email_authorizations import EmailContent, EmailAuthorizationCreate, EmailAuthorizationUpdate, EmailAuthorizationOut
 from app.schemas.email_authorizations import EmailContent, EmailAuthorizationCreate, EmailAuthorizationUpdate, EmailAuthorizationOut
 from app.schemas.emails import VasEmailCreate, VasEmailOut
 from app.schemas.emails import VasEmailCreate, VasEmailOut
@@ -60,7 +60,7 @@ from app.services.docker_remote_service import DockerRemoteService
 from app.services.configuration_service import ConfigurationService
 from app.services.configuration_service import ConfigurationService
 from app.services.troov_service import TroovService
 from app.services.troov_service import TroovService
 from app.services.visametric_service import VisametricService
 from app.services.visametric_service import VisametricService
-from app.services.sms_service import save_short_message, query_short_message
+from app.services.sms_service import save_short_message, query_short_message, send_sms
 from app.services.email_authorizations_service import EmailAuthorizationService
 from app.services.email_authorizations_service import EmailAuthorizationService
 from app.services.emails_service import EmailsService
 from app.services.emails_service import EmailsService
 from app.services.short_url_service import ShortUrlService
 from app.services.short_url_service import ShortUrlService
@@ -291,6 +291,18 @@ async def sms_download(
     obj = await query_short_message(redis_client, phone, keyword or None, sent_at or None)
     obj = await query_short_message(redis_client, phone, keyword or None, sent_at or None)
     return success(data=obj)
     return success(data=obj)
 
 
+
+@admin_required_router.post("/sms/send", summary="发送短信", tags=["短信接口"], response_model=ApiResponse[str])
+async def sms_send(
+    payload: SmsSendIn,
+):
+    res = await send_sms(
+        send_to=payload.send_to,
+        sender=payload.sender,
+        content=payload.content,
+    )
+    return success(data=res)
+
 @admin_required_router.get("/troov/rate", summary="TROOV 查询rate", tags=["通用接口"], response_model=ApiResponse[List[TroovRate]])
 @admin_required_router.get("/troov/rate", summary="TROOV 查询rate", tags=["通用接口"], response_model=ApiResponse[List[TroovRate]])
 async def troov_rate(date: str = Query(..., description="查询的日期, 格式: YYYY-MM-DD"),
 async def troov_rate(date: str = Query(..., description="查询的日期, 格式: YYYY-MM-DD"),
                redis_client: Redis = Depends(get_redis_client)):
                redis_client: Redis = Depends(get_redis_client)):

+ 7 - 1
app/schemas/sms.py

@@ -3,4 +3,10 @@ from pydantic import BaseModel
 class ShortMessageDetail(BaseModel):
 class ShortMessageDetail(BaseModel):
     phone: str
     phone: str
     message: str
     message: str
-    received_at: str
+    received_at: str
+
+
+class SmsSendIn(BaseModel):
+    send_to: str
+    sender: str
+    content: str

+ 1 - 1
app/services/slot_snapshot_service.py

@@ -46,7 +46,7 @@ class SlotSnapshotService:
             redis_client, 
             redis_client, 
             throttle_key, 
             throttle_key, 
             signature, 
             signature, 
-            expire_seconds=1800
+            expire_seconds=2*60*60
         )
         )
         # ==================== 修复结束 ====================
         # ==================== 修复结束 ====================
 
 

+ 49 - 0
app/services/sms_service.py

@@ -1,9 +1,13 @@
 # app/services/sms_service.py
 # app/services/sms_service.py
 
 
 import json
 import json
+import os
 from typing import List
 from typing import List
+from urllib.parse import quote
+import aiohttp
 from redis.asyncio import Redis
 from redis.asyncio import Redis
 from app.schemas.sms import ShortMessageDetail
 from app.schemas.sms import ShortMessageDetail
+from app.core.biz_exception import BizLogicError
 
 
 
 
 async def save_short_message(
 async def save_short_message(
@@ -84,3 +88,48 @@ async def query_short_message(
         ]
         ]
 
 
     return messages
     return messages
+
+
+async def send_sms(
+    send_to: str,
+    sender: str,
+    content: str,
+    cpid: str = "",
+    cppwd: str = "",
+    base_url: str = "",
+) -> str:
+    """
+    发送短信(异步版)
+    """
+    cpid = cpid or os.getenv("SMS_CPID", "6jLoZoRZ")
+    cppwd = cppwd or os.getenv("SMS_CPPWD", "LYTErsAE")
+    base_url = base_url or os.getenv("SMS_BASE_URL", "http://api2.santo.cc/submit")
+
+    if not send_to:
+        raise BizLogicError("sms send_to required")
+    if not sender:
+        raise BizLogicError("sms sender required")
+    if not content:
+        raise BizLogicError("sms content required")
+
+    encoded = quote(content, safe="")
+    url = (
+        f"{base_url}"
+        f"?command=MT_REQUEST"
+        f"&cpid={cpid}"
+        f"&cppwd={cppwd}"
+        f"&da={send_to}"
+        f"&sa={sender}"
+        f"&sm={encoded}"
+    )
+
+    timeout = aiohttp.ClientTimeout(total=10)
+    try:
+        async with aiohttp.ClientSession(timeout=timeout) as session:
+            async with session.get(url) as resp:
+                text = await resp.text()
+                if resp.status >= 300:
+                    raise BizLogicError(f"sms send failed, http_status={resp.status}, body={text}")
+                return text
+    except aiohttp.ClientError as e:
+        raise BizLogicError(f"sms send request error: {e}")