feat: 添加后台登录验证码、记住密码功能,优化媒体资源与前端规范

- 新增后台登录图形验证码功能,完善登录安全防护
- 新增登录rememberMe参数,控制Refresh Token的会话持久化策略
- 实现OSS私有桶媒体URL自动签名,统一处理图片资源的临时访问签名
- 新增素材库数据库表与上传API,规范媒体资源管理流程
- 统一前端UI图标使用@element-plus/icons-vue,重构布局图标组件
- 登录页新增验证码输入、刷新功能,添加账号记忆与记住密码逻辑
- 更新全套文档,补充API契约、技术决策记录与集成流程说明
- 修复多个业务页面的图标展示问题,新增认证流程相关测试用例
This commit is contained in:
duanshuwen committed 2026-08-27 07:50:59 +08:00
1 parent 2c8c327de7
commit 6245159e7c
35 files changed
+914 -79

No files matched your search

+44 -1
View File
@@ -11,6 +11,7 @@ from app.models import AdminUser, Customer, HeroSlide, Lead, MediaAsset, Vehicle
from app.routers import admin as admin_router
from app.routers import public as public_router
from app.routers.shared import site_config
from app.redis_session import InMemoryAdminSessionStore, get_admin_session_store
from app.schemas import LeadCreateIn, LeadQuery
@@ -264,6 +265,39 @@ def test_admin_dynamic_routers_requires_admin_authentication():
assert response.json() == {"code": 401, "msg": "请先登录后台", "data": None}
def test_admin_login_requires_valid_captcha():
admin_user = AdminUser(
id="admin-test",
email="admin@example.com",
name="Admin",
role="admin",
passwordHash=hash_password("ChangeMe123!", rounds=4),
isActive=True,
)
fake_db = FakeDb(scalar_values=[admin_user])
store = InMemoryAdminSessionStore()
store.create_captcha("captcha-test", "ABCD", 120)
app = create_app()
app.dependency_overrides[get_db] = lambda: fake_db
app.dependency_overrides[get_admin_session_store] = lambda: store
try:
response = TestClient(app).post(
"/api/admin/auth/login",
json={
"email": "admin@example.com",
"password": "ChangeMe123!",
"captchaId": "captcha-test",
"captchaCode": "WRONG",
},
)
finally:
app.dependency_overrides.clear()
assert response.status_code == 401
assert response.json()["data"] is None
def test_admin_login_returns_token_and_user():
admin_user = AdminUser(
id="admin-test",
@@ -274,13 +308,22 @@ def test_admin_login_returns_token_and_user():
isActive=True,
)
fake_db = FakeDb(scalar_values=[admin_user])
store = InMemoryAdminSessionStore()
store.create_captcha("captcha-contract", "ABCD", 120)
app = create_app()
app.dependency_overrides[get_db] = lambda: fake_db
app.dependency_overrides[get_admin_session_store] = lambda: store
try:
response = TestClient(app).post(
"/api/admin/auth/login",
json={"email": "admin@example.com", "password": "ChangeMe123!"},
json={
"email": "admin@example.com",
"password": "ChangeMe123!",
"captchaId": "captcha-contract",
"captchaCode": "ABCD",
"rememberMe": True,
},
)
finally:
app.dependency_overrides.clear()