Vue3+java开发组队功能

Vue3+java开发系统组队功能

需求分析

  1. 创建用户可以创建一个队伍(一个房间队长),设置队伍人数,队伍名称(标题),描述,超时时间。
  2. 搜索
  3. 加入,用户可以加入未满的队伍(其他人,未满,未过期),是否需要队长同意
  4. 分享队伍,邀请人员
  5. 显示队伍人数
  6. 聊天
  7. 修改队伍信息
  8. 退出
  9. 解散

系统(接口)设计

  1. 判断请求参数是否为空
  2. 是否登录,未登录直接跳转到登录,不允许创建
  3. 校验信息
    1. 队伍人数大于1小于20
    2. 队伍名称<=20
    3. 队伍人数<=412
    4. 是否公开(int)不穿默认位0,公开
    5. 如果是加密状态,一定3要有密码,且密码<=32
    6. 超时时间>当前时间
    7. 校验用户最多创建5个队伍
  4. 插入队伍信息到队伍表
  5. 插入用户 => 队伍关系到关系表

实现

1. 库表设计(10min)

  1. 数据库表设计,队伍表,队伍用户表
    -- 队伍表
    create table team
    (
        id bigint auto_increment comment 'id'
            primary key,
        name varchar(256) not null comment '队伍名称',
        description varchar(1024) null comment '描述',
        maxNum int default 1 not null comment '最大人数',
        expireTime datetime null comment '过期时间',
        userId bigint comment '用户id',
        status int default 0 not null comment '0 - 公开,1 - 私有,2 - 加密',
        password varchar(512) null comment '密码',
        createTime datetime default CURRENT_TIMESTAMP null comment '创建时间',
        updateTime datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP,
        isDelete tinyint default 0 not null comment '是否删除'
    )
        comment '队伍';
    
    -- 用户队伍关系表
    create table user_team
    (
        id bigint auto_increment comment 'id'
            primary key,
        userId bigint comment '用户id',
        teamId bigint comment '队伍id',
        joinTime datetime null comment '加入时间',
        createTime datetime default CURRENT_TIMESTAMP null comment '创建时间',
        updateTime datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP,
        isDelete tinyint default 0 not null comment '是否删除'
    )
        comment '用户队伍关系';
    

