基于Java的仓库管理系统设计与实现(三)

好几天没写,当前进度已经写了七七八八的六六七七了,配置了SpringSecurity和Jwt实现权限控制,原本的登录方法也改成了使用过滤器控制,还有大部分的增删改查。

1. 导入依赖

1.1 导入SpringSecurity和Jwt依赖

这里还导入了hutool,简单来说就是包含多种常用的工具类,这里主要是进行jwt处理。

        <!-- <hutool.version>5.8.26</hutool.version>
        <jwt.version>0.12.5</jwt.version> -->
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-security</artifactId>
         </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>${hutool.version}</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>${jwt.version}</version>
        </dependency>

1.2 编写配置类

首先编写SpringSecurity配置类,SecurityConfig.java 这里还使用了jwt过滤器,登录成功处理器、登陆失败处理器、BC加密、自定义登录过滤器(因为SpringSecurity登录默认是表单格式,我要改成json格式,所以自定义登录过滤器),直接复制即可,具体场景具体修改,不会就百度搜,能用就是好的。

  1. SecurityConfig.java
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Resource
    JwtFilter jwtFilter;

    @Resource
    LoginSuccessHandler loginSuccessHandler;

    @Resource
    LoginFailHandler loginFailHandler;
    @Resource
    UserDetailsService userDetailsService;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }

    /**
     * 配置Spring Security过滤链
     *
     * @param http HttpSecurity对象,用于配置安全过滤链
     * @return 配置好的SecurityFilterChain对象
     * @throws Exception 如果配置过程中发生异常
     */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.csrf(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests(authorize -> authorize
                        .requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll()
                        .requestMatchers("/auth/**").permitAll()
                        .anyRequest().authenticated()
                )
                .sessionManagement(sessionManagement -> sessionManagement
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                )
                .addFilterAt(loginFilter(), UsernamePasswordAuthenticationFilter.class)
                .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
                .authenticationProvider(customAuthenticationProvider())
//                .formLogin(form -> form
//                        .loginProcessingUrl("/auth/login")
//                        .successHandler(loginSuccessHandler)
//                        .failureHandler(loginFailHandler)
//                )
                .userDetailsService(userDetailsService);

        return http.build();
    }


    @Bean
    JsonLoginFilter loginFilter() throws Exception {
        JsonLoginFilter loginFilter = new JsonLoginFilter();
        AuthenticationManager authenticationManager = authenticationManager(authenticationConfiguration());
        loginFilter.setAuthenticationManager(authenticationManager);
        loginFilter.setFilterProcessesUrl("/auth/login");
        loginFilter.setAuthenticationSuccessHandler(loginSuccessHandler);
        loginFilter.setAuthenticationFailureHandler(loginFailHandler);
        return loginFilter;
    }

    @Bean
    public AuthenticationConfiguration authenticationConfiguration() {
        return new AuthenticationConfiguration();
    }

    @Bean
    public CustomAuthenticationProvider customAuthenticationProvider() {
        return new CustomAuthenticationProvider(userDetailsService, passwordEncoder());
    }
}
  1. 创建filter包,包下创建自定义登录过滤器JsonLoginFilter.java
public class JsonLoginFilter extends UsernamePasswordAuthenticationFilter {

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        //仅支持POST方法
        if (!"POST".equals(request.getMethod())) {
            throw new UserNamePasswordException("不支持当前请求:" + request.getMethod());
        }
        if ("application/json".equals(request.getContentType())) {
            try {
                Map<String, String> loginData = objectMapper.readValue(request.getInputStream(), Map.class);
                String username = loginData.get("username");
                String password = loginData.get("password");
                UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
                setDetails(request, authRequest);
                return this.getAuthenticationManager().authenticate(authRequest);
            } catch (IOException e) {
                throw new UserNamePasswordException("请输入正确的账号密码");
            }
        } else {
            throw new UserNamePasswordException("请输入正确的账号密码");
        }
    }
}
  1. 登录处理器,成功和失败LoginFailHandlerLoginSuccessHandler
@Component
public class LoginSuccessHandler implements AuthenticationSuccessHandler {

//    @Resource
//    private RedisUtils redisUtils;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
                                        HttpServletResponse response,
                                        Authentication authentication) throws IOException, ServletException {
        //设置客户端的响应内容格式为JSON
        response.setContentType("application/json;charset=UTF-8");
        User user = (User) authentication.getPrincipal();
        //生成token
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("username", user.getUsername());
        map.put("userId",user.getId());
        String token = JwtUtil.createToken(map);
        //获取一下过期时间
        NumberWithFormat claim = (NumberWithFormat) JwtUtil.parseToken(token).getClaim(JWTPayload.EXPIRES_AT);
        long expiredTime = Convert.toDate(claim).getTime();
        AuthenticationResult authenticationResult = new AuthenticationResult(user.getId(), ResultCode.SUCCESS,token,expiredTime,true,"登录成功");
        //获取一个结果
        String result = JSONUtil.toJsonStr(authenticationResult);
        //获取输出流
        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.write(result.getBytes(StandardCharsets.UTF_8));
        outputStream.flush();
        outputStream.close();
//        //把token存到redis里面,设置过期时间
//        String tokenKey = "token:" + token;
//        long nowTime = DateTime.now().getTime();
//        redisUtils.set(tokenKey,token,(expiredTime-nowTime)/1000);
    }
}



