智教助手平台:完整初始化

- 前端:Vue3 + TS + Element Plus,24 个页面路由(课件/组题/教案/动画/思维导图/作文批改/命题/课堂/资源/社区等)
- 后端:FastAPI + SQLAlchemy + SQLite,17 个路由模块,AI 服务层含降级模板
- AI:glm-5.x 推理模型已禁用思维链,确保输出真实内容
- 修复:ai_service 两处请求体注入 enable_thinking/thinking disabled
- 测试账号:13900999999 / test1234
This commit is contained in:
Zhang Jing Xuan
2026-07-29 16:29:10 +08:00
commit 0841b1a103
193 changed files with 44995 additions and 0 deletions
+130
View File
@@ -0,0 +1,130 @@
from pydantic import BaseModel, Field, field_validator
from datetime import datetime
from typing import Optional
class UserLogin(BaseModel):
phone: str = Field(..., pattern=r"^1[3-9]\d{9}$", description="手机号")
password: str = Field(..., min_length=6, max_length=50, description="密码")
class UserRegister(BaseModel):
phone: str = Field(..., pattern=r"^1[3-9]\d{9}$")
password: str = Field(..., min_length=6, max_length=50)
name: str = Field(..., min_length=2, max_length=50)
subject: str = Field(default="", max_length=50)
school: str = Field(default="", max_length=100)
grade: str = Field(default="", max_length=50)
class UserUpdate(BaseModel):
name: Optional[str] = None
avatar: Optional[str] = None
subject: Optional[str] = None
school: Optional[str] = None
grade: Optional[str] = None
class PasswordChange(BaseModel):
old_password: str = Field(..., min_length=6, max_length=50, description="当前密码")
new_password: str = Field(..., min_length=6, max_length=50, description="新密码")
class UserOut(BaseModel):
id: int
phone: str
name: str
avatar: str = ""
subject: str = ""
school: str = ""
grade: str = ""
role: str = "teacher"
credits: int = 0
total_credits_granted: int = 0
total_credits_used: int = 0
created_at: datetime | None = None
@field_validator("avatar", "subject", "school", "grade", "name", "role", mode="before")
@classmethod
def _none_to_empty(cls, v):
return "" if v is None else v
model_config = {"from_attributes": True}
class Token(BaseModel):
access_token: str
refresh_token: str
token_type: str = "bearer"
class TokenPayload(BaseModel):
sub: int
exp: datetime
class ProfileRecentItem(BaseModel):
id: int
item_type: str
title: str
subtitle: str = ""
status: str = ""
updated_at: datetime | None = None
class CreditTransactionOut(BaseModel):
id: int
amount: int
action: str = ""
description: str = ""
balance_after: int = 0
created_at: datetime | None = None
model_config = {"from_attributes": True}
class CreditBenefitOut(BaseModel):
credits: int = 0
daily_amount: int = 0
daily_claimed: bool = False
next_claim_text: str = ""
recent_checkins: list[CreditTransactionOut] = Field(default_factory=list)
class ProfileStatsOut(BaseModel):
credits: int = 0
total_credits_granted: int = 0
total_credits_used: int = 0
total_works: int = 0
draft_works: int = 0
published_works: int = 0
published_resources: int = 0
public_resources: int = 0
private_resources: int = 0
favorite_resources: int = 0
total_views: int = 0
total_downloads: int = 0
total_favorites: int = 0
classroom_activities: int = 0
active_classroom_activities: int = 0
classroom_responses: int = 0
community_posts: int = 0
community_favorites: int = 0
community_comments: int = 0
works_by_type: dict[str, int] = Field(default_factory=dict)
resources_by_type: dict[str, int] = Field(default_factory=dict)
recent_works: list[ProfileRecentItem] = Field(default_factory=list)
recent_resources: list[ProfileRecentItem] = Field(default_factory=list)
recent_interactions: list[ProfileRecentItem] = Field(default_factory=list)
recent_credit_transactions: list[CreditTransactionOut] = Field(default_factory=list)
class SendCodeRequest(BaseModel):
phone: str = Field(..., pattern=r"^1[3-9]\d{9}$", description="手机号")
class ResetPasswordRequest(BaseModel):
phone: str = Field(..., pattern=r"^1[3-9]\d{9}$")
code: str = Field(..., min_length=6, max_length=6, description="6位验证码")
new_password: str = Field(..., min_length=6, max_length=50, description="新密码")