Files
Mutual_Fund/service/account.py
2026-09-10 23:21:30 +08:00

81 lines
2.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""资金账户服务:余额查询 + 余额加减(路由层只编排,不碰数据/逻辑)。"""
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)