心链10----查询修改加入队伍业务实现

心链 — 伙伴匹配系统

接口设计

查询队伍列表

:::success
分页展示队伍列表,根据名称、最大人数等搜索队伍 P0,信息流中不展示已过期的队伍

  1. 从请求参数中取出队伍名称等查询条件,如果存在则作为查询条件
  2. 不展示已过期的队伍(根据过期时间筛选)
  3. 可以通过某个关键词同时对名称和描述查询
  4. 只有管理员才能查看加密还有非公开的房间
  5. 关联查询已加入队伍的用户信息
  6. 关联查询已加入队伍的用户信息(可能会很耗费性能,建议大家用自己写 SQL 的方式实现)todo
    :::
    为了保护数据不被暴露,所以我们要新建封装类
    在model包新建vo包,并创建TeamUserVO(队伍和用户信息封装类),UserVO类(用户封装类),这两个类是返回给前端看
/*** 队伍和用户信息封装类(脱敏)** @author yupi*/
@Data
public class TeamUserVO implements Serializable {private static final long serialVersionUID = 163478861968488713L;/*** id*/private Long id;/*** 队伍名称*/private String name;/*** 描述*/private String description;/*** 最大人数*/private Integer maxNum;/*** 过期时间*/private Date expireTime;/*** 用户id*/private Long userId;/*** 0 - 公开,1 - 私有,2 - 加密*/private Integer status;/*** 创建时间*/private Date createTime;/*** 更新时间*/private Date updateTime;/*** 创建人用户信息*/private UserVO createUser;/*** 已加入的用户数*/private Integer hasJoinNum;/*** 是否已加入队伍*/private boolean hasJoin = false;
}
/*** 用户包装类(脱敏)*/
@Data
public class UserVO implements Serializable {/*** id*/private long id;/*** 用户昵称*/private String username;/*** 账号*/private String userAccount;/*** 用户头像*/private String avatarUrl;/*** 性别*/private Integer gender;/*** 电话*/private String phone;/*** 邮箱*/private String email;/*** 标签列表 json*/private String tags;/*** 状态 0 - 正常*/private Integer userStatus;/*** 创建时间*/private Date createTime;/*** */private Date updateTime;/*** 用户角色 0 - 普通用户 1 - 管理员*/private Integer userRole;/*** 星球编号*/private String planetCode;private static final long serialVersionUID = 1L;
}

