SpringBoot项目--库存管理系统

1.前台页面展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

使用的技术

本项目采用前后端分离的技术实现。

后端技术:

  • JDK11
  • SpringBoot
  • Redis
  • MyBatisPlus
  • JWT
  • MySQL

前端技术:

  • Vue2
  • ElementUI
  • Nodejs

创建项目

使用Spring Initializr创建SpringBoot工程,导入必要的pom依赖。
pom文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.12</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.xzj</groupId>
    <artifactId>IMS</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>IMS</name>
    <description>IMS</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.5</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
            <version>3.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>32.1.1-jre</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.11.2</version>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-redis</artifactId>
            <version>1.4.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.4.0</version>
                <configuration>
                    <configurationFile>src/main/resources/generatorConfiguration.xml</configurationFile>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
                <!--加入下面这个依赖-->
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>8.0.32</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

</project>

src目录结构

在这里插入图片描述

各数据表结构

小技巧:在创建各表时,创建时间和更新时间都可以设置默认值CURRENT_TIMESTAMP,其中更新时间勾选上On Update(我是在Navicat定义表的),这样就不用MyBatisPlus的额外配置也能实现时间的自动创建和更新了。

  1. 用户表
    在这里插入图片描述

  2. 部门表
    在这里插入图片描述

  3. 菜单表
    在这里插入图片描述

  4. 角色表
    在这里插入图片描述

  5. 角色-菜单表
    在这里插入图片描述

  6. 商品表
    在这里插入图片描述

配置文件

application.yml

server:
  port: 8080
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/ims?serverTimezone=GMT%2B8
    username: root
    password: 416527&&xzj123
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher

  redis:
    host: 192.168.217.133       #Redis服务器连接端口
    port: 6379
    password:                   #Redis服务器连接密码(默认为空)
    pool:
      max-active: 8             #连接池最大连接数 使用负值表示没有限制)
      max-wait: -1                #连接池最大阻塞等待时间(使用负值表示没有限制)
      max-idle: 8                  #连接池中的最大空闲连接
      min-idle: 0                #连接池中的最小空闲连接
    timeout: 30000                #连接超时时间 (毫秒)


mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

#配置 jwt 生成 token 的secret
jwt:
  auth:
    secret: 123456
    expired: 86400000 #毫秒
    redis:
      enable: false

logging:
  config: classpath:log/logback.xml

实体类

位于com.xzj.model包

//Base.java
/**
 * 其他表共有的属性
 */
@Data
public class Base {
    private Long createUser;

    private Long updateUser;

    private Timestamp createTime;

    @TableField("update_time")
    private Timestamp editTime;

    @TableField(exist = false)
    private String createUserName;

    @TableField(exist = false)
    private String editUserName;
}


//Users.java
@Data
@TableName("user1")
public class Users extends Base{

    @TableId(type = IdType.AUTO)
    private Long id;

    private Long roleId;

    private String userName;

    private String account;

    private String gender;

    private String password;

    private Long deptId;

    @TableField(value = "phone")
    private String userMobile;

    @TableField(exist = false)
    private String roleName;

    @TableField(exist = false)
    private String deptName;
}


//Dept.java
@Data
@TableName("dept")
public class Dept extends Base{
    @TableId(type = IdType.AUTO)
    private Long id;
    private String deptName;
    @TableField(value = "dept_code")
    private String deptNo;
}


//Role.java
@Data
public class Role extends Base{
    @TableId(type = IdType.AUTO)
    private Long id;

    private String roleName;

    @TableField(value = "role_code")
    private String roleNo;
}


//Menu.java
@Data
@TableName("menu")
public class Menu {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String icon;
    private String menuName;
    @TableField(value = "has_Third")
    private String hasThird;
    private String url;
    private Long pid;
    private Integer orderValue;
    @TableField(exist = false)
    private List<Menu> menus;
}


//RoleMenu.java
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("role_menu")
public class RoleMenu {
    @TableId(type = IdType.AUTO)
   private Long id;
   private Long menuId;
   private Long roleId;
}


//Goods.java
@Data
@TableName("goods")
public class Goods extends Base{
    @TableId(type = IdType.AUTO)
    private Long id;
    private String goodsName;
    @TableField("goods_code")
    private String goodsNo;
    private Double price;
    private Integer inventory;
    private String stemPlace;
}

工具类

位于com.xzj.utils包
JsonUtil.java

public class JsonUtil {
    public static ObjectMapper mapper = new ObjectMapper();