@Component
public class LoginFailHandler implements AuthenticationFailureHandler {

    /**
     * 处理登录失败的方法。
     *
     * @param request   当前的HTTP请求
     * @param response  当前的HTTP响应
     * @param exception 登录过程中抛出的异常
     * @throws IOException      如果输出流操作失败
     * @throws ServletException 如果Servlet操作失败
     */
    @Override
    public void onAuthenticationFailure(HttpServletRequest request,
                                        HttpServletResponse response,
                                        AuthenticationException exception) throws IOException, ServletException {
        // 设置响应内容类型为JSON,字符编码为UTF-8
        response.setContentType("application/json;charset=UTF-8");

        // 获取响应的输出流
        ServletOutputStream outputStream = response.getOutputStream();

        // 初始化错误码和错误信息
        int code = ResultCode.ERROR;
        String msg = exception.getMessage();;
        System.out.println("失败异常类型:" + exception.getClass());
        // 根据不同的异常类型设置相应的错误码和错误信息
        if (exception instanceof CustomerAuthenticationException) {
            code = ResultCode.UNAUTHORIZED;
        }

        // 将错误信息封装到Result对象中,并转换为JSON字符串
        String result = JSONUtil.toJsonStr(Result.fail().setCode(code).setMessage(msg));
        // 将JSON字符串写入输出流
        outputStream.write(result.getBytes(StandardCharsets.UTF_8));

        // 刷新输出流并关闭
        outputStream.flush();
        outputStream.close();
    }
}

  1. 登录成功要生成token,所以需要定义jwt工具类
public class JwtUtil {
    private static final String SECRET_KEY = "23306010225";
    private static final long EXPIRATION_TIME = 86400000;

    /**
     * 生成JWT Token
     *
     * @param payload 包含用户信息的Map对象
     * @return 生成的JWT Token
     */
    public static String createToken(Map<String, Object> payload) {
        // 获取当前时间
        DateTime now = DateTime.now();
        // 计算Token的过期时间
        DateTime date = new DateTime(now.getTime() + EXPIRATION_TIME);

        // 设置签发时间
        payload.put(JWTPayload.ISSUED_AT, now);
        // 设置过期时间
        payload.put(JWTPayload.EXPIRES_AT, date);
        // 设置生效时间,确保Token在签发后立即生效
        payload.put(JWTPayload.NOT_BEFORE, now);

        // 使用Hutool工具类生成JWT Token
        return JWTUtil.createToken(payload, SECRET_KEY.getBytes());
    }


    /**
     * 解析JWT Token,获取Payload信息
     *
     * @param token 需要解析的JWT Token
     * @return 解析后的Payload对象
     */
    public static JWTPayload parseToken(String token) {
        JWT jwt = null;
        // 使用Hutool工具类解析JWT Token
        try {
            jwt = JWTUtil.parseToken(token);
        } catch (Exception e) {
            throw new CustomerAuthenticationException("token无效");
        }

        // 设置密钥并验证Token的签名
        if (!jwt.setKey(SECRET_KEY.getBytes()).verify() || !jwt.validate(0)) {
            throw new CustomerAuthenticationException("token无效");
        }

//        // 验证Token是否过期
//        if (!jwt.validate(0)) {
//            throw new CustomerAuthenticationException("Token已过期");
//        }

        // 返回解析后的Payload对象
        return jwt.getPayload();
    }
}
  1. 还有登录成功返回的用户数据,定义一个认证返回结果类
/**
 * 认证登录返回结果
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AuthenticationResult {
    private Long id;
    private int code;
    private String access_token;
    private Long expireTime;
    private boolean success;
    private String message;
}
  1. 自定义用户服务类,权限还没写,注释掉
/**
 * 自定义用户详情服务类,实现Spring Security的UserDetailsService接口。
 * 该类负责根据用户名从数据库中加载用户信息,并设置用户的权限。
 */
@Component
public class CustomerUserDetailsService implements UserDetailsService {

    // 注入用户服务接口
    @Resource
    private IUserService userService;

    // 注入权限服务接口
    @Resource
    private IPermissionService permissionService;

    /**
     * 根据用户名加载用户详情。
     * 该方法首先根据用户名从数据库中查询用户信息,
     * 如果用户不存在,则抛出UsernameNotFoundException异常。
     * 如果用户存在,则查询用户的权限列表,并设置用户的权限。
     *
     * @param username 用户名
     * @return UserDetails 用户详情对象
     * @throws UsernameNotFoundException 如果用户不存在,则抛出此异常
     */
    @Override
    public UserDetails loadUserByUsername(String username) {
            // 根据用户名在数据库中查询用户信息
            User user = userService.getUserInfo(username);
            if (Objects.isNull(user)) {
                throw new UsernameNotFoundException("账号不存在");
            }
            // 账号被禁用
            if(user.getStatus() == 1){
                throw new DisabledException("账号已禁用");
            }

            // 返回用户详情对象
            return user;
    }



//        // 查询用户的权限列表
//        List<Permission> permissionList = permissionService.selectPermissionsListByUserId(user.getId());
//
//        // 设置用户的权限列表
//        user.setPermissions(permissionList);
//
//        // 过滤掉空值,并将权限代码转换为字符串列表
//        List<String> list = permissionList.stream()
//                .filter(Objects::nonNull)
//                .map(Permission::getPermissionCode)
//                .filter(Objects::nonNull)
//                .collect(Collectors.toList());
//
//        // 将权限列表转换为字符串数组
//        String[] array = list.toArray(new String[list.size()]);
//
//        // 创建GrantedAuthority列表
//        List<GrantedAuthority> authorityList = AuthorityUtils.createAuthorityList(array);
//
//        // 设置用户的GrantedAuthority列表
//        user.setAuthorities(authorityList);
}

  1. 还有jwt过滤器,实现对请求进行拦截,token验证
@Component
public class JwtFilter extends OncePerRequestFilter {
    @Resource
    UserDetailsService userDetailsService;

    private static final String LOGIN_URL = "/auth/login";

    @Resource
    LoginFailHandler loginFailHandler;

    private final RequestMatcher permitAllMatcher;

    public JwtFilter() {
        this.permitAllMatcher = new OrRequestMatcher(
                new AntPathRequestMatcher("/swagger-ui/**"),
                new AntPathRequestMatcher("/v3/api-docs/**"),
                new AntPathRequestMatcher("/auth/**")
        );
    }
    /**
     * 重写doFilterInternal方法,执行Token验证逻辑。
     *
     * @param request 请求对象
     * @param response 响应对象
     * @param filterChain 过滤器链
     * @throws ServletException Servlet异常
     * @throws IOException IO异常
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        String url = request.getRequestURI();
        if (permitAllMatcher.matches(request)) {
            // 继续执行过滤链
            doFilter(request, response, filterChain);
            return;
        }
        // 检查是否是登录请求,不需要进行Token验证
        if (!url.equals(LOGIN_URL)) {
            try {
                verifyToken(request, response);
            } catch (AuthenticationException e) {
                // 处理认证失败的情况
                loginFailHandler.onAuthenticationFailure(request, response, e);
            }
        }
        // 继续执行过滤链
        doFilter(request, response, filterChain);
    }

    /**
     * 验证请求中的Token。
     *
     * @param request 请求对象
     * @param response 响应对象
     * @throws AuthenticationException 如果Token无效或缺失,则抛出该异常
     */
    private void verifyToken(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        // 从请求头中获取Token
        String token = request.getHeader("token");
        // 如果请求头中没有Token,则从请求参数中获取
        if (token == null || token.isEmpty()) {
            token = request.getParameter("token");
        }
        // 如果仍然没有Token,则抛出异常
        if (token == null || token.isEmpty()) {
            throw new CustomerAuthenticationException("缺少必要参数token");
        }
        // Token存在,尝试从Redis中获取对应的Token值
//        String tokenKey = "token:" + token;
//        String redisToken = redisUtils.get(tokenKey);
        // 校验Redis中的Token是否存在并且与提供的Token一致
//        if (redisToken == null || !redisToken.equals(token)) {
//            throw new CustomerAuthenticationException("token已过期或无效");
//        }
        // 解析Token获取用户名

        String username = JwtUtil.parseToken(token).getClaim("username").toString();
        if (username == null) {
            throw new CustomerAuthenticationException("token无效");
        }
        // 根据用户名加载用户详情
        UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        if (userDetails == null) {
            throw new CustomerAuthenticationException("token无效");
        }
        // 所有验证通过,创建认证令牌
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
        // 设置请求的详细信息
        authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
        // 将认证信息存入SecurityContext
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
    }
}

  1. 但是有个问题,我想实现账号不存在抛出异常,最终运行抛出后流程仍然继续执行,最终返回密码错误BadCredentialsException异常,AI解决方案是自定义这个Provider

这样做了以后,执行自定义服务类的loadUserByUsername方法后,抛出UsernameNotFoundException异常,不会再被BadCredentialsException覆盖,实现响应账号不存在,但是换机器部署又响应403,本地怀疑缓存,清缓存又重启试过,仍然可行,暂时先这样,没有案例相关经验,有点挠头。

public class CustomAuthenticationProvider implements AuthenticationProvider {

    private final UserDetailsService userDetailsService;
    private final PasswordEncoder passwordEncoder;

    public CustomAuthenticationProvider(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
        this.userDetailsService = userDetailsService;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        String password = authentication.getCredentials().toString();

        try {
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            if (!passwordEncoder.matches(password, userDetails.getPassword())) {
                throw new BadCredentialsException("密码错误");
            }
            return new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities());
        } catch (UsernameNotFoundException e) {
            throw e; // 直接抛出 UsernameNotFoundException,不合并到 BadCredentialsException
        }
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }
}

