Skip to main content

yggdrasil/api/notes/
mod.rs

1//! 笔记的浏览器入口。认证适配后,统一调用 store 的版本与发布规则。
2#![allow(clippy::unused_unit, deprecated)]
3use crate::models::note::*;
4use dioxus::prelude::*;
5#[cfg(feature = "server")]
6pub mod attachments;
7#[cfg(feature = "server")]
8pub mod store;
9
10#[server(ListNotes, "/api")]
11pub async fn list_notes(filter: NoteFilter) -> Result<NotePage, ServerFnError> {
12    Ok(store::list(store::Access::Public, filter).await?)
13}
14
15#[server(GetNote, "/api")]
16pub async fn get_note(slug: String) -> Result<Note, ServerFnError> {
17    Ok(store::get(store::Access::Public, None, Some(slug), None).await?)
18}
19
20#[server(ListNotebooks, "/api")]
21pub async fn list_notebooks() -> Result<Vec<Notebook>, ServerFnError> {
22    Ok(store::notebooks(store::Access::Public).await?)
23}
24
25#[server(ListOwnedNotes, "/api")]
26pub async fn list_owned_notes(filter: NoteFilter) -> Result<NotePage, ServerFnError> {
27    let user = crate::api::auth::get_current_admin_user().await?;
28    Ok(store::list(store::Access::Owner(user.id), filter).await?)
29}
30
31#[server(GetOwnedNote, "/api")]
32pub async fn get_owned_note(id: i32, version: Option<i32>) -> Result<Note, ServerFnError> {
33    let user = crate::api::auth::get_current_admin_user().await?;
34    Ok(store::get(store::Access::Owner(user.id), Some(id), None, version).await?)
35}
36
37#[server(SaveNote, "/api")]
38pub async fn save_note(draft: NoteDraft) -> Result<Note, ServerFnError> {
39    let user = crate::api::auth::get_current_admin_user().await?;
40    Ok(store::save(user.id, draft, None).await?)
41}
42
43#[server(ActOnNote, "/api")]
44pub async fn act_on_note(
45    id: i32,
46    expected_version: i32,
47    action: NoteAction,
48) -> Result<Note, ServerFnError> {
49    let user = crate::api::auth::get_current_admin_user().await?;
50    Ok(store::act(user.id, id, expected_version, action).await?)
51}
52
53#[server(NoteHistory, "/api")]
54pub async fn note_history(id: i32) -> Result<Vec<NoteRevision>, ServerFnError> {
55    let user = crate::api::auth::get_current_admin_user().await?;
56    Ok(store::history(user.id, id).await?)
57}
58
59#[server(OwnedNotebooks, "/api")]
60pub async fn owned_notebooks() -> Result<Vec<Notebook>, ServerFnError> {
61    let user = crate::api::auth::get_current_admin_user().await?;
62    Ok(store::notebooks(store::Access::Owner(user.id)).await?)
63}
64
65#[server(SaveNotebook, "/api")]
66pub async fn save_notebook(input: NotebookInput) -> Result<(), ServerFnError> {
67    let user = crate::api::auth::get_current_admin_user().await?;
68    Ok(store::save_notebook(user.id, input).await?)
69}
70
71#[server(ReorderNotebook, "/api")]
72pub async fn reorder_notebook(id: i32, note_ids: Vec<i32>) -> Result<(), ServerFnError> {
73    let user = crate::api::auth::get_current_admin_user().await?;
74    Ok(store::reorder(user.id, id, note_ids).await?)
75}
76
77#[server(ArchiveNotebook, "/api")]
78pub async fn archive_notebook(id: i32, archived: bool) -> Result<(), ServerFnError> {
79    let user = crate::api::auth::get_current_admin_user().await?;
80    Ok(store::archive_notebook(user.id, id, archived).await?)
81}
82
83#[server(NotebookOrder, "/api")]
84pub async fn notebook_order(id: i32) -> Result<Vec<(i32, String)>, ServerFnError> {
85    let user = crate::api::auth::get_current_admin_user().await?;
86    let client = crate::db::pool::get_conn()
87        .await
88        .map_err(crate::api::error::AppError::db_conn)?;
89    let rows=client.query("SELECT n.id, CASE WHEN r.title='' THEN r.summary ELSE r.title END FROM notebook_notes bn
90        JOIN notebooks b ON b.id=bn.notebook_id JOIN notes n ON n.id=bn.note_id
91        JOIN note_revisions r ON r.note_id=n.id AND r.version=n.version
92        WHERE b.id=$1 AND b.owner_id=$2 ORDER BY bn.position,n.id", &[&id,&user.id]).await.map_err(crate::api::error::AppError::query)?;
93    Ok(rows.iter().map(|r| (r.get(0), r.get(1))).collect())
94}