前端
https://blog.csdn.net/m0_37613503/article/details/128961447
数据库
1.用户表
- CREATE TABLE `x_user` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `username` varchar(50) NOT NULL,
- `password` varchar(100) DEFAULT NULL,
- `email` varchar(50) DEFAULT NULL,
- `phone` varchar(20) DEFAULT NULL,
- `status` int(1) DEFAULT NULL,
- `avatar` varchar(200) DEFAULT NULL,
- `deleted` INT(1) DEFAULT 0,
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
复制代码- insert into `x_user` (`id`, `username`, `password`, `email`, `phone`, `status`, `avatar`, `deleted`) values('1','admin','123456','super@aliyun.com','18677778888','1','https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif','0');
- insert into `x_user` (`id`, `username`, `password`, `email`, `phone`, `status`, `avatar`, `deleted`) values('2','zhangsan','123456','zhangsan@gmail.com','13966667777','1','https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif','0');
- insert into `x_user` (`id`, `username`, `password`, `email`, `phone`, `status`, `avatar`, `deleted`) values('3','lisi','123456','lisi@gmail.com','13966667778','1','https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif','0');
- insert into `x_user` (`id`, `username`, `password`, `email`, `phone`, `status`, `avatar`, `deleted`) values('4','wangwu','123456','wangwu@gmail.com','13966667772','1','https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif','0');
- insert into `x_user` (`id`, `username`, `password`, `email`, `phone`, `status`, `avatar`, `deleted`) values('5','zhaoer','123456','zhaoer@gmail.com','13966667776','1','https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif','0');
- insert into `x_user` (`id`, `username`, `password`, `email`, `phone`, `status`, `avatar`, `deleted`) values('6','songliu','123456','songliu@gmail.com','13966667771','1','https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif','0');
复制代码 2.角色表
- CREATE TABLE `x_role` (
- `role_id` int(11) NOT NULL AUTO_INCREMENT,
- `role_name` varchar(50) DEFAULT NULL,
- `role_desc` varchar(100) DEFAULT NULL,
- PRIMARY KEY (`role_id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
复制代码- insert into `x_role` (`role_id`, `role_name`, `role_desc`) values('1','admin','超级管理员');
- insert into `x_role` (`role_id`, `role_name`, `role_desc`) values('2','hr','人事专员');
- insert into `x_role` (`role_id`, `role_name`, `role_desc`) values('3','normal','普通员工');
复制代码 3.菜单表
- CREATE TABLE `x_menu` (
- `menu_id` int(11) NOT NULL AUTO_INCREMENT,
- `component` varchar(100) DEFAULT NULL,
- `path` varchar(100) DEFAULT NULL,
- `redirect` varchar(100) DEFAULT NULL,
- `name` varchar(100) DEFAULT NULL,
- `title` varchar(100) DEFAULT NULL,
- `icon` varchar(100) DEFAULT NULL,
- `parent_id` int(11) DEFAULT NULL,
- `is_leaf` varchar(1) DEFAULT NULL,
- `hidden` tinyint(1) DEFAULT NULL,
- PRIMARY KEY (`menu_id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4;
复制代码- insert into `x_menu`(`menu_id`,`component`,`path`,`redirect`,`name`,`title`,`icon`,`parent_id`,`is_leaf`,`hidden`) values (1,'Layout','/user','/user/list','userManage','用户管理','userManage',0,'N',0),(2,'user/user','list',NULL,'userList','用户列表','userList',1,'Y',0),(3,'user/role','role',NULL,'roleList','角色列表','role',1,'Y',0),(4,'user/permission','permission',NULL,'permissionList','权限列表','permission',1,'Y',0);
复制代码 4.用户角色映射表
- CREATE TABLE `x_user_role` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `user_id` int(11) DEFAULT NULL,
- `role_id` int(11) DEFAULT NULL,
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;
复制代码- insert into `x_user_role` (`id`, `user_id`, `role_id`) values('1','1','1');
复制代码 5.角色菜单映射表
- CREATE TABLE `x_role_menu` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `role_id` int(11) DEFAULT NULL,
- `menu_id` int(11) DEFAULT NULL,
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;
复制代码 后端
1、创建springboot项目2.6.13
2、pom依赖
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
-
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.baomidou</groupId>
- <artifactId>mybatis-plus-boot-starter</artifactId>
- <version>3.5.2</version>
- </dependency>
- <dependency>
- <groupId>com.baomidou</groupId>
- <artifactId>mybatis-plus-generator</artifactId>
- <version>3.5.2</version>
- </dependency>
-
- <dependency>
- <groupId>org.freemarker</groupId>
- <artifactId>freemarker</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-redis</artifactId>
- </dependency>
复制代码 3.yml
- server:
- port: 9999
- spring:
- datasource:
- username: root
- password: 123456
- url: jdbc:mysql://localhost:3306/xdb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT
- redis:
- port: 6379
- host: localhost
- logging:
- level:
- com.zhu: debug
复制代码 2、Mybatis-plus代码天生
1.编写代码天生器
- package com.zhu;
- import com.baomidou.mybatisplus.generator.FastAutoGenerator;
- import com.baomidou.mybatisplus.generator.config.OutputFile;
- import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
- import java.util.Collections;
- public class CodeGenerator {
- public static void main(String[] args) {
- String url = "jdbc:mysql://localhost:3306/xdb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT";
- String username = "root";
- String password = "123456";
- String moduleName = "sys";
- String mapperLocation = "E:\\Intellij IDEA\\项目\\x-admin\\src\\main\\resources\\mapper\"+ moduleName;
- String tables = "x_user,x_menu,x_role,x_role_menu,x_user_role";
- FastAutoGenerator.create(url, username, password)
- .globalConfig(builder -> {
- builder.author("zhutieyang") // 设置作者
- //.enableSwagger() // 开启 swagger 模式
- .fileOverride() // 覆盖已生成文件
- .outputDir("E:\\Intellij IDEA\\项目\\x-admin\\src\\main\\java"); // 指定输出目录
- })
- .packageConfig(builder -> {
- builder.parent("com.zhu") // 设置父包名
- .moduleName(moduleName) // 设置父包模块名
- .pathInfo(Collections.singletonMap(OutputFile.xml, mapperLocation)); // 设置mapperXml生成路径
- })
- .strategyConfig(builder -> {
- builder.addInclude(tables) // 设置需要生成的表名
- .addTablePrefix("x_"); // 设置过滤表前缀
- })
- .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
- .execute();
- }
- }
复制代码
2、启动类加注解
因为自动天生的时候没有@mapper
3、测试
3、公共响应类
- package com.zhu.common;
- import lombok.AllArgsConstructor;
- import lombok.Data;
- import lombok.NoArgsConstructor;
- @Data
- @AllArgsConstructor
- @NoArgsConstructor
- public class Result<T> {
- private Integer code;
- private String message;
- private T data;
- public static <T> Result<T> success(){
- return new Result<>(20000,"success",null);
- }
- public static <T> Result<T> success(T data){
- return new Result<>(20000,"success",data);
- }
- public static <T> Result<T> success(T data,String message){
- return new Result<>(20000,message,data);
- }
- public static <T> Result<T> success(String message){
- return new Result<>(20000,message,null);
- }
- public static<T> Result<T> fail(){
- return new Result<>(20001,"fail",null);
- }
- public static<T> Result<T> fail(Integer code){
- return new Result<>(code,"fail",null);
- }
- public static<T> Result<T> fail(Integer code, String message){
- return new Result<>(code,message,null);
- }
- public static<T> Result<T> fail( String message){
- return new Result<>(20001,message,null);
- }
- }
复制代码
4.登录相关接口
4.1、登录
controller- @PostMapping("/login")
- public Result<Map<String,Object>> login(@RequestBody User user){
- Map<String,Object> data = userService.login(user);
- if(data !=null){
- return Result.success(data);
- }
- return Result.fail(20002,"用户名或密码错误");
- }
复制代码 service- package com.zhu.sys.service.impl;
- import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
- import com.zhu.config.MyRedisConfig;
- import com.zhu.sys.entity.User;
- import com.zhu.sys.mapper.UserMapper;
- import com.zhu.sys.service.IUserService;
- import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
- import org.omg.CORBA.TIMEOUT;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.stereotype.Service;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.UUID;
- import java.util.concurrent.TimeUnit;
- /**
- * <p>
- * 服务实现类
- * </p>
- *
- * @author zhutieyang
- * @since 2024-04-06
- */
- @Service
- public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
- @Autowired
- private RedisTemplate redisTemplate;
- @Override
- public Map<String, Object> login(User user) {
- // 根据用户名和密码去查询
- LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
- wrapper.eq(User::getUsername,user.getUsername());
- wrapper.eq(User::getPassword,user.getPassword());
- User loginUser = this.baseMapper.selectOne(wrapper);
- // 结果不为空,则生成token,并将用户信息存入redis
- if(loginUser !=null){
- // 暂时用UUID,终极方案是jwt
- String key ="user:"+ UUID.randomUUID();
- // 存入redis
- loginUser.setPassword(null);
- redisTemplate.opsForValue().set(key,loginUser,30, TimeUnit.MINUTES);
- // 返回数据
- Map<String, Object> data = new HashMap<>();
- data.put("token",key);
- return data;
- }
- return null;
- }
- }
复制代码 4.1.2、整合redis
1.pom- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-redis</artifactId>
- </dependency>
复制代码 2.yml- spring:
- redis:
- host: localhost
- port: 6379
复制代码 3.设置类- package com.zhu.config;
- import com.fasterxml.jackson.annotation.JsonAutoDetect;
- import com.fasterxml.jackson.annotation.JsonInclude;
- import com.fasterxml.jackson.annotation.JsonTypeInfo;
- import com.fasterxml.jackson.annotation.PropertyAccessor;
- import com.fasterxml.jackson.databind.DeserializationFeature;
- import com.fasterxml.jackson.databind.MapperFeature;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.fasterxml.jackson.databind.SerializationFeature;
- import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.data.redis.connection.RedisConnectionFactory;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
- import org.springframework.data.redis.serializer.StringRedisSerializer;
- import org.springframework.stereotype.Controller;
- import javax.annotation.Resource;
- import java.text.SimpleDateFormat;
- import java.util.TimeZone;
- @Configuration
- public class MyRedisConfig {
- @Resource
- private RedisConnectionFactory factory;
- @Bean
- public RedisTemplate redisTemplate(){
- RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
- redisTemplate.setConnectionFactory(factory);
- redisTemplate.setKeySerializer(new StringRedisSerializer());
- Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
- redisTemplate.setValueSerializer(serializer);
- ObjectMapper om = new ObjectMapper();
- om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
- om.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
- om.setTimeZone(TimeZone.getDefault());
- om.configure(MapperFeature.USE_ANNOTATIONS, false);
- om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
- om.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
- om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance ,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
- om.setSerializationInclusion(JsonInclude.Include.NON_NULL);
- serializer.setObjectMapper(om);
- return redisTemplate;
- }
- }
复制代码 4.2、获取用户信息
controller- @GetMapping("/info")
- public Result<?> getUserInfo(@Param("token") String token){
- Map<String,Object> data = userService.getUserInfo(token);
- if(data != null){
- return Result.success(data);
- }
- return Result.fail(20003,"用户信息获取失败");
- }
复制代码 service- public Map<String, Object> getUserInfo(String token) {
- // 从redis查询token
- Object obj = redisTemplate.opsForValue().get(token);
- // 反序列化
- User user = JSON.parseObject(JSON.toJSONString(obj),User.class);
- if(user != null){
- Map<String, Object> data = new HashMap<>();
- data.put("name",user.getUsername());
- data.put("avatar",user.getAvatar());
- List<String> roleList = this.getBaseMapper().getRoleNamesByUserId(user.getId());
- data.put("roles", roleList);
- return data;
- }
- return null;
- }
复制代码 mapper.xml- <select id="getRoleNamesByUserId" parameterType="Integer" resultType="String">
- SELECT
- b.role_name
- FROM x_user_role a,x_role b
- WHERE a.`user_id` = #{userId}
- AND a.`role_id` = b.`role_id`
- </select>
复制代码 4.3、注销
controller- @PostMapping("/logout")
- public Result<?> logout(@RequestHeader("X-Token") String token){
- userService.logout(token);
- return Result.success("注销成功");
- }
复制代码 service- public void logout(String token) {
- redisTemplate.delete(token);
- }
复制代码 5、跨域处理
记得打开redis- package com.zhu.config;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.web.cors.CorsConfiguration;
- import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
- import org.springframework.web.filter.CorsFilter;
- @Configuration
- public class MyCorsConfig {
- @Bean
- public CorsFilter corsFilter(){
- //添加CORS配置信息
- CorsConfiguration configuration = new CorsConfiguration();
- //允许的域,不要写*,否则cookie就无法使用了
- configuration.addAllowedOrigin("http://localhost:8888");//这里填写请求的前端服务器
- //是否发送Cookie信息
- configuration.setAllowCredentials(true);
- //允许的请求方式
- configuration.addAllowedMethod("*");
- // 4)允许的头信息
- configuration.addAllowedHeader("*");
- // 添加映射路径,我们拦截一切请求
- UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
- urlBasedCorsConfigurationSource.registerCorsConfiguration("/**",configuration);
- //返回新的CorsFilter
- return new CorsFilter(urlBasedCorsConfigurationSource);
- }
- }
复制代码 6、用户管理接口
6.1、查询用户列表
1、controller
- @GetMapping("/list")
- public Result<Map<String,Object>> getUserList(@RequestParam(value = "username",required = false) String username,
- @RequestParam(value = "phone",required = false) String phone,
- @RequestParam(value = "pageNo") Long pageNo,
- @RequestParam(value = "pageSize") Long pageSize){
- LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
- wrapper.eq(StringUtils.hasLength(username),User::getUsername,username);
- wrapper.eq(StringUtils.hasLength(phone),User::getPhone,phone);
- Page<User> page = new Page<>(pageNo,pageSize);
- userService.page(page,wrapper);
- Map<String,Object> data = new HashMap<>();
- data.put("total",page.getTotal());
- data.put("rows",page.getRecords());
- return Result.success(data);
复制代码 2、分页拦截器
- @Configuration
- public class MpConfig {
- @Bean
- public MybatisPlusInterceptor mybatisPlusInterceptor() {
- MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
- interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
- return interceptor;
- }
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |