# nxu **Repository Path**: jshand/nxu ## Basic Information - **Project Name**: nxu - **Description**: 宁大实训 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 5 - **Forks**: 0 - **Created**: 2026-07-13 - **Last Updated**: 2026-07-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 工具 - IDEA - JDK 21+ (SpringBoot3+ 要求 JDK11+) - Maven 3.9.9+ - https://dlcdn.apache.org/maven/maven-3/3.9.16/binaries/apache-maven-3.9.16-bin.zip - MySQL: 8.0.30 - Nodejs(16、18、20) 使用nvm 管理Node - nvm install 16.12 nvm use 16.12 - nvm install 18.10 # SpringBoot 课件: [01.SpringBoot框架 (yuque.com)](https://www.yuque.com/neuedu/campus/abu40gvz0fby14gm) [官网文档:: Spring Boot](https://docs.spring.io/spring-boot/3.5/tutorial/first-application/index.html) 翻译: [Spring Boot 中文文档 (springdoc.cn)](https://springdoc.cn/spring-boot/) SpringBoot: 开箱即用在,集成启动器(starter-web: 集成内嵌在Tomcat,快速在SpringMVC...)、自动配置 单体架构(所有代码都在一个项目 ) 前后端分离: 持久层框架: Hibernate(ORM )、MyBatis、MyBatisPlus(基于MyBatis) 前段: Vue3.4+(编译环境Node ) maven的配置 ```xml C:/app/jarrepository aliyun-maven * 阿里云公共仓库 https://maven.aliyun.com/repository/public ``` ![image-20260713085013074](assets/image-20260713085013074.png) ## 项目环境 Maven: 安装目录 : C:\app\apache-maven-3.9.9 M2_HOME: C:\app\apache-maven-3.9.9 ![image-20260713084517528](assets/image-20260713084517528.png) ## 创建项目(聚合项目) nxu - springboot - vue - ..... ![image-20260713085112424](assets/image-20260713085112424.png) ## 创建springboot项目 手动创建 - 创建Java工程 - 添加 starter-web : 内嵌 web webmvc Tomcat - 启动类 - 编写测试Controller ![image-20260713085526100](assets/image-20260713085526100.png) ![image-20260713085657849](assets/image-20260713085657849.png) ## 使用 initialze初始化一个项目 ## 常见的注解 ### RestController - Controller + @ResponseBody 会将方法的返回结果进行序列化(json) - 普通的Controller修饰的接口中 方法返回的字符串 会查找试图(jsp、页面) ### RequestMapping - RequetMapping : 映射地址 (RESTFul 风格的API 语义化 ) - Http 7 中 : - Post :@PostMapping 接受Post请求 - Get:@GetMapping 接受Get 请求 - Delete @DeleteMapping - Put @PutMapping - @Option( 跟ajax ) ![image-20260713100510408](assets/image-20260713100510408.png) ### 参数接受 表单数据直接定义变量 使用Apifox 进行接口调试 加入到团队: 金山 在 Apifox 邀请你加入团队 示例团队 https://app.apifox.com/invite?token=9eAg0LLGpy75OknUk79Y4 可以看到我的项目: ![image-20260713103030220](assets/image-20260713103030220.png) #### @RequestParam 绑定表单数据到参数列表中 注解默认必填() ![image-20260713103347494](assets/image-20260713103347494.png) ![image-20260713103412056](assets/image-20260713103412056.png) RequestBody ## 上传文件 - 发送请求 - 表单(form) method: Post enctype: 表单中存在 file ```html
Name
Email
Select a file to upload
``` - Ajax (URLForm)对象 - 后端: - 解析Reqeust - Common-IO request.getInputStrem : x 需要额外添加依赖 暂时不用 - Servlet 3.0+ : request.getParts() - 需要配置上传文件大小 ![image-20260713110124477](assets/image-20260713110124477.png) ### 需要转储 ``` C:\upload ``` 如果需要编写静态文件 html css、JavaScript 可以放到如下目录中 .`/resources``/public``/static` [Static Resources :: Spring Framework](https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-config/static-resources.html) ## 拦截器 ![image-20260713141130188](assets/image-20260713141130188.png) ``` RequestMappingHandlerMapping RequestMappingHandlerAdapter ``` ![image-20260713141453552](assets/image-20260713141453552.png) - - 定义拦截器 (重写三个方法、编写逻辑) - 添加到请求链中 ```java package com.neuedu.boot.filter; import jakarta.servlet.*; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import java.io.IOException; /*** * 拦截器 * * * * * */ public class SSOInteceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("SSOInteceptor.preHandle"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("SSOInteceptor.postHandle"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("SSOInteceptor.afterCompletion"); } } ``` ### 添加到HandlerChain ```java package com.neuedu.boot.config; import filter.boot.com.neuedu.nxu.SSOInteceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * 配置类,会被SpringBoot默认加载 */ @Configuration public class WebConfig implements WebMvcConfigurer { //从容器中 获取一个拦截器的对象 @Autowired private SSOInteceptor ssoInteceptor; @Override public void addInterceptors(InterceptorRegistry registry) { System.out.println("WebConfig.addInterceptors 添加拦截器"); registry.addInterceptor(ssoInteceptor) //配置拦截器生效的URL .addPathPatterns("/**") //排除,不需要拦截 .excludePathPatterns("/login","/swagger-ui.html"); } } ``` ![image-20260713142147702](assets/image-20260713142147702.png) | preHandle | Controller(是否有异常) | postHandle | afterCompletion | | --------- | ------------------------ | ---------- | --------------- | | true √ | 不产生异常√ | √ | √ | | true √ | 产生异常 √ | X | √ | | false √ | X | X | X | ## RESTful ```java package com.neuedu.boot.controller; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/role") public class RoleController { /** * http://localhost:8080/role * @return */ String list(){ return "list"; } /*** * http://localhost:8080/role get * @return */ @GetMapping String getById(){ return "getById"; } /*** * http://localhost:8080/role Post * @return */ @PostMapping String save(){ return "save"; } /*** * http://localhost:8080/role delete * @return */ @DeleteMapping String delete(){ return "delete"; } } ``` ![image-20260713150711867](assets/image-20260713150711867.png) # MyBaits 课件:[01.MyBatis (yuque.com)](https://www.yuque.com/neuedu/campus/qbbgpsvzod9u0fl0) 半自动的持久层框架 ORM (Hibernate-JPA) 可以自己定义SQL语句 对象映射关系 ## 安装数据库 MySQL 8.0.30+ 下载地址: [MySQL :: MySQL Downloads](https://www.mysql.com/downloads/) ![image-20260713152803130](assets/image-20260713152803130.png) 1. msi: 驱动、doc、文档 2. 压缩卷: - 解压, - 初始化 同时在控制台显示信息(包含临时密码) - 安装成系统服务 开机启动 - 使用net 命令 启动服务器 - 登录mysql 管理员身份运行cmd ``` # 初始化 c:\app\mysql-8.0.30-winx64\bin>mysqld --initialize --console 2026-07-13T07:31:08.762080Z 0 [System] [MY-013169] [Server] c:\app\mysql-8.0.30-winx64\bin\mysqld.exe (mysqld 8.0.30) initializing of server in progress as process 10804 2026-07-13T07:31:08.771619Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started. 2026-07-13T07:31:09.092017Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended. 2026-07-13T07:31:09.747944Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: 4+*iicjh(lhF # 安装成系统服务 c:\app\mysql-8.0.30-winx64\bin>mysqld --install Service successfully installed. # 启动MySQL c:\app\mysql-8.0.30-winx64\bin>net start mysql MySQL 服务正在启动 . MySQL 服务已经启动成功。 # 使用临时密码登录 c:\app\mysql-8.0.30-winx64\bin>mysql -uroot -p Enter password: ************ Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 8.0.30 Copyright (c) 2000, 2022, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> ``` ## 修改密码 - 新在加密方式: - mysql_native_password password('root') 旧的加密方式 ```shell mysql> alter user 'root'@'localhost' identified with mysql_native_password by 'root'; Query OK, 0 rows affected (0.01 sec) mysql> ``` 退出使用新密码登录 ```shell c:\app\mysql-8.0.30-winx64\bin>mysql -uroot -proot mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 9 Server version: 8.0.30 MySQL Community Server - GPL Copyright (c) 2000, 2022, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 4 rows in set (0.01 sec) mysql> ``` ## 创建数据库 创建并还原 若依在数据库 ```sql CREATE DATABASE ry; USE ry; -- ---------------------------- -- 1、部门表 -- ---------------------------- DROP TABLE IF EXISTS sys_dept; CREATE TABLE sys_dept ( dept_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '部门id', parent_id BIGINT(20) DEFAULT 0 COMMENT '父部门id', ancestors VARCHAR(50) DEFAULT '' COMMENT '祖级列表', dept_name VARCHAR(30) DEFAULT '' COMMENT '部门名称', order_num INT(4) DEFAULT 0 COMMENT '显示顺序', leader VARCHAR(20) DEFAULT NULL COMMENT '负责人', phone VARCHAR(11) DEFAULT NULL COMMENT '联系电话', email VARCHAR(50) DEFAULT NULL COMMENT '邮箱', STATUS CHAR(1) DEFAULT '0' COMMENT '部门状态(0正常 1停用)', del_flag CHAR(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', create_by VARCHAR(64) DEFAULT '' COMMENT '创建者', create_time DATETIME COMMENT '创建时间', update_by VARCHAR(64) DEFAULT '' COMMENT '更新者', update_time DATETIME COMMENT '更新时间', PRIMARY KEY (dept_id) ) ENGINE=INNODB AUTO_INCREMENT=200 COMMENT = '部门表'; -- ---------------------------- -- 初始化-部门表数据 -- ---------------------------- INSERT INTO sys_dept VALUES(100, 0, '0', '若依科技', 0, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', SYSDATE(), '', NULL); INSERT INTO sys_dept VALUES(101, 100, '0,100', '深圳总公司', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', SYSDATE(), '', NULL); INSERT INTO sys_dept VALUES(102, 100, '0,100', '长沙分公司', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', SYSDATE(), '', NULL); INSERT INTO sys_dept VALUES(103, 101, '0,100,101', '研发部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', SYSDATE(), '', NULL); INSERT INTO sys_dept VALUES(104, 101, '0,100,101', '市场部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', SYSDATE(), '', NULL); INSERT INTO sys_dept VALUES(105, 101, '0,100,101', '测试部门', 3, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', SYSDATE(), '', NULL); INSERT INTO sys_dept VALUES(106, 101, '0,100,101', '财务部门', 4, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', SYSDATE(), '', NULL); INSERT INTO sys_dept VALUES(107, 101, '0,100,101', '运维部门', 5, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', SYSDATE(), '', NULL); INSERT INTO sys_dept VALUES(108, 102, '0,100,102', '市场部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', SYSDATE(), '', NULL); INSERT INTO sys_dept VALUES(109, 102, '0,100,102', '财务部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', SYSDATE(), '', NULL); -- ---------------------------- -- 2、用户信息表 -- ---------------------------- DROP TABLE IF EXISTS sys_user; CREATE TABLE sys_user ( user_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID', dept_id BIGINT(20) DEFAULT NULL COMMENT '部门ID', user_name VARCHAR(30) NOT NULL COMMENT '用户账号', nick_name VARCHAR(30) NOT NULL COMMENT '用户昵称', user_type VARCHAR(2) DEFAULT '00' COMMENT '用户类型(00系统用户)', email VARCHAR(50) DEFAULT '' COMMENT '用户邮箱', phonenumber VARCHAR(11) DEFAULT '' COMMENT '手机号码', sex CHAR(1) DEFAULT '0' COMMENT '用户性别(0男 1女 2未知)', avatar VARCHAR(100) DEFAULT '' COMMENT '头像地址', PASSWORD VARCHAR(100) DEFAULT '' COMMENT '密码', STATUS CHAR(1) DEFAULT '0' COMMENT '账号状态(0正常 1停用)', del_flag CHAR(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', login_ip VARCHAR(128) DEFAULT '' COMMENT '最后登录IP', login_date DATETIME COMMENT '最后登录时间', pwd_update_date DATETIME COMMENT '密码最后更新时间', create_by VARCHAR(64) DEFAULT '' COMMENT '创建者', create_time DATETIME COMMENT '创建时间', update_by VARCHAR(64) DEFAULT '' COMMENT '更新者', update_time DATETIME COMMENT '更新时间', remark VARCHAR(500) DEFAULT NULL COMMENT '备注', PRIMARY KEY (user_id) ) ENGINE=INNODB AUTO_INCREMENT=100 COMMENT = '用户信息表'; -- ---------------------------- -- 初始化-用户信息表数据 -- ---------------------------- INSERT INTO sys_user VALUES(1, 103, 'admin', '若依', '00', 'ry@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', SYSDATE(), SYSDATE(), 'admin', SYSDATE(), '', NULL, '管理员'); INSERT INTO sys_user VALUES(2, 105, 'ry', '若依', '00', 'ry@qq.com', '15666666666', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', SYSDATE(), SYSDATE(), 'admin', SYSDATE(), '', NULL, '测试员'); -- ---------------------------- -- 3、岗位信息表 -- ---------------------------- DROP TABLE IF EXISTS sys_post; CREATE TABLE sys_post ( post_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '岗位ID', post_code VARCHAR(64) NOT NULL COMMENT '岗位编码', post_name VARCHAR(50) NOT NULL COMMENT '岗位名称', post_sort INT(4) NOT NULL COMMENT '显示顺序', STATUS CHAR(1) NOT NULL COMMENT '状态(0正常 1停用)', create_by VARCHAR(64) DEFAULT '' COMMENT '创建者', create_time DATETIME COMMENT '创建时间', update_by VARCHAR(64) DEFAULT '' COMMENT '更新者', update_time DATETIME COMMENT '更新时间', remark VARCHAR(500) DEFAULT NULL COMMENT '备注', PRIMARY KEY (post_id) ) ENGINE=INNODB COMMENT = '岗位信息表'; -- ---------------------------- -- 初始化-岗位信息表数据 -- ---------------------------- INSERT INTO sys_post VALUES(1, 'ceo', '董事长', 1, '0', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_post VALUES(2, 'se', '项目经理', 2, '0', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_post VALUES(3, 'hr', '人力资源', 3, '0', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_post VALUES(4, 'user', '普通员工', 4, '0', 'admin', SYSDATE(), '', NULL, ''); -- ---------------------------- -- 4、角色信息表 -- ---------------------------- DROP TABLE IF EXISTS sys_role; CREATE TABLE sys_role ( role_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '角色ID', role_name VARCHAR(30) NOT NULL COMMENT '角色名称', role_key VARCHAR(100) NOT NULL COMMENT '角色权限字符串', role_sort INT(4) NOT NULL COMMENT '显示顺序', data_scope CHAR(1) DEFAULT '1' COMMENT '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)', menu_check_strictly TINYINT(1) DEFAULT 1 COMMENT '菜单树选择项是否关联显示', dept_check_strictly TINYINT(1) DEFAULT 1 COMMENT '部门树选择项是否关联显示', STATUS CHAR(1) NOT NULL COMMENT '角色状态(0正常 1停用)', del_flag CHAR(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', create_by VARCHAR(64) DEFAULT '' COMMENT '创建者', create_time DATETIME COMMENT '创建时间', update_by VARCHAR(64) DEFAULT '' COMMENT '更新者', update_time DATETIME COMMENT '更新时间', remark VARCHAR(500) DEFAULT NULL COMMENT '备注', PRIMARY KEY (role_id) ) ENGINE=INNODB AUTO_INCREMENT=100 COMMENT = '角色信息表'; -- ---------------------------- -- 初始化-角色信息表数据 -- ---------------------------- INSERT INTO sys_role VALUES('1', '超级管理员', 'admin', 1, 1, 1, 1, '0', '0', 'admin', SYSDATE(), '', NULL, '超级管理员'); INSERT INTO sys_role VALUES('2', '普通角色', 'common', 2, 2, 1, 1, '0', '0', 'admin', SYSDATE(), '', NULL, '普通角色'); -- ---------------------------- -- 5、菜单权限表 -- ---------------------------- DROP TABLE IF EXISTS sys_menu; CREATE TABLE sys_menu ( menu_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '菜单ID', menu_name VARCHAR(50) NOT NULL COMMENT '菜单名称', parent_id BIGINT(20) DEFAULT 0 COMMENT '父菜单ID', order_num INT(4) DEFAULT 0 COMMENT '显示顺序', path VARCHAR(200) DEFAULT '' COMMENT '路由地址', component VARCHAR(255) DEFAULT NULL COMMENT '组件路径', QUERY VARCHAR(255) DEFAULT NULL COMMENT '路由参数', route_name VARCHAR(50) DEFAULT '' COMMENT '路由名称', is_frame INT(1) DEFAULT 1 COMMENT '是否为外链(0是 1否)', is_cache INT(1) DEFAULT 0 COMMENT '是否缓存(0缓存 1不缓存)', menu_type CHAR(1) DEFAULT '' COMMENT '菜单类型(M目录 C菜单 F按钮)', visible CHAR(1) DEFAULT 0 COMMENT '菜单状态(0显示 1隐藏)', STATUS CHAR(1) DEFAULT 0 COMMENT '菜单状态(0正常 1停用)', perms VARCHAR(100) DEFAULT NULL COMMENT '权限标识', icon VARCHAR(100) DEFAULT '#' COMMENT '菜单图标', create_by VARCHAR(64) DEFAULT '' COMMENT '创建者', create_time DATETIME COMMENT '创建时间', update_by VARCHAR(64) DEFAULT '' COMMENT '更新者', update_time DATETIME COMMENT '更新时间', remark VARCHAR(500) DEFAULT '' COMMENT '备注', PRIMARY KEY (menu_id) ) ENGINE=INNODB AUTO_INCREMENT=2000 COMMENT = '菜单权限表'; -- ---------------------------- -- 初始化-菜单信息表数据 -- ---------------------------- -- 一级菜单 INSERT INTO sys_menu VALUES('1', '系统管理', '0', '1', 'system', NULL, '', '', 1, 0, 'M', '0', '0', '', 'system', 'admin', SYSDATE(), '', NULL, '系统管理目录'); INSERT INTO sys_menu VALUES('2', '系统监控', '0', '2', 'monitor', NULL, '', '', 1, 0, 'M', '0', '0', '', 'monitor', 'admin', SYSDATE(), '', NULL, '系统监控目录'); INSERT INTO sys_menu VALUES('3', '系统工具', '0', '3', 'tool', NULL, '', '', 1, 0, 'M', '0', '0', '', 'tool', 'admin', SYSDATE(), '', NULL, '系统工具目录'); INSERT INTO sys_menu VALUES('4', '若依官网', '0', '4', 'http://ruoyi.vip', NULL, '', '', 0, 0, 'M', '0', '0', '', 'guide', 'admin', SYSDATE(), '', NULL, '若依官网地址'); -- 二级菜单 INSERT INTO sys_menu VALUES('100', '用户管理', '1', '1', 'user', 'system/user/index', '', '', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 'admin', SYSDATE(), '', NULL, '用户管理菜单'); INSERT INTO sys_menu VALUES('101', '角色管理', '1', '2', 'role', 'system/role/index', '', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 'admin', SYSDATE(), '', NULL, '角色管理菜单'); INSERT INTO sys_menu VALUES('102', '菜单管理', '1', '3', 'menu', 'system/menu/index', '', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'tree-table', 'admin', SYSDATE(), '', NULL, '菜单管理菜单'); INSERT INTO sys_menu VALUES('103', '部门管理', '1', '4', 'dept', 'system/dept/index', '', '', 1, 0, 'C', '0', '0', 'system:dept:list', 'tree', 'admin', SYSDATE(), '', NULL, '部门管理菜单'); INSERT INTO sys_menu VALUES('104', '岗位管理', '1', '5', 'post', 'system/post/index', '', '', 1, 0, 'C', '0', '0', 'system:post:list', 'post', 'admin', SYSDATE(), '', NULL, '岗位管理菜单'); INSERT INTO sys_menu VALUES('105', '字典管理', '1', '6', 'dict', 'system/dict/index', '', '', 1, 0, 'C', '0', '0', 'system:dict:list', 'dict', 'admin', SYSDATE(), '', NULL, '字典管理菜单'); INSERT INTO sys_menu VALUES('106', '参数设置', '1', '7', 'config', 'system/config/index', '', '', 1, 0, 'C', '0', '0', 'system:config:list', 'edit', 'admin', SYSDATE(), '', NULL, '参数设置菜单'); INSERT INTO sys_menu VALUES('107', '通知公告', '1', '8', 'notice', 'system/notice/index', '', '', 1, 0, 'C', '0', '0', 'system:notice:list', 'message', 'admin', SYSDATE(), '', NULL, '通知公告菜单'); INSERT INTO sys_menu VALUES('108', '日志管理', '1', '9', 'log', '', '', '', 1, 0, 'M', '0', '0', '', 'log', 'admin', SYSDATE(), '', NULL, '日志管理菜单'); INSERT INTO sys_menu VALUES('109', '在线用户', '2', '1', 'online', 'monitor/online/index', '', '', 1, 0, 'C', '0', '0', 'monitor:online:list', 'online', 'admin', SYSDATE(), '', NULL, '在线用户菜单'); INSERT INTO sys_menu VALUES('110', '定时任务', '2', '2', 'job', 'monitor/job/index', '', '', 1, 0, 'C', '0', '0', 'monitor:job:list', 'job', 'admin', SYSDATE(), '', NULL, '定时任务菜单'); INSERT INTO sys_menu VALUES('111', '数据监控', '2', '3', 'druid', 'monitor/druid/index', '', '', 1, 0, 'C', '0', '0', 'monitor:druid:list', 'druid', 'admin', SYSDATE(), '', NULL, '数据监控菜单'); INSERT INTO sys_menu VALUES('112', '服务监控', '2', '4', 'server', 'monitor/server/index', '', '', 1, 0, 'C', '0', '0', 'monitor:server:list', 'server', 'admin', SYSDATE(), '', NULL, '服务监控菜单'); INSERT INTO sys_menu VALUES('113', '缓存监控', '2', '5', 'cache', 'monitor/cache/index', '', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis', 'admin', SYSDATE(), '', NULL, '缓存监控菜单'); INSERT INTO sys_menu VALUES('114', '缓存列表', '2', '6', 'cacheList', 'monitor/cache/list', '', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis-list', 'admin', SYSDATE(), '', NULL, '缓存列表菜单'); INSERT INTO sys_menu VALUES('115', '表单构建', '3', '1', 'build', 'tool/build/index', '', '', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', SYSDATE(), '', NULL, '表单构建菜单'); INSERT INTO sys_menu VALUES('116', '代码生成', '3', '2', 'gen', 'tool/gen/index', '', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', SYSDATE(), '', NULL, '代码生成菜单'); INSERT INTO sys_menu VALUES('117', '系统接口', '3', '3', 'swagger', 'tool/swagger/index', '', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', SYSDATE(), '', NULL, '系统接口菜单'); -- 三级菜单 INSERT INTO sys_menu VALUES('500', '操作日志', '108', '1', 'operlog', 'monitor/operlog/index', '', '', 1, 0, 'C', '0', '0', 'monitor:operlog:list', 'form', 'admin', SYSDATE(), '', NULL, '操作日志菜单'); INSERT INTO sys_menu VALUES('501', '登录日志', '108', '2', 'logininfor', 'monitor/logininfor/index', '', '', 1, 0, 'C', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', SYSDATE(), '', NULL, '登录日志菜单'); -- 用户管理按钮 INSERT INTO sys_menu VALUES('1000', '用户查询', '100', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:query', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1001', '用户新增', '100', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:add', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1002', '用户修改', '100', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:edit', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1003', '用户删除', '100', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:remove', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1004', '用户导出', '100', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:export', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1005', '用户导入', '100', '6', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:import', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1006', '重置密码', '100', '7', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:resetPwd', '#', 'admin', SYSDATE(), '', NULL, ''); -- 角色管理按钮 INSERT INTO sys_menu VALUES('1007', '角色查询', '101', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:query', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1008', '角色新增', '101', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:add', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1009', '角色修改', '101', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:edit', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1010', '角色删除', '101', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:remove', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1011', '角色导出', '101', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:export', '#', 'admin', SYSDATE(), '', NULL, ''); -- 菜单管理按钮 INSERT INTO sys_menu VALUES('1012', '菜单查询', '102', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:query', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1013', '菜单新增', '102', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:add', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1014', '菜单修改', '102', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:edit', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1015', '菜单删除', '102', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:remove', '#', 'admin', SYSDATE(), '', NULL, ''); -- 部门管理按钮 INSERT INTO sys_menu VALUES('1016', '部门查询', '103', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:query', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1017', '部门新增', '103', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:add', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1018', '部门修改', '103', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:edit', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1019', '部门删除', '103', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:remove', '#', 'admin', SYSDATE(), '', NULL, ''); -- 岗位管理按钮 INSERT INTO sys_menu VALUES('1020', '岗位查询', '104', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:query', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1021', '岗位新增', '104', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:add', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1022', '岗位修改', '104', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:edit', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1023', '岗位删除', '104', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:remove', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1024', '岗位导出', '104', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:export', '#', 'admin', SYSDATE(), '', NULL, ''); -- 字典管理按钮 INSERT INTO sys_menu VALUES('1025', '字典查询', '105', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:query', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1026', '字典新增', '105', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:add', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1027', '字典修改', '105', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:edit', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1028', '字典删除', '105', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:remove', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1029', '字典导出', '105', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:export', '#', 'admin', SYSDATE(), '', NULL, ''); -- 参数设置按钮 INSERT INTO sys_menu VALUES('1030', '参数查询', '106', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:query', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1031', '参数新增', '106', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:add', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1032', '参数修改', '106', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:edit', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1033', '参数删除', '106', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:remove', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1034', '参数导出', '106', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:export', '#', 'admin', SYSDATE(), '', NULL, ''); -- 通知公告按钮 INSERT INTO sys_menu VALUES('1035', '公告查询', '107', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:query', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1036', '公告新增', '107', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:add', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1037', '公告修改', '107', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:edit', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1038', '公告删除', '107', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:remove', '#', 'admin', SYSDATE(), '', NULL, ''); -- 操作日志按钮 INSERT INTO sys_menu VALUES('1039', '操作查询', '500', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:query', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1040', '操作删除', '500', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:remove', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1041', '日志导出', '500', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:export', '#', 'admin', SYSDATE(), '', NULL, ''); -- 登录日志按钮 INSERT INTO sys_menu VALUES('1042', '登录查询', '501', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1043', '登录删除', '501', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1044', '日志导出', '501', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1045', '账户解锁', '501', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 'admin', SYSDATE(), '', NULL, ''); -- 在线用户按钮 INSERT INTO sys_menu VALUES('1046', '在线查询', '109', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1047', '批量强退', '109', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1048', '单条强退', '109', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', SYSDATE(), '', NULL, ''); -- 定时任务按钮 INSERT INTO sys_menu VALUES('1049', '任务查询', '110', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:query', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1050', '任务新增', '110', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:add', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1051', '任务修改', '110', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:edit', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1052', '任务删除', '110', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:remove', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1053', '状态修改', '110', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:changeStatus', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1054', '任务导出', '110', '6', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:export', '#', 'admin', SYSDATE(), '', NULL, ''); -- 代码生成按钮 INSERT INTO sys_menu VALUES('1055', '生成查询', '116', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:query', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1056', '生成修改', '116', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:edit', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1057', '生成删除', '116', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:remove', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1058', '导入代码', '116', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1059', '预览代码', '116', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_menu VALUES('1060', '生成代码', '116', '6', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', SYSDATE(), '', NULL, ''); -- ---------------------------- -- 6、用户和角色关联表 用户N-1角色 -- ---------------------------- DROP TABLE IF EXISTS sys_user_role; CREATE TABLE sys_user_role ( user_id BIGINT(20) NOT NULL COMMENT '用户ID', role_id BIGINT(20) NOT NULL COMMENT '角色ID', PRIMARY KEY(user_id, role_id) ) ENGINE=INNODB COMMENT = '用户和角色关联表'; -- ---------------------------- -- 初始化-用户和角色关联表数据 -- ---------------------------- INSERT INTO sys_user_role VALUES ('1', '1'); INSERT INTO sys_user_role VALUES ('2', '2'); -- ---------------------------- -- 7、角色和菜单关联表 角色1-N菜单 -- ---------------------------- DROP TABLE IF EXISTS sys_role_menu; CREATE TABLE sys_role_menu ( role_id BIGINT(20) NOT NULL COMMENT '角色ID', menu_id BIGINT(20) NOT NULL COMMENT '菜单ID', PRIMARY KEY(role_id, menu_id) ) ENGINE=INNODB COMMENT = '角色和菜单关联表'; -- ---------------------------- -- 初始化-角色和菜单关联表数据 -- ---------------------------- INSERT INTO sys_role_menu VALUES ('2', '1'); INSERT INTO sys_role_menu VALUES ('2', '2'); INSERT INTO sys_role_menu VALUES ('2', '3'); INSERT INTO sys_role_menu VALUES ('2', '4'); INSERT INTO sys_role_menu VALUES ('2', '100'); INSERT INTO sys_role_menu VALUES ('2', '101'); INSERT INTO sys_role_menu VALUES ('2', '102'); INSERT INTO sys_role_menu VALUES ('2', '103'); INSERT INTO sys_role_menu VALUES ('2', '104'); INSERT INTO sys_role_menu VALUES ('2', '105'); INSERT INTO sys_role_menu VALUES ('2', '106'); INSERT INTO sys_role_menu VALUES ('2', '107'); INSERT INTO sys_role_menu VALUES ('2', '108'); INSERT INTO sys_role_menu VALUES ('2', '109'); INSERT INTO sys_role_menu VALUES ('2', '110'); INSERT INTO sys_role_menu VALUES ('2', '111'); INSERT INTO sys_role_menu VALUES ('2', '112'); INSERT INTO sys_role_menu VALUES ('2', '113'); INSERT INTO sys_role_menu VALUES ('2', '114'); INSERT INTO sys_role_menu VALUES ('2', '115'); INSERT INTO sys_role_menu VALUES ('2', '116'); INSERT INTO sys_role_menu VALUES ('2', '117'); INSERT INTO sys_role_menu VALUES ('2', '500'); INSERT INTO sys_role_menu VALUES ('2', '501'); INSERT INTO sys_role_menu VALUES ('2', '1000'); INSERT INTO sys_role_menu VALUES ('2', '1001'); INSERT INTO sys_role_menu VALUES ('2', '1002'); INSERT INTO sys_role_menu VALUES ('2', '1003'); INSERT INTO sys_role_menu VALUES ('2', '1004'); INSERT INTO sys_role_menu VALUES ('2', '1005'); INSERT INTO sys_role_menu VALUES ('2', '1006'); INSERT INTO sys_role_menu VALUES ('2', '1007'); INSERT INTO sys_role_menu VALUES ('2', '1008'); INSERT INTO sys_role_menu VALUES ('2', '1009'); INSERT INTO sys_role_menu VALUES ('2', '1010'); INSERT INTO sys_role_menu VALUES ('2', '1011'); INSERT INTO sys_role_menu VALUES ('2', '1012'); INSERT INTO sys_role_menu VALUES ('2', '1013'); INSERT INTO sys_role_menu VALUES ('2', '1014'); INSERT INTO sys_role_menu VALUES ('2', '1015'); INSERT INTO sys_role_menu VALUES ('2', '1016'); INSERT INTO sys_role_menu VALUES ('2', '1017'); INSERT INTO sys_role_menu VALUES ('2', '1018'); INSERT INTO sys_role_menu VALUES ('2', '1019'); INSERT INTO sys_role_menu VALUES ('2', '1020'); INSERT INTO sys_role_menu VALUES ('2', '1021'); INSERT INTO sys_role_menu VALUES ('2', '1022'); INSERT INTO sys_role_menu VALUES ('2', '1023'); INSERT INTO sys_role_menu VALUES ('2', '1024'); INSERT INTO sys_role_menu VALUES ('2', '1025'); INSERT INTO sys_role_menu VALUES ('2', '1026'); INSERT INTO sys_role_menu VALUES ('2', '1027'); INSERT INTO sys_role_menu VALUES ('2', '1028'); INSERT INTO sys_role_menu VALUES ('2', '1029'); INSERT INTO sys_role_menu VALUES ('2', '1030'); INSERT INTO sys_role_menu VALUES ('2', '1031'); INSERT INTO sys_role_menu VALUES ('2', '1032'); INSERT INTO sys_role_menu VALUES ('2', '1033'); INSERT INTO sys_role_menu VALUES ('2', '1034'); INSERT INTO sys_role_menu VALUES ('2', '1035'); INSERT INTO sys_role_menu VALUES ('2', '1036'); INSERT INTO sys_role_menu VALUES ('2', '1037'); INSERT INTO sys_role_menu VALUES ('2', '1038'); INSERT INTO sys_role_menu VALUES ('2', '1039'); INSERT INTO sys_role_menu VALUES ('2', '1040'); INSERT INTO sys_role_menu VALUES ('2', '1041'); INSERT INTO sys_role_menu VALUES ('2', '1042'); INSERT INTO sys_role_menu VALUES ('2', '1043'); INSERT INTO sys_role_menu VALUES ('2', '1044'); INSERT INTO sys_role_menu VALUES ('2', '1045'); INSERT INTO sys_role_menu VALUES ('2', '1046'); INSERT INTO sys_role_menu VALUES ('2', '1047'); INSERT INTO sys_role_menu VALUES ('2', '1048'); INSERT INTO sys_role_menu VALUES ('2', '1049'); INSERT INTO sys_role_menu VALUES ('2', '1050'); INSERT INTO sys_role_menu VALUES ('2', '1051'); INSERT INTO sys_role_menu VALUES ('2', '1052'); INSERT INTO sys_role_menu VALUES ('2', '1053'); INSERT INTO sys_role_menu VALUES ('2', '1054'); INSERT INTO sys_role_menu VALUES ('2', '1055'); INSERT INTO sys_role_menu VALUES ('2', '1056'); INSERT INTO sys_role_menu VALUES ('2', '1057'); INSERT INTO sys_role_menu VALUES ('2', '1058'); INSERT INTO sys_role_menu VALUES ('2', '1059'); INSERT INTO sys_role_menu VALUES ('2', '1060'); -- ---------------------------- -- 8、角色和部门关联表 角色1-N部门 -- ---------------------------- DROP TABLE IF EXISTS sys_role_dept; CREATE TABLE sys_role_dept ( role_id BIGINT(20) NOT NULL COMMENT '角色ID', dept_id BIGINT(20) NOT NULL COMMENT '部门ID', PRIMARY KEY(role_id, dept_id) ) ENGINE=INNODB COMMENT = '角色和部门关联表'; -- ---------------------------- -- 初始化-角色和部门关联表数据 -- ---------------------------- INSERT INTO sys_role_dept VALUES ('2', '100'); INSERT INTO sys_role_dept VALUES ('2', '101'); INSERT INTO sys_role_dept VALUES ('2', '105'); -- ---------------------------- -- 9、用户与岗位关联表 用户1-N岗位 -- ---------------------------- DROP TABLE IF EXISTS sys_user_post; CREATE TABLE sys_user_post ( user_id BIGINT(20) NOT NULL COMMENT '用户ID', post_id BIGINT(20) NOT NULL COMMENT '岗位ID', PRIMARY KEY (user_id, post_id) ) ENGINE=INNODB COMMENT = '用户与岗位关联表'; -- ---------------------------- -- 初始化-用户与岗位关联表数据 -- ---------------------------- INSERT INTO sys_user_post VALUES ('1', '1'); INSERT INTO sys_user_post VALUES ('2', '2'); -- ---------------------------- -- 10、操作日志记录 -- ---------------------------- DROP TABLE IF EXISTS sys_oper_log; CREATE TABLE sys_oper_log ( oper_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '日志主键', title VARCHAR(50) DEFAULT '' COMMENT '模块标题', business_type INT(2) DEFAULT 0 COMMENT '业务类型(0其它 1新增 2修改 3删除)', method VARCHAR(200) DEFAULT '' COMMENT '方法名称', request_method VARCHAR(10) DEFAULT '' COMMENT '请求方式', operator_type INT(1) DEFAULT 0 COMMENT '操作类别(0其它 1后台用户 2手机端用户)', oper_name VARCHAR(50) DEFAULT '' COMMENT '操作人员', dept_name VARCHAR(50) DEFAULT '' COMMENT '部门名称', oper_url VARCHAR(255) DEFAULT '' COMMENT '请求URL', oper_ip VARCHAR(128) DEFAULT '' COMMENT '主机地址', oper_location VARCHAR(255) DEFAULT '' COMMENT '操作地点', oper_param VARCHAR(2000) DEFAULT '' COMMENT '请求参数', json_result VARCHAR(2000) DEFAULT '' COMMENT '返回参数', STATUS INT(1) DEFAULT 0 COMMENT '操作状态(0正常 1异常)', error_msg VARCHAR(2000) DEFAULT '' COMMENT '错误消息', oper_time DATETIME COMMENT '操作时间', cost_time BIGINT(20) DEFAULT 0 COMMENT '消耗时间', PRIMARY KEY (oper_id), KEY idx_sys_oper_log_bt (business_type), KEY idx_sys_oper_log_s (STATUS), KEY idx_sys_oper_log_ot (oper_time) ) ENGINE=INNODB AUTO_INCREMENT=100 COMMENT = '操作日志记录'; -- ---------------------------- -- 11、字典类型表 -- ---------------------------- DROP TABLE IF EXISTS sys_dict_type; CREATE TABLE sys_dict_type ( dict_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '字典主键', dict_name VARCHAR(100) DEFAULT '' COMMENT '字典名称', dict_type VARCHAR(100) DEFAULT '' COMMENT '字典类型', STATUS CHAR(1) DEFAULT '0' COMMENT '状态(0正常 1停用)', create_by VARCHAR(64) DEFAULT '' COMMENT '创建者', create_time DATETIME COMMENT '创建时间', update_by VARCHAR(64) DEFAULT '' COMMENT '更新者', update_time DATETIME COMMENT '更新时间', remark VARCHAR(500) DEFAULT NULL COMMENT '备注', PRIMARY KEY (dict_id), UNIQUE (dict_type) ) ENGINE=INNODB AUTO_INCREMENT=100 COMMENT = '字典类型表'; INSERT INTO sys_dict_type VALUES(1, '用户性别', 'sys_user_sex', '0', 'admin', SYSDATE(), '', NULL, '用户性别列表'); INSERT INTO sys_dict_type VALUES(2, '菜单状态', 'sys_show_hide', '0', 'admin', SYSDATE(), '', NULL, '菜单状态列表'); INSERT INTO sys_dict_type VALUES(3, '系统开关', 'sys_normal_disable', '0', 'admin', SYSDATE(), '', NULL, '系统开关列表'); INSERT INTO sys_dict_type VALUES(4, '任务状态', 'sys_job_status', '0', 'admin', SYSDATE(), '', NULL, '任务状态列表'); INSERT INTO sys_dict_type VALUES(5, '任务分组', 'sys_job_group', '0', 'admin', SYSDATE(), '', NULL, '任务分组列表'); INSERT INTO sys_dict_type VALUES(6, '系统是否', 'sys_yes_no', '0', 'admin', SYSDATE(), '', NULL, '系统是否列表'); INSERT INTO sys_dict_type VALUES(7, '通知类型', 'sys_notice_type', '0', 'admin', SYSDATE(), '', NULL, '通知类型列表'); INSERT INTO sys_dict_type VALUES(8, '通知状态', 'sys_notice_status', '0', 'admin', SYSDATE(), '', NULL, '通知状态列表'); INSERT INTO sys_dict_type VALUES(9, '操作类型', 'sys_oper_type', '0', 'admin', SYSDATE(), '', NULL, '操作类型列表'); INSERT INTO sys_dict_type VALUES(10, '系统状态', 'sys_common_status', '0', 'admin', SYSDATE(), '', NULL, '登录状态列表'); -- ---------------------------- -- 12、字典数据表 -- ---------------------------- DROP TABLE IF EXISTS sys_dict_data; CREATE TABLE sys_dict_data ( dict_code BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '字典编码', dict_sort INT(4) DEFAULT 0 COMMENT '字典排序', dict_label VARCHAR(100) DEFAULT '' COMMENT '字典标签', dict_value VARCHAR(100) DEFAULT '' COMMENT '字典键值', dict_type VARCHAR(100) DEFAULT '' COMMENT '字典类型', css_class VARCHAR(100) DEFAULT NULL COMMENT '样式属性(其他样式扩展)', list_class VARCHAR(100) DEFAULT NULL COMMENT '表格回显样式', is_default CHAR(1) DEFAULT 'N' COMMENT '是否默认(Y是 N否)', STATUS CHAR(1) DEFAULT '0' COMMENT '状态(0正常 1停用)', create_by VARCHAR(64) DEFAULT '' COMMENT '创建者', create_time DATETIME COMMENT '创建时间', update_by VARCHAR(64) DEFAULT '' COMMENT '更新者', update_time DATETIME COMMENT '更新时间', remark VARCHAR(500) DEFAULT NULL COMMENT '备注', PRIMARY KEY (dict_code) ) ENGINE=INNODB AUTO_INCREMENT=100 COMMENT = '字典数据表'; INSERT INTO sys_dict_data VALUES(1, 1, '男', '0', 'sys_user_sex', '', '', 'Y', '0', 'admin', SYSDATE(), '', NULL, '性别男'); INSERT INTO sys_dict_data VALUES(2, 2, '女', '1', 'sys_user_sex', '', '', 'N', '0', 'admin', SYSDATE(), '', NULL, '性别女'); INSERT INTO sys_dict_data VALUES(3, 3, '未知', '2', 'sys_user_sex', '', '', 'N', '0', 'admin', SYSDATE(), '', NULL, '性别未知'); INSERT INTO sys_dict_data VALUES(4, 1, '显示', '0', 'sys_show_hide', '', 'primary', 'Y', '0', 'admin', SYSDATE(), '', NULL, '显示菜单'); INSERT INTO sys_dict_data VALUES(5, 2, '隐藏', '1', 'sys_show_hide', '', 'danger', 'N', '0', 'admin', SYSDATE(), '', NULL, '隐藏菜单'); INSERT INTO sys_dict_data VALUES(6, 1, '正常', '0', 'sys_normal_disable', '', 'primary', 'Y', '0', 'admin', SYSDATE(), '', NULL, '正常状态'); INSERT INTO sys_dict_data VALUES(7, 2, '停用', '1', 'sys_normal_disable', '', 'danger', 'N', '0', 'admin', SYSDATE(), '', NULL, '停用状态'); INSERT INTO sys_dict_data VALUES(8, 1, '正常', '0', 'sys_job_status', '', 'primary', 'Y', '0', 'admin', SYSDATE(), '', NULL, '正常状态'); INSERT INTO sys_dict_data VALUES(9, 2, '暂停', '1', 'sys_job_status', '', 'danger', 'N', '0', 'admin', SYSDATE(), '', NULL, '停用状态'); INSERT INTO sys_dict_data VALUES(10, 1, '默认', 'DEFAULT', 'sys_job_group', '', '', 'Y', '0', 'admin', SYSDATE(), '', NULL, '默认分组'); INSERT INTO sys_dict_data VALUES(11, 2, '系统', 'SYSTEM', 'sys_job_group', '', '', 'N', '0', 'admin', SYSDATE(), '', NULL, '系统分组'); INSERT INTO sys_dict_data VALUES(12, 1, '是', 'Y', 'sys_yes_no', '', 'primary', 'Y', '0', 'admin', SYSDATE(), '', NULL, '系统默认是'); INSERT INTO sys_dict_data VALUES(13, 2, '否', 'N', 'sys_yes_no', '', 'danger', 'N', '0', 'admin', SYSDATE(), '', NULL, '系统默认否'); INSERT INTO sys_dict_data VALUES(14, 1, '通知', '1', 'sys_notice_type', '', 'warning', 'Y', '0', 'admin', SYSDATE(), '', NULL, '通知'); INSERT INTO sys_dict_data VALUES(15, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', SYSDATE(), '', NULL, '公告'); INSERT INTO sys_dict_data VALUES(16, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', SYSDATE(), '', NULL, '正常状态'); INSERT INTO sys_dict_data VALUES(17, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', SYSDATE(), '', NULL, '关闭状态'); INSERT INTO sys_dict_data VALUES(18, 99, '其他', '0', 'sys_oper_type', '', 'info', 'N', '0', 'admin', SYSDATE(), '', NULL, '其他操作'); INSERT INTO sys_dict_data VALUES(19, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', SYSDATE(), '', NULL, '新增操作'); INSERT INTO sys_dict_data VALUES(20, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', SYSDATE(), '', NULL, '修改操作'); INSERT INTO sys_dict_data VALUES(21, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', SYSDATE(), '', NULL, '删除操作'); INSERT INTO sys_dict_data VALUES(22, 4, '授权', '4', 'sys_oper_type', '', 'primary', 'N', '0', 'admin', SYSDATE(), '', NULL, '授权操作'); INSERT INTO sys_dict_data VALUES(23, 5, '导出', '5', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', SYSDATE(), '', NULL, '导出操作'); INSERT INTO sys_dict_data VALUES(24, 6, '导入', '6', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', SYSDATE(), '', NULL, '导入操作'); INSERT INTO sys_dict_data VALUES(25, 7, '强退', '7', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', SYSDATE(), '', NULL, '强退操作'); INSERT INTO sys_dict_data VALUES(26, 8, '生成代码', '8', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', SYSDATE(), '', NULL, '生成操作'); INSERT INTO sys_dict_data VALUES(27, 9, '清空数据', '9', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', SYSDATE(), '', NULL, '清空操作'); INSERT INTO sys_dict_data VALUES(28, 1, '成功', '0', 'sys_common_status', '', 'primary', 'N', '0', 'admin', SYSDATE(), '', NULL, '正常状态'); INSERT INTO sys_dict_data VALUES(29, 2, '失败', '1', 'sys_common_status', '', 'danger', 'N', '0', 'admin', SYSDATE(), '', NULL, '停用状态'); -- ---------------------------- -- 13、参数配置表 -- ---------------------------- DROP TABLE IF EXISTS sys_config; CREATE TABLE sys_config ( config_id INT(5) NOT NULL AUTO_INCREMENT COMMENT '参数主键', config_name VARCHAR(100) DEFAULT '' COMMENT '参数名称', config_key VARCHAR(100) DEFAULT '' COMMENT '参数键名', config_value VARCHAR(500) DEFAULT '' COMMENT '参数键值', config_type CHAR(1) DEFAULT 'N' COMMENT '系统内置(Y是 N否)', create_by VARCHAR(64) DEFAULT '' COMMENT '创建者', create_time DATETIME COMMENT '创建时间', update_by VARCHAR(64) DEFAULT '' COMMENT '更新者', update_time DATETIME COMMENT '更新时间', remark VARCHAR(500) DEFAULT NULL COMMENT '备注', PRIMARY KEY (config_id) ) ENGINE=INNODB AUTO_INCREMENT=100 COMMENT = '参数配置表'; INSERT INTO sys_config VALUES(1, '主框架页-默认皮肤样式名称', 'sys.index.skinName', 'skin-blue', 'Y', 'admin', SYSDATE(), '', NULL, '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow' ); INSERT INTO sys_config VALUES(2, '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', 'admin', SYSDATE(), '', NULL, '初始化密码 123456' ); INSERT INTO sys_config VALUES(3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', SYSDATE(), '', NULL, '深色主题theme-dark,浅色主题theme-light' ); INSERT INTO sys_config VALUES(4, '账号自助-验证码开关', 'sys.account.captchaEnabled', 'true', 'Y', 'admin', SYSDATE(), '', NULL, '是否开启验证码功能(true开启,false关闭)'); INSERT INTO sys_config VALUES(5, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', 'false', 'Y', 'admin', SYSDATE(), '', NULL, '是否开启注册用户功能(true开启,false关闭)'); INSERT INTO sys_config VALUES(6, '用户登录-黑名单列表', 'sys.login.blackIPList', '', 'Y', 'admin', SYSDATE(), '', NULL, '设置登录IP黑名单限制,多个匹配项以;分隔,支持匹配(*通配、网段)'); INSERT INTO sys_config VALUES(7, '用户管理-初始密码修改策略', 'sys.account.initPasswordModify', '1', 'Y', 'admin', SYSDATE(), '', NULL, '0:初始密码修改策略关闭,没有任何提示,1:提醒用户,如果未修改初始密码,则在登录时就会提醒修改密码对话框'); INSERT INTO sys_config VALUES(8, '用户管理-账号密码更新周期', 'sys.account.passwordValidateDays', '0', 'Y', 'admin', SYSDATE(), '', NULL, '密码更新周期(填写数字,数据初始化值为0不限制,若修改必须为大于0小于365的正整数),如果超过这个周期登录系统时,则在登录时就会提醒修改密码对话框'); INSERT INTO sys_config VALUES(9, '用户管理-密码字符范围', 'sys.account.chrtype', '0', 'Y', 'admin', SYSDATE(), '', NULL, '默认任意字符范围,0任意(密码可以输入任意字符),1数字(密码只能为0-9数字),2英文字母(密码只能为a-z和A-Z字母),3字母和数字(密码必须包含字母,数字),4字母数字和特殊字符(目前支持的特殊字符包括:~!@#$%^&*()-=_+)'); -- ---------------------------- -- 14、系统访问记录 -- ---------------------------- DROP TABLE IF EXISTS sys_logininfor; CREATE TABLE sys_logininfor ( info_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '访问ID', user_name VARCHAR(50) DEFAULT '' COMMENT '用户账号', ipaddr VARCHAR(128) DEFAULT '' COMMENT '登录IP地址', login_location VARCHAR(255) DEFAULT '' COMMENT '登录地点', browser VARCHAR(50) DEFAULT '' COMMENT '浏览器类型', os VARCHAR(50) DEFAULT '' COMMENT '操作系统', STATUS CHAR(1) DEFAULT '0' COMMENT '登录状态(0成功 1失败)', msg VARCHAR(255) DEFAULT '' COMMENT '提示消息', login_time DATETIME COMMENT '访问时间', PRIMARY KEY (info_id), KEY idx_sys_logininfor_s (STATUS), KEY idx_sys_logininfor_lt (login_time) ) ENGINE=INNODB AUTO_INCREMENT=100 COMMENT = '系统访问记录'; -- ---------------------------- -- 15、定时任务调度表 -- ---------------------------- DROP TABLE IF EXISTS sys_job; CREATE TABLE sys_job ( job_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '任务ID', job_name VARCHAR(64) DEFAULT '' COMMENT '任务名称', job_group VARCHAR(64) DEFAULT 'DEFAULT' COMMENT '任务组名', invoke_target VARCHAR(500) NOT NULL COMMENT '调用目标字符串', cron_expression VARCHAR(255) DEFAULT '' COMMENT 'cron执行表达式', misfire_policy VARCHAR(20) DEFAULT '3' COMMENT '计划执行错误策略(1立即执行 2执行一次 3放弃执行)', CONCURRENT CHAR(1) DEFAULT '1' COMMENT '是否并发执行(0允许 1禁止)', STATUS CHAR(1) DEFAULT '0' COMMENT '状态(0正常 1暂停)', create_by VARCHAR(64) DEFAULT '' COMMENT '创建者', create_time DATETIME COMMENT '创建时间', update_by VARCHAR(64) DEFAULT '' COMMENT '更新者', update_time DATETIME COMMENT '更新时间', remark VARCHAR(500) DEFAULT '' COMMENT '备注信息', PRIMARY KEY (job_id, job_name, job_group) ) ENGINE=INNODB AUTO_INCREMENT=100 COMMENT = '定时任务调度表'; INSERT INTO sys_job VALUES(1, '系统默认(无参)', 'DEFAULT', 'ryTask.ryNoParams', '0/10 * * * * ?', '3', '1', '1', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_job VALUES(2, '系统默认(有参)', 'DEFAULT', 'ryTask.ryParams(\'ry\')', '0/15 * * * * ?', '3', '1', '1', 'admin', SYSDATE(), '', NULL, ''); INSERT INTO sys_job VALUES(3, '系统默认(多参)', 'DEFAULT', 'ryTask.ryMultipleParams(\'ry\', true, 2000L, 316.50D, 100)', '0/20 * * * * ?', '3', '1', '1', 'admin', SYSDATE(), '', NULL, ''); -- ---------------------------- -- 16、定时任务调度日志表 -- ---------------------------- DROP TABLE IF EXISTS sys_job_log; CREATE TABLE sys_job_log ( job_log_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '任务日志ID', job_name VARCHAR(64) NOT NULL COMMENT '任务名称', job_group VARCHAR(64) NOT NULL COMMENT '任务组名', invoke_target VARCHAR(500) NOT NULL COMMENT '调用目标字符串', job_message VARCHAR(500) COMMENT '日志信息', STATUS CHAR(1) DEFAULT '0' COMMENT '执行状态(0正常 1失败)', exception_info VARCHAR(2000) DEFAULT '' COMMENT '异常信息', start_time DATETIME COMMENT '执行开始时间', end_time DATETIME COMMENT '执行结束时间', create_time DATETIME COMMENT '创建时间', PRIMARY KEY (job_log_id) ) ENGINE=INNODB COMMENT = '定时任务调度日志表'; -- ---------------------------- -- 17、通知公告表 -- ---------------------------- DROP TABLE IF EXISTS sys_notice; CREATE TABLE sys_notice ( notice_id INT(4) NOT NULL AUTO_INCREMENT COMMENT '公告ID', notice_title VARCHAR(50) NOT NULL COMMENT '公告标题', notice_type CHAR(1) NOT NULL COMMENT '公告类型(1通知 2公告)', notice_content LONGBLOB DEFAULT NULL COMMENT '公告内容', STATUS CHAR(1) DEFAULT '0' COMMENT '公告状态(0正常 1关闭)', create_by VARCHAR(64) DEFAULT '' COMMENT '创建者', create_time DATETIME COMMENT '创建时间', update_by VARCHAR(64) DEFAULT '' COMMENT '更新者', update_time DATETIME COMMENT '更新时间', remark VARCHAR(255) DEFAULT NULL COMMENT '备注', PRIMARY KEY (notice_id) ) ENGINE=INNODB AUTO_INCREMENT=10 COMMENT = '通知公告表'; -- ---------------------------- -- 初始化-公告信息表数据 -- ---------------------------- INSERT INTO sys_notice VALUES('1', '温馨提醒:2018-07-01 若依新版本发布啦', '2', '新版本内容', '0', 'admin', SYSDATE(), '', NULL, '管理员'); INSERT INTO sys_notice VALUES('2', '维护通知:2018-07-01 若依系统凌晨维护', '1', '维护内容', '0', 'admin', SYSDATE(), '', NULL, '管理员'); INSERT INTO sys_notice VALUES('3', '若依开源框架介绍', '1', '

项目介绍

RuoYi开源项目是为企业用户定制的后台脚手架框架,为企业打造的一站式解决方案,降低企业开发成本,提升开发效率。主要包括用户管理、角色管理、部门管理、菜单管理、参数管理、字典管理、岗位管理、定时任务服务监控、登录日志、操作日志、代码生成等功能。其中,还支持多数据源、数据权限、国际化、Redis缓存、Docker部署、滑动验证码、第三方认证登录、分布式事务、分布式文件存储、分库分表处理等技术特点。


官网及演示

若依官网地址: http://ruoyi.vip

若依文档地址: http://doc.ruoyi.vip

演示地址【不分离版】: http://demo.ruoyi.vip

演示地址【分离版本】: http://vue.ruoyi.vip

演示地址【微服务版】: http://cloud.ruoyi.vip

演示地址【移动端版】: http://h5.ruoyi.vip


', '0', 'admin', SYSDATE(), '', NULL, '管理员'); -- ---------------------------- -- 18、公告已读记录表 -- ---------------------------- DROP TABLE IF EXISTS sys_notice_read; CREATE TABLE sys_notice_read ( read_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '已读主键', notice_id INT(4) NOT NULL COMMENT '公告id', user_id BIGINT(20) NOT NULL COMMENT '用户id', read_time DATETIME NOT NULL COMMENT '阅读时间', PRIMARY KEY (read_id), UNIQUE KEY uk_user_notice (user_id, notice_id) COMMENT '同一用户同一公告只记录一次' ) ENGINE=INNODB AUTO_INCREMENT=1 COMMENT='公告已读记录表'; -- ---------------------------- -- 19、代码生成业务表 -- ---------------------------- DROP TABLE IF EXISTS gen_table; CREATE TABLE gen_table ( table_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '编号', table_name VARCHAR(200) DEFAULT '' COMMENT '表名称', table_comment VARCHAR(500) DEFAULT '' COMMENT '表描述', sub_table_name VARCHAR(64) DEFAULT NULL COMMENT '关联子表的表名', sub_table_fk_name VARCHAR(64) DEFAULT NULL COMMENT '子表关联的外键名', class_name VARCHAR(100) DEFAULT '' COMMENT '实体类名称', tpl_category VARCHAR(200) DEFAULT 'crud' COMMENT '使用的模板(crud单表操作 tree树表操作)', tpl_web_type VARCHAR(30) DEFAULT '' COMMENT '前端模板类型(element-ui模版 element-plus模版)', package_name VARCHAR(100) COMMENT '生成包路径', module_name VARCHAR(30) COMMENT '生成模块名', business_name VARCHAR(30) COMMENT '生成业务名', function_name VARCHAR(50) COMMENT '生成功能名', function_author VARCHAR(50) COMMENT '生成功能作者', form_col_num INT(1) DEFAULT 1 COMMENT '表单布局(单列 双列 三列)', gen_type CHAR(1) DEFAULT '0' COMMENT '生成代码方式(0zip压缩包 1自定义路径)', gen_path VARCHAR(200) DEFAULT '/' COMMENT '生成路径(不填默认项目路径)', OPTIONS VARCHAR(1000) COMMENT '其它生成选项', create_by VARCHAR(64) DEFAULT '' COMMENT '创建者', create_time DATETIME COMMENT '创建时间', update_by VARCHAR(64) DEFAULT '' COMMENT '更新者', update_time DATETIME COMMENT '更新时间', remark VARCHAR(500) DEFAULT NULL COMMENT '备注', PRIMARY KEY (table_id) ) ENGINE=INNODB AUTO_INCREMENT=1 COMMENT = '代码生成业务表'; -- ---------------------------- -- 20、代码生成业务表字段 -- ---------------------------- DROP TABLE IF EXISTS gen_table_column; CREATE TABLE gen_table_column ( column_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '编号', table_id BIGINT(20) COMMENT '归属表编号', column_name VARCHAR(200) COMMENT '列名称', column_comment VARCHAR(500) COMMENT '列描述', column_type VARCHAR(100) COMMENT '列类型', java_type VARCHAR(500) COMMENT 'JAVA类型', java_field VARCHAR(200) COMMENT 'JAVA字段名', is_pk CHAR(1) COMMENT '是否主键(1是)', is_increment CHAR(1) COMMENT '是否自增(1是)', is_required CHAR(1) COMMENT '是否必填(1是)', is_insert CHAR(1) COMMENT '是否为插入字段(1是)', is_edit CHAR(1) COMMENT '是否编辑字段(1是)', is_list CHAR(1) COMMENT '是否列表字段(1是)', is_query CHAR(1) COMMENT '是否查询字段(1是)', query_type VARCHAR(200) DEFAULT 'EQ' COMMENT '查询方式(等于、不等于、大于、小于、范围)', html_type VARCHAR(200) COMMENT '显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)', dict_type VARCHAR(200) DEFAULT '' COMMENT '字典类型', sort INT COMMENT '排序', create_by VARCHAR(64) DEFAULT '' COMMENT '创建者', create_time DATETIME COMMENT '创建时间', update_by VARCHAR(64) DEFAULT '' COMMENT '更新者', update_time DATETIME COMMENT '更新时间', PRIMARY KEY (column_id) ) ENGINE=INNODB AUTO_INCREMENT=1 COMMENT = '代码生成业务表字段'; ``` 用于演示在项目 P03 ![image-20260713154541810](assets/image-20260713154541810.png) ## 编写MyBaits在代码 - 添加依赖(jar) - Mybatis - 数据库驱动 - mysql-connector-java mysql-connector-C - mysql-connector-j (8.0.30) mysql-connector-c 新在版本 - 总在配置文件 SQLMapConfig.xml - 数据源 - 自定义在Mapper(User.xml) - 使用配置文件创建SQLSessionFactory对象 - SQLSessionFactoryBuilder 加载配置文件 - SQLSession 调用各种CRUD - 调用不同在语句块 - 编写User.xml - 各种SQL语句 User.xml ```xml ``` 核心配置文件 ```xml ``` ![image-20260713161009796](assets/image-20260713161009796.png) ## 单元测试 ```java package com.neuedu.nxu; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.Map; public class MyBaitsTest { @Test public void test() throws IOException { String resource = "SqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); //重量级的对象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); int id = 1 ; Map user = sqlSession.selectOne("User.selectList",id); //查询数据的 System.out.println("user = " + user); sqlSession.close(); } } ``` ## 常见的 CRUD ### 工具封装 ```java package com.neuedu.nxu.util; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException; import java.io.InputStream; public class MyBatisUtil { public static SqlSessionFactory sqlSessionFactory; /** * 全局唯一的 SqlSessionFactory * @return * @throws IOException */ public static synchronized SqlSessionFactory getSqlSessionFactory() throws IOException { if(sqlSessionFactory == null){ String resource = "SqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } //重量级的对象 return sqlSessionFactory; } } ``` ### User.xml ```xml INSERT INTO `ry`.`sys_user` ( `dept_id`, `user_name`, `nick_name`, `user_type`, `email`, `phonenumber`, `sex`, `password`, `status` ) VALUES ( #{deptId}, #{userName}, #{nickName}, #{userType}, #{email}, #{phonenumber}, #{sex}, #{password}, #{status} ) ; UPDATE `sys_user` SET `dept_id` = #{dept_id}, `user_name` = #{user_name}, `nick_name` = #{nick_name}, `user_type` = #{user_type}, `email` = #{email}, `phonenumber` = #{phonenumber}, `sex` = #{sex}, `avatar` = #{avatar}, `password` = #{password}, `status` = #{status}, `del_flag` = #{del_flag}, `login_ip` = #{login_ip}, `login_date` = #{login_date}, `pwd_update_date` = #{pwd_update_date}, `create_by` = #{create_by}, `create_time` = #{create_time}, `update_by` = #{update_by}, `update_time` = #{update_time}, `remark` = #{remark} WHERE `user_id` = #{user_id} delete from sys_user where user_id = #{id} ``` ### 单元测试 ```java package com.neuedu.nxu; import nxu.com.neuedu.nxu.MyBatisUtil; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.List; import java.util.Map; public class MyBaitsTest { private SqlSessionFactory sqlSessionFactory; @Before public void setUp() throws Exception { sqlSessionFactory = MyBatisUtil.getSqlSessionFactory(); } @Test public void test() throws IOException { SqlSession sqlSession = sqlSessionFactory.openSession(); int id = 1 ; Map user = sqlSession.selectOne("User.selectOne",id); //查询数据的 System.out.println("user = " + user); sqlSession.close(); } @Test public void testList() throws IOException { SqlSession sqlSession = sqlSessionFactory.openSession(); int id = 1 ; List list = sqlSession.selectList("User.selectList"); //查询数据的 list.forEach(System.out::println); sqlSession.close(); } @Test public void testInsert() throws IOException { SqlSession sqlSession = sqlSessionFactory.openSession(); Map user = new HashMap(); user.put("deptId",1); user.put("userName","super"); user.put("nickName","医生"); user.put("userType","00"); user.put("phonenumber","super"); user.put("sex","1"); user.put("email","abc@neuedu.com"); user.put("password","123456"); user.put("status","0"); try{ int count = sqlSession.insert("User.insert",user); //查询数据的 System.out.println("count = " + count); sqlSession.commit(); }catch (Exception e){ e.printStackTrace(); sqlSession.rollback(); }finally { sqlSession.close(); } } @Test public void testUpdate() throws IOException { SqlSession sqlSession = sqlSessionFactory.openSession(); try{ int id = 100 ; Map user = sqlSession.selectOne("User.selectOne",id); System.out.println(user); user.put("user_name","superadmin"); int updateCount = sqlSession.update("User.updateById", user); //更新的条数 System.out.println("updateCount = " + updateCount); sqlSession.commit(); }catch (Exception e){ e.printStackTrace(); sqlSession.rollback(); }finally { sqlSession.close(); } } @Test public void testDelete() throws IOException { SqlSession sqlSession = sqlSessionFactory.openSession(); try{ int id = 100 ; int deleteCount = sqlSession.delete("User.deleteById", id); //更新的条数 System.out.println("deleteCount = " + deleteCount); sqlSession.commit(); }catch (Exception e){ e.printStackTrace(); sqlSession.rollback(); }finally { sqlSession.close(); } } } ``` ## 使用实体类作为参数和返回结果 ### User.java ```java package com.neuedu.nxu.entity; import java.util.Date; public class User { private Integer userId; private String deptId; private String userName; private String nickName; private String userType; private String email; private String phonenumber; private String sex; private String password; private String status; private String delFlag ; private String loginIp; private Date loginDate; private String pwdUpdateDate; private String createBy; private Date createTime; private String updateBy; private Date updateTime; private String remark; public User() { } public User(Integer userId, String deptId, String userName, String nickName, String userType, String email, String phonenumber, String sex, String password, String status, String delFlag, String loginIp, Date loginDate, String pwdUpdateDate, String createBy, Date createTime, String updateBy, Date updateTime, String remark) { this.userId = userId; this.deptId = deptId; this.userName = userName; this.nickName = nickName; this.userType = userType; this.email = email; this.phonenumber = phonenumber; this.sex = sex; this.password = password; this.status = status; this.delFlag = delFlag; this.loginIp = loginIp; this.loginDate = loginDate; this.pwdUpdateDate = pwdUpdateDate; this.createBy = createBy; this.createTime = createTime; this.updateBy = updateBy; this.updateTime = updateTime; this.remark = remark; } public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getDeptId() { return deptId; } public void setDeptId(String deptId) { this.deptId = deptId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getNickName() { return nickName; } public void setNickName(String nickName) { this.nickName = nickName; } public String getUserType() { return userType; } public void setUserType(String userType) { this.userType = userType; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPhonenumber() { return phonenumber; } public void setPhonenumber(String phonenumber) { this.phonenumber = phonenumber; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public String getDelFlag() { return delFlag; } public void setDelFlag(String delFlag) { this.delFlag = delFlag; } public String getLoginIp() { return loginIp; } public void setLoginIp(String loginIp) { this.loginIp = loginIp; } public Date getLoginDate() { return loginDate; } public void setLoginDate(Date loginDate) { this.loginDate = loginDate; } public String getPwdUpdateDate() { return pwdUpdateDate; } public void setPwdUpdateDate(String pwdUpdateDate) { this.pwdUpdateDate = pwdUpdateDate; } public String getCreateBy() { return createBy; } public void setCreateBy(String createBy) { this.createBy = createBy; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } public String getUpdateBy() { return updateBy; } public void setUpdateBy(String updateBy) { this.updateBy = updateBy; } public Date getUpdateTime() { return updateTime; } public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } @Override public String toString() { return "User{" + "userId=" + userId + ", deptId='" + deptId + '\'' + ", userName='" + userName + '\'' + ", nickName='" + nickName + '\'' + ", userType='" + userType + '\'' + ", email='" + email + '\'' + ", phonenumber='" + phonenumber + '\'' + ", sex='" + sex + '\'' + ", password='" + password + '\'' + ", status='" + status + '\'' + ", delFlag='" + delFlag + '\'' + ", loginIp='" + loginIp + '\'' + ", loginDate=" + loginDate + ", pwdUpdateDate='" + pwdUpdateDate + '\'' + ", createBy='" + createBy + '\'' + ", createTime=" + createTime + ", updateBy='" + updateBy + '\'' + ", updateTime=" + updateTime + ", remark='" + remark + '\'' + '}'; } } ``` ### User.xml ```xml INSERT INTO `ry`.`sys_user` ( `dept_id`, `user_name`, `nick_name`, `user_type`, `email`, `phonenumber`, `sex`, `password`, `status` ) VALUES ( #{deptId}, #{userName}, #{nickName}, #{userType}, #{email}, #{phonenumber}, #{sex}, #{password}, #{status} ) ; UPDATE `sys_user` SET `dept_id` = #{deptId}, `user_name` = #{userName}, `nick_name` = #{nickName}, `user_type` = #{userType}, `email` = #{email}, `phonenumber` = #{phonenumber}, `sex` = #{sex}, `avatar` = #{avatar}, `password` = #{password}, `status` = #{status}, `del_flag` = #{delFlag}, `login_ip` = #{loginIp}, `login_date` = #{loginDate}, `pwd_update_date` = #{pwdUpdateDate}, `create_by` = #{createBy}, `create_time` = #{createTime}, `update_by` = #{updateBy}, `update_time` = #{updateTime}, `remark` = #{remark} WHERE `user_id` = #{userId} delete from sys_user where user_id = #{id} ``` ### 单元测试 ```java package com.neuedu.nxu; import entity.nxu.com.neuedu.nxu.User; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; public class MyBaitsTest { private SqlSessionFactory sqlSessionFactory; @Before public void setUp() throws Exception { sqlSessionFactory = MyBatisUtil.getSqlSessionFactory(); } @Test public void test() throws IOException { SqlSession sqlSession = sqlSessionFactory.openSession(); int id = 1 ; User user = sqlSession.selectOne("User.selectOne",id); //查询数据的 System.out.println("user = " + user); sqlSession.close(); } @Test public void testList() throws IOException { SqlSession sqlSession = sqlSessionFactory.openSession(); int id = 1 ; List list = sqlSession.selectList("User.selectList"); //查询数据的 list.forEach(System.out::println); sqlSession.close(); } @Test public void testInsert() throws IOException { SqlSession sqlSession = sqlSessionFactory.openSession(); // Map user = new HashMap(); // user.put("deptId",1); // user.put("userName","super"); // user.put("nickName","医生"); // user.put("userType","00"); // user.put("phonenumber","super"); // user.put("sex","1"); // user.put("email","abc@neuedu.com"); // user.put("password","123456"); // user.put("status","0"); User user = new User(); user.setDeptId("100"); user.setUserName("super"); user.setPassword("123456"); user.setNickName("super"); user.setUserType("00"); user.setSex("1"); user.setEmail("abc@eqq.com"); user.setStatus("1"); try{ int count = sqlSession.insert("User.insert",user); //查询数据的 System.out.println("count = " + count); sqlSession.commit(); }catch (Exception e){ e.printStackTrace(); sqlSession.rollback(); }finally { sqlSession.close(); } } @Test public void testUpdate() throws IOException { SqlSession sqlSession = sqlSessionFactory.openSession(); try{ int id = 100 ; User user = sqlSession.selectOne("User.selectOne",id); user.setUserName("superadmin"); int updateCount = sqlSession.update("User.updateById", user); //更新的条数 System.out.println("updateCount = " + updateCount); sqlSession.commit(); }catch (Exception e){ e.printStackTrace(); sqlSession.rollback(); }finally { sqlSession.close(); } } @Test public void testDelete() throws IOException { SqlSession sqlSession = sqlSessionFactory.openSession(); try{ int id = 101 ; int deleteCount = sqlSession.delete("User.deleteById", id); //更新的条数 System.out.println("deleteCount = " + deleteCount); sqlSession.commit(); }catch (Exception e){ e.printStackTrace(); sqlSession.rollback(); }finally { sqlSession.close(); } } } ``` 三层架构 ## MVC架构(Mapper) 单体系统中的架构 - Controller Service Dao - 使用MyBatis 封装下 Dao 使用Mapper自动生成Dao的代理对象 - 接口中的方法名称 要求跟 xml中 ID相同 - namespace 就是 接口的名称 (Mapper的全限定名) - 如果使用package的方式注册 包路径要求一致 ![image-20260714092928154](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20260714092928154.png) ![image-20260714092951923](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20260714092951923.png) ## 带条件查询 动态SQL - if ## 动态 SQL 参考 网站: https://mybatis.p2hp.com/dynamic-sql.html 动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。 编程 使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。 如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。 - if - choose (when, otherwise) - trim (where, set) - foreach ### if 使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分。比如: ``` ``` 这条语句提供了可选的查找文本功能。如果不传入 “title”,那么所有处于 “ACTIVE” 状态的 BLOG 都会返回;如果传入了 “title” 参数,那么就会对 “title” 一列进行模糊查找并返回对应的 BLOG 结果(细心的读者可能会发现,“title” 的参数值需要包含查找掩码或通配符字符)。 如果希望通过 “title” 和 “author” 两个参数进行可选搜索该怎么办呢?首先,我想先将语句名称修改成更名副其实的名称;接下来,只需要加入另一个条件即可。 ``` ``` ## 集成SpringBoot ![image-20260714105206031](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20260714105206031.png) - springboot 项目 - starter-web - 搭建mybaits zheng - 集成 - 让SpringBoot(IOC容器)管理 所有的Mapper层的注册 ### 整合MyBaits 帮我们在容器中注册 SQlSessionFactory、Session、自动注册所有的Mapper ``` 4.0.0 com.neuedu nxu 1.0 com.neuedu.boot p04-springboot-mybatis 0.0.1 p04-springboot-mybatis 21 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test org.mybatis.spring.boot mybatis-spring-boot-starter 3.0.5 compile com.mysql mysql-connector-j com.neuedu p-common 1.0 org.springframework.boot spring-boot-maven-plugin ``` ![image-20260714105945674](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20260714105945674.png) ### 配置数据源 在application.yaml(properties) 还需要配置mapper的映射 ``` server: port: 8080 ## 配置数据源信息 spring: datasource: username: root password: root url: jdbc:mysql://localhost:3306/ry driver-class-name: com.mysql.cj.jdbc.Driver ## 配置mapper映射文件路径 mybatis: mapper-locations: classpath:com/neuedu/nxu/mapper/*.xml ``` 编写Mapper.java、Mapper.xml(复制的上一个项目) ![image-20260714111347561](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20260714111347561.png) ### 在IOC中注册 Mapper 在Spring Boot的启动类上添加 @MapperScan ```java package com.neuedu.nxu; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Hello world! * */ @SpringBootApplication //在Spring容器中 生命 所有Mapper的代理对象 @MapperScan("com.neuedu.nxu.mapper") public class BootMybaitsApp { public static void main( String[] args ) { SpringApplication.run(BootMybaitsApp.class,args); } } ``` ### 单元测试 ```java package com.neuedu.nxu.mapper; import nxu.com.neuedu.nxu.BootMybaitsApp; import entity.nxu.nxu.com.neuedu.nxu.User; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.List; import static org.junit.jupiter.api.Assertions.*; @SpringBootTest(classes = BootMybaitsApp.class) class UserMapperTest { @Autowired private UserMapper userMapper; @Test void selectList() { System.out.println("userMapper = " + userMapper); User user = new User(); user.setUserName("ad"); List users = userMapper.selectList(user); users.forEach(System.out::println); } } ``` ## 分页查询 通过在 SQL 添加 limit (基于MySQL) 分页分析: ```sql -- total 总条数() -- size 每页分多少条 5/页 10/页 -- current: 当前页号 1 、2 3 -- pages 总页数 假如total 18 size:5 18/5 约等于 4 -- size : 3 -- current 1 2 3 -- start(current-1)*size 0 3 6 SELECT * FROM 表 LIMIT START ,size SELECT * FROM sys_dept LIMIT 0,3; SELECT * FROM sys_dept LIMIT 3,3; -- 分页的SQL SELECT * FROM( SELECT * FROM sys_dept ) t LIMIT 0 ,3 ``` ### 使用PageHelper分页插件 - 添加依赖 - 编写代码 - 注册分页插件 - 使用分页插件 - 配置分页数据 PageHelper.startPage(1,10) - 调用查询方法 - 获取分页数据 ```xml 4.0.0 com.neuedu nxu 1.0 com.neuedu.boot p04-springboot-mybatis 0.0.1 p04-springboot-mybatis 21 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test org.mybatis.spring.boot mybatis-spring-boot-starter 3.0.5 compile com.github.pagehelper pagehelper-spring-boot-starter 4.1.1 compile com.mysql mysql-connector-j com.neuedu p-common 1.0 org.springframework.boot spring-boot-maven-plugin ``` 分页查询 ```java @Test void selectListPage() { Page page = PageHelper.startPage(1, 2); List users = userMapper.selectList(null); //分页数据 List result = page.getResult(); long total = page.getTotal(); int pageNum = page.getPageNum(); int pageSize = page.getPageSize(); int pages = page.getPages(); System.out.println("result = " + result); System.out.println("total = " + total); System.out.println("pageNum = " + pageNum); System.out.println("pageSize = " + pageSize); System.out.println("pages = " + pages); System.out.println("============================================================="); System.out.println("============================================================="); System.out.println("============================================================="); System.out.println("============================================================="); page = PageHelper.startPage(2, 2); users = userMapper.selectList(null); //分页数据 result = page.getResult(); total = page.getTotal(); pageNum = page.getPageNum(); pageSize = page.getPageSize(); pages = page.getPages(); System.out.println("result = " + result); System.out.println("total = " + total); System.out.println("pageNum = " + pageNum); System.out.println("pageSize = " + pageSize); System.out.println("pages = " + pages); } ``` # MyBaitsPlus 官网: baomidou.com ## 搭建入门环境 创建SPringBoot项目 Boot 通用的配置: https://docs.spring.io/spring-boot/3.5/appendix/application-properties/index.html 整合Plus - 添加依赖 - ### 依赖 ```xml com.baomidou mybatis-plus-spring-boot3-starter 3.5.17 com.mysql mysql-connector-j ``` ### 配置数据源 ```yaml server: port: 8080 servlet: # http://localhost:8080/api context-path: /api spring: # 配置数据源 datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/ry username: root password: root ``` ### 编写实体类 需要添加MP的注解 ```java package com.neuedu.nxu.entity; import com.baomidou.mybatisplus.annotation.TableName; import java.util.Date; //根据 sys_user生成CRUD @TableName("sys_user") public class User { private Integer userId; private String deptId; private String userName; private String nickName; private String userType; private String email; private String phonenumber; private String sex; private String avatar; private String password; private String status; private String delFlag ; private String loginIp; private Date loginDate; private String pwdUpdateDate; private String createBy; private Date createTime; private String updateBy; private Date updateTime; private String remark; public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getDeptId() { return deptId; } public void setDeptId(String deptId) { this.deptId = deptId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getNickName() { return nickName; } public void setNickName(String nickName) { this.nickName = nickName; } public String getUserType() { return userType; } public void setUserType(String userType) { this.userType = userType; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPhonenumber() { return phonenumber; } public void setPhonenumber(String phonenumber) { this.phonenumber = phonenumber; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAvatar() { return avatar; } public void setAvatar(String avatar) { this.avatar = avatar; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public String getDelFlag() { return delFlag; } public void setDelFlag(String delFlag) { this.delFlag = delFlag; } public String getLoginIp() { return loginIp; } public void setLoginIp(String loginIp) { this.loginIp = loginIp; } public Date getLoginDate() { return loginDate; } public void setLoginDate(Date loginDate) { this.loginDate = loginDate; } public String getPwdUpdateDate() { return pwdUpdateDate; } public void setPwdUpdateDate(String pwdUpdateDate) { this.pwdUpdateDate = pwdUpdateDate; } public String getCreateBy() { return createBy; } public void setCreateBy(String createBy) { this.createBy = createBy; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } public String getUpdateBy() { return updateBy; } public void setUpdateBy(String updateBy) { this.updateBy = updateBy; } public Date getUpdateTime() { return updateTime; } public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } @Override public String toString() { return "User{" + "userId=" + userId + ", deptId='" + deptId + '\'' + ", userName='" + userName + '\'' + ", nickName='" + nickName + '\'' + ", userType='" + userType + '\'' + ", email='" + email + '\'' + ", phonenumber='" + phonenumber + '\'' + ", sex='" + sex + '\'' + ", avatar='" + avatar + '\'' + ", password='" + password + '\'' + ", status='" + status + '\'' + ", delFlag='" + delFlag + '\'' + ", loginIp='" + loginIp + '\'' + ", loginDate=" + loginDate + ", pwdUpdateDate='" + pwdUpdateDate + '\'' + ", createBy='" + createBy + '\'' + ", createTime=" + createTime + ", updateBy='" + updateBy + '\'' + ", updateTime=" + updateTime + ", remark='" + remark + '\'' + '}'; } } ``` ### 编写UserMapper ```java package com.neuedu.nxu.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.neuedu.nxu.entity.User; public interface UserMapper extends BaseMapper { } ``` ### 在IOC容器中注册 Mapper ```java package com.neuedu.nxu; import com.neuedu.nxu.entity.User; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Hello world! * */ @SpringBootApplication @MapperScan("com.neuedu.nxu.mapper") public class MyBatisPlusApp { public static void main( String[] args ) { SpringApplication.run(MyBatisPlusApp.class,args); } } ``` ## 单元测试 ```java package com.neuedu.nxu.mapper; import com.neuedu.nxu.entity.User; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.List; import static org.junit.jupiter.api.Assertions.*; @SpringBootTest class UserMappeTest { @Autowired private UserMapper userMapper; @Test public void testSelectList(){ List users = userMapper.selectList(null); users.forEach(System.out::println); } } ``` ### 开启日志(打印SQL) ```yaml server: port: 8080 servlet: # http://localhost:8080/api context-path: /api spring: # 配置数据源 datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/ry username: root password: root logging: level: # 所有mapper 日志级别 使用DEBUG 打印SQL com.neuedu.nxu.mapper: DEBUG ``` ## 使用@TableId声明主键 ```java package com.neuedu.nxu.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import java.util.Date; //根据 sys_user生成CRUD @TableName("sys_user") public class User { @TableId(type= IdType.AUTO) private Integer userId; private String deptId; private String userName; private String nickName; private String userType; private String email; private String phonenumber; private String sex; private String avatar; private String password; private String status; private String delFlag ; private String loginIp; private Date loginDate; private String pwdUpdateDate; private String createBy; private Date createTime; private String updateBy; private Date updateTime; private String remark; public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getDeptId() { return deptId; } public void setDeptId(String deptId) { this.deptId = deptId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getNickName() { return nickName; } public void setNickName(String nickName) { this.nickName = nickName; } public String getUserType() { return userType; } public void setUserType(String userType) { this.userType = userType; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPhonenumber() { return phonenumber; } public void setPhonenumber(String phonenumber) { this.phonenumber = phonenumber; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAvatar() { return avatar; } public void setAvatar(String avatar) { this.avatar = avatar; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public String getDelFlag() { return delFlag; } public void setDelFlag(String delFlag) { this.delFlag = delFlag; } public String getLoginIp() { return loginIp; } public void setLoginIp(String loginIp) { this.loginIp = loginIp; } public Date getLoginDate() { return loginDate; } public void setLoginDate(Date loginDate) { this.loginDate = loginDate; } public String getPwdUpdateDate() { return pwdUpdateDate; } public void setPwdUpdateDate(String pwdUpdateDate) { this.pwdUpdateDate = pwdUpdateDate; } public String getCreateBy() { return createBy; } public void setCreateBy(String createBy) { this.createBy = createBy; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } public String getUpdateBy() { return updateBy; } public void setUpdateBy(String updateBy) { this.updateBy = updateBy; } public Date getUpdateTime() { return updateTime; } public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } @Override public String toString() { return "User{" + "userId=" + userId + ", deptId='" + deptId + '\'' + ", userName='" + userName + '\'' + ", nickName='" + nickName + '\'' + ", userType='" + userType + '\'' + ", email='" + email + '\'' + ", phonenumber='" + phonenumber + '\'' + ", sex='" + sex + '\'' + ", avatar='" + avatar + '\'' + ", password='" + password + '\'' + ", status='" + status + '\'' + ", delFlag='" + delFlag + '\'' + ", loginIp='" + loginIp + '\'' + ", loginDate=" + loginDate + ", pwdUpdateDate='" + pwdUpdateDate + '\'' + ", createBy='" + createBy + '\'' + ", createTime=" + createTime + ", updateBy='" + updateBy + '\'' + ", updateTime=" + updateTime + ", remark='" + remark + '\'' + '}'; } } ``` ## 使用MyBatisPlus提供的Service ## CRUD使用 参考 : https://baomidou.com/guides/data-interface/ ![image-20260714152317789](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20260714152317789.png) ## 条件构造器 参考: https://baomidou.com/guides/wrapper/ ![image-20260714154639629](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20260714154639629.png) ## 分页 添加分页插件的依赖 3.5.9 开始分页插件的需要单独的引用 ```xml com.baomidou mybatis-plus-jsqlparser ``` ## 配置插件 ```java package com.neuedu.nxu.config; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.springframework.beans.factory.annotation.Configurable; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MPConfig { /** * 添加分页插件 */ @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); //生成 MYSQL的 sql 分页 limit // top ... interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } } ``` ## 单元测试 ```java @Test public void testPage(){ Page page = new Page(1,2); userService.page(page); //获取分页数据 long current = page.getCurrent(); long size = page.getSize(); long total = page.getTotal(); long pages = page.getPages(); //数据 List records = page.getRecords(); System.out.println("current = " + current); System.out.println("size = " + size); System.out.println("total = " + total); System.out.println("pages = " + pages); System.out.println("records = " + records); System.out.println("=================================================================="); System.out.println("=================================================================="); System.out.println("=================================================================="); page = new Page(2,2); userService.page(page); //获取分页数据 current = page.getCurrent(); size = page.getSize(); total = page.getTotal(); pages = page.getPages(); //数据 records = page.getRecords(); System.out.println("current = " + current); //2 System.out.println("size = " + size); //2 System.out.println("total = " + total); // 3 System.out.println("pages = " + pages); // 2 System.out.println("records = " + records); //第二页的数据 } ``` ## 自动填充 文档: https://baomidou.com/guides/auto-fill-field/ ![image-20260714165025239](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20260714165025239.png) # Vue 官网: [Vue.js - 渐进式 JavaScript 框架 | Vue.js (vuejs.org)](https://cn.vuejs.org/) 课件: [01.初识Vue (yuque.com)](https://www.yuque.com/jshand/hrbu-edu/cp0kr908sgt47mwz) Vue (发音为 /vjuː/,类似 **view**) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。无论是简单还是复杂的界面,Vue 都可以胜任。 ![image-20260715082306023](assets/image-20260715082306023.png) ## 工具 - WebStrom - VSCODE 下载 [Download Visual Studio Code - Free AI Code Editor for Mac, Linux, Windows](https://code.visualstudio.com/Download?_exp_download=d53503e735) ![image-20260715082644360](assets/image-20260715082644360.png) ![image-20260715082721147](assets/image-20260715082721147.png) ![image-20260715082743636](assets/image-20260715082743636.png) ![image-20260715082945991](assets/image-20260715082945991.png) ## 入门环境搭建 - 使用script 引入 - 工程化 ![image-20260715083340937](assets/image-20260715083340937.png) ![image-20260715083415077](assets/image-20260715083415077.png) 编写入门代码: ```html Document
{{ message }}
``` 安装一个静态的服务器(开发服务器) 、使用IDEA内置的静态服务器打开 ![image-20260715090632693](assets/image-20260715090632693.png) 如果网络不同,可以下载**`vsix`** 离线安装 ![image-20260715090604188](assets/image-20260715090604188.png) ![image-20260715084507580](assets/image-20260715084507580.png) ## 使用内置的服务器预览 ![image-20260715090736243](assets/image-20260715090736243.png) ![image-20260715084520765](assets/image-20260715084520765.png) ## 基础语法 ### 属性绑定 [02.Vue基本语法 (yuque.com)](https://www.yuque.com/jshand/hrbu-edu/wkkn2glsvmlvsfbr#52e99e73) ### 事件绑定 ```html Document
内容: {{ message }}

``` ### 循环渲染 ```html Document
    中午饭的菜单
  • {{food}}

序号 id 姓名 年龄 爱好
{{i+1}} {{p.id}} {{p.name}} {{p.age}} {{`${j+1} ${fav}`}}

遍历对象

  • {{index}}--{{key}}: {{value}}
``` ### 综合案例 ```html Document
编号 姓名 年龄 操作
{{person.userId}} {{person.userName}} {{person.userAge}}

添加

姓名:
年龄:
{{form}}
``` ## 计算属性、Watch、表单绑定 ## 工程化开发 ### 工具的安装 - nvm ![image-20260715144756977](assets/image-20260715144756977.png) ![image-20260715144820354](assets/image-20260715144820354.png) ![image-20260715144842435](assets/image-20260715144842435.png) ![image-20260715144937898](assets/image-20260715144937898.png) 查看Node版本 ``` C:\Users\Administrator>nvm list available | CURRENT | LTS | OLD STABLE | OLD UNSTABLE | |--------------|--------------|--------------|--------------| | 26.5.0 | 24.18.0 | 0.12.18 | 0.11.16 | | 26.4.0 | 24.17.0 | 0.12.17 | 0.11.15 | | 26.3.1 | 24.16.0 | 0.12.16 | 0.11.14 | | 26.3.0 | 24.15.0 | 0.12.15 | 0.11.13 | | 26.2.0 | 24.14.1 | 0.12.14 | 0.11.12 | | 26.1.0 | 24.14.0 | 0.12.13 | 0.11.11 | | 26.0.0 | 24.13.1 | 0.12.12 | 0.11.10 | | 25.9.0 | 24.13.0 | 0.12.11 | 0.11.9 | | 25.8.2 | 24.12.0 | 0.12.10 | 0.11.8 | | 25.8.1 | 24.11.1 | 0.12.9 | 0.11.7 | | 25.8.0 | 24.11.0 | 0.12.8 | 0.11.6 | | 25.7.0 | 22.23.1 | 0.12.7 | 0.11.5 | | 25.6.1 | 22.23.0 | 0.12.6 | 0.11.4 | | 25.6.0 | 22.22.3 | 0.12.5 | 0.11.3 | | 25.5.0 | 22.22.2 | 0.12.4 | 0.11.2 | | 25.4.0 | 22.22.1 | 0.12.3 | 0.11.1 | | 25.3.0 | 22.22.0 | 0.12.2 | 0.11.0 | | 25.2.1 | 22.21.1 | 0.12.1 | 0.9.12 | | 25.2.0 | 22.21.0 | 0.12.0 | 0.9.11 | | 25.1.0 | 22.20.0 | 0.10.48 | 0.9.10 | This is a partial list. For a complete list, visit https://nodejs.org/en/download/releases C:\Users\Administrator> ``` ### 安装Node ``` C:\Users\Administrator>nvm install 24.18.0 Downloading node.js version 24.18.0 (64-bit)... Extracting node and npm... Complete Installation complete. If you want to use this version, type: nvm use 24.18.0 ``` ### 切换到该版本 ``` C:\Users\Administrator>nvm use 24.18.0 Now using node v24.18.0 (64-bit) C:\Users\Administrator>node --version v24.18.0 C:\Users\Administrator>npm --version 11.16.0 C:\Users\Administrator> ``` 配置镜像 ```shell npm config set registry https://registry.npmmirror.com ``` 配置完成在全局上会有一个配置文件 ~home/npmrc ### 创建Vue工程项目 npm create vue@latest ![image-20260715145642281](assets/image-20260715145642281.png) ![image-20260715145748569](assets/image-20260715145748569.png) ````shell C:\Users\Administrator\IdeaProjects\nxu>npm create vue@latest Need to install the following packages: create-vue@3.22.4 Ok to proceed? (y) > npx > create-vue T Vue.js - The Progressive JavaScript Framework | o 请输入项目名称: | vue-vite-ts | o 是否使用 TypeScript 语法? | Yes | o 请选择要包含的功能: (↑/↓ 切换,空格选择,a 全选,回车确认) | none | o 选择要包含的试验特性: (↑/↓ 切换,空格选择,a 全选,回车确认) | none | o 跳过所有示例代码,创建一个空白的 Vue 项目? | No 正在初始化项目 C:\Users\Administrator\IdeaProjects\nxu\vue-vite-ts... | — 项目初始化完成,可执行以下命令: cd vue-vite-ts npm install npm run dev | 可选:使用以下命令在项目目录中初始化 Git: git init && git add -A && git commit -m "initial commit" C:\Users\Administrator\IdeaProjects\nxu ```` 安装项目依赖 npm install 安装 尽量用镜像 ``` C:\Users\Administrator\IdeaProjects\nxu>cd vue-vite-ts C:\Users\Administrator\IdeaProjects\nxu\vue-vite-ts>npm install added 150 packages in 26s 36 packages are looking for funding run `npm fund` for details C:\Users\Administrator\IdeaProjects\nxu\vue-vite-ts> ``` 启动内置的开发服务器查看 ``` npm run dev ``` 基于vscode的插件 Vue ![image-20260715150308520](assets/image-20260715150308520.png) ### ref 和Reactive的区别 自动补全 ref类型数据的.value ![image-20260715154127022](assets/image-20260715154127022.png) ![image-20260715154103393](assets/image-20260715154103393.png) ### 创建代码片段 ![image-20260715155812248](assets/image-20260715155812248.png) ![image-20260715155858012](assets/image-20260715155858012.png) ``` { // Place your vue-vite-ts workspace snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and // description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope // is left empty or omitted, the snippet gets applied to all languages. The prefix is what is // used to trigger the snippet and the body will be expanded and inserted. Possible variables are: // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. // Placeholders with the same ids are connected. // Example: "创建Vue3": { "scope": "vue", "prefix": "log", "body": [ "", "", "" ], "description": "创建Vue3" } } ``` ### 自定义组件 ### 使用第三方的组件 ElementPlus(ElementUI --Vuejs 2.x ) ```shell C:\Users\Administrator\IdeaProjects\nxu\vue-vite-ts>npm install element-plus --save added 21 packages in 28s 40 packages are looking for funding run `npm fund` for details C:\Users\Administrator\IdeaProjects\nxu\vue-vite-ts> C:\Users\Administrator\IdeaProjects\nxu\vue-vite-ts> ``` #### 使用ElementPlus ``` // import './assets/main.css' import { createApp } from 'vue' import App from './App.vue' import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' const app = createApp(App) // 添加了一个ElementPlus插件 // app.use(ElementPlus,{ // size:'small' // }) app.use(ElementPlus) app.mount('#app') ``` ```vue ``` #### 使用容器组件 #### 表单 #### 表格 ## VueRouter路由 **[官网 | Vue Router](https://router.vuejs.org/zh/introduction.html)** - 安装路由 通过npm的方式安装 - 注册到app - 定义路由表 - 在App.vue定义站位 - 将写死的 Home,Login 组件替换成 动态的占位符 router-view ```shell C:\Users\Administrator\IdeaProjects\nxu\vue-vite-ts>npm install vue-router -S added 29 packages in 7s 50 packages are looking for funding run `npm fund` for details C:\Users\Administrator\IdeaProjects\nxu\vue-vite-ts> ``` 定义路由表 ```typescript import { createRouter, createWebHistory } from 'vue-router' import Home from "../views/home/index.vue"; import Login from "../views/login/index.vue"; const router = createRouter({ // 浏览器历史记录 history: createWebHistory(), routes: [ // { // path:'/home', // component:Home, // children:[ // { // path:'/home/user', // component:UserManager, // } // ] // }, { path: '/home', redirect: '/' }, { path: '/', component: Home, children: [ { path: '/user', // 只有使用的时候才会动态加载 component: () => import('../views/system/user/index.vue'), }, { path: '/dept', component: () => import('../views/system/dept/index.vue') , } ] }, { path: '/login', component: Login } ] }) //定义路由对象,在main.ts中注册 export default router; ``` 在main.ts中注册 ```ts // 重置样式,归零 import './assets/reset.css' import { createApp } from 'vue' import App from './App.vue' // import router from './router/index.ts' import router from './router' import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' const app = createApp(App) // 添加了一个ElementPlus插件 // app.use(ElementPlus,{ // size:'small' // }) //注册全局组件 app.use(router) app.use(ElementPlus) app.mount('#app') ``` 在App中使用一级路由 ```vue ``` 在Home中使用二级路由 ```vue ``` ## 登录组件 ![image-20260716091802751](assets/image-20260716091802751.png) ## router-路由守卫 # 使用Vue+Boot完成CRUD操作 ## 编写接口 ```java package com.neuedu.nxu.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.neuedu.nxu.entity.User; import com.neuedu.nxu.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; /*** * http * @param page * @return */ @RequestMapping("/page") Page page(Page page){ userService.page(page); return page; } /*** * http * @param user * @return */ @RequestMapping("/saveOrUpdate") boolean saveOrUpdate(@RequestBody User user){ return userService.saveOrUpdate(user); } /*** * http * @param id * @return */ @RequestMapping("/getById/{id}") User getById(@PathVariable Long id){ return userService.getById(id); } /*** * http * @param id * @return */ @RequestMapping("/removeById/{id}") boolean removeById(@PathVariable Long id){ return userService.removeById(id); } } ``` ![image-20260716112935147](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20260716112935147.png) ## 完成Vue整合 使用Axios组件完成网络请求: 参考: [起步 | Axios中文文档 | Axios中文网 (axios-http.cn)](https://www.axios-http.cn/docs/intro) 安装 npm install axios ## 跨域的解决方案 开发的环境 和 部署的环境应该是 ### 后端解决跨域 ![image-20260716113601917](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20260716113601917.png) ### 前端跨域 ![image-20260716113836057](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20260716113836057.png) ## User/index.vue(列表查询) ```vue ``` ![image-20260716114641637](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20260716114641637.png) ## 分页查询 ![image-20260716142724930](assets/image-20260716142724930.png) ## 添加功能 ![image-20260716150504478](assets/image-20260716150504478.png) ![image-20260716150527093](assets/image-20260716150527093.png) ## 删除修改 ![image-20260716153327766](assets/image-20260716153327766.png) ![image-20260716153346292](assets/image-20260716153346292.png) ## 封装Axios(API 请求 baseURL) ![image-20260716162642253](assets/image-20260716162642253.png) ![image-20260716162752467](assets/image-20260716162752467.png) # 登录 ## 使用JWT **JWT(JSON Web Token)** 一种基于 JSON 的开放标准([RFC 7519](https://zhida.zhihu.com/search?content_id=260899166&content_type=Article&match_order=1&q=RFC+7519&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3ODQzNjU1MzgsInEiOiJSRkMgNzUxOSIsInpoaWRhX3NvdXJjZSI6ImVudGl0eSIsImNvbnRlbnRfaWQiOjI2MDg5OTE2NiwiY29udGVudF90eXBlIjoiQXJ0aWNsZSIsIm1hdGNoX29yZGVyIjoxLCJ6ZF90b2tlbiI6bnVsbH0.l0RrsZ0-PnqxulU-1FbHnR6mA79sInufQXUoj9ezwpo&zhida_source=entity)),用于在各方之间安全地传递信息。 **特点** - **紧凑(Compact)**:可通过 URL、POST 参数或 HTTP 头传输 - **自包含(Self-contained)**:携带了用户的基本身份信息和声明(Claims) - **可验证(Verifiable)**:签名保证数据未被篡改 **典型场景**:用户登录后,服务器颁发一个 JWT,客户端每次请求都携带它,无需再查数据库做 Session 验证。 参考文档: [一文读懂 JWT(JSON Web Token) - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/1932939645169164990) ## 添加依赖 ``` com.auth0 java-jwt 4.5.2 compile ``` ### 生成jwt、解析jwt ```java package com.neuedu.nxu.util; import com.auth0.jwt.JWT; import com.auth0.jwt.JWTCreator; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.interfaces.DecodedJWT; import com.auth0.jwt.interfaces.Verification; import org.junit.jupiter.api.Test; public class JWTUtilTest { static String security = "123456789"; @Test public void createToken() { JWTCreator.Builder buidler = JWT.create(); buidler.withClaim("userId",100); buidler.withClaim("userName","admin"); String token = buidler.sign(Algorithm.HMAC256(security)); System.out.println("token = " + token); //eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEwMCwidXNlck5hbWUiOiJhZG1pbiJ9.S_Yvbdbd4fjETUlrCvlgedNhJFq7-0rGDv-F3zbX_G4 } @Test public void decodeToken() { // String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEwMCwidXNlck5hbWUiOiJhZG1pbiJ9.S_Yvbdbd4fjETUlrCvlgedNhJFq7-0rGDv-F3zbX_G4"; String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ8.eyJ1c2VySWQiOjEwMCwidXNlck5hbWUiOiJhZG1pbiJ9.S_Yvbdbd4fjETUlrCvlgedNhJFq7-0rGDv-F3zbX_G4"; Verification require = JWT.require(Algorithm.HMAC256(security)); try { DecodedJWT jwt = require.build().verify(token); System.out.println("解析成功"); }catch (Exception e) { System.out.println("Token 异常"); e.printStackTrace(); } } } ``` ![image-20260716171936793](assets/image-20260716171936793.png) ![image-20260716171957355](assets/image-20260716171957355.png) 将加密的 秘钥 配置到Spring的配置文件application.yaml中 ```yaml server: port: 8080 servlet: # http://localhost:8080/api context-path: /api spring: # 配置数据源 datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/ry username: root password: root logging: level: # 所有mapper 日志级别 使用DEBUG 打印SQL com.neuedu.nxu.mapper: DEBUG login: jwt: # 生成JWT的时候使用的秘钥 security: Yh2jAXrxyHKTWmEjeKu7 ``` ![image-20260717082049641](C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20260717082049641.png) ## 封装JWT工具 ```java package com.neuedu.nxu.util; import com.auth0.jwt.JWT; import com.auth0.jwt.JWTCreator; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.interfaces.Claim; import com.auth0.jwt.interfaces.DecodedJWT; import com.auth0.jwt.interfaces.Verification; import com.neuedu.nxu.entity.User; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.util.Map; @Component public class JWTUtils { @Value("${login.jwt.security}") private String security; /** * 生成Token * @param user * @return */ String encode(User user){ JWTCreator.Builder buidler = JWT.create(); //负载的信息 payload //Integer buidler.withClaim("userId",user.getUserId()); //String buidler.withClaim("userName",user.getUserName()); //生成Token String token = buidler.sign(Algorithm.HMAC256(security)); return token; } /** * 解析token * @param token * @return */ User decode(String token){ User user = null; Verification require = JWT.require(Algorithm.HMAC256(security)); try { DecodedJWT jwt = require.build().verify(token); //Token 是 合法的, 通过的验证 user = new User(); // 从token中获取数据 Map claims = jwt.getClaims(); int userId = claims.get("userId").asInt(); String userName = claims.get("userName").asString(); user.setUserId(userId); user.setUserName(userName); }catch (Exception e) { } return user; } } ``` ## 编写登录接口,返回Token ```java package com.neuedu.nxu.controller; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.neuedu.nxu.entity.User; import com.neuedu.nxu.service.UserService; import com.neuedu.nxu.util.JWTUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class LoginController { @Autowired private JWTUtils jwtUtils; @Autowired private UserService userService ; /** * 登录接口 * @param userName * @param password * @return */ @RequestMapping("/login") String login(String userName, String password) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(User::getUserName,userName); queryWrapper.eq(User::getPassword,password); User user = userService.getOne(queryWrapper); if(user == null){ throw new RuntimeException("用户名或者密码错误"); } String token = jwtUtils.encode(user); return token; } } ``` ## api/login/index.ts ```ts // 封装了 BaseURL的 axios import request from "@/utils/request.ts"; export function login(params:object){ let url = "/login" return request.get(url,{ params }); } ``` 前段使用login接口 ```vue ``` ## 登录操作,记录Token ![image-20260717084518746](assets/image-20260717084518746.png) ## 封装统一的返回格式 ```json { code: 200/500/404, msg: 错误消息, data: 接口返回的数据 (Object) } ``` ### 统一返回结果 ```java package com.neuedu.nxu.framework; /** * 通用的返回结果 */ public class Ret { Integer code; // 接口的响应状态 200 404 500 403 String message; T data; public Ret(Integer code, String message, T data) { this.code = code; this.message = message; this.data = data; } /** * 正常的响应结果 * @param data * @return * @param */ public static Ret ok(T data) { return new Ret(200, "success", data); } /** * 异常 * @param message * @return * @param */ public static Ret fail(String message) { return new Ret(500, message, null); } public static Ret fail() { return fail("接口异常,请联系管理人员"); } /** * url地址不正确, * @return * @param */ public static Ret notFound() { return new Ret<>(404,"路径不正确",null); } //未登录,token失效了 public static Ret noPermission() { return new Ret<>(403,"没有操作权限",null); } public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public T getData() { return data; } public void setData(T data) { this.data = data; } } ``` ![image-20260717090450848](assets/image-20260717090450848.png) ## 异常的处理 默认的错误页面 ![image-20260717090600725](assets/image-20260717090600725.png) ## 自定义全局异常处理器 ```java package com.neuedu.nxu.framework; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; //对Controller进行增强 @RestControllerAdvice public class ControllerExceptionHandler { @ExceptionHandler(Exception.class) public Ret handlerException(HttpServletRequest request, HttpServletResponse response, Exception e) throws Exception { return Ret.fail(e.getMessage()); } } ``` ![image-20260717090940945](assets/image-20260717090940945.png) ## 接口请求携带token ```ts // const baseUrl = "http://localhost:8080/api" import router from "@/router"; import axios from "axios"; import { ElNotification } from 'element-plus' const request = axios.create({ baseURL : 'http://localhost:8080/api' }); //拦截器 //1 请求拦截 // 添加请求拦截器 request.interceptors.request.use(function (config) { //获取登录时 的token,每次请求 携带 const token = window.localStorage.getItem('token'); if(token){ config.headers['token'] = token; } // 在发送请求之前做些什么 return config; }, function (error) { // 对请求错误做些什么 return Promise.reject(error); }); //2 响应结果的拦截 // 添加响应拦截器 request.interceptors.response.use(function (result) { // 2xx 范围内的状态码都会触发该函数。 const ret = result.data const {code,message,data} = ret; if(code === 200){ return data; }else if(code === 403){ ElNotification({ title: '错误', message: message||'接口异常', type: 'error', }) router.replace({ path:'/login' }) } else{ // alert('用户名或者密码不正确') ElNotification({ title: '错误', message: message||'接口异常', type: 'error', }) } // 对响应数据做点什么 return Promise.reject("接口调用失败"); }, function (error) { // 超出 2xx 范围的状态码都会触发该函数。 // 对响应错误做点什么 return Promise.reject(error); }); export default request; ``` ## 登录收尾 - 路由守卫 使用token验证 - 退出接口 # Agent 工具 开源大语言模型 DeepSeek Glm 智谱 miniMax(价格最便宜 ) - Claude Code App 国内用不了 - Codex : 桌面端 有闪退 - Cursor - Trae : 免费的额度 - QoderSetup-x64 阿里 - openclaw: - harness - QClaw - workbuddy : 腾讯 ## Claude code https://claude.com/product/claude-code - 基于Nodejs ![image-20260717104229519](assets/image-20260717104229519.png) 基于Node环境使用npm的方式 直接安装 npm An....../Claude Code... 使用 `npm install -g @anthropic-ai/claude-code` ``` C:\Users\Administrator>npm install -g @anthropic-ai/claude-code added 2 packages in 21s npm warn allow-scripts 1 package has install scripts not yet covered by allowScripts: npm warn allow-scripts @anthropic-ai/claude-code@2.1.212 (postinstall: node install.cjs) npm warn allow-scripts npm warn allow-scripts Run `npm approve-scripts --allow-scripts-pending` to review, or `npm approve-scripts ` to allow. C:\Users\Administrator>where claude C:\Users\Administrator\AppData\Roaming\npm\claude C:\Users\Administrator\AppData\Roaming\npm\claude.cmd C:\Users\Administrator>claude Welcome to Claude Code v2.1.212 .......................................................... * █████▓▓░ * ███▓░ ░░ ░░░░░░ ███▓░ ░░░ ░░░░░░░░░░ ███▓░ ░░░░░░░░░░░░░░░░░░░ * ██▓░░ ▓ ░▓▓███▓▓░ * ░░░░ ░░░░░░░░ ░░░░░░░░░░░░░░░░ █████████ * ██▄█████▄██ * █████████ * .......█ █ █ █.......................................... Unable to connect to Anthropic services Failed to connect to api.anthropic.com: Unknown system error -138 Please check your internet connection and network settings. Note: Claude Code might not be available in your country. Check supported countries at https://anthropic.com/supported-countries  C:\Users\Administrator> ``` 默认连不上 claude ## 配置 API地址 - deepseek - minimax ### DeepSeek 需要充值 ![image-20260717105713879](assets/image-20260717105713879.png) [DeepSeek 开放平台](https://platform.deepseek.com/api_keys) ![image-20260717104845951](assets/image-20260717104845951.png) ![image-20260717104920348](assets/image-20260717104920348.png) ![image-20260717104946813](assets/image-20260717104946813.png) ### API:Key sk-dc0d34848axxxxxx543ec59388b57f ### 使用cc-switch配置 Claude Code 链接 Deepseek [CC Switch 官方网站 - AI 编程工具统一管理平台](https://ccswitch.io/zh) ![image-20260717105145678](assets/image-20260717105145678.png) 点击下载之后会跳转到github,需要翻墙 ![image-20260717105220565](assets/image-20260717105220565.png) ![image-20260717105233508](assets/image-20260717105233508.png) ![image-20260717105241342](assets/image-20260717105241342.png) ![image-20260717105254406](assets/image-20260717105254406.png) ### 配置CC ![image-20260717105324840](assets/image-20260717105324840.png) ![image-20260717105426567](assets/image-20260717105426567.png) ![image-20260717105610677](assets/image-20260717105610677.png) ![image-20260717105646177](assets/image-20260717105646177.png) ### 使用CC 在工作区(有操作文档权限) claude ![image-20260717105925132](assets/image-20260717105925132.png) ![image-20260717110037236](assets/image-20260717110037236.png) ### 授信 ![image-20260717110109793](assets/image-20260717110109793.png) ## 可以对话 ![image-20260717110150303](assets/image-20260717110150303.png) ![image-20260717110231334](assets/image-20260717110231334.png) ## minimax 官网: [MiniMax](https://www.minimaxi.com/) ![image-20260717110730626](assets/image-20260717110730626.png) ![image-20260717110804943](assets/image-20260717110804943.png) ### 找到API Key ![image-20260717110844903](assets/image-20260717110844903.png) ### 使用cc-switch配置 CLaude 使用Minimax ![image-20260717110954050](assets/image-20260717110954050.png) ![image-20260717111258949](assets/image-20260717111258949.png) ## 使用CLaude(MiniMax) ![image-20260717111340189](assets/image-20260717111340189.png) ### 对话后可以查看到用量 ![image-20260717113417208](assets/image-20260717113417208.png) # 使用Claude code ## 修改登录页面的样式 我正在开发一个vue+vite的项目,项目中使用 ElementPlus 帮我修改一个 登录界面,位置在 src/views/login/index.vue 界面颜色偏亮一点,不要AI的味道太浓 ![image-20260717112847668](assets/image-20260717112847668.png) ## 反馈结果 ![image-20260717112940964](assets/image-20260717112940964.png) ## 可以查看到改动的内容 ![image-20260717113016959](assets/image-20260717113016959.png) ## 修改后的 外观 ![image-20260717113135296](assets/image-20260717113135296.png) # Vite配置 配置开发服务器端口号: vite.config.ts ``` import { fileURLToPath, URL } from 'node:url' import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import vueDevTools from 'vite-plugin-vue-devtools' // https://vite.dev/config/ export default defineConfig({ server:{ // proxy:{ // '/api':'http://localhost:8080//' // } // 配置端口号 port:80 }, plugins: [ vue(), vueDevTools(), ], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)), }, }, }) ``` ## 使用环境变量 加载的环境变量也会通过 `import.meta.env` 以字符串形式暴露给客户端源码。 为了防止意外地将一些环境变量泄漏到客户端,只有以 `VITE_` 为前缀的变量才会暴露给经过 vite 处理的代码。例如下面这些环境变量: ![image-20260717141457312](assets/image-20260717141457312.png) # MyBatisX插件 ![image-20260717143816594](assets/image-20260717143816594.png) ## 根据数据库逆向生成代码 创建数据源 ![image-20260717143946736](assets/image-20260717143946736.png) # 使用MP代码生成器 ```java package com.neuedu.nxu; import com.baomidou.mybatisplus.generator.FastAutoGenerator; import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; import org.junit.jupiter.api.Test; public class Generator { @Test public void generator() { String url = "jdbc:mysql://127.0.0.1:3306/ry"; FastAutoGenerator.create(url, "root", "root") .globalConfig(builder -> builder .author("金山老师") .outputDir( "C:/Users/Administrator/IdeaProjects/nxu/p05-springboot-mybatisplus/src/main/java") .commentDate("yyyy-MM-dd") ) .packageConfig(builder -> builder .parent("com.neuedu.nxu") .entity("entity") .mapper("mapper") .service("service") .serviceImpl("service.impl") .xml("mapper") ) .strategyConfig(builder -> builder .entityBuilder() .enableLombok() ) //使用Frememarker的模板 .templateEngine(new FreemarkerTemplateEngine()) .execute(); } } ``` 启动Lombok ![image-20260717145955856](assets/image-20260717145955856.png) ![image-20260717150854848](assets/image-20260717150854848.png)