课程说明

  • 实现我的喜欢功能
  • 实现用户通用设置
  • 实现黑名单功能
  • 实现修改手机号功能

    1、我的喜欢统计数

    在我的模块中,将详细展现“喜欢”相关的数据,如下:
    1572445671626
    1572445655283

    1.1、概念说明

  • 喜欢

  • 我喜欢别人,如:张三喜欢李四,就是喜欢的数据,并不代表李四也喜欢张三。
  • 粉丝
  • 对于李四而言,张三就是他的粉丝。
  • 相互关注(喜欢)
  • 如果李四也喜欢张三,那么,张三和李四就是相互喜欢。

1.2、dubbo服务

1.2.1、UserLikeApi

  1. //com.tanhua.dubbo.server.api.UserLikeApi
  2. /**
  3. * 相互喜欢的数量
  4. *
  5. * @return
  6. */
  7. Long queryMutualLikeCount(Long userId);
  8. /**
  9. * 喜欢数
  10. *
  11. * @return
  12. */
  13. Long queryLikeCount(Long userId);
  14. /**
  15. * 粉丝数
  16. *
  17. * @return
  18. */
  19. Long queryFanCount(Long userId);

1.2.2、UserLikeApiImpl

  1. //com.tanhua.dubbo.server.api.UserLikeApiImpl
  2. /**
  3. * 查询相互喜欢数
  4. * 实现2种方式:第一种:查询redis,第二种:查询MongoDB
  5. * 建议:优先使用redis查询,其次考虑使用Mongodb
  6. *
  7. * @param userId
  8. * @return
  9. */
  10. @Override
  11. public Long queryMutualLikeCount(Long userId) {
  12. //查询我的喜欢列表
  13. List<Long> likeUserIdList = this.queryLikeList(userId);
  14. Long count = 0L;
  15. for (Long likeUserId : likeUserIdList) {
  16. String redisKey = this.getLikeRedisKey(likeUserId);
  17. String hashKey = String.valueOf(userId);
  18. //“别人” 的喜欢列表中是否有 “我”
  19. if (this.redisTemplate.opsForHash().hasKey(redisKey, hashKey)) {
  20. count++;
  21. }
  22. }
  23. return count;
  24. }
  25. @Override
  26. public Long queryLikeCount(Long userId) {
  27. String redisKey = this.getLikeRedisKey(userId);
  28. return this.redisTemplate.opsForHash().size(redisKey);
  29. }
  30. @Override
  31. public Long queryFanCount(Long userId) {
  32. //无法通过redis查询完成,必须从Mongodb中查询
  33. Query query = Query.query(Criteria.where("likeUserId").is(userId));
  34. return this.mongoTemplate.count(query, UserLike.class);
  35. }

1.2.3、单元测试

  1. package com.tanhua.dubbo.server.api;
  2. import org.junit.Test;
  3. import org.junit.runner.RunWith;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.boot.test.context.SpringBootTest;
  6. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  7. @RunWith(SpringJUnit4ClassRunner.class)
  8. @SpringBootTest
  9. public class TestUserLikeApiImpl {
  10. @Autowired
  11. private UserLikeApi userLikeApi;
  12. @Test
  13. public void testQueryCounts(){
  14. System.out.println(this.userLikeApi.queryEachLikeCount(1L));
  15. System.out.println(this.userLikeApi.queryFanCount(1L));
  16. System.out.println(this.userLikeApi.queryLikeCount(1L));
  17. }
  18. }

1.3、APP接口服务

文档地址:https://mock-java.itheima.net/project/35/interface/api/899

1.3.1、CountsVo

  1. package com.tanhua.server.vo;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. @Data
  6. @NoArgsConstructor
  7. @AllArgsConstructor
  8. public class CountsVo {
  9. private Long eachLoveCount; //互相喜欢
  10. private Long loveCount; //喜欢
  11. private Long fanCount; //粉丝
  12. }

1.3.2、UsersController

  1. //com.tanhua.server.controller.MyCenterController
  2. /**
  3. * 互相喜欢,喜欢,粉丝 - 统计
  4. *
  5. * @return
  6. */
  7. @GetMapping("counts")
  8. public ResponseEntity<CountsVo> queryCounts(){
  9. try {
  10. CountsVo countsVo = this.myCenterService.queryCounts();
  11. if(null != countsVo){
  12. return ResponseEntity.ok(countsVo);
  13. }
  14. } catch (Exception e) {
  15. e.printStackTrace();
  16. }
  17. return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
  18. }

1.3.3、UsersService

  1. //com.tanhua.server.service.MyCenterService
  2. public CountsVo queryCounts() {
  3. User user = UserThreadLocal.get();
  4. CountsVo countsVo = new CountsVo();
  5. countsVo.setEachLoveCount(this.userLikeApi.queryMutualLikeCount(user.getId()));
  6. countsVo.setFanCount(this.userLikeApi.queryFanCount(user.getId()));
  7. countsVo.setLoveCount(this.userLikeApi.queryLikeCount(user.getId()));
  8. return countsVo;
  9. }

1.3.4、测试

image-20210120113145052

2、喜欢列表

