ymt-python / routers /product_utils.py
hsailorj's picture
Add application file
551658a
Raw
History Blame Contribute Delete
4.58 kB
from fastapi import HTTPException, status
from sqlalchemy.orm import Session
from models.product import Product
from models.user import User
from utils.r2_uploader import get_r2_uploader, R2Config, get_cached_config, set_cached_config
from models.company_r2_config import CompanyR2Config
from typing import Optional
from dotenv import load_dotenv
from pathlib import Path
import os
# 加载.env文件
BASE_DIR = Path(__file__).parent.parent
load_dotenv(BASE_DIR / ".env")
def get_r2_config_from_env() -> Optional[R2Config]:
"""从.env文件获取R2配置"""
r2_account_id = os.getenv('R2_ACCOUNT_ID', '')
r2_access_key_id = os.getenv('R2_ACCESS_KEY_ID', '')
r2_secret_access_key = os.getenv('R2_SECRET_ACCESS_KEY', '')
r2_bucket_name = os.getenv('R2_BUCKET_NAME', 'yomaton')
r2_public_url = os.getenv('R2_PUBLIC_URL', '')
r2_enabled = os.getenv('R2_ENABLED', 'true').lower() == 'true'
if r2_enabled and r2_account_id and r2_access_key_id and r2_secret_access_key:
return R2Config({
'r2_account_id': r2_account_id,
'r2_access_key_id': r2_access_key_id,
'r2_secret_access_key': r2_secret_access_key,
'r2_bucket_name': r2_bucket_name,
'r2_public_url': r2_public_url,
'r2_enabled': 1 if r2_enabled else 0
})
return None
def validate_product_exists(
product_number: str,
current_user: User,
db: Session
) -> Product:
"""
验证产品是否存在并返回产品对象
Args:
product_number: 产品货号
current_user: 当前用户
db: 数据库会话
Returns:
产品对象
Raises:
HTTPException: 当产品不存在时抛出404错误
"""
from routers.auth import is_admin_user
query = db.query(Product).filter(Product.product_number == product_number)
if not is_admin_user(current_user):
query = query.filter(Product.company_code == current_user.company_code)
product = query.first()
if product is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Product not found"
)
return product
def get_company_r2_config(company_code: str, db: Session) -> Optional[R2Config]:
"""
获取公司的 R2 配置
优先从缓存获取,没有则从数据库获取,最后从.env获取并缓存
Args:
company_code: 公司代码
db: 数据库会话
Returns:
R2配置对象,如果不存在则返回None
"""
cached_config = get_cached_config(company_code)
if cached_config:
return cached_config
# 先从当前公司的数据库配置获取
db_config = db.query(CompanyR2Config).filter(
CompanyR2Config.company_code == company_code
).first()
# 如果没有,尝试从默认公司(0000)获取
if not db_config:
db_config = db.query(CompanyR2Config).filter(
CompanyR2Config.company_code == "0000"
).first()
if db_config and db_config.r2_enabled:
r2_config = R2Config({
'r2_account_id': db_config.r2_account_id,
'r2_access_key_id': db_config.r2_access_key_id,
'r2_secret_access_key': db_config.r2_secret_access_key,
'r2_bucket_name': db_config.r2_bucket_name,
'r2_public_url': db_config.r2_public_url,
'r2_enabled': db_config.r2_enabled
})
set_cached_config(company_code, r2_config)
return r2_config
# 最后从.env获取
env_config = get_r2_config_from_env()
if env_config:
set_cached_config(company_code, env_config)
return env_config
return None
def delete_r2_and_local_files(
r2_key: Optional[str],
thumbnail_r2_key: Optional[str],
file_path: Optional[str],
company_code: str,
db: Session
) -> None:
"""
删除R2文件(不再删除本地文件)
Args:
r2_key: R2文件键
thumbnail_r2_key: R2缩略图文件键
file_path: 本地文件路径(已不再使用)
company_code: 公司代码
db: 数据库会话
"""
r2_config = get_company_r2_config(company_code, db)
if r2_config:
r2_uploader = get_r2_uploader()
if r2_uploader.is_available(r2_config):
if r2_key:
r2_uploader.delete_file(r2_key, r2_config)
if thumbnail_r2_key:
r2_uploader.delete_file(thumbnail_r2_key, r2_config)