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

news2024/11/23 11:48:06

文章目录

  • 🌞 Sun Frame:SpringBoot 的轻量级开发框架(个人开源项目推荐)
    • 🌟 亮点功能
    • 📦 spring cloud模块概览
      • 常用工具
    • 🔗 更多信息
    • 1.Gateway实现Redis拉取信息
        • 1.目录结构
        • 2.RedisConfig.java
        • 3.RedisUtil.java
        • 4.StpInterfaceImpl.java
    • 2.用户模块-用户注册
        • 1.easycode生成auth_user代码
          • 1.创建好目录
          • 2.配置生成代码
          • 3.将dao层的类剪切到mapper层
          • 4.AuthUserDao.java删除Pageable的参数
          • 5.service层删除分页查询接口和实现类
          • 6.最终目录结构
        • 2.sun-club-auth-application-controller 基本配置
          • 1.目录创建
          • 2.GlobalConfig.java mvc的全局处理
        • 3.sun-club-auth-common 基本配置
          • 1.目录结构
          • 2.PageInfo.java
          • 3.PageResult.java
          • 4.Result.java
          • 5.IsDeleteFlagEnum.java
          • 6.ResultCodeEnum.java
        • 4.sun-club-auth-application-controller层
          • 1.AuthUserDTO.java
          • 2.sun-club-auth-domain 模块
            • AuthUserBO.java 与DTO一致
          • 3.AuthUserDTOConverter.java
        • 5.sun-club-auth-domain层
          • 1.目录创建
          • 2.AuthUserBOConverter.java
          • 3.AuthUserDomainService.java
          • 4.AuthUserDomainServiceImpl.java
        • 6.sun-club-auth-infra层
          • 1.AuthUserService.java 修改insert返回为Integer
          • 2.AuthUserServiceImpl.java
          • 3.AuthUserDao.java
          • 4.AuthUserDao.xml
        • 7.最后:UserController.java
        • 8.测试
          • 1.接口设计
          • 2.结果
          • 3.DB
          • 4.发现DB中没有插入status
            • 1.sun-club-auth-common模块新增枚举 AuthUserStatusEnum.java
            • 2.sun-club-auth-application-controller UserController.java新增语句
            • 3.重启测试
    • 3.用户模块-更新用户信息
        • 1.接口设计
        • 2.sun-club-auth-application-controller
          • 1.UserController.java
        • 3.sun-club-auth-domain
          • 1.AuthUserDomainService.java
          • 2.AuthUserDomainServiceImpl.java
        • 4.sun-club-auth-infra
          • 1.AuthUserService.java
          • 2.AuthUserServiceImpl.java
        • 5.测试
          • 1.结果
          • 2.DB
    • 4.用户模块-删除用户信息
        • 1.接口设计
        • 2.sun-club-auth-application-controller
          • 1.UserController.java
        • 3.sun-club-auth-domain
          • 1.AuthUserDomainService.java
          • 2.AuthUserDomainServiceImpl.java
        • 4.测试
          • 1.结果
          • 2.DB
    • 5.用户模块-启用/禁用信息
        • 1.接口设计
        • 2.UserController.java
        • 3.测试
          • 1.结果
          • 2.DB

🌞 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。

🔗 更多信息

  • 开源地址:Gitee Sun Frame
  • 详细文档:语雀文档
    在这里插入图片描述

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 <T>
     */
    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 <T>
     */
    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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1983300.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

无人机动力系统详解

一、动力源 动力源是无人机动力系统的核心&#xff0c;负责提供飞行所需的能量。 二、传动系统 传动系统负责将动力源产生的能量传递到无人机的旋翼或螺旋桨上&#xff0c;使其产生升力。 三、控制系统 控制系统是无人机动力系统的“大脑”&#xff0c;它根据飞行指令和传…

C++ 正则表达式调试器

设计背景 部分网页正则表达式测试工具&#xff0c;输入$匹配符会卡死&#xff0c;决定自己实现一个 界面设计 关键代码 void RegexpDialog::on_edt_regx_textChanged(const QString &pattern) {auto text ui->edt_content->text();QRegularExpression regxp(patte…

C语言 ——— 学习并使用 strtok 函数

目录 strtok函数的功能 strtok函数的参数以及返回值​编辑 使用strtok函数 使用方法一&#xff1a;根据需要分段的字符串写代码 使用方法二&#xff1a;配合for循环巧妙使用 strtok函数的功能 将字符串拆分为各个段&#xff0c;举例说明&#xff1a; 输入&#xff1a; 第…

LVS-DR模式集群:案例与概念

DR模式&#xff08;直接路由&#xff09; 概念 Direct Routing&#xff0c;简称DR模式采用半开放式的网络结构&#xff0c;与TUN模式的结构类似&#xff0c;但内网服务器并不是分散在各地&#xff0c;而是与调度器位于同一个物理网络负载调度器与内网服务器通过本地网络连接&a…

SQL Server 临时存储过程及示例

在本文中&#xff0c;我们将深入探讨 SQL Server 中的临时存储过程&#xff0c;并提供一些实际的示例。在我们之前的文章中&#xff0c;我们讨论了 SQL Server 存储过程中的返回值。本文将详细介绍以下内容&#xff1a; 什么是 SQL Server 临时存储过程&#xff1f; 在数据库…

什么是面包板和杜邦线?

1.面包板&#xff1a;搭建电路 2.杜邦线&#xff1a;电流的连接线 分为三类&#xff1a;公公线&#xff0c;公母线&#xff0c;母母线

UE GAS学习