接口服务:https://mock-java.itheima.net/project/35/interface/api/905
该接口集成了4个接口,用type做了区分: 1 互相关注 2 我关注 3 粉丝 4 谁看过我

2.1、喜欢dubbo接口服务

2.1.1、定义接口

在dubbo接口中定义方法:

  1. //com.tanhua.dubbo.server.api.UserLikeApi
  2. /**
  3. * 查询相互喜欢列表
  4. *
  5. * @param userId
  6. * @param page
  7. * @param pageSize
  8. * @return
  9. */
  10. PageInfo<UserLike> queryMutualLikeList(Long userId, Integer page, Integer pageSize);
  11. /**
  12. * 查询我喜欢的列表
  13. *
  14. * @param userId
  15. * @param page
  16. * @param pageSize
  17. * @return
  18. */
  19. PageInfo<UserLike> queryLikeList(Long userId, Integer page, Integer pageSize);
  20. /**
  21. * 查询粉丝列表
  22. *
  23. * @param userId
  24. * @param page
  25. * @param pageSize
  26. * @return
  27. */
  28. PageInfo<UserLike> queryFanList(Long userId, Integer page, Integer pageSize);

2.1.2、实现接口

  1. //com.tanhua.dubbo.server.api.UserLikeApiImpl
  2. @Override
  3. public PageInfo<UserLike> queryMutualLikeList(Long userId, Integer page, Integer pageSize) {
  4. //查询我的喜欢列表
  5. List<Long> userLikeIdList = this.queryLikeList(userId);
  6. //查询喜欢我的人
  7. Query query = Query.query(Criteria.where("userId").in(userLikeIdList)
  8. .and("likeUserId").is(userId)
  9. );
  10. return this.queryList(query, page, pageSize);
  11. }
  12. @Override
  13. public PageInfo<UserLike> queryLikeList(Long userId, Integer page, Integer pageSize) {
  14. Query query = Query.query(Criteria.where("userId").is(userId));
  15. return this.queryList(query, page, pageSize);
  16. }
  17. @Override
  18. public PageInfo<UserLike> queryFanList(Long userId, Integer page, Integer pageSize) {
  19. Query query = Query.query(Criteria.where("likeUserId").is(userId));
  20. return this.queryList(query, page, pageSize);
  21. }
  22. private PageInfo<UserLike> queryList(Query query, Integer page, Integer pageSize) {
  23. //设置分页
  24. PageRequest pageRequest = PageRequest.of(page - 1, pageSize,
  25. Sort.by(Sort.Order.desc("created")));
  26. query.with(pageRequest);
  27. List<UserLike> userLikeList = this.mongoTemplate.find(query, UserLike.class);
  28. PageInfo<UserLike> pageInfo = new PageInfo<>();
  29. pageInfo.setPageNum(page);
  30. pageInfo.setPageSize(pageSize);
  31. pageInfo.setRecords(userLikeList);
  32. return pageInfo;
  33. }

2.2、最近访客dubbo服务

2.2.1、定义接口

  1. //com.tanhua.dubbo.server.api.VisitorsApi
  2. /**
  3. * 按照时间倒序排序,查询最近的访客信息
  4. *
  5. * @param userId
  6. * @param page
  7. * @param pageSize
  8. * @return
  9. */
  10. PageInfo<Visitors> topVisitor(Long userId, Integer page, Integer pageSize);

2.2.2、编写实现

  1. //com.tanhua.dubbo.server.api.VisitorsApiImpl
  2. @Override
  3. public List<Visitors> queryMyVisitor(Long userId) {
  4. // 查询前5个访客数据,按照访问时间倒序排序
  5. // 如果用户已经查询过列表,记录查询时间,后续查询需要按照这个时间往后查询
  6. // 上一次查询列表的时间
  7. Long date = Convert.toLong(this.redisTemplate.opsForHash().get(VISITOR_REDIS_KEY, String.valueOf(userId)));
  8. PageRequest pageRequest = PageRequest.of(0, 5, Sort.by(Sort.Order.desc("date")));
  9. Query query = Query.query(Criteria.where("userId").is(userId))
  10. .with(pageRequest);
  11. if (ObjectUtil.isNotEmpty(date)) {
  12. query.addCriteria(Criteria.where("date").gte(date));
  13. }
  14. return this.queryList(query, userId);
  15. }
  16. private List<Visitors> queryList(Query query, Long userId){
  17. List<Visitors> visitorsList = this.mongoTemplate.find(query, Visitors.class);
  18. //查询每个来访用户的得分
  19. for (Visitors visitors : visitorsList) {
  20. Query queryScore = Query.query(Criteria.where("toUserId")
  21. .is(userId).and("userId").is(visitors.getVisitorUserId())
  22. );
  23. RecommendUser recommendUser = this.mongoTemplate.findOne(queryScore, RecommendUser.class);
  24. if(ObjectUtil.isNotEmpty(recommendUser)){
  25. visitors.setScore(recommendUser.getScore());
  26. }else {
  27. //默认得分
  28. visitors.setScore(90d);
  29. }
  30. }
  31. return visitorsList;
  32. }
  33. @Override
  34. public PageInfo<Visitors> topVisitor(Long userId, Integer page, Integer pageSize) {
  35. PageRequest pageRequest = PageRequest.of(page - 1, pageSize,
  36. Sort.by(Sort.Order.desc("date")));
  37. Query query = Query.query(Criteria.where("userId").is(userId)).with(pageRequest);
  38. List<Visitors> visitorsList = this.queryList(query, userId);
  39. PageInfo<Visitors> pageInfo = new PageInfo<>();
  40. pageInfo.setPageNum(page);
  41. pageInfo.setPageSize(pageSize);
  42. pageInfo.setRecords(visitorsList);
  43. //记录当前的时间到redis中,在首页查询时,就可以在这个时间之后查询了
  44. String redisKey = VISITOR_REDIS_KEY;
  45. String hashKey = String.valueOf(userId);
  46. String value = String.valueOf(System.currentTimeMillis());
  47. this.redisTemplate.opsForHash().put(redisKey, hashKey, value);
  48. return pageInfo;
  49. }

