from datetime import datetime, timezone, timedelta from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy import func, select from sqlalchemy.exc import IntegrityError from sqlalchemy.ext.asyncio import AsyncSession from app.dependencies import get_db, get_current_user from app.models.contact_request import ContactRequest from app.models.user import User from app.schemas.contact import ContactRequestCreate, ContactRequestListOut, ContactRequestOut from app.utils.id_gen import generate_id router = APIRouter(prefix="/contact", tags=["contact"]) @router.post("/request", summary="提交联系请求", status_code=status.HTTP_201_CREATED) async def create_contact_request( request: ContactRequestCreate, db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user), ): today_str = datetime.now(timezone.utc).strftime("%Y-%m-%d") async with db.begin_nested(): user_result = await db.execute( select(User).where(User.id == user.id).with_for_update().limit(1) ) locked_user = user_result.scalar_one_or_none() if not locked_user: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="用户不存在") existing = await db.execute( select(ContactRequest.id) .where(ContactRequest.user_id == user.id) .where(ContactRequest.submit_date == today_str) .limit(1) ) if existing.scalar_one_or_none(): raise HTTPException( status_code=status.HTTP_429_TOO_MANY_REQUESTS, detail="每个账号每天只能提交一次联系我们" ) try: contact_request = ContactRequest( id=generate_id(), user_id=user.id, phone=request.phone, company_name=request.company_name, industry=request.industry, name=request.name, message=request.message, submit_date=today_str, ) db.add(contact_request) await db.commit() except IntegrityError: await db.rollback() raise HTTPException( status_code=status.HTTP_429_TOO_MANY_REQUESTS, detail="每个账号每天只能提交一次联系我们" ) return {"message": "提交成功,我们会尽快与您联系"} @router.get("/requests", summary="获取联系请求列表", response_model=ContactRequestListOut) async def get_contact_requests( page: int = 1, page_size: int = 20, is_handled: bool | None = None, db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user), ): if not user.is_admin: raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="无权限") query = select(ContactRequest) count_query = select(func.count(ContactRequest.id)) if is_handled is not None: query = query.where(ContactRequest.is_handled == is_handled) count_query = count_query.where(ContactRequest.is_handled == is_handled) query = query.order_by(ContactRequest.created_at.desc()) offset = (page - 1) * page_size result = await db.execute(query.offset(offset).limit(page_size)) items = result.scalars().all() total = (await db.execute(count_query)).scalar_one() return {"items": items, "total": total} @router.get("/requests/{request_id}", summary="获取联系请求详情", response_model=ContactRequestOut) async def get_contact_request( request_id: str, db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user), ): if not user.is_admin: raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="无权限") result = await db.execute(select(ContactRequest).where(ContactRequest.id == request_id)) contact_request = result.scalar_one_or_none() if not contact_request: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="记录不存在") return contact_request @router.put("/requests/{request_id}/handle", summary="标记为已处理") async def mark_as_handled( request_id: str, db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user), ): if not user.is_admin: raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="无权限") result = await db.execute(select(ContactRequest).where(ContactRequest.id == request_id)) contact_request = result.scalar_one_or_none() if not contact_request: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="记录不存在") contact_request.is_handled = True await db.commit() await db.refresh(contact_request) return {"message": "已标记为处理"} @router.delete("/requests/{request_id}", summary="删除联系请求") async def delete_contact_request( request_id: str, db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user), ): if not user.is_admin: raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="无权限") result = await db.execute(select(ContactRequest).where(ContactRequest.id == request_id)) contact_request = result.scalar_one_or_none() if not contact_request: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="记录不存在") await db.delete(contact_request) await db.commit() return {"message": "删除成功"}