This commit is contained in:
jeremygan2021
2026-02-16 19:14:45 +08:00
parent 569c07ecc0
commit 4467d5211e
2 changed files with 78 additions and 34 deletions

View File

@@ -148,7 +148,8 @@ docker run -d -p 9090:9090 \
### 短信服务
- `POST /api/send-sms` - 发送短信
- `POST /api/send-sms` - 发送验证码
- `POST /api/send-sms/diy` - 发送定制短信
- `GET /api/sms-records` - 获取短信记录
### OSS 服务

109
main.py
View File

@@ -7,20 +7,13 @@ from fastapi.middleware.cors import CORSMiddleware
from fastapi.security import APIKeyHeader
import uuid
import os
from typing import Optional, List
from typing import Optional, List, Dict, Any
from pydantic import BaseModel
from sms import SMS
from oss_service import oss_service
from config import settings
class SMSRequest(BaseModel):
phone_number: str
code: Optional[str] = None
template_code: Optional[str] = settings.sms_template_code
sign_name: Optional[str] = settings.sms_sign_name
class Config:
extra = "allow"
@@ -837,33 +830,95 @@ def update_user(phone: str, user_update: UserUpdate, current_user: dict = Depend
pool.putconn(conn)
class SMSCodeRequest(BaseModel):
phone_number: str
code: str
template_code: Optional[str] = settings.sms_template_code
sign_name: Optional[str] = settings.sms_sign_name
class SMSCustomRequest(BaseModel):
phone_number: str
template_code: str
sign_name: str
template_params: Optional[Dict[str, Any]] = None
class Config:
extra = "allow"
@app.post("/api/send-sms", tags=["短信服务"])
async def send_sms(sms_request: SMSRequest):
"""发送短信API"""
async def send_sms(request: SMSCodeRequest):
"""发送验证码API"""
sms = SMS()
# 构造参数
params = {"code": request.code}
print(f"Sending Verification Code to {request.phone_number}: {request.code}")
result = sms.main(
self=sms,
phone_number=request.phone_number,
template_code=request.template_code,
sign_name=request.sign_name,
**params
)
# 保存发送记录
_save_sms_record(request.phone_number, request.template_code, request.sign_name, params, result)
if not result or not result.get('success'):
return {"status": "failed", "message": result.get('error_message') if result else "发送失败"}
return {"status": "success", "message": "验证码发送请求已处理", "data": result}
@app.post("/api/send-sms/diy", tags=["短信服务"])
async def send_custom_sms(request: SMSCustomRequest):
"""通用短信发送API (支持自定义模板和参数)"""
sms = SMS()
# 获取所有参数
request_data = sms_request.dict()
request_data = request.dict()
# 提取固定参数
# 提取已知字段
phone_number = request_data.pop('phone_number')
template_code = request_data.pop('template_code')
sign_name = request_data.pop('sign_name')
template_params = request_data.pop('template_params', None)
# 过滤掉值为 None 的参数,剩余的作为动态参数
dynamic_params = {k: v for k, v in request_data.items() if v is not None}
# 剩下的作为动态参数
dynamic_params = request_data
print(f"Sending SMS with template_code: {template_code}, sign_name: {sign_name}, params: {dynamic_params}")
# 如果有显式的 template_params合并进去
if template_params:
dynamic_params.update(template_params)
# 特殊处理:兼容 Swagger UI 或某些客户端生成的 additionalProp1
if 'additionalProp1' in dynamic_params and isinstance(dynamic_params['additionalProp1'], dict):
extra_props = dynamic_params.pop('additionalProp1')
dynamic_params.update(extra_props)
print(f"Sending Custom SMS with template_code: {template_code}, params: {dynamic_params}")
result = sms.main(
self=sms,
phone_number=phone_number,
template_code=template_code,
self=sms,
phone_number=phone_number,
template_code=template_code,
sign_name=sign_name,
**dynamic_params
)
# 保存发送记录到数据库
# 保存发送记录
_save_sms_record(phone_number, template_code, sign_name, dynamic_params, result)
if not result or not result.get('success'):
return {"status": "failed", "message": result.get('error_message') if result else "发送失败"}
return {"status": "success", "message": "短信发送请求已处理", "data": result}
def _save_sms_record(phone_number, template_code, sign_name, params, result):
"""辅助函数:保存短信记录到数据库"""
conn = pool.getconn()
try:
with conn.cursor() as cur:
@@ -871,15 +926,7 @@ async def send_sms(sms_request: SMSRequest):
biz_id = result.get('biz_id') if result else None
error_message = result.get('error_message') if result else 'Unknown error'
# 将参数转换为字符串存储
if dynamic_params:
# 如果只有 code 参数,为了保持兼容性,优先尝试只存 code 值(如果这是之前的习惯)
# 但考虑到现在支持多参数,存 JSON 更加通用。
# 这里为了直观,如果有多个参数或没有 code存 JSON。
# 如果只有 code也可以存 JSON因为 sms.py 内部最终是转 JSON 发送的。
saved_param = json.dumps(dynamic_params, ensure_ascii=False)
else:
saved_param = ""
saved_param = json.dumps(params, ensure_ascii=False) if params else ""
cur.execute("""
INSERT INTO sms_records (phone_number, template_code, template_param, sign_name, status, biz_id, error_message)
@@ -890,11 +937,7 @@ async def send_sms(sms_request: SMSRequest):
print(f"Error saving SMS record: {e}")
finally:
pool.putconn(conn)
if not result or not result.get('success'):
return {"status": "failed", "message": result.get('error_message') if result else "发送失败"}
return {"status": "success", "message": "短信发送请求已处理", "data": result}
class ConversationCreate(BaseModel):
user_phone: str | None = None