Initial commit: Audio Dashboard Management System
Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
from routes.brands import router as brands_router
|
||||
from routes.models import router as models_router
|
||||
|
||||
__all__ = ["brands_router", "models_router"]
|
||||
@@ -0,0 +1,106 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import List, Optional
|
||||
from database import get_db
|
||||
from models.brand import Brand
|
||||
from schemas import BrandCreate, BrandUpdate, BrandResponse
|
||||
from response import ApiResponse, PageData
|
||||
|
||||
router = APIRouter(prefix="/api/brands", tags=["brands"])
|
||||
|
||||
|
||||
@router.get("/", response_model=ApiResponse)
|
||||
def get_brands(
|
||||
skip: int = Query(0, ge=0, description="跳过记录数"),
|
||||
limit: int = Query(100, ge=1, le=1000, description="返回记录数"),
|
||||
name: Optional[str] = Query(None, description="品牌名称(支持模糊查询)"),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""获取所有品牌列表(支持按名称模糊查询)"""
|
||||
try:
|
||||
query = db.query(Brand)
|
||||
if name:
|
||||
query = query.filter(Brand.name.like(f"%{name}%"))
|
||||
|
||||
total = query.count()
|
||||
brands = query.offset(skip).limit(limit).all()
|
||||
|
||||
if not brands:
|
||||
return ApiResponse(code=2, msg="empty", data=None)
|
||||
|
||||
# 转换为字典列表
|
||||
brands_data = [brand.to_dict() for brand in brands]
|
||||
|
||||
return ApiResponse(code=1, msg="success", data={"items": brands_data, "total": total, "skip": skip, "limit": limit})
|
||||
except Exception as e:
|
||||
return ApiResponse(code=0, msg="error", data=None)
|
||||
|
||||
|
||||
@router.get("/{brand_id}", response_model=ApiResponse)
|
||||
def get_brand(brand_id: int, db: Session = Depends(get_db)):
|
||||
"""获取单个品牌"""
|
||||
try:
|
||||
brand = db.query(Brand).filter(Brand.id == brand_id).first()
|
||||
if not brand:
|
||||
return ApiResponse(code=2, msg="empty", data=None)
|
||||
return ApiResponse(code=1, msg="success", data=brand.to_dict())
|
||||
except Exception as e:
|
||||
return ApiResponse(code=0, msg="error", data=None)
|
||||
|
||||
|
||||
@router.post("/", response_model=ApiResponse)
|
||||
def create_brand(brand: BrandCreate, db: Session = Depends(get_db)):
|
||||
"""创建新品牌"""
|
||||
try:
|
||||
# 检查是否已存在
|
||||
existing = db.query(Brand).filter(Brand.name == brand.name).first()
|
||||
if existing:
|
||||
return ApiResponse.error(msg="品牌名称已存在", code=0)
|
||||
|
||||
db_brand = Brand(name=brand.name)
|
||||
db.add(db_brand)
|
||||
db.commit()
|
||||
db.refresh(db_brand)
|
||||
return ApiResponse.success(data=db_brand.to_dict(), msg="品牌创建成功")
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
return ApiResponse.error(msg=f"创建失败:{str(e)}", code=0)
|
||||
|
||||
|
||||
@router.put("/{brand_id}", response_model=ApiResponse)
|
||||
def update_brand(brand_id: int, brand: BrandUpdate, db: Session = Depends(get_db)):
|
||||
"""更新品牌"""
|
||||
try:
|
||||
db_brand = db.query(Brand).filter(Brand.id == brand_id).first()
|
||||
if not db_brand:
|
||||
return ApiResponse.no_data(msg="品牌不存在")
|
||||
|
||||
# 如果更新名称,检查是否冲突
|
||||
if brand.name and brand.name != db_brand.name:
|
||||
existing = db.query(Brand).filter(Brand.name == brand.name).first()
|
||||
if existing:
|
||||
return ApiResponse.error(msg="品牌名称已存在", code=0)
|
||||
db_brand.name = brand.name
|
||||
|
||||
db.commit()
|
||||
db.refresh(db_brand)
|
||||
return ApiResponse.success(data=db_brand.to_dict(), msg="品牌更新成功")
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
return ApiResponse.error(msg=f"更新失败:{str(e)}", code=0)
|
||||
|
||||
|
||||
@router.delete("/{brand_id}", response_model=ApiResponse)
|
||||
def delete_brand(brand_id: int, db: Session = Depends(get_db)):
|
||||
"""删除品牌"""
|
||||
try:
|
||||
db_brand = db.query(Brand).filter(Brand.id == brand_id).first()
|
||||
if not db_brand:
|
||||
return ApiResponse.no_data(msg="品牌不存在")
|
||||
|
||||
db.delete(db_brand)
|
||||
db.commit()
|
||||
return ApiResponse.success(msg="删除成功")
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
return ApiResponse.error(msg=f"删除失败:{str(e)}", code=0)
|
||||
@@ -0,0 +1,214 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query, Body
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import List, Optional
|
||||
from database import get_db
|
||||
from models.model import Model
|
||||
from schemas import ModelCreate, ModelUpdate, ModelResponse
|
||||
from response import ApiResponse, PageData
|
||||
import requests
|
||||
import os
|
||||
|
||||
router = APIRouter(prefix="/api/models", tags=["models"])
|
||||
|
||||
# Meilisearch 配置(从环境变量读取)
|
||||
MEILISEARCH_URL = os.getenv("MEILISEARCH_URL", "http://localhost:7700")
|
||||
MEILISEARCH_API_KEY = os.getenv("MEILISEARCH_API_KEY", "")
|
||||
MEILISEARCH_INDEX = os.getenv("MEILISEARCH_INDEX", "models")
|
||||
|
||||
|
||||
@router.get("/", response_model=ApiResponse)
|
||||
def get_models(
|
||||
skip: int = Query(0, ge=0, description="跳过记录数"),
|
||||
limit: int = Query(100, ge=1, le=1000, description="返回记录数"),
|
||||
brand_name: Optional[str] = Query(None, description="按品牌名称模糊查询"),
|
||||
name: Optional[str] = Query(None, description="按型号名称模糊查询"),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""获取所有型号列表(支持按品牌名称和型号名称模糊查询)"""
|
||||
try:
|
||||
query = db.query(Model)
|
||||
if brand_name:
|
||||
query = query.filter(Model.brand_name.like(f"%{brand_name}%"))
|
||||
if name:
|
||||
query = query.filter(Model.name.like(f"%{name}%"))
|
||||
|
||||
total = query.count()
|
||||
models = query.offset(skip).limit(limit).all()
|
||||
|
||||
if not models:
|
||||
return ApiResponse(code=2, msg="empty", data=None)
|
||||
|
||||
# 转换为字典列表
|
||||
models_data = [model.to_dict() for model in models]
|
||||
|
||||
return ApiResponse(code=1, msg="success", data={"items": models_data, "total": total, "skip": skip, "limit": limit})
|
||||
except Exception as e:
|
||||
return ApiResponse(code=0, msg="error", data=None)
|
||||
|
||||
|
||||
@router.get("/{model_id}", response_model=ApiResponse)
|
||||
def get_model(model_id: int, db: Session = Depends(get_db)):
|
||||
"""获取单个型号"""
|
||||
try:
|
||||
model = db.query(Model).filter(Model.id == model_id).first()
|
||||
if not model:
|
||||
return ApiResponse(code=2, msg="empty", data=None)
|
||||
return ApiResponse(code=1, msg="success", data=model.to_dict())
|
||||
except Exception as e:
|
||||
return ApiResponse(code=0, msg="error", data=None)
|
||||
|
||||
|
||||
@router.post("/", response_model=ApiResponse)
|
||||
def create_model(model: ModelCreate, db: Session = Depends(get_db)):
|
||||
"""创建新型号"""
|
||||
try:
|
||||
# 检查是否已存在
|
||||
existing = db.query(Model).filter(
|
||||
Model.brand_name == model.brand_name,
|
||||
Model.name == model.name
|
||||
).first()
|
||||
if existing:
|
||||
return ApiResponse(code=0, msg="该品牌下型号名称已存在", data=None)
|
||||
|
||||
db_model = Model(
|
||||
brand_name=model.brand_name,
|
||||
name=model.name,
|
||||
form=model.form,
|
||||
rig=model.rig,
|
||||
source=model.source,
|
||||
eq_key=model.eq_key
|
||||
)
|
||||
db.add(db_model)
|
||||
db.commit()
|
||||
db.refresh(db_model)
|
||||
return ApiResponse(code=1, msg="success", data=db_model.to_dict())
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
return ApiResponse(code=0, msg="error", data=None)
|
||||
|
||||
|
||||
@router.put("/{model_id}", response_model=ApiResponse)
|
||||
def update_model(model_id: int, model: ModelUpdate, db: Session = Depends(get_db)):
|
||||
"""更新型号"""
|
||||
try:
|
||||
db_model = db.query(Model).filter(Model.id == model_id).first()
|
||||
if not db_model:
|
||||
return ApiResponse(code=2, msg="empty", data=None)
|
||||
|
||||
# 如果更新品牌或型号名称,检查是否冲突
|
||||
if model.brand_name or model.name:
|
||||
new_brand_name = model.brand_name or db_model.brand_name
|
||||
new_name = model.name or db_model.name
|
||||
|
||||
if new_brand_name != db_model.brand_name or new_name != db_model.name:
|
||||
existing = db.query(Model).filter(
|
||||
Model.brand_name == new_brand_name,
|
||||
Model.name == new_name
|
||||
).first()
|
||||
if existing:
|
||||
return ApiResponse(code=0, msg="该品牌下型号名称已存在", data=None)
|
||||
|
||||
# 更新字段
|
||||
if model.brand_name:
|
||||
db_model.brand_name = model.brand_name
|
||||
if model.name:
|
||||
db_model.name = model.name
|
||||
if model.form is not None:
|
||||
db_model.form = model.form
|
||||
if model.rig is not None:
|
||||
db_model.rig = model.rig
|
||||
if model.source is not None:
|
||||
db_model.source = model.source
|
||||
if model.eq_key is not None:
|
||||
db_model.eq_key = model.eq_key
|
||||
|
||||
db.commit()
|
||||
db.refresh(db_model)
|
||||
return ApiResponse(code=1, msg="success", data=db_model.to_dict())
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
return ApiResponse(code=0, msg="error", data=None)
|
||||
|
||||
|
||||
@router.delete("/{model_id}", response_model=ApiResponse)
|
||||
def delete_model(model_id: int, db: Session = Depends(get_db)):
|
||||
"""删除型号"""
|
||||
try:
|
||||
db_model = db.query(Model).filter(Model.id == model_id).first()
|
||||
if not db_model:
|
||||
return ApiResponse(code=2, msg="empty", data=None)
|
||||
|
||||
db.delete(db_model)
|
||||
db.commit()
|
||||
return ApiResponse(code=1, msg="success", data=None)
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
return ApiResponse(code=0, msg="error", data=None)
|
||||
|
||||
|
||||
@router.post("/push-to-search", response_model=ApiResponse)
|
||||
def push_to_search(
|
||||
model_ids: List[int] = Body(..., embed=True, description="型号 ID 列表"),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""推送型号数据到 Meilisearch"""
|
||||
try:
|
||||
if not model_ids:
|
||||
return ApiResponse(code=0, msg="请选择要推送的型号", data=None)
|
||||
|
||||
# 查询选中的型号
|
||||
models = db.query(Model).filter(Model.id.in_(model_ids)).all()
|
||||
|
||||
if not models:
|
||||
return ApiResponse(code=0, msg="未找到选中的型号数据", data=None)
|
||||
|
||||
# 准备推送数据
|
||||
push_data = []
|
||||
for model in models:
|
||||
model_dict = {
|
||||
'id': model.id,
|
||||
'brand_name': model.brand_name,
|
||||
'name': model.name,
|
||||
'rig': model.rig,
|
||||
'form': model.form,
|
||||
'source': model.source
|
||||
}
|
||||
# 只包含有值的字段
|
||||
push_data.append({k: v for k, v in model_dict.items() if v is not None})
|
||||
|
||||
# 推送到 Meilisearch
|
||||
headers = {
|
||||
"Authorization": f"Bearer {MEILISEARCH_API_KEY}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
# 如果索引不存在,先创建索引
|
||||
try:
|
||||
# 更新或添加文档
|
||||
response = requests.post(
|
||||
f"{MEILISEARCH_URL}/indexes/{MEILISEARCH_INDEX}/documents",
|
||||
json=push_data,
|
||||
headers=headers,
|
||||
timeout=30
|
||||
)
|
||||
|
||||
if response.status_code not in [200, 202]:
|
||||
return ApiResponse(code=0, msg=f"推送到 Meilisearch 失败:{response.text}", data=None)
|
||||
|
||||
task_info = response.json()
|
||||
|
||||
return ApiResponse(
|
||||
code=1,
|
||||
msg="success",
|
||||
data={
|
||||
"pushed_count": len(push_data),
|
||||
"task_uid": task_info.get("taskUid"),
|
||||
"models": push_data
|
||||
}
|
||||
)
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
return ApiResponse(code=0, msg=f"连接 Meilisearch 失败:{str(e)}", data=None)
|
||||
|
||||
except Exception as e:
|
||||
return ApiResponse(code=0, msg="error", data=None)
|
||||
Reference in New Issue
Block a user