axum-with-seaorm/src/service/article.rs

116 lines
3.6 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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())
}
}