admin
2020-05-20 98b1a0affd69bbe63223c21fdd2c404e8bedfccb
fanli/src/main/java/com/yeshi/fanli/service/impl/user/UserInfoExtraServiceImpl.java
@@ -1,5 +1,8 @@
package com.yeshi.fanli.service.impl.user;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@@ -8,25 +11,40 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.yeshi.utils.DateUtil;
import org.yeshi.utils.FileUtil;
import org.yeshi.utils.HttpUtil;
import org.yeshi.utils.entity.FileUploadResult;
import org.yeshi.utils.tencentcloud.COSManager;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.Producer;
import com.yeshi.fanli.dao.mybatis.user.UserInfoExtraMapper;
import com.yeshi.fanli.dao.mybatis.user.UserRankRecordMapper;
import com.yeshi.fanli.entity.bus.user.ThreeSale;
import com.yeshi.fanli.dto.mq.user.UserTopicTagEnum;
import com.yeshi.fanli.dto.mq.user.body.InviteCodeActiveMQMsg;
import com.yeshi.fanli.dto.mq.user.body.UserInfoUpdateMQMsg;
import com.yeshi.fanli.dto.mq.user.body.UserInfoUpdateMQMsg.UserInfoUpdateTypeEnum;
import com.yeshi.fanli.dto.wx.WXAccountInfoDTO;
import com.yeshi.fanli.entity.bus.user.UserInfo;
import com.yeshi.fanli.entity.bus.user.UserInfoExtra;
import com.yeshi.fanli.entity.bus.user.UserRank;
import com.yeshi.fanli.entity.bus.user.UserRankRecord;
import com.yeshi.fanli.entity.bus.user.WeiXinUser;
import com.yeshi.fanli.exception.ThreeSaleException;
import com.yeshi.fanli.entity.bus.user.notify.UserActivedRecord;
import com.yeshi.fanli.entity.system.ConfigKeyEnum;
import com.yeshi.fanli.exception.user.ThreeSaleException;
import com.yeshi.fanli.exception.user.UserInfoExtraException;
import com.yeshi.fanli.log.LogHelper;
import com.yeshi.fanli.service.inter.config.ConfigService;
import com.yeshi.fanli.service.inter.hongbao.ThreeSaleSerivce;
import com.yeshi.fanli.service.inter.order.CommonOrderCountService;
import com.yeshi.fanli.service.inter.user.ForbiddenUserIdentifyCodeService;
import com.yeshi.fanli.service.inter.user.UserAccountService;
@@ -34,19 +52,27 @@
import com.yeshi.fanli.service.inter.user.UserInfoService;
import com.yeshi.fanli.service.inter.user.UserInviteRecordService;
import com.yeshi.fanli.service.inter.user.UserRankService;
import com.yeshi.fanli.service.inter.user.invite.ThreeSaleSerivce;
import com.yeshi.fanli.service.inter.user.msg.UserAccountMsgNotificationService;
import com.yeshi.fanli.service.inter.user.notify.UserActivedRecordService;
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.FilePathEnum;
import com.yeshi.fanli.util.InviteCodeFilterUtil;
import com.yeshi.fanli.util.StringUtil;
import com.yeshi.fanli.util.account.UserUtil;
import com.yeshi.fanli.util.rocketmq.MQMsgBodyFactory;
import com.yeshi.fanli.util.rocketmq.MQTopicName;
import com.yeshi.fanli.util.wx.WXLoginUtil;
import com.yeshi.fanli.vo.user.UserInfoExtraVO;
import net.coobird.thumbnailator.Thumbnails;
@Service
public class UserInfoExtraServiceImpl implements UserInfoExtraService {
   @Resource
   private UserInfoExtraMapper userInfoExtraMapper;
   @Resource
   private UserRankRecordMapper userRankRecordMapper;
@@ -58,22 +84,31 @@
   @Resource
   private ConfigService configService;
   @Resource
   private ThreeSaleSerivce threeSaleSerivce;
   @Resource
   private UserInfoService userInfoService;
   @Resource
   private UserAccountService userAccountService;
   @Resource
   private ForbiddenUserIdentifyCodeService forbiddenUserIdentifyCodeService;
   @Resource
   private UserInviteRecordService userInviteRecordService;
   @Resource
   @Lazy
   private UserActivedRecordService userActivedRecordService;
   
