rust15-菜单模块

rust15-菜单模块

1、菜单模块表的创建

🍎创建菜单表menus

javascript 复制代码
DROP TABLE IF EXISTS `sys_menu`;
CREATE TABLE `sys_menu`  (
  `menu_id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '菜单ID',
  `menu_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '菜单名称',
  `parent_id` bigint(0) NULL DEFAULT 0 COMMENT '父菜单ID',
  `order_num` int(0) NULL DEFAULT 0 COMMENT '显示顺序',
  `path` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '路由地址',
  `component` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '组件路径',
  `query` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '路由参数',
  `is_frame` int(0) NULL DEFAULT 1 COMMENT '是否为外链(0是 1否)',
  `is_cache` int(0) NULL DEFAULT 0 COMMENT '是否缓存(0缓存 1不缓存)',
  `menu_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '菜单类型(M目录 C菜单 F按钮)',
  `visible` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '菜单状态(0显示 1隐藏)',
  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '菜单状态(0正常 1停用)',
  `perms` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '权限标识',
  `icon` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '#' COMMENT '菜单图标',
  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
  `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '备注',
  PRIMARY KEY (`menu_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2008 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '菜单权限表' ROW_FORMAT = Dynamic;

2、接口开发

👉路由入口引入申明

接下来我们完成菜单模块,在完成功能之前我们需要先添加模块入口,这样rust才能认识到是哪个模块

🍎src\main.rs

先在入口引入我们的模块

javascript 复制代码
  .service(
      web::scope("/api") // 这里加上 /api 前缀
        .configure(modules::menu::menus::config)
  )

🍎模块申明

全局文件之中菜单模块申明

我们的文件结构如下所示,mod.rs作为入口文件进行申明文件暴露

javascript 复制代码
// src\modules\mod.rs
pub mod menu;

建立文件结构如下图所示:

javascript 复制代码
// src\modules\menu

📦menus
 ┣ 📜handlers.rs
 ┣ 📜mod.rs
 ┗ 📜menus.rs

基础模块申明

src\modules\menu下面搭建模块

mod.rs模块

javascript 复制代码
// mod.rs
pub mod handlers;
pub mod menus;

menus.rs模块

javascript 复制代码
use actix_web::web;
pub fn config(cfg: &mut web::ServiceConfig) {
  cfg.route("/system/menus", web::get().to(crate::modules::muenus::handlers::get_list));
  cfg.route("/system/menus", web::post().to(crate::modules::muenus::handlers::post_add));
  cfg.route("/system/menus/{id}", web::get().to(crate::modules::muenus::handlers::get_detail));
  cfg.route("/system/menus", web::put().to(crate::modules::role::handlers::put_update));
  cfg.route("/system/menus/{id}", web::delete().to(crate::modules::muenus::handlers::del_delete));
}

handlers.rs方法逻辑

javascript 复制代码
// handlers.rs方法逻辑

use actix_web::{HttpResponse};
use crate::common::response::ApiResponse; // 导入 ApiResponse 模型

// 通用查询
pub async fn get_list() -> HttpResponse {
    HttpResponse::Ok().json(ApiResponse {
        code: 200,
        msg: "接口信息",
        data:  None::<()>,
    })
}

// 通用新增
pub async fn post_add() -> HttpResponse {
    HttpResponse::Ok().json(ApiResponse {
        code: 200,
        msg: "接口信息",
        data:  None::<()>,
    })
}
// 通用详情
pub async fn get_detail() -> HttpResponse {
    HttpResponse::Ok().json(ApiResponse {
        code: 200,
        msg: "接口信息",
        data:  None::<()>,
    })
}
// 通用更新
pub async fn put_update() -> HttpResponse {
    HttpResponse::Ok().json(ApiResponse {
        code: 200,
        msg: "接口信息",
        data:  None::<()>,
    })
}
// 通用更新
pub async fn del_delete() -> HttpResponse {
    HttpResponse::Ok().json(ApiResponse {
        code: 200,
        msg: "接口信息",
        data:  None::<()>,
    })
}

3、功能实现

🍎新增功能

接下来我们实现菜单模块的新增部分

javascript 复制代码
pub async fn post_add(pool: web::Data<MySqlPool>, form: web::Json<AddMenuRequest>) -> HttpResponse {
    let mut data = std::collections::HashMap::new();
    
    // 插入基础字段
    data.insert("parent_id".to_string(), form.parent_id.to_string());
    data.insert("menu_name".to_string(), form.menu_name.clone());
    data.insert("menu_type".to_string(), form.menu_type.clone());
    data.insert("order_num".to_string(), form.order_num.to_string());
    data.insert("path".to_string(), form.path.clone());
    data.insert("status".to_string(), form.status.clone());

    // 将布尔值转换为字符串格式
    data.insert("is_frame".to_string(), form.is_frame.clone());
    data.insert("is_cache".to_string(), form.is_cache.clone());
    data.insert("visible".to_string(), form.visible.clone());

    // 调用API创建方法
    crate::common::apimethods::create_api(
        pool.get_ref(),
        "sys_menu",
        &data,
        &[
            "menu_name".to_string(),
            "path".to_string(),
        ],
    )
    .await
}

测试接口

javascript 复制代码
{
    "parentId": 0,
    "menuName": "cesss",
    "icon": "build",
    "menuType": "M",
    "orderNum": 22,
    "isFrame": "1",
    "isCache": "0",
    "visible": "0",
    "status": "0",
    "path": "11"
}

返回信息

javascript 复制代码
{
    "code": 200,
    "msg": "新增成功"
}

测试功能ok

🍎查询功能

这里查询我们直接引我们之前的查询部分的参数和方法

javascript 复制代码
// 通过方法
#[allow(unused_imports)]
use crate::common::apimethods::list_api_page; // 引入公共分页查询方法

// 通用查询
pub async fn get_list(
    pool: web::Data<MySqlPool>,
    query: web::Query<QueryParams>,
    filter: Option<web::Query<HashMap<String, String>>>,
) -> impl Responder {
    // 调试:打印查询参数
    if let Some(ref filter_params) = filter {
        println!("查询参数: {:?}", filter_params);
    }
    // 精确查询字段(exact query)
    let exactquery = vec!["status".to_string()];
    // 模糊查询字段(like query) "role_name".to_string()
    let likequery = vec!["menu_name".to_string()];
    // 调用 list_api_page 传入查询条件
    list_api_page(pool, query, filter, "sys_menu", exactquery, likequery).await
}

测试功能ok

🍎详情功能

javascript 复制代码
// 通用详情
pub async fn get_detail(
    pool: web::Data<MySqlPool>,
    path: web::Path<i32>,
) -> HttpResponse {
    crate::common::apimethods::detail_api::<Menu>(pool, "sys_menu", "menu_id", path.into_inner()).await
}

测试功能ok

🍎更新功能

javascript 复制代码
pub async fn put_update(
    pool: web::Data<MySqlPool>,
    item: web::Json<UpdateMenuRequest>,
) -> HttpResponse {
    let mut data = HashMap::new();
    // 只更新需要的字段
    // 插入基础字段
    data.insert("parent_id".to_string(), item.parent_id.to_string());
    data.insert("menu_name".to_string(), item.menu_name.clone());
    data.insert("menu_type".to_string(), item.menu_type.clone());
    data.insert("order_num".to_string(), item.order_num.to_string());
    data.insert("path".to_string(), item.path.clone());
    data.insert("status".to_string(), item.status.clone());
    data.insert("is_frame".to_string(), item.is_frame.to_string());
    data.insert("is_cache".to_string(), item.is_cache.to_string());
    // data.insert("visible".to_string(), item.visible.clone());
    crate::common::apimethods::update_api(
        pool.get_ref(),
        "sys_menu",
        "menu_id",
        item.menu_id,
        &data,
    )
    .await
}

测试功能ok

🍎删除功能

javascript 复制代码
// 删除
pub async fn del_delete(pool: web::Data<MySqlPool>, id: web::Path<i32>) -> HttpResponse {
    crate::common::apimethods::delete_api(
        pool.get_ref(),
        "sys_menu",
        "menu_id",
        *id,
        false, // 软删除,isDeleted=1
    )
    .await
}

测试功能ok,到这里我们的功能就ok了,然后我们继续做导出和导出模块,并且进一步进行优化和完善

相关推荐
止语Lab2 小时前
好的 DX 不等于少写代码——三种语言的摩擦力设计课
后端
吃饱了得干活2 小时前
别再手动解析 LLM 输出了!LangChain 四种结构化输出方案对比
后端·python·langchain
程序员天天困2 小时前
Arthas trace 命令怎么用?一行定位最慢那行代码
jvm·后端
Huiturn2 小时前
GPT 5.6 连续编码 10 小时,纯 Python 啃下 Word 二进制格式——doc2docx 实现拆解
后端
用户298698530142 小时前
Python 实现 Excel 与 Markdown 互转的实用指南
后端·python·excel
用户77283104908402 小时前
krono-job:零侵入、单二进制交付的分布式任务调度平台(开源)
后端
Conan在掘金2 小时前
鸿蒙报错速查:Function lacks ending return statement,返回路径漏 return 就炸,根因 + 真解法
后端
人间凡尔赛3 小时前
AI-Native 云原生架构:2026 年从容器编排到智能体编排的范式革命
后端·云原生·架构
IT_陈寒3 小时前
Vue的响应式让我加班到凌晨3点,原来问题出在这
前端·人工智能·后端
卷无止境3 小时前
提升 Python 代码健壮性的方法大盘点
后端·python