2. 增删改查代码实现(10min)

  1. 使用mybatisX-generation插件自动生成实体类服务层,持久层代码
  2. 队伍基本增删改查代码编写
    /**
     * 队伍接口
     */
    @RestController
    @RequestMapping("/team")
    @CrossOrigin(origins = {"http://localhost:5173"}, allowCredentials = "true")
    @Slf4j //lombok的注解,可以在类中使用log打日志
    public class TeamController {
    
        @Resource
        private UserService userService;
    
        @Resource
        private TeamService teamService;
    
        /**
         * 增加队伍
         * @param team
         * @return
         */
        @PostMapping("/add")
        public BaseResponse<Long>  addTeam(@RequestBody Team team){//接收前端传来队伍的信息
            if(team == null){
                throw new  BusinessException(ErrorCode.PARAMS_ERROR);
            }
            boolean save = teamService.save(team);//teamService继承自Iservices的接口,底层实现了serviceImpl
            //需要返回新生成数据的id,使用mybatis的组件回写
            if(!save){
                throw new BusinessException(ErrorCode.SYSTEM_ERROR,"插入失败");
            }
            return ResultUtils.success(team.getId());
    
    
        }
    
        /**
         * 删除队伍
         *
         * @param id
         * @return
         */
        @PostMapping("/delete")
        public BaseResponse<Boolean> deleteTeam(@RequestBody long id){//接收前端传来队伍的信息
            if(id <= 0){
                throw new  BusinessException(ErrorCode.PARAMS_ERROR);
            }
            boolean result = teamService.removeById(id);//teamService继承自Iservices的接口,底层实现了serviceImpl
            //需要返回新生成数据的id,使用mybatis的组件回写
            if(!result){
                throw new BusinessException(ErrorCode.SYSTEM_ERROR,"删除失败");
            }
            return ResultUtils.success(true);
    
    
        }
        /**
         * 改动队伍
         *
         * @param team
         * @return
         */
        @PostMapping("/delete")
        public BaseResponse<Boolean> updateTeam(@RequestBody Team team){//接收前端传来队伍的信息
            if(team == null){
                throw new  BusinessException(ErrorCode.PARAMS_ERROR);
            }
            boolean result = teamService.updateById(team);//teamService继承自Iservices的接口,底层实现了serviceImpl
            //需要返回新生成数据的id,使用mybatis的组件回写
            if(!result){
                throw new BusinessException(ErrorCode.SYSTEM_ERROR,"更新失败");
            }
            return ResultUtils.success(true);
    
    
        }
        
        /**
         * 查询队伍
         *
         * @param id
         * @return
         */
        @GetMapping("/delete")
        public BaseResponse<Team> getTeamById(@RequestBody long id){//接收前端传来队伍id的信息
            if(id <= 0){
                throw new  BusinessException(ErrorCode.PARAMS_ERROR);
            }
            Team team = teamService.getById(id);//teamService继承自Iservices的接口,底层实现了serviceImpl
            //需要返回新生成数据的id,使用mybatis的组件回写
            if(team == null){
                throw new BusinessException(ErrorCode.NULL_ERROR,"数据为空!");
            }
            return ResultUtils.success(team);
        }
    }
    
    
  3. 查询队伍列表功能实现
    1. 新建TeamQuery业务请求参数封装类作为作为参数
      • 原因:
        1. 请求参数和实体类不一样;
        2. 有些参数用不到;
        3. 多个实体类映射到同一个字段
        4. 有些字段要隐藏不返回到前端
      • 代码实现
        /**
         * 队伍查询封装类
         */
        @EqualsAndHashCode(callSuper = true)
        @Data
        public class TeamQuery extends PageRequest {
            /**
             * id
             */
            @TableId(type = IdType.AUTO)
            private Long id;
            /**
             * 队伍名称
             */
            private String name;
            /**
             * 描述
             */
            private String description;
            /**
             * 最大人数
             */
            private Integer maxNum;
            /**
             * 用户id
             */
            private Long userId;
            /**
             * 0 - 公开,1 - 私有,2 - 加密
             */
            private Integer status;
        }
        
    2. 实现查询队伍列表
      /**
       * 查询组队列表
       * @param teamQuery
       * @return
       */
      @GetMapping("/list")
      //新建teamQuery业务请求参数封装类作为,原因:1.请求参数和实体类不一样;2.有些参数用不到;3.有些字段要隐藏不返回到前端
      public BaseResponse<List<Team>> listTeams(TeamQuery teamQuery){
          if (teamQuery == null){
              throw new BusinessException(ErrorCode.PARAMS_ERROR);
          }
          Team team = new Team();
          BeanUtils.copyProperties(team,teamQuery);
          QueryWrapper<Team> queryWrapper = new QueryWrapper<>();
          List<Team> teamList = teamService.list(queryWrapper);
          return ResultUtils.success(teamList);
      }
      
  4. 分页查询队伍列表功能实现
    1. 新建请求分页类
      /**
       * 分页请求类
       *
       * @author Erha
       */
      @Data
      public class PageRequest implements Serializable {
          //使对象序列化保持唯一
          private static final long serialVersionUID = -9075033996918167511L;
      
          /**
           * 页面大小
           */
          protected int pageSize;
          /**
           * 当前第几页
           */
          protected int pageNum;
      }
      
    2. 分页查询队伍实现代码
      /**
       * 分页查询组队列表
       * @param teamQuery
       * @return
       */
      @GetMapping("/list/page")
      public BaseResponse<Page<Team>> listTeamsByPage(TeamQuery teamQuery){
          if(teamQuery == null){
              throw new  BusinessException(ErrorCode.PARAMS_ERROR);
          }
          Team team = new Team();
          BeanUtils.copyProperties(team, teamQuery);//把哪个对象的字段复制到另外一个中
          Page<Team> page = new Page<>(teamQuery.getPageNum(), teamQuery.getPageSize());
          QueryWrapper<Team> queryWrapper = new QueryWrapper<>(team);
          Page<Team> Resultpage = teamService.page(page, queryWrapper);
          return ResultUtils.success(Resultpage);
      
      }
      
  5. 使用Swagger+knif4j文档接口
    在这里插入图片描述

