feat: 添加后台登录验证码、记住密码功能,优化媒体资源与前端规范
- 新增后台登录图形验证码功能,完善登录安全防护 - 新增登录rememberMe参数,控制Refresh Token的会话持久化策略 - 实现OSS私有桶媒体URL自动签名,统一处理图片资源的临时访问签名 - 新增素材库数据库表与上传API,规范媒体资源管理流程 - 统一前端UI图标使用@element-plus/icons-vue,重构布局图标组件 - 登录页新增验证码输入、刷新功能,添加账号记忆与记住密码逻辑 - 更新全套文档,补充API契约、技术决策记录与集成流程说明 - 修复多个业务页面的图标展示问题,新增认证流程相关测试用例
This commit is contained in:
1 parent
2c8c327de7
commit
6245159e7c
35 files changed
+914
-79
No files matched your search
@@ -1,6 +1,8 @@
|
||||
from datetime import datetime
|
||||
from sqlalchemy.inspection import inspect
|
||||
|
||||
from .media_urls import resolve_media_url
|
||||
|
||||
|
||||
def encode_value(value):
|
||||
if isinstance(value, datetime):
|
||||
@@ -20,6 +22,21 @@ def model_dict(instance, include: dict[str, object] | None = None) -> dict:
|
||||
return data
|
||||
|
||||
|
||||
def media_model_dict(instance) -> dict:
|
||||
return resolve_media_fields(model_dict(instance))
|
||||
|
||||
|
||||
def resolve_media_fields(data: dict) -> dict:
|
||||
result = dict(data)
|
||||
for field in ("image", "avatar", "qrImage"):
|
||||
if field in result:
|
||||
result[field] = resolve_media_url(result[field])
|
||||
for field in ("gallery", "images"):
|
||||
if field in result and isinstance(result[field], list):
|
||||
result[field] = [resolve_media_url(value) for value in result[field]]
|
||||
return result
|
||||
|
||||
|
||||
def lead_dict(lead) -> dict:
|
||||
return model_dict(
|
||||
lead,
|
||||
@@ -32,7 +49,7 @@ def public_wanfa_route_dict(route) -> dict:
|
||||
"id": route.id,
|
||||
"title": route.title,
|
||||
"subtitle": route.subtitle,
|
||||
"image": route.image,
|
||||
"image": resolve_media_url(route.image),
|
||||
"routeCount": route.routeCount,
|
||||
"demandKeyword": route.demandKeyword,
|
||||
}
|
||||
@@ -47,7 +64,7 @@ def public_wanfa_category_dict(category) -> dict:
|
||||
|
||||
|
||||
def detail_record_dict(detail) -> dict:
|
||||
return model_dict(detail)
|
||||
return media_model_dict(detail)
|
||||
|
||||
|
||||
def public_detail_dict(detail, concierge_advisor=None) -> dict:
|
||||
@@ -62,7 +79,7 @@ def public_detail_dict(detail, concierge_advisor=None) -> dict:
|
||||
"included": detail.included or [],
|
||||
"excluded": detail.excluded or [],
|
||||
"notes": detail.notes or [],
|
||||
"gallery": detail.gallery or [],
|
||||
"gallery": [resolve_media_url(image) for image in (detail.gallery or [])],
|
||||
"conciergeAdvisor": public_concierge_advisor_dict(concierge_advisor) if concierge_advisor else None,
|
||||
}
|
||||
|
||||
@@ -77,16 +94,16 @@ def public_home_wanfa_recommendation_dict(item) -> dict:
|
||||
|
||||
|
||||
def concierge_advisor_dict(advisor) -> dict:
|
||||
return model_dict(advisor)
|
||||
return media_model_dict(advisor)
|
||||
|
||||
|
||||
def public_concierge_advisor_dict(advisor) -> dict:
|
||||
return {
|
||||
"avatar": advisor.avatar,
|
||||
"avatar": resolve_media_url(advisor.avatar),
|
||||
"name": advisor.name,
|
||||
"role": advisor.role,
|
||||
"details": advisor.details or [],
|
||||
"qrImage": advisor.qrImage,
|
||||
"qrImage": resolve_media_url(advisor.qrImage),
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +114,7 @@ def public_home_experience_dict(item) -> dict:
|
||||
"category": item.category,
|
||||
"title": item.title,
|
||||
"englishTitle": item.englishTitle,
|
||||
"image": item.image,
|
||||
"image": resolve_media_url(item.image),
|
||||
"demandKeyword": item.demandKeyword,
|
||||
}
|
||||
|
||||
@@ -108,7 +125,7 @@ def public_home_team_building_dict(item) -> dict:
|
||||
"tag": item.tag,
|
||||
"title": item.title,
|
||||
"description": item.description,
|
||||
"image": item.image,
|
||||
"image": resolve_media_url(item.image),
|
||||
"demandKeyword": item.demandKeyword,
|
||||
}
|
||||
|
||||
@@ -132,7 +149,7 @@ def public_home_wild_archive_dict(item) -> dict:
|
||||
return {
|
||||
"id": item.id,
|
||||
"title": item.title,
|
||||
"image": item.image,
|
||||
"image": resolve_media_url(item.image),
|
||||
"demandKeyword": item.demandKeyword,
|
||||
"photoCount": len(item.images or [item.image]),
|
||||
}
|
||||
@@ -144,5 +161,5 @@ def public_home_wild_archive_detail_dict(item) -> dict:
|
||||
images = [item.image]
|
||||
return {
|
||||
**public_home_wild_archive_dict(item),
|
||||
"images": images,
|
||||
"images": [resolve_media_url(image) for image in images],
|
||||
}
|
||||
Reference in new issue
Block a user