chore(release): bump version to 1.9.1 and apply pending changes

This commit is contained in:
小鱼开发
2026-06-16 15:17:30 +08:00
parent 9a71584d6c
commit c6a40331d4
152 changed files with 9396 additions and 10267 deletions
+19 -15
View File
@@ -6,7 +6,7 @@
"""
import logging
from datetime import UTC, datetime
from datetime import UTC, datetime, timedelta
import httpx
from fastapi import APIRouter, Depends, HTTPException, Request
@@ -14,6 +14,7 @@ from fastapi.responses import JSONResponse
from sqlalchemy.ext.asyncio import AsyncSession
from app.api.deps import get_current_user, get_db
from app.core.exceptions import InsufficientPointsException
from app.crud.point_recharge_order import point_recharge_order
from app.crud.point_transaction import point_transaction
from app.models.user import User
@@ -35,6 +36,7 @@ router = APIRouter(prefix="/points", tags=["Points"])
# ── 余额查询 ──────────────────────────────────────────
@router.get("/balance", response_model=ApiResponse[PointBalanceResponse])
async def get_balance(
db: AsyncSession = Depends(get_db),
@@ -47,6 +49,7 @@ async def get_balance(
# ── 流水查询 ──────────────────────────────────────────
@router.get("/transactions", response_model=ApiResponse[PointTransactionListResponse])
async def list_transactions(
pagination: PaginationParams = Depends(),
@@ -127,12 +130,13 @@ async def list_transactions(
# ── 充值 ──────────────────────────────────────────────
@router.post("/recharge", response_model=ApiResponse[RechargeResponse])
async def create_recharge_order(
request: RechargeRequest,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
http_request: Request = None,
http_request: Request = None, # type: ignore[assignment]
):
"""
创建积分充值订单(微信支付 Native 扫码)
@@ -213,6 +217,7 @@ async def create_recharge_order(
logger.error(f"[Points] 微信统一下单未返回 code_url: {wx_result}")
order.status = "failed"
order.error_msg = "微信未返回二维码链接"
await db.commit()
raise HTTPException(status_code=500, detail="微信支付下单失败")
order.prepay_id = wx_result.get("prepay_id")
@@ -303,9 +308,7 @@ async def handle_wxpay_notify(
return _wx_response()
# 查找订单
order = await point_recharge_order.get_by_out_trade_no(
db, out_trade_no=out_trade_no
)
order = await point_recharge_order.get_by_out_trade_no(db, out_trade_no=out_trade_no)
if not order:
logger.error(f"[WechatPay] 回调订单不存在: {out_trade_no}")
return _wx_response()
@@ -371,6 +374,7 @@ async def handle_wxpay_notify(
await db.rollback()
logger.exception(f"[WechatPay] 订单 {out_trade_no} 充值积分失败: {e}")
# 记录错误但不抛出,返回 SUCCESS 避免微信重试
order.status = "failed"
order.error_msg = f"充值积分失败: {e}"
await db.commit()
@@ -400,9 +404,7 @@ async def query_recharge_status(
wxpay = get_wxpay_service()
async with httpx.AsyncClient(timeout=httpx.Timeout(30.0, connect=10.0)) as client:
wx_result = await wxpay.query_order(
client, out_trade_no=order.out_trade_no
)
wx_result = await wxpay.query_order(client, out_trade_no=order.out_trade_no)
order.query_result = str(wx_result)
trade_state = wx_result.get("trade_state", "")
@@ -465,6 +467,7 @@ async def query_recharge_status(
# ── 充值档位查询 ──────────────────────────────────────
@router.get("/recharge-options", response_model=ApiResponse[list[dict]])
async def get_recharge_options(
current_user: User = Depends(get_current_user),
@@ -480,6 +483,7 @@ async def get_recharge_options(
# ── 扣费业务类型查询 ──────────────────────────────────
@router.get("/chargeable-types", response_model=ApiResponse[list[str]])
async def get_chargeable_types(
current_user: User = Depends(get_current_user),
@@ -496,6 +500,7 @@ async def get_chargeable_types(
# ── 积分规则查询 ──────────────────────────────────────
@router.get("/rules", response_model=ApiResponse[list[dict]])
async def get_points_rules(
current_user: User = Depends(get_current_user),
@@ -530,9 +535,9 @@ async def get_points_rules(
# ── 积分预估查询 ──────────────────────────────────────
# ── 今日消费统计 ──────────────────────────────────────
@router.get("/today-consumed", response_model=ApiResponse[dict])
async def get_today_consumed(
db: AsyncSession = Depends(get_db),
@@ -545,6 +550,7 @@ async def get_today_consumed(
# ── 直接消费扣费(前端/Rust 层调用)───────────────────
@router.post("/consume", response_model=ApiResponse[dict])
async def consume_points(
request: ConsumeRequest,
@@ -569,12 +575,12 @@ async def consume_points(
source_type=request.source_type,
source_id=request.source_id,
description=f"{request.description or request.source_type}",
allow_negative=False,
allow_negative=request.allow_negative,
)
except ValueError as e:
except InsufficientPointsException:
# 余额不足(在同一事务内判断,避免竞态)
if "积分不足" in str(e):
raise HTTPException(status_code=402, detail=str(e))
raise
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
await db.commit()
@@ -587,5 +593,3 @@ async def consume_points(
},
message="消费成功",
)