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 端用户登录服务完成。

相关推荐
zhangfeng113323 分钟前
openclaw skills 小龙虾技能 通讯仿真 matlab skill Simulink Agentic Toolkit,通过kimi找到,mcp通讯
开发语言·matlab·openclaw·通讯仿真
Javatutouhouduan7 小时前
2026Java面试的正确打开方式!
java·高并发·java面试·java面试题·后端开发·java编程·java八股文
chao1898447 小时前
基于 SPEA2 的多目标优化算法 MATLAB 实现
开发语言·算法·matlab
JAVA面经实录9177 小时前
Java初级最终完整版学习路线图
java·spring·eclipse·maven
赏金术士7 小时前
Kotlin 习题集 · 高级篇
android·开发语言·kotlin
Cat_Rocky8 小时前
k8s-持久化存储,粗浅学习
java·学习·kubernetes
楼兰公子8 小时前
buildroot 在编译rust时裁剪平台类型数量的方法
开发语言·后端·rust
知识领航员8 小时前
蘑兔AI音乐深度实测:功能拆解、实测表现与适用场景
java·c语言·c++·人工智能·python·算法·github
薛定e的猫咪8 小时前
因果推理研究方向综述笔记
人工智能·笔记·深度学习·算法
AOwhisky9 小时前
虚拟化技术学习笔记
linux·运维·笔记·学习·虚拟化技术