Java项目:Java脚手架项目的 B 端用户服务(十四)

文章目录

  • 前言
  • [一、B 端用户服务](#一、B 端用户服务)
    • [1.1 在 admin-service 下创建 user 包](#1.1 在 admin-service 下创建 user 包)
      • [1.1.1 在 user 包下创建 config、controller、domain、mapper、service 包](#1.1.1 在 user 包下创建 config、controller、domain、mapper、service 包)
      • [1.1.2 在 domain 包下创建 dto、vo、entity](#1.1.2 在 domain 包下创建 dto、vo、entity)
      • [1.1.3 在 mapper 下创建数据库接口](#1.1.3 在 mapper 下创建数据库接口)
      • [1.1.4 在 controller 包下创建控制器](#1.1.4 在 controller 包下创建控制器)
      • [1.1.5 在 service 包下创建接口及其实体类](#1.1.5 在 service 包下创建接口及其实体类)
      • [1.1.6 在 config 包下创建配置类](#1.1.6 在 config 包下创建配置类)
  • [二、验证用户登录和 B 端用户登录](#二、验证用户登录和 B 端用户登录)
  • END

鸡汤:
● 代码会过时,但解决问题的思维永远闪光。
● 记得:关掉屏幕时,窗外的夕阳、家人的笑脸、散步的微风------这些"非代码变量",才是生活的主函数。

前言

前面实现了登录认证服务,现在开始实现用户服务。

一、B 端用户服务

因为 B 端用户流量小、改动少,所以可以将 B 端用户登录服务放在 admin 基础管理服务里

1.1 在 admin-service 下创建 user 包

1.1.1 在 user 包下创建 config、controller、domain、mapper、service 包

1.1.2 在 domain 包下创建 dto、vo、entity


dto:
PasswordLoginDTO:

java 复制代码
package com.my.adminservice.user.domain.dto;

import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;


/**
 * 账号密码登录信息
 */
@Getter
@Setter
public class PasswordLoginDTO implements Serializable {

    /**
     * 手机号
     */
    @NotBlank(message = "手机号不能为空")
    private String phone;

    /**
     * 密码
     */
    @NotBlank(message = "密码不能为空")
    private String password;
}

SysLoginUserDTO:

java 复制代码
package com.my.adminservice.user.domain.dto;

import com.my.adminservice.user.domain.vo.SysLoginUserVO;
import com.my.commoncore.utils.BeanCopyUtil;
import com.my.commonsecurity.domain.dto.LoginUserDTO;
import lombok.Data;

@Data
public class SysLoginUserDTO extends LoginUserDTO {

    /**
     * 昵称
     */
    private String nickName;

    /**
     * 身份
     */
    private String identity;

    /**
     * 状态
     */
    private String status;

    /**
     * B端用户登录信息DTO转VO
     * @return B端用户登录信息VO
     */
    public SysLoginUserVO convertToVO() {
        SysLoginUserVO sysLoginUserVO = new SysLoginUserVO();
        BeanCopyUtil.copyProperties(this, sysLoginUserVO);
        return sysLoginUserVO;
    }
}

SysUserDTO:

java 复制代码
package com.my.adminservice.user.domain.dto;

import com.my.adminservice.user.domain.vo.SysUserVO;
import com.my.commoncore.utils.BeanCopyUtil;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

/**
 * B端用户信息
 */
@Data
public class SysUserDTO {

    /**
     * B端人员用户ID
     */
    private Long id;

    /**
     * 用户昵称
     */
    @NotBlank(message = "昵称不能为空")
    private String nickName;

    /**
     * 手机号
     */
    private String phoneNumber;

    /**
     * 密码
     */
    private String password;

    /**
     * 身份
     */
    private String identity;

    /**
     * 备注
     */
    private String remark;

    /**
     * 状态
     */
    @NotBlank(message = "状态不能为空")
    private String status;


    /**
     * 校验密码是否合理
     * @return 布尔类型
     */
    public boolean checkPassword() {
        if(!StringUtils.isNotBlank(password)){
            return false;
        }
        if(password.length() > 20 ||  password.length() < 6){
            return false;
        }
        return password.matches("^[a-zA-Z0-9]+$");
    }

    /**
     * DTO转换VO
     * @return B端用户VO
     */
    public SysUserVO convertToVO() {
        SysUserVO sysUserVo = new SysUserVO();
        sysUserVo.setId(this.id);
        sysUserVo.setIdentity(this.identity);
        sysUserVo.setPhoneNumber(this.phoneNumber);
        sysUserVo.setNickName(this.nickName);
        sysUserVo.setStatus(this.status);
        sysUserVo.setRemark(this.remark);
        return sysUserVo;
    }
}

SysUserListReqDTO:

java 复制代码
package com.my.adminservice.user.domain.dto;

import lombok.Data;

import java.io.Serializable;

/**
 * B端用户查询DTO
 */
@Data
public class SysUserListReqDTO implements Serializable {

    /**
     * 用户ID
     */
    private Long id;

    /**
     * 手机号
     */
    private String phoneNumber;

    /**
     * 状态
     */
    private String status;
}

vo:
SysLoginUserVO:

java 复制代码
package com.my.adminservice.user.domain.vo;

import com.my.commonsecurity.domain.vo.LoginUserVO;
import lombok.Data;

/**
 * B端用户登录信息
 */
@Data
public class SysLoginUserVO extends LoginUserVO {

    /**
     * 昵称
     */
    private String nickName;

    /**
     * 身份
     */
    private String identity;

    /**
     * 状态
     */
    private String status;

}

SysUserVO:

java 复制代码
package com.my.adminservice.user.domain.vo;

import lombok.Data;

import java.io.Serializable;

/**
 * B端用户查询VO
 */
@Data
public class SysUserVO implements Serializable {

    /**
     * 用户ID
     */
    private Long id;

    /**
     * 用户昵称
     */
    private String nickName;

    /**
     * 手机号
     */
    private String phoneNumber;

    /**
     * 身份
     */
    private String identity;

    /**
     * 备注
     */
    private String remark;

    /**
     * 状态
     */
    private String status;
}

entity:
SysUser:

java 复制代码
package com.my.adminservice.user.domain.entity;

import com.baomidou.mybatisplus.annotation.TableName;
import com.my.commondomain.domain.dataobject.BaseDO;
import lombok.Data;
import lombok.EqualsAndHashCode;


/**
 * 系统用户对象 sys_user
 */
@Data
@EqualsAndHashCode(callSuper = true)
@TableName(value = "sys_user")
public class SysUser extends BaseDO{

    /**
     * 用户昵称
     */
    private String nickName;

    /**
     * 手机号
     */
    private String phoneNumber;

    /**
     * 密码
     */
    private String password;

    /**
     * 身份
     */
    private String identity;

    /**
     * 备注
     */
    private String remark;

    /**
     * 状态
     */
    private String status;
}

1.1.3 在 mapper 下创建数据库接口


SysUserMapper:

java 复制代码
package com.my.adminservice.user.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.my.adminservice.user.domain.entity.SysUser;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * 处理sys_user表
 */
@Mapper
public interface SysUserMapper extends BaseMapper<SysUser> {

    SysUser selectByPhoneNumber(@Param("phoneNumber") String phone);

    List<SysUser> selectUserList(SysUser selectList);
}

实现的 xml 文件

SysUserMapper.xml:

xml 复制代码
    <select id="selectByPhoneNumber" resultType="com.my.adminservice.user.domain.entity.SysUser">
        select * from sys_user where phone_number = #{phoneNumber}
    </select>

    <select id="selectUserList" resultType="com.my.adminservice.user.domain.entity.SysUser">
        select * from sys_user
        <where>
            <if test="id != null and id != ''">
                and id = #{id}
            </if>
            <if test="phoneNumber != null and phoneNumber != ''">
                and phone_number = #{phoneNumber}
            </if>
            <if test="status != null and status != ''">
                and status = #{status}
            </if>
        </where>
    </select>



<!--    <select id="selectList" resultType="com.my.adminservice.user.domain.entity.SysUser">-->
<!--        select * from sys_user-->
<!--        <where>-->
<!--            <if test="selectList.id != null and selectList.id != ''">-->
<!--                and id = #{id}-->
<!--            </if>-->
<!--            <if test="selectList.phoneNumber != null and selectList.phoneNumber != ''">-->
<!--                and phone_number = #{selectList.phoneNumber}-->
<!--            </if>-->
<!--            <if test="selectList.status != null and selectList.status != ''">-->
<!--                and status = #{selectList.status}-->
<!--            </if>-->
<!--        </where>-->
<!--    </select>-->

1.1.4 在 controller 包下创建控制器


SysUserController:

java 复制代码
package com.my.adminservice.user.controller;

import com.my.adminservice.user.domain.dto.PasswordLoginDTO;
import com.my.adminservice.user.domain.dto.SysLoginUserDTO;
import com.my.adminservice.user.domain.dto.SysUserDTO;
import com.my.adminservice.user.domain.dto.SysUserListReqDTO;
import com.my.adminservice.user.domain.vo.SysLoginUserVO;
import com.my.adminservice.user.domain.vo.SysUserVO;
import com.my.adminservice.user.service.ISysUserService;
import com.my.commondomain.domain.R;
import com.my.commonsecurity.domain.dto.TokenDTO;
import com.my.commonsecurity.domain.vo.TokenVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * B端用户服务控制器类
 */
@RestController
@RequestMapping("/sys_user")
public class SysUserController {

    @Autowired
    private ISysUserService sysUserService;

    /**
     * B端用户登录
     *
     * @param passwordLoginDTO B端用户登录DTO
     * @return token信息
     */
    @PostMapping("/login/password")
    public R<TokenVO> login(@Validated @RequestBody PasswordLoginDTO passwordLoginDTO) {
        TokenDTO login = sysUserService.login(passwordLoginDTO);
        return R.success(login.convertTokenVO());
    }

    /**
     * 新增或编辑用户
     * @param sysUserDTO B端用户信息
     * @return  用户ID
     */
    @PostMapping("/add_edit")
    public R<Long> addOrEditUser(@Validated @RequestBody SysUserDTO sysUserDTO) {
        return R.success(sysUserService.addOrEditUser(sysUserDTO));
    }

    /**
     * 查询B端用户
     * @param listReqDTO 用户查询DTO
     * @return B用户列表
     */
    @PostMapping("/list")
    public R<List<SysUserVO>> getUserList(@RequestBody SysUserListReqDTO listReqDTO) {
        List<SysUserDTO> voList = sysUserService.getUserList(listReqDTO);
        return R.success(voList.stream().map(SysUserDTO::convertToVO).toList());
    }

    /**
     * 获取B端登录用户信息
     * @return B端用户信息VO
     */
    @GetMapping("/login_info/get")
    public R<SysLoginUserVO> getLoginUser() {
        SysLoginUserDTO sysLoginUserDTO = sysUserService.getLoginUser();
        return R.success(sysLoginUserDTO.convertToVO());
    }
}

1.1.5 在 service 包下创建接口及其实体类


ISysUserService:

java 复制代码
package com.my.adminservice.user.service;

import com.my.adminservice.user.domain.dto.PasswordLoginDTO;
import com.my.adminservice.user.domain.dto.SysLoginUserDTO;
import com.my.adminservice.user.domain.dto.SysUserDTO;
import com.my.adminservice.user.domain.dto.SysUserListReqDTO;
import com.my.adminservice.user.domain.vo.SysUserVO;
import com.my.commonsecurity.domain.dto.TokenDTO;

import java.util.List;

public interface ISysUserService {

    /**
     * B端用户登录
     *
     * @param passwordLoginDTO B端用户登录DTO
     * @return token信息
     */
    TokenDTO login(PasswordLoginDTO passwordLoginDTO);

    /**
     * 新增或编辑用户
     * @param sysUserDTO B端用户信息
     * @return  用户ID
     */
    Long addOrEditUser(SysUserDTO sysUserDTO);

    /**
     * 查询B端用户
     * @param listReqDTO 用户查询DTO
     * @return B用户列表
     */
    List<SysUserDTO> getUserList(SysUserListReqDTO listReqDTO);

    /**
     * 获取B端登录用户信息
     * @return B端用户信息VO
     */
    SysLoginUserDTO getLoginUser();
}

SysUserServiceImpl:

java 复制代码
package com.my.adminservice.user.service.Impl;

import cn.hutool.crypto.digest.DigestUtil;
import com.my.adminservice.config.service.ISysDictionaryService;
import com.my.adminservice.user.domain.dto.PasswordLoginDTO;
import com.my.adminservice.user.domain.dto.SysLoginUserDTO;
import com.my.adminservice.user.domain.dto.SysUserDTO;
import com.my.adminservice.user.domain.dto.SysUserListReqDTO;
import com.my.adminservice.user.domain.entity.SysUser;
import com.my.adminservice.user.mapper.SysUserMapper;
import com.my.adminservice.user.service.ISysUserService;
import com.my.commoncore.utils.AESUtil;
import com.my.commoncore.utils.BeanCopyUtil;
import com.my.commoncore.utils.VerifyUtil;
import com.my.commondomain.constants.DictionaryConstants;
import com.my.commondomain.constants.UserStatusConstants;
import com.my.commondomain.domain.ResultCode;
import com.my.commondomain.exception.ServiceException;
import com.my.commonsecurity.domain.dto.LoginUserDTO;
import com.my.commonsecurity.domain.dto.TokenDTO;
import com.my.commonsecurity.service.TokenService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class SysUserServiceImpl implements ISysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private ISysDictionaryService iSysDictionaryService;

    /**
     * B端用户登录
     *
     * @param passwordLoginDTO B端用户登录DTO
     * @return token信息
     */
    @Override
    public TokenDTO login(PasswordLoginDTO passwordLoginDTO) {
        // 1. 校验手机号是否,符合规范
        if(!VerifyUtil.checkPhone(passwordLoginDTO.getPhone())) {
            throw new ServiceException("手机号校验失败", ResultCode.ERROR_PHONE_FORMAT.getCode());
        }
        // 2. 检查数据库中是否存在
        SysUser sysUser = sysUserMapper.selectByPhoneNumber(AESUtil.encryptHex(passwordLoginDTO.getPhone()));
        if(sysUser == null) {
            throw new ServiceException("手机号不存在", ResultCode.INVALID_PARA.getCode());
        }
        // 3. 校验密码
        String password = AESUtil.decryptHex(passwordLoginDTO.getPassword());
        if(!StringUtils.isNotBlank(password)) {
            throw new ServiceException("密码解析为空", ResultCode.INVALID_PARA.getCode());
        }
        // 4. 加密比较 数据库返回密码
        if(!sysUser.getPassword().equals(DigestUtil.sha256Hex(password))) {
            throw new ServiceException("密码不正确", ResultCode.INVALID_PARA.getCode());
        }

        // 5. 校验用户状态
        if(sysUser.getStatus().equals(UserStatusConstants.DISABLE)) {
            throw new ServiceException(ResultCode.USER_DISABLE);
        }

        // 6. 需要用户登录的生命周期LoginUserDTO
        LoginUserDTO loginUserDTO = new LoginUserDTO();
        // 7. 设置登录信息
        loginUserDTO.setUserId(sysUser.getId());
        loginUserDTO.setUserName(sysUser.getNickName());
        loginUserDTO.setUserFrom("sys");

        // 8. 返回token,并注册到redis
        return tokenService.createToken(loginUserDTO);
    }

    /**
     * 新增或编辑用户
     * @param sysUserDTO B端用户信息
     * @return  用户ID
     */
    @Override
    public Long addOrEditUser(SysUserDTO sysUserDTO) {
        // 创建一个空的SysUser对象
        SysUser sysUser = new SysUser();

        // 1. 处理新增逻辑
        if(sysUserDTO.getId() == null) {
            // 2. 首先校验手机号
            if(!VerifyUtil.checkPhone(sysUserDTO.getPhoneNumber())) {
                throw new ServiceException("手机号格式错误", ResultCode.INVALID_PARA.getCode());
            }
            // 3. 校验密码
            if(!sysUserDTO.checkPassword()) {
                throw new ServiceException("密码格式错误", ResultCode.INVALID_PARA.getCode());
            }
            // 4. 校验手机号唯一性
            SysUser existUser = sysUserMapper.selectByPhoneNumber(AESUtil.encryptHex(sysUserDTO.getPhoneNumber()));
            if(existUser != null) {
                throw new ServiceException("手机号已被占用", ResultCode.INVALID_PARA.getCode());
            }
            // 5. 使用字典服务,校验身份信息
            if(StringUtils.isBlank(sysUserDTO.getIdentity())) {
                throw new ServiceException("用户身份不能为空", ResultCode.INVALID_PARA.getCode());
            }
            if(iSysDictionaryService.getDicDataByKey(DictionaryConstants.IDENTITY_TYPE_KEY, sysUserDTO.getIdentity()) == null) {
                throw new ServiceException("无效的用户身份", ResultCode.INVALID_PARA.getCode());
            }
            // 6. 校验成功,执行新增用户逻辑
            // 先填写 新增用户独有的字段
            // 其他字段放在 修改逻辑里添加
            sysUser.setPhoneNumber(AESUtil.encryptHex(sysUserDTO.getPhoneNumber()));
            sysUser.setPassword(DigestUtil.sha256Hex(sysUserDTO.getPassword()));
            sysUser.setIdentity(sysUserDTO.getIdentity());
        }
        // 7. 放入修改逻辑的字段
        sysUser.setId(sysUserDTO.getId());
        sysUser.setNickName(sysUserDTO.getNickName());
        // 8. 判断修改或添加用户的状态
        if(iSysDictionaryService.getDicDataByKey(DictionaryConstants.COMMON_STATUS,sysUserDTO.getStatus()) == null) {
            throw new ServiceException("用户状态错误", ResultCode.INVALID_PARA.getCode());
        }
        sysUser.setStatus(sysUserDTO.getStatus());
        sysUser.setRemark(sysUserDTO.getRemark());
        // 9. 使用 mybatis-plus 的方法, 添加或修改
        sysUserMapper.insertOrUpdate(sysUser);

        // 10. 踢人
        if (sysUserDTO.getId() != null && sysUserDTO.getStatus().equals("disable")) {
            tokenService.delLoginUser(sysUserDTO.getId(), "sys");
        }
        return sysUser.getId();
    }

    /**
     * 查询B端用户
     * @param listReqDTO 用户查询DTO
     * @return B用户列表
     */
    @Override
    public List<SysUserDTO> getUserList(SysUserListReqDTO listReqDTO) {
        // 1. 构建查询参数
        SysUser searchSysUser = new SysUser();
        searchSysUser.setId(listReqDTO.getId());
        searchSysUser.setPhoneNumber(AESUtil.encryptHex(listReqDTO.getPhoneNumber()));
        searchSysUser.setStatus(listReqDTO.getStatus());
        // 2. 调用 mapper 查询
        List<SysUser> sysUserList = sysUserMapper.selectUserList(searchSysUser);

        // 3. 返回结果
        return sysUserList.stream().map(entity -> {
            SysUserDTO dto = new SysUserDTO();
            dto.setId(entity.getId());
            dto.setNickName(entity.getNickName());
            dto.setPhoneNumber(AESUtil.decryptHex(entity.getPhoneNumber()));
            dto.setRemark(entity.getRemark());
            dto.setIdentity(entity.getIdentity());
            dto.setStatus(entity.getStatus());
            return dto;
        }).toList();
    }

    /**
     * 获取B端登录用户信息
     * @return B端用户信息VO
     */
    @Override
    public SysLoginUserDTO getLoginUser() {
        // 1 获取当前登录用户
        // 这是通过 ServletUtil 先获取 request 请求
        // 在通过 SecurityUtil 获得token
        // 在用 tokenService.getLoginUser() 获得当前用户信息
        LoginUserDTO loginUser = tokenService.getLoginUser();
        // 2. 对象判断
        if(loginUser == null || loginUser.getUserId() == null) {
            throw new ServiceException("用户令牌有误", ResultCode.INVALID_PARA.getCode());
        }
        // 3. 查数据库
        SysUser sysUser = sysUserMapper.selectById(loginUser.getUserId());
        if(sysUser == null) {
            throw new ServiceException("用户不存在", ResultCode.INVALID_PARA.getCode());
        }

        // 4 封装结果
        SysLoginUserDTO sysUserLoginDTO = new SysLoginUserDTO();
        BeanCopyUtil.copyProperties(loginUser, sysUserLoginDTO);
        BeanCopyUtil.copyProperties(sysUser, sysUserLoginDTO);
        return sysUserLoginDTO;
    }


}

1.1.6 在 config 包下创建配置类


修改用户信息,并通知其他服务修改信息
RabbitConfig:

java 复制代码
package com.my.adminservice.user.config;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitConfig {

    // 交换机的名称
    public final static String EXCHANGE_NAME = "edit_user_exchange";
    // 队列名称
    public final static String QUEUE_NAME = "edit_user_queue";

    @Bean
    public FanoutExchange editUserExchange() {
        return ExchangeBuilder.fanoutExchange(EXCHANGE_NAME).durable(true).build();
    }

    @Bean
    public Queue editUserQueue() {
        return QueueBuilder.durable(QUEUE_NAME).build();
    }

    @Bean
    public Binding editUserBinding(@Qualifier("editUserQueue") Queue editUserQueue
            ,@Qualifier("editUserExchange") FanoutExchange editUserExchange) {
        return BindingBuilder.bind(editUserQueue).to(editUserExchange);
    }
}

二、验证用户登录和 B 端用户登录

未登录时:

我之前的登录token,因为过期了,被网关鉴权服务拦截结果:

B 端用户登录:

添加 token:

结果:


END

B 端用户登录服务完成。

相关推荐
锅包一切1 小时前
PART17 一维动态规划
c++·学习·算法·leetcode·动态规划·力扣·刷题
科技林总2 小时前
【系统分析师】9.3 通信与网络安全技术
学习
亓才孓2 小时前
[SpringBoot]UnableToConnectException : Public Key Retrieval is not allowed
java·数据库·spring boot
嵌入式×边缘AI:打怪升级日志2 小时前
编写Bootloader实现下载功能
java·前端·网络
wuqingshun3141592 小时前
什么是浅拷贝,什么是深拷贝,如何实现深拷贝?
java·开发语言·jvm
Rainman博2 小时前
AMS-Activity启动流程
android
Stringzhua2 小时前
队列-优先队列【Queue3】
java·数据结构·队列
恋猫de小郭3 小时前
Flutter 设计包解耦新进展,material_ui 和 cupertino_ui 发布预告
android·前端·flutter