diff --git a/.gitignore b/.gitignore index c45175a..081d63d 100755 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,6 @@ build/ /han-note-auth/src/main/resources/application-prod.yml /han-note-auth/logs/ /logs/ -/.idea/ /han-note-oss/han-note-oss-biz/src/main/resources/application-dev.yml /han-note-user/han-note-user-biz/src/main/resources/application-dev.yml +/han-note-user/han-note-user-biz/logs/ diff --git a/han-note-auth/pom.xml b/han-note-auth/pom.xml index c119563..4e302a4 100755 --- a/han-note-auth/pom.xml +++ b/han-note-auth/pom.xml @@ -26,18 +26,6 @@ com.hanserwei hanserwei-spring-boot-starter-biz-operationlog - - com.mysql - mysql-connector-j - - - com.baomidou - mybatis-plus-spring-boot3-starter - - - com.alibaba - druid-spring-boot-3-starter - com.hanserwei hanserwei-spring-boot-starter-jackson @@ -102,6 +90,10 @@ org.springframework.security spring-security-crypto + + com.hanserwei + han-note-user-api + diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/HanNoteAuthApplication.java b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/HanNoteAuthApplication.java index 846cb53..65c7b9a 100755 --- a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/HanNoteAuthApplication.java +++ b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/HanNoteAuthApplication.java @@ -1,11 +1,11 @@ package com.hanserwei.hannote.auth; -import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication -@MapperScan("com.hanserwei.hannote.auth.domain.mapper") +@EnableFeignClients(basePackages = "com.hanserwei.hannote") public class HanNoteAuthApplication { public static void main(String[] args) { diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/controller/UserController.java b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/controller/AuthController.java similarity index 81% rename from han-note-auth/src/main/java/com/hanserwei/hannote/auth/controller/UserController.java rename to han-note-auth/src/main/java/com/hanserwei/hannote/auth/controller/AuthController.java index d9281cc..dc0fc03 100644 --- a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/controller/UserController.java +++ b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/controller/AuthController.java @@ -4,7 +4,7 @@ import com.hanserwei.framework.biz.operationlog.aspect.ApiOperationLog; import com.hanserwei.framework.common.response.Response; import com.hanserwei.hannote.auth.model.vo.user.UpdatePasswordReqVO; import com.hanserwei.hannote.auth.model.vo.user.UserLoginReqVO; -import com.hanserwei.hannote.auth.service.UserService; +import com.hanserwei.hannote.auth.service.AuthService; import jakarta.annotation.Resource; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -16,26 +16,26 @@ import org.springframework.web.bind.annotation.RestController; @RestController @Slf4j @RequiredArgsConstructor -public class UserController { +public class AuthController { @Resource - private UserService userService; + private AuthService authService; @PostMapping("/login") @ApiOperationLog(description = "用户登录/注册") public Response loginAndRegister(@Validated @RequestBody UserLoginReqVO userLoginReqVO) { - return userService.loginAndRegister(userLoginReqVO); + return authService.loginAndRegister(userLoginReqVO); } @PostMapping("/logout") @ApiOperationLog(description = "账号登出") public Response logout() { - return userService.logout(); + return authService.logout(); } @PostMapping("/password/update") @ApiOperationLog(description = "修改密码") public Response updatePassword(@Validated @RequestBody UpdatePasswordReqVO updatePasswordReqVO) { - return userService.updatePassword(updatePasswordReqVO); + return authService.updatePassword(updatePasswordReqVO); } } diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/dataobject/UserDO.java b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/dataobject/UserDO.java deleted file mode 100644 index 7bda988..0000000 --- a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/dataobject/UserDO.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.hanserwei.hannote.auth.domain.dataobject; - -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.time.LocalDate; -import java.time.LocalDateTime; - -/** - * 用户表 - */ -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -@TableName(value = "t_user") -public class UserDO { - /** - * 主键ID - */ - @TableId(value = "id", type = IdType.ASSIGN_ID) - private Long id; - - /** - * 小憨书号(唯一凭证) - */ - @TableField(value = "han_note_id") - private String hanNoteId; - - /** - * 密码 - */ - @TableField(value = "`password`") - private String password; - - /** - * 昵称 - */ - @TableField(value = "nickname") - private String nickname; - - /** - * 头像 - */ - @TableField(value = "avatar") - private String avatar; - - /** - * 生日 - */ - @TableField(value = "birthday") - private LocalDate birthday; - - /** - * 背景图 - */ - @TableField(value = "background_img") - private String backgroundImg; - - /** - * 邮箱 - */ - @TableField(value = "email") - private String email; - - /** - * 性别(0:女 1:男) - */ - @TableField(value = "sex") - private Integer sex; - - /** - * 状态(0:启用 1:禁用) - */ - @TableField(value = "`status`") - private Integer status; - - /** - * 个人简介 - */ - @TableField(value = "introduction") - private String introduction; - - /** - * 创建时间 - */ - @TableField(value = "create_time") - private LocalDateTime createTime; - - /** - * 更新时间 - */ - @TableField(value = "update_time") - private LocalDateTime updateTime; - - /** - * 逻辑删除(0:未删除 1:已删除) - */ - @TableField(value = "is_deleted") - private Boolean isDeleted; -} \ No newline at end of file diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/mapper/UserDOMapper.java b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/mapper/UserDOMapper.java deleted file mode 100644 index c5d844b..0000000 --- a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/mapper/UserDOMapper.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.hanserwei.hannote.auth.domain.mapper; - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.hanserwei.hannote.auth.domain.dataobject.UserDO; - -public interface UserDOMapper extends BaseMapper { -} \ No newline at end of file diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/enums/ResponseCodeEnum.java b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/enums/ResponseCodeEnum.java index 3caf502..62c04f9 100644 --- a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/enums/ResponseCodeEnum.java +++ b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/enums/ResponseCodeEnum.java @@ -18,6 +18,7 @@ public enum ResponseCodeEnum implements BaseExceptionInterface { LOGIN_TYPE_ERROR("AUTH-20002", "登录类型错误"), USER_NOT_FOUND("AUTH-20003", "该用户不存在"), MAIL_OR_PASSWORD_ERROR("AUTH-20004", "邮箱号或密码错误"), + LOGIN_FAIL("AUTH-20005", "登录失败"), diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/rpc/UserRpcService.java b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/rpc/UserRpcService.java new file mode 100644 index 0000000..42dee32 --- /dev/null +++ b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/rpc/UserRpcService.java @@ -0,0 +1,68 @@ +package com.hanserwei.hannote.auth.rpc; + +import com.hanserwei.framework.common.response.Response; +import com.hanserwei.hannote.user.api.UserFeignApi; +import com.hanserwei.hannote.user.dto.req.FindUserByEmailReqDTO; +import com.hanserwei.hannote.user.dto.req.RegisterUserReqDTO; +import com.hanserwei.hannote.user.dto.req.UpdateUserPasswordReqDTO; +import com.hanserwei.hannote.user.dto.resp.FindUserByEmailRspDTO; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + +@Component +public class UserRpcService { + + @Resource + private UserFeignApi userFeignApi; + + /** + * 用户注册 + * + * @param email 邮箱 + * @return 用户ID + */ + public Long registerUser(String email) { + RegisterUserReqDTO registerUserReqDTO = new RegisterUserReqDTO(); + registerUserReqDTO.setEmail(email); + + Response response = userFeignApi.registerUser(registerUserReqDTO); + + if (!response.isSuccess()) { + return null; + } + + return response.getData(); + } + + /** + * 根据邮箱号查询用户信息 + * + * @param email 邮箱 + * @return 用户信息 + */ + public FindUserByEmailRspDTO findUserByEmail(String email) { + FindUserByEmailReqDTO findUserByEmailReqDTO = new FindUserByEmailReqDTO(); + findUserByEmailReqDTO.setEmail(email); + + Response response = userFeignApi.findByPhone(findUserByEmailReqDTO); + + if (!response.isSuccess()) { + return null; + } + + return response.getData(); + } + + /** + * 密码更新 + * + * @param encodePassword 加密后的密码 + */ + public void updatePassword(String encodePassword) { + UpdateUserPasswordReqDTO updateUserPasswordReqDTO = new UpdateUserPasswordReqDTO(); + updateUserPasswordReqDTO.setEncodePassword(encodePassword); + + userFeignApi.updatePassword(updateUserPasswordReqDTO); + } + +} \ No newline at end of file diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/service/UserService.java b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/service/AuthService.java similarity index 79% rename from han-note-auth/src/main/java/com/hanserwei/hannote/auth/service/UserService.java rename to han-note-auth/src/main/java/com/hanserwei/hannote/auth/service/AuthService.java index 71932e6..88589cc 100644 --- a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/service/UserService.java +++ b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/service/AuthService.java @@ -1,12 +1,10 @@ package com.hanserwei.hannote.auth.service; -import com.baomidou.mybatisplus.extension.service.IService; import com.hanserwei.framework.common.response.Response; -import com.hanserwei.hannote.auth.domain.dataobject.UserDO; import com.hanserwei.hannote.auth.model.vo.user.UpdatePasswordReqVO; import com.hanserwei.hannote.auth.model.vo.user.UserLoginReqVO; -public interface UserService extends IService { +public interface AuthService { /** * 登录与注册 diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/service/impl/AuthServiceImpl.java b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/service/impl/AuthServiceImpl.java new file mode 100644 index 0000000..e9b00f1 --- /dev/null +++ b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/service/impl/AuthServiceImpl.java @@ -0,0 +1,130 @@ +package com.hanserwei.hannote.auth.service.impl; + +import cn.dev33.satoken.stp.SaTokenInfo; +import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.util.StrUtil; +import com.google.common.base.Preconditions; +import com.hanserwei.framework.biz.context.holder.LoginUserContextHolder; +import com.hanserwei.framework.common.exception.ApiException; +import com.hanserwei.framework.common.response.Response; +import com.hanserwei.hannote.auth.constant.RedisKeyConstants; +import com.hanserwei.hannote.auth.enums.LoginTypeEnum; +import com.hanserwei.hannote.auth.enums.ResponseCodeEnum; +import com.hanserwei.hannote.auth.model.vo.user.UpdatePasswordReqVO; +import com.hanserwei.hannote.auth.model.vo.user.UserLoginReqVO; +import com.hanserwei.hannote.auth.rpc.UserRpcService; +import com.hanserwei.hannote.auth.service.AuthService; +import com.hanserwei.hannote.user.dto.resp.FindUserByEmailRspDTO; +import jakarta.annotation.Resource; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; + +import java.util.Objects; + +@Slf4j +@Service +@RequiredArgsConstructor +public class AuthServiceImpl implements AuthService { + + + private final RedisTemplate redisTemplate; + private final UserRpcService userRpcService; + @Resource(name = "authTaskExecutor") + private ThreadPoolTaskExecutor authTaskExecutor; + private final PasswordEncoder passwordEncoder; + + @Override + public Response loginAndRegister(UserLoginReqVO reqVO) { + Integer loginType = reqVO.getType(); + String email = reqVO.getEmail(); + LoginTypeEnum loginTypeEnum = LoginTypeEnum.valueOf(loginType); + + Long userId = null; + + //noinspection DataFlowIssue + switch (loginTypeEnum) { + case VERIFICATION_CODE: + String verificationCode = reqVO.getCode(); + //校验参数是否为空 + Preconditions.checkArgument(StringUtils.isNotBlank(verificationCode), "验证码不能为空"); + + //构建验证码的RedisKey + String key = RedisKeyConstants.buildVerificationCodeKey(email); + // 查询存储在 Redis 中该用户的登录验证码 + String sentCode = (String) redisTemplate.opsForValue().get(key); + // 判断用户提交的验证码,与 Redis 中的验证码是否一致 + if (!StrUtil.equals(verificationCode, sentCode)) { + throw new ApiException(ResponseCodeEnum.VERIFICATION_CODE_ERROR); + } + // RPC: 调用用户服务,注册用户 + Long userIdTmp = userRpcService.registerUser(email); + + // 若调用用户服务,返回的用户 ID 为空,则提示登录失败 + if (Objects.isNull(userIdTmp)) { + throw new ApiException(ResponseCodeEnum.LOGIN_FAIL); + } + + userId = userIdTmp; + break; + case PASSWORD: + String password = reqVO.getPassword(); + + // RPC: 调用用户服务,通过手机号查询用户 + FindUserByEmailRspDTO findUserByEmailRspDTO = userRpcService.findUserByEmail(email); + + // 判断该手机号是否注册 + if (Objects.isNull(findUserByEmailRspDTO)) { + throw new ApiException(ResponseCodeEnum.USER_NOT_FOUND); + } + + // 拿到密文密码 + String encodePassword = findUserByEmailRspDTO.getPassword(); + + // 匹配密码是否一致 + boolean isPasswordCorrect = passwordEncoder.matches(password, encodePassword); + + // 如果不正确,则抛出业务异常,提示用户名或者密码不正确 + if (!isPasswordCorrect) { + throw new ApiException(ResponseCodeEnum.MAIL_OR_PASSWORD_ERROR); + } + + userId = findUserByEmailRspDTO.getId(); + break; + default: + break; + } + // SaToken 登录用户,并返回 token 令牌 + StpUtil.login(userId); + + SaTokenInfo tokenInfo = StpUtil.getTokenInfo(); + + return Response.success(tokenInfo.getTokenValue()); + } + + @Override + public Response logout() { + Long userId = LoginUserContextHolder.getUserId(); + authTaskExecutor.submit(() -> { + Long userId2 = LoginUserContextHolder.getUserId(); + log.info("==> 异步线程中获取 userId: {}", userId2); + }); + StpUtil.logout(userId); + return Response.success(); + } + + @Override + public Response updatePassword(UpdatePasswordReqVO updatePasswordReqVO) { + // 新密码 + String newPassword = updatePasswordReqVO.getNewPassword(); + // 加密后的密码 + String encodePassword = passwordEncoder.encode(newPassword); + // RPC: 调用用户服务:更新密码 + userRpcService.updatePassword(encodePassword); + return Response.success(); + } +} diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/service/impl/UserServiceImpl.java b/han-note-auth/src/main/java/com/hanserwei/hannote/auth/service/impl/UserServiceImpl.java deleted file mode 100644 index c41553c..0000000 --- a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/service/impl/UserServiceImpl.java +++ /dev/null @@ -1,196 +0,0 @@ -package com.hanserwei.hannote.auth.service.impl; - -import cn.dev33.satoken.stp.SaTokenInfo; -import cn.dev33.satoken.stp.StpUtil; -import cn.hutool.core.util.StrUtil; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.google.common.base.Preconditions; -import com.hanserwei.framework.biz.context.holder.LoginUserContextHolder; -import com.hanserwei.framework.common.enums.DeletedEnum; -import com.hanserwei.framework.common.enums.StatusEnum; -import com.hanserwei.framework.common.exception.ApiException; -import com.hanserwei.framework.common.response.Response; -import com.hanserwei.framework.common.utils.JsonUtils; -import com.hanserwei.hannote.auth.constant.RedisKeyConstants; -import com.hanserwei.hannote.auth.constant.RoleConstants; -import com.hanserwei.hannote.auth.domain.dataobject.RoleDO; -import com.hanserwei.hannote.auth.domain.dataobject.UserDO; -import com.hanserwei.hannote.auth.domain.dataobject.UserRoleDO; -import com.hanserwei.hannote.auth.domain.mapper.RoleDOMapper; -import com.hanserwei.hannote.auth.domain.mapper.UserDOMapper; -import com.hanserwei.hannote.auth.domain.mapper.UserRoleDOMapper; -import com.hanserwei.hannote.auth.enums.LoginTypeEnum; -import com.hanserwei.hannote.auth.enums.ResponseCodeEnum; -import com.hanserwei.hannote.auth.model.vo.user.UpdatePasswordReqVO; -import com.hanserwei.hannote.auth.model.vo.user.UserLoginReqVO; -import com.hanserwei.hannote.auth.service.UserService; -import jakarta.annotation.Resource; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Service; -import org.springframework.transaction.support.TransactionTemplate; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -@Slf4j -@Service -@RequiredArgsConstructor -public class UserServiceImpl extends ServiceImpl implements UserService { - - - private final RedisTemplate redisTemplate; - private final UserRoleDOMapper userRoleDOMapper; - private final TransactionTemplate transactionTemplate; - private final RoleDOMapper roleDOMapper; - @Resource(name = "authTaskExecutor") - private ThreadPoolTaskExecutor authTaskExecutor; - private final PasswordEncoder passwordEncoder; - - @Override - public Response loginAndRegister(UserLoginReqVO reqVO) { - Integer loginType = reqVO.getType(); - String email = reqVO.getEmail(); - LoginTypeEnum loginTypeEnum = LoginTypeEnum.valueOf(loginType); - - Long userId = null; - - //noinspection DataFlowIssue - switch (loginTypeEnum) { - case VERIFICATION_CODE: - String verificationCode = reqVO.getCode(); - //校验参数是否为空 - Preconditions.checkArgument(StringUtils.isNotBlank(verificationCode), "验证码不能为空"); - - //构建验证码的RedisKey - String key = RedisKeyConstants.buildVerificationCodeKey(email); - // 查询存储在 Redis 中该用户的登录验证码 - String sentCode = (String) redisTemplate.opsForValue().get(key); - // 判断用户提交的验证码,与 Redis 中的验证码是否一致 - if (!StrUtil.equals(verificationCode, sentCode)) { - throw new ApiException(ResponseCodeEnum.VERIFICATION_CODE_ERROR); - } - //通过邮箱查询用户 - UserDO userDO = this.getOne(new QueryWrapper().eq("email", email)); - log.info("==> 用户是否注册, email: {}, userDO: {}", email, JsonUtils.toJsonString(userDO)); - // 判断是否注册 - if (Objects.isNull(userDO)) { - // 若此用户还没有注册,系统自动注册该用户 - userId = registerUser(email); - } else { - // 已注册,则获取其用户 ID - userId = userDO.getId(); - } - break; - case PASSWORD: - String password = reqVO.getPassword(); - // 根据邮箱号查询 - UserDO userDO1 = this.getOne(new QueryWrapper().eq("email", email)); - if (Objects.isNull(userDO1)){ - throw new ApiException(ResponseCodeEnum.USER_NOT_FOUND); - } - // 拿到密文密码 - String encodePassword = userDO1.getPassword(); - boolean isPasswordCorrect = passwordEncoder.matches(password, encodePassword); - if (!isPasswordCorrect) { - throw new ApiException(ResponseCodeEnum.MAIL_OR_PASSWORD_ERROR); - } - userId = userDO1.getId(); - break; - default: - break; - } - // SaToken 登录用户,并返回 token 令牌 - StpUtil.login(userId); - - SaTokenInfo tokenInfo = StpUtil.getTokenInfo(); - - return Response.success(tokenInfo.getTokenValue()); - } - - public Long registerUser(String email) { - return transactionTemplate.execute(status -> { - try { - // 获取全局自增的小憨书ID - Long hanNoteId = redisTemplate.opsForValue().increment(RedisKeyConstants.HAN_NOTE_ID_GENERATOR_KEY); - UserDO userDO = UserDO.builder() - .hanNoteId(String.valueOf(hanNoteId)) // 自动生成小红书号 ID - .nickname("小憨憨" + hanNoteId) // 自动生成昵称, 如:小憨憨10000 - .status(StatusEnum.ENABLE.getValue()) // 状态为启用 - .email(email) - .createTime(LocalDateTime.now()) - .updateTime(LocalDateTime.now()) - .isDeleted(DeletedEnum.NO.getValue()) // 逻辑删除 - .build(); - - // 添加入库 - this.save(userDO); - - // 获取入库的用户ID - Long userId = userDO.getId(); - - // 添加默认用户角色 - UserRoleDO userRoleDO = UserRoleDO.builder() - .userId(userId) - .roleId(RoleConstants.COMMON_USER_ROLE_ID) - .createTime(LocalDateTime.now()) - .updateTime(LocalDateTime.now()) - .isDeleted(DeletedEnum.NO.getValue()) - .build(); - userRoleDOMapper.insert(userRoleDO); - - RoleDO roleDO = roleDOMapper.selectByPrimaryKey(RoleConstants.COMMON_USER_ROLE_ID); - - // 将该用户的角色 ID 存入 Redis 中,指定初始容量为 1,这样可以减少在扩容时的性能开销 - List roles = new ArrayList<>(1); - roles.add(roleDO.getRoleKey()); - - String userRolesKey = RedisKeyConstants.buildUserRoleKey(userId); - redisTemplate.opsForValue().set(userRolesKey, JsonUtils.toJsonString(roles)); - - return userId; - } catch (Exception e) { - status.setRollbackOnly(); // 标记事务为回滚 - log.error("==> 系统注册用户异常: ", e); - return null; - } - }); - } - - @Override - public Response logout() { - Long userId = LoginUserContextHolder.getUserId(); - authTaskExecutor.submit(() -> { - Long userId2 = LoginUserContextHolder.getUserId(); - log.info("==> 异步线程中获取 userId: {}", userId2); - }); - StpUtil.logout(userId); - return Response.success(); - } - - @Override - public Response updatePassword(UpdatePasswordReqVO updatePasswordReqVO) { - // 新密码 - String newPassword = updatePasswordReqVO.getNewPassword(); - // 加密后的密码 - String encodePassword = passwordEncoder.encode(newPassword); - // 获取用户ID - Long userId = LoginUserContextHolder.getUserId(); - - UserDO userDO = UserDO.builder() - .id(userId) - .password(encodePassword) - .updateTime(LocalDateTime.now()) - .build(); - // 更新用户密码 - this.updateById(userDO); - return Response.success(); - } -} diff --git a/han-note-auth/src/main/resources/application.yml b/han-note-auth/src/main/resources/application.yml index 024fea0..6ea4bd3 100755 --- a/han-note-auth/src/main/resources/application.yml +++ b/han-note-auth/src/main/resources/application.yml @@ -34,13 +34,6 @@ spring: mail.smtp.starttls.required: true server: port: 8080 # 项目启动的端口 -mybatis-plus: - configuration: - map-underscore-to-camel-case: true - log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl - global-config: - banner: false - mapper-locations: classpath*:/mapperxml/*.xml logging: level: com.hanserwei.hannote.auth.domain.mapper: debug @@ -62,5 +55,3 @@ sa-token: token-style: random-128 # 是否输出操作日志 is-log: true -alarm: - type: mail # 告警类型 diff --git a/han-note-auth/src/main/resources/mapperxml/UserDOMapper.xml b/han-note-auth/src/main/resources/mapperxml/UserDOMapper.xml deleted file mode 100644 index 490a8a1..0000000 --- a/han-note-auth/src/main/resources/mapperxml/UserDOMapper.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - id, han_note_id, `password`, nickname, avatar, birthday, background_img, email, sex, - `status`, introduction, create_time, update_time, is_deleted - - \ No newline at end of file diff --git a/han-note-auth/src/test/java/com/hanserwei/hannote/auth/DruidTests.java b/han-note-auth/src/test/java/com/hanserwei/hannote/auth/DruidTests.java deleted file mode 100644 index cc17864..0000000 --- a/han-note-auth/src/test/java/com/hanserwei/hannote/auth/DruidTests.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.hanserwei.hannote.auth; - -import com.alibaba.druid.filter.config.ConfigTools; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -@Slf4j -class DruidTests { - - - /** - * Druid 密码加密 - */ - @Test - @SneakyThrows - void testEncodePassword() { - // 你的密码 - String password = "mysql"; - String[] arr = ConfigTools.genKeyPair(512); - - // 私钥 - log.info("privateKey: {}", arr[0]); - // 公钥 - log.info("publicKey: {}", arr[1]); - - // 通过私钥加密密码 - String encodePassword = ConfigTools.encrypt(arr[0], password); - log.info("password: {}", encodePassword); - } - -} \ No newline at end of file diff --git a/han-note-auth/src/test/java/com/hanserwei/hannote/auth/HanNoteAuthApplicationTests.java b/han-note-auth/src/test/java/com/hanserwei/hannote/auth/HanNoteAuthApplicationTests.java deleted file mode 100755 index 3586e33..0000000 --- a/han-note-auth/src/test/java/com/hanserwei/hannote/auth/HanNoteAuthApplicationTests.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.hanserwei.hannote.auth; - - -import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -@Slf4j -class HanNoteAuthApplicationTests { - - - -} - diff --git a/han-note-auth/src/test/java/com/hanserwei/hannote/auth/RedisTests.java b/han-note-auth/src/test/java/com/hanserwei/hannote/auth/RedisTests.java deleted file mode 100644 index c4a8b7d..0000000 --- a/han-note-auth/src/test/java/com/hanserwei/hannote/auth/RedisTests.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.hanserwei.hannote.auth; - -import jakarta.annotation.Resource; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.data.redis.core.RedisTemplate; - -@SpringBootTest -@Slf4j -class RedisTests { - - @Resource - private RedisTemplate redisTemplate; - - /** - * set key value - */ - @Test - void testSetKeyValue() { - // 添加一个 key 为 name, value 值为 Hanserwei - redisTemplate.opsForValue().set("name", "Hanserwei"); - } - - /** - * 判断某个 key 是否存在 - */ - @Test - void testHasKey() { - log.info("key 是否存在:{}", redisTemplate.hasKey("name")); - } - - /** - * 获取某个 key 的 value - */ - @Test - void testGetValue() { - log.info("value 值:{}", redisTemplate.opsForValue().get("name")); - } - - /** - * 删除某个 key - */ - @Test - void testDelete() { - redisTemplate.delete("name"); - } - -} \ No newline at end of file diff --git a/han-note-auth/src/test/java/com/hanserwei/hannote/auth/ThreadPoolTaskExecutorTests.java b/han-note-auth/src/test/java/com/hanserwei/hannote/auth/ThreadPoolTaskExecutorTests.java deleted file mode 100644 index e82a62e..0000000 --- a/han-note-auth/src/test/java/com/hanserwei/hannote/auth/ThreadPoolTaskExecutorTests.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.hanserwei.hannote.auth; - -import jakarta.annotation.Resource; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; - -@SpringBootTest -@Slf4j -public class ThreadPoolTaskExecutorTests { - - @Resource - private ThreadPoolTaskExecutor threadPoolTaskExecutor; - - /** - * 测试线程池 - */ - @Test - void testSubmit() { - threadPoolTaskExecutor.submit(() -> log.info("异步线程中说: Hanserwei是傻逼")); - } -} \ No newline at end of file diff --git a/han-note-user/han-note-user-api/pom.xml b/han-note-user/han-note-user-api/pom.xml index 94e452b..befb92f 100644 --- a/han-note-user/han-note-user-api/pom.xml +++ b/han-note-user/han-note-user-api/pom.xml @@ -20,6 +20,18 @@ com.hanserwei hanserwei-common + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + diff --git a/han-note-user/han-note-user-api/src/main/java/com/hanserwei/hannote/user/api/UserFeignApi.java b/han-note-user/han-note-user-api/src/main/java/com/hanserwei/hannote/user/api/UserFeignApi.java new file mode 100644 index 0000000..29e0d77 --- /dev/null +++ b/han-note-user/han-note-user-api/src/main/java/com/hanserwei/hannote/user/api/UserFeignApi.java @@ -0,0 +1,45 @@ +package com.hanserwei.hannote.user.api; + +import com.hanserwei.framework.common.response.Response; +import com.hanserwei.hannote.user.constant.ApiConstants; +import com.hanserwei.hannote.user.dto.req.FindUserByEmailReqDTO; +import com.hanserwei.hannote.user.dto.req.RegisterUserReqDTO; +import com.hanserwei.hannote.user.dto.req.UpdateUserPasswordReqDTO; +import com.hanserwei.hannote.user.dto.resp.FindUserByEmailRspDTO; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +@FeignClient(name = ApiConstants.SERVICE_NAME) +public interface UserFeignApi { + + String PREFIX = "/user"; + + /** + * 用户注册 + * + * @param registerUserReqDTO 注册信息 + * @return 响应 + */ + @PostMapping(value = PREFIX + "/register") + Response registerUser(@RequestBody RegisterUserReqDTO registerUserReqDTO); + + /** + * 根据手机号查询用户信息 + * + * @param findUserByEmailReqDTO 查询信息请求 + * @return 响应 + */ + @PostMapping(value = PREFIX + "/findByEmail") + Response findByPhone(@RequestBody FindUserByEmailReqDTO findUserByEmailReqDTO); + + /** + * 更新密码 + * + * @param updateUserPasswordReqDTO 修改密码请求 + * @return 响应 + */ + @PostMapping(value = PREFIX + "/password/update") + Response updatePassword(@RequestBody UpdateUserPasswordReqDTO updateUserPasswordReqDTO); + +} \ No newline at end of file diff --git a/han-note-user/han-note-user-api/src/main/java/com/hanserwei/hannote/user/constant/ApiConstants.java b/han-note-user/han-note-user-api/src/main/java/com/hanserwei/hannote/user/constant/ApiConstants.java new file mode 100644 index 0000000..3d93fe5 --- /dev/null +++ b/han-note-user/han-note-user-api/src/main/java/com/hanserwei/hannote/user/constant/ApiConstants.java @@ -0,0 +1,9 @@ +package com.hanserwei.hannote.user.constant; + +public interface ApiConstants { + + /** + * 服务名称 + */ + String SERVICE_NAME = "han-note-user"; +} \ No newline at end of file diff --git a/han-note-user/han-note-user-api/src/main/java/com/hanserwei/hannote/user/dto/req/FindUserByEmailReqDTO.java b/han-note-user/han-note-user-api/src/main/java/com/hanserwei/hannote/user/dto/req/FindUserByEmailReqDTO.java new file mode 100644 index 0000000..7611599 --- /dev/null +++ b/han-note-user/han-note-user-api/src/main/java/com/hanserwei/hannote/user/dto/req/FindUserByEmailReqDTO.java @@ -0,0 +1,23 @@ +package com.hanserwei.hannote.user.dto.req; + +import com.hanserwei.framework.common.validate.EmailNumber; +import jakarta.validation.constraints.NotBlank; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class FindUserByEmailReqDTO { + + /** + * 邮箱号 + */ + @NotBlank(message = "邮箱号不能为空") + @EmailNumber + private String email; + +} \ No newline at end of file diff --git a/han-note-user/han-note-user-api/src/main/java/com/hanserwei/hannote/user/dto/req/RegisterUserReqDTO.java b/han-note-user/han-note-user-api/src/main/java/com/hanserwei/hannote/user/dto/req/RegisterUserReqDTO.java new file mode 100644 index 0000000..9fd67c5 --- /dev/null +++ b/han-note-user/han-note-user-api/src/main/java/com/hanserwei/hannote/user/dto/req/RegisterUserReqDTO.java @@ -0,0 +1,23 @@ +package com.hanserwei.hannote.user.dto.req; + +import com.hanserwei.framework.common.validate.EmailNumber; +import jakarta.validation.constraints.NotBlank; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class RegisterUserReqDTO { + + /** + * 手机号 + */ + @NotBlank(message = "邮箱号不能为空") + @EmailNumber + private String email; + +} \ No newline at end of file diff --git a/han-note-user/han-note-user-api/src/main/java/com/hanserwei/hannote/user/dto/req/UpdateUserPasswordReqDTO.java b/han-note-user/han-note-user-api/src/main/java/com/hanserwei/hannote/user/dto/req/UpdateUserPasswordReqDTO.java new file mode 100644 index 0000000..cd18466 --- /dev/null +++ b/han-note-user/han-note-user-api/src/main/java/com/hanserwei/hannote/user/dto/req/UpdateUserPasswordReqDTO.java @@ -0,0 +1,18 @@ +package com.hanserwei.hannote.user.dto.req; + +import jakarta.validation.constraints.NotBlank; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class UpdateUserPasswordReqDTO { + + @NotBlank(message = "密码不能为空") + private String encodePassword; + +} \ No newline at end of file diff --git a/han-note-user/han-note-user-api/src/main/java/com/hanserwei/hannote/user/dto/resp/FindUserByEmailRspDTO.java b/han-note-user/han-note-user-api/src/main/java/com/hanserwei/hannote/user/dto/resp/FindUserByEmailRspDTO.java new file mode 100644 index 0000000..28fe9e3 --- /dev/null +++ b/han-note-user/han-note-user-api/src/main/java/com/hanserwei/hannote/user/dto/resp/FindUserByEmailRspDTO.java @@ -0,0 +1,18 @@ +package com.hanserwei.hannote.user.dto.resp; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class FindUserByEmailRspDTO { + + private Long id; + + private String password; + +} \ No newline at end of file diff --git a/han-note-user/han-note-user-biz/pom.xml b/han-note-user/han-note-user-biz/pom.xml index 34c572e..dd75d46 100644 --- a/han-note-user/han-note-user-biz/pom.xml +++ b/han-note-user/han-note-user-biz/pom.xml @@ -70,6 +70,20 @@ com.hanserwei han-note-oss-api + + + org.springframework.boot + spring-boot-starter-data-redis + + + + org.apache.commons + commons-pool2 + + + com.hanserwei + han-note-user-api + diff --git a/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/config/RedisTemplateConfig.java b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/config/RedisTemplateConfig.java new file mode 100644 index 0000000..2f35cd8 --- /dev/null +++ b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/config/RedisTemplateConfig.java @@ -0,0 +1,31 @@ +package com.hanserwei.hannote.user.biz.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +@Configuration +public class RedisTemplateConfig { + + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) { + RedisTemplate redisTemplate = new RedisTemplate<>(); + // 设置 RedisTemplate 的连接工厂 + redisTemplate.setConnectionFactory(connectionFactory); + + // 使用 StringRedisSerializer 来序列化和反序列化 redis 的 key 值,确保 key 是可读的字符串 + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setHashKeySerializer(new StringRedisSerializer()); + + // 使用 Jackson2JsonRedisSerializer 来序列化和反序列化 redis 的 value 值, 确保存储的是 JSON 格式 + Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<>(Object.class); + redisTemplate.setValueSerializer(serializer); + redisTemplate.setHashValueSerializer(serializer); + + redisTemplate.afterPropertiesSet(); + return redisTemplate; + } +} \ No newline at end of file diff --git a/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/constant/RedisKeyConstants.java b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/constant/RedisKeyConstants.java new file mode 100644 index 0000000..99c6593 --- /dev/null +++ b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/constant/RedisKeyConstants.java @@ -0,0 +1,39 @@ +package com.hanserwei.hannote.user.biz.constant; + +public class RedisKeyConstants { + + /** + * 小憨书全局 ID 生成器 KEY + */ + public static final String HAN_NOTE_ID_GENERATOR_KEY = "hannote.id.generator"; + + /** + * 用户角色数据 KEY 前缀 + */ + private static final String USER_ROLES_KEY_PREFIX = "user:roles:"; + + /** + * 角色对应的权限集合 KEY 前缀 + */ + private static final String ROLE_PERMISSIONS_KEY_PREFIX = "role:permissions:"; + + /** + * 构建用户-角色 Key + * + * @param userId 邮箱 + * @return 用户角色key + */ + public static String buildUserRoleKey(Long userId) { + return USER_ROLES_KEY_PREFIX + userId; + } + + /** + * 构建角色对应的权限集合 KEY + * + * @param roleKey 角色ID + * @return 角色权限集合key + */ + public static String buildRolePermissionsKey(String roleKey) { + return ROLE_PERMISSIONS_KEY_PREFIX + roleKey; + } +} \ No newline at end of file diff --git a/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/constant/RoleConstants.java b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/constant/RoleConstants.java new file mode 100644 index 0000000..ca75c80 --- /dev/null +++ b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/constant/RoleConstants.java @@ -0,0 +1,11 @@ +package com.hanserwei.hannote.user.biz.constant; + +public class RoleConstants { + + + /** + * 普通用户的角色 ID + */ + public static final Long COMMON_USER_ROLE_ID = 1L; + +} \ No newline at end of file diff --git a/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/controller/UserController.java b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/controller/UserController.java index 4ce2807..3a0c739 100644 --- a/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/controller/UserController.java +++ b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/controller/UserController.java @@ -1,13 +1,19 @@ package com.hanserwei.hannote.user.biz.controller; +import com.hanserwei.framework.biz.operationlog.aspect.ApiOperationLog; import com.hanserwei.framework.common.response.Response; import com.hanserwei.hannote.user.biz.model.vo.UpdateUserInfoReqVO; import com.hanserwei.hannote.user.biz.service.UserService; +import com.hanserwei.hannote.user.dto.req.FindUserByEmailReqDTO; +import com.hanserwei.hannote.user.dto.req.RegisterUserReqDTO; +import com.hanserwei.hannote.user.dto.req.UpdateUserPasswordReqDTO; +import com.hanserwei.hannote.user.dto.resp.FindUserByEmailRspDTO; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.http.MediaType; import org.springframework.validation.annotation.Validated; 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; @@ -30,4 +36,23 @@ public class UserController { return userService.updateUserInfo(updateUserInfoReqVO); } + // ===================================== 对其他服务提供的接口 ===================================== + @PostMapping("/register") + @ApiOperationLog(description = "用户注册") + public Response register(@Validated @RequestBody RegisterUserReqDTO registerUserReqDTO) { + return userService.register(registerUserReqDTO); + } + + @PostMapping("/findByEmail") + @ApiOperationLog(description = "邮箱号查询用户信息") + public Response findByPhone(@Validated @RequestBody FindUserByEmailReqDTO findUserByEmailReqDTO) { + return userService.findByEmail(findUserByEmailReqDTO); + } + + @PostMapping("/password/update") + @ApiOperationLog(description = "密码更新") + public Response updatePassword(@Validated @RequestBody UpdateUserPasswordReqDTO updateUserPasswordReqDTO) { + return userService.updatePassword(updateUserPasswordReqDTO); + } + } \ No newline at end of file diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/dataobject/PermissionDO.java b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/dataobject/PermissionDO.java similarity index 96% rename from han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/dataobject/PermissionDO.java rename to han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/dataobject/PermissionDO.java index c3e11c0..2a772fa 100644 --- a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/dataobject/PermissionDO.java +++ b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/dataobject/PermissionDO.java @@ -1,14 +1,15 @@ -package com.hanserwei.hannote.auth.domain.dataobject; +package com.hanserwei.hannote.user.biz.domain.dataobject; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import java.util.Date; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import java.util.Date; + /** * 权限表 */ diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/dataobject/RoleDO.java b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/dataobject/RoleDO.java similarity index 96% rename from han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/dataobject/RoleDO.java rename to han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/dataobject/RoleDO.java index 983636a..3645884 100644 --- a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/dataobject/RoleDO.java +++ b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/dataobject/RoleDO.java @@ -1,14 +1,15 @@ -package com.hanserwei.hannote.auth.domain.dataobject; +package com.hanserwei.hannote.user.biz.domain.dataobject; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import java.util.Date; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import java.util.Date; + /** * 角色表 */ diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/dataobject/RolePermissionDO.java b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/dataobject/RolePermissionDO.java similarity index 94% rename from han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/dataobject/RolePermissionDO.java rename to han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/dataobject/RolePermissionDO.java index 11a54d9..a4395d5 100644 --- a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/dataobject/RolePermissionDO.java +++ b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/dataobject/RolePermissionDO.java @@ -1,14 +1,15 @@ -package com.hanserwei.hannote.auth.domain.dataobject; +package com.hanserwei.hannote.user.biz.domain.dataobject; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import java.util.Date; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import java.util.Date; + /** * 用户权限表 */ diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/dataobject/UserRoleDO.java b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/dataobject/UserRoleDO.java similarity index 95% rename from han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/dataobject/UserRoleDO.java rename to han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/dataobject/UserRoleDO.java index 2dedc7b..e795e54 100644 --- a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/dataobject/UserRoleDO.java +++ b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/dataobject/UserRoleDO.java @@ -1,4 +1,4 @@ -package com.hanserwei.hannote.auth.domain.dataobject; +package com.hanserwei.hannote.user.biz.domain.dataobject; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/mapper/PermissionDOMapper.java b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/mapper/PermissionDOMapper.java similarity index 70% rename from han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/mapper/PermissionDOMapper.java rename to han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/mapper/PermissionDOMapper.java index a16a0ba..6546017 100644 --- a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/mapper/PermissionDOMapper.java +++ b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/mapper/PermissionDOMapper.java @@ -1,7 +1,7 @@ -package com.hanserwei.hannote.auth.domain.mapper; +package com.hanserwei.hannote.user.biz.domain.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.hanserwei.hannote.auth.domain.dataobject.PermissionDO; +import com.hanserwei.hannote.user.biz.domain.dataobject.PermissionDO; import java.util.List; diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/mapper/RoleDOMapper.java b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/mapper/RoleDOMapper.java similarity index 73% rename from han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/mapper/RoleDOMapper.java rename to han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/mapper/RoleDOMapper.java index e069e75..5d420a5 100644 --- a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/mapper/RoleDOMapper.java +++ b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/mapper/RoleDOMapper.java @@ -1,7 +1,7 @@ -package com.hanserwei.hannote.auth.domain.mapper; +package com.hanserwei.hannote.user.biz.domain.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.hanserwei.hannote.auth.domain.dataobject.RoleDO; +import com.hanserwei.hannote.user.biz.domain.dataobject.RoleDO; import java.util.List; diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/mapper/RolePermissionDOMapper.java b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/mapper/RolePermissionDOMapper.java similarity index 76% rename from han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/mapper/RolePermissionDOMapper.java rename to han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/mapper/RolePermissionDOMapper.java index afac2bc..14b4811 100644 --- a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/mapper/RolePermissionDOMapper.java +++ b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/mapper/RolePermissionDOMapper.java @@ -1,7 +1,7 @@ -package com.hanserwei.hannote.auth.domain.mapper; +package com.hanserwei.hannote.user.biz.domain.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.hanserwei.hannote.auth.domain.dataobject.RolePermissionDO; +import com.hanserwei.hannote.user.biz.domain.dataobject.RolePermissionDO; import org.apache.ibatis.annotations.Param; import java.util.List; diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/mapper/UserRoleDOMapper.java b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/mapper/UserRoleDOMapper.java similarity index 50% rename from han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/mapper/UserRoleDOMapper.java rename to han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/mapper/UserRoleDOMapper.java index 3c0cdbf..c91d52a 100644 --- a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/domain/mapper/UserRoleDOMapper.java +++ b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/domain/mapper/UserRoleDOMapper.java @@ -1,7 +1,7 @@ -package com.hanserwei.hannote.auth.domain.mapper; +package com.hanserwei.hannote.user.biz.domain.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.hanserwei.hannote.auth.domain.dataobject.UserRoleDO; +import com.hanserwei.hannote.user.biz.domain.dataobject.UserRoleDO; public interface UserRoleDOMapper extends BaseMapper { } \ No newline at end of file diff --git a/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/enums/ResponseCodeEnum.java b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/enums/ResponseCodeEnum.java index 97c1f0f..74f9f10 100644 --- a/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/enums/ResponseCodeEnum.java +++ b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/enums/ResponseCodeEnum.java @@ -19,6 +19,7 @@ public enum ResponseCodeEnum implements BaseExceptionInterface { INTRODUCTION_VALID_FAIL("USER-20004", "个人简介请设置1-100个字符"), UPLOAD_AVATAR_FAIL("USER-20005", "头像上传失败"), UPLOAD_BACKGROUND_IMG_FAIL("USER-20006", "背景图上传失败"), + USER_NOT_FOUND("USER-20007", "该用户不存在"), ; // 异常码 diff --git a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/runner/PushRolePermissions2RedisRunner.java b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/runner/PushRolePermissions2RedisRunner.java similarity index 89% rename from han-note-auth/src/main/java/com/hanserwei/hannote/auth/runner/PushRolePermissions2RedisRunner.java rename to han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/runner/PushRolePermissions2RedisRunner.java index 0f1abd2..8e28157 100644 --- a/han-note-auth/src/main/java/com/hanserwei/hannote/auth/runner/PushRolePermissions2RedisRunner.java +++ b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/runner/PushRolePermissions2RedisRunner.java @@ -1,16 +1,16 @@ -package com.hanserwei.hannote.auth.runner; +package com.hanserwei.hannote.user.biz.runner; import cn.hutool.core.collection.CollUtil; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.hanserwei.framework.common.utils.JsonUtils; -import com.hanserwei.hannote.auth.constant.RedisKeyConstants; -import com.hanserwei.hannote.auth.domain.dataobject.PermissionDO; -import com.hanserwei.hannote.auth.domain.dataobject.RoleDO; -import com.hanserwei.hannote.auth.domain.dataobject.RolePermissionDO; -import com.hanserwei.hannote.auth.domain.mapper.PermissionDOMapper; -import com.hanserwei.hannote.auth.domain.mapper.RoleDOMapper; -import com.hanserwei.hannote.auth.domain.mapper.RolePermissionDOMapper; +import com.hanserwei.hannote.user.biz.constant.RedisKeyConstants; +import com.hanserwei.hannote.user.biz.domain.dataobject.PermissionDO; +import com.hanserwei.hannote.user.biz.domain.dataobject.RoleDO; +import com.hanserwei.hannote.user.biz.domain.dataobject.RolePermissionDO; +import com.hanserwei.hannote.user.biz.domain.mapper.PermissionDOMapper; +import com.hanserwei.hannote.user.biz.domain.mapper.RoleDOMapper; +import com.hanserwei.hannote.user.biz.domain.mapper.RolePermissionDOMapper; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.ApplicationArguments; diff --git a/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/service/UserService.java b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/service/UserService.java index cde35b9..efbe969 100644 --- a/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/service/UserService.java +++ b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/service/UserService.java @@ -4,6 +4,10 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.hanserwei.framework.common.response.Response; import com.hanserwei.hannote.user.biz.domain.dataobject.UserDO; import com.hanserwei.hannote.user.biz.model.vo.UpdateUserInfoReqVO; +import com.hanserwei.hannote.user.dto.req.FindUserByEmailReqDTO; +import com.hanserwei.hannote.user.dto.req.RegisterUserReqDTO; +import com.hanserwei.hannote.user.dto.req.UpdateUserPasswordReqDTO; +import com.hanserwei.hannote.user.dto.resp.FindUserByEmailRspDTO; public interface UserService extends IService { @@ -14,4 +18,28 @@ public interface UserService extends IService { * @return 响应结果 */ Response updateUserInfo(UpdateUserInfoReqVO updateUserInfoReqVO); + + /** + * 用户注册 + * + * @param registerUserReqDTO 注册用户请求参数 + * @return 响应结果 + */ + Response register(RegisterUserReqDTO registerUserReqDTO); + + /** + * 根据邮箱号查询用户信息 + * + * @param findUserByEmailReqDTO 查询用户信息请求参数 + * @return 响应结果 + */ + Response findByEmail(FindUserByEmailReqDTO findUserByEmailReqDTO); + + /** + * 更新密码 + * + * @param updateUserPasswordReqDTO 更新密码请求参数 + * @return 响应结果 + */ + Response updatePassword(UpdateUserPasswordReqDTO updateUserPasswordReqDTO); } \ No newline at end of file diff --git a/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/service/impl/UserServiceImpl.java b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/service/impl/UserServiceImpl.java index 4544921..066c62f 100644 --- a/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/service/impl/UserServiceImpl.java +++ b/han-note-user/han-note-user-biz/src/main/java/com/hanserwei/hannote/user/biz/service/impl/UserServiceImpl.java @@ -1,26 +1,44 @@ package com.hanserwei.hannote.user.biz.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.google.common.base.Preconditions; import com.hanserwei.framework.biz.context.holder.LoginUserContextHolder; +import com.hanserwei.framework.common.enums.DeletedEnum; +import com.hanserwei.framework.common.enums.StatusEnum; import com.hanserwei.framework.common.exception.ApiException; import com.hanserwei.framework.common.response.Response; +import com.hanserwei.framework.common.utils.JsonUtils; import com.hanserwei.framework.common.utils.ParamUtils; +import com.hanserwei.hannote.user.biz.constant.RedisKeyConstants; +import com.hanserwei.hannote.user.biz.constant.RoleConstants; +import com.hanserwei.hannote.user.biz.domain.dataobject.RoleDO; import com.hanserwei.hannote.user.biz.domain.dataobject.UserDO; +import com.hanserwei.hannote.user.biz.domain.dataobject.UserRoleDO; +import com.hanserwei.hannote.user.biz.domain.mapper.RoleDOMapper; import com.hanserwei.hannote.user.biz.domain.mapper.UserDOMapper; +import com.hanserwei.hannote.user.biz.domain.mapper.UserRoleDOMapper; import com.hanserwei.hannote.user.biz.enums.ResponseCodeEnum; import com.hanserwei.hannote.user.biz.enums.SexEnum; import com.hanserwei.hannote.user.biz.model.vo.UpdateUserInfoReqVO; import com.hanserwei.hannote.user.biz.rpc.OssRpcService; import com.hanserwei.hannote.user.biz.service.UserService; +import com.hanserwei.hannote.user.dto.req.FindUserByEmailReqDTO; +import com.hanserwei.hannote.user.dto.req.RegisterUserReqDTO; +import com.hanserwei.hannote.user.dto.req.UpdateUserPasswordReqDTO; +import com.hanserwei.hannote.user.dto.resp.FindUserByEmailRspDTO; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; @Service @@ -29,6 +47,12 @@ public class UserServiceImpl extends ServiceImpl implement @Resource private OssRpcService ossRpcService; + @Resource + private UserRoleDOMapper userRoleDOMapper; + @Resource + private RoleDOMapper roleDOMapper; + @Resource + private RedisTemplate redisTemplate; @Override public Response updateUserInfo(UpdateUserInfoReqVO updateUserInfoReqVO) { @@ -114,4 +138,92 @@ public class UserServiceImpl extends ServiceImpl implement } return Response.success(); } + + @Override + @Transactional(rollbackFor = Exception.class) + public Response register(RegisterUserReqDTO registerUserReqDTO) { + String email = registerUserReqDTO.getEmail(); + + // 先判断该手机号是否已被注册 + UserDO userDO1 = this.getOne(new QueryWrapper().eq("email", email)); + + log.info("==> 用户是否注册, email: {}, userDO: {}", email, JsonUtils.toJsonString(userDO1)); + + // 若已注册,则直接返回用户 ID + if (Objects.nonNull(userDO1)) { + return Response.success(userDO1.getId()); + } + + // 否则注册新用户 + // 获取全局自增的小憨书 ID + Long hanNoteId = redisTemplate.opsForValue().increment(RedisKeyConstants.HAN_NOTE_ID_GENERATOR_KEY); + + UserDO userDO = UserDO.builder() + .email(email) + .hanNoteId(String.valueOf(hanNoteId)) // 自动生成小憨书号 ID + .nickname("小憨憨" + hanNoteId) // 自动生成昵称, 如:小憨憨10000 + .status(StatusEnum.ENABLE.getValue()) // 状态为启用 + .createTime(LocalDateTime.now()) + .updateTime(LocalDateTime.now()) + .isDeleted(DeletedEnum.NO.getValue()) // 逻辑删除 + .build(); + + // 添加入库 + this.save(userDO); + + // 获取刚刚添加入库的用户 ID + Long userId = userDO.getId(); + + // 给该用户分配一个默认角色 + UserRoleDO userRoleDO = UserRoleDO.builder() + .userId(userId) + .roleId(RoleConstants.COMMON_USER_ROLE_ID) + .createTime(LocalDateTime.now()) + .updateTime(LocalDateTime.now()) + .isDeleted(DeletedEnum.NO.getValue()) + .build(); + userRoleDOMapper.insert(userRoleDO); + + RoleDO roleDO = roleDOMapper.selectByPrimaryKey(RoleConstants.COMMON_USER_ROLE_ID); + + // 将该用户的角色 ID 存入 Redis 中 + List roles = new ArrayList<>(1); + roles.add(roleDO.getRoleKey()); + + String userRolesKey = RedisKeyConstants.buildUserRoleKey(userId); + redisTemplate.opsForValue().set(userRolesKey, JsonUtils.toJsonString(roles)); + + return Response.success(userId); + } + + @Override + public Response findByEmail(FindUserByEmailReqDTO findUserByEmailReqDTO) { + String email = findUserByEmailReqDTO.getEmail(); + UserDO userDO = this.getOne(new QueryWrapper().eq("email", email)); + if (Objects.isNull(userDO)){ + throw new ApiException(ResponseCodeEnum.USER_NOT_FOUND); + } + // 构建返参 + FindUserByEmailRspDTO findUserByEmailRspDTO = FindUserByEmailRspDTO.builder() + .id(userDO.getId()) + .password(userDO.getPassword()) + .build(); + return Response.success(findUserByEmailRspDTO); + } + + @Override + public Response updatePassword(UpdateUserPasswordReqDTO updateUserPasswordReqDTO) { + // 获取当前请求对应的用户 ID + Long userId = LoginUserContextHolder.getUserId(); + + UserDO userDO = UserDO.builder() + .id(userId) + .password(updateUserPasswordReqDTO.getEncodePassword()) // 加密后的密码 + .updateTime(LocalDateTime.now()) + .build(); + + // 更新用户密码 + return updateById(userDO) ? Response.success() : Response.fail(); + } } + diff --git a/han-note-user/han-note-user-biz/src/main/resources/application.yml b/han-note-user/han-note-user-biz/src/main/resources/application.yml index e532ea4..78396c3 100644 --- a/han-note-user/han-note-user-biz/src/main/resources/application.yml +++ b/han-note-user/han-note-user-biz/src/main/resources/application.yml @@ -8,6 +8,20 @@ spring: multipart: max-file-size: 20MB # 单个文件最大大小 max-request-size: 100MB # 单次请求最大大小(包含多个文件) + data: + redis: + database: 5 # Redis 数据库索引(默认为 0) + host: 127.0.0.1 # Redis 服务器地址 + port: 6379 # Redis 服务器连接端口 + password: redis # Redis 服务器连接密码(默认为空) + timeout: 5s # 读超时时间 + connect-timeout: 5s # 链接超时时间 + lettuce: + pool: + max-active: 200 # 连接池最大连接数 + max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) + min-idle: 0 # 连接池中的最小空闲连接 + max-idle: 10 # 连接池中的最大空闲连接 mybatis-plus: configuration: map-underscore-to-camel-case: true diff --git a/han-note-auth/src/main/resources/mapperxml/PermissionDOMapper.xml b/han-note-user/han-note-user-biz/src/main/resources/mapperxml/PermissionDOMapper.xml similarity index 88% rename from han-note-auth/src/main/resources/mapperxml/PermissionDOMapper.xml rename to han-note-user/han-note-user-biz/src/main/resources/mapperxml/PermissionDOMapper.xml index 29a0b97..d53f35a 100644 --- a/han-note-auth/src/main/resources/mapperxml/PermissionDOMapper.xml +++ b/han-note-user/han-note-user-biz/src/main/resources/mapperxml/PermissionDOMapper.xml @@ -1,7 +1,7 @@ - - + + diff --git a/han-note-auth/src/main/resources/mapperxml/RoleDOMapper.xml b/han-note-user/han-note-user-biz/src/main/resources/mapperxml/RoleDOMapper.xml similarity index 89% rename from han-note-auth/src/main/resources/mapperxml/RoleDOMapper.xml rename to han-note-user/han-note-user-biz/src/main/resources/mapperxml/RoleDOMapper.xml index 3e6bc0e..8f436f5 100644 --- a/han-note-auth/src/main/resources/mapperxml/RoleDOMapper.xml +++ b/han-note-user/han-note-user-biz/src/main/resources/mapperxml/RoleDOMapper.xml @@ -1,7 +1,7 @@ - - + + diff --git a/han-note-auth/src/main/resources/mapperxml/RolePermissionDOMapper.xml b/han-note-user/han-note-user-biz/src/main/resources/mapperxml/RolePermissionDOMapper.xml similarity index 84% rename from han-note-auth/src/main/resources/mapperxml/RolePermissionDOMapper.xml rename to han-note-user/han-note-user-biz/src/main/resources/mapperxml/RolePermissionDOMapper.xml index c7a3893..a660801 100644 --- a/han-note-auth/src/main/resources/mapperxml/RolePermissionDOMapper.xml +++ b/han-note-user/han-note-user-biz/src/main/resources/mapperxml/RolePermissionDOMapper.xml @@ -1,7 +1,7 @@ - - + + diff --git a/han-note-auth/src/main/resources/mapperxml/UserRoleDOMapper.xml b/han-note-user/han-note-user-biz/src/main/resources/mapperxml/UserRoleDOMapper.xml similarity index 80% rename from han-note-auth/src/main/resources/mapperxml/UserRoleDOMapper.xml rename to han-note-user/han-note-user-biz/src/main/resources/mapperxml/UserRoleDOMapper.xml index d358bb0..49491bb 100644 --- a/han-note-auth/src/main/resources/mapperxml/UserRoleDOMapper.xml +++ b/han-note-user/han-note-user-biz/src/main/resources/mapperxml/UserRoleDOMapper.xml @@ -1,7 +1,7 @@ - - + + diff --git a/han-note-user/han-note-user-biz/src/test/java/HannoteIdGenerateTest.java b/han-note-user/han-note-user-biz/src/test/java/HannoteIdGenerateTest.java new file mode 100644 index 0000000..73668c2 --- /dev/null +++ b/han-note-user/han-note-user-biz/src/test/java/HannoteIdGenerateTest.java @@ -0,0 +1,20 @@ +import com.hanserwei.hannote.user.biz.HannoteUserBizApplication; +import com.hanserwei.hannote.user.biz.constant.RedisKeyConstants; +import jakarta.annotation.Resource; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.redis.core.RedisTemplate; + +@SpringBootTest(classes = HannoteUserBizApplication.class) +public class HannoteIdGenerateTest { + + @Resource + private RedisTemplate redisTemplate; + + @Test + public void test() { +// Long id = redisTemplate.opsForValue().increment(RedisKeyConstants.HAN_NOTE_ID_GENERATOR_KEY); + Object id = redisTemplate.opsForValue().get(RedisKeyConstants.HAN_NOTE_ID_GENERATOR_KEY); + System.out.println(id); + } +} diff --git a/pom.xml b/pom.xml index 616dc0f..517e121 100755 --- a/pom.xml +++ b/pom.xml @@ -215,6 +215,13 @@ feign-form ${feign-form.version} + + com.hanserwei + han-note-user-api + ${revision} + + +