在TeamService里编写查询队伍方法并在TeamServiceImpl里实现
image.png
在TeamService里面实现listTeams方法并实现
image.png
编写业务层,其中只有管理员才能查看加密还有非公开的房间,所以我们需要从请求中获得是否为管理员
所以我们这边提前修改listTeams方法(鱼皮是在写的过程中发现要获得是否为管理员,才去修改)
image.png

    @Overridepublic List<TeamUserVO> listTeams(TeamQuery teamQuery, boolean isAdmin) {QueryWrapper<Team> queryWrapper = new QueryWrapper<>();//组合查询条件if (teamQuery != null) {Long id = teamQuery.getId();if (id != null && id > 0) {queryWrapper.eq("id", id);}String searchText = teamQuery.getSearchText();if (StringUtils.isNotBlank(searchText)) {queryWrapper.and(qw -> qw.like("name", searchText).or().like("expireTime", searchText));}String name = teamQuery.getName();if (StringUtils.isNotBlank(name)) {queryWrapper.like("name", name);}String description = teamQuery.getDescription();if (StringUtils.isNotBlank(description)) {queryWrapper.like("description", description);}Integer maxNum = teamQuery.getMaxNum();//查询最大人数相等if (maxNum != null && maxNum > 0) {queryWrapper.eq("maxMum", maxNum);}Long userId = teamQuery.getUserId();//根据创建人来查询if (userId != null && userId > 0) {queryWrapper.eq("userId", userId);}//根据状态来查询Integer status = teamQuery.getStatus();TeamStatusEnum statusEnum = TeamStatusEnum.getEnumByValue(status);if (statusEnum == null) {statusEnum = TeamStatusEnum.PUBLIC;}if (!isAdmin && !statusEnum.equals(TeamStatusEnum.PUBLIC)) {throw new BusinessException(ErrorCode.NO_AUTH);}queryWrapper.eq("status", statusEnum.getValue());}//不展示已过期的队伍//expireTime is null or expireTime > now()queryWrapper.and(qw -> qw.gt("expireTime", new Date()).or().isNull("expireTime"));List<Team> teamList = this.list(queryWrapper);if (CollectionUtils.isEmpty(teamList)) {return new ArrayList<>();}List<TeamUserVO> teamUserVOList = new ArrayList<>();//关联查询创建人的用户信息for (Team team : teamList) {Long userId = team.getUserId();if (userId == null) {continue;}User user = userService.getById(userId);TeamUserVO teamUserVO = new TeamUserVO();BeanUtils.copyProperties(team, teamUserVO);//脱敏用户信息if (user!=null){UserVO userVO = new UserVO();BeanUtils.copyProperties(user, userVO);teamUserVO.setCreateUser(userVO);}teamUserVOList.add(teamUserVO);}return teamUserVOList;}

请求接口修改整理为:

    @GetMapping("/list")public BaseResponse<List<TeamUserVO>> listTeams(TeamQuery teamQuery,HttpServletRequest request){if (teamQuery == null){throw new BusinessException(ErrorCode.PARAMS_ERROR); }boolean isAdmin = userService.isAdmin(request);List<TeamUserVO> teamList = teamService.listTeams(teamQuery,isAdmin);return ResultUtils.success(teamList);}

测试,打开knife4j接口,直接不带参数发送(等于查询全部)
image.png

修改队伍信息

:::success

  1. 判断请求参数是否为空
  2. 查询队伍是否存在
  3. 只有管理员或者队伍的创建者可以修改
  4. 如果用户传入的新值和老值一致,就不用 update 了(可自行实现,降低数据库使用次数)TODO
  5. 如果队伍状态改为加密,必须要有密码
  6. 更新成功
    :::
    在TeamService里编写修改队伍信息方法并在TeamServiceImpl里实现
    同样在请求包里封装一个用户登录请求体
/*** 用户登录请求体** @author shaosao*/
@Data
public class TeamUpdateRequest implements Serializable {private static final long serialVersionUID = -6043915331807008592L;/*** id*/private Long id;/*** 队伍名称*/private String name;/*** 描述*/private String description;/*** 过期时间*/private Date expireTime;/*** 0 - 公开,1 - 私有,2 - 加密*/private Integer status;/*** 密码*/private String password;
}

在TeamService里面实现updateTeam方法并实现
image.png
修改接口更改为

    @PostMapping("/update")public BaseResponse<Boolean> updateTeam(@RequestBody TeamUpdateRequest teamUpdateRequest,HttpServletRequest request) {if (teamUpdateRequest == null) {throw new BusinessException(ErrorCode.PARAMS_ERROR);}User loginUser = userService.getLoginUser(request);boolean result = teamService.updateTeam(teamUpdateRequest,loginUser);if (!result) {throw new BusinessException(ErrorCode.SYSTEM_ERROR, "更新失败");}return ResultUtils.success(true);}

编写实现类

    @Overridepublic boolean updateTeam(TeamUpdateRequest teamUpdateRequest, User loginUser) {if (teamUpdateRequest == null) {throw new BusinessException(ErrorCode.PARAMS_ERROR);}Long id = teamUpdateRequest.getId();if (id == null || id <= 0) {throw new BusinessException(ErrorCode.PARAMS_ERROR);}Team oldTeam = this.getById(id);if (oldTeam==null){throw new BusinessException(ErrorCode.NULL_ERROR,"队伍不存在");}//只有管理员或者队伍的创建者才可以修改if (oldTeam.getUserId()!=loginUser.getId()&&!userService.isAdmin(loginUser)){throw new BusinessException(ErrorCode.NO_AUTH);}Team updateTeam = new Team();BeanUtils.copyProperties(teamUpdateRequest,updateTeam);return this.updateById(updateTeam);}

image.png

但是这段代码还有有bug,如果状态为公开,也可以修改信息(需要把密码清除),所以**如果队伍状态改为加密,必须要有密码,**修改实现类的代码,增加红框处校验
image.png
image.png

用户加入队伍

:::success
其他人、未满、未过期,允许加入多个队伍,但是要有个上限 P0

  1. 用户最多加入 5 个队伍
  2. 队伍必须存在,只能加入未满、未过期的队伍
  3. 不能加入自己的队伍,不能重复加入已加入的队伍(幂等性)
  4. 禁止加入私有的队伍
  5. 如果加入的队伍是加密的,必须密码匹配才可以
  6. 新增队伍 - 用户关联信息

注意,一定要加上事务注解!!!!
:::

在TeamService里编写用户加入队伍方法并在TeamServiceImpl里实现
同样在请求包里封装一个用户加入队伍请求体

/*** 用户加入队伍请求体** */
@Data
public class TeamJoinRequest implements Serializable {private static final long serialVersionUID = -24663018187059425L;/*** id*/private Long teamId;/*** 密码*/private String password;
}

在TeamService里面实现joinTeam方法并实现
image.png
编写用户加入队伍接口

    @PostMapping("/join")public BaseResponse<Boolean> joinTeam(@RequestBody TeamJoinRequest teamJoinRequest,HttpServletRequest request){if (teamJoinRequest==null){throw new BusinessException(ErrorCode.PARAMS_ERROR);}User loginUser = userService.getLoginUser(request);boolean result = teamService.joinTeam(teamJoinRequest, loginUser);return ResultUtils.success(result);}
 @Overridepublic boolean joinTeam(TeamJoinRequest teamJoinRequest, User loginUser) {if (teamJoinRequest == null) {throw new BusinessException(ErrorCode.PARAMS_ERROR);}Long teamId = teamJoinRequest.getTeamId();if (teamId == null || teamId <= 0) {throw new BusinessException(ErrorCode.PARAMS_ERROR);}Team team = this.getById(teamId);if (team == null) {throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍不存在");}Date expireTime = team.getExpireTime();if (expireTime != null && expireTime.before(new Date())) {throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍已过期");}Integer status = team.getStatus();TeamStatusEnum teamStatusEnum = TeamStatusEnum.getEnumByValue(status);if (teamStatusEnum.PRIVATE.equals(teamStatusEnum)) {throw new BusinessException(ErrorCode.PARAMS_ERROR, "禁止加入私有队伍");}String password = teamJoinRequest.getPassword();if (teamStatusEnum.SECRET.equals(teamStatusEnum)) {if (StringUtils.isBlank(password) || !password.equals(team.getPassword())) {throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码错误");}}//该用户已加入的队伍数量 数据库查询所以放到下面,减少查询时间Long userId = loginUser.getId();QueryWrapper<UserTeam> userTeamQueryWrapper = new QueryWrapper<>();userTeamQueryWrapper.eq("userId", userId);long hasJoinNum = userTeamService.count(userTeamQueryWrapper);if (hasJoinNum > 5) {throw new BusinessException(ErrorCode.PARAMS_ERROR, "最多创建和加入5个队伍");}//不能重复加入已加入的队伍userTeamQueryWrapper = new QueryWrapper<>();userTeamQueryWrapper.eq("userId", userId);userTeamQueryWrapper.eq("teamId", teamId);long hasUserJoinTeam = userTeamService.count(userTeamQueryWrapper);if (hasUserJoinTeam > 0) {throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户已加入该队伍");}//已加入队伍的人数userTeamQueryWrapper = new QueryWrapper<>();userTeamQueryWrapper.eq("teamId", teamId);long teamHasJoinNum = userTeamService.count(userTeamQueryWrapper);if (teamHasJoinNum >= team.getMaxNum()) {throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍已满");}//修改队伍信息UserTeam userTeam = new UserTeam();userTeam.setUserId(userId);userTeam.setTeamId(teamId);userTeam.setJoinTime(new Date());return userTeamService.save(userTeam);}

换个用户测试加入队伍
image.png
数据库中队伍1有两个用户id,测试成功
image.png

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker实战命令大全

文章目录 1 环境准备1.1 移除旧版本Docker1.2安装工具包1.3配置docker yum源 2 安装最新docker2.1 设置开机自启docker2.2配置加速器 3 实操-镜像3.1搜索镜像3.2下载镜像3.3查看镜像3.4 删除镜像 4 实操-容器4.1运行nginx容器4.2 查看容器4.3启动容器4.5关闭容器4.6查看容器日志…

功能强大的开源数据中台系统 DataCap 2024.03.5 发布

推荐一套基于 SpringBoot 开发的简单、易用的开源权限管理平台&#xff0c;建议下载使用: https://github.com/devlive-community/authx 推荐一套为 Java 开发人员提供方便易用的 SDK 来与目前提供服务的的 Open AI 进行交互组件&#xff1a;https://github.com/devlive-commun…

2个不同node版本的前端项目,用到的一个node版本管理工具nvm,可一键切换node版本

背景&#xff1a; 对于需要在电脑运行2个不同的前端项目&#xff0c;但是使用的node版本不同&#xff0c;为了快捷切换和管理node版本&#xff0c;所以需要用到一个非常方便的工具&#xff0c;那就是下边的nvm&#xff0c;一个命令就可以非常方便的切换你想要的node。 1、下载…

分布式光纤测温DTS与光纤光栅FBG解调仪有什么区别?

分布式光纤测温DTS和光纤光栅FBG解调仪之间存在本质区别。分布式光纤测温DTS是一种完全分布式的温度监测技术&#xff0c;意味着光纤的整个长度都充当传感器&#xff0c;可以感知任何位置的温度变化。然而&#xff0c;由于空间分辨率的限制&#xff0c;目前国内外的大多数技术只…

Three.js中的Raycasting技术:实现3D场景交互事件的Raycaster详解

前言 在Web开发中&#xff0c;Three.js是一个极为强大的库&#xff0c;它让开发者能够轻松地在浏览器中创建和展示3D图形。随着3D技术在网页设计、游戏开发、数据可视化等领域的广泛应用&#xff0c;用户与3D场景的交互变得日益重要。而要实现这种交互&#xff0c;一个核心的技…

探索地产营销管理系统业务架构的设计与应用

随着城市化进程的加速和人们对居住环境需求的不断提升&#xff0c;地产行业正迎来前所未有的发展机遇和挑战。在这个背景下&#xff0c;地产营销管理系统作为地产开发企业营销管理的重要工具&#xff0c;扮演着至关重要的角色。本文将深入探讨地产营销管理系统业务架构的设计与…

java中的面试高频问题----2

一、进程、线程、协程有什么区别&#xff1f; 1.进程&#xff1a;进程是操作系统中独立运行的程序实例&#xff0c;每个进程都有自己的内存空间和系统资源&#xff1b;进程之间相互独立&#xff0c;每个进程有自己的内存地址空间&#xff0c;一个进程无法直接访问另一个进程的…

H3C运维工程师面经

H3C运维工程师面经 1、常用linux命令:top的作用1.1.系统监控与性能分析:1.2.进程管理:1.3.资源使用统计:1.4.自定义视图与交互操作:2、接触过的linux系统、小版本是多少?2.1CentOS的版本CentOS 8系列:CentOS 7系列:CentOS 6系列:2.2Ubuntu版本Ubuntu LTS版本:Ubuntu非…

手机怎么压缩图片?通过三种压缩操作

手机怎么压缩图片&#xff1f;在智能手机日益普及的今天&#xff0c;拍照分享已成为日常生活的一部分。然而&#xff0c;高质量的照片往往占用较大的存储空间&#xff0c;且在网络上传输时速度较慢。那么&#xff0c;如何在手机上压缩图片呢&#xff1f;本文将介绍三种实用的手…

文件无法在当前环境下执行在 x86_64 系统上运行 ARM 可执行文件

目录 遇到的问题是由于"..."文件无法在当前环境下执行。这个错误通常是因为二进制文件的格式不兼容&#xff0c;可能是因为它是为不同的架构编译的。例如&#xff0c;如果二进制文件是为 x86 架构编译的&#xff0c;但你在 ARM 设备上尝试运行它&#xff0c;就会出现…

Oracle创建索引的LOGGING | NOLOGGING区别

在Oracle中&#xff0c;创建索引时的LOGGING和NOLOGGING选项主要影响索引创建过程中产生的重做日志&#xff08;redo log&#xff09;的数量。这两个选项对于性能和数据恢复能力有着显著的影响。以下是关于这两个选项的详细解释和区别&#xff1a; LOGGING 定义&#xff1a;当…

[数据集][目标检测]道路圆石墩检测数据集VOC+YOLO格式461张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;462 标注数量(xml文件个数)&#xff1a;462 标注数量(txt文件个数)&#xff1a;462 标注类别…

Python怎么做单元测试

在Python中&#xff0c;最常用的单元测试框架是unittest。以下是如何使用unittest进行单元测试的步骤&#xff1a; 导入unittest模块&#xff1a; 首先&#xff0c;你需要导入unittest模块。 import unittest创建测试类&#xff1a; 你需要创建一个继承自unittest.TestCase的类…

运放应用2 - 同相放大电路

1. 前置知识 同相放大电路存在 负反馈电路 &#xff0c;工作在线性区&#xff0c;可以利用 虚短 概念来分析电路。 注&#xff1a;运放的 虚断 特性是一直存在的&#xff0c;虚短 特性则需要运放工作在 线性区 有关运放的基础知识&#xff0c;可以参考我的另外一篇文章&#x…

LeetCode题练习与总结:杨辉三角--118

一、题目描述 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]示例 2: 输入: numRows 1 输出: [[1…

【解决方案】前端React 、Vue工程如何开启GZIP压缩

在前端工程中&#xff0c;React 和 Vue 项目通常通过构建工具&#xff08;如Webpack&#xff09;进行打包&#xff0c;而服务器端配置则负责实际的GZIP压缩。以下是如何在React和Vue项目中开启GZIP压缩的一般步骤&#xff1a; React项目 使用Webpack构建&#xff1a; 如果你的…

单元测试之CppTest测试框架

目录 1 背景2 设计3 实现4 使用4.1 主函数4.2 测试用例4.2.1 定义4.2.2 实现 4.3 运行 1 背景 前面文章CppTest实战演示中讲述如何使用CppTest库。其主函数如下&#xff1a; int main(int argc, char *argv[]) {Test::Suite mainSuite;Test::TextOutput output(Test::TextOut…

Linux系统安全(用户、密码、grub引导密码、增加终端)

目录 系统安全 用户安全 密码安全 PAM认证 命令的历史 用户切换 命令的执行权限 grub引导密码 增加终端 系统安全 用户安全 命令 说明 chattr i /etc/passwd chattr&#xff1a;为文件添加特殊权限 i&#xff1a;指定文件设为不可修改&#xff0c;只有root用户能为…

【Centos】深度解析:CentOS下安装pip的完整指南

【Centos】深度解析&#xff1a;CentOS下安装pip的完整指南 大家好 我是寸铁&#x1f44a; 总结了一篇【Centos】深度解析&#xff1a;CentOS下安装pip的完整指南✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 方式1(推荐) 下载get-pip.py到本地 sudo wget https://bootstrap.p…

Python 机器学习 基础 之 【常用机器学习库】 NumPy 数值计算库

Python 机器学习 基础 之 【常用机器学习库】 NumPy 数值计算库 目录 Python 机器学习 基础 之 【常用机器学习库】 NumPy 数值计算库 一、简单介绍 二、Numpy 基础 1、安装NumPy 2、导入NumPy 3、创建数组 4、数组操作 5、常用函数 6、矩阵运算 7、广播机制 8、随机…