    /**
     * 对象转换为Json
     * @param obj 对象
     * @return Json串
     */
    public static String getJsonString(Object obj){
        String s = null;
        try {
            s = mapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return s;
    }

    /**
     * Json串转换为对象
     * @param jsonString json串
     * @param resultCls 结果类型字节码
     * @param <T> 泛型T
     * @return 对象
     */
    public static <T> T getModel(String jsonString,Class<T> resultCls){
        T t = null;
        try {
            t = mapper.readValue(jsonString, resultCls);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return t;
    }
}

JwtUtil.java

public class JwtUtil {
    //Base64负载,包括用户的相关信息
    public static String USER_ID = "userId";
    public static String USER_NAME = "userName";
    public static String USER_ROLES = "roles";

    /**
     * 使用jwt生成token,Signature = HMAC256(Base64(头部)+"."+Base64(负载),secretKey)
     * @param authInfo
     * @param expireDate
     * @param secret
     * @return
     */
    public static String getToken(AuthInfo authInfo,Date expireDate,String secret){
        Preconditions.checkArgument(authInfo != null,"加密内容不能为空");
        Preconditions.checkArgument(expireDate != null,"过期时间异常");
        Preconditions.checkArgument(secret != null,"加密密码不能为null");
        Map<String,Object> map = new HashMap<>();
        map.put("alg","HS256");
        map.put("typ","JWT");

        String token;//签名
        token = JWT.create()
                .withClaim(USER_ID,authInfo.getUserId()) //Payload,key-value
                .withClaim(USER_NAME,authInfo.getUserName())
                .withClaim(USER_ROLES,authInfo.getRoleId())
                .withIssuedAt(new Date())//签名时间
                .withExpiresAt(expireDate)//过期时间
                .sign(Algorithm.HMAC256(secret)); //签名使用的密钥secret
        return token;
    }

    /**
     * 验证token正确性并返回AuthInfo对象
     * @param token
     * @param secret
     * @return
     */
    public static AuthInfo verifyToken(String token,String secret){
        /**
         * 通过接收前端的token,用base64 URL解码出原文
         * 从header中获取哈希签名的算法,从payload中获取有效的数据
         * 再使用密钥加密一次对比原来的token,一致则通过
         */
        //校验器
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret)).build();
        DecodedJWT jwt;
        try {
            //该函数会将token分为三部分,header | payload | signature,然后使用签名算法和密钥对前两部分再次签名,与signature对比
            //相同则验签成功,否则失败
            jwt = verifier.verify(token);
        }catch (Exception e){
            throw new ImsAuthException("凭证已过期,请重新登录");
        }
        AuthInfo authInfo = new AuthInfo();
        authInfo.setUserId(jwt.getClaim(USER_ID).asLong());
        authInfo.setUserName(jwt.getClaim(USER_NAME).asString());
        authInfo.setRoleId(jwt.getClaim(USER_ROLES).asLong());
        return authInfo;
    }
}

RedisUtil.java

@AllArgsConstructor
public class RedisUtil {
    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 写入缓存
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    /**
     * 写入缓存设置时效时间
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value, Long expireTime , TimeUnit timeUnit) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expireTime, timeUnit);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    /**
     * 批量删除对应的value
     * @param keys
     */
    public void remove(final String... keys) {
        for (String key : keys) {
            remove(key);
        }
    }
    /**
     * 批量删除key
     * @param pattern
     */
    public void removePattern(final String pattern) {
        Set<Serializable> keys = redisTemplate.keys(pattern);
        if (keys.size() > 0){
            redisTemplate.delete(keys);
        }
    }
    /**
     * 删除对应的value
     * @param key
     */
    public void remove(final String key) {
        if (exists(key)) {
            redisTemplate.delete(key);
        }
    }
    /**
     * 判断缓存中是否有对应的value
     * @param key
     * @return
     */
    public boolean exists(final String key) {
        return redisTemplate.hasKey(key);
    }
    /**
     * 读取缓存
     * @param key
     * @return
     */
    public Object get(final String key) {
        Object result = null;
        ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
        result = operations.get(key);
        return result;
    }
}

使用ThreadLocal保存登录用户的信息

首先规定用户登录后需要保存哪些信息,定义AuthInfo类【com.xzj.auth包】:

@Data
public class AuthInfo {
    private Long userId;
    private String userName;
    private Long roleId;
    private Long expired;  //过期时间
    private String key;   //密钥(对称加密)
}

再定义UserThreadLocal【com.xzj.local】:

public class UserThreadLocal {
    private static final ThreadLocal<AuthInfo> threadLocal=new ThreadLocal<>();
    public static void put(AuthInfo authInfo){
        threadLocal.set(authInfo);
    }
    public static AuthInfo get(){
        return threadLocal.get();
    }
    public static void remove(){
        threadLocal.remove();
    }
}

登录认证器(登录认证用)

认证器接口Authenticator.java【com.xzj.auth】

    /**
     * 认证器做认证使用
     * @param token
     * @return
     */
    AuthInfo auth(String token);

认证器实现类1:普通实现
AuthticatorImpl.java

@Component    //认证器注解注入
@AllArgsConstructor
@NoArgsConstructor
public class AuthenticatorImpl implements Authenticator{
    @Value("${jwt.auth.secret}")
    private String secret;

    /**
     * Bearer xxxxxx 客户端鉴权时添加的Bearer,说明鉴权类型
     * @param token
     * @return
     */
    @Override
    public AuthInfo auth(String token) {
        String authToken;
        int index = token.indexOf(" ");
        if (index == -1){
            authToken = token;
        }else{
            String tokenType = token.substring(0,index);
            if (!"Bearer".equals(tokenType)){
                throw new ImsAuthException(String.format("无法识别的token类型[%s]",token));
            }else{
                authToken = token.substring(index).trim();
            }
        }
        AuthInfo authInfo = JwtUtil.verifyToken(authToken,secret);
        return authInfo;
    }
}

认证器实现2,Redis实现
AuthenticatorRedisImpl.java

@AllArgsConstructor
@NoArgsConstructor
public class AuthenticatorRedisImpl implements Authenticator{
    private RedisUtil util;
    /**
     * Bearer xxxxxx 客户端鉴权时添加的Bearer,说明鉴权类型
     * @param token
     * @return
     */
    @Override
    public AuthInfo auth(String token) {
        if (util == null){
            return null;
        }
        Object obj = util.get(token);
        if (obj == null){
            throw new ImsAuthException("找不到token对应的用户信息");
        }else{
            AuthInfo authInfo = (AuthInfo)obj;
            if (authInfo.getExpired() < System.currentTimeMillis()){
                throw new ImsAuthException("token已过期");
            }
            return authInfo;
        }

    }
}

