short_url_service.py 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. import string
  2. import random
  3. from sqlalchemy.orm import Session
  4. from app.core.biz_exception import NotFoundError, PermissionDeniedError, BizLogicError
  5. from app.models.short_url import ShortUrl
  6. class ShortUrlService:
  7. @staticmethod
  8. def generate_short_key(length: int = 8) -> str:
  9. """生成随机短 Key(由字母+数字组成)"""
  10. chars = string.ascii_letters + string.digits
  11. return ''.join(random.choices(chars, k=length))
  12. @staticmethod
  13. def create_short_url(db: Session, long_url: str) -> ShortUrl:
  14. """创建短链接"""
  15. # 检查是否已经存在相同的长链接
  16. existing = db.query(ShortUrl).filter(ShortUrl.long_url == long_url).first()
  17. if existing:
  18. raise BizLogicError("Short url already exist")
  19. # 生成唯一 short_key
  20. short_key = ShortUrlService.generate_short_key()
  21. while db.query(ShortUrl).filter(ShortUrl.short_key == short_key).first():
  22. short_key = ShortUrlService.generate_short_key()
  23. db_obj = ShortUrl(short_key=short_key, long_url=long_url)
  24. db.add(db_obj)
  25. db.commit()
  26. db.refresh(db_obj)
  27. return db_obj
  28. @staticmethod
  29. def get_long_url(db: Session, short_key: str) -> str:
  30. """通过短 key 获取原始长链接"""
  31. record = db.query(ShortUrl).filter(ShortUrl.short_key == short_key).first()
  32. if not record:
  33. raise NotFoundError("Short url not found")
  34. return record.long_url