content: package com.ld.poetry.service.impl;
  
  import cn.hutool.crypto.SecureUtil;
  import com.alibaba.fastjson.JSON;
  import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
  import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  import com.ld.poetry.config.PoetryResult;
  import com.ld.poetry.constants.CommonConst;
  import com.ld.poetry.dao.UserMapper;
  import com.ld.poetry.entity.User;
  import com.ld.poetry.entity.WebInfo;
  import com.ld.poetry.entity.WeiYan;
  import com.ld.poetry.enums.PoetryEnum;
  import com.ld.poetry.handle.PoetryRuntimeException;
  import com.ld.poetry.im.http.dao.ImChatGroupUserMapper;
  import com.ld.poetry.im.http.dao.ImChatUserFriendMapper;
  import com.ld.poetry.im.http.entity.ImChatGroupUser;
  import com.ld.poetry.im.http.entity.ImChatUserFriend;
  import com.ld.poetry.im.websocket.ImConfigConst;
  import com.ld.poetry.im.websocket.TioUtil;
  import com.ld.poetry.im.websocket.TioWebsocketStarter;
  import com.ld.poetry.service.UserService;
  import com.ld.poetry.service.WeiYanService;
  import com.ld.poetry.utils.*;
  import com.ld.poetry.utils.cache.PoetryCache;
  import com.ld.poetry.utils.mail.MailUtil;
  import com.ld.poetry.vo.BaseRequestVO;
  import com.ld.poetry.vo.UserVO;
  import lombok.extern.slf4j.Slf4j;
  import org.springframework.beans.BeanUtils;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.beans.factory.annotation.Value;
  import org.springframework.stereotype.Service;
  import org.springframework.util.CollectionUtils;
  import org.springframework.util.DigestUtils;
  import org.springframework.util.StringUtils;
  import org.tio.core.Tio;
  
  import java.nio.charset.StandardCharsets;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Random;
  import java.util.UUID;
  import java.util.concurrent.atomic.AtomicInteger;
  import java.util.stream.Collectors;
  
  /**
   * <p>
   * 用户信息表 服务实现类
   * </p>
   *
   * @author sara
   * @since 2021-08-12
   */
  @Service
  @Slf4j
  public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
  
      @Autowired
      private WeiYanService weiYanService;
  
      @Autowired
      private ImChatGroupUserMapper imChatGroupUserMapper;
  
      @Autowired
      private ImChatUserFriendMapper imChatUserFriendMapper;
  
      @Autowired
      private MailUtil mailUtil;
  
      @Value("${user.code.format}")
      private String codeFormat;
  
      @Override
      public PoetryResult<UserVO> login(String account, String password, Boolean isAdmin) {
          password = new String(SecureUtil.aes(CommonConst.CRYPOTJS_KEY.getBytes(StandardCharsets.UTF_8)).decrypt(password));
  
          User one = lambdaQuery().and(wrapper -> wrapper
                          .eq(User::getUsername, account)
                          .or()
                          .eq(User::getEmail, account)
                          .or()
                          .eq(User::getPhoneNumber, account))
                  .eq(User::getPassword, DigestUtils.md5DigestAsHex(password.getBytes()))
                  .one();
  
          if (one == null) {
              return PoetryResult.fail("账号/密码错误，请重新输入！");
          }
  
          if (!one.getUserStatus()) {
              return PoetryResult.fail("账号被冻结！");
          }
  
          String adminToken = "";
          String userToken = "";
  
          if (isAdmin) {
              if (one.getUserType() != PoetryEnum.USER_TYPE_ADMIN.getCode() && one.getUserType() != PoetryEnum.USER_TYPE_DEV.getCode()) {
                  return PoetryResult.fail("请输入管理员账号！");
              }
              if (PoetryCache.get(CommonConst.ADMIN_TOKEN + one.getId()) != null) {
                  adminToken = (String) PoetryCache.get(CommonConst.ADMIN_TOKEN + one.getId());
              }
          } else {
              if (PoetryCache.get(CommonConst.USER_TOKEN + one.getId()) != null) {
                  userToken = (String) PoetryCache.get(CommonConst.USER_TOKEN + one.getId());
              }
          }
  
  
          if (isAdmin && !StringUtils.hasText(adminToken)) {
              String uuid = UUID.randomUUID().toString().replaceAll("-", "");
              adminToken = CommonConst.ADMIN_ACCESS_TOKEN + uuid;
              PoetryCache.put(adminToken, one, CommonConst.TOKEN_EXPIRE);
              PoetryCache.put(CommonConst.ADMIN_TOKEN + one.getId(), adminToken, CommonConst.TOKEN_EXPIRE);
          } else if (!isAdmin && !StringUtils.hasText(userToken)) {
              String uuid = UUID.randomUUID().toString().replaceAll("-", "");
              userToken = CommonConst.USER_ACCESS_TOKEN + uuid;
              PoetryCache.put(userToken, one, CommonConst.TOKEN_EXPIRE);
              PoetryCache.put(CommonConst.USER_TOKEN + one.getId(), userToken, CommonConst.TOKEN_EXPIRE);
          }
  
  
          UserVO userVO = new UserVO();
          BeanUtils.copyProperties(one, userVO);
          userVO.setPassword(null);
          if (isAdmin && one.getUserType() == PoetryEnum.USER_TYPE_ADMIN.getCode()) {
              userVO.setIsBoss(true);
          }
  
          if (isAdmin) {
              userVO.setAccessToken(adminToken);
          } else {
              userVO.setAccessToken(userToken);
          }
          return PoetryResult.success(userVO);
      }
  
      @Override
      public PoetryResult exit() {
          String token = PoetryUtil.getToken();
          Integer userId = PoetryUtil.getUserId();
          if (token.contains(CommonConst.USER_ACCESS_TOKEN)) {
              PoetryCache.remove(CommonConst.USER_TOKEN + userId);
              TioWebsocketStarter tioWebsocketStarter = TioUtil.getTio();
              if (tioWebsocketStarter != null) {
                  Tio.removeUser(tioWebsocketStarter.getServerTioConfig(), String.valueOf(userId), "remove user");
              }
          } else if (token.contains(CommonConst.ADMIN_ACCESS_TOKEN)) {
              PoetryCache.remove(CommonConst.ADMIN_TOKEN + userId);
          }
          PoetryCache.remove(token);
          return PoetryResult.success();
      }
  
      @Override
      public PoetryResult<UserVO> regist(UserVO user) {
          String regex = "\\d{11}";
          if (user.getUsername().matches(regex)) {
              return PoetryResult.fail("用户名不能为11位数字！");
          }
  
          if (user.getUsername().contains("@")) {
              return PoetryResult.fail("用户名不能包含@！");
          }
  
          if (StringUtils.hasText(user.getPhoneNumber()) && StringUtils.hasText(user.getEmail())) {
              return PoetryResult.fail("手机号与邮箱只能选择其中一个！");
          }
  
          if (StringUtils.hasText(user.getPhoneNumber())) {
              Integer codeCache = (Integer) PoetryCache.get(CommonConst.FORGET_PASSWORD + user.getPhoneNumber() + "_1");
              if (codeCache == null || codeCache != Integer.parseInt(user.getCode())) {
                  return PoetryResult.fail("验证码错误！");
              }
              PoetryCache.remove(CommonConst.FORGET_PASSWORD + user.getPhoneNumber() + "_1");
          } else if (StringUtils.hasText(user.getEmail())) {
              Integer codeCache = (Integer) PoetryCache.get(CommonConst.FORGET_PASSWORD + user.getEmail() + "_2");
              if (codeCache == null || codeCache != Integer.parseInt(user.getCode())) {
                  return PoetryResult.fail("验证码错误！");
              }
              PoetryCache.remove(CommonConst.FORGET_PASSWORD + user.getEmail() + "_2");
          } else {
              return PoetryResult.fail("请输入邮箱或手机号！");
          }
  
  
          user.setPassword(new String(SecureUtil.aes(CommonConst.CRYPOTJS_KEY.getBytes(StandardCharsets.UTF_8)).decrypt(user.getPassword())));
  
          Integer count = lambdaQuery().eq(User::getUsername, user.getUsername()).count();
          if (count != 0) {
              return PoetryResult.fail("用户名重复！");
          }
          if (StringUtils.hasText(user.getPhoneNumber())) {
              Integer phoneNumberCount = lambdaQuery().eq(User::getPhoneNumber, user.getPhoneNumber()).count();
              if (phoneNumberCount != 0) {
                  return PoetryResult.fail("手机号重复！");
              }
          } else if (StringUtils.hasText(user.getEmail())) {
              Integer emailCount = lambdaQuery().eq(User::getEmail, user.getEmail()).count();
              if (emailCount != 0) {
                  return PoetryResult.fail("邮箱重复！");
              }
          }
  
          User u = new User();
          u.setUsername(user.getUsername());
          u.setPhoneNumber(user.getPhoneNumber());
          u.setEmail(user.getEmail());
          u.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));
          u.setAvatar(PoetryUtil.getRandomAvatar(null));
          save(u);
  
          User one = lambdaQuery().eq(User::getId, u.getId()).one();
  
          String userToken = CommonConst.USER_ACCESS_TOKEN + UUID.randomUUID().toString().replaceAll("-", "");
          PoetryCache.put(userToken, one, CommonConst.TOKEN_EXPIRE);
          PoetryCache.put(CommonConst.USER_TOKEN + one.getId(), userToken, CommonConst.TOKEN_EXPIRE);
  
          UserVO userVO = new UserVO();
          BeanUtils.copyProperties(one, userVO);
          userVO.setPassword(null);
          userVO.setAccessToken(userToken);
  
          WeiYan weiYan = new WeiYan();
          weiYan.setUserId(one.getId());
          weiYan.setContent("到此一游");
          weiYan.setType(CommonConst.WEIYAN_TYPE_FRIEND);
          weiYan.setIsPublic(Boolean.TRUE);
          weiYanService.save(weiYan);
  
          ImChatGroupUser imChatGroupUser = new ImChatGroupUser();
          imChatGroupUser.setGroupId(ImConfigConst.DEFAULT_GROUP_ID);
          imChatGroupUser.setUserId(one.getId());
          imChatGroupUser.setUserStatus(ImConfigConst.GROUP_USER_STATUS_PASS);
          imChatGroupUserMapper.insert(imChatGroupUser);
  
          ImChatUserFriend imChatUser = new ImChatUserFriend();
          imChatUser.setUserId(one.getId());
          imChatUser.setFriendId(PoetryUtil.getAdminUser().getId());
          imChatUser.setRemark("站长");
          imChatUser.setFriendStatus(ImConfigConst.FRIEND_STATUS_PASS);
          imChatUserFriendMapper.insert(imChatUser);
  
          ImChatUserFriend imChatFriend = new ImChatUserFriend();
          imChatFriend.setUserId(PoetryUtil.getAdminUser().getId());
          imChatFriend.setFriendId(one.getId());
          imChatFriend.setFriendStatus(ImConfigConst.FRIEND_STATUS_PASS);
          imChatUserFriendMapper.insert(imChatFriend);
  
          return PoetryResult.success(userVO);
      }
  
      @Override
      public PoetryResult<UserVO> updateUserInfo(UserVO user) {
          if (StringUtils.hasText(user.getUsername())) {
              String regex = "\\d{11}";
              if (user.getUsername().matches(regex)) {
                  return PoetryResult.fail("用户名不能为11位数字！");
              }
  
              if (user.getUsername().contains("@")) {
                  return PoetryResult.fail("用户名不能包含@！");
              }
  
              Integer count = lambdaQuery().eq(User::getUsername, user.getUsername()).ne(User::getId, PoetryUtil.getUserId()).count();
              if (count != 0) {
                  return PoetryResult.fail("用户名重复！");
              }
          }
          User u = new User();
          u.setId(PoetryUtil.getUserId());
          u.setUsername(user.getUsername());
          u.setAvatar(user.getAvatar());
          u.setGender(user.getGender());
          u.setIntroduction(user.getIntroduction());
          updateById(u);
          User one = lambdaQuery().eq(User::getId, u.getId()).one();
          PoetryCache.put(PoetryUtil.getToken(), one, CommonConst.TOKEN_EXPIRE);
          PoetryCache.put(CommonConst.USER_TOKEN + one.getId(), PoetryUtil.getToken(), CommonConst.TOKEN_EXPIRE);
  
          UserVO userVO = new UserVO();
          BeanUtils.copyProperties(one, userVO);
          userVO.setPassword(null);
          userVO.setAccessToken(PoetryUtil.getToken());
          return PoetryResult.success(userVO);
      }
  
      @Override
      public PoetryResult getCode(Integer flag) {
          User user = PoetryUtil.getCurrentUser();
          int i = new Random().nextInt(900000) + 100000;
          if (flag == 1) {
              if (!StringUtils.hasText(user.getPhoneNumber())) {
                  return PoetryResult.fail("请先绑定手机号！");
              }
  
              log.info(user.getId() + "---" + user.getUsername() + "---" + "手机验证码---" + i);
          } else if (flag == 2) {
              if (!StringUtils.hasText(user.getEmail())) {
                  return PoetryResult.fail("请先绑定邮箱！");
              }
  
              log.info(user.getId() + "---" + user.getUsername() + "---" + "邮箱验证码---" + i);
  
              List<String> mail = new ArrayList<>();
              mail.add(user.getEmail());
              String text = getCodeMail(i);
              WebInfo webInfo = (WebInfo) PoetryCache.get(CommonConst.WEB_INFO);
  
              AtomicInteger count = (AtomicInteger) PoetryCache.get(CommonConst.CODE_MAIL + mail.get(0));
              if (count == null || count.get() < CommonConst.CODE_MAIL_COUNT) {
                  mailUtil.sendMailMessage(mail, "您有一封来自" + (webInfo == null ? "POETIZE" : webInfo.getWebName()) + "的回执！", text);
                  if (count == null) {
                      PoetryCache.put(CommonConst.CODE_MAIL + mail.get(0), new AtomicInteger(1), CommonConst.CODE_EXPIRE);
                  } else {
                      count.incrementAndGet();
                  }
              } else {
                  return PoetryResult.fail("验证码发送次数过多，请明天再试！");
              }
          }
          PoetryCache.put(CommonConst.USER_CODE + PoetryUtil.getUserId() + "_" + flag, Integer.valueOf(i), 300);
          return PoetryResult.success();
      }
  
      @Override
      public PoetryResult getCodeForBind(String place, Integer flag) {
          int i = new Random().nextInt(900000) + 100000;
          if (flag == 1) {
              log.info(place + "---" + "手机验证码---" + i);
          } else if (flag == 2) {
              log.info(place + "---" + "邮箱验证码---" + i);
              List<String> mail = new ArrayList<>();
              mail.add(place);
              String text = getCodeMail(i);
              WebInfo webInfo = (WebInfo) PoetryCache.get(CommonConst.WEB_INFO);
  
              AtomicInteger count = (AtomicInteger) PoetryCache.get(CommonConst.CODE_MAIL + mail.get(0));
              if (count == null || count.get() < CommonConst.CODE_MAIL_COUNT) {
                  mailUtil.sendMailMessage(mail, "您有一封来自" + (webInfo == null ? "POETIZE" : webInfo.getWebName()) + "的回执！", text);
                  if (count == null) {
                      PoetryCache.put(CommonConst.CODE_MAIL + mail.get(0), new AtomicInteger(1), CommonConst.CODE_EXPIRE);
                  } else {
                      count.incrementAndGet();
                  }
              } else {
                  return PoetryResult.fail("验证码发送次数过多，请明天再试！");
              }
          }
          PoetryCache.put(CommonConst.USER_CODE + PoetryUtil.getUserId() + "_" + place + "_" + flag, Integer.valueOf(i), 300);
          return PoetryResult.success();
      }
  
      @Override
      public PoetryResult<UserVO> updateSecretInfo(String place, Integer flag, String code, String password) {
          password = new String(SecureUtil.aes(CommonConst.CRYPOTJS_KEY.getBytes(StandardCharsets.UTF_8)).decrypt(password));
  
          User user = PoetryUtil.getCurrentUser();
          if ((flag == 1 || flag == 2) && !DigestUtils.md5DigestAsHex(password.getBytes()).equals(user.getPassword())) {
              return PoetryResult.fail("密码错误！");
          }
          if ((flag == 1 || flag == 2) && !StringUtils.hasText(code)) {
              return PoetryResult.fail("请输入验证码！");
          }
          User updateUser = new User();
          updateUser.setId(user.getId());
          if (flag == 1) {
              Integer count = lambdaQuery().eq(User::getPhoneNumber, place).count();
              if (count != 0) {
                  return PoetryResult.fail("手机号重复！");
              }
              Integer codeCache = (Integer) PoetryCache.get(CommonConst.USER_CODE + PoetryUtil.getUserId() + "_" + place + "_" + flag);
              if (codeCache != null && codeCache.intValue() == Integer.parseInt(code)) {
  
                  PoetryCache.remove(CommonConst.USER_CODE + PoetryUtil.getUserId() + "_" + place + "_" + flag);
  
                  updateUser.setPhoneNumber(place);
              } else {
                  return PoetryResult.fail("验证码错误！");
              }
  
          } else if (flag == 2) {
              Integer count = lambdaQuery().eq(User::getEmail, place).count();
              if (count != 0) {
                  return PoetryResult.fail("邮箱重复！");
              }
              Integer codeCache = (Integer) PoetryCache.get(CommonConst.USER_CODE + PoetryUtil.getUserId() + "_" + place + "_" + flag);
              if (codeCache != null && codeCache.intValue() == Integer.parseInt(code)) {
  
                  PoetryCache.remove(CommonConst.USER_CODE + PoetryUtil.getUserId() + "_" + place + "_" + flag);
  
                  updateUser.setEmail(place);
              } else {
                  return PoetryResult.fail("验证码错误！");
              }
          } else if (flag == 3) {
              if (DigestUtils.md5DigestAsHex(place.getBytes()).equals(user.getPassword())) {
                  updateUser.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
              } else {
                  return PoetryResult.fail("密码错误！");
              }
          }
          updateById(updateUser);
  
          User one = lambdaQuery().eq(User::getId, user.getId()).one();
          PoetryCache.put(PoetryUtil.getToken(), one, CommonConst.TOKEN_EXPIRE);
          PoetryCache.put(CommonConst.USER_TOKEN + one.getId(), PoetryUtil.getToken(), CommonConst.TOKEN_EXPIRE);
  
          UserVO userVO = new UserVO();
          BeanUtils.copyProperties(one, userVO);
          userVO.setPassword(null);
          return PoetryResult.success(userVO);
      }
  
      @Override
      public PoetryResult getCodeForForgetPassword(String place, Integer flag) {
          int i = new Random().nextInt(900000) + 100000;
          if (flag == 1) {
              log.info(place + "---" + "手机验证码---" + i);
          } else if (flag == 2) {
              log.info(place + "---" + "邮箱验证码---" + i);
  
              List<String> mail = new ArrayList<>();
              mail.add(place);
              String text = getCodeMail(i);
              WebInfo webInfo = (WebInfo) PoetryCache.get(CommonConst.WEB_INFO);
  
              AtomicInteger count = (AtomicInteger) PoetryCache.get(CommonConst.CODE_MAIL + mail.get(0));
              if (count == null || count.get() < CommonConst.CODE_MAIL_COUNT) {
                  mailUtil.sendMailMessage(mail, "您有一封来自" + (webInfo == null ? "POETIZE" : webInfo.getWebName()) + "的回执！", text);
                  if (count == null) {
                      PoetryCache.put(CommonConst.CODE_MAIL + mail.get(0), new AtomicInteger(1), CommonConst.CODE_EXPIRE);
                  } else {
                      count.incrementAndGet();
                  }
              } else {
                  return PoetryResult.fail("验证码发送次数过多，请明天再试！");
              }
          }
          PoetryCache.put(CommonConst.FORGET_PASSWORD + place + "_" + flag, Integer.valueOf(i), 300);
          return PoetryResult.success();
      }
  
      @Override
      public PoetryResult updateForForgetPassword(String place, Integer flag, String code, String password) {
          password = new String(SecureUtil.aes(CommonConst.CRYPOTJS_KEY.getBytes(StandardCharsets.UTF_8)).decrypt(password));
  
          Integer codeCache = (Integer) PoetryCache.get(CommonConst.FORGET_PASSWORD + place + "_" + flag);
          if (codeCache == null || codeCache != Integer.parseInt(code)) {
              return PoetryResult.fail("验证码错误！");
          }
  
          PoetryCache.remove(CommonConst.FORGET_PASSWORD + place + "_" + flag);
  
          if (flag == 1) {
              User user = lambdaQuery().eq(User::getPhoneNumber, place).one();
              if (user == null) {
                  return PoetryResult.fail("该手机号未绑定账号！");
              }
  
              if (!user.getUserStatus()) {
                  return PoetryResult.fail("账号被冻结！");
              }
  
              lambdaUpdate().eq(User::getPhoneNumber, place).set(User::getPassword, DigestUtils.md5DigestAsHex(password.getBytes())).update();
              PoetryCache.remove(CommonConst.USER_CACHE + user.getId().toString());
          } else if (flag == 2) {
              User user = lambdaQuery().eq(User::getEmail, place).one();
              if (user == null) {
                  return PoetryResult.fail("该邮箱未绑定账号！");
              }
  
              if (!user.getUserStatus()) {
                  return PoetryResult.fail("账号被冻结！");
              }
  
              lambdaUpdate().eq(User::getEmail, place).set(User::getPassword, DigestUtils.md5DigestAsHex(password.getBytes())).update();
              PoetryCache.remove(CommonConst.USER_CACHE + user.getId().toString());
          }
  
          return PoetryResult.success();
      }
  
      @Override
      public PoetryResult<Page> listUser(BaseRequestVO baseRequestVO) {
          LambdaQueryChainWrapper<User> lambdaQuery = lambdaQuery();
  
          if (baseRequestVO.getUserStatus() != null) {
              lambdaQuery.eq(User::getUserStatus, baseRequestVO.getUserStatus());
          }
  
          if (baseRequestVO.getUserType() != null) {
              lambdaQuery.eq(User::getUserType, baseRequestVO.getUserType());
          }
  
          if (StringUtils.hasText(baseRequestVO.getSearchKey())) {
              lambdaQuery.and(lq -> lq.like(User::getUsername, baseRequestVO.getSearchKey())
                      .or()
                      .like(User::getPhoneNumber, baseRequestVO.getSearchKey())
                      .or()
                      .like(User::getEmail, baseRequestVO.getSearchKey()));
          }
  
          lambdaQuery.orderByDesc(User::getCreateTime).page(baseRequestVO);
  
          List<User> records = baseRequestVO.getRecords();
          if (!CollectionUtils.isEmpty(records)) {
              records.forEach(u -> {
                  u.setPassword(null);
                  u.setOpenId(null);
              });
          }
          return PoetryResult.success(baseRequestVO);
      }
  
      @Override
      public PoetryResult<List<UserVO>> getUserByUsername(String username) {
          List<User> users = lambdaQuery().select(User::getId, User::getUsername, User::getAvatar, User::getGender, User::getIntroduction).like(User::getUsername, username).last("limit 5").list();
          List<UserVO> userVOS = users.stream().map(u -> {
              UserVO userVO = new UserVO();
              userVO.setId(u.getId());
              userVO.setUsername(u.getUsername());
              userVO.setAvatar(u.getAvatar());
              userVO.setIntroduction(u.getIntroduction());
              userVO.setGender(u.getGender());
              return userVO;
          }).collect(Collectors.toList());
          return PoetryResult.success(userVOS);
      }
  
      @Override
      public PoetryResult<UserVO> token(String userToken) {
          userToken = new String(SecureUtil.aes(CommonConst.CRYPOTJS_KEY.getBytes(StandardCharsets.UTF_8)).decrypt(userToken));
  
          if (!StringUtils.hasText(userToken)) {
              throw new PoetryRuntimeException("未登陆，请登陆后再进行操作！");
          }
  
          User user = (User) PoetryCache.get(userToken);
  
          if (user == null) {
              throw new PoetryRuntimeException("登录已过期，请重新登陆！");
          }
  
          UserVO userVO = new UserVO();
          BeanUtils.copyProperties(user, userVO);
          userVO.setPassword(null);
  
          userVO.setAccessToken(userToken);
  
          return PoetryResult.success(userVO);
      }
  
      @Override
      public PoetryResult<UserVO> subscribe(Integer labelId, Boolean flag) {
          UserVO userVO = null;
          User one = lambdaQuery().eq(User::getId, PoetryUtil.getUserId()).one();
          List<Integer> sub = JSON.parseArray(one.getSubscribe(), Integer.class);
          if (sub == null) sub = new ArrayList<>();
          if (flag) {
              if (!sub.contains(labelId)) {
                  sub.add(labelId);
                  User user = new User();
                  user.setId(one.getId());
                  user.setSubscribe(JSON.toJSONString(sub));
                  updateById(user);
  
                  userVO = new UserVO();
                  BeanUtils.copyProperties(one, userVO);
                  userVO.setPassword(null);
                  userVO.setSubscribe(user.getSubscribe());
                  userVO.setAccessToken(PoetryUtil.getToken());
              }
          } else {
              if (sub.contains(labelId)) {
                  sub.remove(labelId);
                  User user = new User();
                  user.setId(one.getId());
                  user.setSubscribe(JSON.toJSONString(sub));
                  updateById(user);
  
                  userVO = new UserVO();
                  BeanUtils.copyProperties(one, userVO);
                  userVO.setPassword(null);
                  userVO.setSubscribe(user.getSubscribe());
                  userVO.setAccessToken(PoetryUtil.getToken());
              }
          }
          return PoetryResult.success(userVO);
      }
  
      private String getCodeMail(int i) {
          WebInfo webInfo = (WebInfo) PoetryCache.get(CommonConst.WEB_INFO);
          String webName = (webInfo == null ? "POETIZE" : webInfo.getWebName());
          return String.format(mailUtil.getMailText(),
                  webName,
                  String.format(MailUtil.imMail, PoetryUtil.getAdminUser().getUsername()),
                  PoetryUtil.getAdminUser().getUsername(),
                  String.format(codeFormat, i),
                  "",
                  webName);
      }
  }
  