"""笔记相关路由""" from fastapi import APIRouter, Depends, HTTPException, Request from sqlalchemy.orm import Session from models import get_db, Note from middleware.user_context import UserContext router = APIRouter(tags=["笔记"]) @router.get("/api/notes") def list_notes(folder_id: int = None, db: Session = Depends(get_db), request: Request = None): """获取笔记列表(仅当前用户)""" user_id = UserContext.get_user_id(request) q = db.query(Note).filter(Note.created_by == user_id) if folder_id: q = q.filter(Note.folder_id == folder_id) return q.order_by(Note.updated_at.desc()).all() @router.post("/api/notes") def create_note(data: dict, db: Session = Depends(get_db), request: Request = None): """创建笔记""" user_id = UserContext.get_user_id(request) note = Note( title=data.get("title", "无标题"), content=data.get("content", ""), folder_id=data.get("folder_id"), created_by=user_id, updated_by=user_id, ) db.add(note) db.commit() db.refresh(note) return {"id": note.id, "title": note.title, "content": note.content, "folder_id": note.folder_id, "created_by": note.created_by, "updated_by": note.updated_by, "created_at": str(note.created_at), "updated_at": str(note.updated_at)} @router.get("/api/notes/{note_id}") def get_note(note_id: int, db: Session = Depends(get_db), request: Request = None): """获取单个笔记""" user_id = UserContext.get_user_id(request) note = db.query(Note).filter(Note.id == note_id, Note.created_by == user_id).first() if not note: raise HTTPException(404, "笔记不存在") return {"id": note.id, "title": note.title, "content": note.content, "folder_id": note.folder_id, "created_by": note.created_by, "updated_by": note.updated_by, "created_at": str(note.created_at), "updated_at": str(note.updated_at)} @router.put("/api/notes/{note_id}") def update_note(note_id: int, data: dict, db: Session = Depends(get_db), request: Request = None): """更新笔记""" user_id = UserContext.get_user_id(request) note = db.query(Note).filter(Note.id == note_id, Note.created_by == user_id).first() if not note: raise HTTPException(404, "笔记不存在") if "title" in data: note.title = data["title"] if "content" in data: note.content = data["content"] if "folder_id" in data: note.folder_id = data["folder_id"] note.updated_by = user_id db.commit() db.refresh(note) return {"ok": True} @router.delete("/api/notes/{note_id}") def delete_note(note_id: int, db: Session = Depends(get_db), request: Request = None): """删除笔记""" user_id = UserContext.get_user_id(request) note = db.query(Note).filter(Note.id == note_id, Note.created_by == user_id).first() if not note: raise HTTPException(404, "笔记不存在") db.delete(note) db.commit() return {"ok": True} # ===== 分享 ===== import secrets @router.post("/api/notes/{note_id}/share") def share_note(note_id: int, data: dict = {}, db: Session = Depends(get_db), request: Request = None): """生成/刷新分享链接,可设置有效期""" from datetime import datetime, timedelta user_id = UserContext.get_user_id(request) note = db.query(Note).filter(Note.id == note_id, Note.created_by == user_id).first() if not note: raise HTTPException(404, "笔记不存在") note.share_token = secrets.token_urlsafe(16) # 有效期: 7d / 30d / 1y / forever ttl = data.get("ttl", "forever") if ttl == "7d": note.share_expires_at = datetime.utcnow() + timedelta(days=7) elif ttl == "30d": note.share_expires_at = datetime.utcnow() + timedelta(days=30) elif ttl == "1y": note.share_expires_at = datetime.utcnow() + timedelta(days=365) else: note.share_expires_at = None # 永久 db.commit() return { "share_token": note.share_token, "url": f"/share/{note.share_token}", "expires_at": note.share_expires_at.strftime("%Y-%m-%d %H:%M") if note.share_expires_at else "永久有效", } @router.delete("/api/notes/{note_id}/share") def unshare_note(note_id: int, db: Session = Depends(get_db), request: Request = None): """取消分享""" user_id = UserContext.get_user_id(request) note = db.query(Note).filter(Note.id == note_id, Note.created_by == user_id).first() if not note: raise HTTPException(404, "笔记不存在") note.share_token = None db.commit() return {"ok": True} # ===== 移动 ===== @router.put("/api/notes/{note_id}/move") def move_note(note_id: int, data: dict, db: Session = Depends(get_db), request: Request = None): """移动笔记到另一个文件夹""" user_id = UserContext.get_user_id(request) note = db.query(Note).filter(Note.id == note_id, Note.created_by == user_id).first() if not note: raise HTTPException(404, "笔记不存在") note.folder_id = data.get("folder_id") db.commit() return {"ok": True, "folder_id": note.folder_id} # ===== 分享管理 ===== @router.get("/api/shares") def list_shares(db: Session = Depends(get_db), request: Request = None): """列出当前用户已分享的笔记""" user_id = UserContext.get_user_id(request) notes = db.query(Note).filter( Note.share_token.isnot(None), Note.created_by == user_id, ).order_by(Note.updated_at.desc()).all() result = [] for n in notes: result.append({ "id": n.id, "title": n.title, "share_token": n.share_token, "share_url": f"/share/{n.share_token}", "share_expires_at": n.share_expires_at.strftime("%Y-%m-%d %H:%M") if n.share_expires_at else "永久有效", "created_by": n.created_by, "updated_at": str(n.updated_at), }) return result