81 lines
2.6 KiB
Python
81 lines
2.6 KiB
Python
"""资金账户服务:余额查询 + 余额加减(路由层只编排,不碰数据/逻辑)。"""
|
||||
|
|
from __future__ import annotations
|
|||
|
|
|
|||
|
|
from decimal import Decimal
|
|||
|
|
|
|||
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|||
|
|
|
|||
|
|
from model.fin_account import FinAccount
|
|||
|
|
from model.sys_user import SysUser
|
|||
|
|
from repositories.fin_account import FinAccountRepo
|
|||
|
|
from schemas.account import BalanceResp
|
|||
|
|
from utils.exceptions import ForbiddenError, NotFoundError, ParamError
|
|||
|
|
|
|||
|
|
_ZERO = Decimal("0.00")
|
|||
|
|
_DEFAULT_CURRENCY = "CNY"
|
|||
|
|
|
|||
|
|
|
|||
|
|
def _build_balance_resp(account: FinAccount) -> BalanceResp:
|
|||
|
|
return BalanceResp(
|
|||
|
|
customer_id=account.customer_id,
|
|||
|
|
balance=account.balance,
|
|||
|
|
available_balance=account.balance - account.frozen_amount,
|
|||
|
|
frozen_amount=account.frozen_amount,
|
|||
|
|
currency=account.currency,
|
|||
|
|
status=account.status,
|
|||
|
|
update_time=account.update_time,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
async def get_balance(db: AsyncSession, user: SysUser) -> BalanceResp:
|
|||
|
|
"""查询当前用户现金余额。
|
|||
|
|
|
|||
|
|
- 仅客户账号可查(员工共用 sys_user,但无资金账户);
|
|||
|
|
- 未开资金户时按零余额返回,不报错。
|
|||
|
|
"""
|
|||
|
|
if user.user_type != "CUSTOMER":
|
|||
|
|
raise ForbiddenError("仅客户账号可查询资金余额")
|
|||
|
|
|
|||
|
|
account = await FinAccountRepo(db).get_by_customer_id(user.id)
|
|||
|
|
if account is None:
|
|||
|
|
return BalanceResp(
|
|||
|
|
customer_id=user.id,
|
|||
|
|
balance=_ZERO,
|
|||
|
|
available_balance=_ZERO,
|
|||
|
|
frozen_amount=_ZERO,
|
|||
|
|
currency=_DEFAULT_CURRENCY,
|
|||
|
|
status="正常",
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
return _build_balance_resp(account)
|
|||
|
|
|
|||
|
|
|
|||
|
|
async def adjust_balance(
|
|||
|
|
db: AsyncSession, user: SysUser, direction: str, amount: Decimal
|
|||
|
|
) -> BalanceResp:
|
|||
|
|
"""加减余额:direction=add 入账 / sub 出账。
|
|||
|
|
|
|||
|
|
- add:balance += amount,未开资金户时自动开户入账;
|
|||
|
|
- sub:balance -= amount,可用余额(balance - frozen_amount)不足时报错。
|
|||
|
|
"""
|
|||
|
|
if user.user_type != "CUSTOMER":
|
|||
|
|
raise ForbiddenError("仅客户账号可调整余额")
|
|||
|
|
|
|||
|
|
repo = FinAccountRepo(db)
|
|||
|
|
account = await repo.get_by_customer_id(user.id)
|
|||
|
|
|
|||
|
|
if direction == "add":
|
|||
|
|
if account is None:
|
|||
|
|
account = await repo.create(user.id, amount)
|
|||
|
|
else:
|
|||
|
|
account = await repo.add_balance(user.id, amount)
|
|||
|
|
else: # sub
|
|||
|
|
if account is None:
|
|||
|
|
raise NotFoundError("资金账户不存在")
|
|||
|
|
updated = await repo.subtract_balance(user.id, amount)
|
|||
|
|
if updated is None:
|
|||
|
|
raise ParamError("可用余额不足")
|
|||
|
|
account = updated
|
|||
|
|
|
|||
|
|
return _build_balance_resp(account)
|