2. 全局异常处理配置

感觉写的很蠢,(ˉ▽ˉ;)...

    /**
     * 全局异常处理类
     * 用于捕获并处理Spring Boot应用中的所有异常,并返回统一的响应格式
     */
@RestControllerAdvice
@Slf4j
public class GlobalException {

        /**
         * 处理所有类型的异常
         *
         * @param e 捕获到的异常对象
         * @return 包含异常信息的统一响应结果
         */
        @ExceptionHandler(value = Exception.class)
        public Result<?> handleException(Exception e) {
            // 记录异常信息到日志
            Integer code = ResultCode.ERROR;
            log.error("异常信息:{} ,异常类别:{}", e.getMessage() , e.getClass());
            if (e.getMessage().contains("PageUtil"))return Result.fail().setMessage("缺少必要参数pageNum或pageSize").setCode(code);
            else if (e.getMessage().contains("Duplicate"))return Result.fail().setMessage("请检查内容是否已存在").setCode(code);
            else if (e.getMessage().contains("is null"))return Result.fail().setMessage("缺少必要参数").setCode(code);
            // 返回包含异常信息的统一响应结果
            return Result.fail().setMessage(e.getMessage()).setCode(code);
        }
         /**
          * 可以单独处理类型的异常,不再演示,根据需求编写
          *
          * @param e 捕获到的异常对象
          * @return 包含异常信息的统一响应结果
          */
         @ExceptionHandler(value = HttpMessageNotReadableException.class)
         public Result<?> handleException(HttpMessageNotReadableException  e) {
             // 记录异常信息到日志
             log.error("异常信息:{} ,异常类别:{}", e.getMessage() , e.getClass());
             // 返回包含异常信息的统一响应结果
             return Result.fail().setMessage("JSON解析错误");
         }

        /**
         * 可以单独处理类型的异常,不再演示,根据需求编写
         *
         * @param e 捕获到的异常对象
         * @return 包含异常信息的统一响应结果
         */
        @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
        public Result<?> handleException(HttpRequestMethodNotSupportedException  e) {
            // 记录异常信息到日志
            log.error("异常信息:{} ,异常类别:{}", e.getMessage() , e.getClass());
            // 返回包含异常信息的统一响应结果
            return Result.fail().setMessage("不支持该请求");
        }

        @ExceptionHandler(value = DataIntegrityViolationException.class)
        public Result<?> handleException(DataIntegrityViolationException  e) {
            // 记录异常信息到日志
            log.error("异常信息:{} ,异常类别:{}", e.getMessage() , e.getClass());
            // 返回包含异常信息的统一响应结果
            return Result.fail().setMessage("缺少必要参数");
        }

        @ExceptionHandler(value = DuplicateKeyException.class)
        public Result<?> handleException(DuplicateKeyException e) {
            // 记录异常信息到日志
            log.error("异常信息:{} ,异常类别:{}", e.getMessage() , e.getClass());
            // 返回包含异常信息的统一响应结果
            return Result.fail().setMessage("请检查内容是否已存在");
        }

3. 项目进度

前端还没想好到底怎么搞,框架最为省事,后端还是自己写一遍熟悉业务流程,积累经验。

3.1 用户控制器

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 十一月的早晨
 * @since 2025-02-26
 */
@RestController
@RequestMapping("/system/user")
@Tag(name = "用户管理", description = "负责用户管理")
public class    UserController {
    @Resource
    IUserService userService;


