feat: Airwallex 发卡管理后台完整实现

- 后端: FastAPI + SQLAlchemy + SQLite, JWT认证, 代理支持的AirwallexClient
- 前端: React 18 + Vite + Ant Design 5, 中文界面
- 功能: 卡片管理, 持卡人管理, 交易记录, API令牌, 系统设置, 审计日志
- 第三方API: X-API-Key认证, 权限控制
- Docker部署: docker-compose编排前后端
This commit is contained in:
zqq61
2026-03-15 23:05:08 +08:00
commit 4f53889a8e
98 changed files with 10847 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
"""
Models for the Airwallex Issuing Cardholder API.
"""
from typing import Optional, List, Dict, Any, Literal
from pydantic import Field, EmailStr
from .base import AirwallexModel
from .issuing_common import Address, Name, Employer, HasMoreResponse
class Individual(AirwallexModel):
"""Model for individual cardholder details."""
address: Address = Field(..., description="Address of the cardholder")
cardholder_agreement_terms_consent_obtained: Optional[str] = Field(None, description="Whether consent was obtained")
date_of_birth: str = Field(..., description="Date of birth in YYYY-MM-DD format")
employers: Optional[List[Employer]] = Field(None, description="Employers")
express_consent_obtained: Optional[str] = Field(None, description="Whether express consent was obtained")
name: Name = Field(..., description="Name of the cardholder")
class CardholderCreateRequest(AirwallexModel):
"""Model for cardholder creation request."""
email: EmailStr = Field(..., description="Email address of the cardholder")
individual: Individual = Field(..., description="Details about the cardholder")
mobile_number: Optional[str] = Field(None, description="Mobile number of the cardholder")
postal_address: Optional[Address] = Field(None, description="Postal address of the cardholder")
type: str = Field(..., description="The type of cardholder (INDIVIDUAL or DELEGATE)")
class CardholderUpdateRequest(AirwallexModel):
"""Model for cardholder update request."""
individual: Optional[Individual] = Field(None, description="Details about the cardholder")
mobile_number: Optional[str] = Field(None, description="Mobile number of the cardholder")
postal_address: Optional[Address] = Field(None, description="Postal address of the cardholder")
type: Optional[str] = Field(None, description="The type of cardholder (INDIVIDUAL or DELEGATE)")
class Cardholder(AirwallexModel):
"""Model for an Airwallex cardholder."""
resource_name: str = "issuing/cardholders"
cardholder_id: str = Field(..., description="Unique Identifier for cardholder")
email: EmailStr = Field(..., description="Email address of the cardholder")
individual: Optional[Individual] = Field(None, description="Details about the cardholder")
mobile_number: Optional[str] = Field(None, description="The mobile number of the cardholder")
postal_address: Optional[Address] = Field(None, description="Postal address for the cardholder")
status: str = Field(..., description="The status of the cardholder (PENDING, READY, DISABLED, INCOMPLETE)")
type: str = Field(..., description="The type of cardholder (INDIVIDUAL or DELEGATE)")
class CardholderListResponse(HasMoreResponse):
"""Model for cardholder list response."""
items: List[Cardholder] = Field(..., description="List of cardholders")