初始化

This commit is contained in:
zg
2026-07-15 16:08:17 +08:00
parent f0d70aded4
commit 4e0057ece5
89 changed files with 13512 additions and 0 deletions

159
backend/routes/notes.py Normal file
View File

@@ -0,0 +1,159 @@
"""笔记相关路由"""
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