    @PostMapping("/list")
    @Operation(summary = "获取用户列表", description = "根据分页参数和查询条件获取用户列表")
    @ApiResponse(responseCode = "200", description = "成功获取用户列表", content = @Content(schema = @Schema(example = "{\"code\": 200,\"message\": \"获取成功\",\"data\": {\"records\": [{\"id\": 6,\"username\": \"syy\",\"password\": null,\"realName\": \"赵大海\",\"phone\": \"13222221212\",\"email\": \"13222221212@qq.com\",\"roleId\": 4,\"isDeleted\": 0,\"gmtCreate\": \"2025-02-28T15:21:31\",\"gmtModified\": \"2025-02-28T15:21:31\",\"status\": null}],\"total\": 1,\"size\": 3,\"current\": 1,\"pages\": 1},\"success\": true}")))
    @Parameters({
            @Parameter(name = "token", description = "认证令牌", required = true, in = ParameterIn.HEADER, schema = @Schema(type = "string",example = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"))
    })
    public Result<?> getRoleList(
            @Validated @RequestBody
            @Schema(example = "{\"pageNum\": \"1\",\"pageSize\": \"3\",\"data\": {\"username\": \"syy\",\"realName\": \"大海\",\"phone\": \"13222221212\",\"email\": \"13222221212@qq.com\"}}")
            PageUtil<User> user) {
        PageUtil.validatePageParam(user);
        Page<User> page = userService.getUserList(new Page<>(user.getPageNum(), user.getPageSize()),user.getData());
        return Result.success().setMessage("获取成功").setData(page);
    }


    @PostMapping("/add")
    @Operation(summary = "添加用户列表", description = "添加用户列表")
    @ApiResponse(responseCode = "200", description = "添加成功", content = @Content(schema = @Schema(example = "{\"code\":200,\"message\":\"添加成功\",\"data\":null,\"success\":true}")))
    @Parameters({
            @Parameter(name = "token", description = "认证令牌", required = true, in = ParameterIn.HEADER, schema = @Schema(type = "string",example = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"))
    })
    public Result<?> addUser(
            @Schema(example = "{\"username\": \"dahai1\",\"password\": \"123456zz\",\"realName\":\"大海1号\",\"phone\":\"13835664521\",\"email\": \"571497983@qq.com\"}")
            @RequestBody User user) {
        if(userService.saveUser(user)) return Result.success().setMessage("添加成功");
        return Result.fail().setMessage("添加失败");
    }

    @PutMapping("/edit")
    @Operation(summary = "修改用户列表", description = "修改用户列表")
    @ApiResponse(responseCode = "200", description = "修改成功", content = @Content(schema = @Schema(example = "{\"code\":200,\"message\":\"修改成功\",\"data\":null,\"success\":true}")))
    @Parameters({
            @Parameter(name = "token", description = "认证令牌", required = true, in = ParameterIn.HEADER, schema = @Schema(type = "string",example = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"))
    })
    public Result<?> editUser(
            @Schema(example = "{\"id\":7,\"realName\":\"大海1号\",\"phone\":\"13835664521\",\"email\": \"571497983@qq.com\"}")
            @RequestBody User user) {
        // 帐号和密码不允许在这里被修改   密码单独修改
        if(!StringUtils.isNullOrEmpty(user.getUsername())){
            return Result.fail().setMessage("账号不允许被修改");
        }else if(!StringUtils.isNullOrEmpty(user.getPassword())){
            return Result.fail().setMessage("密码不允许被修改");
        }else{
            if(userService.updateById(user)) return Result.success().setMessage("修改成功");
            return Result.fail().setMessage("修改失败");
        }
    }

    @DeleteMapping("/del")
    @Operation(summary = "删除用户列表", description = "删除用户列表")
    @ApiResponse(responseCode = "200", description = "删除成功", content = @Content(schema = @Schema(example = "{\"code\":200,\"message\":\"删除成功\",\"data\":null,\"success\":true}")))
    @Parameters({
            @Parameter(name = "token", description = "认证令牌", required = true, in = ParameterIn.HEADER, schema = @Schema(type = "string",example = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"))
    })
    public Result<?> delUser(
            @Schema(example = "{\"id\":3}")
            @RequestBody User user) {
        if(userService.removeById(user)) return Result.success().setMessage("删除成功");
        return Result.fail().setMessage("删除失败");
    }
}

3.2 api-docs

{"openapi":"3.0.1","info":{"title":"基于java的仓库管理系统","description":"基于java的仓库管理系统-接口文档","version":"v1"},"externalDocs":{"description":"项目API文档"},"servers":[{"url":"http://localhost:8080","description":"Generated server url"}],"tags":[{"name":"商品管理","description":"负责商品管理"},{"name":"类别管理","description":"负责商品类别管理"},{"name":"菜单管理","description":"负责菜单管理"},{"name":"库存明细管理","description":"负责商品库存明细管理"},{"name":"用户管理","description":"负责用户管理"},{"name":"客户管理","description":"负责客户管理"},{"name":"登录控制器","description":"登录流程控制管理,负责用户登录、注册等控制"},{"name":"仓库管理","description":"负责仓库管理"},{"name":"角色对应权限","description":"用于获取角色对应权限列表"},{"name":"供应商管理","description":"负责供应商管理"},{"name":"角色管理","description":"负责角色管理"}],"paths":{"/warehouse/warehouse/edit":{"put":{"tags":["仓库管理"],"summary":"修改仓库列表","description":"修改仓库列表","operationId":"editWarehouse","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"id":3,"name":"三号仓库","location":"上海市徐汇区","purpose":"生鲜类、肉禽类存储"}}}},"required":true},"responses":{"200":{"description":"修改成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"修改成功","data":null,"success":true}}}}}}}},"/system/user/edit":{"put":{"tags":["用户管理"],"summary":"修改用户列表","description":"修改用户列表","operationId":"editUser","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"id":7,"realName":"大海1号","phone":"13835664521","email":"571497983@qq.com"}}}},"required":true},"responses":{"200":{"description":"修改成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"修改成功","data":null,"success":true}}}}}}}},"/system/role/edit":{"put":{"tags":["角色管理"],"summary":"修改角色列表","description":"修改角色列表","operationId":"editRole","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"id":5,"roleName":"游客2","description":"无任何权限,新注册用户为游客"}}}},"required":true},"responses":{"200":{"description":"修改成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"修改成功","data":null,"success":true}}}}}}}},"/system/menu/edit":{"put":{"tags":["菜单管理"],"summary":"修改菜单列表","description":"修改菜单列表","operationId":"editMenu","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"id":14,"menuName":"客户管理","path":"/business/client","parentId":12,"icon":"","orderNum":1,"menuType":1}}}},"required":true},"responses":{"200":{"description":"修改成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"修改成功","data":null,"success":true}}}}}}}},"/product/product/edit":{"put":{"tags":["商品管理"],"summary":"修改商品列表","description":"修改商品列表","operationId":"editProduct","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"id":3,"name":"百事可乐 330ml","categoryId":2,"spec":"330ml*24罐","unit":"箱","purchasePrice":42.5,"salePrice":60,"minStock":50}}}},"required":true},"responses":{"200":{"description":"修改成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"修改成功","data":null,"success":true}}}}}}}},"/product/category/edit":{"put":{"tags":["类别管理"],"summary":"修改商品分类列表","description":"修改商品分类列表","operationId":"editCategory","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"id":3,"name":"美特好超市","contact":"赵经理","phone":"13222222222","address":"太原市迎泽区"}}}},"required":true},"responses":{"200":{"description":"修改成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"修改成功","data":null,"success":true}}}}}}}},"/business/supplier/edit":{"put":{"tags":["供应商管理"],"summary":"修改供应商列表","description":"修改供应商列表","operationId":"editProduct_1","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"id":3,"name":"百事可乐公司","contact":"大经理","phone":"15236549988","address":"上海市徐汇区","minOrder":600,"supplyCategory":"2"}}}},"required":true},"responses":{"200":{"description":"修改成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"修改成功","data":null,"success":true}}}}}}}},"/business/client/edit":{"put":{"tags":["客户管理"],"summary":"修改客户列表","description":"修改客户列表","operationId":"editClient","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"id":5,"name":"主食类","parentId":1,"level":2}}}},"required":true},"responses":{"200":{"description":"修改成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"修改成功","data":null,"success":true}}}}}}}},"/warehouse/warehouse/list":{"post":{"tags":["仓库管理"],"summary":"获取仓库列表","description":"根据分页参数和查询条件获取仓库列表","operationId":"getWarehouseList","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"pageNum":"1","pageSize":"3","data":{"name":"一号仓库","location":"北京","purpose":"食品"}}}}},"required":true},"responses":{"200":{"description":"成功获取仓库列表","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"获取成功","data":{"records":[{"id":1,"name":"一号仓库","location":"北京市朝阳区","purpose":"食品存储","isDeleted":null}],"total":1,"size":3,"current":1,"pages":1},"success":true}}}}}}}},"/warehouse/warehouse/add":{"post":{"tags":["仓库管理"],"summary":"添加仓库列表","description":"添加仓库列表","operationId":"addWarehouse","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"name":"三号仓库","location":"上海市徐汇区","purpose":"生鲜类存储"}}}},"required":true},"responses":{"200":{"description":"添加成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"添加成功","data":null,"success":true}}}}}}}},"/system/user/list":{"post":{"tags":["用户管理"],"summary":"获取用户列表","description":"根据分页参数和查询条件获取用户列表","operationId":"getRoleList","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"pageNum":"1","pageSize":"3","data":{"username":"syy","realName":"大海","phone":"13222221212","email":"13222221212@qq.com"}}}}},"required":true},"responses":{"200":{"description":"成功获取用户列表","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"获取成功","data":{"records":[{"id":6,"username":"syy","password":null,"realName":"赵大海","phone":"13222221212","email":"13222221212@qq.com","roleId":4,"isDeleted":0,"gmtCreate":"2025-02-28T15:21:31","gmtModified":"2025-02-28T15:21:31","status":null}],"total":1,"size":3,"current":1,"pages":1},"success":true}}}}}}}},"/system/user/add":{"post":{"tags":["用户管理"],"summary":"添加用户列表","description":"添加用户列表","operationId":"addUser","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"username":"dahai1","password":"123456zz","realName":"大海1号","phone":"13835664521","email":"571497983@qq.com"}}}},"required":true},"responses":{"200":{"description":"添加成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"添加成功","data":null,"success":true}}}}}}}},"/system/rolePermission/byRoleId":{"post":{"tags":["角色对应权限"],"summary":"获取角色权限列表","description":"根据分页参数和查询条件获取角色","operationId":"getRolePermissionList","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"roleId":1}}}},"required":true},"responses":{"200":{"description":"成功获取角色权限列表","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"获取成功","data":{"records":[{"roleId":1,"permissionId":1,"permissionName":"system:user:add","permissionDesc":"添加用户"}],"total":1,"size":3,"current":1,"pages":1},"success":true}}}}}}}},"/system/role/list":{"post":{"tags":["角色管理"],"summary":"获取角色列表","description":"根据分页参数和查询条件获取角色列表","operationId":"getRoleList_1","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"pageNum":"1","pageSize":"3","data":{"roleName":"游客","status":"0"}}}}},"required":true},"responses":{"200":{"description":"成功获取角色列表","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"获取成功","data":{"records":[{"id":4,"roleName":"游客","description":"无任何权限,新注册用户为游客","isDeleted":null,"createTime":"2025-02-28T06:42:02","status":0}],"total":1,"size":3,"current":1,"pages":1},"success":true}}}}}}}},"/system/role/add":{"post":{"tags":["角色管理"],"summary":"添加角色列表","description":"添加角色列表","operationId":"addRole","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"roleName":"游客","description":"无任何权限,新注册用户为游客"}}}},"required":true},"responses":{"200":{"description":"添加成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"添加成功","data":null,"success":true}}}}}}}},"/system/menu/list":{"post":{"tags":["菜单管理"],"summary":"获取菜单列表","description":"获取菜单列表","operationId":"getMenuList","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"responses":{"200":{"description":"成功获取菜单列表","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"获取成功","data":{"records":[{"id":1,"menuName":"系统管理","path":"#","parentId":0,"icon":null,"orderNum":0,"menuType":"0"}],"total":1,"size":3,"current":1,"pages":1},"success":true}}}}}}}},"/system/menu/add":{"post":{"tags":["菜单管理"],"summary":"添加菜单列表","description":"添加菜单列表","operationId":"addMenu","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"menuName":"客户管理","path":"/business/client","parentId":12,"icon":"","orderNum":1,"menuType":1}}}},"required":true},"responses":{"200":{"description":"添加成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"添加成功","data":null,"success":true}}}}}}}},"/product/product/list":{"post":{"tags":["商品管理"],"summary":"获取商品列表","description":"根据分页参数和查询条件获取商品列表","operationId":"getProductList","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"pageNum":"1","pageSize":"3","data":{"name":"可口可乐","categoryName":"饮料"}}}}},"required":true},"responses":{"200":{"description":"成功获取商品列表","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"获取成功","data":{"records":[{"id":null,"name":"可口可乐 330ml","categoryId":null,"spec":"330ml*24罐","unit":"箱","purchasePrice":40.0,"salePrice":60.0,"minStock":50,"isDeleted":null,"categoryName":"饮料"}],"total":1,"size":3,"current":1,"pages":1},"success":true}}}}}}}},"/product/product/add":{"post":{"tags":["商品管理"],"summary":"添加商品列表","description":"添加商品列表","operationId":"addProduct","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"name":"百事可乐 330ml","categoryId":2,"spec":"330ml*24罐","unit":"箱","purchasePrice":42.5,"salePrice":60,"minStock":50}}}},"required":true},"responses":{"200":{"description":"添加成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"添加成功","data":null,"success":true}}}}}}}},"/product/inventory/list":{"post":{"tags":["库存明细管理"],"summary":"获取库存明细列表","description":"根据分页参数和查询条件获取库存明细列表","operationId":"getInventoryList","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"pageNum":"1","pageSize":"3","data":{"warehouseName":"一号仓库","productName":"可口可乐"}}}}},"required":true},"responses":{"200":{"description":"成功获取库存明细列表","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"获取成功","data":{"records":[{"warehouseName":"一号仓库","quantity":100,"productName":"可口可乐 330ml","minStock":50}],"total":1,"size":3,"current":1,"pages":1},"success":true}}}}}}}},"/product/category/list":{"post":{"tags":["类别管理"],"summary":"获取商品分类列表","description":"根据分页参数和查询条件获取商品分类列表","operationId":"getCategoryList","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"pageNum":"1","pageSize":"3","data":{"name":"饮料"}}}}},"required":true},"responses":{"200":{"description":"成功获取商品分类列表","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"获取成功","data":{"records":[{"id":1,"name":"饮料","parentId":1,"level":2,"isDeleted":null}],"total":1,"size":3,"current":1,"pages":1},"success":true}}}}}}}},"/product/category/add":{"post":{"tags":["类别管理"],"summary":"添加商品分类列表","description":"添加商品分类列表","operationId":"addCategory","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"name":"主食类","parentId":1,"level":2}}}},"required":true},"responses":{"200":{"description":"添加成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"添加成功","data":null,"success":true}}}}}}}},"/business/supplier/list":{"post":{"tags":["供应商管理"],"summary":"获取供应商列表","description":"根据分页参数和查询条件获取供应商列表","operationId":"getRoleList_2","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"pageNum":"1","pageSize":"3","data":{"name":"可口","contact":"王经理","phone":"13800138003","address":"广州市","supplyCategory":"饮料"}}}}},"required":true},"responses":{"200":{"description":"成功获取供应商列表","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"获取成功","data":{"records":[{"id":1,"name":"可口可乐公司","contact":"王经理","phone":"13800138003","address":"广州市天河区","minOrder":1000,"supplyCategory":"饮料","isDeleted":null}],"total":1,"size":3,"current":1,"pages":1},"success":true}}}}}}}},"/business/supplier/add":{"post":{"tags":["供应商管理"],"summary":"添加供应商列表","description":"添加供应商列表","operationId":"addProduct_1","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"name":"百事可乐公司","contact":"大经理","phone":"15236549988","address":"上海市徐汇区","minOrder":600,"supplyCategory":"2"}}}},"required":true},"responses":{"200":{"description":"添加成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"添加成功","data":null,"success":true}}}}}}}},"/business/client/list":{"post":{"tags":["客户管理"],"summary":"获取客户列表","description":"根据分页参数和查询条件获取客户列表","operationId":"getClientList","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"pageNum":"1","pageSize":"3","data":{"name":"沃尔玛","contact":"张经理","phone":"13800138001","address":"北京市"}}}}},"required":true},"responses":{"200":{"description":"成功获取客户列表","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"获取成功","data":{"records":[{"id":1,"name":"沃尔玛超市","contact":"张经理","phone":"13800138001","address":"北京市朝阳区","coopStartDate":"2023-01-01","coopEndDate":null,"isDeleted":null}],"total":1,"size":3,"current":1,"pages":1},"success":true}}}}}}}},"/business/client/add":{"post":{"tags":["客户管理"],"summary":"添加客户列表","description":"添加客户列表","operationId":"addClient","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"name":"美特好超市","contact":"王经理","phone":"13222222222","address":"太原市迎泽区"}}}},"required":true},"responses":{"200":{"description":"添加成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"添加成功","data":null,"success":true}}}}}}}},"/auth/register":{"post":{"tags":["登录控制器"],"summary":"注册账号","description":"进行用户注册","operationId":"registerUser","requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"username":"dahai","password":"mm123456","realName":"张三","phone":"13266665455","email":"xxxxxx@163.com"}}}},"required":true},"responses":{"200":{"description":"注册成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"注册成功","data":null,"success":"true"}}}}}}}},"/auth/login":{"post":{"tags":["登录控制器"],"summary":"登录账号","description":"进行用户登录","operationId":"login","requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"username":"dahai","password":"mima123456"}}}},"required":true},"responses":{"200":{"description":"登陆成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"登录成功","data":{"access_token":"ey..."},"success":"true"}}}}}}}},"/auth/checkUser":{"post":{"tags":["登录控制器"],"summary":"检测账号是否存在","description":"根据输入账号检测用户是否存在","operationId":"checkUserByAccount","requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"username":"dahai"}}}},"required":true},"responses":{"200":{"description":"账号不存在","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"账号不存在","data":null,"success":"true"}}}}}}}},"/warehouse/warehouse/del":{"delete":{"tags":["仓库管理"],"summary":"删除仓库列表","description":"删除仓库列表","operationId":"delWarehouse","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"id":3}}}},"required":true},"responses":{"200":{"description":"删除成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"删除成功","data":null,"success":true}}}}}}}},"/system/user/del":{"delete":{"tags":["用户管理"],"summary":"删除用户列表","description":"删除用户列表","operationId":"delUser","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"id":3}}}},"required":true},"responses":{"200":{"description":"删除成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"删除成功","data":null,"success":true}}}}}}}},"/system/role/del":{"delete":{"tags":["角色管理"],"summary":"删除角色列表","description":"删除角色列表","operationId":"delRole","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"id":10}}}},"required":true},"responses":{"200":{"description":"删除成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"删除成功","data":null,"success":true}}}}}}}},"/system/menu/del":{"delete":{"tags":["菜单管理"],"summary":"删除菜单列表","description":"删除菜单列表","operationId":"delMenu","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"id":14}}}},"required":true},"responses":{"200":{"description":"删除成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"删除成功","data":null,"success":true}}}}}}}},"/product/product/del":{"delete":{"tags":["商品管理"],"summary":"删除商品列表","description":"删除商品列表","operationId":"delProduct","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"id":4}}}},"required":true},"responses":{"200":{"description":"删除成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"删除成功","data":null,"success":true}}}}}}}},"/product/category/del":{"delete":{"tags":["类别管理"],"summary":"删除商品分类列表","description":"删除商品分类列表","operationId":"delCategory","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"id":2}}}},"required":true},"responses":{"200":{"description":"删除成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"删除成功","data":null,"success":true}}}}}}}},"/business/supplier/del":{"delete":{"tags":["供应商管理"],"summary":"删除供应商列表","description":"删除供应商列表","operationId":"delProduct_1","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"id":4}}}},"required":true},"responses":{"200":{"description":"删除成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"删除成功","data":null,"success":true}}}}}}}},"/business/client/del":{"delete":{"tags":["客户管理"],"summary":"删除客户列表","description":"删除客户列表","operationId":"delClient","parameters":[{"name":"token","in":"header","description":"认证令牌","required":true,"schema":{"type":"string","example":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9......"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"string","example":{"id":2}}}},"required":true},"responses":{"200":{"description":"删除成功","content":{"*/*":{"schema":{"type":"string","example":{"code":200,"message":"删除成功","data":null,"success":true}}}}}}}}},"components":{}}

3.3 项目地址

项目部署在gitee上,地址如下:https://gitee.com/jimbaby/wms_manager.git