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 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 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 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 result = Maps.newHashMap(); result.put("user", user); // 创建商城系统账号,获取商城系统token String url = "http://localhost:8888/buyer/passport/member/registerFromTik"; MultiValueMap 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 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 searchByNickname(String nickname, Integer page, Integer pageSize, String currentUserId) { try { PageHelper.startPage(page, pageSize); List userList = usersMapper.searchByNickname(nickname); if(currentUserId.isEmpty()){ return userList; } // 提取模糊查询出的用户 ID 列表 List 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> followedRelations = fansMapper.getFollowedVlogerIds(currentUserId, vlogerIds); // log.info("获取当前用户关注的: {}", followedRelations); // // 构建 vlogerId 到 is_fan_friend_of_mine 的映射 // java.util.Map 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 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); } } }