v2.1: 新增通知提醒功能和安全增强
功能: - 通知提醒系统: 还款日提醒、逾期提醒、系统消息横幅、登录时通知 - 通知中心UI: 铃铛图标 + 下拉列表 + 未读徽章 - 定时任务: APScheduler 每小时检查即将到期的还款 - 邮件通知: SMTP 发送还款提醒和安全警告 - 异常登录通知: 3/5/10次失败触发网页和邮件通知 安全: - 登录安全告警: 异常登录次数达到阈值时发送通知 - 密码重置链接: 一次性使用, 5分钟有效期 - 登录频率限制: IP级和账户级限制 技术: - 后端: FastAPI + SQLAlchemy + PostgreSQL - 前端: 纯 HTML/CSS/JS - 部署: Docker Compose (新增 build 配置)
This commit is contained in:
0
backend/app/schemas/__init__.py
Normal file
0
backend/app/schemas/__init__.py
Normal file
256
backend/app/schemas/schemas.py
Normal file
256
backend/app/schemas/schemas.py
Normal file
@@ -0,0 +1,256 @@
|
||||
from pydantic import BaseModel
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class RegisterRequest(BaseModel):
|
||||
account: str
|
||||
password: str
|
||||
nickname: str = ""
|
||||
group_id: int | None = None
|
||||
|
||||
|
||||
class LoginRequest(BaseModel):
|
||||
account: str
|
||||
password: str
|
||||
|
||||
|
||||
class TokenResponse(BaseModel):
|
||||
access_token: str
|
||||
refresh_token: str
|
||||
token_type: str = "bearer"
|
||||
|
||||
|
||||
class RefreshRequest(BaseModel):
|
||||
refresh_token: str
|
||||
|
||||
|
||||
class UserProfile(BaseModel):
|
||||
id: int
|
||||
account: str
|
||||
nickname: str
|
||||
real_email: str = ""
|
||||
role: str
|
||||
status: str
|
||||
group_id: int | None = None
|
||||
group_name: str = ""
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class ChangePasswordRequest(BaseModel):
|
||||
old_password: str
|
||||
new_password: str
|
||||
|
||||
|
||||
class GroupCreate(BaseModel):
|
||||
name: str
|
||||
description: str = ""
|
||||
|
||||
|
||||
class GroupResponse(BaseModel):
|
||||
id: int
|
||||
name: str
|
||||
description: str
|
||||
member_count: int = 0
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class GroupMemberAdd(BaseModel):
|
||||
user_id: int
|
||||
|
||||
|
||||
class LoanCreate(BaseModel):
|
||||
name: str
|
||||
date: str
|
||||
amount: float
|
||||
rate: float
|
||||
periods: int
|
||||
method: str
|
||||
purpose: str = ""
|
||||
schedule: list[dict] = []
|
||||
paid: list[int] = []
|
||||
|
||||
|
||||
class LoanResponse(BaseModel):
|
||||
id: int
|
||||
name: str
|
||||
date: str
|
||||
amount: float
|
||||
rate: float
|
||||
periods: int
|
||||
method: str
|
||||
purpose: str
|
||||
schedule: list[dict]
|
||||
paid: list[int]
|
||||
user_id: int
|
||||
owner_name: str = ""
|
||||
|
||||
|
||||
class DebtCreate(BaseModel):
|
||||
creditor_name: str
|
||||
amount: int
|
||||
borrow_date: datetime
|
||||
interest_rate: float
|
||||
rate_type: str = "annual"
|
||||
repayment_method: str
|
||||
period_count: int
|
||||
period_unit: str = "month"
|
||||
notes: str = ""
|
||||
|
||||
|
||||
class DebtUpdate(BaseModel):
|
||||
creditor_name: str | None = None
|
||||
amount: int | None = None
|
||||
borrow_date: datetime | None = None
|
||||
interest_rate: float | None = None
|
||||
rate_type: str | None = None
|
||||
repayment_method: str | None = None
|
||||
period_count: int | None = None
|
||||
period_unit: str | None = None
|
||||
notes: str | None = None
|
||||
|
||||
|
||||
class DebtResponse(BaseModel):
|
||||
id: int
|
||||
user_id: int
|
||||
creditor_name: str
|
||||
amount: int
|
||||
borrow_date: datetime
|
||||
interest_rate: float
|
||||
rate_type: str
|
||||
repayment_method: str
|
||||
period_count: int
|
||||
period_unit: str
|
||||
status: str
|
||||
notes: str
|
||||
created_at: datetime
|
||||
total_paid: int = 0
|
||||
total_interest: int = 0
|
||||
owner_name: str = ""
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class RepaymentPlanResponse(BaseModel):
|
||||
id: int
|
||||
debt_id: int
|
||||
due_date: datetime
|
||||
principal_due: int
|
||||
interest_due: int
|
||||
total_due: int
|
||||
status: str
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class RepaymentRecordCreate(BaseModel):
|
||||
debt_id: int
|
||||
plan_id: int | None = None
|
||||
amount: int
|
||||
paid_date: datetime
|
||||
notes: str = ""
|
||||
|
||||
|
||||
class RepaymentRecordResponse(BaseModel):
|
||||
id: int
|
||||
debt_id: int
|
||||
plan_id: int | None
|
||||
amount: int
|
||||
paid_date: datetime
|
||||
notes: str
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class DashboardSummary(BaseModel):
|
||||
total_debt: int
|
||||
total_paid: int
|
||||
total_remaining: int
|
||||
active_count: int
|
||||
overdue_count: int
|
||||
paid_count: int
|
||||
upcoming_payments: list[dict]
|
||||
|
||||
|
||||
class AdminUserResponse(BaseModel):
|
||||
id: int
|
||||
account: str
|
||||
nickname: str
|
||||
real_email: str = ""
|
||||
role: str
|
||||
status: str
|
||||
group_id: int | None = None
|
||||
group_name: str = ""
|
||||
created_at: datetime
|
||||
debt_count: int = 0
|
||||
total_amount: int = 0
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class AdminDashboard(BaseModel):
|
||||
total_users: int
|
||||
active_debts: int
|
||||
total_amount: int
|
||||
overdue_count: int
|
||||
rate_distribution: dict
|
||||
status_distribution: dict
|
||||
|
||||
|
||||
class SystemSettingUpdate(BaseModel):
|
||||
value: str
|
||||
|
||||
|
||||
class NotificationResponse(BaseModel):
|
||||
id: int
|
||||
user_id: int
|
||||
title: str
|
||||
message: str
|
||||
type: str
|
||||
is_read: int
|
||||
related_debt_id: int | None = None
|
||||
related_plan_id: int | None = None
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class NotificationListResponse(BaseModel):
|
||||
items: list[NotificationResponse]
|
||||
total: int
|
||||
unread: int
|
||||
|
||||
|
||||
class EmailServiceConfig(BaseModel):
|
||||
smtp_host: str = ""
|
||||
smtp_port: int = 465
|
||||
smtp_user: str = ""
|
||||
smtp_password: str = ""
|
||||
smtp_from: str = ""
|
||||
smtp_use_tls: bool = True
|
||||
|
||||
|
||||
class ForgotPasswordRequest(BaseModel):
|
||||
account: str
|
||||
|
||||
|
||||
class VerifyResetCodeRequest(BaseModel):
|
||||
account: str
|
||||
code: str
|
||||
|
||||
|
||||
class ResetPasswordRequest(BaseModel):
|
||||
account: str
|
||||
code: str
|
||||
new_password: str
|
||||
Reference in New Issue
Block a user