【Unreal】虚幻GAS系统快速入门-CSDN博客 GameplayTags FGameplayTags是一种层级标签&#xff0c;如Parent.Child.GrandChild。 通过GameplayTagManager进行注册。替代了原来的Bool&#xff0c;或Enum的结构&#xff0c;可以在玩法设计中更高效地标记对象的行为或状态。 Gamep…

【用C语言编写】题目名称:分数求和题目内容:计算1/1-1/2+1/3-1/4+1/5-......+1/99-1/100的值,打印出结果

题目名称&#xff1a;分数求和 题目内容&#xff1a;计算1/1-1/21/3-1/41/5-......1/99-1/100的值&#xff0c;打印出结果 错误的代码如下&#xff1a; #include <stdio.h> int main() {int i 0;double sum 0.0;int flag 1;for (i 1; i < 100; i){sum flag * 1/ …

OpenTiny HUICharts 正式开源发布,一个简单、易上手的图表组件库

引言 大家好&#xff01; 我们非常高兴地跟大家宣布&#xff0c;今天正式发布我们的新产品——OpenTiny HUICharts。这是一款前端 Web 可视化图表库&#xff0c;其基础图表功能构建于 ECharts 之上&#xff0c;而高阶图表则采用了新的底层技术&#xff0c;以满足更广泛的数据…

JAVA基础:String字符串

目录 前言 String的内部机制 String的两种创建方式 前言 关于String字符串我们并不陌生&#xff0c;在我们的程序中经常使用String这个类&#xff0c;甚至有的同学会把string当成基本数据类型&#xff0c;今天我们就来了解一下String这个类 String的内部机制 我们把string称为…

nature immunology | BACH2调控“调节性”和“促炎性”TH17细胞的染色质多样化状态

–https://doi.org/10.1038/s41590-024-01901-1 BACH2 regulates diversification of regulatory and proinflammatory chromatin states in TH17 cells 留意更多内容&#xff0c;欢迎关注微信公众号&#xff1a;组学之心 研究团队和研究单位 Aviv Regev–Genentech Vijay …

深度学习入门——深度学习

加深网络 前情回顾 构成神经网络的各种层学习时的有效技巧对图像特别有效的CNN参数的最优化方法 向更深的网络出发 网络特点 基于33 的小型滤波器的卷积层。激活函数是ReLU。全连接层的后面使用Dropout层。基于Adam的最优化。使用He初始值作为权重初始值。 进一步提高识别精…

【Linux】yum(工具篇)

文章目录 前言&#xff1a;什么是软件包yum 的介绍yum源yum源的配置第三方源的配置官方源的配置镜像站点安装wget包备份本地yum源配置网易yum源重新生成yum缓存 前言&#xff1a;什么是软件包 在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程…

【学术会议征稿】第三届环境遥感与地理信息技术国际学术会议(ERSGIT 2024)

第三届环境遥感与地理信息技术国际学术会议(ERSGIT 2024) 2024 3rd International Conference on Environmental Remote Sensing and Geographic Information Technology&#xff08;ERSGIT 2024&#xff09; 第三届环境遥感与地理信息技术国际学术会议&#xff08;ERSGIT 20…

LVS-DR集群的部署

LVS-DR集群 LVS-DR(Linux Virtual Server Director Server)工作模式&#xff0c;是生产环境中最常用的一种工作模式。 LVS-DR工作原理 LVS-DR 模式&#xff0c;Director Server 作为群集的访问入口&#xff0c;不作为网关使用&#xff0c;节点 DirectorServer 与 Real Serve…

zabbix7.0TLS-01-部署服务端

文章目录 1 介绍1.1 架构1.2 主要概念和名词1.3 最新 7.0 TLS 版本的部分新特性更灵活的资源发现和管理 2 官方部署指导地址3 在 Rocky Linux 9 上安装 zabbix3.1 安装软件包3.2 创建初始化数据库3.3 配置zabbix-server3.4 启动Zabbix server和agent进程3.5 默认监听端口3.6 访…

Linux中Samba服务配置和管理

文章目录 一、Samba介绍1.1、Samba是什么1.2、Samba的核心功能1.3、Samba的主要组件1.4、Samba的工作流程1.5、Samba主要配置文件smb.conf 二、Samba安装2.1、更新yum源2.2、安装Samba客户端和服务器软件包2.3、启动Samba 三、Samba的使用3.1、设置Samba服务的全局选项3.2、tes…

Simulink模型开发中的一些自动化方法

随着Simulink模型的产品化开发进程&#xff0c;许多模型开发人员会关心模型的建模自动化问题。比如如何对模型中的元素进行批量查找和修改&#xff1b;如何构建自己的建模规则对模型进行检查&#xff1b;如何实现测试自动化等。在这些使用场景中我们都需要了解一些Simulink函数…

Puppeteer-py:Python 中的无头浏览器自动化

1. 引言 在当今快速发展的互联网时代&#xff0c;自动化测试和数据抓取变得越来越重要。Puppeteer-py 作为一个 Python 库&#xff0c;提供了一种简单而强大的方法来控制无头浏览器&#xff0c;实现网页的自动化操作。无论是进行端到端的测试&#xff0c;还是抓取动态生成的数…

公司新来的两个Java后端,因题背太熟轻松过面试?

以前面试是背八股文&#xff0c;而2024年的后端面试都是流行问场景题&#xff01;建议大家把面试想简单一点&#xff0c;顺的场景题直接给有需要的人&#xff0c;希望能对大家有所帮助&#xff01; 由于平台篇幅原因&#xff0c;很多java面试资料内容展示不了&#xff0c;需要…