-
Notifications
You must be signed in to change notification settings - Fork 2
/
article.rs
116 lines (112 loc) · 3.43 KB
/
article.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use axum::{
extract::{Form, Query},
Extension,
};
use sea_orm::{
ActiveModelTrait,
ActiveValue::{NotSet, Set},
ColumnTrait, Condition, EntityTrait, PaginatorTrait, QueryFilter, QueryOrder, QuerySelect,
};
use std::sync::Arc;
use crate::{
entity::{article, category, tag},
form,
handler::render,
param,
state::AppState,
view, AppError, Result,
};
use super::{get_conn, log_error, redirect, HtmlRespon, RedirectRespon};
pub async fn index(
Extension(state): Extension<Arc<AppState>>,
Query(params): Query<param::ArticleParams>,
) -> Result<HtmlRespon> {
let handler_name = "article/index";
let conn = get_conn(&state);
let condition = Condition::all().add(article::Column::IsDel.eq(false));
let selc = article::Entity::find().filter(condition);
let record_total = selc
.clone()
.count(conn)
.await
.map_err(AppError::from)
.map_err(log_error(handler_name))?;
let page_size = 15usize;
let page = 0usize;
let page_total = f64::ceil(record_total as f64 / page_size as f64) as usize;
let offset = page_size * page;
let list = selc
.find_also_related(category::Entity)
.order_by_desc(article::Column::Id)
.limit(page_size as u64)
.offset(offset as u64)
.all(conn)
.await
.map_err(AppError::from)
.map_err(log_error(handler_name))?;
let tpl = view::ArticlesTemplate {
list,
page_total,
params,
};
render(tpl, handler_name)
}
pub async fn add_ui(Extension(state): Extension<Arc<AppState>>) -> Result<HtmlRespon> {
let handler_name = "article/add_ui";
let conn = get_conn(&state);
let categies = category::Entity::find()
.filter(category::Column::IsDel.eq(false))
.limit(100)
.order_by_asc(category::Column::Id)
.all(conn)
.await
.map_err(AppError::from)
.map_err(log_error(handler_name))?;
let tpl = view::ArticleAddTemplate { categies };
render(tpl, handler_name)
}
pub async fn add(
Extension(state): Extension<Arc<AppState>>,
Form(frm): Form<form::ArticleForm>,
) -> Result<RedirectRespon> {
let handler_name = "article/add";
let conn = get_conn(&state);
article::ActiveModel {
id: NotSet,
title: Set(frm.title),
category_id: Set(frm.category_id),
content: Set(frm.content),
..Default::default()
}
.save(conn)
.await
.map_err(AppError::from)
.map_err(log_error(handler_name))?;
redirect("/article?msg=文章添加成功")
}
pub async fn list_with_tags(Extension(state): Extension<Arc<AppState>>) -> Result<String> {
let handler_name = "article/list_with_tags";
let conn = get_conn(&state);
let list: Vec<(article::Model, Vec<tag::Model>)> = article::Entity::find()
.find_with_related(tag::Entity)
.all(conn)
.await
.map_err(AppError::from)
.map_err(log_error(handler_name))?;
let mut ss = vec![];
for item in list {
let (article, tags) = item;
let tags = tags
.iter()
.map(|tag| format!("【#{} - {}】", &tag.id, &tag.name))
.collect::<Vec<String>>()
.join(", ")
.to_string();
let s = format!(
"文章ID: {}, 文章标题: {}, 标签: {}",
&article.id, &article.title, tags,
);
ss.push(s);
}
Ok(ss.join("\n").to_string())
}