   @Resource
   private UserAccountMsgNotificationService userAccountMsgNotificationService;
   @Resource(name = "producer")
   private Producer producer;
   @Override
   public UserInfoExtraVO getRankInfo(Long uid) throws UserInfoExtraException, Exception {
@@ -83,19 +118,19 @@
         throw new UserInfoExtraException(1, "用户附加信息不存在");
      }
      // 等级对照表
      String contrast = configService.get("user_rank_contrast");
      // 等级对照表
      String contrast = configService.get(ConfigKeyEnum.userRankContrast.getKey());
      extraVO.setRankContrast(contrast);
      // 特别提醒
      String rankTip = configService.get("user_rank_tip");
      String rankTip = configService.get(ConfigKeyEnum.userRankTip.getKey());
      extraVO.setRankTip(rankTip);
      Integer rankOrderNum = extraVO.getRankOrderNum();
      UserRank userRank = extraVO.getUserRank();
      // 青铜等级不返回恭喜语句 注:青铜等级id 必须为1
      if (userRank != null && userRank.getId() != null && userRank.getId() > 1) {
         String rankMsg = null;
         Integer rankSource = extraVO.getRankSource();
         switch (rankSource) {
@@ -150,13 +185,14 @@
   }
   @Override
   public void updateUserRankByUid(Long uid) throws UserInfoExtraException{
   public void updateUserRankByUid(Long uid) throws UserInfoExtraException {
      if (uid == null || uid == 0) {
         return;
      }
      boolean isupdateRank = true;
      UserInfoExtra extra = new UserInfoExtra();
      UserInfoExtra userInfoExtra = userInfoExtraMapper.getInfoExtraByUid(uid);
      if (userInfoExtra != null && userInfoExtra.getId() != null) {
         // 判断当月是否已更新
@@ -166,126 +202,109 @@
            if (sdf.format(rankUpdateTime).equals(sdf.format(new Date()))) {
               isupdateRank = false;
            }
         }
         }
         extra.setId(userInfoExtra.getId());
      } else {
         userInfoExtra = new UserInfoExtra();
         userInfoExtra.setUserInfo(new UserInfo(uid));
         extra.setUserInfo(new UserInfo(uid));
      }
      // 更新等级
      if (isupdateRank) {
         updateRank(userInfoExtra);
         List<UserRank> listRank = userRankService.getAllRank();
         if (listRank == null || listRank.size() == 0) {
            throw new UserInfoExtraException(1, "系统等级不存在");
         }
         int selfOrderNum = 0;
         int sharedOrderNum = 0;
         int inviteOrderNum = 0;
         Map<String, Object> map = commonOrderCountService.lastMonthSettleOrderNumber(uid);
         if (map != null) {
            // 返利订单
            if (map.get("totalSelf") != null) {
               selfOrderNum = Integer.parseInt(map.get("totalSelf").toString());
            }
            // 分享订单
            if (map.get("totalShared") != null) {
               sharedOrderNum = Integer.parseInt(map.get("totalShared").toString());
            }
            // 邀请订单
            if (map.get("totalInvite") != null) {
               inviteOrderNum = Integer.parseInt(map.get("totalInvite").toString());
            }
         }
         UserRank rank = null;
         for (UserRank userRank : listRank) {
            // 邀请满足
            Integer inviteNum = userRank.getInviteNum();
            if (inviteOrderNum >= inviteNum) {
               rank = userRank;
               extra.setRankOrderNum(inviteOrderNum);
               extra.setRankSource(Constant.TYPE_INVITE);
            }
            // 分享满足
            int shareNum = userRank.getShareNum();
            if (sharedOrderNum >= shareNum) {
               rank = userRank;
               extra.setRankOrderNum(sharedOrderNum);
               extra.setRankSource(Constant.TYPE_SHAER);
            }
            // 返利满足
            int directNum = userRank.getRebateNum();
            if (selfOrderNum >= directNum) {
               rank = userRank;
               extra.setRankOrderNum(selfOrderNum);
               extra.setRankSource(Constant.TYPE_REBATE);
            }
            if (rank != null) {
               extra.setUserRank(rank);
            } else {
               rank = userRank;
               // 默认最低等级:青铜
               extra.setUserRank(rank);
               extra.setRankOrderNum(selfOrderNum);
               extra.setRankSource(Constant.TYPE_REBATE);
               break;
            }
         }
         // 等级更新时间 当月1号
         Calendar calendar1 = Calendar.getInstance();
         calendar1.set(Calendar.DAY_OF_MONTH, 1);
         extra.setRankUpdateTime(calendar1.getTime());
         // 保存等级信息
         saveUserInfoExtra(extra);
         // 保存等级变化记录
         UserRankRecord userRankRecord = new UserRankRecord();
         userRankRecord.setUid(uid);
         userRankRecord.setRankId(rank.getId());
         userRankRecord.setCreateTime(new Date());
         userRankRecordMapper.insertSelective(userRankRecord);
      }
   }
   @Override
   public void createUserInfoExtra (Long uid) throws UserInfoExtraException{
   public void createUserInfoExtra(Long uid) throws UserInfoExtraException {
      UserInfoExtra userInfoExtra = userInfoExtraMapper.getInfoExtraByUid(uid);
      if (userInfoExtra != null) {
         return;
      }
      }
      userInfoExtra = new UserInfoExtra();
      userInfoExtra.setUserInfo(new UserInfo(uid));
      userInfoExtra.setFirstLoginTime(new Date());
      userInfoExtra.setCreateTime(new Date());
      userInfoExtra.setUpdateTime(new Date());
      userInfoExtra.setActiveTime(new Date());
      userInfoExtraMapper.insertSelective(userInfoExtra);
   }
   @Override
   public UserInfoExtra updateRank(UserInfoExtra userInfoExtra) throws UserInfoExtraException {
      UserInfo userInfo = userInfoExtra.getUserInfo();
      if (userInfo == null ) {
         throw new UserInfoExtraException(1, "用户不存在");
      }
      Long uid = userInfo.getId();
      if (uid == null ) {
         throw new UserInfoExtraException(1, "用户ID不存在");
      }
      List<UserRank> listRank = userRankService.getAllRank();
      if (listRank == null || listRank.size() == 0) {
         throw new UserInfoExtraException(1, "系统等级不存在");
      }
      int selfOrderNum = 0;
      int sharedOrderNum = 0;
      int inviteOrderNum = 0;
      Map<String, Object> map = commonOrderCountService.lastMonthSettleOrderNumber(uid);
      if (map != null) {
         // 返利订单
         if (map.get("totalSelf") != null) {
            selfOrderNum = Integer.parseInt(map.get("totalSelf").toString());
         }
         // 分享订单
         if (map.get("totalShared") != null) {
            sharedOrderNum = Integer.parseInt(map.get("totalShared").toString());
         }
         // 邀请订单
         if (map.get("totalInvite") != null) {
            inviteOrderNum = Integer.parseInt(map.get("totalInvite").toString());
         }
      }
      UserRank rank = null;
      for (UserRank userRank : listRank) {
         // 邀请满足
         Integer inviteNum = userRank.getInviteNum();
         if (inviteOrderNum >= inviteNum) {
            rank = userRank;
            userInfoExtra.setRankOrderNum(inviteOrderNum);
            userInfoExtra.setRankSource(Constant.TYPE_INVITE);
         }
         // 分享满足
         int shareNum = userRank.getShareNum();
         if (sharedOrderNum >= shareNum) {
            rank = userRank;
            userInfoExtra.setRankOrderNum(sharedOrderNum);
            userInfoExtra.setRankSource(Constant.TYPE_SHAER);
         }
         // 返利满足
         int directNum = userRank.getRebateNum();
         if (selfOrderNum >= directNum) {
            rank = userRank;
            userInfoExtra.setRankOrderNum(selfOrderNum);
            userInfoExtra.setRankSource(Constant.TYPE_REBATE);
         }
         if (rank != null) {
            userInfoExtra.setUserRank(rank);
         } else {
            rank = userRank;
            // 默认最低等级:青铜
            userInfoExtra.setUserRank(rank);
            userInfoExtra.setRankOrderNum(selfOrderNum);
            userInfoExtra.setRankSource(Constant.TYPE_REBATE);
            break;
         }
      }
      // 等级更新时间 当月1号
      Calendar calendar1=Calendar.getInstance();
        calendar1.set(Calendar.DAY_OF_MONTH, 1);
      userInfoExtra.setRankUpdateTime(calendar1.getTime());
      // 保存信息并返回
      saveUserInfoExtra(userInfoExtra);
      UserRankRecord userRankRecord = new UserRankRecord();
      userRankRecord.setUid(uid);
      userRankRecord.setRankId(rank.getId());
      userRankRecord.setCreateTime(new Date());
      userRankRecordMapper.insertSelective(userRankRecord);
      return userInfoExtra;
   }
   @Override
@@ -320,92 +339,51 @@
      }
      return userInfoExtra;
   }
   @Override
   public String activateInviteCode(Long uid, String inviteCode, String platform, String version) throws UserInfoExtraException{
      if (uid == null || inviteCode == null) {
         throw new UserInfoExtraException(1, "用户id、邀请码不能为空");
      }
   @Transactional(rollbackFor = Exception.class)
   public String activateInviteCode(Long uid, String inviteCode) throws UserInfoExtraException {
      if (uid == null || inviteCode == null)
         throw new UserInfoExtraException(1, "激活信息不能为空");
      // 被邀请人信息
      UserInfo invitee = userInfoService.selectByPKey(uid);
      if (invitee == null) {
      if (invitee == null)
         throw new UserInfoExtraException(1, "用户不存在");
      }
      // 额外信息
      UserInfoExtra extra = userInfoExtraMapper.getInfoExtraByUid(uid);
      if (extra != null) {
         String inviteCodeHas = extra.getInviteCode();
         if (inviteCodeHas != null && inviteCodeHas.trim().length() > 0) {
            throw new UserInfoExtraException(1, "已存在邀请码,请刷新页面");
         }
      }
      // 邀请人信息
      UserInfo inviter = userInfoService.getInfoByPhoneOrInviteCode(inviteCode, inviteCode);
      if (inviter == null) {
      if (extra != null && !StringUtil.isNullOrEmpty(extra.getInviteCode()))
         throw new UserInfoExtraException(1, "已经激活, 无需再次激活");
      inviteCode = inviteCode.toUpperCase();
      // 邀请码对应用户信息
      UserInfo boss = userInfoService.getUserInfoByInviteCode(inviteCode);
      if (boss == null || boss.getState() != UserInfo.STATE_NORMAL)
         throw new UserInfoExtraException(1, "上级邀请码不存在");
      }
      // 绑定关系
      try {
         threeSaleSerivce.bindRelationshipByInviteCode(invitee, inviter, platform, version);
      } catch (ThreeSaleException e) {
         try {
            LogHelper.errorDetailInfo(e);
         } catch (Exception e1) {
            e1.printStackTrace();
         }
         throw new UserInfoExtraException(1, "激活失败");
      }
      // 邀请码有效、生成邀请码
      String code = UserUtil.getInviteCode(uid);
      if (code == null || code.trim().length() == 0) {
         throw new UserInfoExtraException(1, "激活码生成失败");
      }
      UserInfoExtra userInfoExtra = new UserInfoExtra();
      userInfoExtra.setUserInfo(invitee);
      userInfoExtra.setInviteCode(code);
      // 保存额外信息
      saveUserInfoExtra(userInfoExtra);
      Long id = userInfoExtra.getId();
      if (id == null) {
         throw new UserInfoExtraException(1, "激活码生成失败");
      }
      return code;
      // 生成邀请关系
      return inviteCodeActive(uid, boss.getId());
   }
   @Override
   public void activationInviteWX(Long uid, String code, String platform, String version) throws UserInfoExtraException{
      if (uid == null || code == null) {
   @Transactional(rollbackFor = Exception.class)
   public void activationInviteWX(WXAccountInfoDTO wxAccount, Long uid, String code) throws UserInfoExtraException {
      if (uid == null || code == null)
         throw new UserInfoExtraException(1, "激活信息不完整");
      }
      // 用户信息
      UserInfo invitee = userInfoService.selectByPKey(uid);
      if (invitee == null) {
      if (invitee == null)
         throw new UserInfoExtraException(1, "用户不存在");
      }
      // 用户额外信息
      // 额外信息
      UserInfoExtra extra = userInfoExtraMapper.getInfoExtraByUid(uid);
      if (extra != null) {
         String inviteCodeHas = extra.getInviteCode();
         if (inviteCodeHas != null && inviteCodeHas.trim().length() > 0) {
            throw new UserInfoExtraException(1, "已经激活, 无需再次激活");
         }
      }
      if (extra != null && !StringUtil.isNullOrEmpty(extra.getInviteCode()))
         throw new UserInfoExtraException(1, "已经激活, 无需再次激活");
      // 获取微信信息
      WeiXinUser weiXinUser = WXLoginUtil.getWeiXinUser(code);
      WeiXinUser weiXinUser = WXLoginUtil.getWeiXinUser(code, wxAccount.getAppId(), wxAccount.getAppSecret());
      if (weiXinUser == null) {
         throw new UserInfoExtraException(1, "微信授权失败");
      }
@@ -413,7 +391,7 @@
      if (wxUnionId == null || wxUnionId.trim().length() == 0) {
         throw new UserInfoExtraException(1, "微信授权失败");
      }
      // 验证数据
      String wxUnionIdExist = invitee.getWxUnionId();
      if (StringUtil.isNullOrEmpty(wxUnionIdExist)) {
@@ -421,51 +399,167 @@
         if (newUser != null) {
            throw new UserInfoExtraException(1, "此微信已被其他帐号绑定");
         }
         // 自动绑定微信
         UserInfo updateUserInfo = new UserInfo(uid);
         updateUserInfo.setWxOpenId(weiXinUser.getOpenid());
         updateUserInfo.setWxUnionId(weiXinUser.getUnionid());
         if (!StringUtil.isNullOrEmpty(weiXinUser.getNickname())) {
            updateUserInfo.setWxName(weiXinUser.getNickname());
            updateUserInfo.setNickName(weiXinUser.getNickname());
         updateUserInfo.setWxName(weiXinUser.getNickname());
         updateUserInfo.setWxPic(weiXinUser.getHeadimgurl());
         // 将默认昵称替换成微信昵称
         String defaultNickName = Constant.systemCommonConfig.getDefaultNickName();
         if (!StringUtil.isNullOrEmpty(defaultNickName) && !StringUtil.isNullOrEmpty(weiXinUser.getNickname())) {
            defaultNickName = defaultNickName + uid;
            if ((defaultNickName.equals(invitee.getNickName()) || "返利券".equals(invitee.getNickName())
                  || invitee.getNickName().startsWith(Constant.systemCommonConfig.getDefaultNickName()))) {
               updateUserInfo.setNickName(weiXinUser.getNickname());
            }
         }
         if (!StringUtil.isNullOrEmpty(weiXinUser.getHeadimgurl())) {
            updateUserInfo.setWxPic(weiXinUser.getHeadimgurl());
            updateUserInfo.setPortrait(weiXinUser.getHeadimgurl());
         // 将默认头像替换成微信头像
         String defaultPortrait = Constant.systemCommonConfig.getDefaultPortrait();
         if (!StringUtil.isNullOrEmpty(weiXinUser.getHeadimgurl()) && !StringUtil.isNullOrEmpty(defaultPortrait)
               && defaultPortrait.equals(invitee.getPortrait())) {
            String headimgurl = weiXinUser.getHeadimgurl();
            InputStream asInputStream = HttpUtil.getAsInputStream(headimgurl);
            if (asInputStream == null) {
               LogHelper.test("微信头像下载失败: " + weiXinUser.getUnionid() + " " + headimgurl);
            } else {
               FileUploadResult result = COSManager.getInstance().uploadFile(asInputStream,
                     String.format(FilePathEnum.userWXPortrait.getPath() + "%s_%s.jpg", weiXinUser.getUnionid(),
                           System.currentTimeMillis() + ""));
               if (result != null && !StringUtil.isNullOrEmpty(result.getUrl())) {
                  headimgurl = result.getUrl();
               } else {
                  LogHelper.test("微信头像上传失败: " + weiXinUser.getUnionid() + " " + headimgurl);
               }
            }
            updateUserInfo.setPortrait(headimgurl);
         }
         userInfoService.updateByPrimaryKeySelective(updateUserInfo);
      } else if (!wxUnionId.equals(wxUnionIdExist)){
      } else if (!wxUnionId.equals(wxUnionIdExist)) {
         throw new UserInfoExtraException(1, "绑定微信与激活微信不一致");
      }
      // 是否存在邀请人
      Long inviterId = userInviteRecordService.getNewestInviterId(wxUnionId);
      if (inviterId == null)
         throw new UserInfoExtraException(1, "没有对应的邀请关系");
      
      UserInfo boss = userInfoService.selectByPKey(inviterId);
      if (boss == null || boss.getState() != UserInfo.STATE_NORMAL) {
         throw new UserInfoExtraException(1, "没有对应的邀请关系");
      }
      // 邀请码激活
      inviteCodeActive(uid, boss.getId());
   }
   @Override
   @Transactional(rollbackFor = Exception.class)
   public void activeInviteWX(Long uid, WeiXinUser weiXinUser) throws UserInfoExtraException {
      if (uid == null || weiXinUser == null) {
         throw new UserInfoExtraException(1, "激活信息不完整");
      }
      // 用户信息
      UserInfo invitee = userInfoService.selectByPKey(uid);
      if (invitee == null) {
         throw new UserInfoExtraException(1, "用户不存在");
      }
      String wxUnionId = weiXinUser.getUnionid();
      if (wxUnionId == null || wxUnionId.trim().length() == 0) {
         throw new UserInfoExtraException(1, "微信授权失败");
      }
      // 验证数据
      String wxUnionIdExist = invitee.getWxUnionId();
      if (StringUtil.isNullOrEmpty(wxUnionIdExist)) {
         UserInfo newUser = userInfoService.getEffectiveUserInfoByWXUnionId(weiXinUser.getUnionid());
         if (newUser != null) {
            throw new UserInfoExtraException(1, "此微信已被其他帐号绑定");
         }
         // 自动绑定微信
         UserInfo updateUserInfo = new UserInfo(uid);
         updateUserInfo.setWxOpenId(weiXinUser.getOpenid());
         updateUserInfo.setWxUnionId(weiXinUser.getUnionid());
         updateUserInfo.setWxName(weiXinUser.getNickname());
         updateUserInfo.setWxPic(weiXinUser.getHeadimgurl());
         // 将默认昵称替换成微信昵称
         String defaultNickName = Constant.systemCommonConfig.getDefaultNickName();
         if (!StringUtil.isNullOrEmpty(defaultNickName) && !StringUtil.isNullOrEmpty(weiXinUser.getNickname())) {
            defaultNickName = defaultNickName + uid;
            if ((defaultNickName.equals(invitee.getNickName()) || "返利券".equals(invitee.getNickName())
                  || invitee.getNickName().startsWith(Constant.systemCommonConfig.getDefaultNickName()))) {
               updateUserInfo.setNickName(weiXinUser.getNickname());
            }
         }
         // 将默认头像替换成微信头像
         String defaultPortrait = Constant.systemCommonConfig.getDefaultPortrait();
         if (!StringUtil.isNullOrEmpty(weiXinUser.getHeadimgurl()) && !StringUtil.isNullOrEmpty(defaultPortrait)
               && defaultPortrait.equals(invitee.getPortrait())) {
            String headimgurl = weiXinUser.getHeadimgurl();
            InputStream asInputStream = HttpUtil.getAsInputStream(headimgurl);
            if (asInputStream == null) {
               LogHelper.test("微信头像下载失败: " + weiXinUser.getUnionid() + " " + headimgurl);
            } else {
               FileUploadResult result = COSManager.getInstance().uploadFile(asInputStream,
                     String.format(FilePathEnum.userWXPortrait.getPath() + "%s_%s.jpg", weiXinUser.getUnionid(),
                           System.currentTimeMillis() + ""));
               if (result != null && !StringUtil.isNullOrEmpty(result.getUrl())) {
                  headimgurl = result.getUrl();
               } else {
                  LogHelper.test("微信头像上传失败: " + weiXinUser.getUnionid() + " " + headimgurl);
               }
            }
            updateUserInfo.setPortrait(headimgurl);
         }
         userInfoService.updateByPrimaryKeySelective(updateUserInfo);
      } else if (!wxUnionId.equals(wxUnionIdExist)) {
         throw new UserInfoExtraException(1, "绑定微信与激活微信不一致");
      }
      // 邀请人ID -1.5.3新版
      Long inviterId = userInviteRecordService.getNewestInviterId(wxUnionId);
      // 兼容1.5.3 之前版本
      ThreeSale threeSale = threeSaleSerivce.getByWorkerId(uid);
      if (inviterId == null && threeSale != null) {
         Long bossId = threeSale.getBoss().getId();
         UserInfoExtra inviterExtra = userInfoExtraMapper.getInfoExtraByUid(bossId);
         if (inviterExtra != null && inviterExtra.getInviteCode() == null ) {
            // 更新邀请码
            UserInfoExtra inviterInfoExtra = new UserInfoExtra();
            inviterInfoExtra.setId(inviterExtra.getId());
            inviterInfoExtra.setInviteCode(UserUtil.getInviteCode(bossId));
            userInfoExtraMapper.updateByPrimaryKeySelective(inviterInfoExtra);
         }
      if (inviterId == null) {
         throw new UserInfoExtraException(1, "没有对应的邀请关系");
      }
      
      // 没有被邀请过
      if (inviterId == null && threeSale == null) {
      UserInfo boss = userInfoService.selectByPKey(inviterId);
      if (boss == null || boss.getState() != UserInfo.STATE_NORMAL) {
         throw new UserInfoExtraException(1, "没有对应的邀请关系");
      }
      // 邀请码激活
      inviteCodeActive(uid, boss.getId());
   }
   /**
    * 邀请关系生成激活码
    * @param uid
    * @param bossId
    * @return
    * @throws UserInfoExtraException
    */
   private String inviteCodeActive(Long uid, Long bossId) throws UserInfoExtraException{
      UserInfoExtra extra = userInfoExtraMapper.getInfoExtraByUid(uid);
      if (extra != null && !StringUtil.isNullOrEmpty(extra.getInviteCode())) {
         throw new UserInfoExtraException(1, "已经激活, 无需再次激活");
      }
      
      // 绑定关系
      try {
         threeSaleSerivce.bindRelationshipByWX(invitee, inviterId, threeSale, platform, version);
         threeSaleSerivce.bindInviteRelationship(uid, bossId);
      } catch (ThreeSaleException e) {
         try {
            LogHelper.errorDetailInfo(e);
@@ -474,16 +568,14 @@
         }
         throw new UserInfoExtraException(1, "关系绑定时失败");
      }
      // 邀请码有效、生成邀请码
      String inviteCode = UserUtil.getInviteCode(uid);
      if (inviteCode == null || inviteCode.trim().length() == 0) {
      // 生成邀请码
      String inviteCode = createInviteCode(uid);
      if (StringUtil.isNullOrEmpty(inviteCode))
         throw new UserInfoExtraException(1, "激活码生成失败");
      }
      // 保存邀请码
      UserInfoExtra userInfoExtra = new UserInfoExtra();
      userInfoExtra.setUserInfo(invitee);
      userInfoExtra.setUserInfo(new UserInfo(uid));
      userInfoExtra.setInviteCode(inviteCode);
      userInfoExtra.setUpdateTime(new Date());
      if (extra != null) {
@@ -493,65 +585,125 @@
         userInfoExtra.setCreateTime(new Date());
         userInfoExtraMapper.insertSelective(userInfoExtra);
      }
   }
   @Override
   public UserInfoExtra getUserInfoExtra(Long uid) {
      return userInfoExtraMapper.getInfoExtraByUid(uid);
   }
   @Override
   public UserInfoExtraVO getInfoExtraVOByUid(Long uid) {
      return userInfoExtraMapper.getInfoExtraVOByUid(uid);
   }
   @Override
   public String getUserInviteCode(Long uid) throws UserInfoExtraException {
      
      UserInfoExtra userInfoExtra = userInfoExtraMapper.getInfoExtraByUid(uid);
      if (userInfoExtra == null) {
         userInfoExtra = new UserInfoExtra();
      }
      // 邀请码
      String inviteCode = userInfoExtra.getInviteCode();
      if (inviteCode == null || inviteCode.trim().length() == 0) {
         // 判断用户
         int relationshipNum = threeSaleSerivce.getSuccessRelationshipNum(uid);
         if (relationshipNum > 0) {
            // 邀请码有效、生成邀请码
            inviteCode = UserUtil.getInviteCode(uid);
            if (inviteCode == null || inviteCode.trim().length() == 0) {
               throw new UserInfoExtraException(1, "激活码生成失败");
            }
            // 保存邀请码
            userInfoExtra.setUserInfo(new UserInfo(uid));
            userInfoExtra.setInviteCode(inviteCode);
            // 保存附加信息
            saveUserInfoExtra(userInfoExtra);
         }
      userActivedRecordService.add(new UserActivedRecord(uid));
      if (!Constant.IS_TEST) { // 发送激活成功消息
         Message message = MQMsgBodyFactory.create(MQTopicName.TOPIC_USER, UserTopicTagEnum.inviteCodeActive,
               new InviteCodeActiveMQMsg(uid, new Date()));
         producer.send(message);
      }
      
      return inviteCode;
   }
   
   @Override
   public void updateActiveTime(Long uid, Date date) {
      UserInfoExtra userInfoExtra = new UserInfoExtra();
      userInfoExtra.setUserInfo(new UserInfo(uid));
      userInfoExtra.setActiveTime(date);
      userInfoExtraMapper.updateInfoExtraByUid(userInfoExtra);
   }
   @Override
   public UserInfoExtra getUserInfoExtra(Long uid) {
      return userInfoExtraMapper.getInfoExtraByUid(uid);
   }
   @Override
   public UserInfoExtra getUserALLInfo(Long uid) {
      return userInfoExtraMapper.gerUserRank(uid);
   }
   @Override
   @Transactional
   public UserInfoExtra getByUidForUpdate(Long uid) {
      return userInfoExtraMapper.getByUidForUpdate(uid);
   }
   @Override
   @Transactional
   public void updateGoldCoin(Long id, Integer goldCoin) {
      userInfoExtraMapper.updateGoldCoin(id, goldCoin);
   }
   @Override
   public void addGoldCoinByUid(Long uid, Integer goldCoin) {
      userInfoExtraMapper.addGoldCoinByUid(uid, goldCoin);
   }
   @Override
   public void updateByPrimaryKeySelective(UserInfoExtra record) {
      userInfoExtraMapper.updateByPrimaryKeySelective(record);
   }
   @Override
   public UserInfoExtraVO getInfoExtraVOByUid(Long uid) {
      return userInfoExtraMapper.getInfoExtraVOByUid(uid);
   }
   @Override
   public String getInviteCodeByUid(Long uid) {
      UserInfoExtra userInfoExtra = userInfoExtraMapper.getInfoExtraByUid(uid);
      if (userInfoExtra != null) {
         // vip邀请码优先
         if (!StringUtil.isNullOrEmpty(userInfoExtra.getInviteCodeVip()))
            return userInfoExtra.getInviteCodeVip();
         if (!StringUtil.isNullOrEmpty(userInfoExtra.getInviteCode()))
            return userInfoExtra.getInviteCode();
         // 是否满足生产邀请码
         int relationshipNum = threeSaleSerivce.getSuccessRelationshipNum(uid);
         if (relationshipNum > 0) {
            try {
               String inviteCode = createInviteCode(uid);
               if (!StringUtil.isNullOrEmpty(inviteCode)) {
                  UserInfoExtra extra = new UserInfoExtra();
                  extra.setId(userInfoExtra.getId());
                  extra.setInviteCode(inviteCode);
                  userInfoExtraMapper.updateByPrimaryKeySelective(extra);
                  return inviteCode;
               }
            } catch (Exception e) {
               LogHelper.errorDetailInfo(e);
            }
         }
      }
      return "";
   }
   /**
    * 生产邀请码
    *
    * @param uid
    * @return
    */
   private String createInviteCode(Long uid) {
      String inviteCode = null;
      for (int i = 1; i <= 5; i++) {
         inviteCode = UserUtil.getInviteCode(i, uid);
         long countCode = userInfoExtraMapper.countByInviteCode(inviteCode);
         if (countCode <= 0)
            break;
      }
      return inviteCode;
   }
   @Override
   public long countByRankId(Long rankId) {
      return userInfoExtraMapper.countByRankId(rankId);
   }
   @Override
   public boolean isNewUser(Long uid) {
      boolean isNew = false;
      if (uid == null) {
         return isNew;
      }
      UserInfoExtra extra = userInfoExtraMapper.getInfoExtraByUid(uid);
      if (extra != null && extra.getFirstLoginTime() != null) {
         try {
@@ -565,49 +717,48 @@
      }
      return isNew;
   }
   @Override
   public UserRank gerUserRank(Long uid) {
      if(uid == null) {
      if (uid == null) {
         return null;
      }
      UserInfoExtra userInfoExtra = userInfoExtraMapper.gerUserRank(uid);
      if (userInfoExtra == null) {
         return null;
      }
      return userInfoExtra.getUserRank();
   }
   @Override
   public UserInfo getUserByInviteCode(String inviteCode) throws UserInfoExtraException{
      if (StringUtil.isNullOrEmpty(inviteCode)) {
   public UserInfo getUserByInviteCode(String inviteCode) throws UserInfoExtraException {
      if (StringUtil.isNullOrEmpty(inviteCode))
         throw new UserInfoExtraException(1, "邀请码不能为空");
      }
      // 邀请人信息
      UserInfo inviter = userInfoService.getInfoByPhoneOrInviteCode(inviteCode, inviteCode);
      if (inviter == null) {
      UserInfo inviter = userInfoService.getUserInfoByInviteCode(inviteCode);
      if (inviter == null)
         throw new UserInfoExtraException(1, "上级邀请码不存在");
      if (inviter.getState() != UserInfo.STATE_NORMAL) {
         throw new UserInfoExtraException(1, "上级邀请码不存在");
      }
      return inviter;
   }
   @Override
   public UserInfo getInviterInfo(Long uid, String code) throws UserInfoExtraException{
      if (code == null) {
         throw new UserInfoExtraException(1, "code信息不完整");
   public UserInfo getInviterInfo(Long uid, String wxUnionId) throws UserInfoExtraException {
      if (wxUnionId == null) {
         throw new UserInfoExtraException(1, "unionId信息不完整");
      }
      // 用户信息
      UserInfo invitee = userInfoService.selectByPKey(uid);
      if (invitee == null) {
         throw new UserInfoExtraException(1, "用户不存在");
      }
      // 用户额外信息
      UserInfoExtra extra = userInfoExtraMapper.getInfoExtraByUid(uid);
      if (extra != null) {
@@ -616,38 +767,120 @@
            throw new UserInfoExtraException(1, "已经激活, 无需再次激活");
         }
      }
      // 获取微信信息
      WeiXinUser weiXinUser = WXLoginUtil.getWeiXinUser(code);
      if (weiXinUser == null) {
         throw new UserInfoExtraException(1, "微信授权失败");
      }
      String wxUnionId = weiXinUser.getUnionid();
      if (wxUnionId == null || wxUnionId.trim().length() == 0) {
         throw new UserInfoExtraException(1, "微信授权失败");
      }
      // 验证数据
      String wxUnionIdExist = invitee.getWxUnionId();
      if (StringUtil.isNullOrEmpty(wxUnionIdExist)) {
         UserInfo newUser = userInfoService.getEffectiveUserInfoByWXUnionId(weiXinUser.getUnionid());
         UserInfo newUser = userInfoService.getEffectiveUserInfoByWXUnionId(wxUnionId);
         if (newUser != null) {
            throw new UserInfoExtraException(1, "此微信已被其他帐号绑定");
         }
      } else if (!wxUnionId.equals(wxUnionIdExist)){
      } else if (!wxUnionId.equals(wxUnionIdExist)) {
         throw new UserInfoExtraException(1, "绑定微信与激活微信不一致");
      }
      // 邀请人ID
      Long inviterId = userInviteRecordService.getNewestInviterId(wxUnionId);
      if (inviterId == null) {
         throw new UserInfoExtraException(1, "没有对应的邀请关系");
      }
      UserInfo inviter = userInfoService.selectByPKey(inviterId);
      if (inviter == null) {
         throw new UserInfoExtraException(1, "对应的邀请关系不存在");
      }
      if (inviter.getState() != UserInfo.STATE_NORMAL) {
         throw new UserInfoExtraException(1, "对应的邀请关系不存在");
      }
      return inviter;
   }
   @Transactional(rollbackFor = Exception.class)
   @Override
   public void updateInviteCodeVip(String inviteCodeVip, Long uid) throws UserInfoExtraException {
      if (inviteCodeVip == null || inviteCodeVip.length() < 4 || inviteCodeVip.length() > 12)
         throw new UserInfoExtraException(1, "邀请码必须为4到12位");
      UserInfoExtra extra = getUserInfoExtra(uid);
      if (extra == null)
         throw new UserInfoExtraException(2, "用户信息不存在");
      if (StringUtil.isNullOrEmpty(extra.getInviteCode()))
         throw new UserInfoExtraException(3, "邀请码尚未激活");
      if (!StringUtil.isNullOrEmpty(extra.getInviteCodeVip()))
         throw new UserInfoExtraException(4, "只能修改一次");
      // 转换成大写
      inviteCodeVip = inviteCodeVip.toUpperCase();
      // 验证特殊码
      if (InviteCodeFilterUtil.isSpecialCode(inviteCodeVip))
         throw new UserInfoExtraException(5, "邀请码已存在");
      if (inviteCodeVip.equalsIgnoreCase(extra.getInviteCode()))
         throw new UserInfoExtraException(5, "不能为原邀请码");
      long count = userInfoExtraMapper.countByInviteCode(inviteCodeVip);
      if (count > 0)
         throw new UserInfoExtraException(6, "邀请码已存在");
      UserInfoExtra update = new UserInfoExtra();
      update.setId(extra.getId());
      update.setInviteCodeVip(inviteCodeVip);
      update.setUpdateTime(new Date());
      userInfoExtraMapper.updateByPrimaryKeySelective(update);
      if (!Constant.IS_TEST) { // 发送邀请码更改成功的消息
         Message message = MQMsgBodyFactory.create(MQTopicName.TOPIC_USER, UserTopicTagEnum.userInfoUpdate,
               new UserInfoUpdateMQMsg(uid, UserInfoUpdateTypeEnum.inviteCode, inviteCodeVip,
                     new Date()));
         producer.send(message);
      }
      // 消息
      userAccountMsgNotificationService.createChangeInviteCode(uid, extra.getInviteCode(), inviteCodeVip);
   }
   @Override
   public void uploadERCode(MultipartFile file, Long uid) {
      UserInfoExtra extra = userInfoExtraMapper.getInfoExtraByUid(uid);
      if (extra == null)
         return;
      // 压缩
      String targetPath = FileUtil.getCacheDir() + "/erCode_" + uid + "_" + System.currentTimeMillis() + ".jpg";
      try {
         Thumbnails.of(file.getInputStream()).size(200, 200).toFile(targetPath);
      } catch (IOException e) {
         LogHelper.errorDetailInfo(e);
         return;
      }
      // 执行上传
      String filePath = FilePathEnum.userERcode.getPath() + UUID.randomUUID().toString().replace("-", "") + ".jpg";
      String fileLink = COSManager.getInstance().uploadFile(new File(targetPath), filePath).getUrl();
      // 删除本地图片
      if (new File(targetPath).exists()) {
         new File(targetPath).delete();
      }
      // 原二维码
      String erCode = extra.getErCode();
      UserInfoExtra update = new UserInfoExtra();
      update.setId(extra.getId());
      update.setErCode(fileLink);
      userInfoExtraMapper.updateByPrimaryKeySelective(update);
      // 原二维码
      if (!StringUtil.isNullOrEmpty(erCode)) {
         COSManager.getInstance().deleteFile(erCode);
      }
   }
}