init
This commit is contained in:
84
backend/src/services/menu_service.rs
Normal file
84
backend/src/services/menu_service.rs
Normal file
@ -0,0 +1,84 @@
|
||||
use sea_orm::{EntityTrait, ColumnTrait, QueryFilter, ActiveModelTrait, Set, QueryOrder};
|
||||
use sea_orm::prelude::DateTimeWithTimeZone;
|
||||
use crate::{db::Db, models::menu, error::AppError};
|
||||
use sea_orm::PaginatorTrait;
|
||||
|
||||
#[derive(Clone, Debug, serde::Serialize)]
|
||||
pub struct MenuInfo { pub id: i64, pub parent_id: Option<i64>, pub name: String, pub path: Option<String>, pub component: Option<String>, pub r#type: i32, pub icon: Option<String>, pub order_no: i32, pub visible: bool, pub status: i32, pub keep_alive: bool, pub perms: Option<String>, pub created_at: DateTimeWithTimeZone }
|
||||
impl From<menu::Model> for MenuInfo { fn from(m: menu::Model) -> Self { Self { id: m.id, parent_id: m.parent_id, name: m.name, path: m.path, component: m.component, r#type: m.r#type, icon: m.icon, order_no: m.order_no, visible: m.visible, status: m.status, keep_alive: m.keep_alive, perms: m.perms, created_at: m.created_at } } }
|
||||
|
||||
pub async fn list_all(db: &Db, keyword: Option<String>) -> Result<Vec<MenuInfo>, AppError> {
|
||||
let mut selector = menu::Entity::find();
|
||||
if let Some(k) = keyword { let like = format!("%{}%", k); selector = selector.filter(menu::Column::Name.like(like)); }
|
||||
let models = selector.order_by_asc(menu::Column::OrderNo).order_by_asc(menu::Column::Id).all(db).await?;
|
||||
Ok(models.into_iter().map(Into::into).collect())
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
pub struct CreateMenuInput { pub parent_id: Option<i64>, pub name: String, pub path: Option<String>, pub component: Option<String>, pub r#type: i32, pub icon: Option<String>, pub order_no: Option<i32>, pub visible: Option<bool>, pub status: Option<i32>, pub keep_alive: Option<bool>, pub perms: Option<String> }
|
||||
|
||||
pub async fn create(db: &Db, input: CreateMenuInput) -> Result<MenuInfo, AppError> {
|
||||
let mut am: menu::ActiveModel = Default::default();
|
||||
am.parent_id = Set(input.parent_id);
|
||||
am.name = Set(input.name);
|
||||
am.path = Set(input.path);
|
||||
am.component = Set(input.component);
|
||||
am.r#type = Set(input.r#type);
|
||||
am.icon = Set(input.icon);
|
||||
am.order_no = Set(input.order_no.unwrap_or(0));
|
||||
am.visible = Set(input.visible.unwrap_or(true));
|
||||
am.status = Set(input.status.unwrap_or(1));
|
||||
am.keep_alive = Set(input.keep_alive.unwrap_or(true));
|
||||
am.perms = Set(input.perms);
|
||||
let m = am.insert(db).await?;
|
||||
Ok(m.into())
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
pub struct UpdateMenuInput { pub parent_id: Option<i64>, pub name: Option<String>, pub path: Option<String>, pub component: Option<String>, pub r#type: Option<i32>, pub icon: Option<String>, pub order_no: Option<i32>, pub visible: Option<bool>, pub status: Option<i32>, pub keep_alive: Option<bool>, pub perms: Option<String> }
|
||||
|
||||
pub async fn update(db: &Db, id: i64, input: UpdateMenuInput) -> Result<MenuInfo, AppError> {
|
||||
let m = menu::Entity::find_by_id(id).one(db).await?.ok_or(AppError::NotFound)?;
|
||||
let mut am: menu::ActiveModel = m.into();
|
||||
if let Some(v) = input.parent_id { am.parent_id = Set(Some(v)); }
|
||||
if let Some(v) = input.name { am.name = Set(v); }
|
||||
if let Some(v) = input.path { am.path = Set(Some(v)); }
|
||||
if let Some(v) = input.component { am.component = Set(Some(v)); }
|
||||
if let Some(v) = input.r#type { am.r#type = Set(v); }
|
||||
if let Some(v) = input.icon { am.icon = Set(Some(v)); }
|
||||
if let Some(v) = input.order_no { am.order_no = Set(v); }
|
||||
if let Some(v) = input.visible { am.visible = Set(v); }
|
||||
if let Some(v) = input.status { am.status = Set(v); }
|
||||
if let Some(v) = input.keep_alive { am.keep_alive = Set(v); }
|
||||
if let Some(v) = input.perms { am.perms = Set(Some(v)); }
|
||||
let m = am.update(db).await?;
|
||||
Ok(m.into())
|
||||
}
|
||||
|
||||
pub async fn list_by_ids(db: &Db, ids: Vec<i64>) -> Result<Vec<MenuInfo>, AppError> {
|
||||
if ids.is_empty() { return Ok(vec![]); }
|
||||
let models = menu::Entity::find()
|
||||
.filter(menu::Column::Id.is_in(ids))
|
||||
.filter(menu::Column::Visible.eq(true))
|
||||
.filter(menu::Column::Status.eq(1))
|
||||
.order_by_asc(menu::Column::OrderNo)
|
||||
.order_by_asc(menu::Column::Id)
|
||||
.all(db)
|
||||
.await?;
|
||||
Ok(models.into_iter().map(Into::into).collect())
|
||||
}
|
||||
|
||||
// 新增:删除菜单(禁止删除存在子菜单的项),并清理角色关联
|
||||
use crate::models::role_menu;
|
||||
use sea_orm::TransactionTrait;
|
||||
|
||||
pub async fn delete(db: &Db, id: i64) -> Result<(), AppError> {
|
||||
let _ = menu::Entity::find_by_id(id).one(db).await?.ok_or(AppError::NotFound)?;
|
||||
let child_count = menu::Entity::find().filter(menu::Column::ParentId.eq(Some(id))).count(db).await?;
|
||||
if child_count > 0 { return Err(AppError::BadRequest("请先删除子菜单".into())); }
|
||||
let txn = db.begin().await?;
|
||||
role_menu::Entity::delete_many().filter(role_menu::Column::MenuId.eq(id)).exec(&txn).await?;
|
||||
let _ = menu::Entity::delete_by_id(id).exec(&txn).await?;
|
||||
txn.commit().await?;
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user