2.3、APP接口服务

接口文档:https://mock-java.itheima.net/project/35/interface/api/905

2.3.1、UserLikeListVo

  1. package com.tanhua.server.vo;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. @Data
  6. @NoArgsConstructor
  7. @AllArgsConstructor
  8. public class UserLikeListVo {
  9. private Long id;
  10. private String avatar;
  11. private String nickname;
  12. private String gender;
  13. private Integer age;
  14. private String city;
  15. private String education;
  16. private Integer marriage; //婚姻状态(0未婚,1已婚)
  17. private Integer matchRate; //匹配度
  18. private Boolean alreadyLove; //是否喜欢ta
  19. }

2.3.2、MyCenterController

  1. //com.tanhua.server.controller.MyCenterController
  2. /**
  3. * 互相关注、我关注、粉丝、谁看过我 - 翻页列表
  4. *
  5. * @param type 1 互相关注 2 我关注 3 粉丝 4 谁看过我
  6. * @param page
  7. * @param pageSize
  8. * @param nickname
  9. * @return
  10. */
  11. @GetMapping("friends/{type}")
  12. public ResponseEntity<PageResult> queryLikeList(@PathVariable("type") String type,
  13. @RequestParam(value = "page", defaultValue = "1") Integer page,
  14. @RequestParam(value = "pagesize", defaultValue = "10") Integer pageSize,
  15. @RequestParam(value = "nickname", required = false) String nickname) {
  16. try {
  17. page = Math.max(1, page);
  18. PageResult pageResult = this.myCenterService.queryLikeList(Integer.valueOf(type), page, pageSize, nickname);
  19. return ResponseEntity.ok(pageResult);
  20. } catch (Exception e) {
  21. e.printStackTrace();
  22. }
  23. return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
  24. }

2.3.3、MyCenterService

  1. //com.tanhua.server.service.MyCenterService
  2. public PageResult queryLikeList(Integer type, Integer page, Integer pageSize, String nickname) {
  3. PageResult pageResult = new PageResult();
  4. pageResult.setPage(page);
  5. pageResult.setPagesize(pageSize);
  6. Long userId = UserThreadLocal.get().getId();
  7. List<Object> userIdList = null;
  8. //1 互相关注 2 我关注 3 粉丝 4 谁看过我
  9. switch(type){
  10. case 1:{
  11. PageInfo<UserLike> pageInfo = this.userLikeApi.queryMutualLikeList(userId, page, pageSize);
  12. userIdList = CollUtil.getFieldValues(pageInfo.getRecords(), "userId");
  13. break;
  14. }
  15. case 2:{
  16. PageInfo<UserLike> pageInfo = this.userLikeApi.queryLikeList(userId, page, pageSize);
  17. userIdList = CollUtil.getFieldValues(pageInfo.getRecords(), "likeUserId");
  18. break;
  19. }
  20. case 3:{
  21. PageInfo<UserLike> pageInfo = this.userLikeApi.queryFanList(userId, page, pageSize);
  22. userIdList = CollUtil.getFieldValues(pageInfo.getRecords(), "userId");
  23. break;
  24. }
  25. case 4:{
  26. PageInfo<Visitors> pageInfo = this.visitorsApi.topVisitor(userId, page, pageSize);
  27. userIdList = CollUtil.getFieldValues(pageInfo.getRecords(), "visitorUserId");
  28. break;
  29. }
  30. default:
  31. return pageResult;
  32. }
  33. if(CollUtil.isEmpty(userIdList)){
  34. return pageResult;
  35. }
  36. QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
  37. queryWrapper.in("user_id", userIdList);
  38. if(StrUtil.isNotEmpty(nickname)){
  39. queryWrapper.like("nick_name", nickname);
  40. }
  41. List<UserInfo> userInfoList = this.userInfoService.queryUserInfoList(queryWrapper);
  42. List<UserLikeListVo> userLikeListVos = new ArrayList<>();
  43. for (UserInfo userInfo : userInfoList) {
  44. UserLikeListVo userLikeListVo = new UserLikeListVo();
  45. userLikeListVo.setAge(userInfo.getAge());
  46. userLikeListVo.setAvatar(userInfo.getLogo());
  47. userLikeListVo.setCity(userInfo.getCity());
  48. userLikeListVo.setEducation(userInfo.getEdu());
  49. userLikeListVo.setGender(userInfo.getSex().name().toLowerCase());
  50. userLikeListVo.setId(userInfo.getUserId());
  51. userLikeListVo.setMarriage(StringUtils.equals(userInfo.getMarriage(), "已婚") ? 1 : 0);
  52. userLikeListVo.setNickname(userInfo.getNickName());
  53. //是否喜欢 userLikeApi中的isLike开放出来
  54. userLikeListVo.setAlreadyLove(this.userLikeApi.isLike(userId, userInfo.getUserId()));
  55. Double score = this.recommendUserService.queryScore(userId, userInfo.getUserId());
  56. userLikeListVo.setMatchRate(Convert.toInt(score));
  57. userLikeListVos.add(userLikeListVo);
  58. }
  59. pageResult.setItems(userLikeListVos);
  60. return pageResult;
  61. }

