116 lines
3.6 KiB
Rust
116 lines
3.6 KiB
Rust
use sea_orm::{ColumnTrait, Condition, DatabaseConnection, EntityTrait, NotSet, PaginatorTrait};
|
||
use sea_orm::{ActiveModelTrait, QueryFilter, QueryOrder, QuerySelect};
|
||
use sea_orm::ActiveValue::Set;
|
||
|
||
use crate::{APPLICATION_CONTEXT, view};
|
||
use crate::common::err::{AppError, log_error};
|
||
use crate::common::Result;
|
||
use crate::entity::{article, category, tag};
|
||
use crate::form::ArticleForm;
|
||
use crate::param::ArticleParams;
|
||
|
||
pub struct ArticleService;
|
||
|
||
impl ArticleService {
|
||
pub async fn index(handler_name: &str, params: ArticleParams) -> Result<view::ArticlesTemplate> {
|
||
let conn = APPLICATION_CONTEXT.get::<DatabaseConnection>();
|
||
|
||
let condition = Condition::all()
|
||
.add(article::Column::IsDel.eq(false))
|
||
.add_option(
|
||
params.keyword_opt().map(|n| article::Column::Title.contains(&n))
|
||
)
|
||
.add_option(params.is_del_opt().map(|n| article::Column::IsDel.eq(n)));
|
||
|
||
let mut select = article::Entity::find()
|
||
.filter(condition);
|
||
|
||
let page = params.page(); // 当前页码
|
||
let page_size = params.page_size(); // 每页条数,默认15
|
||
|
||
if let Some(ord) = params.order() {
|
||
select = select.order_by(category::Column::Id, ord);
|
||
}
|
||
|
||
let paginator = select
|
||
.find_also_related(category::Entity)
|
||
.paginate(conn, page_size);
|
||
|
||
let page_total = paginator.num_pages().await.map_err(AppError::from)?;
|
||
|
||
let list: Vec<(article::Model, Option<category::Model>)> = paginator
|
||
.fetch_page(page)
|
||
.await
|
||
.map_err(AppError::from)
|
||
.map_err(log_error(handler_name))?;
|
||
|
||
Ok(view::ArticlesTemplate {
|
||
list,
|
||
page_total,
|
||
params,
|
||
})
|
||
}
|
||
|
||
pub async fn add_ui(handler_name: &str) -> Result<view::ArticleAddTemplate> {
|
||
let conn = APPLICATION_CONTEXT.get::<DatabaseConnection>();
|
||
|
||
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))?;
|
||
|
||
Ok(view::ArticleAddTemplate { categies })
|
||
}
|
||
|
||
pub async fn add(handler_name: &str, frm: ArticleForm) -> Result<article::ActiveModel> {
|
||
let conn = APPLICATION_CONTEXT.get::<DatabaseConnection>();
|
||
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))
|
||
}
|
||
pub async fn list_with_tags(handler_name: &str) -> Result<String> {
|
||
let conn = APPLICATION_CONTEXT.get::<DatabaseConnection>();
|
||
|
||
let list = 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())
|
||
}
|
||
}
|
||
|
||
|
||
|