user_material_service.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. from backend.modules.database.connection import DatabaseConnection
  2. from backend.modules.database.operations import DatabaseOperations
  3. from backend.modules.database.models import ImageRecord, User
  4. from backend.utils.logger_config import setup_logger
  5. from typing import Optional, List, Dict, Any
  6. import os
  7. import uuid
  8. logger = setup_logger(__name__)
  9. """
  10. 实现用户素材管理服务:用户上传素材,用户管理素材,用户删除素材
  11. """
  12. class UserMaterialService:
  13. def __init__(self):
  14. self.db_ops = DatabaseOperations()
  15. self.upload_dir = os.path.join(os.getcwd(), 'backend', 'data', 'materials')
  16. os.makedirs(self.upload_dir, exist_ok=True)
  17. def upload_material(self, user_id: int, file_bytes: bytes, image_type: str, original_filename: str) -> Dict[str, Any]:
  18. """
  19. 用户上传素材
  20. :param user_id: 用户ID
  21. :param file_bytes: 文件内容(二进制)
  22. :param image_type: 图片类型(face/cloth/result/original)
  23. :param original_filename: 原始文件名
  24. :return: 上传结果
  25. """
  26. logger.info(f"用户{user_id}上传素材: {original_filename}, 类型: {image_type}")
  27. user = self.db_ops.get_user_by_id(user_id)
  28. if not user:
  29. return {"success": False, "error": "用户不存在"}
  30. if not user.get("is_active", False):
  31. return {"success": False, "error": "用户已被禁用"}
  32. # 生成唯一文件名
  33. ext = os.path.splitext(original_filename)[-1]
  34. unique_name = f"{user_id}_{uuid.uuid4().hex}{ext}"
  35. save_path = os.path.join(self.upload_dir, unique_name)
  36. try:
  37. with open(save_path, 'wb') as f:
  38. f.write(file_bytes)
  39. except Exception as e:
  40. logger.error(f"文件保存失败: {e}")
  41. return {"success": False, "error": "文件保存失败"}
  42. # 在数据库中记录素材信息
  43. image_record = self.db_ops.create_image_record(
  44. user_id=user_id,
  45. image_type=image_type,
  46. original_filename=original_filename,
  47. stored_path=save_path
  48. )
  49. if not image_record:
  50. return {"success": False, "error": "数据库记录失败"}
  51. # 生成可访问的URL
  52. file_name = os.path.basename(save_path)
  53. file_url = f"/materials/{file_name}"
  54. return {
  55. "success": True,
  56. "material_id": image_record['id'],
  57. "file_path": save_path,
  58. "file_url": file_url,
  59. "original_filename": original_filename
  60. }
  61. def list_materials(self, user_id: int, material_type: Optional[str] = None, page: int = 1, page_size: int = 20) -> Dict[str, Any]:
  62. """
  63. 获取用户素材列表
  64. :param user_id: 用户ID
  65. :param material_type: 素材类型(可选)
  66. :param page: 页码
  67. :param page_size: 每页数量
  68. :return: 素材列表
  69. """
  70. logger.info(f"获取用户{user_id}的素材列表, 类型: {material_type}, 页码: {page}")
  71. user = self.db_ops.get_user_by_id(user_id)
  72. if not user:
  73. return {"success": False, "error": "用户不存在"}
  74. if not user.get("is_active", False):
  75. return {"success": False, "error": "用户已被禁用"}
  76. result = self.db_ops.get_user_images(user_id, material_type, page, page_size)
  77. # 保持与旧版本兼容的数据格式
  78. return {
  79. "success": True,
  80. "images": result.get("images", []),
  81. "total": result.get("total", 0),
  82. "page": result.get("page", 1),
  83. "page_size": result.get("page_size", 20),
  84. "total_pages": result.get("total_pages", 1)
  85. }
  86. def delete_material(self, user_id: int, material_id: int) -> Dict[str, Any]:
  87. """
  88. 删除用户素材
  89. :param user_id: 用户ID
  90. :param material_id: 素材ID
  91. :return: 删除结果
  92. """
  93. logger.info(f"用户{user_id}请求删除素材{material_id}")
  94. user = self.db_ops.get_user_by_id(user_id)
  95. if not user:
  96. return {"success": False, "error": "用户不存在"}
  97. if not user.get("is_active", False):
  98. return {"success": False, "error": "用户已被禁用"}
  99. image = self.db_ops.get_image_record_by_id(material_id)
  100. if not image:
  101. return {"success": False, "error": "素材不存在"}
  102. if image['user_id'] != user_id:
  103. return {"success": False, "error": "无权删除他人素材"}
  104. # 删除文件
  105. try:
  106. if os.path.exists(image['stored_path']):
  107. os.remove(image['stored_path'])
  108. except Exception as e:
  109. logger.error(f"文件删除失败: {e}")
  110. return {"success": False, "error": "文件删除失败"}
  111. # 删除数据库记录
  112. success = self.db_ops.delete_image_record(material_id)
  113. if not success:
  114. return {"success": False, "error": "数据库删除失败"}
  115. return {"success": True, "message": "素材删除成功"}
  116. def update_material(self, user_id: int, material_id: int, data: dict) -> Dict[str, Any]:
  117. """
  118. 更新用户素材信息
  119. :param user_id: 用户ID
  120. :param material_id: 素材ID
  121. :param data: 更新数据
  122. :return: 更新结果
  123. """
  124. logger.info(f"用户{user_id}请求更新素材{material_id}")
  125. user = self.db_ops.get_user_by_id(user_id)
  126. if not user:
  127. return {"success": False, "error": "用户不存在"}
  128. if not user.get("is_active", False):
  129. return {"success": False, "error": "用户已被禁用"}
  130. image = self.db_ops.get_image_record_by_id(material_id)
  131. if not image:
  132. return {"success": False, "error": "素材不存在"}
  133. if image['user_id'] != user_id:
  134. return {"success": False, "error": "无权更新他人素材"}
  135. # 更新数据库记录
  136. success = self.db_ops.update_image_record(material_id, data)
  137. if not success:
  138. return {"success": False, "error": "数据库更新失败"}
  139. return {"success": True, "message": "素材更新成功"}
  140. user_material_service = UserMaterialService()