前言
今天分享个案例,需求是这样的:一个团组中是可以包含多个会员,在给团组创建训练方案时,本质上是给每个会员分别制定了一套训练方案。那么会有个问题,比如创建一个团组A,里面有会员1,会员2,会员3,然后给团组A创建了个方案,那么对应的三个会员都有训练方案,此时,将会员4拉到团组A中,此时会员4是没有任何方案的,所以我们现在要做的就是将会员4也同步上团组A的方案。
思路
在给团组新建完方案之后,通过团组管理是可以对该团组中的成员增加或者减少的,就像微信群聊一样,既可以重新邀人,也可以踢人出去。只是我们的业务里面加入了方案的概念。
新加的人就需要同步训练方案,删除的人就需要删掉他的方案,这个地方我是这样处理的:
- 通过
java
中集合的方法,找出哪些是新加的人,哪些是减去的人。 - 将团组和两个集合(新加的人的集合和减少的人的集合)传入到处理方案的方法中去操作
- 涉及到两个系统,一个是我方系统,一个是训练方案系统,并且都是我写的,所以接口操作起来就比较方便。
具体代码
团组管理
/** * 修改团组 团组里面编辑成员时,更新对应的训练方案 */ @PostMapping("/updateGroup") @ApiOperationSupport(order = 2) @ApiOperation(value = "app-新增团组", notes = "传入teamGroup") public R updateGroup(@RequestBody TeamGroup teamGroup) { //1.先把原来的人放在一个集合中 List<Long> userListOld = new ArrayList<>(); LambdaQueryWrapper<GroupUser> groupUserLambdaQueryWrapper = new LambdaQueryWrapper<>(); groupUserLambdaQueryWrapper.eq(GroupUser::getGroupId, teamGroup.getId()); //集合去重 List<GroupUser> groupUserList = groupUserService .list(groupUserLambdaQueryWrapper) .stream() .distinct() .collect(Collectors.toList()); for (GroupUser groupUser : groupUserList) { //将原来的用户添加到这个集合中 userListOld.add(groupUser.getUserId()); } //拿到人员集合,把关联表中的数据,根据团组id把之前的数据都删掉, //然后再重新添加新获得的人员集合. groupUserService.remove(groupUserLambdaQueryWrapper); //2.将新更新过来的人放在一个集合中 List<Long> userListNew = new ArrayList<>(); if (teamGroup.getUserIds() != null && !"".equals(teamGroup.getUserIds())) { userListNew = CommonUtil.transLongList(teamGroup.getUserIds()); //设置团组人数 teamGroup.setNumPeople(userListNew.size()); //把人员和团组在关联表中维护起来. for (int i = 0; i < userListNew.size(); i++) { GroupUser groupUser = new GroupUser(); groupUser.setGroupId(teamGroup.getId()); User user = userService.getUserById(userListNew.get(i)); groupUser.setUserId(user.getId()); groupUser.setUserName(user.getName()); groupUser.setIsDeleted(0); groupUserService.save(groupUser); } } //3.两个集合比较哪些是新增的,哪些是删除的 //新增的会员 List<Long> userListAdd = new ArrayList<>(userListNew); userListAdd.removeAll(userListOld); //输出集合中的元素 System.out.println("新增了的会员:"); userListAdd.forEach(System.out::println); //删除了的会员 List<Long> userListDel = new ArrayList<>(userListOld); userListDel.removeAll(userListNew); //输出集合中的元素 System.out.println("删除了的会员:"); userListDel.forEach(System.out::println); //传给训练方案系统,团组id,要删除的会员集合,要新增的会员集合--2022年7月5日13:56:15 updateer:穆雄雄 R r = trainingSchemeUrlService.updateProgrammeByGroupIdAndOldUserIdAndNewUserId(teamGroup.getId(),userListAdd,userListDel); if(r.getCode()!=200){ return R.fail("同步团组训练方案失败"); } //更新团组的基础信息 return R.status(teamGroupService.updateById(teamGroup)); }
代码中基本都有注释,下面我来分析一下关键的代码,比较两个集合中哪些是新增的,哪些是删除的?
//新增的会员 List<Long> userListAdd = new ArrayList<>(userListNew); userListAdd.removeAll(userListOld); //输出集合中的元素 System.out.println("新增了的会员:"); userListAdd.forEach(System.out::println); //删除了的会员 List<Long> userListDel = new ArrayList<>(userListOld); userListDel.removeAll(userListNew); //输出集合中的元素 System.out.println("删除了的会员:"); userListDel.forEach(System.out::println);
接下来就是在本系统中调用训练方案系统的同步方案接口了,具体代码如下:
Service
接口层:
/** * 团组更新成员时,方案也跟着同步 * @param * @param * @param * @return */ R updateProgrammeByGroupIdAndOldUserIdAndNewUserId(Long groupId, List<Long> userListAdd, List<Long>userListDel);
ServiceImpl
实现类:
@Override public R updateProgrammeByGroupIdAndOldUserIdAndNewUserId(Long groupId, List<Long> userListAdd, List<Long> userListDel) { //请求接口地址 String url = TrainingSchemeConstant.updateProgrammeByGroupIdAndOldUserIdAndNewUserId; JSONObject jsonObject = new JSONObject(); jsonObject.putOpt("groupId", groupId); jsonObject.putOpt("userListAdd", userListAdd); jsonObject.putOpt("userListDel", userListDel); try { String body = HttpRequest.post(url) .header("Content-Type", "application/json") .body(jsonObject.toString()) .execute().body(); if (StringUtils.isBlank(body)) { return R.fail("操作失败"); } JSONObject obj = JSONUtil.parseObj(body); if (obj == null) { return R.fail("操作失败"); } String code = obj.get("code").toString(); if ("200".equals(code)) { return R.success("操作成功"); } } catch (Exception e) { e.printStackTrace(); } return null; }
接口地址工具类:
/** * 根据会员Id 状态 时间,查询所有动作 */ public String updateProgrammeByGroupIdAndOldUserIdAndNewUserId = TRAINING_PROGRAMME+"/api/trainingprogramev3/updateProgrammeByGroupIdAndOldUserIdAndNewUserId";
训练方案系统中同步团组方案
/** * 根据团组id,新老用户的id编辑方案 * 2022年5月31日22:16:01 * 穆雄雄 * * @return */ @PostMapping(value = "/updateProgrammeByGroupIdAndOldUserIdAndNewUserId") public String updateProgrammeByGroupIdAndOldUserIdAndNewUserId(@RequestBody GroupUpdateUser groupUpdateUser) { JSONObject jsonObject = new JSONObject(); if (groupUpdateUser.getGroupId() == null) { jsonObject.put("code", 500); jsonObject.put("success", false); jsonObject.put("msg", "团组id不能为空"); } //先从redis里面取一下,如果redis里面没有的话,就执行下面的内容 Map<String, Object> programmeMap = bladeRedis.get("createGroupProgramme:" + groupUpdateUser.getGroupId()); System.out.println("团组在编辑会员的时候,redis中的数据是:" + programmeMap); Programme programme = null; TeamGroup teamGroup = null; //方案的集合 List<Programme> programmeList = new ArrayList<>(); //时间戳 Long timechuo = null; //缓存里面没有 QueryWrapper<TeamGroup> teamGroupQueryWrapper = new QueryWrapper<>(); teamGroupQueryWrapper.eq("group_id", groupUpdateUser.getGroupId()).orderByDesc("id").last("limit 1"); teamGroup = teamGroupService.getOne(teamGroupQueryWrapper); //判断如果缓存里面没有的话,查询一下实际的 if (programmeMap == null) { //没有方案的话 if (teamGroup == null) { jsonObject.put("code", 200); jsonObject.put("success", true); jsonObject.put("msg", "操作成功"); return jsonObject.toJSONString(); } //将peibeizhu的值修改一下 //根据方案的id查询出来方案信息 programme = programmeService.getById(teamGroup.getProgrammeId()); timechuo = programme.getTimechuo(); System.out.println("编辑方案时,redis缓存里面没有数据"); }else{ //获取缓存中的时间戳 timechuo = (Long) programmeMap.get("timechuo"); System.out.println("编辑方案时,redis缓存里面有数据"); } //aid的集合,最后放在pbeizhu里面去 List<Long> pBeiZhuAidList = new ArrayList<>(); //根据时间戳查询出所有方案 LambdaQueryWrapper<Programme> programmeLambdaQueryWrapper = new LambdaQueryWrapper<>(); programmeLambdaQueryWrapper.eq(Programme::getTimechuo, timechuo); List<Programme> programmeListByTimeChuo = programmeService.list(programmeLambdaQueryWrapper); programmeListByTimeChuo.forEach(pro -> { //重新赋值pbeizhu的值 pBeiZhuAidList.add(pro.getPaid()); programmeList.add(pro); }); //运动员主键id集合 List<Long> aidList = new ArrayList<>(); //同步一下新加的用户信息 if (groupUpdateUser.getUserListAdd().size() > 0) { for (Long aid : groupUpdateUser.getUserListAdd()) { Athletes athletes = new Athletes(); LambdaQueryWrapper<Athletes> athletesLambdaQueryWrapper = new LambdaQueryWrapper<>(); athletesLambdaQueryWrapper.eq(Athletes::getWorkcode, aid); List<Athletes> athleteList = athletesService.list(athletesLambdaQueryWrapper); if (athleteList.size() > 0) { //找到了 athletes = athleteList.get(0); } else { //没有找到 athletes.setAname(aid.toString()); athletes.setWorkcode(aid.toString()); athletesService.save(athletes); } aidList.add(athletes.getId()); } } //加上了的成员 for (Long aid : aidList) { //根据时间戳和用户id查询方案,有则添加,无则不用 LambdaQueryWrapper<Programme> programmeWrapper = new LambdaQueryWrapper<>(); programmeWrapper .eq(Programme::getPaid, aid) .eq(Programme::getTimechuo, timechuo) .last("limit 1"); List<Programme> programmeQueryList = programmeService.list(programmeWrapper); if (programmeQueryList.size() == 0) { if(programme==null){ programme = programmeList.get(0); } //远动员主键 programme.setPaid(aid); //是否是团组方案 0是 1 不是 programme.setIsGroupProgramme(0); //给用户保存方案 programmeService.save(programme); } } //将运动员的主键拿到放在集合里面(删除方案)--暂时先不删除了。因为怕误删掉个人的方案 2022年7月4日21:23:19 if (groupUpdateUser.getUserListDel().size() > 0) { //删除了的成员 for (Long uid : groupUpdateUser.getUserListDel()) { //去运动员表卡里面查询这个人的编号 LambdaQueryWrapper<Athletes> athletesLambdaQueryWrapper = new LambdaQueryWrapper<>(); athletesLambdaQueryWrapper.select(Athletes::getId) .eq(Athletes::getWorkcode, uid) .last("limit 1"); Athletes athletes = athletesService.getOne(athletesLambdaQueryWrapper); if (athletes != null) { //(遗留了bug,如果这个人正好是这个团组的最后一个方案的话,删掉之后,会导致团组和方案关联表中的方案id在方案里面找不到) //将方案表中的paid是这个人的都删掉 Map<String, Object> map = new HashMap<>(); map.put("paid", athletes.getId()); map.put("timechuo", programme.getTimechuo()); //map.put("is_group_programme",0); //物理删除 programmeService.delProgrammeByAid(map); } } } //把集合中的 String pbeizhu = StringUtils.join(pBeiZhuAidList, ","); programmeListByTimeChuo.forEach(pro -> { //重新赋值pbeizhu的值 pro.setPbeizhu(pbeizhu); //修改pbiezhu的信息 programmeService.updateById(pro); }); //重新修改团组和方案关联表的方案id if (programmeList.size() > 0) { //将最后一个方案的Id修改到 teamGroup.setProgrammeId(programmeList.get(programmeList.size() - 1).getId().longValue()); teamGroupService.updateById(teamGroup); } jsonObject.put("code", 200); jsonObject.put("success", true); jsonObject.put("msg", "操作成功"); return jsonObject.toJSONString(); }
代码中使用了redis
,刚开始将方案的信息放在了redis
中,在操作方案的时候先从redis
中取,如果缓存中没有,则从库里面查询,如果有,则直接使用。