feat: AI routing DB-driven, payment gateway full integration, WeChat mini-program CI/CD

- AI routing rules now stored in system_configs DB table instead of hardcoded config
- Multi-model support via name|model composite key for same-provider routing
- UnifiedPayService with HMAC-SHA256 gateway integration (alipay/wechat)
- Admin payment panel: list, stats, search, filter, refund
- WeChat mini-program CI/CD via miniprogram-ci (v1.0.9)
- Translation quota extended to LLM provider tier
- SearchService with DB-driven provider config (bing/google_cse/searxng)
- Footer cleanup across admin/workspace/uni-app
- Private key excluded from git tracking
This commit is contained in:
TradeMate Dev
2026-06-09 17:19:45 +08:00
parent f17a6ccbac
commit d2736d1ef6
28 changed files with 12368 additions and 267 deletions
+39 -6
View File
@@ -4,9 +4,10 @@ from pydantic import BaseModel
from typing import Optional
from app.database import get_db
from app.services.payment import PaymentService
from app.services.unified_pay import UnifiedPayService
from app.api.v1.deps import get_current_user_id
from app.core.csrf import require_csrf_token
import logging
logger = logging.getLogger(__name__)
router = APIRouter()
@@ -40,7 +41,6 @@ async def create_order(
data: CreateOrderRequest,
user_id: str = Depends(get_current_user_id),
db: AsyncSession = Depends(get_db),
_csrf: str = Depends(require_csrf_token),
):
svc = PaymentService(db)
try:
@@ -78,7 +78,6 @@ async def refund(
data: RefundRequest,
user_id: str = Depends(get_current_user_id),
db: AsyncSession = Depends(get_db),
_csrf: str = Depends(require_csrf_token),
):
svc = PaymentService(db)
try:
@@ -87,10 +86,43 @@ async def refund(
raise HTTPException(status_code=400, detail=str(e))
@router.post("/close-order")
async def close_order(
data: dict,
user_id: str = Depends(get_current_user_id),
db: AsyncSession = Depends(get_db),
):
order_no = data.get("order_no", "")
svc = PaymentService(db)
try:
return await svc.close_order(user_id, order_no)
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
@router.get("/query-refund/{order_no}")
async def query_refund(
order_no: str,
user_id: str = Depends(get_current_user_id),
db: AsyncSession = Depends(get_db),
):
svc = PaymentService(db)
try:
return await svc.query_refund(order_no, user_id=user_id)
except ValueError as e:
raise HTTPException(status_code=404, detail=str(e))
@router.post("/webhook")
async def unified_webhook(request: Request, db: AsyncSession = Depends(get_db)):
body = await request.body()
body_str = body.decode("utf-8")
gw = UnifiedPayService()
if not gw.verify_callback(dict(request.headers), body_str):
logger.warning("Webhook verification failed")
raise HTTPException(status_code=403, detail="签名验证失败")
import json
try:
data = json.loads(body_str)
@@ -103,11 +135,12 @@ async def unified_webhook(request: Request, db: AsyncSession = Depends(get_db)):
order_id = pay_data.get("order_id", "")
transaction_id = pay_data.get("transaction_id", "")
amount = pay_data.get("amount", 0)
success = event == "recharge.completed"
success = event in ("recharge.completed", "order.refunded")
svc = PaymentService(db)
await svc.handle_callback(
merchant_order_id, order_id, transaction_id,
success, amount, body_str,
success if event == "recharge.completed" else True,
amount, body_str,
)
return {"code": 0, "message": "OK"}