vlog/book-service/src/main/java/com/imooc/service/impl/UserServiceImpl.java
2025-05-07 10:11:09 +08:00

433 lines
14 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.imooc.service.impl;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Maps;
import com.imooc.base.BaseInfoProperties;
import com.imooc.bo.UpdatedUserBO;
import com.imooc.enums.Sex;
import com.imooc.enums.UserInfoModifyType;
import com.imooc.enums.YesOrNo;
import com.imooc.exceptions.GraceException;
import com.imooc.grace.result.ResponseStatusEnum;
import com.imooc.mapper.FansMapper;
import com.imooc.mapper.FansMapperCustom;
import com.imooc.service.FansService;
import com.imooc.mapper.UserMemberMapper;
import com.imooc.mapper.UsersMapper;
import com.imooc.mo.Token;
import com.imooc.pojo.Fans;
import com.imooc.pojo.UserMember;
import com.imooc.pojo.Users;
import com.imooc.service.UserService;
import com.imooc.utils.*;
import com.imooc.vo.FansVO;
import com.imooc.vo.UsersVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.n3r.idworker.Sid;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import tk.mybatis.mapper.entity.Example;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import static com.imooc.base.BaseInfoProperties.REDIS_USER_TOKEN;
import static com.imooc.base.BaseInfoProperties.MOBILE_SMSCODE;
/**
* @author vercen
* @version 1.0
* @date 2023/5/25 21:02
*/
@Slf4j
@Service
public class UserServiceImpl extends BaseInfoProperties implements UserService {
@Autowired
private UsersMapper usersMapper;
@Autowired
private FansMapperCustom fansMapperCustom;
@Autowired
private FansService fansService;
@Resource
private PasswordEncoder passwordEncoder;
@Autowired
private UserMemberMapper userMemberMapper;
@Autowired
private FansMapper fansMapper;
//@Autowired
//public RedisOperator redis;
@Resource(name = "redisTemplate")
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private Sid sid;
private static final String USER_FACE1 = "http://43.143.227.203:29000/bucket/logo.png";
@Override
public Users queryMobileIsExist(String mobile) {
Example userExample = new Example(Users.class);
Example.Criteria criteria = userExample.createCriteria();
criteria.andEqualTo("mobile", mobile);
Users user = usersMapper.selectOneByExample(userExample);
return user;
}
@Override
public Users createUser(String mobile) {
// 获得全局唯一主键
String userId = sid.nextShort();
Users user = new Users();
user.setId(userId);
user.setPassword(mobile);
user.setMobile(mobile);
user.setNickname("用户:" + DesensitizationUtil.commonDisplay(mobile));
user.setImoocNum("用户:" + DesensitizationUtil.commonDisplay(mobile));
user.setFace(USER_FACE1);
user.setBirthday(DateUtil.stringToDate("1999-01-01"));
user.setSex(Sex.secret.type);
user.setBgImg(USER_FACE1);
user.setCountry("中国");
user.setProvince("");
user.setCity("");
user.setDistrict("");
user.setDescription("这家伙很懒,什么都没留下~");
user.setCanImoocNumBeUpdated(YesOrNo.YES.type);
user.setCreatedTime(new Date());
user.setUpdatedTime(new Date());
usersMapper.insert(user);
return user;
}
@Override
public Users getUser(String userId) {
Users users = usersMapper.selectByPrimaryKey(userId);
return users;
}
@Transactional
@Override
public Users updateUserInfo(UpdatedUserBO updatedUserBO) {
Users users = new Users();
BeanUtils.copyProperties(updatedUserBO, users);
usersMapper.updateByPrimaryKeySelective(users);
return getUser(updatedUserBO.getId());
}
@Transactional
@Override
public Users updateUserInfo(UpdatedUserBO updatedUserBO, Integer type) {
if (type == UserInfoModifyType.NICKNAME.type) {
usersMapper.updateNickname(updatedUserBO);
}
if (type == UserInfoModifyType.SEX.type) {
usersMapper.updateSex(updatedUserBO);
}
if (type == UserInfoModifyType.BIRTHDAY.type) {
usersMapper.updateBirthday(updatedUserBO);
}
if (type == UserInfoModifyType.LOCATION.type) {
usersMapper.updateLocation(updatedUserBO);
}
if (type == UserInfoModifyType.DESC.type) {
usersMapper.updateDescription(updatedUserBO);
}
if (type == UserInfoModifyType.IMOOCNUM.type) {
if (updatedUserBO.getCanImoocNumBeUpdated() == YesOrNo.NO.type) {
GraceException.display(ResponseStatusEnum.USER_INFO_CANT_UPDATED_IMOOCNUM_ERROR);
}
// 校验唯一性
List<UsersVO> haveImooc = usersMapper.selectByImoocNum(updatedUserBO.getImoocNum());
if (haveImooc != null && !haveImooc.isEmpty()) {
GraceException.display(ResponseStatusEnum.USER_INFO_UPDATED_IMOOCNUM_EXIST_ERROR);
}
usersMapper.updateVnum(updatedUserBO);
}
return getUser(updatedUserBO.getId());
// Example example = new Example(Users.class);
// Example.Criteria criteria = example.createCriteria();
// if (type == UserInfoModifyType.NICKNAME.type) {
// criteria.andEqualTo("nickname", updatedUserBO.getNickname());
// Users user = usersMapper.selectOneByExample(example);
// if (user != null) {
// GraceException.display(ResponseStatusEnum.USER_INFO_UPDATED_NICKNAME_EXIST_ERROR);
// }
// }
//
// if (type == UserInfoModifyType.IMOOCNUM.type) {
// criteria.andEqualTo("imoocNum", updatedUserBO.getImoocNum());
// Users user = usersMapper.selectOneByExample(example);
// if (user != null) {
// GraceException.display(ResponseStatusEnum.USER_INFO_UPDATED_NICKNAME_EXIST_ERROR);
// }
//
// Users tempUser = getUser(updatedUserBO.getId());
// if (tempUser.getCanImoocNumBeUpdated() == YesOrNo.NO.type) {
// GraceException.display(ResponseStatusEnum.USER_INFO_CANT_UPDATED_IMOOCNUM_ERROR);
// }
//
// updatedUserBO.setCanImoocNumBeUpdated(YesOrNo.NO.type);
// }
//
// return updateUserInfo(updatedUserBO);
}
@Transactional(rollbackFor = RuntimeException.class)
@Override
public Map<String, Object> createUserNew(String mobile) {
// 获得全局唯一主键
String userId = sid.nextShort();
// 创建短视频系统账号
Users user = new Users();
user.setId(userId);
user.setPassword(passwordEncoder.encode(mobile));
user.setMobile(mobile);
user.setNickname("用户:" + DesensitizationUtil.commonDisplay(mobile));
user.setImoocNum("用户:" + DesensitizationUtil.commonDisplay(mobile));
user.setFace(USER_FACE1);
user.setBirthday(DateUtil.stringToDate("1999-01-01"));
user.setSex(Sex.secret.type);
user.setBgImg(USER_FACE1);
user.setCountry("中国");
user.setProvince("");
user.setCity("");
user.setDistrict("");
user.setDescription("这家伙很懒,什么都没留下~");
user.setBgImg("");
user.setCanImoocNumBeUpdated(YesOrNo.YES.type);
user.setCreatedTime(new Date());
user.setUpdatedTime(new Date());
int row = usersMapper.insert(user);
if (row > 0) {
Map<String, Object> result = Maps.newHashMap();
result.put("user", user);
// 创建商城系统账号,获取商城系统token
String url = "http://localhost:8888/buyer/passport/member/registerFromTik";
MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
param.add("userName", mobile);
param.add("password", mobile);
param.add("mobilePhone", mobile);
param.add("userId", user.getId());
RestTemplateUtil.post(null, null, null, url, param, String.class, t -> {
if (t.getStatusCode() == HttpStatus.OK) {
String content = t.getBody();
if (StringUtils.isNotBlank(content)) {
Token token = GsonUtil.jsonToBean(content, Token.class);
result.put("token", token);
} else {
throw new RuntimeException("账号注册异常");
}
} else {
throw new RuntimeException("账号注册异常");
}
});
return result;
}
return null;
}
@Override
public Token getShopToken(String userId) {
Token[] tokens = { null };
String url = "http://localhost:8888/buyer/passport/member/getTokenFromTik";
MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
param.add("userId", userId);
RestTemplateUtil.post(null, null, null, url, param, String.class, t -> {
if (t.getStatusCode() == HttpStatus.OK) {
String content = t.getBody();
if (StringUtils.isNotBlank(content)) {
tokens[0] = GsonUtil.jsonToBean(content, Token.class);
} else {
throw new RuntimeException("账号注册异常");
}
} else {
throw new RuntimeException("账号注册异常");
}
});
return tokens[0];
}
@Transactional(rollbackFor = RuntimeException.class)
@Override
public Users createUserFromShop(String mobile, String memberId) {
String tempMobile = StringUtils.isBlank(mobile) ? "unionID" : mobile;
// 获得全局唯一主键
String userId = sid.nextShort();
Users user = new Users();
user.setId(userId);
user.setPassword(tempMobile);
user.setMobile(tempMobile);
user.setNickname("用户:" + DesensitizationUtil.commonDisplay(tempMobile));
user.setImoocNum("WZJ" + (System.currentTimeMillis() / 1000) + (int)(Math.random() * 1000));
user.setFace(USER_FACE1);
user.setBirthday(DateUtil.stringToDate("1999-01-01"));
user.setSex(Sex.secret.type);
user.setBgImg("https://wuzhongjie.com.cn/download/logo.png"); // 测试用地址
user.setCountry("中国");
user.setProvince("");
user.setCity("");
user.setDistrict("");
user.setDescription("这家伙很懒,什么都没留下~");
user.setCanImoocNumBeUpdated(YesOrNo.YES.type);
user.setCreatedTime(new Date());
user.setUpdatedTime(new Date());
// 短视频用户与商城账号关系
UserMember userMember = new UserMember();
userMember.setUserId(user.getId());
userMember.setMemberId(memberId);
if (usersMapper.insert(user) > 0 && userMemberMapper.insert(userMember) > 0) {
return user;
}
return null;
}
@Override
public String getUserInfoFromShop(String memberId) {
return Optional.ofNullable(userMemberMapper.getUserByMemberId(memberId))//
.map(user -> {
String uToken = UUID.randomUUID().toString();
//redis.set(REDIS_USER_TOKEN + ":" + user.getId(), uToken);
redisTemplate.opsForValue().set(REDIS_USER_TOKEN + ":" + user.getId(), uToken);
// 返回给前端
UsersVO usersVO = new UsersVO();
BeanUtils.copyProperties(user, usersVO);
usersVO.setUserToken(uToken);
return GsonUtil.beanToJson(usersVO);
})//
.orElseGet(() -> StringUtils.EMPTY);
}
@Override
public List<UsersVO> searchByNickname(String nickname, Integer page, Integer pageSize, String currentUserId) {
try {
PageHelper.startPage(page, pageSize);
List<UsersVO> userList = usersMapper.searchByNickname(nickname);
if(currentUserId.isEmpty()){
return userList;
}
// 提取模糊查询出的用户 ID 列表
List<String> vlogerIds = userList.stream().map(UsersVO::getId).collect(Collectors.toList());
log.info("用户列表" + vlogerIds);
if (vlogerIds.isEmpty()) {
log.info("没有查询到用户 ID跳过关注关系查询");
return userList;
}
//
userList.forEach(usersVO -> {
// 当前用户是否关注博主
Boolean isFollowed = fansService.queryDoIFollowVloger(currentUserId,usersVO.getId());
// 我的粉丝总数
String myFansCountsStr = redis.get(REDIS_MY_FANS_COUNTS + ":" + usersVO.getId());
// 获赞总数
String likedVlogerCountsStr = redis.get(REDIS_VLOGER_BE_LIKED_COUNTS + ":" + usersVO.getId());
int fansCount = 0;
int likeCount = 0;
if (myFansCountsStr != null) {
try {
fansCount = Integer.parseInt(myFansCountsStr);
} catch (NumberFormatException e) {
// 可选:记录日志或处理异常
fansCount = 0;
}
}
if (likedVlogerCountsStr != null) {
try {
likeCount = Integer.parseInt(likedVlogerCountsStr);
} catch (NumberFormatException e) {
// 可选:记录日志或处理异常
likeCount = 0;
}
}
usersVO.setMyFansCounts(fansCount);
usersVO.setTotalLikeMeCounts(likeCount);
if (isFollowed) {
String relationship = redis.get(REDIS_FANS_AND_VLOGGER_RELATIONSHIP + ":" + usersVO.getId() + ":" + currentUserId);
if (StringUtils.isNotBlank(relationship) && relationship.equalsIgnoreCase("1")) {
usersVO.setFollowStatus("互相关注");
}else {
usersVO.setFollowStatus("已关注");
}
} else {
usersVO.setFollowStatus("未关注");
}
});
return userList;
//
//
//
//
// // 获取当前用户关注的
// List<java.util.Map<String, Object>> followedRelations = fansMapper.getFollowedVlogerIds(currentUserId, vlogerIds);
// log.info("获取当前用户关注的: {}", followedRelations);
// // 构建 vlogerId 到 is_fan_friend_of_mine 的映射
// java.util.Map<String, Integer> relationMap = followedRelations.stream()
// .filter(Objects::nonNull) // 排除整个 map 为 null 的情况
// .collect(Collectors.toMap(
// map -> (String) map.get("vloger_id"),
// map -> (Integer) map.get("is_fan_friend_of_mine")
// ));
// log.info("构造的 relationMap: {}", relationMap);
// Set<String> followedVlogerIds = relationMap.keySet();
//
// // 遍历设置每个用户的关注状态及展示状态
// userList.forEach(usersVO -> {
// boolean isFollowed = followedVlogerIds.contains(usersVO.getId());
// usersVO.setIsFollowed(isFollowed);
// if (isFollowed) {
// Integer isFanFriendOfMine = relationMap.get(usersVO.getId());
// if (isFanFriendOfMine != null && isFanFriendOfMine == 1) {
// usersVO.setFollowStatus("互相关注"); // 假设 UsersVO 有此方法设置展示状态
// } else {
// usersVO.setFollowStatus("已关注");
// }
// } else {
// usersVO.setFollowStatus("未关注");
// }
// });
//
// log.info("用户列表" + userList);
// return userList;
} catch (Exception e) {
log.error("搜索用户时发生异常", e);
throw new RuntimeException("搜索用户时发生异常", e);
}
}
}