oss.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. """统一附件 sys_oss CRUD"""
  2. from __future__ import annotations
  3. from typing import Optional
  4. from sqlalchemy.orm import Session
  5. from app.core.utils import generate_uuid
  6. from app.models.crm_models import SysOss
  7. def create_oss(
  8. db: Session,
  9. *,
  10. tenant_no: str,
  11. url: str,
  12. original_name: str,
  13. file_suffix: str = "",
  14. file_size: int = 0,
  15. file_type: str = "",
  16. biz_type: str = "",
  17. biz_id: str = "",
  18. attach_type: str = "attachment",
  19. sort_order: int = 0,
  20. user_id: Optional[str] = None,
  21. ext1: Optional[str] = None,
  22. ) -> SysOss:
  23. """写入 sys_oss 附件记录"""
  24. stored_name = url.rsplit("/", 1)[-1] if url else original_name
  25. obj = SysOss(
  26. id=generate_uuid(),
  27. tenant_no=tenant_no,
  28. biz_type=biz_type or None,
  29. biz_id=biz_id or None,
  30. file_name=stored_name or original_name,
  31. original_name=original_name,
  32. file_suffix=file_suffix,
  33. url=url,
  34. file_size=file_size,
  35. file_type=file_type,
  36. attach_type=attach_type,
  37. sort_order=sort_order,
  38. service="minio",
  39. ext1=ext1,
  40. create_by=user_id,
  41. create_dept_id="",
  42. del_flag=0,
  43. )
  44. db.add(obj)
  45. db.commit()
  46. db.refresh(obj)
  47. return obj
  48. def get_oss_by_url(db: Session, tenant_no: str, url: str) -> Optional[SysOss]:
  49. """按 MinIO 相对路径查询附件"""
  50. if not url:
  51. return None
  52. return (
  53. db.query(SysOss)
  54. .filter(SysOss.url == url, SysOss.tenant_no == tenant_no, SysOss.del_flag == 0)
  55. .first()
  56. )
  57. def get_oss_by_id(db: Session, tenant_no: str, oss_id: str) -> Optional[SysOss]:
  58. """按主键 id 查询附件(兼容旧 CRM 雪花 oss_id 迁入后的记录)"""
  59. if not oss_id:
  60. return None
  61. return (
  62. db.query(SysOss)
  63. .filter(SysOss.id == str(oss_id).strip(), SysOss.tenant_no == tenant_no, SysOss.del_flag == 0)
  64. .first()
  65. )
  66. def resolve_storage_path(db: Session, tenant_no: str, file_url_or_id: str) -> tuple[str, Optional[SysOss]]:
  67. """将 fileUrl 或旧 CRM 数字 ossId 解析为 MinIO 相对路径。
  68. 门户新上传把相对路径写入业务字段;迁入合同附件仍存数字 ossId。
  69. """
  70. raw = (file_url_or_id or "").strip()
  71. if not raw:
  72. return "", None
  73. by_url = get_oss_by_url(db, tenant_no, raw)
  74. if by_url:
  75. return (by_url.url or raw), by_url
  76. # 纯数字 / UUID:按 sys_oss.id 查真实 object key
  77. if "/" not in raw and not raw.startswith("http"):
  78. by_id = get_oss_by_id(db, tenant_no, raw)
  79. if by_id and by_id.url:
  80. return by_id.url, by_id
  81. return raw, None