3. 业务逻辑(30min)

  1. 创建队伍业务逻辑实现
    /**
    * @author serendipity
    * @description 针对表【team(队伍)】的数据库操作Service实现
    * @createDate 2023-11-28 19:33:44
    */
    @Service
    public class TeamServiceImpl extends ServiceImpl<TeamMapper, Team>
            implements TeamService {
        @Resource
        private UserTeamService userTeamService;
        @Override
        @Transactional(rollbackFor = Exception.class)
        public long addTeam(Team team, User loginUser) {
            //1.请求参数是否为空
            if (team == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
            //2.是否登录,未登录不允许创建
            if (loginUser == null) {
                throw new BusinessException(ErrorCode.NO_AUTH);
            }
            final long userId = loginUser.getId();
            //3.检验信息
            //(1).队伍人数>1且<=20
            int maxNum = Optional.ofNullable(team.getMaxNum()).orElse(0);//如果为空,直接赋值为0
            if (maxNum < 1 || maxNum > 20) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍人数不满足要求");
            }
            //(2).队伍标题 <=20
            String name = team.getName();
            if (StringUtils.isBlank(name) || name.length() > 20) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍标题不满足要求");
            }
            // (3) 描述<= 512
            String description = team.getDescription();
            if (StringUtils.isNotBlank(description) && description.length() > 512) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍描述过长");
            }
            //(4)status 是否公开,不传默认为0
            int status = Optional.ofNullable(team.getStatus()).orElse(0);
            TeamStatusEnum statusEnum = TeamStatusEnum.getEnumByValue(status);
            if (statusEnum == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍状态不满足要求");
            }
            //(5)如果status是加密状态,一定要密码 且密码<=32
            String password = team.getPassword();
            if (TeamStatusEnum.SECRET.equals(statusEnum)) {
                if (StringUtils.isBlank(password) || password.length() > 32) {
                    throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码设置不正确");
                }
            }
            //(6)超出时间 > 当前时间
            Date expireTime = team.getExpireTime();
            if (new Date().after(expireTime)) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "超出时间 > 当前时间");
            }
            //(7)校验用户最多创建5个队伍
            //todo 有bug。可能同时创建100个队伍
            QueryWrapper<Team> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("userId", userId);
            long hasTeamNum = this.count(queryWrapper);
            if (hasTeamNum >= 5) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户最多创建5个队伍");
            }
            //4.插入队伍消息到队伍表
            team.setId(null);
            team.setUserId(userId);
            boolean result = this.save(team);
            Long teamId = team.getId();
            if (!result || teamId == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "创建队伍失败");
            }
            //5. 插入用户 ==> 队伍关系 到关系表
            UserTeam userTeam = new UserTeam();
            userTeam.setUserId(userId);
            userTeam.setTeamId(teamId);
            userTeam.setJoinTime(new Date());
            result = userTeamService.save(userTeam);
            if (!result) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "创建队伍失败");
            }
            return teamId;
        }
    }
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/198432.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

iconfont 使用彩色图标

1、下载iconfont到本地 2、全局安装 iconfont-tools npm install -g iconfont-tools 3、在iconfont解压目录下执行命令、一直回车 iconfont-tools 4、文件拷贝 执行完上述命令后会生成iconfont-weapp目录&#xff0c;将iconfont-weapp目录下的iconfont-weapp- icon.css文件…

ELK日志系统

&#xff08;一&#xff09;ELK 1、elk&#xff1a;是一套完整的日志集中处理方案&#xff0c;由三个开源的软件简称组成 2、E&#xff1a;ElasticSearch&#xff08;ES&#xff09;&#xff0c;是一个开源的&#xff0c;分布式的存储检索引擎&#xff08;索引型的非关系型数…

【开源】基于JAVA的城市桥梁道路管理系统

项目编号&#xff1a; S 025 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S025&#xff0c;文末获取源码。} 项目编号&#xff1a;S025&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询城市桥…

大模型训练为什么用A100不用4090

这是一个好问题。先说结论&#xff0c;大模型的训练用 4090 是不行的&#xff0c;但推理&#xff08;inference/serving&#xff09;用 4090 不仅可行&#xff0c;在性价比上还能比 H100 稍高。4090 如果极致优化&#xff0c;性价比甚至可以达到 H100 的 2 倍。 事实上&#x…

蓝桥杯day02——移动机器人

1.题目 有一些机器人分布在一条无限长的数轴上&#xff0c;他们初始坐标用一个下标从 0 开始的整数数组 nums 表示。当你给机器人下达命令时&#xff0c;它们以每秒钟一单位的速度开始移动。 给你一个字符串 s &#xff0c;每个字符按顺序分别表示每个机器人移动的方向。L 表…

leetcode LCR24反转单链表

反转单链表 题目描述 题目分析 先来说迭代的思想&#xff1a; 上面next cur->next应该放在cur->next pre前面执行&#xff0c;这里笔误 再来说递归的思想&#xff1a; 题目代码 这个代码里面我加了我自己写的测试数据&#xff0c;自己可以去找对应的部分&#xff0c…

springboot整合redis+自定义注解+反射+aop实现分布式锁

1.定义注解 import java.lang.annotation.*; import java.util.concurrent.TimeUnit;/** Author: best_liu* Description:* Date: 16:13 2023/9/4* Param * return **/ Retention(RetentionPolicy.RUNTIME) Target({ElementType.METHOD}) Documented public interface RedisLo…

OpenCV | 傅里叶变换——低通滤波器与高通滤波器

import cv2 #opencv 读取的格式是BGR import numpy as np import matplotlib.pyplot as plt #Matplotlib是RGB %matplotlib inline def cv_show(img,name):cv2.imshow(name,img)cv2.waitKey()cv2.destroyAllWindows() 傅里叶变换 傅里叶变换的作用 高频&#xff1a;变化剧烈…