2.3.4、测试

1572535858665
1572535875980
1572535893293
image-20210120221811034
1572535940981

2.4、取消喜欢

在列表中可以进行“取消喜欢”操作。
接口文档:https://mock-java.itheima.net/project/35/interface/api/923

2.4.1、MyCenterController

  1. //com.tanhua.server.controller.MyCenterController
  2. /**
  3. * 取消喜欢
  4. *
  5. * @param userId
  6. * @return
  7. */
  8. @DeleteMapping("like/{uid}")
  9. public ResponseEntity<Void> disLike(@PathVariable("uid") Long userId) {
  10. try {
  11. this.myCenterService.disLike(userId);
  12. return ResponseEntity.ok(null);
  13. } catch (Exception e) {
  14. e.printStackTrace();
  15. }
  16. return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
  17. }

2.4.2、MyCenterService

  1. //com.tanhua.server.service.MyCenterService
  2. /**
  3. * 取消喜欢
  4. *
  5. * @param userId
  6. */
  7. public void disLike(Long userId) {
  8. //判断当前用户与此用户是否相互喜欢
  9. User user = UserThreadLocal.get();
  10. Boolean mutualLike = this.userLikeApi.isMutualLike(user.getId(), userId);
  11. //取消喜欢
  12. this.userLikeApi.notLikeUser(user.getId(), userId);
  13. if(mutualLike){
  14. //取消好友关系,解除在环信平台的好友关系
  15. this.imService.removeUser(userId);
  16. }
  17. }

2.4.3、IMService

  1. //com.tanhua.server.service.IMService
  2. /**
  3. * 删除好友
  4. *
  5. * @param userId 好友id
  6. */
  7. public void removeUser(Long userId) {
  8. //删除好友关系
  9. User user = UserThreadLocal.get();
  10. Boolean result = this.usersApi.removeUsers(user.getId(), userId);
  11. if(result){
  12. //将环信平台的好友关系解除
  13. this.huanXinApi.removeUserFriend(user.getId(), userId);
  14. }
  15. }

2.4.4、测试

测试时,需要将MongoDB中的user_like表数据清空以及将Redis中喜欢和不喜欢数据删除。
使用用户2进行测试,现在和用户1是好友:
image-20210120231421237
取消喜欢:
image-20210120231523590

2.5、 喜欢粉丝

在查看粉丝列表中,可以对粉丝进行“喜欢操作”。
文档地址:https://mock-java.itheima.net/project/35/interface/api/917

2.5.1、MyCenterController

  1. //com.tanhua.server.controller.MyCenterController
  2. /**
  3. * 关注粉丝
  4. *
  5. * @param userId
  6. * @return
  7. */
  8. @PostMapping("fans/{uid}")
  9. public ResponseEntity<Void> likeFan(@PathVariable("uid") Long userId){
  10. try {
  11. this.myCenterService.likeFan(userId);
  12. return ResponseEntity.ok(null);
  13. } catch (Exception e) {
  14. e.printStackTrace();
  15. }
  16. return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
  17. }

2.5.2、MyCenterService

  1. //com.tanhua.server.service.MyCenterService
  2. @Autowired
  3. private TanHuaService tanHuaService;
  4. /**
  5. * 喜欢
  6. *
  7. * @param userId
  8. */
  9. public void likeFan(Long userId) {
  10. //喜欢用户,如果用户是相互喜欢的话就会成为好友
  11. this.tanHuaService.likeUser(userId);
  12. }

2.5.3、测试

image-20210121094407113

3、用户通用设置

