deliveryman-api/app/core/account.py
aaron 1c38cf825b 1. 规范订单号
2. 账户明细中,关联对应的订单号。
2025-01-19 23:44:59 +08:00

73 lines
2.1 KiB
Python

from sqlalchemy.orm import Session
from app.models.user_account import UserAccountDB, AccountDetailDB, AccountDetailType
from decimal import Decimal
from typing import Optional
class AccountManager:
"""用户账户管理类"""
def __init__(self, db: Session):
self.db = db
def get_or_create_account(self, user_id: int) -> UserAccountDB:
"""获取或创建用户账户"""
account = self.db.query(UserAccountDB).filter(
UserAccountDB.user_id == user_id
).first()
if not account:
account = UserAccountDB(
user_id=user_id,
balance=0
)
self.db.add(account)
self.db.flush()
return account
def change_balance(
self,
user_id: int,
amount: float,
description: str,
transaction_id: Optional[str] = None
) -> UserAccountDB:
"""
变更用户余额
Args:
user_id: 用户ID
amount: 变更金额(正数为收入,负数为支出)
description: 变更说明
transaction_id: 关联订单号
Returns:
更新后的账户信息
Raises:
Exception: 余额不足等异常
"""
# 转换为 Decimal 以确保精确计算
decimal_amount = Decimal(str(amount))
# 获取或创建账户
account = self.get_or_create_account(user_id)
# 检查余额是否充足(支出时)
if decimal_amount < 0 and account.balance + decimal_amount < 0:
raise Exception("账户余额不足")
# 更新余额
account.balance += decimal_amount
# 记录账户明细
detail = AccountDetailDB(
user_id=user_id,
amount=decimal_amount,
type=AccountDetailType.INCOME if decimal_amount > 0 else AccountDetailType.EXPENSE,
description=description,
transaction_id=transaction_id
)
self.db.add(detail)
return account