Java抽象类:类的幕后黑手,提供继承和扩展的框架。

&#x1f451;专栏内容&#xff1a;Java⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;前路未远&#xff0c;步履不停 目录 一、抽象类的概念二、注意事项三、抽象类的作用 一、抽象类的概念 在面向对象的概念中&#xff0c;所有的对象都是通过类来描绘…

Facebook的这份开源协议使React四面楚歌

如果你觉得一些科技公司看起来很美好&#xff0c;每天都在“改变世界”……你应该看看他们的用户条款和法律文书&#xff0c;藏污纳垢之严重令人震惊。 最近&#xff0c;百度和阿里巴巴内部的软件工程团队不约而同做了一件事——弃用 React。 解释下&#xff1a; React 是一个…

Web框架与Django路由层

Web框架 一 web框架 Web框架&#xff08;Web framework&#xff09;是一种开发框架&#xff0c;用来支持动态网站、网络应用和网络服务的开发。这大多数的web框架提供了一套开发和部署网站的方式&#xff0c;也为web行为提供了一套通用的方法。web框架已经实现了很多功能&…

MicroPython STM32F4 RTC功能使用介绍

MicroPython STM32F4 RTC功能使用介绍 &#x1f516;STM32和ESP32 RTC功能差不多&#xff0c;相关篇《MicroPython ESP32 RTC功能使用介绍》&#x1f4cc;固件刷可参考前面一篇《STM32刷Micropython固件参考指南》&#x1f33f; 相关篇《Micropython STM32F4入门点灯》&#x1…

java设计模式 开闭原则

开闭原则&#xff08;Open-Closed Principle&#xff0c;OCP&#xff09;是面向对象设计中的一个重要原则&#xff0c;它指导着我们如何设计和组织代码&#xff0c;以便使系统在扩展性和可维护性方面更加优秀。 开闭原则的定义是&#xff1a;软件实体&#xff08;类、模块、函数…

纵行科技获评“汽车物流行业优秀技术装备供应商”

近日&#xff0c;由中国物流与采购联合会主办&#xff0c;中物联汽车物流分会承办的“2023年全国汽车物流行业年会”在湖北十堰盛大召开。本次年会集合了汽车整车、零部件、售后备件、进出口物流企业和物流装备技术企业、科研机构及院校等&#xff0c;分享汽车物流行业现状、相…

java文件上传以及使用阿里云OSS

JavaWeb 文件上传本地存储阿里云OSS配置文件 yml配置文件 文件上传 前端页面三要素&#xff1a; 表单项type“file” 表单提交方式post 表单的enctype属性multipart/form-data 本地存储 保证上传的文件不重复 //获取原始文件名String originalFilename image.getOriginalFi…

0-1背包的初始化问题

题目链接 这道题的状态转移方程比较易于确定。dp[i][j]表示能放前i个物品的情况下&#xff0c;容量为j时能放物品的数量&#xff08;这道题歌曲数量对应物品数量&#xff0c;容量对应时间&#xff09;。 技巧&#xff08;收获&#xff09; 二维dp数组可以视情况优化为一维dp数组…

Spring Boot 3 + Spring Security 6 最新版本修改 Json 登录后 RememberMe 功能问题失效的解决方案

当 Spring Boot 版本更新到 3 之后&#xff0c;最低要求的 JDK 版本变为 17&#xff0c;相应的 最新版本的 Spring Security 的配置也发生了变化&#xff0c;一下主要讲解一些新的 Spring Security 的配置方法 1. 配置由继承WebSeucrityConfigurerAdapter变成只需添加一个Secur…

人工智能-优化算法之梯度下降

梯度下降 尽管梯度下降&#xff08;gradient descent&#xff09;很少直接用于深度学习&#xff0c; 但了解它是理解下一节随机梯度下降算法的关键。 例如&#xff0c;由于学习率过大&#xff0c;优化问题可能会发散&#xff0c;这种现象早已在梯度下降中出现。 同样地&#x…

一款多功能露营专用氛围灯

一、主要功能 使用COB灯丝3D打印构建精妙的螺旋线条露营灯 选用IP5328P作为电源主控&#xff0c;支持双向PD快充&#xff0c;支持PPS档位输出 电池仓结构设计兼容26650&#xff08;不可更换&#xff09;或21700/18650&#xff08;可更换&#xff09;电池 使用WS2812灯组成顶…

内置函数【MySQL】

文章目录 MySQL 内置函数日期和时间函数字符串函数数学函数信息函数参考资料 MySQL 内置函数 MySQL 的内置函数主要分为以下几种&#xff1a; 字符串函数&#xff1a;用于对字符串进行操作&#xff0c;如连接、截取、替换、反转、格式化等。数值函数&#xff1a;用于对数值进…
最新文章