fix/various fixes

This commit is contained in:
Kevin
2026-03-20 15:15:35 +08:00
parent 7f57f96c25
commit 7317bf10cd
112 changed files with 3790 additions and 2242 deletions

View File

@@ -3,13 +3,21 @@ from datetime import timedelta
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.db import utc_now
from app.core.logging import get_logger
from app.core.redis import redis_service
from app.core.task_tracker import task_tracker
from app.features.user import repo
from app.features.user.models import User
from app.features.user.schemas import (
PURGE_USER_DATA_CONFIRMATION,
PurgeUserDataResponse,
TestSubscriptionResponse,
UpdateUserProfileRequest,
UserProfileResponse,
)
from app.ports.storage import ObjectStorage
logger = get_logger(__name__)
def _user_to_profile(user: User) -> UserProfileResponse:
@@ -74,3 +82,72 @@ class UserService:
message="已关闭测试订阅,恢复免费体验版",
subscription_type="free",
)
async def purge_all_user_data(
self,
user_id: str,
*,
confirmation: str,
object_storage: ObjectStorage | None = None,
) -> PurgeUserDataResponse:
"""物理删除该用户业务数据(不含 users 账号行);提交后再清 Redis / 任务追踪 / 锁 key。"""
if confirmation != PURGE_USER_DATA_CONFIRMATION:
raise ValueError("确认文案不正确,请按提示完整输入口令")
user = await repo.get_user_by_id(user_id, self._db)
if not user:
raise ValueError("用户不存在")
storage_keys = await repo.collect_object_storage_keys_before_purge(
self._db, user_id
)
conv_ids, chapter_ids, story_ids = await repo.collect_purge_context(
self._db, user_id
)
await repo.purge_user_related_rows(self._db, user_id)
await self._db.commit()
if object_storage and storage_keys:
for key in storage_keys:
try:
object_storage.delete(key)
except Exception as e:
logger.warning(
"对象存储删除失败 user_id=%s key=%s err=%s", user_id, key, e
)
for cid in conv_ids:
try:
await redis_service.clear_conversation_history(cid)
except Exception as e:
logger.warning(
"清空会话 Redis 历史失败 conversation_id=%s err=%s", cid, e
)
try:
await task_tracker.clear_user_tasks(user_id)
except Exception as e:
logger.warning("清空用户任务追踪失败 user_id=%s err=%s", user_id, e)
try:
await redis_service.delete_keys_matching_pattern(
f"lock:chapter:{user_id}:*"
)
for ch_id in chapter_ids:
await redis_service.delete_keys_matching_pattern(
f"lock:chapter-images:{ch_id}"
)
for sid in story_ids:
await redis_service.delete_keys_matching_pattern(
f"lock:story-image:{sid}"
)
except Exception as e:
logger.warning("清理 Redis 锁 key 失败 user_id=%s err=%s", user_id, e)
return PurgeUserDataResponse(
success=True,
message=(
"已清空该账号下的对话、记忆、故事、章节、订单等业务数据,并已尝试删除关联的对象存储文件;"
"所有登录会话已失效,请重新登录"
),
)