update
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
import sqlite3
|
||||
from typing import List
|
||||
|
||||
from fastapi import APIRouter, HTTPException, status
|
||||
|
||||
from app.database import Database
|
||||
from app.schemas import AdSlot, AdSlotCreate, AdSlotUpdate
|
||||
from app.temple_scope import TempleId, ensure_temple_exists
|
||||
|
||||
|
||||
router = APIRouter(prefix="/ad-slots", tags=["ad-slots"])
|
||||
|
||||
AD_SLOT_COLUMNS = "id, temple_id, name, code, description, sort_order, is_active"
|
||||
|
||||
|
||||
def row_to_ad_slot(row: sqlite3.Row) -> AdSlot:
|
||||
return AdSlot(
|
||||
id=row["id"],
|
||||
temple_id=row["temple_id"],
|
||||
name=row["name"],
|
||||
code=row["code"],
|
||||
description=row["description"],
|
||||
sort_order=row["sort_order"],
|
||||
is_active=bool(row["is_active"]),
|
||||
)
|
||||
|
||||
|
||||
def raise_duplicate_code_error() -> None:
|
||||
raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="广告位编码已存在")
|
||||
|
||||
|
||||
@router.get("", response_model=List[AdSlot])
|
||||
def list_ad_slots(db: Database, temple_id: TempleId) -> List[AdSlot]:
|
||||
ensure_temple_exists(db, temple_id)
|
||||
rows = db.execute(
|
||||
f"""
|
||||
SELECT {AD_SLOT_COLUMNS}
|
||||
FROM ad_slots
|
||||
WHERE temple_id = ?
|
||||
ORDER BY sort_order, id
|
||||
""",
|
||||
(temple_id,),
|
||||
).fetchall()
|
||||
return [row_to_ad_slot(row) for row in rows]
|
||||
|
||||
|
||||
@router.post("", response_model=AdSlot, status_code=status.HTTP_201_CREATED)
|
||||
def create_ad_slot(payload: AdSlotCreate, db: Database, temple_id: TempleId) -> AdSlot:
|
||||
ensure_temple_exists(db, temple_id)
|
||||
try:
|
||||
cursor = db.execute(
|
||||
"""
|
||||
INSERT INTO ad_slots
|
||||
(temple_id, name, code, description, title, image_url, sort_order, is_active)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
""",
|
||||
(
|
||||
temple_id,
|
||||
payload.name,
|
||||
payload.code,
|
||||
payload.description,
|
||||
payload.name,
|
||||
"",
|
||||
payload.sort_order,
|
||||
int(payload.is_active),
|
||||
),
|
||||
)
|
||||
db.commit()
|
||||
except sqlite3.IntegrityError:
|
||||
raise_duplicate_code_error()
|
||||
|
||||
return get_ad_slot(cursor.lastrowid, db, temple_id)
|
||||
|
||||
|
||||
@router.get("/{ad_slot_id}", response_model=AdSlot)
|
||||
def get_ad_slot(ad_slot_id: int, db: Database, temple_id: TempleId) -> AdSlot:
|
||||
ensure_temple_exists(db, temple_id)
|
||||
row = db.execute(
|
||||
f"""
|
||||
SELECT {AD_SLOT_COLUMNS}
|
||||
FROM ad_slots
|
||||
WHERE id = ? AND temple_id = ?
|
||||
""",
|
||||
(ad_slot_id, temple_id),
|
||||
).fetchone()
|
||||
if row is None:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Ad slot not found")
|
||||
return row_to_ad_slot(row)
|
||||
|
||||
|
||||
@router.patch("/{ad_slot_id}", response_model=AdSlot)
|
||||
def update_ad_slot(ad_slot_id: int, payload: AdSlotUpdate, db: Database, temple_id: TempleId) -> AdSlot:
|
||||
ad_slot = get_ad_slot(ad_slot_id, db, temple_id)
|
||||
updates = payload.model_dump(exclude_unset=True)
|
||||
if not updates:
|
||||
return ad_slot
|
||||
|
||||
name = updates.get("name", ad_slot.name)
|
||||
try:
|
||||
db.execute(
|
||||
"""
|
||||
UPDATE ad_slots
|
||||
SET name = ?, code = ?, description = ?, title = ?, sort_order = ?, is_active = ?
|
||||
WHERE id = ? AND temple_id = ?
|
||||
""",
|
||||
(
|
||||
name,
|
||||
updates.get("code", ad_slot.code),
|
||||
updates.get("description", ad_slot.description),
|
||||
name,
|
||||
updates.get("sort_order", ad_slot.sort_order),
|
||||
int(updates.get("is_active", ad_slot.is_active)),
|
||||
ad_slot_id,
|
||||
temple_id,
|
||||
),
|
||||
)
|
||||
db.commit()
|
||||
except sqlite3.IntegrityError:
|
||||
raise_duplicate_code_error()
|
||||
|
||||
return get_ad_slot(ad_slot_id, db, temple_id)
|
||||
|
||||
|
||||
@router.delete("/{ad_slot_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
def delete_ad_slot(ad_slot_id: int, db: Database, temple_id: TempleId) -> None:
|
||||
ensure_temple_exists(db, temple_id)
|
||||
used = db.execute(
|
||||
"SELECT 1 FROM ads WHERE slot_id = ? AND temple_id = ? LIMIT 1",
|
||||
(ad_slot_id, temple_id),
|
||||
).fetchone()
|
||||
if used is not None:
|
||||
raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="广告位已绑定广告,不能删除")
|
||||
|
||||
cursor = db.execute(
|
||||
"DELETE FROM ad_slots WHERE id = ? AND temple_id = ?",
|
||||
(ad_slot_id, temple_id),
|
||||
)
|
||||
db.commit()
|
||||
if cursor.rowcount == 0:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Ad slot not found")
|
||||
Reference in New Issue
Block a user