• Gateway实现Redis拉取信息+用户模块开发


    文章目录

    🌞 Sun Frame:SpringBoot 的轻量级开发框架(个人开源项目推荐)

    Sun Frame Banner

    轻松高效的现代化开发体验

    Sun Frame 是我个人开源的一款基于 SpringBoot 的轻量级框架,专为中小型企业设计。它提供了一种快速、简单且易于扩展的开发方式。

    我们的开发文档记录了整个项目从0到1的任何细节,实属不易,请给我们一个Star!🌟
    您的支持是我们持续改进的动力。

    🌟 亮点功能

    • 组件化开发:灵活选择,简化流程。
    • 高性能:通过异步日志和 Redis 缓存提升性能。
    • 易扩展:支持多种数据库和消息队列。

    📦 spring cloud模块概览

    • Nacos 服务:高效的服务注册与发现。
    • Feign 远程调用:简化服务间通信。
    • 强大网关:路由与限流。

    常用工具

    • 日志管理:异步处理与链路追踪。
    • Redis 集成:支持分布式锁与缓存。
    • Swagger 文档:便捷的 API 入口。
    • 测试支持:SpringBoot-Test 集成。
    • EasyCode:自定义EasyCode模板引擎,一键生成CRUD。

    🔗 更多信息


    1.Gateway实现Redis拉取信息

    1.目录结构

    image-20240605145202260

    2.RedisConfig.java
    package com.sunxiansheng.club.gateway.redis;
    
    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.JsonTypeInfo;
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    import com.fasterxml.jackson.databind.DeserializationFeature;
    import com.fasterxml.jackson.databind.ObjectMapper;
    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.RedisSerializer;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    
    /**
     * Description: 原生 redis 的 template 的序列化器会产生乱码问题,重写改为 jackson
     * @Author sun
     * @Create 2024/6/5 14:16
     * @Version 1.0
     */
    @Configuration
    public class RedisConfig {
    
        @Bean
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
            RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
            RedisSerializer<String> redisSerializer = new StringRedisSerializer();
            redisTemplate.setConnectionFactory(redisConnectionFactory);
            redisTemplate.setKeySerializer(redisSerializer);
            redisTemplate.setHashKeySerializer(redisSerializer);
            redisTemplate.setValueSerializer(jackson2JsonRedisSerializer());
            redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer());
            return redisTemplate;
        }
    
        private Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer() {
            Jackson2JsonRedisSerializer<Object> jsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
            jsonRedisSerializer.setObjectMapper(objectMapper);
            return jsonRedisSerializer;
        }
    
    }
    
    3.RedisUtil.java
    package com.sunxiansheng.club.gateway.redis;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.Resource;
    import java.util.Set;
    import java.util.concurrent.TimeUnit;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    
    /**
     * Description: RedisUtil工具类
     * @Author sun
     * @Create 2024/6/5 14:17
     * @Version 1.0
     */
    @Component
    @Slf4j
    public class RedisUtil {
    
        @Resource
        private RedisTemplate redisTemplate;
    
        private static final String CACHE_KEY_SEPARATOR = ".";
    
        /**
         * 构建缓存key
         */
        public String buildKey(String... strObjs) {
            return Stream.of(strObjs).collect(Collectors.joining(CACHE_KEY_SEPARATOR));
        }
    
        /**
         * 是否存在key
         */
        public boolean exist(String key) {
            return redisTemplate.hasKey(key);
        }
    
        /**
         * 删除key
         */
        public boolean del(String key) {
            return redisTemplate.delete(key);
        }
    
        public void set(String key, String value) {
            redisTemplate.opsForValue().set(key, value);
        }
    
        public boolean setNx(String key, String value, Long time, TimeUnit timeUnit) {
            return redisTemplate.opsForValue().setIfAbsent(key, value, time, timeUnit);
        }
    
        public String get(String key) {
            return (String) redisTemplate.opsForValue().get(key);
        }
    
        public Boolean zAdd(String key, String value, Long score) {
            return redisTemplate.opsForZSet().add(key, value, Double.valueOf(String.valueOf(score)));
        }
    
        public Long countZset(String key) {
            return redisTemplate.opsForZSet().size(key);
        }
    
        public Set<String> rangeZset(String key, long start, long end) {
            return redisTemplate.opsForZSet().range(key, start, end);
        }
    
        public Long removeZset(String key, Object value) {
            return redisTemplate.opsForZSet().remove(key, value);
        }
    
        public void removeZsetList(String key, Set<String> value) {
            value.stream().forEach((val) -> redisTemplate.opsForZSet().remove(key, val));
        }
    
        public Double score(String key, Object value) {
            return redisTemplate.opsForZSet().score(key, value);
        }
    
        public Set<String> rangeByScore(String key, long start, long end) {
            return redisTemplate.opsForZSet().rangeByScore(key, Double.valueOf(String.valueOf(start)), Double.valueOf(String.valueOf(end)));
        }
    
        public Object addScore(String key, Object obj, double score) {
            return redisTemplate.opsForZSet().incrementScore(key, obj, score);
        }
    
        public Object rank(String key, Object obj) {
            return redisTemplate.opsForZSet().rank(key, obj);
        }
    
    
    }
    
    4.StpInterfaceImpl.java
    package com.sunxiansheng.club.gateway.auth;
    
    import cn.dev33.satoken.stp.StpInterface;
    import com.alibaba.cloud.commons.lang.StringUtils;
    import com.google.gson.Gson;
    import com.sunxiansheng.club.gateway.redis.RedisConfig;
    import com.sunxiansheng.club.gateway.redis.RedisUtil;
    import org.springframework.stereotype.Component;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    /**
     * 自定义权限验证接口扩展
     */
    @Component
    public class StpInterfaceImpl implements StpInterface {
    
        private final RedisUtil redisUtil;
        // 定义存入到redis的前缀
        private String authPermissionPrefix = "auth.permission";
        private String authRolePrefix = "auth.role";
    
        public StpInterfaceImpl(RedisUtil redisUtil) {
            this.redisUtil = redisUtil;
        }
    
        /**
         * 返回此loginId拥有的权限列表
         * @param loginId
         * @param loginType
         * @return
         */
        @Override
        public List<String> getPermissionList(Object loginId, String loginType) {
            return getAuth((String) loginId, authPermissionPrefix);
        }
    
        /**
         * 返回此loginId拥有的角色列表
         * @param loginId
         * @param loginType
         * @return
         */
        @Override
        public List<String> getRoleList(Object loginId, String loginType) {
            return getAuth((String) loginId, authRolePrefix);
        }
    
        private List<String> getAuth(String loginId, String prefix) {
            // 得到该用户在redis中存储的key
            String authKey = redisUtil.buildKey(prefix, loginId.toString());
            // 从redis中获取列表
            String authValue = redisUtil.get(authKey);
            // 判空
            if (StringUtils.isBlank(authValue)) {
                return Collections.emptyList();
            }
            // 如果有权限,则使用Gson反序列化为List
            List<String> authList = new Gson().fromJson(authValue, List.class);
            return authList;
        }
    
    }
    

    2.用户模块-用户注册

    1.easycode生成auth_user代码
    1.创建好目录

    image-20240605150443859

    2.配置生成代码

    image-20240605150614456

    3.将dao层的类剪切到mapper
    4.AuthUserDao.java删除Pageable的参数

    image-20240605151131673

    5.service层删除分页查询接口和实现类

    image-20240605151230210

    image-20240605151243406

    6.最终目录结构

    image-20240605151513469

    2.sun-club-auth-application-controller 基本配置
    1.目录创建

    image-20240605152023941

    2.GlobalConfig.java mvc的全局处理
    package com.sunxiansheng.auth.application.config;
    
    import com.fasterxml.jackson.annotation.JsonInclude;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.SerializationFeature;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.converter.HttpMessageConverter;
    import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
    
    import java.util.List;
    
    /**
     * mvc的全局处理
     */
    @Configuration
    public class GlobalConfig extends WebMvcConfigurationSupport {
    
        @Override
        protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
            super.configureMessageConverters(converters);
            converters.add(mappingJackson2HttpMessageConverter());
        }
        /**
         * 自定义mappingJackson2HttpMessageConverter
         * 目前实现:空值忽略,空字段可返回
         */
        private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
            objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            return new MappingJackson2HttpMessageConverter(objectMapper);
        }
    
    }
    
    3.sun-club-auth-common 基本配置
    1.目录结构

    image-20240605152556975

    2.PageInfo.java
    package com.sunxiansheng.auth.common.eneity;
    
    /**
     * Description: 分页请求的入参
     * @Author sun
     * @Create 2024/5/28 16:25
     * @Version 1.0
     */
    public class PageInfo {
    
        private Integer pageNo = 1;
    
        private Integer pageSize = 20;
    
        public Integer getPageNo() {
            if (pageNo == null || pageNo < 1) {
                return 1;
            }
            return pageNo;
        }
    
        public Integer getPageSize() {
            if (pageSize == null || pageSize < 1 || pageSize > Integer.MAX_VALUE) {
                return 20;
            }
            return pageSize;
        }
    
        public void setPageNo(Integer pageNo) {
            this.pageNo = pageNo;
        }
    
        public void setPageSize(Integer pageSize) {
            this.pageSize = pageSize;
        }
    }
    
    3.PageResult.java
    package com.sunxiansheng.auth.common.eneity;
    
    import java.util.Collections;
    import java.util.List;
    
    /**
     * Description: 分页返回的实体
     * @Author sun
     * @Create 2024/5/28 16:36
     * @Version 1.1
     */
    public class PageResult<T> {
    
        // 当前页码,默认为1
        private Integer pageNo = 1;
    
        // 每页显示的记录数,默认为20
        private Integer pageSize = 20;
    
        // 总记录条数
        private Integer total = 0;
    
        // 总页数
        private Integer totalPages = 0;
    
        // 当前页的记录列表
        private List<T> result = Collections.emptyList();
    
        // 表示当前页是从数据库的第几条记录开始,下标从1开始
        private Integer start = 1;
    
        // 表示当前页是从数据库的第几条记录结束,下标从1开始
        private Integer end = 0;
    
        // 设置当前页码,并重新计算起始和结束位置
        public void setPageNo(Integer pageNo) {
            this.pageNo = pageNo;
            calculateStartAndEnd();
        }
    
        // 设置每页记录数,并重新计算起始和结束位置
        public void setPageSize(Integer pageSize) {
            this.pageSize = pageSize;
            calculateStartAndEnd();
        }
    
        // 设置当前页的记录列表
        public void setRecords(List<T> result) {
            this.result = result;
        }
    
        // 设置总记录条数,并重新计算总页数和起始结束位置
        public void setTotal(Integer total) {
            this.total = total;
            calculateTotalPages();
            calculateStartAndEnd();
        }
    
        // 计算总页数
        private void calculateTotalPages() {
            if (this.pageSize > 0) {
                this.totalPages = (this.total / this.pageSize) + (this.total % this.pageSize == 0 ? 0 : 1);
            } else {
                this.totalPages = 0;
            }
        }
    
        // 计算起始和结束位置
        private void calculateStartAndEnd() {
            if (this.pageSize > 0) {
                this.start = (this.pageNo - 1) * this.pageSize + 1;
                this.end = Math.min(this.pageNo * this.pageSize, this.total);
            } else {
                this.start = 1;
                this.end = this.total;
            }
        }
    
        // 获取数据库查询的起始位置(从0开始)
        public Integer getDBStart() {
            return start - 1;
        }
    
        public Integer getStart() {
            return start;
        }
    
        // 获取每页记录数
        public Integer getPageSize() {
            return pageSize;
        }
    
        // 可选的 Getters 和 Setters
        public Integer getPageNo() {
            return pageNo;
        }
    
        public Integer getTotal() {
            return total;
        }
    
        public Integer getTotalPages() {
            return totalPages;
        }
    
        public List<T> getResult() {
            return result;
        }
    
        public Integer getEnd() {
            return end;
        }
    }
    
    4.Result.java
    package com.sunxiansheng.auth.common.eneity;
    
    import com.sunxiansheng.auth.common.enums.ResultCodeEnum;
    import lombok.Data;
    
    /**
     * Description:
     * @Author sun
     * @Create 2024/5/24 9:48
     * @Version 1.0
     */
    @Data
    public class Result<T> {
    
        private Boolean success;
    
        private Integer code;
    
        private String message;
    
        private T data;
    
        /**
         * 成功返回结果
         * @return
         */
        public static Result ok() {
            Result result = new Result();
            result.setSuccess(true);
            result.setCode(ResultCodeEnum.SUCCESS.getCode());
            result.setMessage(ResultCodeEnum.SUCCESS.getDesc());
            return result;
        }
    
        /**
         * 成功返回结果,携带数据
         * @param data
         * @return
         * @param 
         */
        public static <T> Result ok(T data) {
            Result result = new Result();
            result.setSuccess(true);
            result.setCode(ResultCodeEnum.SUCCESS.getCode());
            result.setMessage(ResultCodeEnum.SUCCESS.getDesc());
            result.setData(data);
            return result;
        }
    
        /**
         * 失败返回结果
         * @return
         */
        public static Result fail() {
            Result result = new Result();
            result.setSuccess(false);
            result.setCode(ResultCodeEnum.FAIL.getCode());
            result.setMessage(ResultCodeEnum.FAIL.getDesc());
            return result;
        }
    
        /**
         * 失败,携带数据
         * @param data
         * @return
         * @param 
         */
        public static <T> Result fail(T data) {
            Result result = new Result();
            result.setSuccess(false);
            result.setCode(ResultCodeEnum.FAIL.getCode());
            result.setMessage(ResultCodeEnum.FAIL.getDesc());
            result.setData(data);
            return result;
        }
    
    }
    
    5.IsDeleteFlagEnum.java
    package com.sunxiansheng.auth.common.enums;
    
    import lombok.Getter;
    
    /**
     * Description: 删除标识枚举
     * @Author sun
     * @Create 2024/5/24 9:53
     * @Version 1.0
     */
    @Getter
    public enum IsDeleteFlagEnum {
        DELETED(1, "已删除"),
        UN_DELETED(0, "未删除");
    
        public int code;
        public String desc;
    
        IsDeleteFlagEnum(int code, String desc) {
            this.code = code;
            this.desc = desc;
        }
    
        /**
         * 根据code获取枚举
         * @param code
         * @return
         */
        public static IsDeleteFlagEnum getByCode(int code) {
            for (IsDeleteFlagEnum value : values()) {
                if (value.code == code) {
                    return value;
                }
            }
            return null;
        }
    }
    
    6.ResultCodeEnum.java
    package com.sunxiansheng.auth.common.enums;
    
    import lombok.Getter;
    
    /**
     * Description: 返回结果枚举
     * @Author sun
     * @Create 2024/5/24 9:53
     * @Version 1.0
     */
    @Getter
    public enum ResultCodeEnum {
        SUCCESS(200, "成功"),
        FAIL(500, "失败");
    
        public int code;
        public String desc;
    
        ResultCodeEnum(int code, String desc) {
            this.code = code;
            this.desc = desc;
        }
    
        /**
         * 根据code获取枚举
         * @param code
         * @return
         */
        public static ResultCodeEnum getByCode(int code) {
            for (ResultCodeEnum value : values()) {
                if (value.code == code) {
                    return value;
                }
            }
            return null;
        }
    }
    
    4.sun-club-auth-application-controller层
    1.AuthUserDTO.java
    package com.sunxiansheng.auth.application.dto;
    
    import lombok.Data;
    
    import java.io.Serializable;
    
    /**
     * 用户信息的dto
     *
     * @author makejava
     * @since 2024-06-05 15:06:10
     */
    @Data
    public class AuthUserDTO implements Serializable {
        /**
         * 主键
         */
        private Long id;
        /**
         * 用户名称/账号
         */
        private String userName;
        /**
         * 昵称
         */
        private String nickName;
        /**
         * 邮箱
         */
        private String email;
        /**
         * 手机号
         */
        private String phone;
        /**
         * 密码
         */
        private String password;
        /**
         * 性别
         */
        private Integer sex;
        /**
         * 头像
         */
        private String avatar;
        /**
         * 状态 0启用 1禁用
         */
        private Integer status;
        /**
         * 个人介绍
         */
        private String introduce;
        /**
         * 特殊字段
         */
        private String extJson;
        /**
         * 是否被删除 0未删除 1已删除
         */
        private Integer isDeleted;
    
    }
    
    
    2.sun-club-auth-domain 模块
    AuthUserBO.java 与DTO一致
    package com.sunxiansheng.auth.domain.entity;
    
    import lombok.Data;
    
    import java.io.Serializable;
    
    /**
     * 用户信息的bo
     *
     * @author makejava
     * @since 2024-06-05 15:06:10
     */
    @Data
    public class AuthUserBO implements Serializable {
        /**
         * 主键
         */
        private Long id;
        /**
         * 用户名称/账号
         */
        private String userName;
        /**
         * 昵称
         */
        private String nickName;
        /**
         * 邮箱
         */
        private String email;
        /**
         * 手机号
         */
        private String phone;
        /**
         * 密码
         */
        private String password;
        /**
         * 性别
         */
        private Integer sex;
        /**
         * 头像
         */
        private String avatar;
        /**
         * 状态 0启用 1禁用
         */
        private Integer status;
        /**
         * 个人介绍
         */
        private String introduce;
        /**
         * 特殊字段
         */
        private String extJson;
        /**
         * 是否被删除 0未删除 1已删除
         */
        private Integer isDeleted;
    
    }
    
    
    3.AuthUserDTOConverter.java
    package com.sunxiansheng.auth.application.convert;
    
    import com.sunxiansheng.auth.application.dto.AuthUserDTO;
    import com.sunxiansheng.auth.domain.entity.AuthUserBO;
    import org.mapstruct.Mapper;
    import org.mapstruct.factory.Mappers;
    
    import java.util.List;
    
    /**
     * Description: DTO转换
     * @Author sun
     * @Create 2024/6/5 15:39
     * @Version 1.0
     */
    @Mapper
    public interface AuthUserDTOConverter {
        AuthUserDTOConverter INSTANCE = Mappers.getMapper(AuthUserDTOConverter.class);
    
        // 将AuthUserDTO转换为AuthUserBO
        AuthUserBO convertDTO2BO(AuthUserDTO authUserDTO);
        // 将AuthUserBO转换为AuthUserDTO
        AuthUserDTO convertBO2DTO(AuthUserBO authUserBO);
        // 将AuthUserDTO集合转换为AuthUserBO集合
        List<AuthUserBO> convertDTO2BO(List<AuthUserDTO> authUserDTOList);
        // 将AuthUserBO集合转换为AuthUserDTO集合
        List<AuthUserDTO> convertBO2DTO(List<AuthUserBO> authUserBOList);
    }
    
    5.sun-club-auth-domain层
    1.目录创建

    image-20240605155441562

    2.AuthUserBOConverter.java
    package com.sunxiansheng.auth.domain.convert;
    
    import com.sunxiansheng.auth.basic.entity.AuthUser;
    import com.sunxiansheng.auth.domain.entity.AuthUserBO;
    import org.mapstruct.Mapper;
    import org.mapstruct.factory.Mappers;
    
    import java.util.List;
    
    /**
     * Description: BO转换
     * @Author sun
     * @Create 2024/5/24 9:18
     * @Version 1.0
     */
    @Mapper // mapstruct的注解
    public interface AuthUserBOConverter {
        // INSTANCE是一个AuthUserBOConverter的静态实例,可以直接通过AuthUserBOConverter.INSTANCE调用内部的方法
        AuthUserBOConverter INSTANCE = Mappers.getMapper(AuthUserBOConverter.class);
    
        // 将AuthUserBO转换为AuthUser
        AuthUser convertBO2Entity(AuthUserBO authUserBO);
        // 将AuthUser转换为AuthUserBO
        AuthUserBO convertEntity2BO(AuthUser authUser);
        // 将AuthUserBO集合转换为AuthUser集合
        List<AuthUser> convertBO2Entity(List<AuthUserBO> authUserBOList);
        // 将AuthUser集合转换为AuthUserBO集合
        List<AuthUserBO> convertEntity2BO(List<AuthUser> authUserList);
    
    }
    
    
    3.AuthUserDomainService.java
    package com.sunxiansheng.auth.domain.service;
    
    import com.sunxiansheng.auth.domain.entity.AuthUserBO;
    
    /**
     * Description:
     * @Author sun
     * @Create 2024/5/24 9:03
     * @Version 1.0
     */
    public interface AuthUserDomainService {
    
        Boolean register(AuthUserBO authUserBO);
    }
    
    4.AuthUserDomainServiceImpl.java
    package com.sunxiansheng.auth.domain.service.impl;
    
    import com.sunxiansheng.auth.basic.entity.AuthUser;
    import com.sunxiansheng.auth.basic.service.AuthUserService;
    import com.sunxiansheng.auth.domain.convert.AuthUserBOConverter;
    import com.sunxiansheng.auth.domain.entity.AuthUserBO;
    import com.sunxiansheng.auth.domain.service.AuthUserDomainService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    
    /**
     * Description:
     * @Author sun
     * @Create 2024/5/24 9:03
     * @Version 1.0
     */
    @Service
    @Slf4j
    public class AuthUserDomainServiceImpl implements AuthUserDomainService {
        @Resource
        private AuthUserService authUserService;
    
        @Override
        public Boolean register(AuthUserBO authUserBO) {
            // BO转换为Entity
            AuthUser authUser = AuthUserBOConverter.INSTANCE.convertBO2Entity(authUserBO);
            // 调用基础服务
            Integer count = authUserService.insert(authUser);
            return count > 0;
        }
    }
    
    6.sun-club-auth-infra层
    1.AuthUserService.java 修改insert返回为Integer
    /**
     * 新增数据
     *
     * @param authUser 实例对象
     * @return 实例对象
     */
    Integer insert(AuthUser authUser);
    
    2.AuthUserServiceImpl.java
    /**
     * 新增数据
     *
     * @param authUser 实例对象
     * @return 实例对象
     */
    @Override
    public Integer insert(AuthUser authUser) {
        return this.authUserDao.insert(authUser);
    }
    
    3.AuthUserDao.java
    /**
     * 新增数据
     *
     * @param authUser 实例对象
     * @return 影响行数
     */
    int insert(AuthUser authUser);
    
    4.AuthUserDao.xml
    
    <insert id="insert" keyProperty="id" useGeneratedKeys="true">
        insert into auth_user(user_name, nick_name, email, phone, password, sex, avatar, status, introduce, ext_json,
                              created_by, created_time, update_by, update_time, is_deleted)
        values (#{userName}, #{nickName}, #{email}, #{phone}, #{password}, #{sex}, #{avatar}, #{status}, #{introduce},
                #{extJson}, #{createdBy}, #{createdTime}, #{updateBy}, #{updateTime}, #{isDeleted})
    insert>
    
    7.最后:UserController.java
    package com.sunxiansheng.auth.application.controller;
    
    import cn.dev33.satoken.stp.SaTokenInfo;
    import cn.dev33.satoken.stp.StpUtil;
    import cn.dev33.satoken.util.SaResult;
    import com.alibaba.fastjson.JSON;
    import com.google.common.base.Preconditions;
    import com.sun.xml.internal.bind.v2.TODO;
    import com.sunxiansheng.auth.application.convert.AuthUserDTOConverter;
    import com.sunxiansheng.auth.application.dto.AuthUserDTO;
    import com.sunxiansheng.auth.common.eneity.Result;
    import com.sunxiansheng.auth.common.enums.IsDeleteFlagEnum;
    import com.sunxiansheng.auth.domain.entity.AuthUserBO;
    import com.sunxiansheng.auth.domain.service.AuthUserDomainService;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.annotation.Resource;
    
    /**
     * Description:
     * @Author sun
     * @Create 2024/6/2 17:25
     * @Version 1.0
     */
    @RestController
    @RequestMapping("/user/")
    @Slf4j
    public class UserController {
    
        @Resource
        private AuthUserDomainService authUserDomainService;
    
        /**
         * 用户注册
         * @param authUserDTO
         * @return
         */
        @RequestMapping("register")
        public Result<Boolean> register(@RequestBody AuthUserDTO authUserDTO) {
            try {
                // 日志
                if (log.isInfoEnabled()) {
                    log.info("UserController register AuthUserDTO, authUserDTO:{}", JSON.toJSONString(authUserDTO));
                }
                // 参数校验
                Preconditions.checkArgument(!StringUtils.isBlank(authUserDTO.getUserName()), "用户名不能为空");
                Preconditions.checkArgument(!StringUtils.isBlank(authUserDTO.getEmail()), "邮箱不能为空");
                Preconditions.checkArgument(!StringUtils.isBlank(authUserDTO.getPassword()), "密码不能为空");
                // 转换DTO为BO
                AuthUserBO authUserBO = AuthUserDTOConverter.INSTANCE.convertDTO2BO(authUserDTO);
                // 调用领域服务
                // 设置逻辑删除
                authUserBO.setIsDeleted(IsDeleteFlagEnum.UN_DELETED.getCode());
                // 注册
                Boolean res = authUserDomainService.register(authUserBO);
                return Result.ok(res);
            } catch (Exception e) {
                log.error("UserController register error:{}", e.getMessage(), e);
                return Result.fail();
            }
        }
    
    }
    
    8.测试
    1.接口设计

    image-20240605163348946

    2.结果

    image-20240605163402309

    3.DB

    image-20240605163427362

    4.发现DB中没有插入status
    1.sun-club-auth-common模块新增枚举 AuthUserStatusEnum.java
    package com.sunxiansheng.auth.common.enums;
    
    import lombok.Getter;
    
    /**
     * Description: 返回结果枚举
     * @Author sun
     * @Create 2024/5/24 9:53
     * @Version 1.0
     */
    @Getter
    public enum AuthUserStatusEnum {
    
        OPEN(0,"启用"),
        CLOSE(1,"禁用");
    
        public int code;
    
        public String desc;
    
        AuthUserStatusEnum(int code, String desc){
            this.code = code;
            this.desc = desc;
        }
    
        public static AuthUserStatusEnum getByCode(int codeVal){
            for(AuthUserStatusEnum resultCodeEnum : AuthUserStatusEnum.values()){
                if(resultCodeEnum.code == codeVal){
                    return resultCodeEnum;
                }
            }
            return null;
        }
    
    }
    
    2.sun-club-auth-application-controller UserController.java新增语句

    3.重启测试

    image-20240605164814865

    3.用户模块-更新用户信息

    1.接口设计

    image-20240605171114841

    2.sun-club-auth-application-controller
    1.UserController.java
    /**
     * 修改用户信息
     * @param authUserDTO
     * @return
     */
    @RequestMapping("update")
    public Result<Boolean> update(@RequestBody AuthUserDTO authUserDTO) {
        try {
            // 日志
            if (log.isInfoEnabled()) {
                log.info("UserController update AuthUserDTO, authUserDTO:{}", JSON.toJSONString(authUserDTO));
            }
            // 参数校验
            Preconditions.checkArgument(!StringUtils.isBlank(authUserDTO.getUserName()), "用户名不能为空");
            // 转换DTO为BO
            AuthUserBO authUserBO = AuthUserDTOConverter.INSTANCE.convertDTO2BO(authUserDTO);
            // 调用领域服务
            // 更新用户信息
            Boolean res = authUserDomainService.update(authUserBO);
            return Result.ok(res);
        } catch (Exception e) {
            // error日志
            log.error("UserController update error:{}", e.getMessage(), e);
            return Result.fail("更新用户信息失败");
        }
    }
    
    3.sun-club-auth-domain
    1.AuthUserDomainService.java
    /**
     * 更新
     * @param authUserBO
     * @return
     */
    Boolean update(AuthUserBO authUserBO);
    
    2.AuthUserDomainServiceImpl.java
    @Override
    public Boolean update(AuthUserBO authUserBO) {
        // BO转换为Entity
        AuthUser authUser = AuthUserBOConverter.INSTANCE.convertBO2Entity(authUserBO);
        // 调用基础服务
        Integer count = authUserService.update(authUser);
        // 有任何的更新,都要与缓存进行同步的修改,要把当前用户的角色和权限都放到redis里
        return count > 0;
    }
    
    4.sun-club-auth-infra
    1.AuthUserService.java
    /**
     * 修改数据
     *
     * @param authUser 实例对象
     * @return 实例对象
     */
    Integer update(AuthUser authUser);
    
    2.AuthUserServiceImpl.java
    /**
     * 修改数据
     *
     * @param authUser 实例对象
     * @return 实例对象
     */
    @Override
    public Integer update(AuthUser authUser) {
        return this.authUserDao.update(authUser);
    }
    
    5.测试
    1.结果

    image-20240605171347052

    2.DB

    image-20240605171417545

    4.用户模块-删除用户信息

    1.接口设计

    image-20240605172400982

    2.sun-club-auth-application-controller
    1.UserController.java
    /**
     * 删除用户信息
     * @param authUserDTO
     * @return
     */
    @RequestMapping("delete")
    public Result<Boolean> delete(@RequestBody AuthUserDTO authUserDTO) {
        try {
            // 日志
            if (log.isInfoEnabled()) {
                log.info("UserController delete AuthUserDTO, authUserDTO:{}", JSON.toJSONString(authUserDTO));
            }
            // 参数校验
            // 转换DTO为BO
            AuthUserBO authUserBO = AuthUserDTOConverter.INSTANCE.convertDTO2BO(authUserDTO);
            // 调用领域服务
            // 删除用户信息
            Boolean res = authUserDomainService.delete(authUserBO);
            return Result.ok(res);
        } catch (Exception e) {
            // error日志
            log.error("UserController delete error:{}", e.getMessage(), e);
            return Result.fail("删除用户信息失败");
        }
    }
    
    3.sun-club-auth-domain
    1.AuthUserDomainService.java
    /**
     * 删除
     * @param authUserBO
     * @return
     */
    Boolean delete(AuthUserBO authUserBO);
    
    2.AuthUserDomainServiceImpl.java
    @Override
    public Boolean delete(AuthUserBO authUserBO) {
        AuthUser authUser = new AuthUser();
        // 设置ID
        authUser.setId(authUserBO.getId());
        // 设置逻辑删除
        authUser.setIsDeleted(IsDeleteFlagEnum.DELETED.getCode());
        // 更新
        Integer count = authUserService.update(authUser);
        return count > 0;
    }
    
    4.测试
    1.结果

    image-20240605172530415

    2.DB

    image-20240605172553742

    5.用户模块-启用/禁用信息

    1.接口设计

    image-20240605173355196

    2.UserController.java
    /**
     * 用户启用/禁用
     * @param authUserDTO
     * @return
     */
    @RequestMapping("changeStatus")
    public Result<Boolean> changeStatus(@RequestBody AuthUserDTO authUserDTO) {
        try {
            // 日志
            if (log.isInfoEnabled()) {
                log.info("UserController changeStatus AuthUserDTO, authUserDTO:{}", JSON.toJSONString(authUserDTO));
            }
            // 参数校验
            Preconditions.checkNotNull(authUserDTO.getStatus(), "用户状态不能为空");
            // 转换DTO为BO
            AuthUserBO authUserBO = AuthUserDTOConverter.INSTANCE.convertDTO2BO(authUserDTO);
            // 调用领域服务
            // 用户启用/禁用,直接调用更新即可
            Boolean res = authUserDomainService.update(authUserBO);
            return Result.ok(res);
        } catch (Exception e) {
            // error日志
            log.error("UserController changeStatus error:{}", e.getMessage(), e);
            return Result.fail("用户启用/禁用失败");
        }
    }
    
    3.测试
    1.结果

    image-20240605173436856

    2.DB

    image-20240605173502549

  • 相关阅读:
    【开发小记】vue项目打包可视化
    【虚拟化生态平台】平台架构图&思路和实现细节
    linux查看用户相关信息的命令
    【LLM】transformer介绍,为啥要有QKV?
    Mac/Linux安装使用 opengauss数据库步骤
    千里共婵娟 | 结合微信公众号用JavaScript完整开发实现换中秋头像的功能
    Golang 语言接口的定义与实现
    快速新建springboot项目
    软件界面设计培训
    MySQL的复制
  • 原文地址:https://blog.csdn.net/m0_64637029/article/details/140924290