fix/various fixes
This commit is contained in:
@@ -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=(
|
||||
"已清空该账号下的对话、记忆、故事、章节、订单等业务数据,并已尝试删除关联的对象存储文件;"
|
||||
"所有登录会话已失效,请重新登录"
|
||||
),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user