过滤器

过滤器用于过滤请求中未携带token的请求
AuthFilter.java

@Slf4j
@NoArgsConstructor
public class AuthFilter implements Filter {
    private AuthenticatorImpl authenticator;
    private AuthenticatorRedisImpl authenticatorRedis;
    private Set<String> urifilter;

    public AuthFilter(AuthenticatorImpl authenticator,AuthenticatorRedisImpl authenticatorRedis) {
        this.authenticator = authenticator;
        this.authenticatorRedis = authenticatorRedis;
    }

    public AuthFilter(AuthenticatorImpl authenticatorimpl) {
        this.authenticator = authenticatorimpl;
    }

    @Override
    public void init(FilterConfig filterConfig) {
        //得到需要放行参数,例如登录
        String initParameter = filterConfig.getInitParameter(Const.UN_FILTER_KEY);
        List<String> list;
        if (StringUtils.isEmpty(initParameter)){
            list = Collections.emptyList();
        }else{
            list = Lists.newArrayList(initParameter.split(","));
            list.removeIf(String::isEmpty);
        }
        urifilter= ImmutableSet.copyOf(list);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //得到请求的uri
        String uri = request.getRequestURI();
        //说明uri符合放行标准
        if (urifilter.stream().anyMatch(uri::startsWith)){
            //放行
                filterChain.doFilter(servletRequest,servletResponse);
                return;
        }
        //不符合放行标准,需要鉴权
        try {
            String header = request.getHeader("token"); //获取请求头中AUTHORIZATION值
            //AUTHORIZATION为空时直接获取名为token的字段值,否则获取AUTHORIZATION字段值
            String token = StringUtils.isEmpty(header) ? request.getParameter("token") : header;
            if (StringUtils.isEmpty(token)) {
                throw new ImsAuthException("未携带 token");
            }
            AuthInfo authInfo;
            //拿得到token就说明验签成功
            if (authenticatorRedis != null) {
                authInfo = authenticatorRedis.auth(token);
            }else{
                authInfo = authenticator.auth(token);
            }

            if (authInfo == null){
                throw  new RuntimeException("鉴权失败");
            }
            //保存当前用户信息
            UserThreadLocal.put(authInfo);
            filterChain.doFilter(servletRequest, servletResponse);
        }
        catch (ImsAuthException e){
            //定义响应格式
            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
            //设置未鉴权状态码
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            String jsonString = JsonUtil.getJsonString(Resp.toReturn(e.getMessage(), false));
            response.getOutputStream().write(jsonString.getBytes());
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

过滤器注册到Spring容器
AuthConfig.java【com.xzj.config】

@Configuration
public class AuthConfig {
    @Autowired(required = false)
    RedisTemplate redisTemplate;
    @Value("${jwt.auth.redis.enable}")
    private Boolean redisEnabled;
    @Autowired
    ApplicationContext context;
    @Bean
    public FilterRegistrationBean<AuthFilter> authFilter(){       //FilterRegistrationBean,Spring中用于注册和配置Filter的类
        FilterRegistrationBean<AuthFilter> filterRegistrationBean = new FilterRegistrationBean<>();
        AuthFilter authFilter;
        if (redisEnabled){
            authFilter = new AuthFilter(authenticatorimpl(),authenticatorRedis());
        }else{
            authFilter = new AuthFilter(authenticatorimpl());
        }

        filterRegistrationBean.setFilter(authFilter);
        filterRegistrationBean.addUrlPatterns("/api/*");
        /**
         * 设置放行参数
         */
        filterRegistrationBean.addInitParameter(Const.UN_FILTER_KEY, Joiner.on(",").join(Const.URL+"login",Const.URL+"xxx"));
        filterRegistrationBean.setEnabled(true);
        return filterRegistrationBean;
    }

    @Bean
    public AuthenticatorImpl authenticatorimpl(){
        String secret = context.getEnvironment().getProperty("jwt.auth.secret");
        return new AuthenticatorImpl(secret);
    }

    @Bean
    @ConditionalOnProperty(value = "jwt.auth.redis.enable",havingValue = "true") //当enable值为真时才构建这个bean
    public AuthenticatorRedisImpl authenticatorRedis(){
        return new AuthenticatorRedisImpl(redisUtil());
    }

    @Bean
    @ConditionalOnProperty(value = "jwt.auth.redis.enable",havingValue = "true")
    public RedisUtil redisUtil(){
        return  new RedisUtil(redisTemplate);
    }
}

常量类:【com.xzj.constant】

public interface Const {
    String URL = "/api/";
    String UN_FILTER_KEY = "UN_FILTER_KEY";
}

Mapper类

位于com.xzj.mapper包

//UsersMapper
@Mapper
public interface UsersMapper extends BaseMapper<Users> {
    @Select("select * from user1 where account = #{account} and password = #{password}")
    UserResp login(@Param("account") String account, @Param("password") String password);

    @Update("update user1 set password = '123456' where id=#{userId}")
    int resetPwd(Long userId);
}

//DeptMapper
@Mapper
public interface DeptMapper extends BaseMapper<Dept> {
}


//RoleMapper
@Mapper
public interface RoleMapper extends BaseMapper<Role> {
}


//GoodsMapper
@Mapper
public interface GoodsMapper extends BaseMapper<Goods> {
}


//MenuMapper
@Mapper
public interface MenuMapper extends BaseMapper<Menu> {
}


//RoleMenuMapper
@Mapper
public interface RoleMenuMapper extends BaseMapper<RoleMenu> {

    @Select("select menu_id from role_menu where role_id = #{roleId}")
    List<Long> selectByRoleId(Long roleId);
}

定义响应类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Resp {
    private boolean success = true;
    private String message;

    public static Resp toReturn(String msg,Boolean success){
        Resp resp = new Resp();
        resp.setSuccess(success);
        resp.setMessage(msg);
        return resp;
    }
}


@Data
public class UserResp {
    private Long id;

    private String userName;

    private Long deptId;

    private Long roleId;

    private String phone;

    private String token;
}


@Data
public class LoginResp extends Resp{
    private UserResp data;
}


@Data
public class TreeResp<T> extends Resp{
    private T data;  //所有菜单
    private List list;  //用户拥有的菜单权限
}


@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageResp<T> extends Resp{
    private T data;
    private Long count;
}


@EqualsAndHashCode(callSuper = true)
@Data
public class ListResp<T> extends Resp{
    private T data;
}

Service层

实现类(接口略):

@Service
public class UserServiceImpl extends ServiceImpl<UsersMapper,Users> implements IUserService {
    @Resource
    private UsersMapper mapper;
    @Resource
    private DeptMapper deptMapper;
    @Resource
    private RoleMapper roleMapper;
    @Value("${jwt.auth.secret}")
    private String secret;
    @Value("${jwt.auth.expired}")
    private Integer expired;
    @Autowired(required = false)
    private RedisUtil redisUtil;
    @Override
    public LoginResp login(String account, String password) {
        LoginResp loginResp = new LoginResp();
        UserResp userResp = mapper.login(account, password);
        if (userResp == null){
            loginResp.setMessage("账号或密码不存在");
            loginResp.setSuccess(false);
            return loginResp;
        }

        AuthInfo authInfo = new AuthInfo();
        authInfo.setUserId(userResp.getId());
        authInfo.setUserName(userResp.getUserName());
        authInfo.setRoleId(userResp.getRoleId());
        authInfo.setExpired(getExpiredTime());
        Date date = new Date(getExpiredTime());
        //根据authInfo生成token
        String token = JwtUtil.getToken(authInfo, date, secret);
        if (redisUtil != null){
            redisUtil.set(token,authInfo);
        }
        userResp.setToken(token);
        loginResp.setData(userResp);
        return loginResp;
    }

    /**
     * 根据当前时间+过期时间得到总时间戳
     * @return
     */
    public Long getExpiredTime(){
        return new Date().getTime() + expired;
    }

    @Override
    public PageResp<List<Users>> selectUserList(Integer page, Integer limit, String userName, String userMobile) {
        QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
        PageHelper.startPage(page,limit);
        if(userName!=null&&!"".equals(userName)){
            queryWrapper.eq("user_name",userName);
        }
        if (userMobile!=null && !"".equals(userMobile)){
            queryWrapper.eq("phone",userMobile);
        }
        List<Users> list = mapper.selectList(queryWrapper);
        list.forEach(li -> {
            li.setRoleName(roleMapper.selectById(li.getRoleId()).getRoleName());
            li.setDeptName(deptMapper.selectById(li.getDeptId()).getDeptName());
            li.setCreateUserName(mapper.selectById(li.getCreateUser()).getUserName());
            if(li.getUpdateUser()!=null){
                li.setEditUserName(mapper.selectById(li.getUpdateUser()).getUserName());
            }
        });
        PageInfo<Users> info = new PageInfo<>(list);
        PageResp<List<Users>> resp = new PageResp<>();
        resp.setCount(info.getTotal());
        resp.setData(list);
        return resp;
    }

    @Override
    public Resp saveOrUpdate(Long userId, String account, String userName, String gender,String userMobile, Long roleId, Long deptId) {
        Users users = new Users();
        users.setAccount(account);
        users.setUserName(userName);
        users.setGender(gender);
        users.setUserMobile(userMobile);
        users.setDeptId(deptId);
        users.setRoleId(roleId);
        //新增
        if (userId == null){
            //初始密码
            users.setPassword("123456");
            users.setCreateUser(UserThreadLocal.get().getUserId());
            int insert = mapper.insert(users);
            Resp.toReturn(insert>0?"成功":"失败",insert>0);
        }
        //更新
        users.setId(userId);
        users.setUpdateUser(UserThreadLocal.get().getUserId());
        int update = mapper.updateById(users);
        return Resp.toReturn(update>0?"成功":"失败",update>0);
    }

    @Override
    public Resp delete(Long userId) {
        int ret = mapper.deleteById(userId);
        return Resp.toReturn(ret>0?"成功":"失败",ret>0);
    }

    @Override
    public Resp resetPwd(Long userId) {
        int ret = mapper.resetPwd(userId);
        return Resp.toReturn(ret>0?"成功":"失败",ret>0);
    }
}
@Service
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements IGoodsService {
    @Resource
    private GoodsMapper mapper;
    @Resource
    private UsersMapper usersMapper;
    @Override
    public PageResp<List<Goods>> selectGoodsList(Integer page, Integer limit, String goodsName, String goodsNo) {
        QueryWrapper<Goods> queryWrapper = new QueryWrapper<>();

        if (StringUtils.isNotBlank(goodsName)) {
            queryWrapper.like("goods_name", goodsName);
        }
        if (StringUtils.isNotBlank(goodsNo)) {
            queryWrapper.eq("goods_code", goodsNo);
        }
        PageHelper.startPage(page,limit);
        List<Goods> goodsList = mapper.selectList(queryWrapper);

        goodsList.forEach(li->{
            li.setCreateUserName(usersMapper.selectById(li.getCreateUser()).getUserName());
            if(li.getUpdateUser()!=null){
                li.setEditUserName(usersMapper.selectById(li.getUpdateUser()).getUserName());
            }
        });

        PageInfo<Goods> pageInfo = new PageInfo<>(goodsList);

        return new PageResp<>(pageInfo.getList(), pageInfo.getTotal());
    }

    @Override
    public Resp saveOrUpdate(Long goodsId, String goodsName, String goodsNo,Double price,Integer inventory,String stemPlace) {
        Goods goods = new Goods();
        goods.setGoodsNo(goodsNo);
        goods.setGoodsName(goodsName);
        if (price!=null){
            goods.setPrice(price);
        }
        if (inventory!=null){
            goods.setInventory(inventory);
        }
        if (stemPlace!=null){
            goods.setStemPlace(stemPlace);
        }
        //新增
        if (goodsId == null){
            goods.setCreateUser(UserThreadLocal.get().getUserId());
            int insert = mapper.insert(goods);
            Resp.toReturn(insert>0?"成功":"失败",insert>0);
        }
        //更新,goodsId肯定不为空
        goods.setId(goodsId);
        goods.setUpdateUser(UserThreadLocal.get().getUserId());
        int update = mapper.updateById(goods);
        return Resp.toReturn(update>0?"成功":"失败",update>0);
    }

    @Override
    public Resp delete(Long goodsId) {
        int ret = mapper.deleteById(goodsId);
        return Resp.toReturn(ret>0?"成功":"失败",ret>0);
    }
}

@Service
public class DeptServiceImpl extends ServiceImpl<DeptMapper,Dept> implements IDeptService {
    @Resource
    private DeptMapper mapper;

    @Autowired
    private UsersMapper usersMapper;
    @Override
    public PageResp<List<Dept>> selectDeptList(Integer page, Integer limit, String deptName, String deptNo) {
        QueryWrapper<Dept> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(deptName)) {
            queryWrapper.like("dept_name", deptName);
        }
        if (StringUtils.isNotBlank(deptNo)) {
            queryWrapper.eq("dept_code", deptNo);
        }
        List<Dept> list = mapper.selectList(queryWrapper);
        list.forEach(li->{
            li.setCreateUserName(usersMapper.selectById(li.getCreateUser()).getUserName());
            li.setEditUserName(usersMapper.selectById(li.getUpdateUser()).getUserName());
        });
        PageHelper.startPage(page,limit);

        PageInfo<Dept> info = new PageInfo<>(list);
        PageResp<List<Dept>> resp = new PageResp<>();
        resp.setCount(info.getTotal());
        resp.setData(list);
        return resp;
    }

    @Override
    public Resp saveOrUpdate(Long deptId, String deptName, String deptNo) {
        Dept dept = new Dept();
        dept.setDeptNo(deptNo);
        dept.setDeptName(deptName);
        //新增
        if (deptId == null){
            //初始密码
            dept.setCreateUser(UserThreadLocal.get().getUserId());
            int insert = mapper.insert(dept);
            Resp.toReturn(insert>0?"成功":"失败",insert>0);
        }
        //更新
        dept.setId(deptId);
        dept.setUpdateUser(UserThreadLocal.get().getUserId());
        int update = mapper.updateById(dept);
        return Resp.toReturn(update>0?"成功":"失败",update>0);
    }

    @Override
    public Resp delete(Long deptId) {
        int ret = mapper.deleteById(deptId);
        return Resp.toReturn(ret>0?"成功":"失败",ret>0);
    }

    @Override
    public ListResp<List<Dept>> selectDeptListNoParams() {
        List<Dept> ret = mapper.selectList(new QueryWrapper<>());
        ListResp<List<Dept>> resp = new ListResp<>();
        resp.setData(ret);
        return resp;
    }
}

@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper,Menu> implements IMenuService {
    @Resource
    private MenuMapper mapper;

    @Resource
    private RoleMenuMapper roleMenuMapper;

    @Override
    public ListResp<List<Menu>> selectMenuList() {
        //得到当前用户在系统中的角色id
        Long roleId = UserThreadLocal.get().getRoleId();
        List<Long> menuIds = roleMenuMapper.selectByRoleId(roleId);
        //查询出来的菜单列表
        List<Menu> menus = new ArrayList<>();
        menuIds.forEach(menuId ->{
            menus.add(mapper.selectById(menuId));
        });
        /**
         * 先找没有儿子的出来,再去找儿子
         */
        //父级菜单
        List<Menu> parentMenus = new ArrayList<>();
        //子级菜单
        List<Menu> sonMenus = new ArrayList<>();
        for (Menu menu : menus) {
            if (menu.getPid() == null){
                //没有pid,说明没有父级,已经是顶级菜单,添加到父级菜单中
                parentMenus.add(menu);
            }
            //添加到儿子菜单中
            sonMenus.add(menu);
        }
        //排好序的父级菜单
        //流式操作,加快集合处理速度
        List<Menu> parentOrderMenus = parentMenus.stream().sorted(Comparator.
                        comparing(Menu::getOrderValue)).
                collect(Collectors.toList());
        for (Menu orderMenu : parentOrderMenus) {
            //根据父级菜单的id和所有子菜单得到该父级菜单下的子菜单
            List<Menu> child = getChild(orderMenu.getId(),sonMenus);
            //排好序的子菜单
            List<Menu> collect = child.stream().
                    sorted(Comparator.comparing(Menu::getOrderValue))
                    .collect(Collectors.toList());
            orderMenu.setMenus(collect);
        }
        ListResp<List<Menu>> listResp = new ListResp<>();
        listResp.setData(parentOrderMenus);
        return listResp;
    }

    @Override
    public ListResp<List<MenuVo>> nodesList() {
        List<Menu> ret = mapper.selectList(new QueryWrapper<Menu>().isNull("pid"));
        ArrayList<MenuVo> list = new ArrayList<>();
        ret.forEach(r->{
            Long id = r.getId();
            String menuName = r.getMenuName();
            list.add(new MenuVo(id,menuName));
        });
        ListResp<List<MenuVo>> resp = new ListResp<>();
        resp.setData(list);
        return resp;
    }

    @Override
    public Resp saveOrUpdate(Long menuId, Long parentId, String menuIcon, String menuUrl, String menuName, Integer menuOrder) {
        Menu menu = new Menu();
        menu.setPid(parentId);
        menu.setIcon(menuIcon);
        menu.setUrl(menuUrl);
        menu.setMenuName(menuName);
        menu.setOrderValue(menuOrder);
        //新增
        if (menuId == null){
            int insert = mapper.insert(menu);
            Resp.toReturn(insert>0?"成功":"失败",insert>0);
        }
        //更新
        menu.setId(menuId);
        int update = mapper.updateById(menu);
        return Resp.toReturn(update>0?"成功":"失败",update>0);
    }

    @Override
    public Resp delete(List<Long> moduleIds) {
        int sum = 0;
        for (Long moduleId : moduleIds) {
            int ret = mapper.deleteById(moduleId);
            sum+=ret;
        }
        return Resp.toReturn(sum == moduleIds.size()?"成功":"失败",sum == moduleIds.size());
    }

    /**
     * 找属于该菜单id的 儿子
     * @param menuId
     * @param allMenus
     * @return
     */
    public List<Menu> getChild(Long menuId, List<Menu> allMenus){
        //找最近的儿子数据出来
        List<Menu> childMenus = new ArrayList<>();
        for (Menu allMenu : allMenus){
            if (allMenu.getPid() == menuId){
                childMenus.add(allMenu);
            }
        }
        if (childMenus.size() == 0){
            return childMenus;
        }
        //还要找儿子的儿子
        for (Menu childMenu : childMenus) {
            //说明还不是最低层的儿子
            if (StringUtils.isEmpty(childMenu.getUrl())){
                //递归
                childMenu.setMenus(getChild(childMenu.getId(),allMenus));
            }
        }
        return childMenus;
    }
}
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper,Role> implements IRoleService {
    @Resource
    private RoleMapper mapper;

    @Resource
    private UsersMapper usersMapper;

    @Resource
    private MenuMapper menuMapper;

    @Resource
    private RoleMenuMapper roleMenuMapper;
    @Override
    public PageResp<List<Role>> selectRoleList(Integer page, Integer limit, String roleName, String roleNo) {
        PageHelper.startPage(page,limit);
        QueryWrapper<Role> queryWrapper = new QueryWrapper<>();
        if(roleName!=null && !"".equals(roleName)){
            queryWrapper.eq("role_name",roleName);
        }
        if(roleNo!=null&&!"".equals(roleNo)){
            queryWrapper.eq("role_code",roleNo);
        }
        List<Role> list = mapper.selectList(queryWrapper);
        list.forEach(li->{
            li.setCreateUserName(usersMapper.selectById(li.getCreateUser()).getUserName());
            if(li.getUpdateUser()!=null){
                li.setEditUserName(usersMapper.selectById(li.getUpdateUser()).getUserName());
            }
        });
        PageInfo<Role> info = new PageInfo<>(list);

        PageResp<List<Role>> resp = new PageResp<>();
        resp.setCount(info.getTotal());
        resp.setData(list);
        return resp;
    }

    @Override
    public Resp saveOrUpdate(Long roleId, String roleName, String roleNo) {
        Role role = new Role();
        role.setRoleNo(roleNo);
        role.setRoleName(roleName);
        //新增
        if (roleId == null){
            //初始密码
            role.setCreateUser(UserThreadLocal.get().getUserId());
            int insert = mapper.insert(role);
            Resp.toReturn(insert>0?"成功":"失败",insert>0);
        }
        //更新
        role.setId(roleId);
        role.setUpdateUser(UserThreadLocal.get().getRoleId());
        int update = mapper.updateById(role);
        return Resp.toReturn(update>0?"成功":"失败",update>0);
    }
//
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Resp delete(Long roleId) {
        //1.删除角色
        int ret = mapper.deleteById(roleId);
        //2.删除角色所拥有的所有权限
        QueryWrapper<RoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id",roleId);
        roleMenuMapper.delete(queryWrapper);
        return Resp.toReturn(ret>0?"成功":"失败",ret>0);
    }

    @Override
    public TreeResp<List<Menu>> roleRight(Long roleId) {
        List<Menu> menus = menuMapper.selectList(null);
        TreeResp<List<Menu>> ret = new TreeResp<>();
        ret.setData(menus);

        List<RoleMenu> roleMenus = roleMenuMapper.selectList(new QueryWrapper<RoleMenu>().eq("role_id",roleId));
        ret.setList(roleMenus);
        return ret;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Resp roleRightSave(Long roleId, List<Long> menuIds) {
        //删除之前的记录
        roleMenuMapper.delete(new QueryWrapper<RoleMenu>().eq("role_id",roleId));
         //批量插入数据
        int ret = 0;
        for (Long menuId : menuIds) {
            ret+=roleMenuMapper.insert(new RoleMenu(null,menuId,roleId));
        }
        return Resp.toReturn(ret == menuIds.size()?"成功":"失败",ret == menuIds.size());
    }

    @Override
    public ListResp<List<Role>> selectRoleListNoParams() {
        List<Role> ret = mapper.selectList(null);
        ListResp<List<Role>> rsp = new ListResp<>();
        rsp.setData(ret);
        return rsp;
    }
}

定义MenuVO

@Data
@AllArgsConstructor
@NoArgsConstructor
public class MenuVo {
    private Long id;
    private String name;
}

Controller层

@RestController
@RequestMapping(Const.URL)
@Api("用户登录")
@Slf4j
public class LoginController {
    @Resource
    private IUserService service;
    @ApiOperation("登录")
    @PostMapping("login")
    public LoginResp login(@RequestParam("username") String account,
                           @RequestParam("password") String password
                           ){
        return service.login(account, password);
    }

}
@RestController
@RequestMapping(Const.URL)
public class  UserController {
    @Resource
    IUserService service;

    @PostMapping("User/list")
    public PageResp<List<Users>> selectUserList(@RequestParam("page") Integer page,
                                                @RequestParam("limit") Integer limit,
                                                @RequestParam(value = "userName",required = false)String userName,
                                                @RequestParam(value = "userMobile",required = false)String userMobile
    ){
        return service.selectUserList(page, limit, userName, userMobile);
    }

    @PostMapping("User/save")
    public Resp saveOrUpdate(@RequestParam(value = "userId",required = false) Long userId,
                             @RequestParam(value = "userName")String userName,
                             @RequestParam(value = "gender") String gender,
                             @RequestParam("account") String account,
                             @RequestParam(value = "userMobile")String userMobile,
                             @RequestParam(value = "roleId") Long roleId,
                             @RequestParam(value = "deptId") Long deptId
    ){
        return service.saveOrUpdate(userId, account, userName, gender,userMobile, roleId, deptId);
    }

    @DeleteMapping("User/delete")
    public Resp delete(@RequestParam(value = "ids") Long userId){
        return service.delete(userId);
    }

    @PostMapping("User/pwd")
    public Resp reset(@RequestParam("userId") Long userId){
        return service.resetPwd(userId);
    }

}
@RestController
@RequestMapping(Const.URL)
public class RoleController {
    @Resource
    IRoleService service;

    @PostMapping("Role/list")
    public PageResp selectRoleList(@RequestParam("page") Integer page,
                               @RequestParam("limit") Integer limit,
                               @RequestParam(value = "roleName",required = false) String roleName,
                               @RequestParam(value = "roleNo",required = false) String roleNo){
        return service.selectRoleList(page,limit,roleName,roleNo);
    }

    @PostMapping("Role/list/no/parms")
    public ListResp selectRoleListNoParams(){
        return service.selectRoleListNoParams();
    }

    @PostMapping("Role/save")
    public Resp saveOrUpdate(@RequestParam(value = "roleId",required = false) Long roleId,
                             @RequestParam(value = "roleName")String roleName,
                             @RequestParam("roleNo") String roleNo
    ){
        return service.saveOrUpdate(roleId, roleName, roleNo);
    }

    @DeleteMapping("Role/delete")
    public Resp delete(@RequestParam(value = "ids") Long roleId){
        return service.delete(roleId);
    }

    @GetMapping("RoleRight/tree/{id}")
    public TreeResp roleRight(@PathVariable(value = "id")Long id){
        return service.roleRight(id);
    }


    @PostMapping("RoleRight/save")
    public Resp roleRightSave(@RequestParam("roleId") Long roleId,
                              @RequestParam("moduleIds")List<Long>moduleIds){
        return service.roleRightSave(roleId,moduleIds);
    }
}

@RestController
@RequestMapping(Const.URL)
public class DeptController {
    @Resource
    IDeptService service;

    @PostMapping("Dept/list")
    public PageResp selectDeptList(@RequestParam("page") Integer page,
                               @RequestParam("limit") Integer limit,
                               @RequestParam(value = "deptName",required = false) String deptName,
                               @RequestParam(value = "deptNo",required = false) String deptNo){
        return service.selectDeptList(page,limit,deptName,deptNo);
    }

    @PostMapping("Dept/save")
    public Resp saveOrUpdate(@RequestParam(value = "deptId",required = false) Long deptId,
                             @RequestParam(value = "deptName")String deptName,
                             @RequestParam("deptNo") String deptNo
    ){
        return service.saveOrUpdate(deptId, deptName, deptNo);
    }

    @PostMapping("Dept/list/no/params")
    public ListResp selectDeptListNoParams(){
        return service.selectDeptListNoParams();
    }

    @DeleteMapping("Dept/delete")
    public Resp delete(@RequestParam(value = "ids") Long deptId){
        return service.delete(deptId);
    }
}

@RestController
@RequestMapping(Const.URL)
public class GoodsController {

    @Resource
    IGoodsService service;

    @PostMapping("Goods/list")
    public PageResp selectDeptList(@RequestParam("page") Integer page,
                                   @RequestParam("limit") Integer limit,
                                   @RequestParam(value = "goodsName",required = false) String goodsName,
                                   @RequestParam(value = "goodsNo",required = false) String goodsNo){
        return service.selectGoodsList(page,limit,goodsName,goodsNo);
    }

    @PostMapping("Goods/save")
    public Resp saveOrUpdate(@RequestParam(value = "goodsId",required = false) Long goodsId,
                             @RequestParam(value = "goodsName")String goodsName,
                             @RequestParam("goodsNo") String goodsNo,
                             @RequestParam("price") Double price,
                             @RequestParam("inventory") Integer inventory,
                             @RequestParam("stemPlace") String stemPlace
    ){
        return service.saveOrUpdate(goodsId, goodsName,goodsNo,price,inventory,stemPlace);
    }

    @DeleteMapping("Goods/delete")
    public Resp delete(@RequestParam(value = "ids") Long goodsId){
        return service.delete(goodsId);
    }
}

@RestController
@RequestMapping(Const.URL)
public class MenuController {
    @Resource
    IMenuService service;

    @GetMapping("menu")
    public ListResp selectMenuList(){
        return service.selectMenuList();
    }

    @PostMapping("Module/list")
    public ListResp menuList(){
        return service.selectMenuList();
    }

    @PostMapping("Module/nodes")
    public ListResp nodesList(){
        return service.nodesList();
    }

    @PostMapping("Module/save")
    public Resp saveOrUpdate(@RequestParam(value = "moduleId",required = false) Long menuId,
                             @RequestParam(value = "parentId",required = false) Long parentId,
                             @RequestParam(value = "moduleIcon")String menuIcon,
                             @RequestParam(value = "moduleUrl")String menuUrl,
                             @RequestParam(value = "moduleName")String menuName,
                             @RequestParam("moduleOrder") Integer menuOrder
    ){
        return service.saveOrUpdate(menuId, parentId, menuIcon, menuUrl, menuName, menuOrder);
    }

    @DeleteMapping("Module/delete")
    public Resp delete(@RequestParam(value = "ids") List<Long> moduleIds){
        return service.delete(moduleIds);
    }
}

定义日志

在resources目录下面定义logback.xml

<configuration>

    <!-- 控制台输出 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 输出到文件 -->
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>${user.dir}/src/main/resources/log/application.log</file>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 设置根logger的级别 -->
    <root level="info">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE"/>
    </root>

</configuration>

定义AOP

位于com.xzj.aspect包
1.数据库层的Asepect监控

@Aspect
@Slf4j
@Component
@Order(1)
public class DaoLogAspect {
    @Pointcut("execution(* com.xzj.mapper.*Mapper.*(..))")
    public void logPointCut(){}


    @Around("logPointCut()")
    public Object doAround(ProceedingJoinPoint point) throws Throwable {
        long startTime = System.currentTimeMillis();
        log.info("数据库开始执行:{}",point.getSignature().toShortString());
        Object proceed = point.proceed();
        log.info("数据库耗时:{} ms",(System.currentTimeMillis() - startTime));
        return proceed;
    }
}

2.网络层的Aspect监控

@Aspect
@Slf4j
@Component
@Order(1)     //优先执行此切面,数字越小,优先级越高
public class WebLogAspect {
    @Pointcut("execution(* com.xzj.controller..*.*(..))")
    public void logPointCut(){}

    @Before("logPointCut()")
    public void doBefore(JoinPoint joinPoint){
        //RequestContextHolder.getRequestAttributes()是Spring框架中的一个静态方法,用于获取当前线程中的请求属性对象。
        ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        log.info("请求地址:{}",request.getRequestURL().toString());
        log.info("请求方法:{}",request.getMethod());
        //getDeclaringTypeName()返回方法所在类的全名称,getName()返回方法名称
        log.info("方法签名信息:{},{}",joinPoint.getSignature().getDeclaringTypeName(),joinPoint.getSignature().getName());
        log.info("请求参数:{}", JsonUtil.getJsonString(joinPoint.getArgs()));
    }

    @AfterReturning(pointcut = "logPointCut()",returning = "ret")
    public void doAfterReturn(Object ret){
        log.debug("返回值:{}",JsonUtil.getJsonString(ret));
    }

    @Around("logPointCut()")
    public Object doAround(ProceedingJoinPoint point) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object proceed = point.proceed();
        log.info("业务层耗时:{} ms",(System.currentTimeMillis() - startTime));
        return proceed;
    }
}

自定义异常及全局捕获

给出全局捕获异常的示例

@Slf4j
@RestControllerAdvice           //用于定义全局的异常处理器(Global Exception Handler)类
public class ImsExceptionHandler extends ResponseEntityExceptionHandler {
    @ExceptionHandler(ImsAuthException.class)  //通过使用@ExceptionHandler注解并指定相应的异常类型,可以为不同类型的异常提供不同的处理逻辑,以便进行精细的异常处理和错误响应生成。
    public ResponseEntity<Resp> authExceptionHandler(ImsAuthException imsAuthException){
        printErrLog(imsAuthException);
        Resp resp = new Resp(false,imsAuthException.getMessage());
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(resp);
    }

    public void printErrLog(Exception e){
        log.error("异常:{}",e.getMessage());
    }

    @ExceptionHandler(ImsBadRequestException.class)
    public ResponseEntity<Resp> badRequestExceptionHandler(ImsBadRequestException imsBadRequestException){
        printErrLog(imsBadRequestException);
        Resp resp = new Resp(false,imsBadRequestException.getMessage());
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(resp);
    }
    @ExceptionHandler(ImsNotFoundException.class)
    public ResponseEntity<Resp> notFoundExceptionHandler(ImsNotFoundException imsNotFoundException){
        printErrLog(imsNotFoundException);
        Resp resp = new Resp(false,imsNotFoundException.getMessage());
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(resp);
    }

}

  • 9
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Munich*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值