文章目录
- 🌞 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 是我个人开源的一款基于 SpringBoot 的轻量级框架,专为中小型企业设计。它提供了一种快速、简单且易于扩展的开发方式。
我们的开发文档记录了整个项目从0到1的任何细节,实属不易,请给我们一个Star!🌟
您的支持是我们持续改进的动力。
您的支持是我们持续改进的动力。
🌟 亮点功能
- 组件化开发:灵活选择,简化流程。
- 高性能:通过异步日志和 Redis 缓存提升性能。
- 易扩展:支持多种数据库和消息队列。
📦 spring cloud模块概览
- Nacos 服务:高效的服务注册与发现。
- Feign 远程调用:简化服务间通信。
- 强大网关:路由与限流。
常用工具
- 日志管理:异步处理与链路追踪。
- Redis 集成:支持分布式锁与缓存。
- Swagger 文档:便捷的 API 入口。
- 测试支持:SpringBoot-Test 集成。
- EasyCode:自定义EasyCode模板引擎,一键生成CRUD。
🔗 更多信息
- 开源地址:Gitee Sun Frame
- 详细文档:语雀文档
1.Gateway实现Redis拉取信息
1.目录结构
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.创建好目录
2.配置生成代码
3.将dao层的类剪切到mapper层
4.AuthUserDao.java删除Pageable的参数
5.service层删除分页查询接口和实现类
6.最终目录结构
2.sun-club-auth-application-controller 基本配置
1.目录创建
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.目录结构
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.目录创建
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.接口设计
2.结果
3.DB
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.重启测试
3.用户模块-更新用户信息
1.接口设计
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.结果
2.DB
4.用户模块-删除用户信息
1.接口设计
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.结果
2.DB
5.用户模块-启用/禁用信息
1.接口设计
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("用户启用/禁用失败");
}
}