3.1、表结构

  1. CREATE TABLE `tb_settings` (
  2. `id` bigint(20) NOT NULL AUTO_INCREMENT,
  3. `user_id` bigint(20) DEFAULT NULL,
  4. `like_notification` tinyint(4) DEFAULT '1' COMMENT '推送喜欢通知',
  5. `pinglun_notification` tinyint(4) DEFAULT '1' COMMENT '推送评论通知',
  6. `gonggao_notification` tinyint(4) DEFAULT '1' COMMENT '推送公告通知',
  7. `created` datetime DEFAULT NULL,
  8. `updated` datetime DEFAULT NULL,
  9. PRIMARY KEY (`id`)
  10. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='设置表';

3.2、pojo

my-tanhua-common工程:

  1. package com.tanhua.common.pojo;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. @Data
  6. @NoArgsConstructor
  7. @AllArgsConstructor
  8. public class Settings extends BasePojo {
  9. private Long id;
  10. private Long userId;
  11. private Boolean likeNotification = true;
  12. private Boolean pinglunNotification = true;
  13. private Boolean gonggaoNotification = true;
  14. }

3.3、SettingsMapper

  1. package com.tanhua.common.mapper;
  2. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  3. import com.tanhua.common.pojo.Settings;
  4. public interface SettingsMapper extends BaseMapper<Settings> {
  5. }

3.4、SettingsService

  1. package com.tanhua.server.service;
  2. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  3. import com.tanhua.common.mapper.SettingsMapper;
  4. import com.tanhua.common.pojo.Settings;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.stereotype.Service;
  7. @Service
  8. public class SettingsService {
  9. @Autowired
  10. private SettingsMapper settingsMapper;
  11. /**
  12. * 根据用户id查询配置
  13. *
  14. * @param userId
  15. * @return
  16. */
  17. public Settings querySettings(Long userId) {
  18. QueryWrapper<Settings> queryWrapper = new QueryWrapper<>();
  19. queryWrapper.eq("user_id", userId);
  20. return this.settingsMapper.selectOne(queryWrapper);
  21. }
  22. }

3.5、查询配置

文档地址:https://mock-java.itheima.net/project/35/interface/api/893

3.5.1、SettingsVo

  1. package com.tanhua.server.vo;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. @Data
  6. @NoArgsConstructor
  7. @AllArgsConstructor
  8. public class SettingsVo {
  9. private Long id;
  10. //陌生人问题
  11. private String strangerQuestion = "";
  12. //手机号
  13. private String phone;
  14. //推送喜欢通知
  15. private Boolean likeNotification = true;
  16. //推送评论通知
  17. private Boolean pinglunNotification = true;
  18. //推送公告通知
  19. private Boolean gonggaoNotification = true;
  20. }

3.5.2、MyCenterController

  1. //com.tanhua.server.controller.MyCenterController
  2. /**
  3. * 查询配置
  4. *
  5. * @return
  6. */
  7. @GetMapping("settings")
  8. public ResponseEntity<SettingsVo> querySettings() {
  9. try {
  10. SettingsVo settingsVo = this.myCenterService.querySettings();
  11. if (null != settingsVo) {
  12. return ResponseEntity.ok(settingsVo);
  13. }
  14. } catch (Exception e) {
  15. e.printStackTrace();
  16. }
  17. return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
  18. }

3.5.3、MyCenterService

  1. //com.tanhua.server.service.MyCenterService
  2. public SettingsVo querySettings() {
  3. SettingsVo settingsVo = new SettingsVo();
  4. User user = UserThreadLocal.get();
  5. //设置用户的基本信息
  6. settingsVo.setId(user.getId());
  7. settingsVo.setPhone(user.getMobile());
  8. //查询用户的配置数据
  9. Settings settings = this.settingsService.querySettings(user.getId());
  10. if(ObjectUtil.isNotEmpty(settings)){
  11. settingsVo.setGonggaoNotification(settings.getGonggaoNotification());
  12. settingsVo.setLikeNotification(settings.getLikeNotification());
  13. settingsVo.setPinglunNotification(settings.getPinglunNotification());
  14. }
  15. //查询陌生人问题
  16. settingsVo.setStrangerQuestion(this.tanHuaService.queryQuestion(user.getId()));
  17. return settingsVo;
  18. }

2.5.4、测试

image-20210121105800044
image-20210121105822095

3.6、保存陌生人问题

文档地址:https://mock-java.itheima.net/project/35/interface/api/929

3.6.1、MyCenterController

  1. //com.tanhua.server.controller.MyCenterController
  2. /**
  3. * 设置陌生人问题
  4. *
  5. * @return
  6. */
  7. @PostMapping("questions")
  8. public ResponseEntity<Void> saveQuestions(@RequestBody Map<String, String> param) {
  9. try {
  10. String content = param.get("content");
  11. this.myCenterService.saveQuestions(content);
  12. return ResponseEntity.ok(null);
  13. } catch (Exception e) {
  14. e.printStackTrace();
  15. }
  16. return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
  17. }

3.6.2、MyCenterService

  1. //com.tanhua.server.service.MyCenterService
  2. public void saveQuestions(String content) {
  3. User user = UserThreadLocal.get();
  4. this.questionService.save(user.getId(), content);
  5. }

3.6.3、QuestionService

  1. //com.tanhua.server.service.QuestionService
  2. public void save(Long userId, String content) {
  3. Question question = this.queryQuestion(userId);
  4. if(null != question){
  5. question.setTxt(content);
  6. this.questionMapper.updateById(question);
  7. }else {
  8. question = new Question();
  9. question.setUserId(userId);
  10. question.setTxt(content);
  11. question.setCreated(new Date());
  12. question.setUpdated(question.getCreated());
  13. this.questionMapper.insert(question);
  14. }
  15. }

3.7、黑名单列表

黑名单功能可以用在陌生人打招呼时,进行判断,如果是黑名单的则不能打招呼。
接口文档:https://mock-java.itheima.net/project/35/interface/api/935

3.7.1、表结构

  1. CREATE TABLE `tb_black_list` (
  2. `id` bigint(20) NOT NULL AUTO_INCREMENT,
  3. `user_id` bigint(20) DEFAULT NULL,
  4. `black_user_id` bigint(20) DEFAULT NULL,
  5. `created` datetime DEFAULT NULL,
  6. `updated` datetime DEFAULT NULL,
  7. PRIMARY KEY (`id`),
  8. KEY `user_id` (`user_id`)
  9. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='黑名单';
  10. --测试数据
  11. INSERT INTO `tb_black_list` (`id`, `user_id`, `black_user_id`, `created`, `updated`) VALUES ('1', '1', '22', '2019-11-01 15:47:22', '2019-11-01 15:47:24');
  12. INSERT INTO `tb_black_list` (`id`, `user_id`, `black_user_id`, `created`, `updated`) VALUES ('2', '1', '23', '2019-11-01 15:47:39', '2019-11-01 15:47:42');
  13. INSERT INTO `tb_black_list` (`id`, `user_id`, `black_user_id`, `created`, `updated`) VALUES ('3', '1', '24', '2019-11-01 15:47:51', '2019-11-01 15:47:56');

3.7.2、pojo

  1. package com.tanhua.common.pojo;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. @Data
  6. @NoArgsConstructor
  7. @AllArgsConstructor
  8. public class BlackList extends BasePojo {
  9. private Long id;
  10. private Long userId;
  11. private Long blackUserId;
  12. }

3.7.3、BlackListMapper

  1. package com.tanhua.common.mapper;
  2. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  3. import com.tanhua.common.pojo.BlackList;
  4. public interface BlackListMapper extends BaseMapper<BlackList> {
  5. }

3.7.4、BlackListService

  1. package com.tanhua.server.service;
  2. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  3. import com.baomidou.mybatisplus.core.metadata.IPage;
  4. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  5. import com.tanhua.common.mapper.BlackListMapper;
  6. import com.tanhua.common.pojo.BlackList;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.stereotype.Service;
  9. @Service
  10. public class BlackListService {
  11. @Autowired
  12. private BlackListMapper blackListMapper;
  13. public IPage<BlackList> queryBlacklist(Long userId, Integer page, Integer pageSize) {
  14. QueryWrapper<BlackList> wrapper = new QueryWrapper<BlackList>();
  15. wrapper.eq("user_id", userId);
  16. wrapper.orderByDesc("created");
  17. Page<BlackList> pager = new Page<>(page, pageSize);
  18. return this.blackListMapper.selectPage(pager, wrapper);
  19. }
  20. }

配置分页插件:

  1. package com.tanhua.server.config;
  2. import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. @Configuration
  6. public class MybatisPlusConfig {
  7. /**
  8. * 分页插件
  9. */
  10. @Bean
  11. public PaginationInterceptor paginationInterceptor() {
  12. return new PaginationInterceptor();
  13. }
  14. }

3.7.5、BlackListVo

  1. package com.tanhua.server.vo;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. @Data
  6. @AllArgsConstructor
  7. @NoArgsConstructor
  8. public class BlackListVo {
  9. private Long id;
  10. private String avatar;
  11. private String nickname;
  12. private String gender;
  13. private Integer age;
  14. }

3.7.6、MyCenterController

  1. //com.tanhua.server.controller.MyCenterController
  2. /**
  3. * 查询黑名单
  4. *
  5. * @param page
  6. * @param pagesize
  7. * @return
  8. */
  9. @GetMapping("blacklist")
  10. public ResponseEntity<PageResult> queryBlacklist(@RequestParam(value = "page", defaultValue = "1") Integer page,
  11. @RequestParam(value = "pagesize", defaultValue = "10") Integer pagesize) {
  12. try {
  13. PageResult pageResult = this.myCenterService.queryBlacklist(page, pagesize);
  14. return ResponseEntity.ok(pageResult);
  15. } catch (Exception e) {
  16. e.printStackTrace();
  17. }
  18. return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
  19. }

3.7.7、MyCenterService

  1. //com.tanhua.server.service.MyCenterService
  2. public PageResult queryBlacklist(Integer page, Integer pageSize) {
  3. User user = UserThreadLocal.get();
  4. IPage<BlackList> blackListIPage = this.blackListService.queryBlacklist(user.getId(), page, pageSize);
  5. PageResult pageResult = new PageResult();
  6. pageResult.setPage(page);
  7. pageResult.setPagesize(pageSize);
  8. pageResult.setCounts(Convert.toInt(blackListIPage.getTotal()));
  9. pageResult.setPages(Convert.toInt(blackListIPage.getPages()));
  10. List<BlackList> records = blackListIPage.getRecords();
  11. if(CollUtil.isEmpty(records)){
  12. return pageResult;
  13. }
  14. List<Object> userIds = CollUtil.getFieldValues(records, "blackUserId");
  15. List<UserInfo> userInfoList = this.userInfoService.queryUserInfoByUserIdList(userIds);
  16. List<BlackListVo> blackListVos = new ArrayList<>();
  17. for (UserInfo userInfo : userInfoList) {
  18. BlackListVo blackListVo = new BlackListVo();
  19. blackListVo.setAge(userInfo.getAge());
  20. blackListVo.setAvatar(userInfo.getLogo());
  21. blackListVo.setGender(userInfo.getSex().name().toLowerCase());
  22. blackListVo.setId(userInfo.getUserId());
  23. blackListVo.setNickname(userInfo.getNickName());
  24. blackListVos.add(blackListVo);
  25. }
  26. pageResult.setItems(blackListVos);
  27. return pageResult;
  28. }

3.7.8、测试

1572595630492

3.8、移除黑名单

接口文档:https://mock-java.itheima.net/project/35/interface/api/941

3.8.1、MyCenterController

  1. /**
  2. * 移除黑名单
  3. *
  4. * @return
  5. */
  6. @DeleteMapping("blacklist/{uid}")
  7. public ResponseEntity<Void> delBlacklist(@PathVariable("uid") Long userId) {
  8. try {
  9. this.myCenterService.delBlacklist(userId);
  10. return ResponseEntity.ok(null);
  11. } catch (Exception e) {
  12. e.printStackTrace();
  13. }
  14. return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
  15. }

3.8.2、MyCenterService

  1. public void delBlacklist(Long userId) {
  2. User user = UserThreadLocal.get();
  3. this.blackListService.delBlacklist(user.getId(), userId);
  4. }

3.8.3、BlackListService

  1. public Boolean delBlacklist(Long userId, Long blackUserId) {
  2. QueryWrapper<BlackList> wrapper = new QueryWrapper<BlackList>();
  3. wrapper.eq("user_id", userId).eq("black_user_id", blackUserId);
  4. return this.blackListMapper.delete(wrapper) > 0;
  5. }

3.9、更新通知

接口文档:https://mock-java.itheima.net/project/35/interface/api/965

3.9.1、MyCenterController

  1. //com.tanhua.server.controller.MyCenterController
  2. /**
  3. * 更新通知设置
  4. *
  5. * @param param
  6. * @return
  7. */
  8. @PostMapping("notifications/setting")
  9. public ResponseEntity<Void> updateNotification(@RequestBody Map<String, Boolean> param) {
  10. try {
  11. Boolean likeNotification = param.get("likeNotification");
  12. Boolean pinglunNotification = param.get("pinglunNotification");
  13. Boolean gonggaoNotification = param.get("gonggaoNotification");
  14. this.usersService.updateNotification(likeNotification, pinglunNotification, gonggaoNotification);
  15. return ResponseEntity.ok(null);
  16. } catch (Exception e) {
  17. e.printStackTrace();
  18. }
  19. return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
  20. }

2.9.2、MyCenterService

  1. //com.tanhua.server.service.MyCenterService
  2. public void updateNotification(Boolean likeNotification, Boolean pinglunNotification, Boolean gonggaoNotification) {
  3. User user = UserThreadLocal.get();
  4. this.settingsService.updateNotification(user.getId(), likeNotification, pinglunNotification, gonggaoNotification);
  5. }

2.9.3、SettingsService

  1. //com.tanhua.server.service.SettingsService
  2. public void updateNotification(Long userId, Boolean likeNotification, Boolean pinglunNotification, Boolean gonggaoNotification) {
  3. QueryWrapper<Settings> queryWrapper = new QueryWrapper<>();
  4. queryWrapper.eq("user_id", userId);
  5. Settings settings = this.settingsMapper.selectOne(queryWrapper);
  6. if(null == settings){
  7. //如果没有数据的话,插入一条数据
  8. settings = new Settings();
  9. settings.setUserId(userId);
  10. this.settingsMapper.insert(settings);
  11. }else{
  12. //更新
  13. settings.setLikeNotification(likeNotification);
  14. settings.setPinglunNotification(pinglunNotification);
  15. settings.setGonggaoNotification(gonggaoNotification);
  16. this.settingsMapper.update(settings, queryWrapper);
  17. }
  18. }

3.10、更新手机号

更新手机号的逻辑在sso系统中完成,其流程是:旧手机号获取验证码,验证码校验通过后,设置新手机号,最后保存新的手机号。
步骤1,发送短信验证码:https://mock-java.itheima.net/project/35/interface/api/947
步骤2,校验验证码:https://mock-java.itheima.net/project/35/interface/api/953
步骤3,保存新手机号:https://mock-java.itheima.net/project/35/interface/api/959
配置nginx:

  1. location /users/phone { #请求路径中凡是以/user/phone开头的请求,转发到sso系统
  2. client_max_body_size 300m; #设置最大的请求体大小,解决大文件上传不了的问题
  3. proxy_connect_timeout 300s; #代理连接超时时间
  4. proxy_send_timeout 300s; #代理发送数据的超时时间
  5. proxy_read_timeout 300s; #代理读取数据的超时时间
  6. proxy_pass http://127.0.0.1:18080; #转发请求
  7. }

3.10.1、 发送短信验证码

MyCenterController:

  1. //com.tanhua.sso.controller.MyCenterController
  2. /**
  3. * 发送短信验证码
  4. *
  5. * @return
  6. */
  7. @PostMapping("phone/sendVerificationCode")
  8. public ResponseEntity<Void> sendVerificationCode(@RequestHeader("Authorization") String token) {
  9. try {
  10. boolean bool = this.myCenterService.sendVerificationCode(token);
  11. if (bool) {
  12. return ResponseEntity.ok(null);
  13. }
  14. } catch (Exception e) {
  15. e.printStackTrace();
  16. }
  17. return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
  18. }

MyCenterService:

  1. //com.tanhua.sso.service.MyCenterService
  2. package com.tanhua.sso.service;
  3. import com.tanhua.common.pojo.User;
  4. import com.tanhua.sso.vo.ErrorResult;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.stereotype.Service;
  7. @Service
  8. public class MyCenterService {
  9. @Autowired
  10. private UserService userService;
  11. @Autowired
  12. private SmsService smsService;
  13. public Boolean sendVerificationCode(String token) {
  14. //校验token
  15. User user = this.userService.queryUserByToken(token);
  16. if(ObjectUtil.isEmpty(user)){
  17. return false;
  18. }
  19. ErrorResult errorResult = this.smsService.sendCheckCode(user.getMobile());
  20. return errorResult == null;
  21. }
  22. }

3.10.2、 校验验证码

MyCenterController:

  1. //com.tanhua.sso.controller.MyCenterController
  2. /**
  3. * 校验验证码
  4. *
  5. * @param param
  6. * @param token
  7. * @return
  8. */
  9. @PostMapping("phone/checkVerificationCode")
  10. public ResponseEntity<Map<String, Object>> checkVerificationCode(@RequestBody Map<String, String> param,
  11. @RequestHeader("Authorization") String token) {
  12. try {
  13. String code = param.get("verificationCode");
  14. Boolean bool = this.myCenterService.checkVerificationCode(code, token);
  15. Map<String, Object> result = new HashMap<>();
  16. result.put("verification", bool);
  17. return ResponseEntity.ok(result);
  18. } catch (Exception e) {
  19. e.printStackTrace();
  20. }
  21. return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
  22. }

MyCenterService:

  1. //com.tanhua.sso.service.MyCenterService
  2. public Boolean checkVerificationCode(String code, String token) {
  3. //校验token
  4. User user = this.userService.queryUserByToken(token);
  5. if(ObjectUtil.isEmpty(user)){
  6. return false;
  7. }
  8. //校验验证码,先查询redis中的验证码
  9. String redisKey = "CHECK_CODE_" + user.getMobile();
  10. String value = this.redisTemplate.opsForValue().get(redisKey);
  11. if(StrUtil.equals(code, value)){
  12. //将验证码删除
  13. this.redisTemplate.delete(redisKey);
  14. return true;
  15. }
  16. return false;
  17. }

3.10.3、保存新手机号

MyCenterController:

  1. //com.tanhua.sso.controller.MyCenterController
  2. /**
  3. * 保存新手机号
  4. *
  5. * @return
  6. */
  7. @PostMapping("phone")
  8. public ResponseEntity<Void> updatePhone(@RequestBody Map<String, String> param,
  9. @RequestHeader("Authorization") String token) {
  10. try {
  11. String newPhone = param.get("phone");
  12. boolean bool = this.myCenterService.updatePhone(token, newPhone);
  13. if (bool) {
  14. return ResponseEntity.ok(null);
  15. }
  16. } catch (Exception e) {
  17. e.printStackTrace();
  18. }
  19. return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
  20. }

MyCenterService:

  1. //com.tanhua.sso.service.MyCenterService
  2. public Boolean updatePhone(String token, String newPhone) {
  3. //校验token
  4. User user = this.userService.queryUserByToken(token);
  5. if(ObjectUtil.isEmpty(user)){
  6. return false;
  7. }
  8. Boolean result = this.userService.updatePhone(user.getId(), newPhone);
  9. if(result){
  10. String redisKey = "TANHUA_USER_MOBILE_" + user.getId();
  11. this.redisTemplate.delete(redisKey);
  12. }
  13. return result;
  14. }

UserService:

  1. //com.tanhua.sso.service.UserService
  2. public Boolean updatePhone(Long userId, String newPhone) {
  3. //先查询新手机号是否已经注册,如果已经注册,就不能修改
  4. QueryWrapper<User> queryWrapper = new QueryWrapper<>();
  5. queryWrapper.eq("mobile", newPhone);
  6. User user = this.userMapper.selectOne(queryWrapper);
  7. if(ObjectUtil.isNotEmpty(user)){
  8. //新手机号已经被注册
  9. return false;
  10. }
  11. user = new User();
  12. user.setId(userId);
  13. user.setMobile(newPhone);
  14. return this.userMapper.updateById(user) > 0;
  15. }