提取service
This commit is contained in:
parent
d40998f917
commit
246c17ba39
|
@ -1,26 +1,13 @@
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use askama::Template;
|
use askama::Template;
|
||||||
use axum::extract::{Path, Query, State};
|
use axum::extract::{Path, Query, State};
|
||||||
use axum::Form;
|
use axum::Form;
|
||||||
use axum::http::{header, HeaderMap, StatusCode};
|
use axum::http::{HeaderMap, StatusCode};
|
||||||
use axum::response::Html;
|
use axum::response::Html;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::{db::member, err::Error, form, model, model::state::AppState, Result, view};
|
use crate::{err::Error, form, model::state::AppState, Result, view};
|
||||||
|
use crate::service::MemberService;
|
||||||
fn get_conn(state: &AppState) -> Arc<sqlx::MySqlPool> {
|
use crate::util::redirect;
|
||||||
state.pool.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn redirect(url: &str) -> Result<(StatusCode, HeaderMap, ())> {
|
|
||||||
let mut header = HeaderMap::new();
|
|
||||||
header.insert(header::LOCATION, url.parse().unwrap());
|
|
||||||
|
|
||||||
Ok((StatusCode::FOUND, header, ()))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct PageQuery {
|
pub struct PageQuery {
|
||||||
|
@ -33,11 +20,7 @@ pub async fn index(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
Query(q): Query<PageQuery>,
|
Query(q): Query<PageQuery>,
|
||||||
) -> Result<Html<String>> {
|
) -> Result<Html<String>> {
|
||||||
let conn = get_conn(&state);
|
let tpl = MemberService::index(&state, q).await?;
|
||||||
|
|
||||||
let p = member::list(&conn, q.page.unwrap_or(0)).await?;
|
|
||||||
|
|
||||||
let tpl = view::Home { p, msg: q.msg };
|
|
||||||
let html = tpl.render().map_err(Error::from)?;
|
let html = tpl.render().map_err(Error::from)?;
|
||||||
Ok(Html(html))
|
Ok(Html(html))
|
||||||
}
|
}
|
||||||
|
@ -46,18 +29,9 @@ pub async fn detail(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
Path(id): Path<u32>,
|
Path(id): Path<u32>,
|
||||||
) -> Result<Html<String>> {
|
) -> Result<Html<String>> {
|
||||||
let conn = get_conn(&state);
|
let tpl = MemberService::detail(&state, id).await?;
|
||||||
|
let html = tpl.render().map_err(Error::from)?;
|
||||||
let m = member::find(&conn, id).await?;
|
Ok(Html(html))
|
||||||
|
|
||||||
match m {
|
|
||||||
None => Err(Error::not_found("不存在的会员")),
|
|
||||||
Some(m) => {
|
|
||||||
let tpl = view::Detail { m };
|
|
||||||
let html = tpl.render().map_err(Error::from)?;
|
|
||||||
Ok(Html(html))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,16 +46,7 @@ pub async fn add(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
Form(frm): Form<form::AddAndEdit>,
|
Form(frm): Form<form::AddAndEdit>,
|
||||||
) -> Result<(StatusCode, HeaderMap, ())> {
|
) -> Result<(StatusCode, HeaderMap, ())> {
|
||||||
let conn = get_conn(&state);
|
MemberService::add(&state, frm).await?;
|
||||||
|
|
||||||
member::add(&conn, &model::member::Member {
|
|
||||||
name: frm.name,
|
|
||||||
balance: frm.balance,
|
|
||||||
types: frm.types,
|
|
||||||
dateline: chrono::Local::now(),
|
|
||||||
..Default::default()
|
|
||||||
}).await?;
|
|
||||||
|
|
||||||
redirect("/?msg=会员添加成功")
|
redirect("/?msg=会员添加成功")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,18 +55,9 @@ pub async fn edit_ui(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
Path(id): Path<u32>,
|
Path(id): Path<u32>,
|
||||||
) -> Result<Html<String>> {
|
) -> Result<Html<String>> {
|
||||||
let conn = get_conn(&state);
|
let tpl = MemberService::edit_ui(&state, id).await?;
|
||||||
|
let html = tpl.render().map_err(Error::from)?;
|
||||||
let m = member::find(&conn, id).await?;
|
Ok(Html(html))
|
||||||
|
|
||||||
match m {
|
|
||||||
Some(m) => {
|
|
||||||
let tpl = view::Edit { m };
|
|
||||||
let html = tpl.render().map_err(Error::from)?;
|
|
||||||
Ok(Html(html))
|
|
||||||
}
|
|
||||||
None => Err(Error::not_found("不存在的会员")),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -110,16 +66,7 @@ pub async fn edit(
|
||||||
Path(id): Path<u32>,
|
Path(id): Path<u32>,
|
||||||
Form(frm): Form<form::AddAndEdit>,
|
Form(frm): Form<form::AddAndEdit>,
|
||||||
) -> Result<(StatusCode, HeaderMap, ())> {
|
) -> Result<(StatusCode, HeaderMap, ())> {
|
||||||
let conn = get_conn(&state);
|
MemberService::edit(&state, id, frm).await?;
|
||||||
|
|
||||||
member::edit(&conn, &model::member::Member {
|
|
||||||
id,
|
|
||||||
name: frm.name,
|
|
||||||
balance: frm.balance,
|
|
||||||
types: frm.types,
|
|
||||||
..Default::default()
|
|
||||||
}).await?;
|
|
||||||
|
|
||||||
redirect("/?msg=会员修改成功")
|
redirect("/?msg=会员修改成功")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,10 +74,7 @@ pub async fn del(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
Path(id): Path<u32>,
|
Path(id): Path<u32>,
|
||||||
) -> Result<(StatusCode, HeaderMap, ())> {
|
) -> Result<(StatusCode, HeaderMap, ())> {
|
||||||
let conn = get_conn(&state);
|
MemberService::del(&state, id).await?;
|
||||||
|
|
||||||
member::del(&conn, id).await?;
|
|
||||||
|
|
||||||
redirect("/?msg=逻辑删除成功")
|
redirect("/?msg=逻辑删除成功")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,10 +82,7 @@ pub async fn real_del(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
Path(id): Path<u32>,
|
Path(id): Path<u32>,
|
||||||
) -> Result<(StatusCode, HeaderMap, ())> {
|
) -> Result<(StatusCode, HeaderMap, ())> {
|
||||||
let conn = get_conn(&state);
|
MemberService::real_del(&state, id).await?;
|
||||||
|
|
||||||
member::real_del(&conn, id).await?;
|
|
||||||
|
|
||||||
redirect("/?msg=物理删除成功")
|
redirect("/?msg=物理删除成功")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,15 +98,7 @@ pub async fn tran(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
Form(frm): Form<form::Tran>,
|
Form(frm): Form<form::Tran>,
|
||||||
) -> Result<(StatusCode, HeaderMap, ())> {
|
) -> Result<(StatusCode, HeaderMap, ())> {
|
||||||
let conn = get_conn(&state);
|
let aff = MemberService::tran(&state, frm).await?;
|
||||||
|
|
||||||
let aff = member::tran(&conn, &model::member::Tran {
|
|
||||||
from_member: frm.from_member,
|
|
||||||
to_member: frm.to_member,
|
|
||||||
amount: frm.amount,
|
|
||||||
}).await?;
|
|
||||||
|
|
||||||
tracing::debug!("{:?}", aff);
|
tracing::debug!("{:?}", aff);
|
||||||
|
|
||||||
redirect("/?msg=转账成功")
|
redirect("/?msg=转账成功")
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,5 +6,6 @@ pub mod model;
|
||||||
pub mod view;
|
pub mod view;
|
||||||
pub mod form;
|
pub mod form;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
|
pub mod service;
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, crate::err::Error>;
|
pub type Result<T> = std::result::Result<T, crate::err::Error>;
|
|
@ -0,0 +1,83 @@
|
||||||
|
use crate::{form, model, view, util, Result};
|
||||||
|
use crate::db::member;
|
||||||
|
use crate::err::Error;
|
||||||
|
use crate::handler::PageQuery;
|
||||||
|
use crate::model::state::AppState;
|
||||||
|
|
||||||
|
pub struct MemberService;
|
||||||
|
|
||||||
|
impl MemberService {
|
||||||
|
pub async fn index(state: &AppState, q: PageQuery) -> Result<view::Home> {
|
||||||
|
let conn = util::get_conn(&state);
|
||||||
|
|
||||||
|
let p = member::list(&conn, q.page.unwrap_or(0)).await?;
|
||||||
|
|
||||||
|
return Ok(view::Home { p, msg: q.msg });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn detail(state: &AppState, id: u32) -> Result<view::Detail> {
|
||||||
|
let conn = util::get_conn(&state);
|
||||||
|
|
||||||
|
let m = member::find(&conn, id).await?;
|
||||||
|
|
||||||
|
match m {
|
||||||
|
None => Err(Error::not_found("不存在的会员")),
|
||||||
|
Some(m) => Ok(view::Detail { m })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn add(state: &AppState, frm: form::AddAndEdit) -> Result<u32> {
|
||||||
|
let conn = util::get_conn(&state);
|
||||||
|
|
||||||
|
member::add(&conn, &model::member::Member {
|
||||||
|
name: frm.name,
|
||||||
|
balance: frm.balance,
|
||||||
|
types: frm.types,
|
||||||
|
dateline: chrono::Local::now(),
|
||||||
|
..Default::default()
|
||||||
|
}).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn edit(state: &AppState, id: u32, frm: form::AddAndEdit) -> Result<u64> {
|
||||||
|
let conn = util::get_conn(&state);
|
||||||
|
|
||||||
|
member::edit(&conn, &model::member::Member {
|
||||||
|
id,
|
||||||
|
name: frm.name,
|
||||||
|
balance: frm.balance,
|
||||||
|
types: frm.types,
|
||||||
|
..Default::default()
|
||||||
|
}).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn edit_ui(state: &AppState, id: u32) -> Result<view::Edit> {
|
||||||
|
let conn = util::get_conn(&state);
|
||||||
|
let m = member::find(&conn, id).await?;
|
||||||
|
|
||||||
|
match m {
|
||||||
|
None => Err(Error::not_found("不存在的会员")),
|
||||||
|
Some(m) => Ok(view::Edit { m })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub async fn del(state: &AppState, id: u32) -> Result<u64> {
|
||||||
|
let conn = util::get_conn(&state);
|
||||||
|
member::del(&conn, id).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn real_del(state: &AppState, id: u32) -> Result<u64> {
|
||||||
|
let conn = util::get_conn(&state);
|
||||||
|
member::real_del(&conn, id).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn tran(state: &AppState, frm: form::Tran) -> Result<(u64, u64)> {
|
||||||
|
let conn = util::get_conn(&state);
|
||||||
|
|
||||||
|
member::tran(&conn, &model::member::Tran {
|
||||||
|
from_member: frm.from_member,
|
||||||
|
to_member: frm.to_member,
|
||||||
|
amount: frm.amount,
|
||||||
|
}).await
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
mod member;
|
||||||
|
|
||||||
|
pub use member::*;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,24 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use axum::http::{header, HeaderMap, StatusCode};
|
||||||
|
|
||||||
|
use crate::model::state::AppState;
|
||||||
|
|
||||||
|
pub fn get_conn(state: &AppState) -> Arc<sqlx::MySqlPool> {
|
||||||
|
state.pool.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn redirect(url: &str) -> crate::Result<(StatusCode, HeaderMap, ())> {
|
||||||
|
let mut header = HeaderMap::new();
|
||||||
|
header.insert(header::LOCATION, url.parse().unwrap());
|
||||||
|
|
||||||
|
Ok((StatusCode::FOUND, header, ()))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub mod default_datetime_format {
|
pub mod default_datetime_format {
|
||||||
use chrono::{DateTime, Local, NaiveDateTime};
|
use chrono::{DateTime, Local, NaiveDateTime};
|
||||||
use serde::{self, Deserialize, Serializer, Deserializer};
|
use serde::{self, Deserialize, Deserializer, Serializer};
|
||||||
|
|
||||||
const FORMAT: &'static str = "%Y-%m-%d %H:%M:%S";
|
const FORMAT: &'static str = "%Y-%m-%d %H:%M:%S";
|
||||||
|
|
||||||
|
@ -16,6 +32,7 @@ pub mod default_datetime_format {
|
||||||
let s = format!("{}", date.format(FORMAT));
|
let s = format!("{}", date.format(FORMAT));
|
||||||
serializer.serialize_str(&s)
|
serializer.serialize_str(&s)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deserialize<'de, D>(
|
pub fn deserialize<'de, D>(
|
||||||
deserializer: D,
|
deserializer: D,
|
||||||
) -> Result<DateTime<Local>, D::Error>
|
) -> Result<DateTime<Local>, D::Error>
|
||||||
|
@ -23,7 +40,7 @@ pub mod default_datetime_format {
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let datetime_str = String::deserialize(deserializer)?;
|
let datetime_str = String::deserialize(deserializer)?;
|
||||||
let dt = NaiveDateTime::parse_from_str(&datetime_str, FORMAT).map_err(serde::de::Error::custom)?;
|
let dt = NaiveDateTime::parse_from_str(&datetime_str, FORMAT).map_err(serde::de::Error::custom)?;
|
||||||
Ok(dt.and_local_timezone(Local).unwrap())
|
Ok(dt.and_local_timezone(Local).unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue